A coding agent with a project summary in its context trusts that summary completely. It does not verify whether the summary is still true, because a file that already answers the question supplies no reason to doubt. We reproduced that on 10 models from three vendors, with zero variance and zero files read. Then we tested every common fix against it. Prompt directives repair it on some models and not others. A published memory architecture never beat a single line of prompt. Curated stores rot the moment maintenance slips. One intervention held on every model we ran it against, including the newest one that broke everything else: deliver the in-force decision into context, completely, and say which value wins. That is the mechanism governed memory implements.
We gave an agent a CLAUDE.md holding six facts about a fabricated product. All six were superseded; the current values sat in dated notes on the same disk. Asked to write a one-pager, every model wrote the fully stale version, having read zero files. Not a retrieval failure — a verification failure. The agent had the tools, the notes were trivially findable, and it never looked, because nothing in its context suggested there was anything to find. Strip the facts out of the summary and the same agent goes and finds them unprompted. The summary is the barrier.
Every mitigation below is measured against that floor, and each one fails where its responsible actor defaults: prompt directives need the model to choose to search, curated stores need a human to keep them fresh. Delivering the in-force decision into context needs neither — and on the model that made the other methods unpredictable, it was the only thing that still held.
New to Memory Bank, ADR, RAG, or spec-driven? See the methods reference →. Want the fixtures, the isolation proof, the trial counts and the two bugs our own grader had? Read the methodology →
An agent verifies a fact only when it has a reason to doubt it. A confident, self-consistent summary supplies none — so staleness is not underweighted, it is invisible. We call this the answer-before-doubt barrier.
Same fixture, same task, same stale summary. Under the floor arm every model wrote a fully stale one-pager and read zero source notes first. Accuracy is 0.0 with zero variance — whatever the newer generations improved, none of it touches this. The most common mitigation is a line of prompt telling the model to check the notes; it works, on some models, unpredictably.
| model | floor (trust summary) | verify (“check notes”) | TierMem (published fix) | mla push (upper bound) |
|---|---|---|---|---|
| Claude Opus 4.8 | 0/6 | 6/6 | 6.0/6 | 6/6 |
| Claude Haiku 4.5 | 0/6 | 0.7/6 | 0.7/6 | 6/6 |
| Gemini 2.5 Pro | 0/6 | 2.0/6 | 0.0/6 | 5.0/6 |
| Gemini 2.5 Flash | 0/6 | 0/6 | 0.0/6 | 6/6 |
| GPT-5.4 | 0/6 | 6/6 | 1.0/6 | 6/6 |
| GPT-5.4-mini | 0/6 | 0/6 | 0.0/6 | 6/6 |
| GPT-5.5 | 0/6 | 6/6 | 0.0/6 | 6/6 |
| GPT-5.6-sol | 0/6 | 5.7/6 | 0.0/6 | 6/6 |
| GPT-5.6-luna | 0/6 | 5.7/6 | 1.7/6 | 5.3/6 |
| GPT-5.6-terra | 0/6 | 6/6 | 0.0/6 | 6/6 |
Hold the corpus, the task and the model identical. Change one thing: the CLAUDE.md file.
| arm | Opus 4.8 | Haiku 4.5 |
|---|---|---|
| floor ↗ | 0/6 | 0/6 |
| verify ↗ (“check notes first”) | 6/6 | 0.7/6 |
| RAG ↗ (all-MiniLM top-k) | 6/6 | 0/6 |
| Memory Bank ↗ | 6/6 | 6/6 |
| ADR ↗ (superseded→accepted) | 6/6 | 6/6 |
| spec ↗ (living doc) | 6/6 | 5.7/6 |
| mla push ↗ | 6/6 | 6/6 |
On Haiku, verify and RAG collapse with 0 tool calls — the search tool worked and the answers were easy to find; the model simply did not look. Note also that 6/6 is this fixture's ceiling: it separates the methods that fail from the ones that do not, and cannot rank the ones that pass. Act III has a fixture with no ceiling.
| arm (under lag) | Opus 4.8 | Haiku 4.5 |
|---|---|---|
| ADR under lag | 4.7/6 | 4.0/6 |
| Memory Bank under lag | 5.3/6 | 5.0/6 |
| spec under lag | 4.0/6 | 3.3/6 |
| RAG (reads raw notes) | 6/6 | 0/6 (won’t search) |
| mla push | 6/6 | 6/6 |
Every curated-store arm degrades on both models. The agent trusts the incomplete store and does not check the complete raw notes — the same suppression, one level down. RAG reads raw notes and is immune to the lag, but that immunity is worthless on Haiku, which never searches. The push arm was never run under this stressor, so its rows here are the unstressed cells and should not be read as surviving it.
Listing mitigations as tools — RAG, tiered memory, a decision log — predicts nothing. Sorting them by which actor is made responsible for the trusted context being correct does. Each family then fails exactly where its actor defaults, and the two stressors above are not a grid we chose: they are the two ways an actor defaults.
| family | responsible actor | fails when | seen in our data |
|---|---|---|---|
| verify · RAG | the agent, on doubt | the model declines to search | ✗ Haiku 0–0.7/6, zero tool calls |
| TierMem | the agent, on insufficiency | the summary is complete and wrong | ✗ never beats one line of prompt |
| Memory Bank · ADR · spec | a human, at write time | maintenance lags | ✗ 3.3–5.3/6 under lag, both models |
| CUPMem | a model, at write time | compression precedes the question | ✗ capped by its own store |
| mla push | the system, at delivery | coverage or precedence fails | the only failure you can engineer against — Act II |
The obvious objection is that a real memory system would handle this, so we built the leading published one as an arm. TierMem (Feb 2026) keeps a short summary beside a complete raw log and escalates to the log only when the summary looks insufficient. We gave it every advantage: the log is complete, and the summary openly states it is a three-month-old snapshot.
| model | TierMem | verify (“check the notes first”) | result |
|---|---|---|---|
| Opus 4.8 | 6.0/6 | 6.0/6 | tie |
| Haiku 4.5 | 0.7/6 | 0.7/6 | tie |
| Gemini 2.5 Pro | 0.0/6 | 2.0/6 | worse |
| Gemini 2.5 Flash | 0.0/6 | 0.0/6 | tie |
| GPT-5.4 | 1.0/6 | 6.0/6 | worse |
| GPT-5.4-mini | 0.0/6 | 0.0/6 | tie |
| GPT-5.5 | 0.0/6 | 6.0/6 | worse |
| GPT-5.6-sol | 0.0/6 | 5.7/6 | worse |
| GPT-5.6-luna | 1.7/6 | 5.7/6 | worse |
| GPT-5.6-terra | 0.0/6 | 6.0/6 | worse |
Averaged over 3 trials. The methods that work on Opus buy their correctness with tool calls and context, and both are billed. Cost is recorded for only some cells — every Claude CLI run and every GPT-5.5 and 5.6 run has none at all — so read this table as a within-vendor comparison, never as a study-wide ranking.
| arm · model | acc /6 | latency | work tok | context tok | cost | tool calls |
|---|---|---|---|---|---|---|
| mla push · Haiku | 6.0 | 12 s | 938 | 52k | $0.027 | 0 |
| mla push · Opus | 6.0 | 56 s | 4.0k | 70k | $0.26 | 2.3 |
| RAG · Opus | 6.0 | 69 s | 5.0k | 141k | $0.42 | 0 |
| verify · Opus | 6.0 | 64 s | 4.1k | 137k | $0.32 | 6.7 |
| ADR-lag · Opus | 4.7 | 119 s | 8.3k | 129k | $0.45 | 8.7 |
| no-summary · Haiku | 5.7 | 55 s | 3.7k | 517k | $0.10 | 15.7 |
| verify · Haiku | 0.7 | 11 s | 0.8k | 52k | $0.026 | 0 |
| floor · Haiku | 0.0 | 13 s | 0.9k | 52k | $0.026 | 0 |
The obvious objection to Act I is that a retrieval layer would catch this. So we built one and measured it. Retrieving the right evidence and appending it beside the summary — what almost every memory product ships — corrected nothing. This act isolates the two properties that separate a delivery that works from one that does not, and they are the two properties governance provides.
We started where a practitioner starts, and where most tooling stops: retrieve the relevant evidence items and append them alongside the summary. Not a mock — a real shipping render path, pointed at the identical floor fixture, with retrieval demonstrably returning the right records. On Opus 4.8 it corrected nothing. The correct values were in the context window and the model wrote the stale one-pager anyway.
Two things were wrong at once, and separating them is what makes this actionable. The block was capped below the task — it carried two of the six facts the deliverable needs — and it labelled what it carried as provisional: “may be cited as unverified… must not be presented as established fact.” The cap alone does not explain the zero, because the two facts it did deliver were not reliably adopted either. Hedged evidence loses to a confident summary.
Identical correct values in every row. The intact stale summary loaded in every row. What varies is the number of facts the appended block carries and the wording it uses. provisional: may be cited as unverified, must not be presented as established fact. conflict: states both values, names no winner. correction: names the asserted value, the in-force value, and which wins.
| cell | facts sent | Haiku 4.5 | Opus 4.8 | Opus 5 |
|---|---|---|---|---|
| provisional-2 — the shipping render path | 2 | 1.5/6 † | 0.0/6 | — |
| provisional-6 — everything, hedged | 6 | 6.0/6 † | 0.0/6 | 0.0/6 |
| conflict-6 — both values, no winner named | 6 | 0.0/6 | 0.0/6 | 6.0/6 |
| correction-2 — assertive, but partial | 2 | 2.0/6 | 2.0/6 | — |
| correction-6 — complete and assertive | 6 | 6.0/6 | 6.0/6 | 5.67/6 |
† Scored correct, and non-compliant on the same trial. The block forbids presenting its values as established fact, and a one-pager does exactly that. Haiku reached those numbers by disregarding the instruction it was given. We report accuracy and compliance separately rather than crediting one as the other.
This is the answer-before-doubt barrier applied one level up. The summary still answers all six facts confidently. A block that flags itself unverified de-rates its own standing while leaving the summary's authority untouched — it lowers the value of the evidence without giving the agent any reason to doubt what it already holds. A conflict notice, by contrast, supplies exactly that reason, which is why the same values behave completely differently under the two wordings.
A newer model, a code deliverable, someone else's test cases, and a fixture with no ceiling. Two of these cut against us.
Claude Opus 5 shipped mid-study. Because the central claim is about what current models do, we re-ran the floor and the adoption cells on it. The floor result does not hold, and how it fails is the interesting part. Comparing a model run days earlier against one run today would confound the model with the agent CLI, which updates constantly — so we re-ran Opus 4.8 on the same build, fixture and harness, changing only the model identifier.
| arm | Opus 4.8 (same-build control) | Opus 5 |
|---|---|---|
| floor (trust the stale summary) | 0.0/6 all 8 trials | 4.42/6 12 trials, floored on 3 |
| provisional-6 (hedged delivery) | 0.0/6 | 0.0/6 |
| conflict-6 (unresolved, no winner) | 0.0/6 | 6.0/6 |
| correction-6 (complete, assertive) | 6.0/6 | 5.67/6 |
| mla push (upper bound) | 6.0/6 | 6.0/6 |
A prose one-pager invites the objection that this is a summarisation artifact. So we built the same mechanism with a code deliverable: the always-loaded file is an API quick-reference stamped “last verified 2026-01-15” asserting six obsolete constructs — create route, auth scheme, config variable, SDK method, response field, default timeout — each superseded in its own dated note among 40 fillers. The task is to write a client that creates a contract check and polls it. Grading matches exact code tokens, so there is no paraphrase to adjudicate.
| arm | Haiku 4.5 | Opus 5 |
|---|---|---|
| code floor — trust the quick-reference | 0.00/6 0 tool calls | 5.67/6 7–13 calls |
| code verify — “check the notes first” | 4.00/6 5–7 calls | 6.00/6 7–14 calls |
| code correction — complete and assertive | 5.00/6 0 tool calls | 6.00/6 0–1 calls |
Every number in Act I comes from a scenario we invented, with the same model family we were testing — a real weakness. So we took STALE, an outside benchmark of 400 expert-written cases where a new fact quietly invalidates an old one, and rebuilt it in our setting: the stale value in the always-loaded summary, the current value in one dated note among 40 look-alikes, their question as the task. 272 of the 400 converted cleanly through a deterministic separation gate, so the answer key is not ours. We ran the first 40 in file order on Haiku 4.5 — a deterministic slice, not a random sample.
| method (Haiku 4.5, 40 cases) | gave the OUTDATED answer | gave the current one | notes read |
|---|---|---|---|
| floor (trust the stale summary) | 26 of 40 (65%) | 0 | 0.0 |
| verify (“check the notes first”) | 27 of 40 (68%) | 1 | 0.4 |
| mla push | 0 of 40 (0%) | 17 | 0.0 |
Almost everything ties at 6/6 in the Opus column of Act I. That tie is a six-question test running out of room, not the methods being equal. So we built a harder one: 20 facts hidden among 100 notes, across five trap tiers — plain recency, a newer proposal that was rejected, an exception scoped to one customer tier, a multi-step calculation, and a near-duplicate superseded draft. It ranks cleanly, and it produced the sharpest limit on our own claim.
| method (20-fact fixture) | Opus 4.8 | Haiku 4.5 |
|---|---|---|
| floor (trust the stale summary) | 16.0/20 | 0.0/20 |
| verify (“check the notes first”) | 14.5/20 (19, then 10) | 0.0/20 |
| CUPMem (adjudicated store) | 14.0/20 | 15.5/20 |
| no-summary (nothing to trust) | 18.5/20 | 12.5/20 |
| mla push | 20.0/20 | 19.5/20 |
TierMem is not the rival worth worrying about. CUPMem is — and it published the core idea this project had been describing as its differentiator, first, with a working prototype and a number. It appears in the same paper as the STALE benchmark (May 2026). When new information arrives it labels every older fact keep / stale / replace / unknown, propagates that judgement to related facts, then constrains what the agent may read. That is close enough to the governance model here that we are not going to claim the idea.
| what is being measured (CUPMem's own benchmark) | CUPMem scores |
|---|---|
| Spotting that a stored fact is now outdated | 89–91% |
| Refusing a question built on an outdated premise | 75–78% |
| Actually applying the updated fact in later work | 32–43% |
| Overall on their benchmark (best model without it: 55.2%) | 68.0% |
Published at the same weight as the results that worked, because a lab that only publishes its confirmations is not measuring anything.
The idea we had not yet earned: in a big enough archive ordinary search truncates — it returns the top handful and quietly drops a related record two hops away — so a structured graph of “this replaced that” links should win. We tested it on all 223 of Wagtail's versioned release notes, 2014 to 2026, pinned to an exact commit: 1,538 searchable chunks, of which a top-10 request sees 0.65%. Then 15 hand-checked deprecation chains where answering needs two documents — the release that removed a feature, and the release one to two years earlier that deprecated it. We also made our own opponent stronger than planned: the obvious baseline was the lab's similarity search, which is weak at exact identifiers, so the baseline became BM25, which is very good at them.
| chains fully retrieved, out of 15 | similarity | BM25 | hybrid | recency-blend |
|---|---|---|---|---|
| asking by exact name, top 10 | 8 | 13 | 13 | 12 |
| asking by exact name, top 30 | 8 | 15 of 15 | 15 of 15 | 15 of 15 |
| asking in plain English, top 10 | 7 | 5 | 7 | 6 |
| asking in plain English, top 50 | 10 | 10 | 13 | 14 |
Our whole premise is a context file that has fallen behind. That deserved testing outside our own fixture, so we took the 12 real repositories from the AGENTS.md study ↗ — 10 of which ship a maintainer-written context file — and mechanically checked every file path those documents mention against the repository as it stands. A path is a claim you can verify without opinion.
| result | value |
|---|---|
| Paths referenced across 7 real context files | 97 |
| Paths that no longer exist | 2 (2.1%) |
This area got crowded fast in 2026. An honest map, including where others got there first.
| paper | what that paper found | how this study differs |
|---|---|---|
| STALE ↗ May 2026 |
400 expert-written cases where a new fact quietly invalidates an old one. The best model scores 55%. Critically, the updated evidence was already in front of the model in 77.5% of failures and it still answered from the old one. | STALE measures “found it, then ignored it.” Act I measures one step earlier — the agent never looks at all, zero files read — and Act II measures the same ignoring, isolated to the two variables that cause it. The failures stack. |
| CUPMem ↗ the fix in that same paper |
Labels each old fact keep / stale / replace / unknown when new information arrives, then blocks the stale ones at read time. Scores 68% on their benchmark. | CUPMem published the write-time adjudication idea first, and that deserves saying plainly. The difference that survives: CUPMem governs what the agent reads, and a rule about reading cannot fire when nothing is read. Detection is near-solved (89–91%); application is not (32–43%), which is the same gap Act II reports from the other side. |
| Plans Don't Persist ↗ Snowflake, June 2026 |
Probes the model's hidden state during long tasks and finds an agent's working information lives in the text of the context window, not in the model. Once that text is dropped or compressed, it is gone. Their phrase: “context management is load-bearing.” | Two methods, one lesson. They probe what the model holds; this study measures what it does. Their honest caution is worth repeating here: re-showing old context does not automatically fix anything — which is precisely what Act II measures the limits of. |
| Evaluating AGENTS.md ↗ Feb 2026 |
Across 438 real coding tasks, adding a project context file did not improve success (−0.5% to −2% for generated ones) and raised cost 20%. The authors could not explain why. | This study offers a candidate mechanism: a file that asserts facts switches off the checking that would have caught those facts changing. It predicts their split too — files describing practices helped slightly (+4%), generated fact summaries did not. |
The barrier, and the ranking of mitigations against it, rest on fabricated fixtures anyone can rebuild — github.com/Meetless/stale-context-bench, MIT, every runner and grader included. The rows labelled mla push measure an idea, not a shipping integration.
git clone https://github.com/Meetless/stale-context-bench
cd stale-context-bench
node validate-isolation.mjs --model claude-opus-4-8 # prove the clean room
node matrix.mjs --trials 3 --conc 3 # every arm x {opus, haiku}
node run.mjs --arm mf-fr-correction6 --model claude-haiku-4-5 # an Act II adoption cell
Fixtures, isolation proof, trial counts, oracle bugs and threats to validity: read the methodology →