Your AGENTS.md Gets Worse Every Time You Fix It
Sep 4, 2026 · AI & BuildingThere is a piece of advice about agent instruction files that almost everyone gives, and it is right: when your coding agent makes a mistake you have already corrected once, write the correction down so it does not happen again. Eric Ma puts it cleanly — “whenever you find yourself giving the same instruction twice, add it to AGENTS.md instead.”
There is a second piece of advice that is also right: these files stop working when they get long. Tian Pan's analysis of instruction files puts reliable compliance at somewhere between 150 and 200 instructions, finds effective files clustering around a few hundred words, and finds the correlation with length turning negative past about a thousand. The escalation he describes will be familiar: a rule gets disobeyed, so you add a clearer version; a different rule gets disobeyed, so you add that one too; a few weeks later the file is four hundred lines and the agent is ignoring more of it than ever.
Both are true. Together they are a contradiction, and it bites somewhere around the fortieth correction. Follow the first and you violate the second. Follow the second and you throw away the accumulated knowledge that makes an agent useful in a real codebase rather than a demo. Most of what is written about this resolves it by telling you to trim — which answers what to take out, and never answers where it goes.
Quick answer: stop trying to fit the corrections into the always-loaded file. Put a short list of triggers there instead — observable moments like “about to claim something is done” or “about to ship anything someone outside will see” — each of which tells the agent to go open a separate registry and check it before acting. In my own workspace that trigger block is 11 lines and 130 words, and it backs a registry of 115 dated corrections totalling 17,853 words. All 115 are in force. None of them are in the context window until a trigger fires.
Three Ways to Split the File, and Only One Handles Corrections
Splitting an instruction file is not a new idea, and I want to be precise about which part of this is. Two split strategies are already well covered, and neither one solves this problem.
Split by directory. This is the AGENTS.md format's own recommendation: put another AGENTS.md inside each package, and agents read the nearest file in the tree, so the closest one takes precedence. It works, and it works at scale — the spec notes that OpenAI's main repository has 88 of them. The lookup key is where the file you are editing lives.
Split by task. This is progressive disclosure, and Tian Pan's piece already proposes it: keep a compact root file and move task-specific guidance into separate documents the agent loads on demand. Also correct. The lookup key is what the agent set out to do — it is about to run the tests, so it opens the testing document.
Now notice what a correction actually is. A correction is knowledge the agent does not know it needs. That is not incidental, it is the definition: if the agent had known the rule applied, it would not have made the mistake that generated the rule. So neither key retrieves it. Directory does not, because a deploy mistake is not a property of a folder. Task does not, because an agent that has just finished a page and is about to call it shipped does not think “I should consult the deployment-mistakes document.” It thinks it is done. That is precisely the state the correction exists to interrupt.
| Split strategy | Lookup key | Good for | Fails on corrections because… |
|---|---|---|---|
By directorynested AGENTS.md | where the file lives | per-package build and style conventions | a mistake is a property of an action, not a folder |
By taskprogressive disclosure | what the agent set out to do | reference material the agent knows to go find | the agent does not know it needs it — that is why it erred |
By triggerfailure registry | a moment the agent is about to pass through | accumulated corrections | — |
A Trigger Is Not a Topic
The whole design rests on the trigger list being short enough to keep permanently loaded and specific enough to actually fire. Three properties do that work.
A trigger names an observable action, not a subject area. “Be careful with deployments” is a topic, and it fires never, because there is no instant at which an agent can tell whether it is currently being careful. “About to claim something is scheduled, sent, confirmed, done, fixed, or validated” is an action, and the agent can tell — it is about to type one of those words. The list of verbs is doing real work there: it converts a judgment call into something close to a string match against the agent's own draft output.
A trigger fires before the action, not after. This sounds obvious and is the most common way a rule gets written uselessly. “Deployments must be verified” is evaluated at review time, which is after the damage. “Before you say the word done, go check” is evaluated at the only moment when intervention is still free.
A trigger points at exactly one file. If the instruction is “check the relevant documentation,” the agent has to decide what is relevant, which is a second judgment call layered on top of the one it already got wrong. One named file, one grep, no discretion.
The shape, concretely. The always-loaded file carries a block that reads roughly: fires on draft / dispatch / edit / send, then four bullet-length trigger conditions, then a single sentence — on any trigger, read the registry and grep for matching entries before acting; treat it as authoritative, it overrides fresh-session recommendations that contradict it. That last clause matters more than it looks. Without it, a capable model with strong priors will confidently re-derive a recommendation the registry already recorded as a mistake, and prefer its own reasoning to the written record.
What Goes in an Entry — and Why the Date Is Load-Bearing
Each entry in mine carries five things: a greppable ID, the symptom as it actually appeared, the condition under which it fires, the fix, and the dated incident that caused the entry to exist.
That last field is the one people leave out, and it is the one that determines whether the registry survives its second year. Without an origin date, every entry reads as equally current and equally load-bearing, so nobody ever deletes one, and the registry grows until it is exactly as unusable as the four-hundred-line file it was supposed to replace — just relocated. With a date, entries become auditable. You can ask of any entry whether its underlying cause was fixed at the root, and retire it if so. Deletions are the point. A registry that only grows is a registry that is slowly failing.
Three Corrections That Earned Their Entry
These are from my own sites. Each is in the registry because it actually happened, not because it seemed like a sensible rule to write.
“A URL in the sitemap is not evidence the page was deployed.” A deploy shipped the homepage and the sitemap — both of which referenced a new post — and never uploaded the post file itself. Net effect for three days: the homepage linked to a 404, and the sitemap submitted one to Google. The file had been sitting in the repository the whole time. A second page repeated the same shape and sat at 404 for two weeks before anyone noticed. The correction is not “be careful when deploying”; it is the specific, checkable instruction to curl the new page itself after every deploy, not the index that links to it.
“Corrections propagate to tables; they don't propagate to sentences.” A set of benchmark figures was corrected across the tech site after a measurement audit — every table updated, every page checked. Three weeks later a new post cited the old numbers in prose, because whoever wrote it pulled them from memory and from an older post rather than from the corrected source, which was on disk the entire time. The resulting rule is narrow and mechanical: when a new page cites an existing measurement, re-open the source of record; never carry a number from memory or from another page. A later incident forced an extension — re-reading the source for the value turned out not to be enough, because a page had attached invented settings to a genuinely measured number. Copy the conditions verbatim, or write “not logged.”
“Two sessions on one machine race the git index.” This is my favourite, because the guardrail already in place did not cover it. A one-writer-per-repository rule was in force and being followed. It did not help, because the git index is per-repository, not per-session: two agent sessions on the same machine satisfy that rule and still collide. What happened was that one session staged files and its commit command failed to bind, leaving the work staged; the next commit by the other session swept those files into an unrelated message. On a later occurrence it was worse than a mislabel — a commit carried stale staged copies of two files and silently reverted edits it had never touched, under a message about something else entirely. The fix is one line: stage and commit in a single command, or use git commit -o <file> -m <msg> to bypass the index, so the staged window is effectively zero.
None of these three could have been derived from first principles by a smarter model. They are facts about a specific environment, discovered by breaking it. That is what a registry is for, and it is why “just use a better model” does not retire the pattern.
AGENTS.md or CLAUDE.md?
Both — but neither should be the source of truth twice. AGENTS.md is the vendor-neutral format, read by a long list of tools including Codex, Cursor, Gemini CLI, Copilot, Zed, Aider, Windsurf and Devin. CLAUDE.md is Claude Code's equivalent, GEMINI.md serves some Google tooling, and the AGENTS.md spec does not mention either of them — so reconciling them is left to you.
The failure mode when more than one agent works in a repository is not that a file is missing. It is that three files exist, all of them plausible, and they have quietly drifted apart, so behavior depends on which tool you happened to open. What I do instead is keep AGENTS.md as the single canonical file and make the others thin shims that import it and add nothing but a pointer or two. Measured this morning: the canonical file is 4,057 words, the Claude shim is 100 words, and the Gemini shim is 161. A behavior change gets made once.
The Numbers, Including the One That Argues Against Me
Measured with wc on 2026-09-04:
| File | Role | Loaded | Size |
|---|---|---|---|
AGENTS.md | canonical entry file | every session | 153 lines / 4,057 words |
| ↳ trigger block | routes to the registry | every session | 11 lines / 130 words |
CLAUDE.md | shim, imports the above | every Claude session | 100 words |
GEMINI.md | shim, imports the above | every Gemini session | 161 words |
PITFALLS.md | failure registry | only when a trigger fires | 115 entries / 17,853 words |
The ratio is the argument. The registry is 4.0× the byte size of the entry file that points at it, and roughly 137× the size of the trigger block that does the actual pointing. Put another way: 115 accumulated corrections cost about 1.1 words each of permanent context budget. Fold those same 115 entries into the always-loaded file and you are carrying something like 22,000 words of standing instructions, which is well into the range where the published measurements say an agent follows fewer rules, not more.
Here is the number that cuts against me, and I would rather print it than have you find it. Tian Pan's data puts effective instruction files at a few hundred words, with the correlation going negative past about a thousand. My entry file is 4,057 words. By that standard it is roughly four times too big even after the split. The split bought a real reduction in what would otherwise be loaded every session; it did not buy a file inside the published sweet spot. Both of those are true, and the second one is the next job rather than a footnote. If you take one measurement from this page, take the trigger block — 130 words — and not the entry file it happens to live in.
Building with agents in a real repo?
I run a free community for people building real data and AI pipelines — warehouse modeling, analytics, and AI-augmented workflows. No course, no paywall, just practitioners shipping.
Join the free AI community →Frequently Asked Questions
Related reading: I Ran Claude Code and Codex Head-to-Head — two agents working the same spec in the same repo, which is the situation this file structure exists to survive. Multi-Model Verification: Catching LLM Hallucinations in Enterprise Reports — the same don't-trust-a-single-pass discipline, applied to output instead of instructions. Governing AI Agents' Data Access — the other half of agent governance: constraining what an agent may read, rather than how it behaves. AI as an Operations Layer — where these agents actually run. For the hardware side, see Blendlogic Tech.
What would make this wrong
- n=1 workspace, and I built it. Every number here is measured, but they are all measurements of one environment designed by the person arguing for the design. I have not run the counterfactual — the same 115 corrections inlined into the entry file, same tasks, compliance compared. Until someone does, the mechanism is reasoned from published length research plus my own incident record, not demonstrated by controlled test.
- I cannot prove the triggers fire reliably. I can show the registry catches things, because entries have been added since it was in place. I cannot show the rate at which an agent passed through a trigger moment and silently failed to check — that is the measurement that would actually settle this, and I have no instrumentation for it. A trigger that fires half the time still beats a rule lost in a long file, but “better” is a weaker claim than the one this page is making.
- My own entry file fails the standard I am citing. At 4,057 words it is roughly four times past the point where the length research shows negative correlation. If that research is right, some of what I attribute to the split is being partly cancelled by an entry file that is still too big.
- Stale entries are a real recurring cost, not a hypothetical. The example in the FAQ — four items named as outstanding that were all already done — was found by accident during unrelated work, which means the audit interval is currently “whenever someone happens to notice.” A registry with no scheduled re-audit will eventually cost more than it saves, and mine does not have one yet.
- Harness features may absorb this. If agent runtimes ship reliable rule retrieval — hooks that fire deterministically on tool calls, or automatic retrieval over a rules corpus — a hand-written trigger block becomes a workaround for a gap that closed. The durable part would be the registry and its dated entries; the trigger list is the part most likely to be obsoleted.
- Small projects should not do this. If you have not yet corrected the same mistake twice, you do not have a registry problem, and building this structure is ceremony. The honest trigger for adopting it is a correction you have had to write down more than once — not a diagram that looks incomplete without it.
Get the build notes
Real AI experiments — what shipped, what failed, and the setups behind them. Straight to your inbox.
No spam, unsubscribe anytime.
You're in — check your inbox for a welcome note.