Supersede and versioning
How a writer that knows it is updating a fact declares the replacement explicitly, and how superseded memories form version history.
Facts evolve: a deploy window moves, a plan becomes an implementation, a
diagnosis is refined into a root cause. In zero-memory the writer that knows
it is updating a fact says so at write time: remember accepts a declared
supersede, which atomically stores the new memory and retires the old one —
no duplicate, no conflict queue, and a clean version chain behind every
current fact.
Why declare instead of detect
Without a declaration, an update lands as a second memory about the same topic, and resolution falls to the automatic hygiene pipeline: a small judge model compares the pair and, when its confidence clears the auto-resolve threshold, retires the older one. That safety net works, but for one common class it is backwards — same-rank refinement, where two authoritative memories describe one evolving topic. The judge's confidence on these pairs tends to land just below the auto-resolve bar, so they queue up for a human.
The absurdity: a strong writing agent that knows it is updating a fact defers the decision to a weaker probabilistic judge, which then misses the threshold. The writer has ground truth and intent; the declaration hands the decision to the party that has both. In practice most queued refinement pairs are written by the very agent that already knows about the replacement — see queue throughput.
How it works
The declaration rides the existing links vocabulary — one syntax for one
intent. Arguments to the remember tool:
{
"content": "Deploy window is Friday 14:00 UTC (moved from Monday).",
"kind": "fact",
"links": [{ "type": "supersedes", "dst": "mem_..." }]
}On a write that declares supersedes links, the server, in one operation:
- stores the new memory as usual;
- retires each named target: sets its
superseded_byto the new memory's id and marks it invalidated — the same reversible lifecycle used byforget. Nothing is deleted; the store is forward-only and the retirement can be undone withrestore_memory; - records the
supersedeslink (new → old) so the version chain is explicit; - skips hygiene for this pair — the intent is declared, so no judge runs and no conflict is queued.
Guardrails:
- Ownership and liveness are validated. Each target is handled best-effort: a dead, missing, or self-referencing target is skipped with a log and the write still succeeds. A target that is invisible to you under row-level security (someone else's private memory) rejects the link and fails the whole write.
- Capped. At most 10 declared supersedes per write — an update names its predecessors, it does not mass-retire.
- Authoritative writers only. The background watcher, whose captures are provisional (see Provenance), cannot declare supersedes; the declaration is reserved for in-band writers with ground truth.
- Closes open loops. Superseding a
taskoropen-questionalso closes the loop (see Open loops). - Composes with dedup. When an incoming write is absorbed into an existing near-duplicate, the absorbing memory becomes the successor for any declared targets.
How to use it
The workflow leans on a habit agents should already have: recall before writing.
recallthe topic before storing — the stale version usually surfaces.- Recognize that the new statement replaces it, not complements it.
- Write the new memory with a
supersedeslink naming the old id.
The server also meets the writer halfway: a remember that did not
declare anything returns similar_existing — the live same-owner memories
nearest to what was just written, ranked by distance and capped at ten, each
with its age and a content preview, filtered so memories from a different
project never appear — plus a hint telling the agent what to do about them.
A writer that skipped the recall still sees, in the write's own response, the
predecessor it probably just rewrote, and can follow up with a declared
supersede immediately.
The list is bounded by rank rather than by a similarity window, and that is a deliberate correction. A window has two edges and both of them hid real predecessors: a precision floor high enough to stay quiet also discards roughly two fifths of the memories a write genuinely replaces, and an upper edge — added on the assumption that anything that similar is a duplicate the server collapses on its own — hid another quarter, because that automatic collapse only fires for a near-verbatim restatement written in the same session. The most similar memory in the store, written last month in another conversation, is exactly what a rewrite replaces, and it was the one thing the window could not show. Ranking has no second edge, and the cap keeps the reply a glance rather than a reading list. Candidates may come from your personal scope as well as the project you are writing into: the portable layer holds operating truth that project work routinely supersedes.
If no supersede is declared — the writer did not recall, or the fact is genuinely new — nothing degrades: the write goes through the normal dedup cascade and hygiene pipeline. Declaration is an optimization on top of the safety net, not a replacement for it.
Superseded pairs do not appear in the conflict review queue — an intentional
update is not a dispute. They appear as version history: the chain of
supersedes links behind a current fact, browsed rather than adjudicated.
The dashboard feed keeps that history out of the way — its default
lifecycle filter hides superseded versions, and a memory's detail page shows
the full chain.

Design notes
- Rejected: lowering the judge's auto-resolve bar for authoritative pairs. The judge often labels genuinely complementary facts as supersedes; loosening the threshold risks silently losing distinguishable facts. An explicit declaration from the writer is safer than a bolder guess from the judge.
- Rejected: manual
recall→forget→remember. Already possible, but it is three calls, non-atomic, and leaves nosupersedeslink — the history disappears. The declaration makes the intent first-class and atomic. - Reversibility is preserved by construction. Because retirement uses the
same add-only lifecycle as
forget, a mistaken supersede is recoverable and the superseded content remains readable in history.