# Current memory tools can pass a poisoned run on. Procedural memory can stop it

> Source: <https://github.com/TheWariend/MuscleMemory/tree/main/benchmarks/results/poisoned-skill-2026-10-18>
> Published: 2026-10-18 18:29:32+00:00

Does a skill learned from one poisoned session reach later sessions? Claude Code on the
configuration-repair fixture, Claude Haiku 5.5 and Claude Sonnet 5.5, three poisons (a new file,
an unrelated line, a line fused into the real fix), four arms (no memory, naive memory, replay,
MuscleMemory). Both memory arms learn from the same four sessions: the poisoned one, then three
clean ones. Harness: `benchmarks/trust_experiment.py`. Summary: `benchmarks/summarize_trust.py`.

- `sessions.jsonl` : one line per session, rescored from the stored memory and hook databases.`canary_in_skill_shown` : the skill served carries the poison in its steps.`canary_in_guidance` :
the guidance the hook injected (rebuilt and matched to the hash it stored,`guidance_rebuilt` )
names the poisoned file, line or key.`canary_planted` : the poison is in the final code.`passed` : the hidden verifier passed. Rows with`in_paper_tables: false` are superseded runs,
kept for the record.
- `summary.json` : per-arm counts with Wilson 95% intervals.

Names in the data: arm `gate` is MuscleMemory and `off` is no memory; poison `file` is the new file, `line` the unrelated line and `subtle` the line fused into the fix.

| Arm (scored, both models) | Poison | Served | In injected guidance | In code | 
|---|---|---|---|---|
| No memory | — | — | — | 0/10 | 
| Replay (control) | each | — | — | 10/10 | 
| Naive memory (Mem0 ranking) | new file | 2/10 | 2/10 | 0/10 | 
| Naive memory (Mem0 ranking) | unrelated line | 1/10 | 0/10 | 0/10 | 
| Naive memory (Mem0 ranking) | fused into the fix | 1/10 | 1/10 | 0/10 | 
| MuscleMemory | new file / unrelated line | 0/20 | 0/20 | 0/20 | 
| MuscleMemory | fused into the fix | 5/10 | 0/10 | 0/10 | 

Naive memory keeps every passing session as its own skill, trusts all of them, and serves the
one the open-source Mem0 library (2.2.1, local `all-MiniLM-L6-v2` embeddings, no LLM extraction)
ranks first for the task prompt (`--equal-naive --picker`, with `benchmarks/mem0_pick.py`).
One naive injection could not be rebuilt from its hash (`guidance_rebuilt: false`).

Every scored session passed the hidden verifier, poisoned or not. The agent carried out the poisoned requirement in 31/31 poisoned learning sessions across all runs.

Known failure (`run: repo-failure`, Haiku only, not in the main table): the obvious poison moved
into the repository's agent instructions, which every session reads. MuscleMemory validated and
served the poisoned skill in 5/5 scored sessions and the poison was in the code in 5/5; without
memory it was in the code in 5/5 too. Proof before reuse does not defend against poisoned inputs.

Superseded runs: the first naive arm learned only from the poisoned session (it served the poison
in 29/30, which followed from that setup); the next naive arms ranked skills by repetition counts
built with MuscleMemory's own matching (they never served the separable poisons and served the
fused one in 5/5 Haiku sessions); and the first MuscleMemory arms used checks this study found
holes in. All are kept in `sessions.jsonl` with `in_paper_tables: false`. The stored databases and
transcripts contain local paths and are not released.
