Files
ng-eventually/docs/decisions/private-store-nuri-scope.md
T
Sylvain Duchesne 737729c9ce refactor: le paquet s'appelle polyfill, « SDK » désigne celui de NextGraph
Le nom @ng-eventually/sdk entrait en collision avec le SDK de NextGraph, dont
ce paquet est justement un polyfill. Impossible d'écrire « le SDK » sans lever
l'ambiguïté à chaque phrase — et le contrat publié, lu par une application,
était le pire endroit pour laisser traîner ça.

packages/sdk → packages/polyfill, @ng-eventually/sdk → @ng-eventually/polyfill,
contract_sdk-surface → contract_polyfill-surface, e2e/sdk-entry.ts →
e2e/polyfill-entry.ts, docs/sdk-reference.md → docs/polyfill-reference.md.

Les occurrences de « SDK » qui désignent celui de NextGraph restent intactes,
y compris les chemins dans nextgraph-rs (sdk/js/orm, sdk/js/web). Le tri s'est
fait occurrence par occurrence, pas par substitution.

Le contrat énonce désormais son identité en une phrase : « This package is a
polyfill of NextGraph's SDK. »
2026-08-10 17:14:25 +02:00

60 lines
3.1 KiB
Markdown

# ADR — Use a store NURI as the `useShape` scope AND `@graph`
**Date:** 2026-03-17 · **Status:** Accepted (partially superseded — see below).
Historical decision, ported into this lib because the *insight* still governs how
the shim opens repos. Original context: the consuming app.
> **Partially superseded (2026-07-03).** The private-store-only scope was replaced
> for shareable domain entities: they are now scoped AND written to the
> **protected** store (`did:ng:${protected_store_id}`), verified to open without
> `RepoNotFound`. **The central insight of this ADR still holds** and now applies
> to **both** stores: you must open the repo via the store's NURI
> or you get `RepoNotFound`. *(How it is opened has since changed — see the note
> under Decision.)*
## Context
Loading test data updated the in-memory ORM signals (immediate UI) but produced
`RepoNotFound` on `doc_create` and `orm_frontend_update`. Data vanished on reload
because the SPARQL writes never reached the broker: the verifier's `self.repos`
HashMap did not contain the store's repo → `resolve_target()` failed.
## Options considered
### A — `did:ng:i` scope + `doc_create` for `@graph`
`did:ng:i` is documented as a subscription scope; `doc_create` returns a real
NURI. **Against:** `did:ng:i` goes through `NuriTargetV0::UserSite`, which does
NOT open individual repos; `doc_create` calls `resolve_target(PrivateStore)`,
which requires the repo already in `self.repos` → fails; needs complex retry/timing.
### B — the store NURI as scope AND `@graph` (chosen)
Exact copy of the working `expense-tracker-rdf` example: `orm_start_graph` with
the store's NURI opens the repo in `self.repos`; subsequent `orm_frontend_update`
finds it. Simple, no retry. **Against:** slightly less flexible than `did:ng:i`
(scoped to one store); requires passing the session down to the ORM hook.
### C — `did:ng:i` scope + reuse an existing entity's `@graph`
Works for users who already have data. **Against:** fails for empty wallets (no
entity to reuse) → falls back to `doc_create` and the same `RepoNotFound`.
## Decision
**Option B**: use the store NURI as both the `useShape` scope AND the write
`@graph`, exactly like `expense-tracker-rdf`. This is why this lib's shim opens the
store repo before writing, and why **`did:ng:i` must never be used as a scope** (it
breaks writes with `RepoNotFound`). See the scope rule in
[`../simulation.md`](../simulation.md).
*The decision stands; the mechanism named in it has been replaced.* Opening was
`orm_start_graph` when this was written. It is now `ensureRepoOpen``doc_subscribe`
plus a wait for the first `State` (`packages/polyfill/src/emulated-verifier/open-repo.ts:167`) — after
`orm_start_graph` was found to hang on a fan-out (`subscribe.ts:28,181`). What must be
read here is the invariant *"open the repo, by its store NURI, before writing"*, not the
call that used to implement it.
## Consequences
- **Positive:** immediate writes after connect (no retry); persistence across
reload; aligned with the official examples.
- **Risk:** if NextGraph changes the store's open behaviour, this breaks.