Writing Instructions That Stick
- Write CLAUDE.md instructions with the specificity and structure that maximizes adherence within the 200-line performance threshold
- Apply the include vs exclude test to prune instructions that degrade attention without improving behavior
- Diagnose compliance failures using /memory, load verification, conflict checking, and the InstructionsLoaded hook
When Claude Ignores Your Instructions
You have written a careful CLAUDE.md. You have described your code style, your testing preferences, your commit message format. And then Claude ignores half of it. Not all of it — some rules are followed perfectly. Others seem to evaporate by the middle of the session. You correct Claude, it improves, and then reverts two turns later.
This is not random. There are specific, diagnosable reasons why CLAUDE.md instructions fail, and most of them come down to three causes: the file is too long, the instructions are too vague, or there are conflicting rules that cause Claude to pick one arbitrarily. This lesson covers all three, plus the tools for figuring out which problem you have.
The 200-Line Budget
CLAUDE.md files are loaded into the context window at the start of every session, consuming tokens alongside your conversation. There is a practical ceiling on how much content Claude can consistently attend to: around 200 lines per CLAUDE.md file. Beyond that, adherence degrades — not because Claude refuses, but because instructions buried deep in a long file receive less reliable attention as the context window fills over the course of a session.
This does not mean 200 lines of dense content. It means 200 lines of the instructions that actually matter — the rules Claude would get wrong without them. Every other line is noise that dilutes the signal.
If your CLAUDE.md is growing large, two mechanisms help: path-scoped rules (covered in lesson 5) move instructions into topic files that only load when relevant, and pruning removes instructions Claude already follows correctly on its own. Both approaches reduce the size of the always-loaded context block.
Structure: Headers and Bullets Over Paragraphs
Claude scans CLAUDE.md the same way a human reader would: organized sections with clear headers are easier to parse than dense prose paragraphs. Use markdown headers to group related instructions and bullets for individual rules. Keep each section focused on one area — code style, workflow, testing, git conventions.
This is not just aesthetic. Well-structured CLAUDE.md files are more reliably followed because Claude can locate and apply specific rules in context. A rule buried in the middle of a long paragraph is harder to retrieve and apply correctly than the same rule as a bullet under a clear header.
Specificity: The Test That Matters
Every instruction in your CLAUDE.md should pass one test: is it specific enough that two developers reading it would agree on whether Claude complied?
Consider the difference between these pairs:
- Vague: "Format code properly" — Specific: "Use 2-space indentation"
- Vague: "Test your changes" — Specific: "Run
npm testbefore committing" - Vague: "Keep files organized" — Specific: "API handlers live in
src/api/handlers/"
Vague instructions leave room for interpretation. That room gets filled differently depending on what else is in context. Specific instructions produce consistent behavior because there is only one correct interpretation.
What to Include vs Exclude
Before adding any instruction to CLAUDE.md, ask: would Claude make a mistake without this? If the answer is no — if Claude already does this correctly on its own, or if it is standard practice for the language — cut it. Bloated CLAUDE.md files cause Claude to lose track of the instructions that actually matter.
A useful mental model: CLAUDE.md should capture the things a new developer would need to learn about this specific project that they could not infer from reading the code. Build and test commands that are non-obvious. Architectural decisions that are project-specific. Naming conventions that differ from language defaults. Non-obvious gotchas. What not to include: anything Claude can infer from the code, standard language conventions, long explanations, and information that changes frequently.
Adding emphasis helps for rules Claude keeps missing. Phrases like IMPORTANT or YOU MUST before a rule genuinely improve adherence — use them for requirements that have caused repeated problems, not as a general inflation technique. If everything is important, nothing is.
HTML Comments for Maintainer Notes
Block-level HTML comments in CLAUDE.md — written as <!-- your note here --> — are stripped before the content enters Claude's context. This means you can leave notes for human maintainers of the CLAUDE.md file without spending context tokens on them. Comments inside code blocks are preserved. When you open the file directly, comments remain visible.
This is useful for documenting why a rule exists, who requested it, or what problem it was addressing — context that matters for the person editing CLAUDE.md but that Claude does not need.
Treating CLAUDE.md Like Code
The healthiest CLAUDE.md files are maintained like a codebase: reviewed when something goes wrong, pruned of dead entries, updated when conventions change. An instruction that made sense six months ago may be wrong today. An instruction that was added for a problem that no longer exists is now just noise.
Build a review habit: when Claude makes the same mistake twice, check whether CLAUDE.md already addresses it (and the instruction needs to be more specific) or whether a new instruction is needed. When a correction holds reliably for two months, check whether the corresponding CLAUDE.md instruction is still necessary.
The /init command with CLAUDE_CODE_NEW_INIT=1 provides a useful starting point for new projects. It explores the codebase with a subagent, fills in gaps via follow-up questions, and presents a reviewable proposal before writing anything. Even if you maintain CLAUDE.md manually, running /init on an existing project can surface gaps in what you have documented.
Troubleshooting: When Instructions Are Ignored
When Claude is not following a CLAUDE.md instruction, work through this sequence:
First, verify the file is loaded. Run /memory and check that your CLAUDE.md appears in the list. If it does not, Claude cannot see it. The most common causes are the file being in the wrong location or a path mismatch.
Second, look for conflicting instructions. If multiple CLAUDE.md files contain different guidance for the same behavior, Claude may pick one arbitrarily. Check all loaded files and resolve the conflict by removing the duplicate or making one instruction clearly take precedence.
Third, make the instruction more specific. Vague instructions are the most common cause of non-compliance. Replace abstractions with concrete, verifiable rules.
Fourth, check file length. If the file is over 200 lines, the instruction may be getting lost. Move infrequently-needed rules to path-scoped rules files or skills.
For systematic debugging, the InstructionsLoaded hook logs exactly which instruction files loaded, when they loaded, and why. This is especially useful for debugging path-specific rules or lazy-loaded files in subdirectories where you need to verify that conditional loading is firing at the expected moment.
Finally: if an instruction must be followed every single time, regardless of what Claude decides, it belongs in a hook, not CLAUDE.md. Hooks are deterministic — they execute as shell commands at fixed lifecycle events. CLAUDE.md is advisory. The right tool depends on how critical the compliance requirement is.
- Adherence degrades past 200 lines — if your CLAUDE.md is longer, Claude may follow some rules and silently ignore others, with no indication of which ones it is missing
- Specific beats general every time — "Run npm test before committing" produces reliable behavior; "test your changes" does not, because it leaves room for interpretation that changes as context fills
- Treat CLAUDE.md like code — review it when something goes wrong, prune entries Claude already gets right without the instruction, and test changes by observing whether behavior actually shifts
- When Claude ignores an instruction, the first debug step is running /memory to verify the file is loaded, then checking for conflicting instructions across all loaded CLAUDE.md files
- If an action must happen regardless of what Claude decides, a hook is the right tool — CLAUDE.md provides guidance that Claude tries to follow, not a safety gate that fires unconditionally