docs: reprendre les citations après le rangement, et retirer le membre login fabriqué
Les deux contrats et la doctrine portent des centaines de citations `file:line` vers `src/`. Le rangement par destin les périmait en bloc — 208 reprises (45 chemins `src/x.ts`, 163 mentions nues). Sans ça la réorganisation pourrissait l'instrument même qui tient la discipline qu'elle sert. Et un défaut relevé par le contrat interne, vérifié : `ng-proxy` fabriquait un membre `login`. `@ng-org/web` n'expose aucune méthode de ce nom — zéro occurrence dans les déclarations installées comme dans `sdk/js/lib-wasm/src/lib.rs` — mais le proxy répondait une fonction au lieu d'`undefined`, laquelle plantait à l'appel. C'était le seul endroit où ce wrapper ajoutait à la surface du SDK, contre son propre en-tête. 157 tests unitaires, typecheck src/test/e2e vert.
This commit is contained in:
+19
-19
@@ -52,10 +52,10 @@ Because the emulation runs on ONE shared wallet, distinguish two levels:
|
||||
|
||||
- **A virtual user** — the library's emulation of one identity: the documents the
|
||||
shim attributes to that account (its three store documents in
|
||||
`store-registry.ts`). This is what "the user owns", and over it "list my
|
||||
`shared-wallet/account-registry.ts`). This is what "the user owns", and over it "list my
|
||||
documents" is meaningful and bounded.
|
||||
|
||||
**Which API you use follows that line, and it is enforced** (see `physical.ts`):
|
||||
**Which API you use follows that line, and it is enforced** (see `shared-wallet/physical.ts`):
|
||||
machinery operating on the *index of virtual users* — the store-root pointer, the
|
||||
doc-shim, the account records — goes through unguarded primitives that are never
|
||||
exported from the package. Everything touching a virtual user's own content goes
|
||||
@@ -70,7 +70,7 @@ ones whose cap you were given.
|
||||
|
||||
At migration each virtual user becomes a real user with its own wallet; the
|
||||
physical/virtual distinction, the "never enumerate the physical one" rule, and
|
||||
`physical.ts` all dissolve into native per-user reads.
|
||||
`shared-wallet/physical.ts` all dissolve into native per-user reads.
|
||||
|
||||
## Two axes, never conflate them (store ≠ document)
|
||||
|
||||
@@ -86,7 +86,7 @@ terminology historically fused:
|
||||
|
||||
`docCreate(sessionId, "Graph", "data:graph", "store", undefined)` targets the shared
|
||||
wallet's private store. The trailing `store` arg left `undefined` targets the
|
||||
private store (this is what `store-registry.ts`'s `createDoc()` does). So every
|
||||
private store (this is what `shared-wallet/account-registry.ts`'s `createDoc()` does). So every
|
||||
document the shim creates physically lives in one store (private), and the
|
||||
`public|protected|private` scope is a logical label tracked in RDF by the
|
||||
shim — not a NextGraph store. Therefore what a consumer application's "multi-store"
|
||||
@@ -100,7 +100,7 @@ logical label the registry attaches.
|
||||
> [`migration-guide.md`](./migration-guide.md)). The private store is reachable
|
||||
> because it opens without `RepoNotFound`.
|
||||
|
||||
## The shared-wallet shim (`store-registry.ts`)
|
||||
## The shared-wallet shim (`shared-wallet/account-registry.ts`)
|
||||
|
||||
Emulates the target infrastructure — where each user owns their own
|
||||
public/protected/private stores — on top of one shared wallet.
|
||||
@@ -207,7 +207,7 @@ store-id:
|
||||
redirect the owner's deposits to itself). Both are dedicated documents (real repo
|
||||
NURIs from `docCreate`), never the private-store root: routing deposits into the shim
|
||||
graph would bloat the account→document trust root without bound. `myInboxes()`
|
||||
enumerates both levels — what `connect.ts` drains at connection — and `isOwnInbox`
|
||||
enumerates both levels — what `emulated-verifier/connect.ts` drains at connection — and `isOwnInbox`
|
||||
answers from the same record. *(The former `resolveInboxAnchor`, a single inbox COMMON
|
||||
to every user, was removed on 2026-07-30: nothing may be common but the mechanisms
|
||||
that make the virtual users work.)*
|
||||
@@ -220,7 +220,7 @@ store-id:
|
||||
A document that has an inbox carries its address on its emulated **Header branch** —
|
||||
a reserved subject inside the document, so any holder of the document reads it, and
|
||||
`read-model` filters the whole `urn:ng-eventually:` namespace out of consumer data
|
||||
(`src/machinery.ts`). This mirrors upstream's split: a depositor seals with the inbox
|
||||
(`src/emulated-verifier/machinery.ts`). This mirrors upstream's split: a depositor seals with the inbox
|
||||
PUBLIC key and needs nothing else, only the owner holds the private half.
|
||||
**One inbox belongs to one document** — never several documents behind one inbox, a
|
||||
relation upstream cannot express (the verifier routes by `inboxes: PubKey → RepoId`
|
||||
@@ -265,7 +265,7 @@ is preserved in [`decisions/private-store-nuri-scope.md`](./decisions/private-st
|
||||
|
||||
A validated hard constraint, not a style choice: `docs.ts` calls the real
|
||||
injected `ng` (`getConfig().ng`) directly, never the public `ng` proxy
|
||||
(`makeNg` in `ng-proxy.ts`).
|
||||
(`makeNg` in `surface/ng-proxy.ts`).
|
||||
|
||||
`@ng-org/web`'s `ng` is already an iframe-RPC proxy (postMessage marshaling,
|
||||
see [`nextgraph-current-state.md`](./nextgraph-current-state.md) § integration).
|
||||
@@ -283,13 +283,13 @@ verified: routing the shim's `doc_create`/SPARQL through the public proxy turned
|
||||
`docs.ts` therefore imports **no** `@ng-org` package and must **not** import from
|
||||
`./ng-proxy`.
|
||||
|
||||
## Emulated ReadCap — per document (`caps.ts` + `read-filter.ts`)
|
||||
## Emulated ReadCap — per document (`emulated-verifier/caps.ts` + `emulated-verifier/read-filter.ts`)
|
||||
|
||||
In the target the broker only delivers documents the wallet holds a ReadCap
|
||||
for, so `useShape` already returns an authorized subset. Here (single shared
|
||||
wallet, everything readable) the lib reproduces that with a read-filtered view:
|
||||
|
||||
- **`CapRegistry` (`caps.ts`)** models a ReadCap as what it is: **the document's
|
||||
- **`CapRegistry` (`emulated-verifier/caps.ts`)** models a ReadCap as what it is: **the document's
|
||||
key**. The access unit is the document = repo NURI (an item's `@graph`), never
|
||||
the item — because in `nextgraph-rs` a store is just a container repo and holding
|
||||
its cap does not grant the repos it references (no store-level read inheritance;
|
||||
@@ -305,13 +305,13 @@ wallet, everything readable) the lib reproduces that with a read-filtered view:
|
||||
constant `OK` (see the module header): the only question the emulation answers is
|
||||
*do I hold this cap or not*, so the value says exactly that and pretends nothing
|
||||
more. P1b, not P1a, is the batch that turns the shape into a protection.
|
||||
- **`read-filter.ts`** — `makeReadFilteredView` wraps the reactive set in a
|
||||
- **`emulated-verifier/read-filter.ts`** — `makeReadFilteredView` wraps the reactive set in a
|
||||
`Proxy`: iteration / `size` / `forEach` keep only items whose `@graph` the
|
||||
current holder holds; everything else (`add`, `delete`, `has`, `getById`…) forwards to
|
||||
the target, preserving writes and reactivity. An item with no `@graph` is kept (it
|
||||
names no document, so there is no cap to hold). `filterReadable` is the pure
|
||||
variant. Note the absence of a `user` parameter — that absence *is* the model.
|
||||
- **`useShape` (`use-shape.ts`)** applies the view only once a cap exists at all
|
||||
- **`useShape` (`surface/use-shape.ts`)** applies the view only once a cap exists at all
|
||||
(`caps.isEnforcing()`) — before that it passes the real set through unchanged (no
|
||||
regression for a consumer that never touches caps). Once ANY cap is issued the
|
||||
regime is possession for **every** holder, including one who holds nothing:
|
||||
@@ -428,7 +428,7 @@ cosmetic. Proven in `test/cross-user-access.test.ts`.
|
||||
|
||||
### Write-guard coverage (honest scope)
|
||||
|
||||
The emulated write guard (`ng-proxy.ts`, `sparql_update` override) enforces the
|
||||
The emulated write guard (`surface/ng-proxy.ts`, `sparql_update` override) enforces the
|
||||
per-document write cap on the public `ng` proxy only. In practice the
|
||||
consumer application's write paths (`docs.sparqlUpdate`, ORM `ngSet`) call the real
|
||||
injected `ng` directly — never the public proxy — for the validated `DataCloneError`
|
||||
@@ -440,7 +440,7 @@ natively at migration); the read side is what makes isolation observably active.
|
||||
|
||||
### The per-document ReadCap is the isolation path (item-level filter retired)
|
||||
|
||||
Isolation is enforced by the per-document ReadCap (`caps.ts` + `read-filter.ts`)
|
||||
Isolation is enforced by the per-document ReadCap (`emulated-verifier/caps.ts` + `emulated-verifier/read-filter.ts`)
|
||||
alone: the access unit is the document (`@graph` = repo), and the only acts are
|
||||
possession-shaped (`createEntityDoc` files a cap, `shareCap` delivers one,
|
||||
`publishRepoLink` emits an openable link). Because the consumer application writes
|
||||
@@ -515,7 +515,7 @@ The inbox + watcher is the one deposit/read mechanism a consumer reuses for its
|
||||
purposes — a registration/deposit, a cap delivery (`shareCap`), a link handed to
|
||||
someone — same `post` API, same watcher.
|
||||
|
||||
## The virtual user boundary (`reach.ts` + `physical.ts`)
|
||||
## The virtual user boundary (`emulated-verifier/reach.ts` + `shared-wallet/physical.ts`)
|
||||
|
||||
Every access function is confined to the user currently connected: no cross-user
|
||||
access, so the consumer is coded against a reach that will actually exist.
|
||||
@@ -541,13 +541,13 @@ named primitive rather than a flag, because it is a different act — you hold n
|
||||
you cannot read back, and you get nothing in return. It is the only channel by which
|
||||
a link crosses between users, hence the bootstrap of the whole reachability graph.
|
||||
|
||||
The machinery lives in `physical.ts` (see *Physical user vs virtual user* above):
|
||||
The machinery lives in `shared-wallet/physical.ts` (see *Physical user vs virtual user* above):
|
||||
unguarded primitives, never exported from the package, used only for the index of
|
||||
virtual users. Separating the FUNCTIONS is what replaced an earlier exemption list —
|
||||
the machinery does not get waved through the guard, it calls something the guard
|
||||
never saw.
|
||||
|
||||
## Connecting a user (`connect.ts`)
|
||||
## Connecting a user (`emulated-verifier/connect.ts`)
|
||||
|
||||
Processing inboxes is the **library's** job, not the app's: a consumer must never
|
||||
have to remember to drain a queue for documents shared with it to become readable —
|
||||
@@ -587,7 +587,7 @@ first.
|
||||
|
||||
The ADR that specified it ([`decisions/discovery-model.md`](./decisions/discovery-model.md)) is marked superseded, and keeps the part that survives: the `discovery → synchronization → query` frame still holds, with stage 1 re-read as *"a link reached you"* rather than *"you consulted an index"*. Which makes the **inbox** the bootstrap of the whole reachability graph — see [`briefs/2026-07-30-virtual-wallet-boundary.md`](./briefs/2026-07-30-virtual-wallet-boundary.md).
|
||||
|
||||
## Emulated write guard (`ng-proxy.ts`)
|
||||
## Emulated write guard (`surface/ng-proxy.ts`)
|
||||
|
||||
The public `ng` proxy overrides `sparql_update` to enforce an emulated write
|
||||
cap: a write is refused unless the current user holds the target document's
|
||||
@@ -596,7 +596,7 @@ specific document (the `anchor` arg) is governed by it — ungoverned docs (the
|
||||
mono-store default, no cap declared) flow through unchanged. This mirrors the target
|
||||
broker/verifier, which refuses a write without the document's write cap.
|
||||
|
||||
## Identity store (`accounts.ts`)
|
||||
## Identity store (`shared-wallet/accounts.ts`)
|
||||
|
||||
The real NextGraph login (redirect to the broker, opening the single shared
|
||||
wallet) is perceived as a technical access barrier (see the login
|
||||
|
||||
Reference in New Issue
Block a user