Memory you can trust — where the field is, and what we pre-register
- memory
- safety
- trust-layer
- pre-registration
Memory is what made agents useful — and what made them attackable. The same store that carries a person's preferences across sessions can carry someone else's instructions into their next prompt, and the field's own measurements of this got sharp in the last two years. This note is our read of that landscape, what we think it implies, and — the part we care most about — the three bars we are registering before we run anything, so the results can be checked against us later.
One thing we are not doing here: disclosing holes. Anything we found in our own house appears in a second note only after its fix has merged, as found → fixed, with the PR. That note is drafted and waiting.
Injection is not execution
The first thing the numbers teach is a distinction most headlines skip: an attack landing in memory and an attack executing are different events, with very different rates. Read the pairs below as two bars per finding — how often the poison persisted or injected, and how often it actually ran.
the data as a table
| measurement | value |
|---|---|
| query-only injection succeedsMINJA — no write access neededsource | 98.2% |
| …and then executesthe step most studies skipsource | 76.8% |
| poison persists in memoryretrievable after the attack — persistence studysource | >97.5–100% |
| …but execution of it varies wildly9 models, one study — the spread is the pointsource | 0–95% |
| full attack chain landsMemSecBench — every stage of the chainsource | 50.3% |
| survives the system's repair attemptMemSecBench — repair success ratesource | 56.1% |
| AgentPoison — attack successat under 0.1% poison ratesource | >80–100% |
| PoisonedRAG — attack success5 poison texts per questionsource | 90% |
Two rows in that chart deserve the emphasis they get. Query-only injection — no write access, the attacker just talks to the agent until the agent poisons its own memory — was reported landing at 98.2%, with 76.8% executing (MINJA). And in the persistence study, one finding cuts both ways: poison stuck in memory more than 97.5% of the time, but its execution ranged from 0 to 95% across nine models on the same attack (arXiv:2605.08442). That spread is the whole argument of this note: what sits between the stored poison and the executed instruction is the model's authority policy — and authority is a thing we can build on purpose.
The nastier variant is laundering: poison that arrives in a document, gets summarized into memory by the agent itself, and rides back in later wearing the memory's own credibility. The best published defense before provenance tracking still left 68% attack success across eight frontier models (arXiv:2606.24322). The memory does not know what it remembers.
What the measured defenses buy
The defenses that have real numbers behind them share a shape. None of them is a better poison classifier. They all change who is allowed to say what, and where it may land: datamarking that keeps untrusted text out of the instruction channel, signing + smoothed retrieval that reject unsigned rows, authority tracked through derivation, gates at write/retrieve/promote.
the data as a table
| comparison | before | after |
|---|---|---|
| Datamarking / spotlightinginjected instructions obeyed — Microsoft, 2024source | >50% | <2% |
| Origin-bound authority + corroboration gateslaundered poison — best prior defensesource | 68% | 0% |
| Signed memory + smoothed retrievalunsigned injected rowssource | 93–100% | 0% |
| Signed memory + smoothed retrievalrows the agent wrote itselfsource | 65.3% | 5.3% |
| Gates at write/retrieve/promote + quarantinecross-agent propagationsource | 38.2% | 0.9% |
That is the design we are committing to. Not "detect the attack" — "memory is data, never authority": every prompt that carries memory fences it into a labelled data section, every row wears its origin, and trust degrades through derivation (a summary inherits the lowest trust of its inputs) rather than laundering upward.
The animation below is the idea, in twenty seconds — synthetic rows only:
a prompt has two channels: instructions come from the operator and the system — memory is data
Synthetic rows — the piece shows how memory meets the prompt, never real content.
What memory layers actually ship
We surveyed the public documentation of the memory layers a buyer would actually shortlist, plus ourselves. The honest headline: the frontier is open. Scope isolation and audit trails exist; provenance-based trust — origin on every row, surviving derivation — is shipped by nobody we could find, and no memory layer publishes a measured poisoning-resistance score.
| Capability | Mem0 | Letta | Zep | Claude | Ours | Next |
|---|---|---|---|---|---|---|
| Scope isolationper tenant / per user | ✓ships | ·not found in docs | ·not found in docs | ✓ships | ◐partial | ✓ships |
| User can view and repair memory | ·not found in docs | ·not found in docs | ·not found in docs | ✓ships | ◐partial | ✓ships |
| Audit trail of memory writesappend-only | ✓ships | ·not found in docs | ·not found in docs | ·not found in docs | ✗not shipped | ✓ships |
| Bi-temporal invalidationfacts valid-in-time, superseded not erased | ·not found in docs | ·not found in docs | ✓ships | ·not found in docs | ◐partial | ✓ships |
| Provenance-based trustorigin + trust on every row, surviving derivation | ✗not shipped | ✗not shipped | ✗not shipped | ✗not shipped | ✗not shipped | ✓ships |
| Signed rows | ✗not shipped | ✗not shipped | ✗not shipped | ✗not shipped | ◐partial | ✓ships |
| Quarantine by defaultlow-trust writes recalled with a label, promoted by the owner | ✗not shipped | ✗not shipped | ✗not shipped | ✗not shipped | ◐partial | ✓ships |
| Measured poisoning resistancea published safety score on a fixed harness | ✗not shipped | ✗not shipped | ✗not shipped | ✗not shipped | ✗not shipped | ✓ships |
- ships
- partial
- not shipped
- not found in docs
- pre-registered, not built
- Zep: Zep / Graphiti
- Claude: Claude memory
- Ours: our own audit, 2026-09-26 — Mycelium today
- Next: pre-registered by the trust-layer program, not built yet
We put our own column in at its real value — including the no cells —
because a trust claim that starts by grading itself generously is worth
nothing. The last column is not a boast either: it is the same matrix,
pre-registered, and the tracker below is what turns it from a matrix into a
changelog.
What we pre-register
Three claims, with bars fixed on 2026-09-26 — before the first run of the suite. If we miss a bar, the miss publishes with the result.
| # | claim | the bar | the guard | |---|-------|---------|-----------| | 1 | Laundering resistance | execution-phase attack success ≤ 2% on a fixed public suite — query-only injection, indirect poison, summarization laundering, federation-import poison — across ≥ 3 backbones including a small on-device model | clean utility drop ≤ 2 points (LongMemEval) vs defenses off | | 2 | Deletion completeness | ≥ 95% of adversarial cases leave no retrievable fact — from derived rows and embeddings, not just the original row — after the source is deleted | measured against Mem0 and Graphiti baselines on the same harness | | 3 | Federation containment | zero home tool actions from imported memories; 100% of foreign rows recalled with the foreign label; ≤ 5% of benign souvenirs wrongly quarantined | the false-quarantine rate is part of the claim — a wall that silences honest visitors fails too |
Why publish bars before results? Because "trust your memory" is exactly the kind of sentence that decays into marketing unless it was falsifiable from the start. The suite, the harness and the receipts will be published with the results; the bars are on the record now.
The tracker
Everything above renders from two JSON files in the site repo — the landscape snapshot and the program tracker. The tracker is the living one: as steps land, their status moves and the PR link fills in, and this page shows the new state on the next build. No numbers are hand-copied into this note.
| Capability | state |
|---|---|
| P0.1auth tightening | ○planned |
| P0.2write authority bound to the caller | ○planned |
| P0.3dead code honesty | ○planned |
| P0.4phone fencing | ○planned |
| P1.1trust tiers + provenance through derivation | ○planned |
| P1.2memory is data, never authority | ○planned |
| P1.3quarantine by default | ○planned |
| P1.4deletion that propagates | ○planned |
| P1.5append-only audit log | ○planned |
| P1.6retrieval trust | ○planned |
| P2.1laundering resistance | ○planned |
| P2.2deletion completeness | ○planned |
| P2.3federation containment | ○planned |
- planned
- in progress
- merged — PR linked
And the results chart, with its axes declared before its data exists. When the first receipts land, the line appears here; until then the empty panel is the honest version of "we haven't run it yet":
the data as a table
no runs yet — the bar was fixed before the first run
The bars are the contract. The tracker is the receipt. Everything else is work — which starts now.