Half of the "Claude Code is ignoring my rules" reports I see have the same root cause: the rule lives in a file Claude Code never loaded. The memory system reads a specific set of files, in a specific order, with a few loading rules that are easy to get backwards. Here is the full lookup order, verified against the official memory docs (code.claude.com/docs/en/memory) on 2026-07-31.
The four memory scopes
Claude Code merges memory from four locations, listed here from broadest to narrowest:
| Scope | Path (macOS) | Shared with |
|---|---|---|
| Managed policy | /Library/Application Support/ClaudeCode/CLAUDE.md |
Everyone in the org (IT-deployed) |
| User | ~/.claude/CLAUDE.md |
Just you, across all projects |
| Project | ./CLAUDE.md |
Your team, via git |
| Project local | ./CLAUDE.local.md |
Just you, this project (auto-gitignored) |
Two details people miss:
-
CLAUDE.local.mdis loaded after the sharedCLAUDE.mdat the same level. That makes it the right place for personal overrides — your sandbox URLs, your preferred test filters — without touching the team file. - The managed policy file exists on Linux and Windows too, at different paths. If a rule appears that nobody on the team wrote, check there first.
What loads at launch vs. on demand
This is the part that explains most "why didn't it load" confusion:
At launch, Claude Code walks up from your working directory. Start it in repo/apps/web and it loads repo/apps/web/CLAUDE.md, repo/apps/CLAUDE.md, repo/CLAUDE.md, and so on above — all in full, concatenated from the root down to your cwd. Instructions closer to your working directory appear later in the context, closest to your actual task.
Subdirectory CLAUDE.md files do not load at launch. A file like repo/apps/web/tests/CLAUDE.md (below your cwd) only loads when Claude actually reads a file inside that subtree. This is by design — you can give each package its own conventions without paying the token cost until the agent goes there. But it also means: if you test your memory setup by asking "what are my rules?" at the repo root, the subdirectory files will look invisible. They are lazy, not broken.
One more launch-time surprise: directories you attach with --add-dir do not get their CLAUDE.md loaded. That only happens if you set CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1.
Imports: the @path syntax
Any memory file can pull in other files:
See @README.md for the project overview and @package.json for scripts.
# Personal preferences
- @~/.claude/my-project-instructions.md
The rules that matter in practice:
-
Relative paths resolve relative to the file containing the import, not your cwd. A
@./shared/rules.mdinsideapps/web/CLAUDE.mdpoints intoapps/web/shared/. - Imports load at launch, together with the importing file. Splitting a huge CLAUDE.md into imported chunks reorganizes it; it does not reduce the context cost.
- Max import depth is 4 hops. Deep chains silently stop resolving past that.
- Imports inside code spans and code blocks are ignored —
`@anthropic-ai/claude-code`in a snippet will not trigger a file read. - Importing a file from outside your project directory triggers an approval dialog the first time, so a malicious repo cannot silently pull your
~/.claudefiles into context.
Using AGENTS.md without duplicating it
Claude Code does not read AGENTS.md natively. The documented pattern is a one-line project CLAUDE.md:
@AGENTS.md
That keeps one source of truth for multi-tool teams (Codex, Cursor agents, etc.) while Claude Code loads it through its normal import path. A symlink works too, with the caveat that creating symlinks on Windows requires admin rights — the import line avoids that entirely.
Scoped rules in .claude/rules/
Instead of one monolithic CLAUDE.md, you can split rules into .claude/rules/*.md. Discovery is recursive, and individual rule files can be path-scoped so they only apply when Claude works on matching files. Combined with the documented target of keeping memory files under ~200 lines, this is the sane way to scale a large repo's conventions: a small always-on core, plus scoped rules that activate where they are relevant.
For monorepos there is also claudeMdExcludes in settings — a glob list that suppresses specific CLAUDE.md files from loading. It works at any settings layer, and the arrays merge across layers.
Small print that bites
-
HTML comments (
<!-- ... -->) are stripped before injection. Useful for maintainer notes that should not spend tokens — but remember they are preserved inside code blocks, so a commented example still costs what it weighs. -
Auto memory has a budget. The
/memorycommand toggles it (autoMemoryEnabledin settings), and only the first 200 lines / 25KB ofMEMORY.mdare loaded each session. If your agent "forgets" something it wrote down, check whether it fell below that line.
A 60-second debug checklist
When a rule is not applying:
- Is the file in one of the four scopes, or below your cwd? Below-cwd files load lazily.
- Started Claude Code from a subdirectory? Files above you load; siblings do not.
- Is the rule past an import chain deeper than 4 hops?
- Is the import accidentally inside a code fence?
- Monorepo: is the file matched by a
claudeMdExcludesglob? - Wrapped in an HTML comment outside a code block? Then it was stripped.
Every one of these has produced a real "the AI ignores my instructions" bug report that was actually a loading rule working exactly as documented.
Most of the value in a rules file is knowing which lines earn their token cost — that is the curation work behind the AI Coding Starter, a $1 set of ten cross-tool rules already shaped for CLAUDE.md, .cursorrules, and AGENTS.md.
I post one field-tested note a day on AI coding workflows on Bluesky: @ai-shop.bsky.social.
Top comments (0)