docs: own the current-NextGraph-state knowledge + boundary (lib side)

This library presents a mature-NextGraph SDK face to consumers while
compensating for the current SDK's gaps via a shared-wallet simulation. It
therefore OWNS all current-state + simulation knowledge — moved here out of the
Festipod app repo, which must treat this library as a finished SDK.

New docs/:
- nextgraph-current-state.md — what the current SDK/broker do and don't expose
  (5 store types, document=repo, per-document ReadCap, inbox not exposed, iframe
  RPC proxy, mono-user/no-global-data, wallet import constraint). Keeps the
  nextgraph-rs source pointers.
- simulation.md — how the lib emulates the mature behaviour on one shared wallet
  (shim, store!=document two axes, docCreate→private store, RepoNotFound scope
  rule, @ng-org double-proxy DataCloneError, emulated ReadCap/inbox/curator).
- decisions/ — the current-SDK ADRs (private-store-nuri-scope, sparql-delete,
  shared-wallet-login, discovery mechanism).
- fork-inbox-fallback.md — the Rust-patch/self-host route not taken.
- migration-guide.md — the checklist for when real NextGraph matures.

README: boundary framing from the lib's side + docs/ index; replaced the stale
"scaffold/stubbed" status with the actually-implemented mechanisms per source.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-07-03 23:23:23 +02:00
parent d804a436d7
commit bea9f51d91
9 changed files with 1021 additions and 4 deletions
+83
View File
@@ -0,0 +1,83 @@
# Migration guide — when real NextGraph matures
The whole point of this library: the consumer already writes SDK-shaped code, so
when NextGraph ships cross-wallet reads, capabilities and inboxes, **only this lib
changes**. The consumer's application code does **not** change. This is the
checklist.
## Guiding invariant
Every emulated piece has a 1:1 image in the real infra. Migration = swap the
emulation for the real primitive, remove the scaffold. If a piece of the emulation
has no clear target image, that is a drift signal (see
[`simulation.md`](./simulation.md)).
## Checklist
### 1. Emulated ReadCaps → real capabilities
Translate the per-document `CapRegistry` (`caps.ts`) into real NextGraph caps: the
broker/verifier enforces them, and `useShape` already returns only authorized
documents. The read filter (`read-filter.ts`) and the write guard (`ng-proxy.ts`
`sparql_update` override) are then **dead code** — remove them. The access unit is
already the document (`@graph`), matching the native per-repo cap model, so this is
a data step, not a reshape.
### 2. Place documents in real native stores
Today `docCreate(..., undefined)` writes every document into the shared wallet's
**private** store, and the `public|protected|private` scope is a **logical label**
in the shim (see the two-axes section in [`simulation.md`](./simulation.md)).
- **`doc_create` cannot target a non-private native store today** — verified:
`StoreRepo` is **not JS-constructible** from the SDK, so there is no way to pass
a public/protected store as the create destination (`docCreate`'s trailing
`store` arg is left `undefined` → private store). The private store works only
because it opens without `RepoNotFound`.
- When the SDK lets you construct/target a native store, the migration adds a
`getNativeStore(scope)`-style resolver returning the real store to pass as the
`docCreate` destination, so the logical scope label becomes a real store
placement. (No such helper exists yet — it is blocked on the SDK gap above.)
- At that point `store-registry.ts` maps `(account, scope)` to the user's **real
store NURI** instead of a document in the shared wallet; the per-scope index
document (the store-container emulation) is replaced by the store itself. The
consumer-facing surface (`createEntityDoc`, `listEntityDocs`, resolvers) is
designed to survive that swap unchanged.
### 3. Drop the resolver / shim
The `sharedWalletShim` (account → 3 scope-document NURIs, RDF in the private store)
has **no target equivalent** — the target has no central directory. Remove it:
`store-registry.ts`, `configureStoreRegistry`, the shim SPARQL. Cross-wallet reads
replace the fan-out; per-user wallets replace the shared one.
### 4. Real inbox → drop the emulated curator
Replace the emulated `inbox.ts` deposit (`docs.sparqlUpdate` into a shared-wallet
document) with the native `inbox_post_link`, and move `read`/`materialize`/`watch`
to a **separate curator package** (the deferred global-index curator — see the
top-level README and [`decisions/discovery-model.md`](./decisions/discovery-model.md)).
The in-client read side goes away. The single global index replaces the
cross-account fan-out.
### 5. Faux login → real per-user login
Remove `accounts.ts` (the username `localStorage` faux login) and the app-level
"Connexion" screen. The technical broker gate **becomes** the real per-user login
(see [`decisions/shared-wallet-login-flow.md`](./decisions/shared-wallet-login-flow.md)).
The flow shape ("broker redirect → app") does not change.
### 6. Drop the isolation scaffold
`isolation.ts` (application social-visibility filter) disappears against a
different piece of infra than the caps: real per-account wallets + a real
per-account social graph. Distinct axis from ReadCaps — remove independently.
### 7. Remove the build alias — the client becomes the real SDK
The consumer imports `@ng-org/web` / `@ng-org/orm` resolved to this lib via a
**build alias** during the polyfill period. Removing the alias makes those imports
resolve to the real SDK — the `ng`/`useShape`/`inbox` surface is SDK-identical, so
**no consumer code changes**. The one non-SDK call — `configure(...)` /
`@ng-eventually/client/polyfill` — is deleted. The lib itself disappears.
## What does NOT change
**The consumer's application code.** Shapes, screens, the *acts* of granting
access, entity→scope mapping, the connection graph — all injected, all untouched.
Migration is entirely inside this library plus removing the alias + the bootstrap
call. That asymmetry — a mature SDK face outward, all compensation inward — is the
library's reason to exist.