docs+refactor(client): fidelity pass — id identity, drop connections, no faux-login, accurate NextGraph framing
Align the polyfill's surface and docs with the verified NextGraph reality and
remove application-level concepts:
- Identity is an ID, not a username: AccountRecord.id, shim predicate shim:id,
normalizeId; accounts core becomes IdentityStore (set/clear/get) — the faux
login/logout framing is gone (identity is set at wallet-import time).
- Relationship/connection is an application concept, not a platform primitive
(NextGraph has no bilateral-connection primitive: grantee is unpersisted
scaffolding, cap-send is unimplemented). Remove connections.ts; caps exposes
only a directed grantRead(doc, granteeId) + a read-only protectedDocsOf(owner).
Delete the now-dead isolation.ts social-visibility axis.
- Inbox docs: NextGraph has no separate curator — the recipient's own verifier
unseals and applies each queued sealed message inline (process_inbox);
inbox_post_link is a proposed/future API. Stop attributing the emulated
curator to the platform.
- Read isolation reframed around the outcome: no cap -> empty union read;
targeted read of an unheld repo -> RepoNotFound; cap introspection
(canRead/governsRead) is emulation-only with no NextGraph API behind it.
- read-model.md corrected: the listing path is per-doc ANCHORED default-graph
queries, never the anchorless GRAPH ?g union (that is O(wallet)); the probe
section no longer claims the opposite.
- README recap table restructured (target | current NextGraph status | current
emulation); INDEX_ACCOUNT documented as reservedAccount("index") in the
sentinel namespace; de-domained generic-layer comments; softened tone.
Consumer application (Festipod) rewired separately to own the relationship
concept and feed the lib an id. Lib gates: bun test 83 pass / 0 fail, tsc clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+37
-34
@@ -1,9 +1,8 @@
|
||||
# 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.
|
||||
The whole point of this library: the consumer application already writes SDK-shaped
|
||||
code, so when NextGraph ships cross-wallet reads, capabilities and inboxes, only this
|
||||
lib changes. The consumer application's code does not change. This is the checklist.
|
||||
|
||||
## Guiding invariant
|
||||
|
||||
@@ -17,18 +16,19 @@ has no clear target image, that is a drift signal (see
|
||||
### 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.
|
||||
documents. The directed `grantRead(doc, granteeId)` maps to a native per-document
|
||||
ReadCap issued to that identity. 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**
|
||||
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
|
||||
- `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`.
|
||||
@@ -36,48 +36,51 @@ in the shim (see the two-axes section in [`simulation.md`](./simulation.md)).
|
||||
`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
|
||||
- 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.
|
||||
surface facing the consumer application (`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:
|
||||
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
|
||||
### 4. Real inbox → drop the in-lib read emulation
|
||||
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.
|
||||
document) with the native `inbox_post_link` (proposed/future). On the read side the
|
||||
recipient's own verifier unseals each queued sealed message and applies it inline
|
||||
when it processes its inbox — there is no separate curator to build; the in-lib read
|
||||
emulation simply goes away (see the deferred global-index note in the top-level
|
||||
README and [`decisions/discovery-model.md`](./decisions/discovery-model.md)). 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
|
||||
### 5. Retire the identity store → real per-user login
|
||||
Remove `accounts.ts` (the `IdentityStore` that persists the identity id in
|
||||
`localStorage`) 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.
|
||||
`isolation.ts` (application-visibility scaffold) disappears against a
|
||||
different piece of infra than the caps: real per-account wallets, and the
|
||||
relationship concept the consumer application owns. 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
|
||||
The consumer application 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(...)` /
|
||||
no consumer code changes. The one non-SDK call — `configure(...)` /
|
||||
`@ng-eventually/client/polyfill` — is deleted. The lib itself disappears.
|
||||
|
||||
## What does NOT change
|
||||
## 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.
|
||||
The consumer application's code. Shapes, screens, the *acts* of granting
|
||||
access, entity→scope mapping, the relationship 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.
|
||||
|
||||
Reference in New Issue
Block a user