Time, provenance and explainability
Track when a fact is true, when the system learned it, and where it came from.
You can track separately when a fact is true, when the system learned it and where it came from. This page covers a memory's time fields, reading as of a point in time, provenance and lineage, and the output of explain_memory.
Time fields
| Field | Set by | Meaning |
|---|---|---|
createdAt | You (REST, optional) | Event time. Defaults to the time of the write. The recency score is based on it. |
observedAt | You (optional) | When the fact was observed. Defaults to createdAt. |
validFrom, validTo | You (optional) | The interval during which the fact is valid in the real world. Default: open-ended from createdAt. |
recordedAt | Server | When the system recorded the fact. Immutable. |
supersededAt | Server | When another memory replaced this one. |
updatedAt | Server | Last change. |
expiresAt | Console / import | Expiry (see below). |
Example: recording today that a pricing rule takes effect on January 1:
curl -s -X POST $API/v1/memory/append -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d "{\"workspaceId\":\"$WS\",\"runId\":\"pricing-7\",\"layer\":\"Workspace\",\"type\":\"decision\",
\"content\":\"From the start of 2027, the Enterprise plan's monthly fee is calculated using the updated rate card\",
\"validFrom\":\"2027-01-01T00:00:00Z\",\"sourceKind\":\"document\",\"sourceRef\":\"pricing-policy-v4\"}"Memories whose validity interval has not started yet or has ended are not returned by default searches.
Revisions
Each memory's content is kept as revisions: the write opens the first revision, and every content update (update_memory / PUT) closes the open revision and opens a new one. An update does not change validity time; what gets corrected is "what we know", not real-world validity.
There is no separate endpoint that lists revisions; past content is visible through the as-of read below. A memory's event history (ADD, UPDATE, MERGE, SUPERSEDED, VISIBILITY_CHANGED …) is in the explain_memory output.
Reading as of a point in time (as-of)
POST /v1/memory/retrieve supports as-of reads on two axes:
asOfAxis | Question | Behavior |
|---|---|---|
valid (default) | "What was true at that time?" | Memories whose validity interval contains the asOf instant. |
transaction | "What did the system know at that time?" | Memories recorded by then and not yet superseded; content is replaced with the revision known at that instant. |
curl -s -X POST $API/v1/memory/retrieve -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d "{\"workspaceId\":\"$WS\",\"runId\":\"audit-1\",\"semanticQuery\":\"enterprise plan fee\",
\"asOf\":\"2026-09-01T00:00:00Z\",\"asOfAxis\":\"transaction\"}"Limits:
- As-of reads with both axes are available over REST and in the .NET client. Node/Python
searchonly takesasOf(defaultvalidaxis). MCPsearch_memorydoes not support as-of. - On the
transactionaxis, memories are found by their current content and then shown with the old revision. You cannot find an old memory by a word that appears only in its old text. - When semantic dedup merging changes content, no new revision is opened; in that case the old text does not appear in a
transactionread.
Expiry
Memories whose expiresAt has passed are hidden from searches; a daily maintenance job permanently forgets them through the deletion flow. Today, expiry can only be set from the console playground and through import; POST /v1/memory/append and MCP add_memory do not accept this field.
Age-based retention (e.g. "delete memories older than 90 days") is a separate setting and is off by default. See Data management.
Provenance
| Field | Meaning |
|---|---|
sourceKind | agent, user, document, import (declared by the caller) or derived, system (assigned by the platform). |
sourceVerified | Was the source kind stamped by the platform (true), or is it the caller's claim (false)? |
sourceRef | A free-form source pointer supplied by the caller. Not verified, and its content is not fetched. |
extractionMethod, model | How the platform produced the memory (e.g. verbatim, LLM fact extraction, rule-based, abstraction, promotion) and the model used. |
agentId, actorId, actorRole, runId, episodeId | Who wrote it, and in which task. |
evidenceCount | How many times it has been confirmed/merged. |
Every memory derived through consolidation or promotion is linked to its sources with evidence links (a source can be an episode event, another memory or a profile row). If a source has been deleted, it appears as deleted in the explanation.
sourceRef can be a URL or a document ID, but it is not a full source trail: which part of the source document the memory came from, the document's permissions and its updates are not tracked.
Source authority
A tenant admin can assign source kinds an authority between 0 and 1 (trust.authority.<kind>, e.g. higher for facts from user sources). Authority shows up in the trust score; it does not affect ranking or access.
explain_memory: "how do you know this?"
curl -s "$API/v1/memory/$ID/explain?workspaceId=$WS" -H "Authorization: Bearer $KEY"| Section | Contents |
|---|---|
memory | All fields of the memory, lifecycle status, visibility and classification. |
trust | Trust breakdown at read time: confidence, evidence, freshness, utility, source authority, contradiction risk. |
lineage | Origin (run, episode, promotion source), what it was derived from, what was derived from it, what it supersedes / is superseded by, evidence sources. |
evidence | Source episodes and events, extraction method and model. |
history | Event history: ADD, MERGE, UPDATE, SUPERSEDED, VISIBILITY_CHANGED, DEPENDENT_STALE, PROMOTION_* … |
usage | How many times it entered context, was used or ignored; recent outcome scores. |
contradictions | Open contradictions. |
dependents | Number and examples of memories that depend on this one. |
Linked memories you cannot see are shown as redacted: true, without content. MCP: explain_memory(memoryId) returns the same information as text.
Change feed
Creates, updates, deletes, shares, promotions and policy changes in the workspace are kept in a cursor-based feed (policy fields only, not content). See Webhooks and change feed.