Skip to content
Docs menu

Concepts

Facts that change

Values change over time. TAM can record when a fact was true, retire old values, and answer both "what is it now?" and "what was it then?".

The problem

In May you saved “billing runs on MySQL”. In August you migrated and saved “billing runs on PostgreSQL”. Both records are still in memory. Which one is true?

TAM gives you three tools for this, from simplest to most precise.

1. Dates on every record

Every record stores when it was saved (UTC). Search results carry that date, and the grounded reader memory_answer sees it too: the latest record about the same subject gives the current value, unless its text describes the past. Asked about billing, it answers PostgreSQL, previously MySQL.

2. Supersede on save

When you know a new record replaces an old value, say so:

memory_save(
  type="fact",
  content="Billing runs on PostgreSQL",
  project="billing-service",
  supersede=true,
)

TAM looks for active records of the same project and type that start with the same words but end in a different value, retires them, and returns their ids as superseded. Use it for single-valued facts only; “likes jazz” would also retire “likes rock”.

3. Temporal facts in the knowledge graph

For facts you want to query by date, store them as subject–predicate–object assertions:

kg_add_fact(subject="billing-service", predicate="database", object="PostgreSQL", project="billing-service")

Adding a fact with the same subject and predicate but a different object closes the old one (its valid_to is set) and keeps the full history.

  • Now: kg_at without a timestamp returns currently valid facts.
  • Then: kg_at(timestamp="2026-05-01T00:00:00Z") returns what was true on that date.
  • History: kg_timeline lists every change for a subject.
  • Close without replacing: kg_invalidate_fact.

Good candidates: stack and dependency choices, owners of a service, environment endpoints, config values.

Contradictions

When two records disagree and neither is clearly newer, memory_answer runs a contradiction-seeking search before answering. By default (MEMORY_CONTRADICTION_POLICY=resolve) it gives the reader both sides with their dates and names the value it replaced; with abstain it answers Not enough information instead. See Configuration. This path needs an LLM provider; plain memory_recall never calls one.

Date arithmetic

memory_temporal_query answers questions like “how many days between these two dates” or “does interval A overlap interval B”, and turns phrases such as “last Thursday” into dates (English and Russian), without an LLM.

Found a mistake? Open an issue on GitHub.

Search