Writing

18 September 2026 · 8 min read

When Did You Learn That? Bi-Temporal Memory for LLM Assistants

A flat store of facts gets corrections, refinements and polite agreement all wrong. Separating when something was true from when the system learned it fixes most of it.

  • LLM
  • Memory
  • Data Modelling

An assistant that remembers you has to handle a set of cases that a flat list of facts gets badly wrong:

  • You moved. The old fact was true and now isn't.
  • You corrected it. The old fact was never true — the system misheard "Pune" as "Mumbai."
  • You refined it. "I work in tech" became "I'm a backend engineer." The old fact wasn't wrong, it was vague.
  • You agreed. The assistant guessed something about you and you said "yeah, sure."

Store all four the same way and the assistant will eventually say something that makes the user distrust it. This post is about the data model that stops that.

The naive model and what it loses

The obvious design is a list of facts with a timestamp: user lives in Mumbai, recorded 12 March. Newer facts win.

That single timestamp is doing two completely different jobs, and they come apart constantly.

There is when the fact was true in the world — you actually moved in January. And there is when the system came to know it — you mentioned it in March. Those are different dates, they arrive out of order, and collapsing them into one field means you can't answer either question reliably afterwards.

It matters in practice. If the user says in March "I moved to Bangalore in January," the fact is new to the system but old in the world. A model that only tracks recording time will order it correctly by accident here and incorrectly the moment two facts arrive out of sequence — which they do, constantly, because people narrate their lives in whatever order the conversation goes.

This problem is not new and it is not specific to LLMs. Databases solved it decades ago, and the answer is bi-temporal modelling: keep two independent time axes, valid time (when it held in the world) and transaction time (when the system recorded it). What's new is mostly that people building LLM memory are reinventing a flat store rather than reaching for the thing that already works.

Not all replacements are the same replacement

The second problem is that "this fact supersedes that one" hides several different relationships, and the difference is visible to the user.

Consider what the assistant should do with the old fact in each case:

  • You moved. The old fact was true, for a period. If the user asks where they used to live, it should still be there. It's history, not an error.
  • You corrected it. The old fact was never true. It should not resurface, ever, in any form. Showing it back to the user is the assistant saying "you told me X" when they didn't, and that is the single most trust-destroying thing a memory system does.
  • You refined it. The old fact is still true, just less specific. It shouldn't be marked false, it should be folded into its replacement — "backend engineer" implies "works in tech," and treating the vaguer statement as an error would be wrong.

One boolean superseded flag cannot express these. Marking a corrected fact and a superseded-by-refinement fact the same way guarantees you will either resurface something the user never said, or discard history they'd expect you to have.

So supersession is typed, not boolean. The type determines whether the old version stays retrievable, stays true, or is suppressed permanently.

The polite-yes problem

This is the part I'd most want another builder to take away, because I haven't seen it discussed much and it's a real trap.

Language models are agreeable. They're trained to be. And in conversation, so are people — when an assistant says "sounds like you're into hiking?", plenty of users will say "yeah, sure" to keep things moving, whether or not it's true.

If you store that as a fact, you have just written a claim about the user that the user never made. And it comes back later in the worst possible framing: "Since you're into hiking…" The user knows they never said that. From their side, the assistant has invented something about them.

The underlying issue is that agreement is much weaker evidence than assertion, and a flat fact store erases the difference. Both end up as "user likes hiking," with identical confidence and no provenance.

So the model keeps them apart. A fact the user volunteered is distinct from a fact the user merely agreed with, and the two are rendered differently — agreed-with facts are hedged rather than asserted. The assistant can use the signal without claiming the user said it.

It's a small distinction that costs one field, and it removes an entire category of moment where the user thinks I never told you that.

One block, not three

A last one that's less conceptual and more practical.

Memory had accumulated in several formats, and all of them were being put into the context separately. The model was receiving what amounted to three different descriptions of the same person and having to reconcile them mid-turn, while also answering the question.

That's work you're paying for on every single turn, in latency and in quality, to solve a problem you created upstream. Merging them into one retrieved block before the model sees it meant reconciliation happened once, deterministically, in code — rather than repeatedly, probabilistically, in the model.

The general form: if your prompt asks the model to resolve an inconsistency you could have resolved before assembling it, resolve it first. Context is not a dumping ground; every contradiction left in it is a task you've silently delegated.

What generalises

Two time axes, not one. When a fact was true and when you learned it are independent, they arrive out of order, and you will want both later.

Type your supersessions. Corrected, superseded, refined and merged behave differently in retrieval. A boolean will eventually resurface something the user never said.

Record how you learned a fact, not just the fact. Volunteered and agreed-with are different strengths of evidence, and rendering them identically is how an assistant ends up attributing things to people.

Reach for prior art. Bi-temporal modelling is old, well-understood, and sitting right there. A surprising amount of LLM memory design is database problems wearing a new hat.