Slowly changing dimensions already solved memory versioning
Every agent memory team eventually hits the same wall: a fact about the user changed, and the system needs both the current truth and the history. The data warehouse world solved exactly this problem decades ago and gave it a name — slowly changing dimensions. Watching memory frameworks reinvent it one conflict-resolution hack at a time is the strongest argument I know for making agent engineers read Kimball before they write a memory schema.
Most agent memory stores today are accidental SCD Type 1: the new fact overwrites the old, or worse, gets appended beside it with no versioning at all. Overwriting destroys history — the agent can never again reason about "the user preferred concise answers until March." Appending without versioning is how you get memory pollution: two contradictory facts, both similarity-matched, both retrieved, the model left to guess. Kimball's answer is Type 2 row versioning: each change closes the old row and opens a new one, with effective and expiry dates, a current flag, and a high-date sentinel on the open row. Reads default to current-flag rows; as-of queries walk the validity intervals. The full taxonomy runs from Type 0 (immutable — exactly right for protected core facts an agent must never let drift) through Type 6 hybrids and Type 7 dual-key views, and the selection criteria — history need, volume, compliance — translate to memory design without modification.
The parts memory teams haven't reinvented yet
Bi-temporal modelling is the piece that repays study most. Warehouses distinguish business time from system time: when the fact became true in the world versus when the system recorded it. Agent memory needs both columns, because agents chronically learn late — the user mentions in August that they changed jobs in May. The warehouse handles that as a late-arriving change: a mid-timeline insert that splits an existing validity interval, with out-of-order changes applied under sequence-by, latest-wins semantics. This is mechanical, tested, boring technology, and it is precisely what a memory arbiter improvises with an LLM prompt today. Hash-based change detection — hashing the tracked attributes to distinguish a genuine change from a restatement — resolves the duplicate-versus-update judgment for free before any model gets involved. MERGE's matched, not-matched, and not-matched-by-source clauses are the complete decision table for a memory write path.
Why insist on history at all? Because facts go stale at wildly different rates — the temporal-decay literature shows political and corporate facts decaying fastest, scientific and geographic slowest — and FreshQA's staleness gap (15–40 percentage points between "ever correct" and "currently correct" answers) is exactly what an unversioned store accumulates silently. A Type 2 memory answers two questions an overwrite store can't: "what do I believe now?" and "what did I believe when I made that recommendation?" The second is the one audits, debugging sessions, and regulators ask. One warehouse caveat transfers verbatim: time travel is not SCD history. Storage-level snapshots expire and were never modelled truth — so no, your agent's session checkpoints are not memory versioning either.
The honest limit of the analogy: SCD assumes discrete, typed facts about identifiable entities. A dimension row has columns; much agent memory is unstructured prose and embeddings, where row versioning has nothing to grip. The pattern applies to the structured layer — user profiles, preferences, semantic facts, entity attributes — not to raw episodic logs, which want an append-only ledger instead. But the structured layer is exactly where teams are hand-rolling update semantics today, and where staleness does its quiet damage. There is no research problem here. There's a forty-year-old pattern, a validity interval, and a current flag. Apply it directly.