Concept · No. 024 · November 8, 2026
Agent memory that only appends will remember both answers
Long-term memory for agents is usually a vector store that keeps growing, and similarity search has no idea which of two contradictory facts is still true. The fix is to treat memories as dated claims that newer claims can retire.
The idea
Most agent memory starts the same way. Something worth keeping is said, a snippet is embedded and stored, and later the closest snippets are pulled back into the prompt. That works until a fact changes.
Similarity search ranks by closeness to the query. It does not rank by recency or validity. If the old fact and the new fact are both stored, both are close to the question, and the model has to guess which one wins. The old fact often ranks higher simply because it was mentioned more often.
The concept is supersession. Each memory is a claim about a subject and an attribute, with a time it was observed and a source. When a new claim arrives for the same subject and attribute, it closes the old one instead of sitting beside it. Retrieval then reads only claims that are currently valid.
An example
Take an assistant that handles billing questions for a customer account.
- Early in the year the customer says invoices go to
finance@. The write path extracts a claim: subjectaccount, attributeinvoice_email, valuefinance@, withobserved_atand the message id as source. - Months later they say invoices should now go to
ap@. Extraction produces a claim with the same key. - Before inserting, the write path looks up open claims with that key, finds the
finance@one, sets itsvalid_toandsuperseded_by, then inserts the new claim as open. - A later question about where invoices go retrieves only open claims, so the model sees
ap@and its date. - A question about what the old address was can still query closed claims, because nothing was deleted.
Where it breaks
Supersession moves the hard decision to write time, so write-time mistakes become durable. A misread message can retire a correct fact, and the error is silent because retrieval now looks clean.
Keying is the real difficulty. Free-text memories rarely map to a tidy subject and attribute, and a fuzzy match can merge two different facts or miss that two phrasings mean the same thing.
Some attributes are multi-valued. A customer with two shipping addresses should not have the first one closed by the second. Some statements are temporary, like a person saying they are travelling this week, and should expire rather than overwrite.
Sources differ in authority. A claim from a signed contract should not be retired by a passing remark in chat.
It is also the wrong tool for document retrieval. If the source of truth is a document, re-index from the document when it changes rather than reconciling extracted claims.
In practice
I would start with these rules:
- Keep raw conversation episodes immutable and derive claims from them, so any claim can be re-extracted or audited.
- Store
observed_at,sourceand an authority level on every claim. - Use deterministic keys for attributes you know matter. Let the model propose a match for the rest, but when it is unsure, keep both claims open and flag the conflict.
- Close claims, never delete them. History is how you debug a wrong answer.
- Allow an explicit
expires_atfor statements that are temporary by nature. - Show dates to the model in the retrieved context, so it can reason about age when a conflict slips through.
- When two open claims conflict, have the agent ask rather than pick.
- Build a small eval set of contradiction sequences and run it on every change to extraction or matching.
Treat each memory as a dated claim that a newer claim can retire, because similarity search alone cannot tell you which of two answers is still true.