Temporal Awareness
People change jobs. Companies rename products. Projects get cancelled. A memory system that only stores the latest fact loses the history that often matters for context. RadarOS memory tracks when facts became true and when they stopped being true, across User Facts, Entity Memory, and Graph Memory. Old facts are never deleted — they’re superseded.The Problem
Consider this sequence of conversations over several months:- January: “I just started at Acme Corp as a junior developer.”
- March: “I got promoted to senior developer!”
- June: “I left Acme and joined Globex as a tech lead.”
How It Works
Every fact and entity carries two temporal fields:- The old fact gets an
invalidatedAttimestamp - The new fact is created with a fresh
validFrom - Both remain in storage
Contradiction Detection
During background extraction, the memory model compares new facts against existing ones. Contradiction detection uses semantic similarity — it doesn’t require exact string matches:- “I also use Python” → additive (doesn’t contradict existing “Uses TypeScript”)
- “I switched to Python” → contradictory (supersedes “Uses TypeScript”)
- “I’m no longer on the platform team” → negation (invalidates without a replacement)
What the Agent Sees
By default,buildContext() only injects currently valid facts (where invalidatedAt is undefined). The agent sees a clean, current view:
Including History
If your use case benefits from historical awareness, enable it:includeSuperseded, the context becomes:
Viewing Temporal History
Query the full timeline for a user programmatically:Works Across Store Types
Temporal awareness is built into multiple memory subsystems:| Store | Temporal Fields | Contradiction Detection |
|---|---|---|
| User Facts | validFrom, invalidatedAt | Yes — semantic similarity |
| Entity Memory | validFrom, invalidatedAt | Yes — same-name entities |
| Graph Memory (nodes) | validFrom, invalidatedAt, lastMentioned | Yes — same-name nodes |
| Graph Memory (edges) | validFrom, invalidatedAt, confidence | Yes — same from/to/type |
| User Profile | updatedAt | Overwrites (structured fields) |
| Decision Log | createdAt | No (append-only) |
name and timezone are simply overwritten since there’s only one current value. The decision log is append-only by design.
Code Example: Full Lifecycle
Cross-References
- Memory Overview — Unified memory system
- Graph Memory — Knowledge graph with temporal edges
- Memory Stores — User Facts, Entity Memory, and other stores
- Memory Curator — Pruning old superseded facts