---
title: "How to handle facts that change over time"
description: "How a memory system stores facts that change over time: overwrite vs append-only vs supersession, with a worked example and an evaluation checklist."
canonical: https://past.dev/guides/facts-that-change-over-time
last-updated: 2026-09-02
---
# How to handle facts that change over time

Source: https://past.dev/guides/facts-that-change-over-time

Facts that change over time are best stored by supersession: close the old value's validity window at the change date, write the new value with an open window, and link the two records. This lets one store answer what the value is now, what it was before, and when it changed. Overwriting destroys the history, and append-only storage keeps both values without marking which is current, so neither can answer all three questions.

## Why agents return stale answers

An agent that remembers facts will eventually be asked about a fact that has changed. What it answers depends on how the memory layer stored the change. Most stale answers trace back to one of three storage decisions, made long before retrieval runs.

- **Overwriting destroys history.** If the new value replaces the old one in place, the previous value no longer exists anywhere. A question about the value before the change has no stored answer, and no retrieval technique can recover data that was deleted at write time.
- **Append-only keeps both values without marking which is current.** The store now holds two records about the same fact. Retrieval sees both, has no marker saying which record is current, and often ranks the older record higher because its wording matches the query better.
- **Retrieval cannot reconstruct what ingestion destroyed.** Reranking, query expansion, and prompt changes all operate on stored records. If change data was never written, no retrieval technique can produce it.

These are ingestion decisions. They determine, at write time, which questions the system will ever be able to answer.

## Three storage strategies compared

There are three common ways to store a fact that changes: overwrite it, append the new value alongside the old one, or supersede it. The strategies differ on the three questions a memory system gets asked about any changing fact.

| Question | Overwrite | Append-only | Supersession |
| --- | --- | --- | --- |
| What is current? | Yes. Only one value exists. | Ambiguous. Two records, no marker. | Yes. The fact whose [validity window](/glossary/validity-window) is open. |
| What was it before? | No. The old value was destroyed. | Sometimes. The old record exists but may rank below unrelated text. | Yes. The superseded fact, with its dates. |
| When did it change? | No. | Only by comparing record timestamps manually. | Yes. The date the old window closed. |

Overwrite answers one question. Append-only stores enough data in principle and loses it in practice, because nothing links the two records. [Fact supersession](/glossary/fact-supersession) answers all three from the same store, which is why [temporal knowledge graphs](/glossary/temporal-knowledge-graph) and [temporal databases](/guides/temporal-database) converge on it.

## How supersession works

Supersession stores each fact with a validity window (the period during which the fact was true) and an optional link to the fact that replaced it. A change is recorded in four steps.

1. Detect that an incoming statement changes an existing fact rather than adding a new one.
2. Close the existing fact's validity window at the change date.
3. Write the new fact with an open validity window starting at the change date.
4. Link the old fact to the new one, so either can be reached from the other.

```twofactrecordsafteronesupersession
[
  {
    "id": "fact_3a1",
    "subject": "project-atlas",
    "predicate": "monthly_budget",
    "value": "12000 USD",
    "valid_from": "2026-01-10",
    "valid_to": "2026-02-18",
    "superseded_by": "fact_9f2"
  },
  {
    "id": "fact_9f2",
    "subject": "project-atlas",
    "predicate": "monthly_budget",
    "value": "18000 USD",
    "valid_from": "2026-02-18",
    "valid_to": null,
    "superseded_by": null
  }
]
```

> **Change vs contradiction**
>
> A change is a new value from a later date. A contradiction is two credible sources disagreeing about the same period. Supersession handles the first. The second needs conflict handling of its own.

## Detecting that a fact changed

Supersession depends on recognizing that two statements describe the same fact. The working rule: same subject, same predicate, new value. "Project Atlas budget is 12,000 USD" and "Atlas is now at 18,000 a month" share a subject and a predicate, so the second supersedes the first. Three conditions make the rule work in practice.

- **Same subject requires [entity resolution](/guides/entity-resolution).** "Project Atlas", "Atlas", and "the Q1 infrastructure project" must resolve to one subject, or the store accumulates parallel facts that never supersede each other.
- **Ordering requires event time.** A late-arriving email about a February decision must supersede January's value and be superseded by March's, whatever day it was ingested. This is the [event time vs ingestion time](/guides/event-time-vs-ingestion-time) distinction, and tracking both axes makes the store [bitemporal](/guides/bitemporal-data).
- **Disagreement at the same time is a different case.** When two credible sources assert different values for the same period, record a conflict rather than picking a winner. The [contradictory facts guide](/guides/contradictory-facts) covers that path.

## A worked example: one budget, three months

A concrete timeline shows what each strategy can answer. Project Atlas's monthly budget changes twice in one quarter.

| Date | Event | Store after supersession |
| --- | --- | --- |
| January 10 | Kickoff email sets the budget at 12,000 USD per month | One fact, window open from January 10 |
| February 18 | Steering meeting raises it to 18,000 USD | January fact closed at February 18 and linked; new fact open |
| March 30 | Scope cut lowers it to 15,000 USD | February fact closed at March 30 and linked; new fact open |

In April, the store answers all three questions from those records. The current budget is 15,000 USD, valid since March 30. The budget in mid February was 12,000 USD, because the February 18 change had not yet happened. The change dates are February 18 and March 30. An overwrite store answers the first question alone. An append-only store holds all three values with no rule for choosing among them.

## Evaluating a memory system on changing facts

Any memory system can be probed on changing facts with a five-minute test. The probe needs no harness, though public benchmarks formalize the same pattern under the name knowledge update; the [benchmark methodology](/benchmarks/methodology) describes how such probes are scored.

1. State a fact with a date: "On January 10 the Atlas budget was set to 12,000 USD per month."
2. State a change with a later date: "On February 18 the budget was raised to 18,000 USD."
3. Ask for the current value. Expect 18,000 USD, effective February 18.
4. Ask for the previous value. Expect 12,000 USD, valid January 10 to February 18.
5. Ask when the budget changed. Expect February 18.

Expect each returned value to cite a dated source as well; that requirement is the [data provenance](/guides/data-provenance) contract. Failures are diagnostic. Answering 12,000 to the current-value probe means retrieval prefers the older record. Answering 18,000 with no trace of 12,000 means the change overwrote history. Answering both values without dates means the records were never linked.

## Where past.dev fits

past.dev is a memory API built on this model. Every fact carries event time from the source timestamp, a validity window, and a supersession link, and recall returns the current and previous values with dated evidence. The [quickstart](/docs/memory-api/quickstart) shows the ingest and recall calls.

## Frequently asked questions

### Why does my AI agent keep giving outdated answers?

Usually because its memory layer either overwrote the old value or appended the new one without marking it current, so retrieval has no way to prefer the newer fact. The fix is storage that records change explicitly, by closing the old value's validity period and linking its replacement.

### What does it mean to supersede a fact in AI memory?

Superseding a fact closes its validity window at the change date, stores the new value as a separate fact, and links the two. Both values stay queryable with their dates, so the system can report the current value, the previous one, and when the change happened.

### How do I test whether a memory system handles facts that change?

State a fact with a date, state a change with a later date, then ask three questions: the current value, the previous value, and the change date. A system that handles change answers all three with correct dates.

### Should old values be deleted when a fact changes?

No. A change should supersede the old value so history remains queryable. Deletion is a separate decision governed by a retention or forgetting policy, and it should never happen as a side effect of an update.

### Does past.dev keep the previous value when a fact changes?

Yes. A change closes the previous fact's validity window and records a supersession link to the replacement. Recall returns both the current and the previous value, each with its dates and sources.

## Related

- [Bitemporal data](https://past.dev/guides/bitemporal-data)
- [Event time vs ingestion time](https://past.dev/guides/event-time-vs-ingestion-time)
- [Contradictory facts](https://past.dev/guides/contradictory-facts)
- [Temporal databases](https://past.dev/guides/temporal-database)
- [Forgetting policy](https://past.dev/guides/forgetting-policy)
- [Fact supersession](https://past.dev/glossary/fact-supersession)