Files
ng-eventually/.tasks/doing/T01.b-what-the-orm-offers-for-writing-and-deleting.md
T

6.0 KiB

id, title, parent, depends_on, created, claimed_by, claimed_at, blocked
id title parent depends_on created claimed_by claimed_at blocked
T01.b What the ORM offers for writing and deleting, and what the three remaining symbols are T01
2026-09-16 claude-f93872b5 2026-09-16T15:25:00Z false

Description

Reconnaissance, not implementation. Piece 2 of the parent task rests on a fact nobody has established: upstream's shape for deletion. Specifying a wrapper before knowing it is how this project has invented before. This child establishes the facts and proposes the arbitrations; T01.e implements against its ## Result.

Read the target at the source. /home/sylvain/projects/nextgraph/nextgraph-rs is a sibling checkout, at 213338f6 when this was planned — the commit the existing knowledge leaves were read at. Record in the leaf you write the commit you actually read.

The three questions:

  1. Deletion. What does the target offer to delete an object? Starting facts, verified at planning: sdk/js/orm/src/connector/ holds getObjects.ts and insertObject.ts and no deletion file; sdk/js/orm/src/core.ts exports exactly initNg, ngSession, OrmSubscription, DiscreteOrmSubscription, insertObject, getObjects, plus getRaw / watch / effect re-exported from @ng-org/alien-deepsignals and the types. Run the cascade of .project/rules/nextgraph/no-divergence-from-nextgraph.md — level 3 first, then level 2 (sdk/js/lib-wasm, sdk/js/web), then the engine's model — and report which level answers, with symbols. A shape the target declares and constructs nowhere is declared-not-wired and is the strongest thing to align on; an absent implementation is not evidence the target will not have one, and must not be reported as one.
  2. getObjects and insertObject. Exact signature, parameters and return of each, precisely enough that a wrapper can be published at an identical signature without translating anything. docs/api-contract.md § 6 already records getObjects as level 3 VERIFIED (sdk/js/orm/src/connector/getObjects.ts:23) — check it rather than re-deriving it, and correct it if it has drifted.
  3. OrmSubscription, DiscreteOrmSubscription, ngSession. What each one is, what it hands the caller, and whether an application coding against this package needs it. Propose an arbitration for each — publish as-is / publish under what name / do not publish — with the evidence. Do not implement. Weigh it against the rule's own tell: a symbol that makes the caller handle what the target will never hand it (a document's key, a store id, its own identity) is a divergence even when upstream exports it.

Established facts — cite them, do not re-derive them from nextgraph-rs: .project/concepts/app-contract/knowledge_what-a-read-scope-is-upstream.md (the Scope type and its two axes; a graphs entry is one document's graph; did:ng:i means the whole local dataset with no permission narrowing; the graph filter is literal; OrmSubscription.readyPromise distinguishes not-ready from ready-and-empty at level 3 while the React useShape adapter drops it; OrmConfig's richness is real and unreachable), knowledge_what-an-iri-says-upstream.md, knowledge_what-an-inbox-is-upstream.md.

The problem being served is a rights hole, not a missing convenience. Today an application must import these straight from @ng-org/orm, and then receives every identity's data out of the shared wallet with nothing signalling it. The filter that closes it is makeReadFilteredView (packages/polyfill/src/emulated-verifier/read-filter.ts, annotated kind=aligned level=1 ref=engine/verifier/src/verifier.rs:load_repo_from_read_cap), applied per document on what comes back — where the target bounds it. For each candidate wrapper, report how that filter would have to apply, or why it cannot. A write path is the hard case: the filter is a read emulation, and packages/polyfill/src/surface/ng-proxy.ts already overrides sparql_update with an emulated write guard — read it before concluding.

Deliverable. A knowledge_ leaf under .project/concepts/app-contract/, written by invoking /concept document rather than by writing the file directly. Every claim points at a symbol, never a line number. The arbitration proposals and every unresolved question go in this task's ## Result, where T01.e will read them.

Out of scope: no edit under packages/, no contract edit, no version bump. If a fact you establish changes what the published contract says, name it in ## Result and leave the edit to the child that owns it.

Pass condition for this child (it changes no code, so the implementation gate does not apply): python3 ~/.claude/skills/concept/lint.py → 0 ERROR; the leaf names the commit it was read at; every target-side claim carries a symbol reference; each of the three questions has either an answer or an explicitly stated open question.

Resolved since planning (2026-09-16). Add one question: verify useShape LIVE against the real broker. bug_useshape-live-read-needs-a-newer-broker may be stale — the owner reports the deployed broker generally tracks NextGraph's source, and the rename landed 2026-01-16. Do not conclude from "generally": measure it. If it works, close the bug leaf and the blocker recorded in T01.d dissolves.

Progress

  • 2026-09-16T15:25Z — claimed. Baselines taken BEFORE any edit: bun test 397 pass / 0 fail; tsc -p packages/polyfill/tsconfig.json exit 0; tsc -p packages/polyfill/e2e/tsconfig.json exit 0; concept/lint.py 0 ERROR (13 WARNING). nextgraph-rs read at 213338f697df15afc086c042f4bab1bffd01aa04 (clean but for one untracked engine test fixture).
  • 2026-09-16T15:30Z — questions 1-3 settled by reading the target. Deletion answers at LEVEL 3 and is wired end to end (DeepSignalSet.delete -> OrmPatch{op:remove} -> graph_orm_update -> Verifier::orm_frontend_update -> SparqlBuilder::remove_object). Full chain recorded in the knowledge leaf.
  • 2026-09-16T15:30Z — question 4: e2e baseline run started (bun run test:e2e) before adding anything.

Result