Your AI Coding Agent Stopped Listening. The Cause Is Context Rot.
For a few weeks my Claude Code setup got steadily worse at following directions. Same model, same prompts, slowly degrading obedience. The easy story is "the model regressed." The real story lives in your context window, and it's uglier.
I went looking. What I found was 4,648 dead files quietly poisoning every session.
More rules, less compliance
Start with the counterintuitive part. Adding instructions makes an agent follow your instructions worse.
A developer wrote up exactly this in "I Wrote 200 Lines of Rules for Claude Code. It Ignored Them All.". The line that stuck with me: research shows "double the instructions, halve the compliance" for the Sonnet tier. This is architectural. An LLM reads your system rules, your CLAUDE.md, your code, and your actual request as one flat token stream with no reliable priority ranking. Your one load-bearing instruction competes for attention with everything else you've ever told it.
Researchers call the attention failure "lost in the middle." Stuff enough text around your instruction and the model's attention sags in the exact region where your instruction sits. The bigger your context window, the more room you have to bury yourself.
That last point matters more than it sounds.
A bigger window is a bigger junk drawer
When I moved to a million-token context window, I assumed everything got better. More room, more memory, more of my stuff in front of the model.
Here's the trap. Nothing in the tooling forces a trim. A small window imposes discipline by force. A huge window removes the forcing function and invites you to stuff it. So you do. Every CLAUDE.md, every memory file, every MCP server's full tool catalog, every skill description rides along on every single turn. The window fills with low-signal scaffolding and your real instruction drowns in the middle of it.
My always-on scaffolding had grown to roughly 38,000 tokens before I'd typed a word. A 60KB memory index the tool itself flagged as too big and truncated. A 33KB CLAUDE.md. Around 200 skill descriptions. Roughly 180 MCP tool names. The model spent its attention budget reading my furniture.
The 4,648 corpses
Then I found the worst offender, and it taught me the real lesson about context rot: dead systems keep injecting after you stop using them.
Months ago I'd installed a memory plugin — the claude-mem family — to auto-capture session context. At some point it stopped running. No background worker, no registered hooks, log files frozen back in February. As far as I knew, it was gone.
It had left landmines. When it was active, it had generated a CLAUDE.md in nearly every folder it touched, each carrying an auto-generated "Recent Activity" block. After it died, those blocks stayed. Every time I worked in one of those directories, Claude Code dutifully loaded the nearest CLAUDE.md and injected a stale block that said, in effect, "Recent activity: none."
I scanned my dev tree. 4,648 CLAUDE.md files carried the dead block. 4,639 of them contained nothing else — pure corpse. One repo alone held 4,186 of them, scattered through every source subfolder. My agent had been reading thousands of fragments of a memory system that had been dead for three months, and every fragment told it I'd done nothing and remembered nothing.
That's context rot in one image: a dead tool, still talking, still consuming the attention budget meant for live work.
How to find your own rot
You can audit this fast. Three questions:
-
What loads on every turn? Add up your
CLAUDE.mdfiles, your memory/index files, and the MCP tool catalogs you've connected. If the total runs into the tens of thousands of tokens, your real instructions are sitting in a haystack. - What's dead but still wired? List every plugin, hook, and MCP server you've ever installed. For each, confirm it still runs and still earns its context cost. Anything that injects text without doing live work is rot.
-
What's duplicated? I had a second instruction file (for a different tool) that was 97% byte-identical to my
CLAUDE.mdand had quietly drifted out of sync. Duplication is rot with a second author.
A grep for your dead plugin's signature across your repos is a sobering five minutes. Mine returned four digits.
Rules are requests; hooks are laws
Trimming context is half the cure. The other half is accepting what a CLAUDE.md rule actually is. The dev.to author put it perfectly: "Rules in prompts are requests. Hooks in code are laws."
A line in CLAUDE.md is a suggestion the model can rationalize past, especially once it's buried. A hook is code that runs deterministically regardless of what the model decides. When I had a standing rule against writing scratch files to a temp directory, the model ignored it for months because the rule was advisory and Claude Code itself was simultaneously telling it that temp directory was a valid workspace. I converted the rule into a PreToolUse hook that returns a hard deny. The behavior stopped that day.
The pattern generalizes. For anything you truly need enforced, move it out of prose and into code that blocks the wrong action before it happens. Keep prose for genuine guidance. Spend your context budget on what's live, true, and load-bearing.
The cleanup
I archived the dead memory install, deleted 3,349 of the junk files I owned outright, stripped the dead block from the handful that still had real content, and flagged the rest for a careful pass because they lived in a repo I share. The global instruction file went back to a few lines of live guidance and a pointer to a cached context snapshot.
The model never changed. The window it had to think in did. Clear the rot, and the thing starts listening again.
Top comments (0)