docs: dire partout que la lecture par lot n'existe plus
Le contrat publie et l'api-contract etaient traites avec le retrait lui-meme ; restaient les documents qui decrivaient readUnion comme la primitive de lecture du paquet, ou qui nommaient le module disparu. Ce que les lecteurs apprennent maintenant : lire un document, c'est docs.sparqlQuery ancre dessus, et lire plusieurs documents, c'est cet appel une fois par document -- avec la decision sur une lecture qui echoue ecrite au point d'appel. Deux consequences sont dites plutot que decouvertes : une lecture refusee leve au lieu de rendre une liste vide, et les sujets sous le prefixe reserve urn:ng-eventually: reviennent dans le resultat, a l'appelant de les ignorer -- sans aucun gain de droits, les deux registres qu'un document ordinaire porte etant l'adresse de sa boite et, pour un document public, la cle que son magasin sert deja a qui la demande. Les briefs dates ne sont pas touches : ils decrivent un etat de juillet, et le reecrire falsifierait ce qui avait ete decide alors.
This commit is contained in:
@@ -232,7 +232,8 @@ export async function readStoreCaps(storeDoc: Nuri): Promise<ReadCap[]> {
|
||||
* store it was created in ({@link holdOwnCap}) — and until 2026-08-16 exactly one path
|
||||
* read it back: `listMyEntityDocs`. So a creator that reloaded the page and went straight
|
||||
* to the document it had just made, without listing that scope first, held nothing for it:
|
||||
* the read was refused, the batch read (`readUnion`) dropped it silently, and the write
|
||||
* the read was refused, the batch read of the day (`readUnion`, removed in `1.0.0-dev.8`)
|
||||
* dropped it silently, and the write
|
||||
* was refused. Its own document, denied to its own author, on the first refresh.
|
||||
*
|
||||
* Restoring what a user HOLDS is already what connecting means here — that is what the
|
||||
|
||||
@@ -288,7 +288,7 @@ async function applyLink(payload: unknown, ctx: Applying): Promise<boolean> {
|
||||
// reports the whole inbox, and everything not yet popped is preserved for the next
|
||||
// attempt. That is the rule stated beside {@link report}, and BOTH arms follow it — but
|
||||
// the reference arm only since its `unreadable` outcome was split out of `refused` on the
|
||||
// same day. It had been the opposite: `read-model.readDoc` swallows a failed read and
|
||||
// same day. It had been the opposite: the batch read of the day swallowed a failed read and
|
||||
// answers `[]`, so an outage arrived as an ordinary refusal and the drain walked the
|
||||
// whole queue destroying it. Correcting one arm and leaving the other is precisely how
|
||||
// that survived a round of review.
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
* nothing had to tell an absence from a failure. **That is no longer true, and it is the
|
||||
* sharpest consequence of consuming.** An absence is deterministic and costs its own deposit;
|
||||
* a silent broker is transient and must stop the drain, or one outage walks the queue and
|
||||
* destroys every reference in it. `read-model.readDoc` answers `[]` for both, so this module
|
||||
* destroys every reference in it. An anchored read answers `[]` for both, so this module
|
||||
* passes it an `onUnreadable` reporter and asks which one happened.
|
||||
*
|
||||
* What it no longer means, since deposits became consumed on 2026-08-26, is "and a later
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* open-repo — cold-start repo opening for the ANCHORED read path (polyfill-era).
|
||||
*
|
||||
* ── The cold-start defect this heals ──────────────────────────────────────
|
||||
* The anchored read path (`surface/read-model.ts` `readDoc`,
|
||||
* The anchored read path (`surface/read-document.ts` `readDocumentSubjects`,
|
||||
* `shared-wallet/account-registry.ts` `readUserStore`) assumes the target repo is
|
||||
* already usable by the verifier — true within the session that CREATED the doc
|
||||
* (every `doc_create` opens it), but FALSE on a FRESH session over the same
|
||||
@@ -19,9 +19,10 @@
|
||||
* the verifier: on a persistent profile `Verifier::load` repopulates `self.repos` from
|
||||
* user storage at construction (`engine/verifier/src/verifier.rs:535-560`), so the repo
|
||||
* is PRESENT but unsynced and the anchored query legitimately matches nothing; and this
|
||||
* library's own `readDoc` catches every error and returns `[]`
|
||||
* (`surface/read-model.ts:122`), so anything that did throw would reach the caller as
|
||||
* emptiness anyway. The fix below is right; the diagnosis written beside it was not.
|
||||
* library's own per-document read caught every error and returned `[]`
|
||||
* (`surface/read-model.ts`'s `readDoc`, until `1.0.0-dev.8` removed it along with the
|
||||
* batch it served), so anything that did throw reached the caller as emptiness anyway.
|
||||
* It no longer does: `surface/read-document.ts` lets the rejection through. The fix below is right; the diagnosis written beside it was not.
|
||||
*
|
||||
* The circularity that made this self-inflicted: `doc_subscribe` WOULD open the
|
||||
* repo, but the reactive layer only subscribes AFTER the listing produced NURIs —
|
||||
|
||||
@@ -165,7 +165,7 @@ export async function assertMayWrite(nuri: Nuri, op: string): Promise<void> {
|
||||
}
|
||||
|
||||
/**
|
||||
* **Rule 2 — do not even attempt**, at the CALLERS (`read-model`, `open-repo`,
|
||||
* **Rule 2 — do not even attempt**, at the CALLERS (`open-repo`,
|
||||
* `subscribe`'s callers…).
|
||||
*
|
||||
* A reader that does not hold a document's cap must not issue the operation at all.
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
* It is SYNCHRONOUS and decides from what the holder holds at that instant. A document
|
||||
* in a PUBLIC store hands its cap to whoever asks (`public-store.ts`), but asking is a
|
||||
* round-trip - so this filter drops such a document until some read path has asked.
|
||||
* The paths that DO ask are the ones this library still reads with (`readUnion`,
|
||||
* The paths that DO ask are the ones this library still reads with (the anchored
|
||||
* document read,
|
||||
* `docs.sparqlQuery`, `ensureRepoOpen`, `documentInboxAddress`). The two SHAPE reads
|
||||
* ask nothing: `useShape` because its signature is the real ORM's and has no await to
|
||||
* spend, and `useShapeQuery` since `1.0.0-dev.6`, because it reads through the SDK's
|
||||
|
||||
@@ -166,7 +166,7 @@ export const STORE_BRANCH_SUBJECT = `${SHIM}:storeBranch`;
|
||||
/**
|
||||
* Fixed subject of the **Header branch** emulation, inside an ENTITY document — the
|
||||
* first compartment we put in a document the consumer also reads, hence the filter in
|
||||
* `read-model.ts` (every `${SHIM}:` subject is machinery and never surfaces as data).
|
||||
* `read-document.ts` (every `${SHIM}:` subject is machinery, and the internal read drops it).
|
||||
*
|
||||
* It carries what must be readable by *whoever can read the document*, as opposed to
|
||||
* what belongs to its owner alone. Today that is one thing: the ADDRESS of the
|
||||
@@ -1165,7 +1165,7 @@ export async function createEntityDoc(id: string, scope: StoreType): Promise<Nur
|
||||
s.sessionId,
|
||||
// NO explicit `GRAPH <…>` wrapper: write the anchored DEFAULT graph (the
|
||||
// `indexDoc` anchor scopes it) — the CANONICAL, always-safe shape the anchored
|
||||
// default-graph read queries (readUserStore below, same as read-model.ts).
|
||||
// default-graph read queries (readUserStore below, same as read-document.ts).
|
||||
// entityNuri is a NURI stored as a literal → escapeLiteral.
|
||||
`INSERT DATA { <${MAIN_BRANCH_SUBJECT}> <${P.contains}> "${escapeLiteral(entityNuri)}" }`,
|
||||
indexDoc,
|
||||
|
||||
@@ -315,7 +315,7 @@ export function configureStoreRegistry(deps: StoreRegistryDeps): void {
|
||||
// Fire the outbox inspection (Volet 3 of the low-level data-path trace) once,
|
||||
// on the FIRST successful `getSession()` resolution — the most reliable
|
||||
// "a session is established" signal available: every low-level reader/writer
|
||||
// (store-registry, open-repo, read-model, subscribe, inbox) reaches its
|
||||
// (store-registry, open-repo, read-document, subscribe, inbox) reaches its
|
||||
// session through this SAME injected `getSession`, so wrapping it HERE catches
|
||||
// the first success from whichever caller happens to run first, instead of
|
||||
// tying the probe to one particular call site. Only on SUCCESS (an error
|
||||
@@ -424,7 +424,7 @@ export function getCurrentUser(): PrincipalId | null {
|
||||
}
|
||||
|
||||
/** The emulated cap registry — what the current identity holds, plus the emulated
|
||||
* public store. The read filter and the read-model consult it. */
|
||||
* public store. The read filter and the document read consult it. */
|
||||
export function getCaps(): CapRegistry {
|
||||
return caps;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import type { Nuri, NuriLike } from "../model/types";
|
||||
// through `sparqlQuery`, every write through `sparqlUpdate` (+ container creation
|
||||
// through `docCreate`) — each ultimately calling the real injected `ng` here. The
|
||||
// access log is therefore instrumented HERE so no access path escapes it. Callers
|
||||
// pass a semantic `label` (readDoc|readUnion|listMyEntityDocs|writeEntity|deposit
|
||||
// pass a semantic `label` (readDocument|listMyEntityDocs|writeEntity|deposit
|
||||
// |…); it is a lib-internal probe param, NOT forwarded to the real `ng` (the docs
|
||||
// primitives forward the exact SDK signature — see test/docs.test.ts). When the
|
||||
// log is OFF (default) the extra param is inert and costs one boolean read.
|
||||
|
||||
@@ -212,7 +212,7 @@ export async function post(targetInboxLike: NuriLike, opts: PostOptions): Promis
|
||||
|
||||
// NO explicit `GRAPH <…>` wrapper — write the anchored DEFAULT graph:
|
||||
// `sparqlUpdate(sid, update, targetInbox)` scopes the write to that repo's
|
||||
// default graph (same shape as read-model.ts readDoc/readUnion). This is the
|
||||
// default graph (same shape as `read-document.ts`'s anchored read). This is the
|
||||
// CANONICAL, always-safe shape and the one the anchored default-graph read
|
||||
// queries. (Not a round-trip necessity on the current broker: the e2e harness
|
||||
// `packages/polyfill/e2e/` verified that an anchored `GRAPH <plainNuri>` write
|
||||
|
||||
@@ -137,7 +137,7 @@ export async function createEntityDoc(store?: NuriLike): Promise<Nuri> {
|
||||
//
|
||||
// - `listMyEntityDocs` has no counterpart at any level: there is no `doc_list`, no
|
||||
// `list_docs`, nothing in the binding. Listing what one created is an ordinary query
|
||||
// over the store's `ldp:contains` — the same shape `readUnion` is, sugar over
|
||||
// over the store's `ldp:contains` — the same shape the anchored document read is, sugar over
|
||||
// something already expressible. It stays reachable at `../shared-wallet/account-registry`
|
||||
// for this library's own read path, which still calls it until that path queries the
|
||||
// store itself.
|
||||
|
||||
@@ -86,7 +86,7 @@ import type { Nuri, NuriLike } from "../model/types";
|
||||
* A push from the platform to a document subscriber. Loosely typed: the raw
|
||||
* serialized `AppResponse` (`{ V0: { State | Patch | TabInfo | ... } }`). The
|
||||
* consumer typically ignores the payload and uses the push purely as a
|
||||
* change SIGNAL (re-query on change — the read-model pattern), so this stays
|
||||
* change SIGNAL (re-query on change — the read model in `docs/read-model.md`), so this stays
|
||||
* permissive rather than modelling every AppResponse variant.
|
||||
*/
|
||||
// @provenance DocChange kind=aligned level=1 ref=engine/net/src/app_protocol.rs:AppResponseV0 — the raw serialized response, left `unknown` rather than modelling every variant
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
* The SDK's own shape query - `RdfOrmSubscription.getOrCreate(shapeType, scope)` - and
|
||||
* nothing of this library's own. Four steps went with the change, and they were one
|
||||
* mechanism: a logical scope resolved to a document set (`listMyEntityDocs`), those
|
||||
* documents opened through `ensureReposOpen` for a sync barrier, `readUnion` over them,
|
||||
* and a filter of the union by the shape's `@type` IRI. All four existed because the
|
||||
* parameter had to be TRANSLATED; once the parameter is upstream's own `Scope`, the
|
||||
* documents opened through `ensureReposOpen` for a sync barrier, one anchored read over
|
||||
* each of them, and a filter of the result by the shape's `@type` IRI. All four existed
|
||||
* because the parameter had to be TRANSLATED; once the parameter is upstream's own `Scope`, the
|
||||
* question goes straight to the thing that answers it. `graphs`, `subjects` and the
|
||||
* whole-dataset marker `did:ng:i` are now read by the engine, literally, and this module
|
||||
* does not interpret them at all - so the three readings are upstream's, not ours.
|
||||
|
||||
Reference in New Issue
Block a user