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:
Sylvain Duchesne
2026-08-04 12:56:02 +02:00
parent cd096de2b0
commit 0b37d17c2f
19 changed files with 151 additions and 145 deletions
+8 -8
View File
@@ -86,7 +86,7 @@ users/quorum (write/permissions), **not** read-cap possession. (Repos of a
> Consequence for this lib's emulation (see [`simulation.md`](./simulation.md)):
> the read access unit is the repo = each item's `@graph` — a per-document
> filter, never per-store and never per-item. This is exactly what
> `caps.ts` (`CapRegistry`) and `read-filter.ts` model: no store-level
> `emulated-verifier/caps.ts` (`CapRegistry`) and `emulated-verifier/read-filter.ts` model: no store-level
> inheritance, purely per-document caps. In a mono-store layout (all items in one
> repo) the filter is therefore all-or-nothing on that document — which *is* the
> native behaviour, and why fine-grained isolation requires one document per
@@ -285,7 +285,7 @@ from JS today a repo becomes queryable ONLY by being `doc_create`d in this sessi
**Consequence for this lib's mono-wallet polyfill:** every account's documents are
`doc_create`d in the one shared wallet within the same session, so they are all
already in `self.repos`. `read-model.ts` reads the bounded, by-need set of docs
already in `self.repos`. `surface/read-model.ts` reads the bounded, by-need set of docs
with one anchored `sparql_query` per doc (`SELECT ?s ?p ?o WHERE { ?s ?p ?o }`,
anchor = the doc NURI): the anchor resolves that same-session repo directly (no
separate open needed) and restricts the query to its graph, so it is O(1) per doc,
@@ -346,7 +346,7 @@ account map fell into (see next section).
### The pointer → doc-shim indirection (how the polyfill shim resolves accounts)
`store-registry.ts` keeps a map `identifier → {docPublic, docProtected, docPrivate}`
`shared-wallet/account-registry.ts` keeps a map `identifier → {docPublic, docProtected, docPrivate}`
(the "shim", the account→document trust root). It must be reachable by a fresh
reconnecting session (findable) AND authoritative on a cold read (so a fresh page
does not mistake sync-lag for "account absent" and PROVISION a fork). Since no single
@@ -750,9 +750,9 @@ On a FRESH session over the SAME persistent wallet (reconnect, new page, re-logi
anchored `sparql_query` against a document written in an earlier session comes back with
**0 rows and no error** — persisted documents read as empty. Observed on every anchored
reader of the polyfill and healed identically in each (`ensureRepoOpen` before the read,
`packages/client/src/open-repo.ts`): the user's own documents,
the user's store (`store-registry.ts` `readUserStore`), the by-need doc batch
(`read-model.ts` `readUnion`), and the store-root pointer read (`store-registry.ts`
`packages/client/src/emulated-verifier/open-repo.ts`): the user's own documents,
the user's store (`shared-wallet/account-registry.ts` `readUserStore`), the by-need doc batch
(`surface/read-model.ts` `readUnion`), and the store-root pointer read (`shared-wallet/account-registry.ts`
`resolvePointer`). The heal is `doc_subscribe(nuri)` → await the first `State` (the sync
barrier) → THEN the anchored read, and it is verified to return the data.
@@ -786,7 +786,7 @@ is a single account subject carrying MULTIPLE values for one scope predicate (ob
five `shim:docPublic`), after which a writer and a later reader can resolve DIFFERENT
scope docs and the reader's anchored read returns 0.
Two polyfill-side guards, both in `packages/client/src/store-registry.ts`: `ensureInFlight`
Two polyfill-side guards, both in `packages/client/src/shared-wallet/account-registry.ts`: `ensureInFlight`
(a bounded promise map keyed by account, so concurrent `ensureAccount` calls share ONE
resolve-or-provision) prevents new forks; `canonicalDoc` (pick the lexicographically
smallest NURI among all distinct values for a scope predicate — NURIs are
@@ -821,7 +821,7 @@ semantics of the replay path itself (VERIFIED by reading `send_outbox`).
**Consequence for this lib:** a queued write can be dropped without any observable error,
and one unknown topic can take the rest of the queue with it. The polyfill's own
`outbox-log.ts` does not record anything: it exports a single `inspectOutbox()` that
`shared-wallet/outbox-log.ts` does not record anything: it exports a single `inspectOutbox()` that
READS the SDK's own `sessionStorage` outbox and logs how many peers still have queued
writes. It observes the symptom; it holds nothing it could replay, and no
write-durability confirmation exists to await — so "the write returned" is not "the write