docs: le contrat descend a ce que le code tient vraiment, et T01.j est scindee
La sixieme revue a refute la reparation du tour 6 et a trouve la famille sur laquelle nous nous etions engages a scinder. `held` n'est pas le registre unique : il y en a trois, et celui que personne n'avait compte est `fanOuts` dans `subscribe.ts`. `configure()`, qui est PUBLIE, vide les auditeurs sans le dire a `open-repo` ; et `held.set()` s'execute avant meme que `establish` atteigne `doc_subscribe`. `held` veut donc toujours dire « on a demande » - le sens plus lache pour lequel j'avais supprime `opened`. J'ai remplace l'un des deux registres qui se contredisaient ; il y en avait trois. Aucun code touche ici. Le defaut de registre part dans T01.m, avec ses deux echecs prouves comme tests d'acceptation. Le contrat dit desormais ce que le code tient : la moitie « le document a-t-il repondu » vaut DANS UNE SESSION ordinaire, et pas apres un second `configure(...)` ni quand le courtier refuse un abonnement tardivement. Les deux situations sont nommees en non-garanties avec leur cause et le renvoi vers T01.m. La moitie « peut-on joindre le document » n'a pas cette reserve : elle est verifiee deux fois contre un vrai courtier, et la retirer ramenerait un succes vide silencieux partout, ce qui est pire qu'une garantie partielle honnetement enoncee. Pas de changement de version : aucun comportement publie ne bouge, seule la justesse de sa description. Et une faute de compte-rendu consignee, parce que c'est un motif : trois fois j'ai affirme qu'un changement avait reduit ou simplifie quelque chose, trois fois la mesure disait le contraire. Regle desormais mecanique - toute affirmation structurelle porte son `wc -l` ou son `--numstat` dans la meme phrase, sinon elle ne s'ecrit pas.
This commit is contained in:
@@ -40,6 +40,6 @@ Three rules follow, and all three are load-bearing:
|
||||
2. **An empty document is a SUCCESS holding zero objects.** The repair for (1) must never be bought by making a real emptiness into an error; that only moves the lie. An empty document, an empty scope, a document nobody opened an inbox on, a document in a public store that exposes no key - each is an answer, and each stays one.
|
||||
3. **The unsynced/empty collision is closed by the barrier, and where the barrier was not crossed the read says so rather than answering.** Crossing it is what makes a zero-row answer mean something (`emulated-verifier/open-repo.ts`, which keeps `synced` and `timed-out` deliberately apart). A reactive read over documents it NAMES consults that distinction and stays PENDING when the barrier was not reached - "I have no authoritative answer" rather than "there is nothing". Turning it into a rejection would be inventing a third outcome the engine does not have, and answering a success would be the collapse this whole leaf is about.
|
||||
|
||||
**What an application can see of this, exactly.** `useShapeQuery` folds it into its own states, and that is the only published channel: a named scope whose barrier was not crossed does not reach `isSuccess`. `inbox.readSyncedForDocument` is the same guarantee on the inbox path. `getSyncState` is INTERNAL and is deliberately not published - this leaf offered it until 2026-09-24, which was a pointer at something no caller can import. It stays internal because it has no counterpart upstream at any level: publishing it would hand an application a polyfill-era symbol to unlearn at migration, on a surface that is busy removing exactly those. The consequence to state plainly rather than paper over: a caller using the anchored `docs.sparqlQuery` directly gets zero rows for an unsynced document and has **no published way to tell that from an empty one** - that is the collapse upstream has too, and it is why the reactive read is the one that carries the distinction.
|
||||
**What an application can see of this, exactly.** `useShapeQuery` folds it into its own states, and that is the only published channel: a named scope whose barrier was not crossed does not reach `isSuccess` - **within one ordinary session**. Two situations break it, both known defects and both carried as acceptance tests by `T01.m` ("there must be one answer to whether a document is open"): a second `configure(...)`, which tears down the subscription layer without telling the open registry, and a broker refusing a subscription after this package has stopped waiting. In both, a document recorded as open is not, and the read answers an empty success. The REACHABILITY half is unaffected. `inbox.readSyncedForDocument` is the same guarantee on the inbox path. `getSyncState` is INTERNAL and is deliberately not published - this leaf offered it until 2026-09-24, which was a pointer at something no caller can import. It stays internal because it has no counterpart upstream at any level: publishing it would hand an application a polyfill-era symbol to unlearn at migration, on a surface that is busy removing exactly those. The consequence to state plainly rather than paper over: a caller using the anchored `docs.sparqlQuery` directly gets zero rows for an unsynced document and has **no published way to tell that from an empty one** - that is the collapse upstream has too, and it is why the reactive read is the one that carries the distinction.
|
||||
|
||||
Related: `knowledge_what-a-read-scope-is-upstream` (what a read request can SAY, including the `[]` that means the empty set and the `[]` that means no filtering), and `polyfill-surface/contract_polyfill-surface` `## Guarantees` for the caller-facing form of all of this.
|
||||
|
||||
Reference in New Issue
Block a user