feat(data): activate isolation — declare identity + connections to the SDK
Festipod performs the domain acts that make isolation real: AccountContext declares the current identity at login/change; FestipodDataContext declares its connections (friendships) to the data SDK. Reads then discriminate by scope through the SDK (private→owner, protected→owner+connections, public→all) — no app-side filtering, no store ids, no awareness that isolation is emulated. New @data scenario proves an unconnected account can't read another's protected entity but can after connecting; public stays visible. @data 21/21. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,8 @@ import { NextGraphProvider, useNextGraph } from '../context/NextGraphContext';
|
||||
import { FestipodDataProvider, useFestipodData } from '../context/FestipodDataContext';
|
||||
// useShape routed through the lib (SDK-identical surface); caps from /polyfill.
|
||||
import { useShape, docs, inbox as docsInbox } from '@ng-eventually/client';
|
||||
import { getCaps, setCurrentUser, resetCaps } from '@ng-eventually/client/polyfill';
|
||||
import { getCaps, getCurrentUser, setCurrentUser, resetCaps, declareConnections } from '@ng-eventually/client/polyfill';
|
||||
import { isolation as ngIsolation } from '@ng-eventually/client';
|
||||
import { hostInboxNuri as regInboxNuri } from '../data/registration';
|
||||
import type { DeepSignalSet } from '@ng-eventually/client';
|
||||
// doc_create goes through the lib's `docs` primitive (T01.a): it calls the REAL
|
||||
@@ -280,6 +281,38 @@ function ConnectedHarness() {
|
||||
setCurrentUser(user);
|
||||
},
|
||||
|
||||
// --- PROTECTED + connections isolation (T03.b) ----------------------
|
||||
// Prove, through the SDK's ReadCap filter on the REAL ORM set, that a
|
||||
// PROTECTED document owned by `owner` is:
|
||||
// - hidden from an UNCONNECTED principal (only owner reads it);
|
||||
// - revealed once the app declares the connection owner↔reader;
|
||||
// - a PUBLIC document stays readable throughout (regardless of caps).
|
||||
// Uses `getCaps().open(doc, scope, owner)` exactly as the app wrapper
|
||||
// (storeRegistry.createEntityDoc) does; the protected participations
|
||||
// document is governed, and a separate makePublic'd doc models a public
|
||||
// entity. <FilterProbe> exposes the read-filtered VIEW over the protected
|
||||
// participations doc. `connect` calls the SDK's declareConnections — the
|
||||
// app's domain sharing act — never touches a doc NURI or the registry.
|
||||
governProtected(owner: string, reader: string) {
|
||||
resetCaps();
|
||||
// The protected participations document (owner-only read at first).
|
||||
getCaps().open(protectedNuri!, 'protected', owner);
|
||||
// A public entity document — readable by anyone regardless of caps.
|
||||
getCaps().makePublic('did:ng:o:public-probe');
|
||||
setCurrentUser(reader);
|
||||
setFilterActive(true);
|
||||
},
|
||||
/** Declare the owner↔reader connection to the SDK (domain sharing act).
|
||||
* The SDK then issues the protected doc's read cap to the connection. */
|
||||
connect(a: string, b: string) {
|
||||
declareConnections(ngIsolation.connectionsFromLinks([{ a, b }]));
|
||||
},
|
||||
/** Does the CURRENT user read the public entity document — through the
|
||||
* SDK's own cap check — regardless of the protected caps? */
|
||||
canReadPublicProbe() {
|
||||
return getCaps().canRead('did:ng:o:public-probe', getCurrentUser());
|
||||
},
|
||||
|
||||
// --- Stopgap multi-store validation (see brief_2026-06-15_shared-wallet-shim) ---
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user