CLAUDE.md that actually works: four patterns from practice
A project instruction file — CLAUDE.md, AGENTS.md or whatever your tool calls it — is the cheapest piece of equipment you own. It is read along at
every session, so every line that sits in it needlessly is a line you pay for a thousand times. And
every line that is missing, you pay for in rework.
Below are four patterns that make the difference in practice, each with its counterargument. They assume a homelab-style setup: your own machines, your own data, several agents working on the same repository.
1. Write down prohibitions, not wishes
"Write clean code" does nothing. An agent cannot test whether it complies. A prohibition can be tested, and that is exactly what you want.
## Harde regels
- Nooit `rm -rf`, glob-deletes of recursieve chmod/chown op home- of volumeroots.
- Nooit een bestand wijzigen zonder eerst `bestand.bak.$(date +%Y%m%d_%H%M%S)`.
- Nooit een dienst herstarten zonder eerst de status te tonen en te wachten op akkoord.
- Bij twijfel: één controle te veel boven dataverlies.
Counterargument: too many prohibitions make an agent passive, and then it asks permission at every step. Stick to rules where a mistake is irreversible. Anything you can undo does not belong on this list.
2. Put in the map of your system, not the manual
An agent does not get lost in your code, it gets lost in your infrastructure: which port, which host, which config file, what runs natively and what runs in a container. That map is short and rarely changes — perfect for an instruction file.
## Waar dingen draaien
| Dienst | Host | Poort | Beheer |
|---------------|-------------|-------|-------------------|
| model-router | mac .135 | 8087 | systemd (native) |
| fallback-laag | mac .135 | 8093 | systemd (native) |
| reverse proxy | nas .176 | 8090 | docker |
Kritieke diensten draaien native op schijf, niet alleen in een dockerstack.
What does not belong in it: explanations the agent can look up itself. Point to the file instead of copying it, otherwise your instruction file falls behind reality — and an outdated map is worse than no map.
3. Describe the verification step, not just the task
The most expensive failure pattern with agents is not an error but a reported successful completion that is not true. So write down what "done" looks like.
## Klaar betekent
- De test draaide en je plakt de laatste 5 regels output in je antwoord.
- Voor een webwijziging: HTTP-status van de betrokken URL, geen "zou moeten werken".
- Voor een configwijziging: `systemctl is-active` van de dienst.
This is the same idea as measuring agents: judge the outcome, not the promise. The method for that is in our piece on evaluating an AI agent, and the failure patterns you catch early this way are in debugging agentic loops.
4. One rule about money, and put it at the top
As soon as an agent calls external models or paid services, the limit belongs in the instruction file — not in your head.
## Geld
- Nooit een abonnement afsluiten of een betaling doen zonder schriftelijke toestemming.
- Dure modellen alleen voor de eindstap; verkenning gaat via het goedkope profiel.
- Meld het geschatte verbruik van een taak vóór je hem uitvoert, niet erna.
If you want to enforce this structurally instead of asking the agent, pin it down one layer lower with hard cost limits and a kill switch. An instruction file is an agreement; a quota is a limit. You want both.
What to leave out
- Style preferences a linter can enforce. Put them in the linter.
- Long stories about the architecture. Those go stale; point to the design document.
- Secrets, hostnames of private networks and API keys. An instruction file ends up in every session, and sometimes in a log line.
- Pleasantries. "Be helpful" costs tokens and delivers nothing.
How to maintain it
Treat the file as code: version control, and one line added at the moment you have fixed a mistake you do not want to repeat. That is the only reliable way it should grow. Rules you add "just in case" are rarely tested and weaken the rest.