"Memory" is one of the most overloaded words in the current conversation about AI systems.
In a single discussion, the word can refer to a model's context window, a vector database, a JSON file on disk, retrieved chat history, a user profile, shared notes between agents, or information encoded in model weights during training. Each of those is a real mechanism. None of them is the same thing as any of the others.
The confusion matters because people make system decisions based on what they think memory means. A developer who believes memory is solved by a larger context window will build a different system than one who recognizes that memory requires an explicit write policy. An architect who equates memory with retrieval will miss the state management problem entirely.
This note separates the mechanisms by running one small scenario through four different conditions. The model, the question, and the source events are held fixed. The only thing that changes is the relationship between persistence, retrieval, and context assembly. The companion repository makes every step inspectable.
Where does a fact go?
Suppose a project team communicates three updates across three days.
On Monday, at standup: "The Orion launch is Friday. Priya owns release approval."
On Tuesday, in the project channel: "Friday launch date is tentative."
On Wednesday, at standup: "Launch moved to Monday. Marcus is covering approval while Priya is out."
Later, in a fresh session, the system is asked: When is Orion launching, and who approves the release?
That question has a correct answer. The launch is Monday. Marcus approves. But whether the system can produce that answer depends entirely on what happened to the information between Tuesday and now.
The Monday facts might exist only in the original conversation context, already gone when the session ended. They might have been saved to a file or database. They might have been embedded in a vector store for later retrieval. They might have been summarized into a structured record. And Wednesday's update might have replaced Monday's facts, or it might have been appended alongside them, or it might never have been written at all.
Each of those is a different system. Each produces a different context for the model. And each is routinely described as "memory."
Context is what the model can see right now
The most common confusion is between context and memory.
A language model does not retain information between calls. Every time it runs, it receives a context. The context might include a system prompt, conversation history, retrieved documents, or facts injected by the application. Whatever is in the context, the model can use. Whatever is not in the context does not exist for the model at that moment.
In the companion experiment, the first condition demonstrates this directly.
When all three Orion updates are present in the conversation, the model can answer the question. It has the facts in front of it. In a new session, the same model cannot answer the same question, because none of those facts survived the session boundary.
Nothing was remembered. The model had access to information, and then it did not.
A larger context window changes how much information the model can hold in a single call. It does not change what happens between calls. An application that depends on context alone loses everything the moment the session ends, the context is truncated, or the conversation grows past the window. That loss is silent. The model does not know what it cannot see.
Storing everything is not the same as remembering
The obvious fix is to save the information somewhere and retrieve it later. Many implementations do exactly that. Every observation, every message, every extracted fact gets written to a store.
This solves the persistence problem. The facts survive across sessions. But it creates a new one.
In the Orion scenario, a system that saves every observation ends up with three records for the launch date: Friday (from Monday's standup), Friday with a tentative flag (from Tuesday's channel message), and Monday (from Wednesday's standup). It also has two records for the release approver: Priya and Marcus.
When the system retrieves everything and assembles a context, the model receives all five records. The launch is simultaneously Friday, tentatively Friday, and Monday. The approver is both Priya and Marcus.
The model now has to resolve contradictions that the memory system created by refusing to manage its own state. Sometimes a model will handle this reasonably, picking the most recent or most confident-sounding fact. Sometimes it will not. Either way, the application has delegated a state management decision to the model's inference, which is the wrong place for it.
Bad memory can be worse than no memory. A system with no persistence at least gives the model a clean context. A system that persists indiscriminately gives the model a contradictory one.
A write policy decides what survives
The third condition in the experiment introduces filtering. Not every observation becomes a persistent record. The write policy evaluates each candidate fact and decides whether to retain it, ignore it, or defer it.
In the Orion scenario, this produces a meaningful difference on Tuesday. The observation that "Friday is tentative" arrives with low confidence. The write policy, applying a confidence threshold, decides not to save it. Monday's high-confidence facts are retained. Wednesday's high-confidence updates are also retained.
This eliminates the noise. The tentative observation does not clutter the store. But it does not solve the state management problem. Monday's record says the launch is Friday. Wednesday's record says the launch is Monday. Both are active. Both are high-confidence. Both get retrieved.
The model still receives contradictory information. The contradiction is smaller, because the tentative duplicate was filtered out. But the stale Friday record remains because the write policy only evaluated incoming facts against a threshold. It did not evaluate them against existing state.
Filtering writes is necessary. It is not sufficient.
Revision is where memory becomes useful
The fourth condition adds one more operation: when a new high-confidence fact arrives for a key that already has an active record, the system supersedes the old record rather than appending alongside it.
Wednesday's "launch moved to Monday" does not just get saved. The write policy finds the existing record for launch date (Friday, from Monday's standup), marks it as superseded, and creates a new record (Monday, from Wednesday's standup) that links back to the one it replaced.
The old record is not deleted. It is marked with a status change and retained for provenance. If someone later needs to know what the system believed on Monday, or what changed and when, the history is there. But when the retrieval layer asks for current state, only the active records come back.
The model receives two facts: launch date is Monday, release approver is Marcus. No contradictions. No stale information. The context is clean because the memory system managed its own state before presenting it.
A launch date is recorded Monday, a tentative update is ignored Tuesday, and the record is revised Wednesday. The superseded version is retained for provenance. Only the current value reaches the model.
This is what makes revision the operationally important layer. Without it, every fact the system ever learned competes for attention in the model's context. With it, the system presents a current, consistent view of what it knows.
The model did not remember that Orion moved to Monday. The application decided that the update should be retained, revised the prior state, retrieved the current record, and placed it into the model's context.
The assembled context is the experimental variable
Across all four conditions, the model is the same. The question is the same. The source events are the same. The decoding parameters are the same.
The only thing that changes is the context produced by the memory system.
CONDITION RETRIEVED RECORDS CONTEXT FOR MODEL
context_only (none, new session) question only
persist_all Friday, Friday, Monday, contradictory
Priya, Marcus
selective Friday, Monday, stale + current
Priya, Marcus
revision Monday, Marcus clean, currentSame model, same question, four different memory lifecycles, four different contexts presented to the model.
This framing matters because it identifies where the system's behavior actually changes. A common instinct when an agent produces a wrong answer from memory is to change the model, the prompt, or the retrieval ranking. Sometimes those are the right interventions. But if the problem is that stale or contradictory facts were assembled into the context before the model ever saw them, no amount of prompt engineering will fix a state management failure.
The assembled context is the boundary between the memory system and the model. Everything upstream of that boundary is the application's responsibility. Everything downstream is inference.
Memory is a lifecycle
The pipeline in the companion repository has six stages:
interaction → write decision → persistent state → retrieval → assembled context → modelEach stage is a different operation with a different failure mode.
The write decision can fail by saving too much, too little, or without revision. The persistent state can use the wrong representation for the access patterns the system needs. The retrieval can return stale records, irrelevant records, or miss critical ones. The context assembly can present information in a way that confuses the model. And the model can misinterpret a perfectly assembled context.
Those are independent problems. Solving one does not address the others. A vector database with perfect semantic search cannot compensate for a write policy that never revises stale facts. A large context window cannot compensate for a retrieval layer that returns contradictory information. And none of those layers can change what the model learned during training, which lives in the weights and is not part of this loop at all.
That last separation is especially easy to lose. When someone asks a model a factual question and it answers from its training data, that is parametric knowledge. When someone asks and the system retrieves a record from a database and injects it into the context, that is a memory system. They look similar from the outside. They are completely different mechanisms with different update cycles, different failure modes, and different trust properties.
A long context window gives the model more to read. A memory system decides what should still exist to be read later.
State management is the hard part
Most of the current discourse about agent memory is focused on storage and retrieval. Which database to use. How to embed memories for semantic search. How to rank retrieved records by relevance. Those are real engineering problems, but they are downstream of the harder question.
The harder question is what gets written in the first place, what happens when it becomes stale, and when it should be removed.
In the Orion scenario, every storage technology would produce the same result if the system saved every observation without a write policy. JSON, SQLite, a vector database, a knowledge graph. The storage format does not determine whether Friday gets superseded by Monday. That is a state management decision, and it has to happen in the write layer before the information reaches the store.
The same applies to forgetting. A fact that was true six months ago may be actively harmful if it is retrieved into a current context. An approver who left the company, a deadline that was moved, a policy that was revised. If the memory system does not have a mechanism for revision or expiration, those facts accumulate and degrade the quality of every context they appear in.
Retention is not the hard part. State management is.
The data model makes it concrete
The companion repository uses a deliberately simple data model:
class Memory:
id: str
key: str
value: str
source: str
created_at: datetime
confidence: float
status: Literal["active", "superseded", "temporary"]
supersedes: str | NoneThere is nothing sophisticated about this structure. That is the point.
Memory is not magic. It is state with lifecycle semantics. Each record has a status that changes over time. Each revision links back to the record it replaced. Each retrieval filters by status so that only current records reach the model.
The store is initially JSON. Not a vector database. Not a graph. Not because those are wrong, but because the teaching point does not depend on the storage technology. Semantic search is a retrieval strategy. Graph traversal is a retrieval strategy. Neither of them is what makes something memory. The lifecycle is.
An optional embedding retriever can be added later to show that retrieval strategy is yet another independent layer. But the four-condition experiment works without it, because the scenario is small enough that simple key-based retrieval is sufficient. The interesting behavior comes entirely from the write policy and revision semantics.
Exercise
Start with the companion repository and run all four conditions against the Orion scenario in offline mode. No credentials are needed. Read the trace output and observe what changes between conditions.
Then configure an LLM endpoint and run the same four conditions against a real model. The assembled context is the primary output. The model response is secondary, but it makes the downstream consequence of each memory condition visible.
Finally, write a new scenario. Change the domain, the number of events, and the kinds of updates. Observe where the write policies make the right decision and where they break down. The revision policy in the repository is simple. A fact about a date is easy to supersede because the key is the same. A fact that modifies a related fact without replacing it is harder. That is where the limits of a simple write policy become visible, and where the next layer of the problem begins.
New teaching notes, occasionally.
RSS