Skip to content

feat(memory): thread_id + supersede action + upsert resurrection fix#379

Merged
velvetmonkey merged 2 commits into
mainfrom
feat/thread-identity-slice1
Jun 7, 2026
Merged

feat(memory): thread_id + supersede action + upsert resurrection fix#379
velvetmonkey merged 2 commits into
mainfrom
feat/thread-identity-slice1

Conversation

@velvetmonkey

Copy link
Copy Markdown
Owner

Plan

mega-monkey plan 73daa28f (thread-identity-resolution-loop), implementation plan v5 — slice 1a, the memory face. Council ×2 verdict: ship this face FIRST because every read path already filters superseded_by IS NULL (schema.ts:392; memory.ts get/search/list; brief.ts; entityHistory.ts) — the face closes the instant the column is populated.

What

  • v44 migration: memories.thread_id (indexed, nullable — correlation id minted by the engine threads registry) + supersede_reason audit column. Index lives in the migration block per the v42 boot-order rule.
  • memory(action:"supersede", thread_id|key, reason): idempotent tombstone. superseded_by = own id (self-pointer = tombstone-without-successor); already-superseded rows counted, not errored. Scope-gated: callers only close facts they can see (global + own agent scope) — never another agent's private facts. Removes memory:{key} graph edges (mirrors forget) so stale edges don't outlive the fact.
  • Upsert resurrection fix (found independently by two council seats at memory.ts:250): same-key store no longer resets superseded_by = NULL. Previously a routine cron re-store on a superseded key silently un-superseded it — the exact "resolved items resurface" bug class. Supersession preserved; thread_id only updates when explicitly provided; graph edges not resurrected; store response flags still_superseded.
  • store accepts thread_id.

No new read-filter work — that would duplicate the existing superseded_by filter.

Pairs with

velvetmonkey/mega-monkey#105 (threads registry + resolution ledger + engine-side applier calling this supersede action). Either side deploys independently: engine supersede pushes stay pending and drain once this lands.

Tests

10 new in memorySupersede.test.ts, including the release gate: superseded fact never resurfaces in get/search/list after supersede, including after a same-key cron re-store. tsc clean.

🤖 Generated with Claude Code

velvetmonkey and others added 2 commits June 7, 2026 13:56
Thread-identity slice 1a (mega-monkey plan 73daa28f v5). The memory face
of resolution-as-fan-out: every read path already filters
superseded_by IS NULL — this PR makes that column actually populated.

- v44 migration: memories.thread_id (indexed, nullable) +
  supersede_reason audit column; index in the migration block per the
  v42 boot-order rule
- memory(action="supersede", thread_id|key, reason): idempotent
  tombstone — superseded_by = own id (self-pointer = tombstone without
  successor), scope-gated (callers only close facts they can see),
  removes memory:{key} graph edges like forget does
- FIX upsert resurrection: same-key store no longer resets
  superseded_by = NULL — a routine cron re-store on a superseded key
  silently un-superseded it. Supersession is preserved; thread_id only
  updates when explicitly provided; graph edges stay removed
- store accepts thread_id; store response flags still_superseded

Tests: 10 new in memorySupersede.test.ts incl. the release gate
(cron re-store cannot resurrect).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e manifest

The supersede addition pushed the memory tool rawDescription to 489
chars (cap 360) and staled the embedding manifest descriptionHash —
the 4 full-matrix CI failures on #379. Trimmed to 355 keeping the
required "Returns"/"Does not" rewrite-completeness phrases; manifest
regenerated. tool-routing contract suite 41/41.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@velvetmonkey velvetmonkey merged commit 28c1c32 into main Jun 7, 2026
18 checks passed
@velvetmonkey velvetmonkey deleted the feat/thread-identity-slice1 branch June 7, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant