← Building Memory for AI Coding Agents
04 / 06 Technical field note

Fixing Stale Memory: Temporal Facts and Supersession

How temporal facts, lifecycle states, and supersession keep contradicted decisions out of working memory while preserving the audit history.

AI AgentsTemporal DataMemory SystemsData Modeling

In the first post I called this the dangerous failure mode, and it’s worth saying why. An agent with no memory is ignorant, and you know to double-check it. An agent with stale memory is confident and wrong, and it cites a real decision your team actually made, just not the current one. That’s harder to catch and more expensive when you don’t.

The canonical example is simple. A stored fact says the team uses Redis. The team later moves to Postgres. In a system with no notion of time, that Redis fact is still sitting in the index, still retrievable, still phrased as present tense truth. The moment the team switches, that fact becomes actively harmful, and naive retrieval has no way to know. Retrieval quietly turns into contamination, and the model sounds confident while being wrong.

Standard RAG has no defense here. It indexes every chunk as equally true forever. In Borg’s benchmark, that produced a stale-fact rate of 11.5%, more than one retrieval in ten pointing the agent at a superseded decision. Borg’s answer is to give every fact a lifecycle.

Facts have a lifecycle, not a boolean

In most systems a fact is true or false, present or absent. In Borg a fact moves through states: observed, current, superseded, or archived. It carries two independent time axes, valid time (when the fact was true in the world) and recording time (when the system learned it). This is a bitemporal model, the same discipline financial and compliance systems have used for decades to answer “what did we believe on this date, and when did that change.”

That structure changes what “retrieve a fact” means. You’re no longer asking “does this string match.” You’re asking “is this fact current,” which is the question that actually matters during real work.

Supersession instead of overwrite

Here’s the move that makes it work. When a new fact contradicts an existing one, Borg does not overwrite or delete the old fact. It marks the old fact superseded and records the new one as current. The Redis fact doesn’t vanish when Postgres arrives; it transitions to superseded, and the Postgres fact becomes current.

This is why overwriting would be the wrong tool. Overwriting destroys the history. Supersession preserves it while keeping it out of the live picture. The classic memory failure Borg is built to avoid is retrieving both “Python 3.9” and “Python 3.12” with no attempt to decide which one still applies. The lifecycle is that attempt, made explicit and stored.

Two readers, two needs

Supersession matters because two very different consumers read the same store.

The agent doing today’s work wants only what’s current. When Borg compiles context, superseded and deprecated facts are kept out by default. The agent never sees the overturned decision, so it can’t act on it. That’s the 11.5% stale rate dropping to 2.5% in the benchmark, a 78% reduction in stale facts reaching the model.

A compliance or audit query wants the opposite: the full history, including what was true when and when it changed. Because nothing was deleted, that history is intact. The episode layer is immutable evidence, and superseded facts remain queryable. You can reconstruct what the system believed on any past date.

One store serves both. Working memory stays current, the historical record stays complete, and you don’t choose between them.

Why this needs the typed graph and one database

Supersession only works if Borg can tell that a new fact actually contradicts an old one, and that requires structure. This is where the typed predicates earn their place. Facts are edges expressed through a fixed reference set of 24 canonical relationship verbs, which lets the system recognize that two statements concern the same relationship and that the new one overrides the old, rather than treating them as unrelated text.

It also leans on the single-database design from the last post. Marking a fact superseded and writing its replacement happens inside one ACID transaction. There’s no window where the contradiction has been recorded but the old fact is still serving as current, which is exactly the inconsistency a two-store system would have to defend against.

The takeaway

Stale memory is not a tuning problem you fix with a better embedding model. It’s a modeling problem. If your facts have no notion of when they stopped being true, no amount of retrieval quality saves you, because the contradicted fact is genuinely similar to the query. It is, after all, about the same thing.

Give facts a lifecycle, supersede instead of overwrite, and serve only current facts at compile time. That’s the whole mechanism, and it’s most of the gap between a memory system you trust and one you have to babysit.

The next post turns to how we know any of this is real: the benchmark behind the numbers I keep citing, and the caveats its own authors put in writing.


Part 4 of a 6-part series on building memory for AI coding agents. Next: Building the benchmark.

Architecture depth + engineering leadership

Building platforms enterprises trust at scale.