Your Agent Memory Needs Two Clocks

Mutable facts need one interval for when they applied and another for when the system knew them.

On April 10, a user tells an assistant, "I started working at Acme on April 1." On July 26, the user adds, "I left Acme on June 30."

The assistant now has to answer three different questions:

  • Where did the user work on June 15? Acme.
  • Where did the user work on July 10? Not Acme.
  • What would the assistant have said on July 10? Acme, because it had not learned about the departure.

A single timestamp cannot represent all three answers. It can record when the claim was stored or when it applied, but not both.

Mutable facts have two timelines

Temporal databases distinguish application time from system time. Application time describes when a row was valid in the domain being modelled. System time describes when that version existed in the database. Keeping both is usually called bitemporal modelling.

The same split is useful for agent memory:

ClockQuestionExample fields
Valid timeWhen did this claim apply in the user's world?valid_at, invalid_at
Knowledge timeWhen did the memory system treat the claim as live?created_at, expired_at

Zep's fact model uses those four timestamps. In the Acme example, the employment claim has a valid interval from April 1 to June 30 and a knowledge interval from April 10 to July 26.

That distinction is not just bookkeeping. A query about July 10 can mean "what was true then, using everything known now?" or "what did the system know then?" The first query uses July 10 as valid time and today as the knowledge cutoff. The second uses July 10 for both.

This also avoids pretending that the memory contains ground truth. It contains sourced claims. A later message may correct the dates again, and the system should be able to reconstruct each version without erasing the evidence that produced it.

Corrections should close intervals, not replace rows

A flat vector store offers two tempting update strategies. Overwriting the old chunk makes current retrieval cleaner but destroys historical answers. Appending the correction preserves history but leaves two semantically similar chunks competing for retrieval.

A bitemporal write keeps both records and changes their roles. When the July message arrives, the memory system can:

  1. Link the new message to the existing employment claim.
  2. Set the old claim's invalid_at to June 30.
  3. Set its expired_at to July 26, when the correction became known.
  4. Preserve both source messages as provenance.

Graphiti, the temporal knowledge graph behind Zep, separates episodes from extracted facts and attaches validity windows to relationships. The episode keeps the original source material; the relationship can be invalidated without deleting that source.

The write path still needs judgment. "I work in Berlin on Tuesdays" may be a scoped exception, not a replacement for "I work remotely." Two similar claims can coexist. Before closing an interval, the system has to decide whether the new evidence supersedes, narrows, contradicts, or merely adds to the old claim.

For single-valued slots such as a shipping address, only one claim should be live for a given valid-time point unless the conflict is explicit. Superseded claims remain queryable, and every state change points back to the source that caused it.

The retriever needs to understand the clocks

Correct timestamps do not guarantee a correct answer. Semantic retrieval may still return the old and new claims together because both mention Acme and employment.

The query planner needs a state view:

  • Current: return the claim valid now, using everything learned so far.
  • Historical: return the claim valid at a requested date.
  • Knowledge-as-of: ignore evidence learned after the requested cutoff.
  • Transition: return the before state, after state, and correction source.

The recent A-TMA paper calls the failure to coordinate these states "ghost memory." Old, current, and transition facts can all exist in the memory bank, yet remain mixed during retrieval or answer generation. Its experiments separate storage, retrieval, and answer failures. They show that temporal graph metadata can preserve relevant facts while the answer still uses the wrong state; the reported gains from explicit state roles depend on the host memory system.

State labels should therefore survive into the model's evidence packet. A superseded address is relevant to "Where did I live before?" and dangerous for "Where should this package go?" Relevance and currentness are separate signals.

Use two clocks when late knowledge can change an answer

A recent Show HN launch for SynapTale illustrates the same requirement in narrative knowledge graphs: a character's state can change by chapter, while the system still needs the earlier state and the event that ended it. Personal assistants, customer records, project decisions, and evolving requirements have the same shape.

Not every memory needs a bitemporal model. Immutable documents and append-only event logs can keep their original timestamps. Session-only preferences may be cheap enough to replace. The extra machinery earns its keep when corrections arrive late, historical questions matter, or an audit needs to reproduce what the agent knew at an earlier point.

If a product can ask both "What was true on that date?" and "What did the agent know on that date?", those questions may have different answers. Its memory then needs two clocks, provenance, and a retriever that knows which clock the user is asking about.