docs: le contrat passe en 1.0.0-dev.9, et ce qu'une lecture echouee repond est consigne

Majeur : trois appels existants se resserrent. `useShapeQuery` publie `isError`
pour un document NOMME qu'il ne peut pas lire, la ou il rendait `isSuccess` avec
`data: []` - la seule image que cette surface reserve a « ce scope ne contient
rien ». `inbox.postToDocument`, `readForDocument` et `readSyncedForDocument`
rejettent la ou elles annoncaient « pas d'inbox ». Rien de ce qui etait deja une
reponse ne bouge : un document vide, `graphs: []`, un document sans inbox, un
document public qui n'expose aucune cle.

Deux non-garanties corrigees parce que le changement les rend fausses : « aucune
des deux lectures par forme ne va chercher la cle d'un store public » ne vaut
plus que pour `useShape` et pour `did:ng:i`, et le pending eternel d'un demarrage
refuse se referme sur le cas nomme.

Nouveau `knowledge_what-a-failed-read-answers-upstream` : ce que la cible repond
pour un document injoignable, non synchronise ou vide, et les deux collisions que
l'appelant ne peut pas demeler - « n'existe pas » contre « pas connu de moi »
d'un cote, « non synchronise » contre « vraiment vide » de l'autre. C'est le fait
durable qui justifie la direction prise, et il vaut quel que soit le remede.

`docs/internal-contract.md`, section open-repo seulement : numeros de ligne,
`ensurePhysicalRepoOpen` qui n'a jamais ete un export de ce module,
`ensureReposOpen` supprime, `openRepoUnguarded` absent, et le second parametre de
`ensureRepoOpen`. Le reste du document porte une derive du meme age, laissee.
This commit is contained in:
Sylvain Duchesne
2026-09-21 15:09:50 +02:00
parent 75313f75a2
commit b0eec7b4dc
11 changed files with 108 additions and 38 deletions
+1 -1
View File
@@ -259,7 +259,7 @@ export function useShapeQuery<T extends BaseType = BaseType>(
**What it reads THROUGH, since `1.0.0-dev.6`: the SDK's own shape query.** `RdfOrmSubscription.getOrCreate(shapeType, scope)`, injected at `configure` as `ormSubscription` (§ 1). Four steps went with the change and they were one mechanism: resolving the logical scope to a document set (`listMyEntityDocs`), opening those documents through `ensureReposOpen` for a sync barrier, an anchored read over each, and filtering the result by the shape's `@type` IRI. All four existed because the parameter had to be TRANSLATED; once it is upstream's own `Scope`, the question goes to the thing that answers it, and `graphs` / `subjects` / `did:ng:i` are read by the engine literally. It does NOT delegate to the SDK's `useShape` — that is React's hook and its `DeepSignalSet` cannot carry the request state, which is the whole reason this symbol exists. What is taken from the SDK is the QUERY; the observable, the snapshot and the state tracking stay here, and so does the capability filter (`emulated-verifier/read-filter.ts`, applied per `@graph` on what comes back, exactly where § 4 applies it).
**Consequences a caller sees.** `data` items are now the SHAPE's own objects — `@id`, `@graph` and the shape's readable predicates — where they were the property bags the then-published `readUnion` returned; `shapeType` is typed `ShapeType<T>` instead of `unknown`, so `T` follows the shape and the snapshot is typed without a cast; and the read no longer opens a document of its own, so a public-store document whose cap has not been fetched by some other read does not appear until it has been (the same limit § 4 carries, and the same `CapRegistry.onChange` recovery).
**Consequences a caller sees.** `data` items are now the SHAPE's own objects — `@id`, `@graph` and the shape's readable predicates — where they were the property bags the then-published `readUnion` returned; `shapeType` is typed `ShapeType<T>` instead of `unknown`, so `T` follows the shape and the snapshot is typed without a cast; and the read no longer opens a document of its own, so a public-store document whose cap has not been fetched by some other read does not appear until it has been (the same limit § 4 carries, and the same `CapRegistry.onChange` recovery). *(Corrected 2026-09-21, `1.0.0-dev.9`: that last clause now holds only for `graphs: "did:ng:i"`. A document NAMED in `scope.graphs` is put through the same public-store fetch and sync barrier `docs.sparqlQuery` applies to its anchor, before the query opens - and is refused out loud rather than silently emptied when its cap cannot be obtained.)*
**The name and the scope, since `1.0.0-dev.5`.** It was `watchShape(shapeType, "public" | "protected" | "private")`. `watchShape` has ZERO occurrences in `nextgraph-rs` and spends `watch`, a verb the ORM already spends on signal observation; the target's own name is `useShapeQuery`, announced by NextGraph's developers and on record in `.project/rules/nextgraph/surface-mirrors-the-sdk.md`, which is what the symbol's `announced-not-written` annotation cites. The three literals were this package's own and named the scope of a READ, which the SDK answers on two axes instead: `graphs` (one document's graph per entry, `did:ng:i` or `""` for the whole dataset, `[]` or `undefined` for no objects at all) and `subjects`. Nothing is translated any more: the `Scope` object a caller writes is the object the SDK receives.