Files
ng-eventually/docs/decisions/sparql-delete-for-orm-objects.md
T
Sylvain Duchesne bea9f51d91 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>
2026-07-03 23:23:23 +02:00

62 lines
2.5 KiB
Markdown

# ADR — Use SPARQL DELETE (not ORM `ngSet.delete()`) to remove objects
**Date:** 2026-03-17 · **Status:** Accepted → Superseded (2026-06-15). Historical
decision, ported for the current-SDK behaviour it records. Original context: the
consuming app.
> **Superseded (2026-06-15).** The `ngSet.delete()` non-persistence bug that
> motivated this decision was largely fixed upstream in `@ng-org/orm`; deletion
> code went back to `ngSet.delete()`. Kept as arbitration memory — the CRDT
> conflict rule ("don't combine the two") **still holds**.
## Context
Removing an object from the NextGraph store: `DeepSignalSet.delete()` updates the
local reactive state (immediate UI) but **does not persist** to the broker — after
refresh the object reappears.
## Options considered
### A — ORM `ngSet.delete(item)`
Official API, instant local reactive update. **Against:** did not persist in
practice (`delete()` returned `true`, local set updated, object back after
refresh); `graph_orm_update` seemed to mishandle "remove" patches for top-level
set objects (likely engine bug); failed silently.
### B — `ng.sparql_update()` with SPARQL DELETE
`DELETE WHERE { GRAPH <graph> { <subject> ?p ?o } }` removes all the RDF triples.
**For:** persists (survives refresh); the broker confirms via a `GraphOrmUpdate`
`op: "remove"` that reactively removes the item from the ORM set; direct control.
**Against:** not instant (~50ms SPARQL round-trip + broker callback); must NOT be
combined with `ngSet.delete()`.
### C — both together
**Does not work:** the ORM `.delete()` patch and the SPARQL DELETE conflict at the
CRDT level → neither UI nor persistence.
## Decision
**Option B — SPARQL DELETE alone.** The broker returns a `GraphOrmUpdate`
`op: "remove"` that reactively removes the item from the ORM set (UI updates, just
not synchronously). **Do NOT** call `ngSet.delete()` alongside.
```ts
await ng.sparql_update(
session_id,
`DELETE WHERE { GRAPH <${partGraph}> { <${partId}> ?p ?o } }`,
partGraph,
);
```
This is the authoritative-delete pattern this lib's emulation relies on for inbox
deposits and shim graphs (an interpolated NURI/subject must pass through
`assertNuri`/`escapeLiteral` first — see SPARQL hardening in
[`../simulation.md`](../simulation.md)).
## Consequences
- **Positive:** deletion persists; single source of truth (broker → ORM → UI).
- **Negative:** slight UI delay (~50ms); diverges from the ORM README examples.
- **Risk:** if `ng.sparql_update` changes, this breaks; revisit as `ngSet.delete()`
matures upstream.