If your agent skips instructions you put in CLAUDE.md, the file is probably too long and too specific. The fix is not louder emphasis - it is a shorter, more universal file, with everything else moved behind progressive disclosure: loaded only when a task actually calls for it, not on every turn.
Definition
CLAUDE.md - a project file (named AGENTS.md in some other tools) that Claude Code loads at the start of every session as standing instructions. It is the agent’s onboarding surface: agents start each session with no memory of your codebase.
What it costs
CLAUDE.md is not free background knowledge. It loads at session start and stays in context on every turn, so each line competes for attention with your actual task. Length is a tax, paid continuously.
A working target, from HumanLayer’s write-up on the file: under 300 lines is best, shorter is better, and their own production file runs under 60. Past that ceiling, expect the agent to start discounting the file.
Why it gets ignored
Start with the mechanism, because it is not a quirk of model attention - it is the harness doing what it was built to do.
Claude Code delivers CLAUDE.md as a <system_reminder> that explicitly tells the model the contents “may or may not be relevant.” That is the instruction the file arrives wrapped in. Your rules are not system-level configuration the model must obey; they are context the model is invited to assess. Once you know that, “why did it ignore my file” stops being mysterious - you handed it something it was told to evaluate for relevance, and it did.
Two failure modes follow, both made worse by length:
- Relevance filtering. The model judges the file against the task in front of it. When much of it reads as irrelevant, the agent discounts the whole thing - including the parts that did matter. This is the documented delivery mechanism above, not a theory about attention.
- Instruction budget. Every instruction you add dilutes the others. HumanLayer pegs reliable adherence at roughly 150–200 instructions for frontier thinking models, and puts Claude Code’s own system prompt at about 50 individual instructions before your file loads - so padding
CLAUDE.mdwith situational rules burns a finite budget on low-value lines.
The through-line: task-specific content in a file that loads for every task is the problem. You are not writing a policy document the agent must follow. You are writing an argument for relevance that it re-reads every turn.
What to include (and exclude)
Anthropic’s best-practices guidance is to put in only what the agent can’t infer:
| Include | Exclude |
|---|---|
| Non-guessable shell commands | Anything obvious from the code or types |
| The project’s test runner | Restating existing docs |
| Code style that differs from defaults | One-off, task-specific steps |
| Repo etiquette and architecture decisions | Long examples better kept in a linked doc |
| Environment quirks and gotchas | Style rules a formatter can enforce |
A useful test: if a competent new contributor could figure it out from the repo in a minute, it doesn’t belong in CLAUDE.md. See keep CLAUDE.md to universal instructions.
A lean file that survives the relevance filter looks like this:
# CLAUDE.md
## Commands
- Test: <non-default test runner>
- Build: <non-guessable build command>
## Conventions
- <code style a formatter can't enforce>
## Architecture
- <one-line decision a newcomer can't infer>
@docs/architecture.md # pulled in only when referenced
Move the rest behind progressive disclosure
Everything that isn’t universal still has a home - just not one that loads every turn:
@path/to/fileimports - pull in a doc only where referenced.- Skills - package a domain workflow the agent loads when the task calls for it.
- Child-directory
CLAUDE.md- scope instructions to the subtree they apply to, loaded on demand. - Separate reference docs - keep the big architecture map or PRD out of the always-on file.
This keeps the always-loaded surface small and high-signal, while the detail stays reachable exactly when it’s needed.
If a section has to stay in the file, scope it out loud. Since the model is already assessing relevance, say when a block applies instead of leaving it to infer: “when working on database migrations:” ahead of the migration rules. HumanLayer reports noticeably better adherence from wrapping sections in conditional tags on tasks where only some of the file should apply. It is the cheap version of progressive disclosure - the content still loads every turn, but a section the model can rule out fast stops dragging the rest of the file down with it.
Don’t use the model as a linter
Style and formatting rules are cheaper and more reliably enforced by tooling - formatters, a Stop hook, or a slash command - than by instructions the agent has to remember every turn. HumanLayer’s version of the rule: never send an LLM to do a linter’s job. Reserve CLAUDE.md for what only prose can convey.
The gap between the two is larger than “a bit more reliable”. Take one rule, state it in CLAUDE.md, and run the same task repeatedly: it gets violated - not occasionally, but routinely, and more often the longer the session runs, because a rule stated three hundred turns ago is competing with everything since. Measured on one adversarial task, a 129-instruction file carrying an explicit verify rule at line 36 returned the same one-word reply as a workspace with no rules at all: a 129-rule CLAUDE.md replied like an empty one. Move the identical rule into a PreToolUse hook that exits 2 and the violations stop, permanently. Not because the model improved, but because the model is no longer the thing being asked.
That is the actual distinction, and it isn’t about reliability at all:
CLAUDE.mdis advisory. It is text the model reads and weighs, which is exactly what the<system_reminder>wrapper tells it to do. Probabilistic by construction.- A hook is deterministic. It is code the harness runs at a fixed lifecycle event. If the command matches, it is blocked - regardless of the model, the context state, or how long the session has run.
Hooks also cost nothing in context, since they are code the harness executes rather than instructions Claude has to keep reading past. So the rule of thumb is stronger than “prefer tooling for formatting”: every rule you can express as a check is a rule you should stop writing as a sentence. What’s left in CLAUDE.md afterwards is the part that genuinely needed prose - and it’s short enough to survive the relevance filter. See hook over prose.
Bottom line
A CLAUDE.md the agent actually follows is short, universal, and ruthlessly pruned. Treat it as the one always-loaded surface and push everything situational behind progressive disclosure - the same context-engineering discipline that governs the rest of the window. It’s one of ten guardrails in the vibe-coding field manual.
To start from these rules instead of a blank file, run npx leanharness - a ten-file starter whose CLAUDE.md skeleton is this article condensed to placeholders, shipped with the checklist, skills, and subagents that keep it honest.