Quick answer

CLAUDE.md is a Markdown file that supplies persistent instructions and project context to Claude Code. It is guidance in the model context, not an executable policy engine. Put stable team conventions in the project file, personal cross-project preferences in ~/.claude/CLAUDE.md, and specialized guidance near the code it governs.

The strongest rules describe an observable workflow: a trigger, a required check, a stop condition, and evidence. Security boundaries that must be guaranteed belong in permissions or hooks, not prose alone.

What CLAUDE.md is and where it loads from

Claude Code starts each session with a fresh context window. CLAUDE.md files carry your written instructions into that window. Files are additive: a more specific file does not erase the broader file. Conflicting instructions therefore remain a conflict, even though guidance closer to the working directory is later and usually more specific.

Common instruction scopes and their intended use
Scope Location Good content
User/global ~/.claude/CLAUDE.md Personal preferences that apply across repositories
Project ./CLAUDE.md or ./.claude/CLAUDE.md Shared architecture, commands, and workflow rules
Local project ./CLAUDE.local.md Uncommitted machine-specific notes
Nested packages/api/CLAUDE.md Instructions that apply only inside that subtree

At launch, Claude Code walks upward from the current working directory and loads CLAUDE.md and CLAUDE.local.md files it finds. Ordering runs from the filesystem root toward the working directory; within one directory, the local file is appended after CLAUDE.md. Child-directory files below the working directory load on demand when Claude reads a file in that subtree.

repo/
├── CLAUDE.md                 # project-wide, loaded at launch
├── .claude/
│   └── rules/
│       └── testing.md        # modular project rule
└── packages/
    └── payments/
        └── CLAUDE.md         # loads when payments files are read

An @path/to/file line can import another file. Relative imports resolve from the file containing the import. Imports improve organization, but they do not save context: imported content still enters the window. Claude Code reads CLAUDE.md directly, not AGENTS.md; import an existing AGENTS.md from CLAUDE.md if both tools must share it.

What changes agent behavior—and what gets ignored

Concrete instructions change behavior most reliably. Name the file pattern or operation that activates the rule, give an exact command or inspection, define the condition that blocks further work, and require an artifact or command result. “Use best practices” provides no decision procedure. “When changing an API route, run the contract test and stop if it fails” does.

Some text is literally excluded or never loaded. Block-level HTML comments are stripped before injection. Import syntax inside fenced code is an example, not an import. Instructions in unrelated child directories are absent until that subtree is read. CLAUDE.md files in directories supplied with --add-dir do not load unless additional-directory memory loading is enabled.

Other rules are not ignored mechanically but are easy to lose: vague prose, duplicated policy, contradictions, long reference dumps, or edits made after the startup file was already loaded. Start a fresh session, use /clear, or compact before expecting a changed startup rule to apply. Finally, a prose instruction cannot guarantee access control. Use settings permissions or a hook for a non-negotiable block.

Six CLAUDE.md example rules that are testable

Each example uses the same four-part contract. Adapt paths and commands to the repository; do not paste commands your project cannot actually run.

1. Database migration safety

## Database migrations
- Trigger: Any change under `db/migrations/`.
- Check: Run `bin/migrate-check --dry-run` against a disposable database.
- Stop: Do not continue if the check reports data loss or a non-reversible step.
- Evidence: Report the command, exit code, and generated migration plan path.

This turns “be careful with migrations” into a gate. The disposable-database constraint also prevents the check itself from becoming destructive.

2. API contract changes

## API contracts
- Trigger: Editing `src/api/**` or `openapi.yaml`.
- Check: Run `npm run test:contract` and `npm run openapi:diff`.
- Stop: Stop if a response field is removed without a versioned migration note.
- Evidence: Include both exit codes and summarize any public schema delta.

The trigger prevents this expensive check from firing on an unrelated documentation edit, while the stop condition catches a specific compatibility risk.

3. Generated-file discipline

## Generated clients
- Trigger: A change to `schema/*.graphql`.
- Check: Run `make generate` followed by `git diff --exit-code -- generated/`.
- Stop: Do not hand-edit files under `generated/`.
- Evidence: Report whether regeneration was clean and list changed generated files.

Generated output often drifts because the instruction says only “regenerate clients.” This version states the source, the forbidden action, and the clean-tree proof.

4. Scoped frontend verification

## User-facing UI
- Trigger: Changing a component, CSS, copy, or interaction.
- Check: Run `npm test` and inspect the changed flow at 375px and 1280px widths.
- Stop: Stop if keyboard focus is hidden or the browser console has new errors.
- Evidence: Record tested routes, viewport widths, and screenshot paths.

“Make it responsive” is subjective. Named viewports, focus behavior, console state, and screenshots are reviewable.

5. Dependency-change containment

## Dependencies
- Trigger: Editing a manifest or lockfile.
- Check: Explain why the dependency is needed; run the focused test suite and audit command.
- Stop: Do not replace the lockfile wholesale or add an unmaintained package.
- Evidence: Name the package/version, affected transitive packages, and command results.

This rule avoids pretending that one package-manager command fits every stack. The repository can replace “audit command” with its real npm, pnpm, Cargo, or other tool invocation.

6. Completion claims

## Completion
- Trigger: Before saying a task is complete.
- Check: Run the smallest relevant tests, linter, and type check from this repository.
- Stop: Do not claim success after a failed check; fix it or classify the blocker.
- Evidence: Report exact commands, exit codes, changed files, and remaining limitations.

This is a high-leverage global project rule because it changes the definition of “done.” Keep the project’s actual command map nearby so “relevant” does not become an excuse to skip checks.

Avoid CLAUDE.md context-budget pitfalls

Every always-loaded instruction competes with the conversation, file contents, tool output, skills, and auto memory. Anthropic recommends targeting fewer than 200 lines per CLAUDE.md. That is a practical attention target, not a reason to compress a giant manual into unreadable one-line bullets.

  1. Keep only facts and rules needed in most sessions at the project root. Move rare procedures into skills or linked docs.
  2. Put package-specific guidance in nested files or path-scoped .claude/rules/ files.
  3. Do not import README files merely because they exist. Imports reorganize tokens; they do not reduce them.
  4. Delete repeated defaults and stale exceptions. One current command is stronger than three historical alternatives.
  5. Audit contradictions across user, parent, project, local, nested, and rules files before blaming the model.

After compaction, project-root CLAUDE.md and unscoped rules are re-injected. Nested and path-scoped instructions reload only after Claude reads a matching file again. If a rule must remain active throughout a long task, keep its essential gate at the project root and leave detailed package guidance nested.

How to test that a CLAUDE.md rule binds

Test loading and adherence separately. First, start a fresh Claude Code session from the directory whose hierarchy you intend to test. Run /memory and confirm the expected user, project, local, nested, and rule files appear. A missing file is a resolution problem; a listed file with poor behavior is a writing or conflict problem.

Paste your file into the free CLAUDE.md Auditor to see which of these rules an agent cannot act on. It runs entirely in the browser and reports checks it cannot evaluate as not evaluated rather than as a pass. If the file is long, read what happens when CLAUDE.md gets too long.

mkdir -p /tmp/claude-rule-probe/src
cd /tmp/claude-rule-probe
git init
printf 'probe\n' > src/example.txt
claude

Use a harmless, observable probe rule in the temporary repo: “Trigger: before proposing an edit under src/. Check: read src/example.txt. Stop: do not edit. Evidence: begin the plan with RULE-PROBE and quote the first word.” Ask Claude to propose an edit, not make one. The expected result is specific and the stop condition prevents mutation.

Repeat from the repository root and from a nested directory to test hierarchy. For a nested file, ask Claude to read a file in that subtree before the probe; nested instructions load on demand. Change one variable per run. If the probe fails, inspect /memory, remove conflicts, shorten the rule, start fresh, and retry. For deeper auditing, the InstructionsLoaded hook can log which instruction file was loaded, when, and why.

Do not use a dangerous command as a compliance test. Proving that prose discourages deletion is not the same as enforcing a deny rule. Test behavior with a reversible marker; test security controls through the permission or hook mechanism that actually blocks the action.

Primary sources