Your CLAUDE.md is a junk drawer: a migration playbook
Standardizing the filename did not fix the file. Here is how to graduate a pile of markdown into something an agent can actually use.
Open the root of almost any repo that has been running coding agents for a while and you find a drawer:
your-repo/
├── CLAUDE.md # Claude Code reads this
├── AGENTS.md # the "standard" one
├── .cursorrules # Cursor's legacy rules file
├── .github/copilot-instructions.md # Copilot reads this
├── memory.md # the agent appends here, unattended, every session
├── product.md # someone added this once
├── context.md # nobody remembers who
├── decisions.md # 3 entries, last touched 6 months ago
└── docs/
└── CLAUDE.md # a nested override that contradicts the root one
Every session, most of it loads. The decision that governs the task in front of the agent is somewhere in that pile. So is its opposite, written eight months ago and never deleted. This is a junk drawer: the place where things end up when there is no proper place for them. The interesting question is not how it got messy. It is why tidying it never works.
The filename war is over. The problem it was hiding is not.
For a year the friction looked like a naming problem. Every tool wanted its own file, so you kept several copies of the same intentions in slightly different dialects. That part is genuinely being solved. AGENTS.md, released by OpenAI in August 2025, was contributed to the Linux Foundation on December 9, 2025 as part of the new Agentic AI Foundation, and it now ships in dozens of tools across more than 60,000 open source projects. The industry agreed on one name for the drawer. Good.
But standardizing the name of the drawer does not empty it. The convention tells every tool to read the same file; it says nothing about what belongs in that file, how much of it, or whether any line is still true. The hard part was never which filename the agent opens. It was that we are using a flat file as the store for something that is not flat.
There is no correct length, and that is the whole problem
Here is the bind, and it is worth being precise because it is the reason you keep re-tuning the file and it keeps feeling wrong. A flat context file gives you exactly two knobs, and both of them break.
| Your only two knobs on a flat file | What you do | What breaks |
|---|---|---|
| Keep it lean | Trim it so the agent is not drowning | The decision the agent needed was one of the lines you cut, so it produces a plausible answer that violates a choice your team already made |
| Keep it complete | Append everything, delete nothing | The whole pile loads every run, so the one decision that binds this task is buried, and you pay to re-read the stale remainder on every session |
| (there is no third knob) | A single file cannot be both complete and selective, because those are properties of a store, not of a document |
Trim toward the first failure or hoard toward the second: there is no setting in between that escapes both, because "complete" and "short" are in direct tension for a flat file and can only be reconciled by something that stores everything and returns a little. The mechanics of why a buried decision gets read past, even inside a large context window, are the subject of an earlier post here, so I will not re-derive them. The point for this playbook is narrower: you cannot tune your way out, so stop trying to find the right length and change what you are tuning.
Why the drawer fills in the first place
A drawer becomes a junk drawer for one structural reason: it has no compartments, so unlike things pile into the same space. A flat context file has the same defect. It has no schema, so four different kinds of thing end up on adjacent lines, each of which actually wants a completely different home:
- Style and convention rules. "Use Vitest, not Jest." "Two-space indent." These are lint rules wearing prose.
- Setup and command lore. "Run
make devfirst." "The migration step needs the VPN." These are scripts and docs wearing prose. - Genuine decisions with a rationale. "We removed the retry wrapper because it masked a real timeout, see the incident." This is the only category that is actually context, and it is the one a flat file holds worst, because it flattens the decision down to the claim and drops the rationale, the status, and the author.
- Dead entries. Lines that were true once, describe code that no longer exists, or contradict a newer line three files away.
Once you see the four piles, the migration is obvious, because most of what is in the drawer was never context at all. It was other things with nowhere better to go.
The playbook
Step 1: Sort the drawer into the four piles. Read the file and tag every line as style, command, decision, or dead. This is tedious exactly once and it is the whole game, because it reveals that the file you thought was your agent's brain is mostly a linter config and a runbook that wandered into the wrong room.
Step 2: Evict the piles that have a real home. Style rules move to the linter and formatter, where they are enforced instead of merely suggested, and where the agent cannot skim past them because the CI gate does not skim. Command lore moves to scripts, a Makefile, or task docs. Dead lines get deleted outright. In practice this evicts the large majority of the file, and none of it was context you will miss, because it now lives somewhere that actually applies it.
Step 3: Give the survivors the fields a line of prose cannot hold. What remains is the decision pile, and this is the part worth migrating rather than deleting. A decision is not a sentence; it is a record with a rationale (why this over the obvious alternative), a status (does it still hold, or was it superseded), and an author (who had the standing to decide it). A flat file keeps only the sentence and loses the other three, which is why agents honor the letter of a CLAUDE.md rule and miss the reason it existed. Turn each surviving decision into that record. The argument for exactly which fields a decision store must carry, and why there are seven of them, is made in a previous post; here you are just applying the conclusion.
Step 4: Find the lines that are lying. The reason the drawer is dangerous, not just messy, is that stale entries do not announce themselves. Two moves surface them cheaply. First, sort your decisions by last-touched date and treat anything old and unconfirmed as suspect until re-checked, the same way you treat a stale cache. Second, scan for contradictions: the nested docs/CLAUDE.md that overrides the root, the decision that a later commit quietly reversed. A store with a real status field lets you mark the loser superseded instead of leaving two live lines that disagree and hoping the agent picks the right one.
Step 5: Change the write path so it stays graduated. The drawer did not fill because people are messy. It filled because the only way to record a decision was to remember, later, to append a line to a file, and that manual write path is unbounded work that scales with how fast you ship. If the migration ends with a clean file and the same append-when-you-remember habit, you have bought yourself a few good months and the drawer will refill. The durable version captures a decision at the moment it is made, from the act itself, so the store stays current without a standing tax on everyone's memory. That capture path is its own subject, covered here.
What you get for the trouble
You get the third knob the flat file could never offer. Everything is stored, so nothing is lost to keep the file short; and only the few decisions that bind the current task are returned, so nothing is buried to keep the file complete. Completeness lives at rest, selection happens at read time, and the Goldilocks bind simply dissolves, because "how long should the file be" was the wrong question. The right length of what the agent reads is however many decisions actually govern this task, which is a number a store can compute and a document can only guess.
We built Brief to be that store, and to do the capture in Step 5 without the manual write path. But the honest center of this post survives without us: Steps 1 and 2 are worth doing this afternoon with nothing but a linter and the delete key, and they will shrink your context file more than any prompt tweak. The migration is not a product. It is what you do once you notice the drawer was never a database and stop asking it to behave like one.
What this does and does not claim
It does not claim AGENTS.md is a mistake. A single conventional filename is a real improvement over five dialects, and for small, stable, genuinely global rules a short flat file is fine and always was. The claim is narrower: the file is the wrong home for the high-cardinality, fast-changing, authored thing we call a decision, and standardizing the filename does not change that. It does not claim the sort is glamorous; it is a chore. And it does not claim you will never touch the file again, only that most of what lives in it today belongs in a linter, a script, or a store, and moving it there is the migration.
Frequently asked questions
How long should a CLAUDE.md or AGENTS.md file be? There is no correct length, which is the tell that length is the wrong dial. Short enough to avoid burying the agent means cutting decisions it needs; long enough to be complete means burying them anyway and paying to re-read the rest each session. Keep the file for small, stable, global conventions, and move decisions with a rationale and a lifecycle into a store you can query, so the length of what the agent reads is set by the task, not by you.
Should I delete my CLAUDE.md or AGENTS.md? No. Keep it for the narrow job it is good at: a handful of stable, global conventions that rarely change. Migrate out of it the two things it holds badly, style and command rules that belong in a linter or scripts, and genuine decisions that need a rationale, a status, and an author. What is left is a short, honest file rather than a junk drawer.
AGENTS.md is the standard now, does that solve the problem? It solves the naming problem, which is real and worth solving: tools now agree on one file to read. It does not touch the data-model problem. Standardizing which file the agent opens says nothing about what belongs in it, how much, or whether a given line is still true, and those are the questions that make a context file rot.
Why does my coding agent ignore my CLAUDE.md? Usually because the relevant line is buried among many that do not apply to the current task, so it is read past rather than read, or because the line it followed had no rationale attached and it honored the letter while missing the reason. Both are symptoms of a flat file doing a store's job: no selection to surface the few lines that matter now, and no schema to carry the why alongside the what.
What belongs in AGENTS.md versus a decision store? Put in the file what is stable, global, and cheap to always apply: formatting conventions, the build command, the test runner. Put in a store what is specific, evolving, and reasoned: the architectural choices, the rejected alternatives and why they were rejected, the constraints that hold until they are superseded. The rule of thumb is that anything with a "because" and an expiry date wants a store, and anything that is just a standing convention can stay in the file.
← Back to Blog