diff --git a/docs/nextgraph-current-state.md b/docs/nextgraph-current-state.md index c61d874..256399f 100644 --- a/docs/nextgraph-current-state.md +++ b/docs/nextgraph-current-state.md @@ -470,3 +470,50 @@ logout is exposed (`ng.session_stop()`, `ng.user_disconnect()`, redirect afterwards. This lib's identity store sidesteps all of it — the identity id is set at wallet-import time and relayed to the lib, without a separate login; see the identity store in [`simulation.md`](./simulation.md). + +## Known open issues (section added 2026-07-18) + +Live limitations observed against the current core/SDK, each with its epistemic +status. **None is treated.** The status labels below are load-bearing — do not +upgrade an OPEN / UNDETERMINED / HYPOTHESIS item to "confirmed" or "fixed" +without new evidence. + +### Write loss on socket death (`SerializationError`) — symptom VERIFIED, mechanism UNSETTLED, OPEN / untreated + +A write made just before an idle period / spontaneous socket death +(`SOCKET IS CLOSED Some(Left(SerializationError))`) can be **silently lost**: +the entity is absent on reconnection while the account survives. Reconnection is +an unimplemented `// TODO` stub in the core (`broker.rs`, ≈ `1051-1076`); +`disconnections_subscribe` DOES fire on the failure but nothing — neither this +polyfill nor the consumer app — consumes it; and there is **no +write-durability-confirmation API** a caller could `await`. Full post-mortem +(logs, causal chain, correction leads, none arbitrated): +[`incidents/2026-07-14-write-loss-on-disconnect.md`](./incidents/2026-07-14-write-loss-on-disconnect.md). + +### Cold-start read does not rehydrate the owner's own scope from the broker — symptom VERIFIED, root cause UNDETERMINED, OPEN / untreated + +Decisive test (2026-07-14): a genuinely no-local cold reader — fresh +non-persistent browser context, SAME wallet + account — reads **0** of the +owner's own scope from the broker. The previously "passing" reconnect test was +FALSE-GREEN: it read the owner's repos from the persistent profile's LOCAL +IndexedDB, so it never proved broker durability. It is UNDETERMINED whether +**(i)** the write never durably reached the broker, or **(ii)** the write IS on +the broker but a fresh session cannot re-open the owner's own scope docs (a +cold-open / rehydration limitation) — both collapse to the same 0-read in this +setup. Next step (NOT done): disambiguate (i) vs (ii) with an independent warm / +second-identity read of the same doc. The same (i)/(ii) reserve is carried in +[`incidents/2026-07-14-write-loss-on-disconnect.md`](./incidents/2026-07-14-write-loss-on-disconnect.md) +(§ *Portée & non-reproduit*), whose Firefox case leans (i) — this cold-reader +signature is distinct (no socket death) and does not settle it. + +### Reactive subscription may not echo the writer's OWN local commit — HYPOTHESIS (high-confidence), confirmation in progress (2026-07-18), NOT confirmed, NOT fixed + +When a client does a local `sparqlUpdate` on a doc it is itself subscribed to +(`subscribeDoc`/`doc_subscribe`), the subscription callback appears NOT to fire +for its own local commit in the same session, so the polyfill's reactive re-read +chain never runs and consumers keep a stale value until the next connection +delivers a fresh initial `State`. REMOTE commits DO push correctly (verified: +cross-browser reactive update works). Verdict pending a live instrumented run. +Full write-up (suspect link, instrumentation, planned polyfill-side fix): +[`../packages/client/docs/sdk-reference.md`](../packages/client/docs/sdk-reference.md) +§ *Current emulation status*. diff --git a/packages/client/docs/sdk-reference.md b/packages/client/docs/sdk-reference.md index 47fed41..2448cf9 100644 --- a/packages/client/docs/sdk-reference.md +++ b/packages/client/docs/sdk-reference.md @@ -244,7 +244,7 @@ helpers live in the consumer app; the SDK exposes the generic reactive/by-need r > [`read-model.md`](../../../docs/read-model.md), > [`simulation.md`](../../../docs/simulation.md). -Today, on a single shared wallet emulating the mature platform, three gaps diverge +Today, on a single shared wallet emulating the mature platform, four gaps diverge from the reactive contract: 1. **Entity-list reads are one-shot, not reactive.** The reactive ORM cannot be used @@ -279,5 +279,38 @@ from the reactive contract: queryable. At the multi-store migration, opening a repo by cap becomes a native broker sync and the anchored read is unchanged. +4. **The subscription may not echo the writer's OWN local commit — HYPOTHESIS + (high-confidence), confirmation in progress (2026-07-18); NOT confirmed, NOT + fixed.** Unlike gaps 1–3 (designed emulation stopgaps), this is a suspected + defect in the polyfill's own reactive assembly. When a client does a local + `sparqlUpdate` on a doc it is itself subscribed to (`subscribeDoc` / + `ng.doc_subscribe`), the subscription callback appears NOT to fire for its OWN + local commit in the same session — so the reactive re-read chain + ([`../src/watch-shape.ts`](../src/watch-shape.ts) `watchShape` → `reread` → + [`../src/read-model.ts`](../src/read-model.ts) `readUnion`) never runs, and + consumers keep the STALE value until the next connection delivers a fresh + initial `State`. **Remote** commits DO push correctly (verified: cross-browser + reactive update works). A code review verified the consumer wiring is correct, + the doc IS in the subscribed set, and a triggered re-read WOULD return the new + value — leaving the self-commit echo as the only suspect link. That link is + **INFERRED**, not observed: the real `ng.doc_subscribe` runtime is not readable + from source, and [`../src/subscribe.ts`](../src/subscribe.ts)'s own doc-comment + CLAIMS local writes push a `Patch` — contradicted by the observation. (This + also sits in tension with § *The reactivity model* above, which documents the + target contract — one commit, every subscriber pushed, local or remote.) The + requirement at stake is multi-user: a value change (e.g. a participant count) + must propagate reactively to ALL viewers — other viewers (remote push, which + works) AND the writer's own view (this suspect link). **Treatment (PLANNED, + not done):** confirm first via the temporary instrumentation just added + ([`../src/subscribe.ts`](../src/subscribe.ts) ≈`:119` logs + `doc_subscribe FIRE (State|Patch)`; + [`../src/watch-shape.ts`](../src/watch-shape.ts) ≈`:341` logs + `reread TRIGGER by ` — line numbers volatile, grep the log strings); + then, IF confirmed, fix **polyfill-side** — a + local commit should notify the doc's active `subscribeDoc` callbacks. + Consumers must not compensate. Short entry: + [`nextgraph-current-state.md`](../../../docs/nextgraph-current-state.md) § + *Known open issues*. + When these gaps close, the read path collapses to the reference above: `useShape` everywhere, push everywhere, no polling and no re-query-on-signal assembly.