Skip to main content

The taxonomy

Every memory carries a type, the same one across CLI, MCP and HTTP. Defaults to fact. A database constraint rejects anything else, even if it gets past the API. Choosing well pays off twice: the viewer filters by type, and the MCP tool description teaches agents the same definitions, so an agent saving “user prefers tabs” tags it preference unprompted.
Recall results can also carry the sentinel type context. Those are chunks of ingested files, not saved memories, and their kind is context. You cannot save one. The sentinel exists so a single result list can hold both kinds honestly.

Beliefs, not rows

A memory is a belief with a lineage. Rows are never mutated in place.

rootId and version

rootId is the stable identity of the belief, version counts up from 1.

Active is current

The newest active row is the belief. Older ones are stale: kept forever, out of recall, dedup and the graph.

Edges agree

Each step writes a replaces edge from child to parent, so history and the graph tell the same story.

Validity is temporal

assertedAt is when a version became the belief. staleSince is when it stopped.

What creates a version

Resolving a conflict can step a version too: keep new and merge make the winner continue the existing lineage, so a settled contradiction lands in that belief’s history instead of orphaning it.

Walking history

Any version’s id works. The same chain is at GET /memory/:id/history, in the viewer’s memory panel, and in the read-only memory_history MCP tool.
Agents can read history but not edit a belief. update is deliberately a human action in the CLI or viewer. Recall never returns stale versions, so old ones cannot shadow the current one.