Supersession and provenance
Brain never mutates memories — corrections supersede old records, contradictions are surfaced not hidden, and every statement traces back to the memories it was extracted from.
The wedge here is immutable history, explicit provenance. A memory store that overwrites rows on update has no replay, no audit, and no defense against silent drift. Brain trades a little storage for the guarantee that every claim has a chain back to the memory that produced it, and every correction leaves a visible diff.
Mutation contracts differ by kind
There is no single "update" operation. What happens when new evidence arrives depends on the statement kind — the contract is set at extraction time, not query time.
| Kind | On new evidence for the same (subject, predicate) |
|---|---|
| Preference | New supersedes old. old.superseded_by = new.id; current-value queries return the new one; history queries return the chain. |
| Fact | Both stored as a contradiction. The planner surfaces the conflict and returns the higher-confidence (or more recent, at equal confidence) one. |
| Event | Immutable. A similar or corrective occurrence is a new, independent Event — Events never supersede each other. |
Supersession instead of mutation
When a user says "actually I moved to Berlin," the extractor finds the existing Preference-style (subject, location) statement ("Lisbon") and writes a new one ("Berlin") linked as a supersession:
old: { id: A, object: "Lisbon", superseded_by: B }
new: { id: B, object: "Berlin", version: n+1 }Both records remain. The default read returns only the current one — the filter chain drops superseded records (see Read pipeline) — but the history is intact and reachable. The value of never overwriting is that analytics, audit, and replay all see the full chain.
Contradiction without supersession
Two Facts with the same (subject, predicate) but different objects are a contradiction, not a supersession. Both are stored, and the planner exposes the conflict — the statement set, the highest-confidence member, and a recommended resolution (by confidence, by recency, or unresolved). Surfacing contradictions is a feature: it's exactly the thing a memory database should not hide. The caller (or an upstream agent) decides how to resolve it.
Provenance is mandatory
Every extracted statement is anchored to the memories it came from. It carries:
struct StatementRow {
// ...
confidence: f32,
evidence: Vec<MemoryId>, // the source memories this claim was extracted from
extractor_id: ExtractorId, // which extractor tier / model produced it
extracted_at: u64, // when it was derived
// ...
}The chain is: statement → evidence (which memories) → each memory's stored text and its embedding model fingerprint → extractor_id (which extractor produced the claim) → extracted_at (when). A memory itself distinguishes created_at (server write time) from occurred_at (the client's event time, when the content actually happened), so a statement's timeline is anchored to reality, not just to ingestion.
You cannot turn provenance off. Every statement carries its evidence list; every memory carries its fingerprint and timestamps.
Inspecting the chain
Because derivation is asynchronous, Brain persists a per-memory write-artifact bundle and exposes it through MEMORY_INSPECT: for any memory, the embedding vector, the stored record, the analyzed text-index terms, the generated HyPE questions, and the typed graph (nodes + edges) that memory produced. That's the "how was this built" view for a single memory. The live analogue is the EncodeTrace returned by encode with wait: "derived", and the StageCompleted events streamed over SUBSCRIBE. See Write pipeline.
Every write is recorded in the WAL, which is Brain's durable audit trail — operators can reconstruct who wrote or forgot what, and when.
Deletion — soft first, hard on demand
Brain deletes through forget, not by mutating a row. There are two modes:
A tombstoned memory is invisible to recall, plan, and reason immediately. After the grace period a maintenance worker reclaims the slot and increments its version, so any stale MemoryId held elsewhere resolves to not_found rather than to a reused slot. Forgetting an already-forgotten memory is a no-op success, not an error. The forget event is recorded even after a hard forget — you can prove later that something was deleted, even though its content is unrecoverable.
Why this is the wedge
If you can't answer "where did this claim come from" with a single traversal, you can't safely use a memory layer in production — eventually a customer asks "why did your agent claim X" and the answer needs to be more specific than "the model said so." Brain's answer: pull the statement's evidence list, read the source memories, see the extractor and timestamp, inspect the write artifacts. That guarantee disappears the first time you mutate a record in place. Supersession — and never overwriting — is what preserves it.
Was this page helpful?
Read pipeline
How recall answers a cue — three retrievers fused with RRF, an always-on cross-encoder rerank, a filter chain, and a membership verdict of Single, Many, or None.
Retention and decay
How Brain ages memory — salience decay, consolidation, and tombstone reclamation — run by per-shard background workers with no operator intervention.