Atlas
TechnicalFrom Atlas

Claude Code Rules: Path-Scoped Instructions

Split a bloated CLAUDE.md into .claude/rules files that load only for matching paths. Setup, glob patterns, limits, debugging and an audit step.

The short version

  • A rule file in .claude/rules with a paths field loads only when Claude works with a matching file; without paths it loads at launch.
  • Aim for under 200 lines per CLAUDE.md. Move guidance for one part of the codebase into path-scoped rules, because @imports do not reduce context cost.
  • Rules and CLAUDE.md are context, not enforcement: anything that must always happen belongs in a hook, and anything that must never happen in a permissions deny rule.
  • Run /context to see what loaded at launch, and /doctor prompt-audit (Claude Code v2.1.283 or later) to find outdated or conflicting instructions.
On this page
  1. The short version
  2. Why split CLAUDE.md into rules?
  3. How do I set up .claude/rules?
  4. How do path-scoped rules work?
  5. A worked example: three rules for a TypeScript monorepo
  6. What are the size limits?
  7. How do I share rules across projects?
  8. How do I check which rules actually loaded?
  9. Can I audit my instruction files for conflicts?
  10. What rules cannot do
  11. How Atlas fits in
  12. Conclusion
  13. Questions people ask

Claude Code rules let you split one long CLAUDE.md into small files under .claude/rules/, and scope each file to the paths it applies to. A rule with a paths field loads only when Claude works with a matching file, so API guidance does not sit in context while it edits CSS. This article shows the setup, the glob syntax, the size limits that bite, and how to debug a rule that does not seem to apply. It is based on Anthropic's Claude Code memory documentation, plus the hooks guide for the section on enforcement.

Why split CLAUDE.md into rules?

Claude treats CLAUDE.md as context, not enforced configuration. The documentation says the more specific and concise your instructions are, the more consistently Claude follows them, and it sets a target of under 200 lines per CLAUDE.md file. Longer files consume more context and reduce adherence.

A growing project file usually mixes three kinds of content:

  • Rules for the whole repository (how to run tests, branch naming).
  • Rules for one area (API handlers, database migrations, React components).
  • Procedures that are only needed for one task (how to cut a release).

The first kind belongs in CLAUDE.md. The second belongs in path-scoped rules. The third is better as a skill, which loads only when you invoke it or when Claude decides it is relevant to your prompt.

One trap: imports do not help here. @path/to/file imports are expanded and loaded together with the CLAUDE.md that references them, so they organize a long file but do not shrink its context cost.

How do I set up .claude/rules?

Put markdown files in .claude/rules/. Each file should cover one topic and have a descriptive name such as testing.md or api-design.md. All .md files are discovered recursively, so subdirectories such as frontend/ and backend/ work.

text
your-project/
├── .claude/
│   ├── CLAUDE.md
│   └── rules/
│       ├── code-style.md
│       ├── testing.md
│       └── security.md

A rule file without paths frontmatter loads at launch, with the same priority as .claude/CLAUDE.md. So moving a topic into rules/testing.md is a tidy-up, not yet a saving. The saving comes from adding paths.

How do path-scoped rules work?

Add YAML frontmatter with a paths list:

markdown
---
paths:
  - "src/api/**/*.ts"
---

# API Development Rules

- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation comments

A path-scoped rule loads when Claude uses the Read, Write or Edit tool on a matching file. It also loads when Claude views a matching file with a Bash command that counts as a read, such as cat or head on a single file. Until then it is not in context.

Patterns are relative to the rule's base directory. For project rules that is the directory containing the .claude folder. For user-level rules in ~/.claude/rules/ it is the session's primary working directory.

Glob patterns that work

PatternMatches
**/*.tsAll TypeScript files in any directory
src/**/*All files under src/
*.mdMarkdown files in the project root
src/components/*.tsxReact components in one directory

You can list several patterns and use brace expansion:

markdown
---
paths:
  - "src/**/*.{ts,tsx}"
  - "lib/**/*.ts"
  - "tests/**/*.test.ts"
---

Each brace group multiplies the patterns: src/*.{ts,tsx} becomes two, and {a,b}/{c,d}/*.{ts,tsx} becomes eight. A rule's whole paths list shares one budget of 1,000 expanded patterns and 4 MiB, and patterns without braces do not count against it. A pattern that would exceed the budget is used unexpanded, and its literal braces match no files.

Two more details. paths is the only frontmatter field Claude Code reads from a rule; any other field is ignored without an error. paths accepts a YAML list or a comma-separated string. If the YAML does not parse, the frontmatter is ignored and the rule loads as if it had no paths, so it quietly becomes an always-on rule. Run claude --debug to see the parse error.

A worked example: three rules for a TypeScript monorepo

Suppose your root CLAUDE.md is 320 lines. A reasonable split:

text
CLAUDE.md                      # under 200 lines: commands, branching, definition of done
.claude/rules/api.md           # paths: ["apps/api/**/*.ts"]
.claude/rules/web.md           # paths: ["apps/web/**/*.{ts,tsx}"]
.claude/rules/migrations.md    # paths: ["db/migrations/**/*.sql"]

Write each rule so it can be checked, as the documentation advises. "Use 2-space indentation" beats "format code properly", and "API handlers live in src/api/handlers/" beats "keep files organized". A migrations rule might say that every migration needs a matching rollback file. The root file keeps only what applies to every task.

What are the size limits?

Three numbers are worth knowing:

  • 200 lines is the target for each CLAUDE.md file. If an instruction file is over the recommended length, you see a warning at startup and in /status.
  • 4 MiB is the ceiling for a file loaded at launch. Claude Code skips a larger file and loads none of it.
  • Per-file limits for on-demand files. Subdirectory CLAUDE.md files and path-scoped rules are cut off if they are too long: 40,000 characters on a 200K context window, and on a 1M window 200,000 characters for Claude Opus 4.6 and Sonnet 4.6 and 150,000 for later models. Claude then gets only the start of the file, plus a note to read the rest with the Read tool. Check with wc -m path/to/file.md. This limit applies from v2.1.309; earlier versions did not apply it to on-demand files.

Each CLAUDE.md, rules file and @path import counts as a separate file for the length warning. You also get a warning when files that are each within the length add up past a combined limit at session start.

How do I share rules across projects?

.claude/rules/ supports symlinks, and circular links are handled:

bash
ln -s ~/shared-claude-rules .claude/rules/shared
ln -s ~/company-standards/security.md .claude/rules/security.md

A symlink whose target is outside your working directory is treated like an external import. It does not load until you approve external imports for the project, and after approval only the linked rules without a paths field load. To load shared rules without that approval, keep them in ~/.claude/rules/, which applies to every project on your machine. User rules load before project rules, and neither overrides the other, so if they conflict Claude may follow either.

For an organization-wide file, the documentation describes a managed CLAUDE.md at /etc/claude-code/CLAUDE.md on Linux and WSL, and /Library/Application Support/ClaudeCode/CLAUDE.md on macOS. Use it for guidance, and use managed settings such as permissions.deny for enforcement.

How do I check which rules actually loaded?

Run /context and read the list under Memory files. If a file is not there, Claude cannot see it. Path-scoped rules and subdirectory CLAUDE.md files will not appear at launch because they load on demand. When a subdirectory CLAUDE.md loads, a Loaded line with its path appears in the terminal. To test a new nested file, create it from your shell rather than asking Claude to write it, then ask Claude to read a file in that folder.

For a log of which CLAUDE.md and rules files loaded, when and why, the documentation points to the InstructionsLoaded hook. It does not fire for an AGENTS.md that Claude reads directly through the Project instructions setting.

Worktrees matter too: to have path-scoped rules load for files in a sibling git worktree, start Claude Code in that worktree or move the session there with /cd.

Can I audit my instruction files for conflicts?

Yes. Run /doctor prompt-audit in a session. It requires Claude Code v2.1.283 or later, and it runs through the bundled /claude-api skill, so it is unavailable while that skill is turned off. Claude looks for instructions written for older models, references to files or commands that do not exist, and files that contradict each other, then reports findings with proposed edits. Nothing changes until you ask Claude to apply them. By default it covers CLAUDE.md, CLAUDE.local.md and AGENTS.md plus the rules, skills, commands, subagents and output styles under .claude/ and ~/.claude/. Pass a path to audit one file or folder, for example /doctor prompt-audit .claude/skills/deploy.

Contradictions are the quiet cost. If two instructions conflict, the documentation warns that Claude may pick one arbitrarily, so review nested CLAUDE.md files and .claude/rules/ periodically.

What rules cannot do

Rules are advice. CLAUDE.md content is delivered as a user message after the system prompt, and there is no guarantee of strict compliance. If something must happen at a fixed moment, such as tests before every commit, use a hook: the hooks guide describes hooks as deterministic control, so certain actions always happen rather than relying on the model to choose. To block an action regardless of what Claude decides, the memory documentation points to a PreToolUse hook, and for organization-wide blocking it points to managed settings such as permissions.deny.

Instructions given only in conversation are lost on /compact. The root CLAUDE.md is re-read from disk after compaction, and nested files and path-scoped rules load again on demand, so anything durable should be written to a file.

If your repository also serves other coding tools, Claude Code can read an AGENTS.md directly when there is no CLAUDE.md in your working directory or above it (this needs v2.1.277 or later). Files in .claude/rules/ keep loading alongside it. If you have a CLAUDE.md, put an @AGENTS.md import in it to share one file.

How Atlas fits in

Atlas runs each engineer as its own Claude Code session with a written role and its own working folder, with model and effort tuned to the role. Atlas does not yet split a project's instructions by folder. That is coming to Atlas, built in, so it will need no setup. Until then, write path-scoped rules by hand in your project as described above.

Conclusion

Keep CLAUDE.md short and universal. Move area-specific guidance into .claude/rules/ files with paths, turn one-off procedures into skills, and put hard requirements in hooks and permissions. Then run /context to see what loaded and /doctor prompt-audit to catch conflicts. Repeat that review periodically, or whenever Claude starts ignoring something you wrote.

Questions people ask

What is .claude/rules in Claude Code?

It is a folder of markdown files in your project, one topic per file, that Claude Code loads as instructions. Files without a paths field load at launch; files with a paths field load only when Claude works with matching files.

How do I make a Claude Code rule apply only to certain files?

Add YAML frontmatter with a paths list of glob patterns, such as src/api/**/*.ts. The rule loads when Claude reads, writes or edits a matching file, or views it with a Bash command that counts as a read, such as cat or head.

Do @imports in CLAUDE.md save context?

No. Imported files load together with the CLAUDE.md that imports them, so imports help organization but not context cost. Path-scoped rules are the documented way to load instructions only when Claude works with matching files.

How can I tell which CLAUDE.md and rules files Claude loaded?

Run /context and check the Memory files list for what loaded at launch. Path-scoped rules and subdirectory files load on demand and do not appear there. An InstructionsLoaded hook can log what loaded, when and why.

Can I check my instruction files for conflicts?

Run /doctor prompt-audit on Claude Code v2.1.283 or later. It reports outdated, broken or contradictory instructions with proposed edits, and changes nothing until you ask it to apply them.

Sources

  1. How Claude remembers your project (Claude Code memory docs)
  2. Automate actions with hooks (Claude Code hooks guide)

Researched and drafted with Claude, then checked against the sources above. Atlas is an independent product, not affiliated with Anthropic or OpenAI. Claude and Claude Code are trademarks of Anthropic; Codex is a product of OpenAI.