Memory for agents

A memory substrate where every belief is a signed claim — and an agent is just an author with a perspective.

LLM agents are about to be the most prolific writers and readers of shared knowledge in existence, and the memory systems we're giving them were designed for none of what makes them dangerous or useful. This page is the case for building agent memory on Rhizomatic — not as one more storage option, but because the problems agent memory actually has are the problems this format was built to dissolve.

What's broken about agent memory today

The current state of the art is some mixture of: a vector store (similarity soup with no record of who asserted what, or when, or why), a scratchpad (a text file the agent rewrites, destroying its own history), and maybe a shared database (one table, one truth, every agent trampling the same rows). Each fails the same five ways:

No provenance. A retrieved memory carries no record of which agent (or which model version, or which human) put it there, from what evidence, at what time. When an agent acts on a bad belief, there is nothing to trace.

No perspective. Either every agent shares one memory (and one agent's hallucination becomes everyone's fact) or each agent is an island (and nothing compounds). There is no way to say: we share the substrate, but I weigh sources my own way.

Destructive revision. Updating a belief overwrites the old one. The question every incident review needs — what did the agent believe at the moment it acted? — is unanswerable by construction.

Unaccountable similarity. The vector index's opinions about what "matches" are opaque, unversioned, and silently change on reindex. Semantic drift is invisible until it bites.

No trust management. When an agent turns out to be compromised, buggy, or just running a worse model, there is no way to discount everything it ever wrote without surgically deleting history — which destroys the audit trail you need most at exactly that moment.

The mapping

Here is the part that reads like a trick, and isn't: every one of those failures maps to a primitive this format already defines, specifies, and tests in two independent implementations. Nothing below is roadmap — it's the substrate the tour runs live in your browser.

Agent memory needs…Rhizomatic primitiveStatus
Every belief attributable: which agent, which model, when, from whatsigned deltas; provenance inside the atombuilt · SPEC-1
Agents disagree without corrupting each othersuperposition — contradiction is databuilt · SPEC-2/5
Shared substrate, sovereign viewpointsresolution policies; trust = byAuthorRankbuilt · SPEC-5
"What did it believe when it acted?"as-of lenses over an append-only logbuilt · SPEC-4
Revision without erasurenegation — a new claim about an old claimbuilt · SPEC-1 §7
Summarizers, dedupers, adjudicators — with receiptsderived authors; replay-verifiable provenancebuilt · SPEC-7
One live verdict per subject, superseded cleanlykeyed emissionbuilt · SPEC-7 §5
Runaway loops contained, observablybudgets; signed suspension claimsbuilt · SPEC-7 §6
Fleets sync; offline agents converge laterfederation = set union; lenses; admissionbuilt · SPEC-6
Durable, portable snapshotspacks — deterministic, self-verifyingbuilt · SPEC-8
Parameterized recall ("about entity X, since T")holes — terms bound at invocationbuilt · SPEC-2 §6
Semantic search that's accountablethe librarian — see belowbuilt · SPEC-9 + chorus

An agent, in this system, is nothing exotic: a keypair, a reactor, and a policy. Its beliefs are claims it signed. Its worldview is a lens it chose. Its trust in others is data it can edit. Its history is an append-only log it cannot quietly rewrite — and neither can anyone else.

lens: A’s policy lens: K’s policy Agent A ed25519:a1c4… its own reactor · its own history policy: trust H › A › K view · deploy_ok = false Agent K ed25519:9be2… its own reactor · its own history policy: trust K › H › A view · deploy_ok = true the shared substrate — signed claims, contradictions held in superposition, nothing ever deleted disagreement, kept
One substrate, two sovereigns: the same claims resolve to different truths under each agent’s own trust policy — deterministically, and without either corrupting the other.

The semantic layer: similarity with receipts

The kernel is deterministic by law — no fuzzy matching below the read boundary, ever, because two agents evaluating the same data must get byte-identical answers. So where does semantic search live? Above the boundary, as an author.

The librarian is a derived author wrapping an embedding model. It watches the substrate and emits ordinary signed claims about meaning. Its unit of judgment is not "these two strings are similar" — it's a mapping into concept nodes with oriented slots. Two applications that never met describe employment differently:

app A:  person —[context: "employer"]→ company     company —[context: "employees"]→ person
app B:  person —[context: "job"]→ company          company —[context: "staff"]→ person

The librarian recognizes both as the same relation seen from its two ends, and emits mapping claims into a concept frame:

concept:employment
  slot employment#worker        ← "employees" (app A) · "staff" (app B)
  slot employment#organization  ← "employer"  (app A) · "job"   (app B)

each mapping: a signed claim — by embedding-model-X-v3, confidence 0.91,
              over input snapshot 1e20…, negatable like anything else

Slots make direction explicit — which end of the relation a vocabulary fragment names is which slot it maps to — so "employer" and "staff" can converge without gluing the wrong ends together. And because mappings are claims:

the librarian effectful author · model-x-v3 concept:employment #worker #organization App A’s vocabulary “employees” “employer” “manager” App B’s vocabulary “staff” “job” signed · conf 0.91 negated by human review every arrow is a claim: attributable to a model-author, confidence-scored, negatable, policy-weighted
Slots make direction explicit — which end of the relation a fragment names is which slot it maps to — and a wrong mapping dies by one signed negation, not a reindex.

Similarity has provenance (which model, which version, what input). Similarity is negatable (a human or a better model overturns a bad mapping with one negation — no reindex, no silent drift). Similarity is policy-weighted (the embedding model is an author with a track record; your agent can demand human-endorsed mappings while mine accepts model hunches). And when two librarians disagree about meaning, the disagreement is held in superposition and resolved per reader — the semantic layer itself lives in the CRDT.

The honest boundary: nearest-neighbor lookup happens inside the librarian, outside the kernel, and mappings lag new vocabulary by one librarian cycle — eventually consistent, accountably. Most recall then becomes exact, deterministic closure queries over materialized mappings; only genuinely novel queries pay a trip to the librarian, and even then the query term it produces is inspectable. The vectors themselves never enter the substrate — they are the librarian's private working memory, rebuildable at will. Judgments are what persist.

Three things you cannot do today

Decision replay. An agent made a call three weeks ago that looks wrong now. Scrub to the moment it acted: the exact belief set it resolved, under the exact policy it held, including the claims that were later retracted — because retraction appends, never erases. Incident review becomes a query, not an archaeology dig through logs that were never designed to answer it.

the append-only log negates the decision what the agent knew — including the claim that was negated afterwards arrived later — invisible at the moment of decision, by construction scrub to any instant: resolve exactly the claims that existed then, under the policy held then
The negation exists now; it did not exist then. Both facts stay queryable forever, which is what makes the replay honest.

Retroactive distrust. Agent K turns out to have been running a poisoned model since Tuesday. Demote K in your resolution policy — one edit, to your own data. Every belief downstream of K's testimony re-resolves instantly; everything corroborated elsewhere stands; and K's full claim history remains intact and queryable, which is precisely what the postmortem needs. No deletion. No rebuild. Trust is a lens, and you just refocused it.

Meaning under dispute. Two teams' agents organize the same domain with different vocabularies. Nobody runs a migration; nobody wins a meeting. The librarian proposes the bridge as claims, a human endorses or vetoes them with a signature, and each fleet's policies decide what the bridge is worth. Integration by judgment — auditable, reversible judgment — instead of integration by committee.

Underneath all three is the same property: perspective without fragmentation. Shared knowledge that compounds across a fleet, while every agent keeps its own epistemic standards — and every standard, every judgment, every revision is itself inspectable data.

What we built

The substrate is done: specified across nine documents, implemented twice (TypeScript and Rust), parity-verified byte-for-byte against a shared conformance suite, running live in the tour. The memory system on top of it is Chorus — a distinct system with Rhizomatic as its substrate: many voices, one piece. All of it ships in the repo today:

The alias layerSPEC-9: the concept/slot vocabulary and the aliased closure, spec'd and vectored with the same two-witness discipline as everything else (the tour's conformance widget runs the vectors in your browser, through both witnesses). · The core library — agent handles (keypair + reactor + policy), a memory API (assert / retract / recall / asOf / explain), pack-based persistence. · Trust dynamics — the adjudicator as a derived author with one live verdict per subject, decision replay (pinned instant + pinned policy + verified basis) and retroactive distrust as first-class operations. · The librarian — the embedding author and live semantic convergence: ask in one dialect, find another's data, the answer in the target's own vocabulary. · Distribution — an MCP server with sixteen tools exposing all of it as drop-in memory for any agent framework: every session is a distinct author (a keypair derived per conversation, bound to its model name by a signed identity claim), the human is one persistent author, concurrent sessions share one append-only store, and a briefing tool hands each new session what came before — including the facts the record disagrees about. · The console — the human's seat at the table: a local web UI over the same store with live receipts ("which model, in which session"), an as-of time scrubber, and a distrust button whose one signed edit re-resolves every future session's world.

See it run. The whole thesis — superposition, adjudication, decision replay, retroactive distrust, the librarian — executes as one deterministic, receipt-printing story:

git clone https://github.com/mbilokonsky/rhizomatic
cd rhizomatic/apps/chorus
npm install && npm run chorus:demo

The source is apps/chorus; the MCP server starts with npm run chorus:mcp.

Progress is tracked in the open in PROGRESS.md.