d337fcb265be8631d278042f1accd5aed008e6c5
The soul was hard-deleting engram nodes: memory/delete and node/delete called engram_forget (frees the node and drops its incident edges), and node/update created a replacement then forgot the original with no link back. That violates the day-one rule that engram nodes are immutable — memory could be silently, irrecoverably destroyed via the API. Convert the three destructive handlers to Will's immutability semantics, mirroring the pattern memory/update and knowledge evolve/promote already use: - node/update -> create the new node, wire a "supersedes" edge new->old, KEEP the original. No engram_forget. (Was: create + forget old, no edge.) - memory/delete and node/delete -> TOMBSTONE: keep the node AND its edges, create a Tombstone marker node (content = target id, label "tombstone:<id>") wired with a "tombstones" edge. Never engram_forget. Default bounded list reads (handle_api_list_typed / the memory list) hide tombstoned nodes and the markers; ?include_deleted=1 returns them, and internal cognition + /api/graph/nodes still traverse them. memory/update was already correct and is unchanged. Full-graph hiding on /api/graph/nodes is deliberately NOT done at the el layer: json_array_get is O(index), so filtering that endpoint (called with limit up to 999999) would be O(n^2). That hide needs a runtime scan filter and is a separate follow-up; nodes there remain traversable, tagged status:deleted via the marker edge. Regenerated dist/soul.c from these sources (flat single-TU amalgamation, compiled under a 3GB physical-RSS watchdog, peak ~32MB). Verified with scripts/verify-soul-contract.sh in neuron-ui: PRESENCE passes (all 27 routes) and IMMUTABILITY passes (all four mutation routes KEPT; deletes produce a real tombstone marker and hide from the default list).
Languages
TypeScript
75.1%
MDX
21.5%
CSS
2.9%
HTML
0.2%
JavaScript
0.1%