Every repository we work in has a CLAUDE.md, and most of the work in them is done by an AI agent. At first we wrote that file the way you'd write onboarding docs for a new hire: what the project is, the stack, a tour of the folders, the coding conventions. Thorough and welcoming.
The agent ignored roughly half of it. So we wrote more rules, the file got longer, and compliance got worse.
The problem wasn't the amount of documentation. It was the kind. We had written a README; what the job needed was a contract.
1. Don't Write Down What the Agent Already Does
The early version contained lines like these.
All true. All unnecessary. An agent does these without being asked — they're general good practice, already baked in.
And they aren't free. A long file buries the rules that matter. If 27 lines out of 30 are things anyone would do anyway, the other three read like more of the same.
If no, delete it. What survives is the things this repository does differently — which is the only reason the file exists.
2. Keep Only the Judgment Calls
After the cut, the surviving rules mostly looked like this.
The second rule is the interesting one. General good practice says "move inline styles into a stylesheet." Here the opposite is correct. Leave it unwritten and the agent helpfully refactors — pulling the inline styles out of a passthrough-copied page and quietly breaking something.
The third rule points the other way, in the same repository. Policy splits by page type. Nothing in the code tells you whether that split is intentional or an accident.
So there are three kinds of rule worth writing down:
- Things that contradict general practice — otherwise the agent will "fix" them.
- Things that split within one repository — otherwise it generalizes from the first example it sees.
- Things that leave no trace in the code — external systems, deploy procedures, agreements with other repos.
3. Every Prohibition Needs a Reason
Bare prohibitions hold poorly. A prohibition with a reason generalizes to adjacent cases.
An agent that read the second version makes the same call later when it meets app-ads.txt or a .well-known domain-verification file. The first version says nothing about those.
For the same reason, "do X" beats "don't do Y." A prohibition with no alternative just sends the agent looking for a way around it. "Write vanilla JS; don't introduce a new client framework" held up far better than "don't use React."
4. Spell Out How to Verify
This section had the largest effect of anything we added. It defines what "done" means.
The second half matters far more than the first. The default assumption is that a green build means the work is done; this states explicitly what the build cannot see.
That last line earns its place surprisingly often. It's a one-sentence rule against reporting a check that never happened.
5. Rules a Document Can't Enforce Belong in Code
This is the real conclusion. The more important a rule is, the less it belongs in the document.
Every post on this site has to exist in Korean and English. Originally that was just a bold line in the rules file — and posts still shipped in one locale only. A document can go unread, and even when read it fades partway through a long task.
So we moved it into a build hook. Add a post in one locale now and the build fails.
The difference is categorical. A documented rule is something it would be good to follow; a build rule is something you cannot proceed without. An agent can skim past a paragraph. It cannot skim past a failing build.
Needing emphasis means the rule gets broken often, and rules that get broken often keep getting broken no matter how much you emphasize them.
Not everything can move, of course. "Translations shouldn't read like machine translation" has no automated check. Leave that class of rule in the document and migrate everything that a check can express.
6. Reporting Rules — Say What Must Be Said
The last section we added, and one we're glad we did.
The real risk with agent work isn't a wrong thing reported as right — that gets caught in review. It's half the work reported as all of it, which doesn't. Deciding in advance what must always be mentioned closes a good deal of that gap.
7. In Summary
The file ended up less than half its original length, and compliance clearly improved. The principles:
- Don't write what would happen anyway. It buries what wouldn't.
- Keep only genuine judgment calls — against general practice, split within the repo, or invisible in the code.
- Attach a reason to every prohibition. Reasons generalize; bare rules don't.
- State how to verify, especially what the build misses.
- Move checkable rules into code. The document is the fallback, not the mechanism.
- Say what must be reported. It exposes half-finished work.
If your CLAUDE.md reads like a README, take another look at it. The reader isn't someone new to the project — it's a collaborator who already knows every general convention and none of your exceptions. The file only needs to carry the difference.