CLAUDE.md is delivered as a user message after the system prompt, not as configuration. It is read and weighed,
never enforced — which is why a rule that must hold every time belongs in a hook or a permission, and why the goal here
is compliance, not completeness. A short file that gets followed beats a full one that gets ignored.
A CLAUDE.md is instruction text. Invoke prompt-engineering for the wording, the instruction budget, and the
timelessness rules that govern every line written here. This skill covers only what is specific to the CLAUDE.md and
.claude/rules/ artifacts — what loads when, which layer owns which content, and why a stated rule gets ignored.
What Loads, and When
Routing and trimming decisions are wrong whenever the loading model is wrong. Establish this first.
- CLAUDE.md and CLAUDE.local.md load at launch from the working directory and every directory above it. Content is
ordered from the filesystem root down, so the file closest to the launch directory is read last. Within one directory,
CLAUDE.local.md is appended after CLAUDE.md.
- Files in subdirectories below the working directory do not load at launch. They load when Claude reads a file in
that directory. A rule that must hold from the first turn cannot live in a nested CLAUDE.md.
- Layer scope, broadest to narrowest — managed policy (
/Library/Application Support/ClaudeCode/CLAUDE.md on macOS,
/etc/claude-code/CLAUDE.md on Linux and WSL, C:\Program Files\ClaudeCode\CLAUDE.md on Windows) → ~/.claude/ →
the project (./CLAUDE.md or ./.claude/CLAUDE.md) → ./CLAUDE.local.md. Managed policy cannot be excluded.
- Load order is not precedence. Every discovered file is concatenated; when two layers contradict, Claude may follow
either. Reconcile the conflict rather than relying on "later wins".
@path imports expand at launch, up to four hops deep. Splitting a large CLAUDE.md into imports buys organization
and never buys context. A path inside backticks stays literal instead of importing.
- A CLAUDE.md over 4 MiB is skipped entirely — no warning in the file itself.
- Block-level HTML comments are stripped before injection. Notes for human maintainers cost no tokens.
claudeMdExcludes skips files by absolute-path glob, set at any settings layer, with arrays merging across
layers. It is the monorepo tool for another team's files, and it excludes their rules along with their CLAUDE.md.
- Verify what actually loaded with
/context, under Memory files. The InstructionsLoaded hook logs each file
as it loads, which is how a lazily-loaded rule is debugged.
Rules Files
- Every
.md under .claude/rules/ is discovered recursively. Subdirectories such as frontend/ and backend/
are a supported layout, and nested .claude/rules/ directories deeper in the tree load on demand. Centralizing every
rule at the repository root is a governance choice, never a requirement.
- A rule without
paths loads at launch at the same priority as .claude/CLAUDE.md. It costs exactly what a
CLAUDE.md line costs.
- A rule with
paths triggers when Claude reads a matching file, not on every tool use. This is the one mechanism
that genuinely reduces baseline context.
~/.claude/rules/ loads before project rules, so a project rule outranks a personal one on the same topic.
- Plugins cannot ship rules. The plugin component set has no rules entry, and a CLAUDE.md at a plugin root is not
loaded as project context. Conventions that must reach every install go in a skill; a rule is written by hand in the
consuming project.
After Compaction
- The project-root CLAUDE.md survives — it is re-read from disk and re-injected.
- Nested CLAUDE.md files and
paths-scoped rules do not. They reload when Claude next reads a file they apply to.
- An instruction given only in conversation is gone. Write it into CLAUDE.md to make it persist.
Routing Content to a Layer
- CLAUDE.md — project identity, capability map, conventions, constraints. Applies to every task regardless of
domain.
.claude/rules/ — conventions scoped to a file type or a path, via glob paths. Lighter than a skill, no
SKILL.md ceremony.
- Skills — procedural workflows and domain expertise for one type of work. Loaded on demand.
- Hooks — anything that must happen without Claude's judgment. Execute at fixed lifecycle events.
- Settings — permissions, environment variables, model configuration. Structural, not instructional.
- Auto memory — user preferences and cross-session context Claude writes for itself.
The test: universal rule → CLAUDE.md. Scoped to file types or paths → .claude/rules/. Scoped to a kind of work →
skill. Must happen automatically → hook.
Prefer the path fence. When one glob covers exactly the files a rule governs, put the rule in .claude/rules/ with
paths — not once CLAUDE.md grows too long, but on the way in, while it is still short. A scoped rule is the only layer
that costs nothing until it is relevant, and it arrives in context beside the file it applies to instead of competing
for attention with every unrelated rule from the first turn.
Keep the rule in CLAUDE.md when the fence leaks — the glob matches files the rule does not govern, or misses files
it does — or when the rule must hold before Claude reads any file. A fence that needs a growing list of patterns to stay
accurate is leaking; state the rule once at the root instead.
Instructions are not enforcement. Models route around soft constraints stated as prose — working from a different
directory to dodge a path restriction, rephrasing to dodge a wording rule. Anything that must never happen goes in
permissions, sandbox configuration, or a hook. CLAUDE.md states working defaults.
Where the record goes instead. Past work → commit messages and the tracker. A lesson from one incident → memory,
promoted to a CLAUDE.md rule only on recurrence. A decision → one present-tense rule here, with any why longer than a
clause moved to an ADR the rule links to.
What Belongs in CLAUDE.md
Two tests, both mandatory. If removing an instruction would not change output quality, cut it. If Claude can infer it by
reading the codebase, cut it.
Include:
- Capability map — which module owns which functionality, and where new code of each kind goes. An ownership map, never
a directory tree
- Stack and tooling — frameworks, test runners, package managers, build tools
- Conventions that differ from language defaults — naming, import style, error handling
- Decisions as present-tense rules, with at most a one-clause causal why
- Verification workflow — the exact commands for test, lint, and build
- Critical constraints — the "never modify X", "always do Y before Z" rules
- Gotchas Claude gets wrong without being told
Exclude:
- Generic best practices and language fundamentals — these are defaults, or they belong in a language skill
- Procedural workflows with strict ordering — these belong in a skill
- Ephemeral state — sprint goals, in-flight migrations, temporary flags. These belong in the tracker
- Project history — changelogs, session logs, migration narratives, abandoned approaches. A described abandoned approach
reads as an available option and gets resurrected
- Directory trees and file listings — anything reproducible with
ls
- Automated behaviors — "whenever X happens, do Y" is a hook, not an instruction
Writing the File
- Every instruction must be concrete enough that two agents cannot diverge on it. Exact paths, exact command names,
exact patterns. An instruction that resists being made concrete does not belong.
- Present tense only. A CLAUDE.md states what is true, never how the project got here: "we migrated from REST to
gRPC" becomes "services communicate over gRPC".
- Temporal markers rot silently — "recently", "new", "now uses", "as of March". Delete the marker or the whole line.
- Prose only in the identity block, the top 10–15% of the file. Everything operational is bullets; a critical rule
cannot hide inside a paragraph, and prose-wrapped rules that conflict produce a compromise instead of either rule.
- A contestable decision carries one causal clause — "IDs are UUIDs — prevents enumeration, enables offline
generation". It stops the model from "fixing" the decision. A mechanical rule carries none; explaining
yarn lint
doubles its cost and changes nothing.
- Lists over tables. Commands, conventions, and capability maps are independent entries. A table earns its place
only when rows are compared across columns. Numbered lists only where order is the content.
- Placement follows the U-shaped attention curve — identity and capability map at the top, conventions in the
middle, verification and critical constraints at the bottom. State a truly critical rule at both ends, worded
differently each time.
- State each rule once, in the section that owns the topic. A nested CLAUDE.md carries only what differs from the
root; restating a root rule produces contradictory signals, not emphasis.
Size and Trimming
Target under 200 lines per file — past that, adherence measurably drops. Treat 200 as the trigger for a classification
pass, never as a cap to cut to: a file that stays above it because every block survived the pass is correct.
/doctor proposes trims for a checked-in CLAUDE.md (v2.1.206 and later): it cuts what Claude can derive from the
codebase — directory layouts, dependency lists, architecture overviews — and keeps pitfalls, rationale, and conventions
that differ from tool defaults.
Classify each block when trimming by hand:
- Keep — used in most sessions, safety-critical, easy to violate, or security-sensitive
- Move to
.claude/rules/ — a path- or filetype-scoped convention. With paths frontmatter it stops costing
baseline context
- Extract to a skill — a "when doing X, follow these steps" block
- Remove — stale content, rules Claude follows by default, one rule restated in different words, rationale that
changes no behavior
Three exceptions stay regardless of how rarely they apply: safety-critical content (violating it loses data,
breaches security, or breaks production), easy-to-violate content (Claude gets it wrong without the reminder), and
security-sensitive content (authentication, authorization, secrets, data exposure). The goal is working efficiency, not
a line count — moving a critical rule into a rarely-loaded file is a regression.
Trim when the file passes 200 lines, Claude ignores rules that are present, unrelated domains share one file, or a
human cannot skim it in under 60 seconds.
Diagnosing an Ignored Rule
Work down this list. The first two causes are mechanical and account for most reports.
- Never loaded — the rule lives in a nested CLAUDE.md or a
paths-scoped rule that has not matched a file, in a
directory outside the launch path, or in a file over 4 MiB. It may also be excluded by claudeMdExcludes. Confirm
with /context under Memory files, or the InstructionsLoaded hook. Fix by moving the rule to a layer that loads
when it is needed.
- Vanished mid-session — compaction dropped a nested CLAUDE.md, a
paths-scoped rule, or an instruction that only
ever existed in conversation. Fix by writing it into the project-root CLAUDE.md, which is re-read from disk.
- Buried in noise — the file is too long and the rule sits in the middle. The signal is a file a human cannot skim
in 60 seconds, critical rules inside prose, and several sections restating one thing. Fix by pruning, then promoting
the rule to the top or the bottom.
- Too vague — plausible but wrong output: right style, wrong location; idiomatic patterns, wrong framework. The
signal is abstract language and architecture named as a slogan with no paths. Fix by replacing every abstraction with
a path, a command, or a pattern.
- Stale — Claude cites files that do not exist or tooling the team dropped. Past-tense narration and temporal
markers are the early warning. Fix by auditing against the codebase, then updating the file in the same change as the
architecture, never as a separate task.
- Contradictory — behavior varies between sessions because two layers disagree, or a hook or CI script carries a
shadow instruction. Fix by establishing one canonical rule per concern across all layers.
- Wrong artifact — a rule shaped "when writing tests, always…" competes for attention across every task while
mattering in few. Fix by moving it to a skill, a hook, or a rules file.
Creating a CLAUDE.md
Start at 50–100 lines and iterate from observed failures. A file written from static analysis is a starting point; the
real content comes from where Claude gets things wrong during work.
Detect the stack from config files (package.json, go.mod, Cargo.toml, pyproject.toml, Makefile, CI and linter
configs). Map capabilities to locations. Identify the conventions that differ from language defaults — those are the
only ones worth writing. Apply the deletion test before delivering.
/init generates a starting file, and suggests improvements rather than overwriting when one already exists.
Read [${CLAUDE_SKILL_DIR}/references/scaffold.md] when creating a file from scratch or restructuring an existing one —
it carries the canonical section order with worked examples, the creation workflow, and the monorepo layouts.
Application
When writing or editing a CLAUDE.md:
- Edit surgically. Add a rule into the section that already owns its topic; wholesale rewrites and section reshuffles of
a working file are defects, not cleanups
- Never delete or reword a rule without first verifying against the code that it is stale
- Apply the conventions silently — do not narrate each rule as it is applied
When auditing a CLAUDE.md:
- Read the file end to end before judging it. A premise is carried by sentences no search term predicts, and an audit
assembled from grep hits reports clean on every line it never opened
- Verify each instruction against the codebase: paths exist, commands run, tools are the ones in use
- Cite the specific line and give the replacement inline. Do not lecture
1---2name: claude-md3description: Write and maintain CLAUDE.md and `.claude/rules/` files: which layer loads when, what content belongs in each, and why a stated rule gets ignored.4---56**CLAUDE.md is delivered as a user message after the system prompt, not as configuration.** It is read and weighed,7never enforced — which is why a rule that must hold every time belongs in a hook or a permission, and why the goal here8is compliance, not completeness. A short file that gets followed beats a full one that gets ignored.910<prerequisite>11A CLAUDE.md is instruction text. Invoke `prompt-engineering` for the wording, the instruction budget, and the12timelessness rules that govern every line written here. This skill covers only what is specific to the CLAUDE.md and13`.claude/rules/` artifacts — what loads when, which layer owns which content, and why a stated rule gets ignored.14</prerequisite>1516## What Loads, and When1718Routing and trimming decisions are wrong whenever the loading model is wrong. Establish this first.1920- **CLAUDE.md and CLAUDE.local.md load at launch from the working directory and every directory above it.** Content is21 ordered from the filesystem root down, so the file closest to the launch directory is read last. Within one directory,22 `CLAUDE.local.md` is appended after `CLAUDE.md`.23- **Files in subdirectories below the working directory do not load at launch.** They load when Claude reads a file in24 that directory. A rule that must hold from the first turn cannot live in a nested CLAUDE.md.25- **Layer scope, broadest to narrowest** — managed policy (`/Library/Application Support/ClaudeCode/CLAUDE.md` on macOS,26 `/etc/claude-code/CLAUDE.md` on Linux and WSL, `C:\Program Files\ClaudeCode\CLAUDE.md` on Windows) → `~/.claude/` →27 the project (`./CLAUDE.md` or `./.claude/CLAUDE.md`) → `./CLAUDE.local.md`. Managed policy cannot be excluded.28- **Load order is not precedence.** Every discovered file is concatenated; when two layers contradict, Claude may follow29 either. Reconcile the conflict rather than relying on "later wins".30- **`@path` imports expand at launch**, up to four hops deep. Splitting a large CLAUDE.md into imports buys organization31 and never buys context. A path inside backticks stays literal instead of importing.32- **A CLAUDE.md over 4 MiB is skipped entirely** — no warning in the file itself.33- **Block-level HTML comments are stripped before injection.** Notes for human maintainers cost no tokens.34- **`claudeMdExcludes` skips files by absolute-path glob**, set at any settings layer, with arrays merging across35 layers. It is the monorepo tool for another team's files, and it excludes their rules along with their CLAUDE.md.36- **Verify what actually loaded with `/context`**, under **Memory files**. The `InstructionsLoaded` hook logs each file37 as it loads, which is how a lazily-loaded rule is debugged.3839### Rules Files4041- **Every `.md` under `.claude/rules/` is discovered recursively.** Subdirectories such as `frontend/` and `backend/`42 are a supported layout, and nested `.claude/rules/` directories deeper in the tree load on demand. Centralizing every43 rule at the repository root is a governance choice, never a requirement.44- **A rule without `paths` loads at launch at the same priority as `.claude/CLAUDE.md`.** It costs exactly what a45 CLAUDE.md line costs.46- **A rule with `paths` triggers when Claude reads a matching file**, not on every tool use. This is the one mechanism47 that genuinely reduces baseline context.48- **`~/.claude/rules/` loads before project rules**, so a project rule outranks a personal one on the same topic.49- **Plugins cannot ship rules.** The plugin component set has no rules entry, and a CLAUDE.md at a plugin root is not50 loaded as project context. Conventions that must reach every install go in a skill; a rule is written by hand in the51 consuming project.5253### After Compaction5455- **The project-root CLAUDE.md survives** — it is re-read from disk and re-injected.56- **Nested CLAUDE.md files and `paths`-scoped rules do not.** They reload when Claude next reads a file they apply to.57- **An instruction given only in conversation is gone.** Write it into CLAUDE.md to make it persist.5859## Routing Content to a Layer6061- **CLAUDE.md** — project identity, capability map, conventions, constraints. Applies to every task regardless of62 domain.63- **`.claude/rules/`** — conventions scoped to a file type or a path, via glob `paths`. Lighter than a skill, no64 SKILL.md ceremony.65- **Skills** — procedural workflows and domain expertise for one type of work. Loaded on demand.66- **Hooks** — anything that must happen without Claude's judgment. Execute at fixed lifecycle events.67- **Settings** — permissions, environment variables, model configuration. Structural, not instructional.68- **Auto memory** — user preferences and cross-session context Claude writes for itself.6970**The test:** universal rule → CLAUDE.md. Scoped to file types or paths → `.claude/rules/`. Scoped to a kind of work →71skill. Must happen automatically → hook.7273**Prefer the path fence.** When one glob covers exactly the files a rule governs, put the rule in `.claude/rules/` with74`paths` — not once CLAUDE.md grows too long, but on the way in, while it is still short. A scoped rule is the only layer75that costs nothing until it is relevant, and it arrives in context beside the file it applies to instead of competing76for attention with every unrelated rule from the first turn.7778**Keep the rule in CLAUDE.md when the fence leaks** — the glob matches files the rule does not govern, or misses files79it does — or when the rule must hold before Claude reads any file. A fence that needs a growing list of patterns to stay80accurate is leaking; state the rule once at the root instead.8182**Instructions are not enforcement.** Models route around soft constraints stated as prose — working from a different83directory to dodge a path restriction, rephrasing to dodge a wording rule. Anything that must never happen goes in84permissions, sandbox configuration, or a hook. CLAUDE.md states working defaults.8586**Where the record goes instead.** Past work → commit messages and the tracker. A lesson from one incident → memory,87promoted to a CLAUDE.md rule only on recurrence. A decision → one present-tense rule here, with any why longer than a88clause moved to an ADR the rule links to.8990## What Belongs in CLAUDE.md9192Two tests, both mandatory. If removing an instruction would not change output quality, cut it. If Claude can infer it by93reading the codebase, cut it.9495**Include:**9697- Capability map — which module owns which functionality, and where new code of each kind goes. An ownership map, never98 a directory tree99- Stack and tooling — frameworks, test runners, package managers, build tools100- Conventions that differ from language defaults — naming, import style, error handling101- Decisions as present-tense rules, with at most a one-clause causal why102- Verification workflow — the exact commands for test, lint, and build103- Critical constraints — the "never modify X", "always do Y before Z" rules104- Gotchas Claude gets wrong without being told105106**Exclude:**107108- Generic best practices and language fundamentals — these are defaults, or they belong in a language skill109- Procedural workflows with strict ordering — these belong in a skill110- Ephemeral state — sprint goals, in-flight migrations, temporary flags. These belong in the tracker111- Project history — changelogs, session logs, migration narratives, abandoned approaches. A described abandoned approach112 reads as an available option and gets resurrected113- Directory trees and file listings — anything reproducible with `ls`114- Automated behaviors — "whenever X happens, do Y" is a hook, not an instruction115116## Writing the File117118- **Every instruction must be concrete enough that two agents cannot diverge on it.** Exact paths, exact command names,119 exact patterns. An instruction that resists being made concrete does not belong.120- **Present tense only.** A CLAUDE.md states what is true, never how the project got here: "we migrated from REST to121 gRPC" becomes "services communicate over gRPC".122- **Temporal markers rot silently** — "recently", "new", "now uses", "as of March". Delete the marker or the whole line.123- **Prose only in the identity block**, the top 10–15% of the file. Everything operational is bullets; a critical rule124 cannot hide inside a paragraph, and prose-wrapped rules that conflict produce a compromise instead of either rule.125- **A contestable decision carries one causal clause** — "IDs are UUIDs — prevents enumeration, enables offline126 generation". It stops the model from "fixing" the decision. A mechanical rule carries none; explaining `yarn lint`127 doubles its cost and changes nothing.128- **Lists over tables.** Commands, conventions, and capability maps are independent entries. A table earns its place129 only when rows are compared across columns. Numbered lists only where order is the content.130- **Placement follows the U-shaped attention curve** — identity and capability map at the top, conventions in the131 middle, verification and critical constraints at the bottom. State a truly critical rule at both ends, worded132 differently each time.133- **State each rule once, in the section that owns the topic.** A nested CLAUDE.md carries only what differs from the134 root; restating a root rule produces contradictory signals, not emphasis.135136## Size and Trimming137138Target under 200 lines per file — past that, adherence measurably drops. Treat 200 as the trigger for a classification139pass, never as a cap to cut to: a file that stays above it because every block survived the pass is correct.140141`/doctor` proposes trims for a checked-in CLAUDE.md (v2.1.206 and later): it cuts what Claude can derive from the142codebase — directory layouts, dependency lists, architecture overviews — and keeps pitfalls, rationale, and conventions143that differ from tool defaults.144145Classify each block when trimming by hand:146147- **Keep** — used in most sessions, safety-critical, easy to violate, or security-sensitive148- **Move to `.claude/rules/`** — a path- or filetype-scoped convention. With `paths` frontmatter it stops costing149 baseline context150- **Extract to a skill** — a "when doing X, follow these steps" block151- **Remove** — stale content, rules Claude follows by default, one rule restated in different words, rationale that152 changes no behavior153154**Three exceptions stay regardless of how rarely they apply:** safety-critical content (violating it loses data,155breaches security, or breaks production), easy-to-violate content (Claude gets it wrong without the reminder), and156security-sensitive content (authentication, authorization, secrets, data exposure). The goal is working efficiency, not157a line count — moving a critical rule into a rarely-loaded file is a regression.158159**Trim when** the file passes 200 lines, Claude ignores rules that are present, unrelated domains share one file, or a160human cannot skim it in under 60 seconds.161162## Diagnosing an Ignored Rule163164Work down this list. The first two causes are mechanical and account for most reports.165166- **Never loaded** — the rule lives in a nested CLAUDE.md or a `paths`-scoped rule that has not matched a file, in a167 directory outside the launch path, or in a file over 4 MiB. It may also be excluded by `claudeMdExcludes`. Confirm168 with `/context` under **Memory files**, or the `InstructionsLoaded` hook. Fix by moving the rule to a layer that loads169 when it is needed.170- **Vanished mid-session** — compaction dropped a nested CLAUDE.md, a `paths`-scoped rule, or an instruction that only171 ever existed in conversation. Fix by writing it into the project-root CLAUDE.md, which is re-read from disk.172- **Buried in noise** — the file is too long and the rule sits in the middle. The signal is a file a human cannot skim173 in 60 seconds, critical rules inside prose, and several sections restating one thing. Fix by pruning, then promoting174 the rule to the top or the bottom.175- **Too vague** — plausible but wrong output: right style, wrong location; idiomatic patterns, wrong framework. The176 signal is abstract language and architecture named as a slogan with no paths. Fix by replacing every abstraction with177 a path, a command, or a pattern.178- **Stale** — Claude cites files that do not exist or tooling the team dropped. Past-tense narration and temporal179 markers are the early warning. Fix by auditing against the codebase, then updating the file in the same change as the180 architecture, never as a separate task.181- **Contradictory** — behavior varies between sessions because two layers disagree, or a hook or CI script carries a182 shadow instruction. Fix by establishing one canonical rule per concern across all layers.183- **Wrong artifact** — a rule shaped "when writing tests, always…" competes for attention across every task while184 mattering in few. Fix by moving it to a skill, a hook, or a rules file.185186## Creating a CLAUDE.md187188Start at 50–100 lines and iterate from observed failures. A file written from static analysis is a starting point; the189real content comes from where Claude gets things wrong during work.190191Detect the stack from config files (`package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`, `Makefile`, CI and linter192configs). Map capabilities to locations. Identify the conventions that differ from language defaults — those are the193only ones worth writing. Apply the deletion test before delivering.194195`/init` generates a starting file, and suggests improvements rather than overwriting when one already exists.196197Read [`${CLAUDE_SKILL_DIR}/references/scaffold.md`] when creating a file from scratch or restructuring an existing one —198it carries the canonical section order with worked examples, the creation workflow, and the monorepo layouts.199200## Application201202When **writing or editing** a CLAUDE.md:203204- Edit surgically. Add a rule into the section that already owns its topic; wholesale rewrites and section reshuffles of205 a working file are defects, not cleanups206- Never delete or reword a rule without first verifying against the code that it is stale207- Apply the conventions silently — do not narrate each rule as it is applied208209When **auditing** a CLAUDE.md:210211- Read the file end to end before judging it. A premise is carried by sentences no search term predicts, and an audit212 assembled from grep hits reports clean on every line it never opened213- Verify each instruction against the codebase: paths exist, commands run, tools are the ones in use214- Cite the specific line and give the replacement inline. Do not lecture