Make engram deletes/updates immutable (tombstone + supersede) #82
Open
will.anderson
wants to merge 4 commits from
feat/immutable-engram-deletes into hotfix/elc-source-typos
pull from: feat/immutable-engram-deletes
merge into: :hotfix/elc-source-typos
:main
:hotfix/elc-source-typos
:fix/safety-contact-truncation
:fix/genesis-boot-crash
:fix/immutable-on-hotfix
:feat/bounded-persona-floor
:ci/rdynamic-http-handler
:ci/harden-gate-boot
:feat/neuron-dev-setup
:feat/immutable-engram-deletes
:feat/agent-phase1-soul
:salvage/elh-state-20260704
:hotfix/trackb-threat-to-others
:feat/soul-model-self-report
:feat/openai-format-providers
:feat/plan-mode-endpoint
:fix/operator-identity-home-resolution
:fix/wrapper-backlog-endpoints
:fix/list-typed-slice-offset
:feat/connectors-call-route
:fix/chat-vision-attachments
:fix/prevent-engram-corruption
:fix/emergency-regressions
:fix/session-continuity-hook
:fix/context-dedup-shared-ids
:fix/engram-float-parser
:improve/recall-context-format
:improve/recall-context-dedup
:improve/recall-cross-session-continuity
:improve/recall-emotional-recall
:improve/recall-activation-seed
:improve/recall-recall-completeness
:improve/recall-temporal-precision
:improve/recall-engram-scoring
:improve/recall-recall-reliability
:improve/recall-session-start-recall
:improve/reliability-engram-write
:improve/reliability-state-management
:improve/soul-memory-formation
:improve/safety-crisis-detection
:improve/reliability-route-error-recovery
:improve/reliability-llm-retry
:improve/reliability-session-boundary
:improve/reliability-safety-resilience
:improve/reliability-engram-connection
:improve/soul-routes-api
:improve/reliability-cross-session-affective
:propose/agent-workspace-root-read
:improve/reliability-conv-history
:improve/soul-strip
:improve/soul-chat-pipeline
:docs/conversation-retrieval-design
:propose/no-fake-tools-in-chat-mode
:fix/ci-soul-build-single-file
:fix/canonical-self-bridge
:feat/agent-tool-workspace-scope
:fix/agentic-tools-duplicate-web-search
:green/agentic-fixes
:feat/connectors-soul
:feat/layer-safety
:feat/layer-imprint
:feat/layer-stewardship
:test/layer-composition
:test/layer-safety
:test/layer-stewardship
:test/layer-imprint
:feat/memory-delete-update
:feat/native-web-search
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "feat/immutable-engram-deletes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Make the soul's engram
deleteandupdateroutes immutable, and regeneratedist/soul.c.Why
Three handlers were destroying engram nodes:
memory/delete,node/delete→engram_forget(frees the node and drops its incident edges)node/update→ created a replacement thenengram_forget'd the original, with no link backThat violates the day-one rule that engram nodes are immutable — API callers could silently, irrecoverably destroy memory.
memory/updatewas already correct (supersede-with-edge); the others were not.The fix (mirrors
memory/updateand knowledge evolve/promote)node/update→ create the new node, wire asupersedesedge new→old, keep the original. Noengram_forget.memory/delete+node/delete→ tombstone: keep the node and all its edges; create aTombstonemarker node (content = target id, labeltombstone:<id>) wired with atombstonesedge. Neverengram_forget. Default bounded list reads (handle_api_list_typed/ the memory list) hide tombstoned nodes and the markers;?include_deleted=1returns them, and internal cognition +/api/graph/nodesstill traverse them.Deliberately deferred (documented in code)
Full-graph hiding on
/api/graph/nodesis not done at the el layer:json_array_getis O(index), so filtering that endpoint (the app calls it withlimitup to 999999) would be O(n²). That hide needs a runtime scan filter (skip tombstoned inengram_scan_nodes_json) and is a separate follow-up. Tombstoned nodes remain present and traversable there, taggedstatus:deletedvia the marker edge.Regen + verification
dist/soul.cregenerated from these sources as a flat single-TU amalgamation, compiled under a 3GB physical-RSS watchdog (macOS ignoresulimit -v), peak ~32MB. Diff is exactlyneuron-api.el+dist/soul.c.hotfix/elc-source-typos(where the shippedsoul.c/ neuron-ui PR #144 came from) so the diff stays minimal.neuron-ui/scripts/verify-soul-contract.shagainst the freshly-built binary on a throwaway port:The stale/destructive binary fails the same gate (memory-delete / node-update / node-delete → DESTROYED), so the gate discriminates.
Never touched the live soul (:7770), engram (:8742),
~/.neuron, or the running :7799 sandbox — all build + test on throwaway paths/ports.Do not merge — going live is a controlled-deploy call.
Phase 1 tombstoned memory/delete + node/delete, but the generic forget path was still destructive. This routes every forget through the same tombstone semantics so nothing in the daemon can hard-delete an engram node anymore. Canonical helper: mem_tombstone (memory.el, imported first so every module can call it) — keep the node + its edges, record a Tombstone marker, never engram_forget. neuron-api's tombstone_node now delegates to it (single source of truth). Per-path before -> after: - memory.el `mem_forget` hard delete (engram_forget) -> tombstone. This alone fixes both callers: the /api/neuron/memory/forget route (handle_api_forget) and the cultivate op=="forget". - awareness.el autonomous `forget` action engram_forget -> mem_tombstone. The soul can no longer autonomously hard-delete a memory. - mcp-wrapper tool_forget was a FAKE no-op that returned {"ok","deleted"} without deleting OR tombstoning -> now routes to the soul's tombstoning /api/neuron/memory/delete; tool description fixed to say it supersedes/tombstones (recoverable), not "Remove a node". Left intentionally as hard deletes (internal GC / lifecycle, not user memory, all call engram_forget directly): session-summary replace (chat.el), mem_consolidate dedup (memory.el), session-start telemetry pruning (soul.el), session lifecycle (sessions.el). Regenerated both ship paths under a 3GB physical-RSS watchdog (peak ~32MB): dist/soul.c (single-TU amalgamation, macOS/Linux) and the per-module dist/{memory,awareness,neuron-api}.c (Windows/Linux build). Verified: no forget handler calls engram_forget; a forget leaves the node present + tombstone marker. Gate (neuron-ui verify-soul-contract.sh, new memory-forget row): PRESENCE + IMMUTABILITY PASS.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.