# CLAUDE.md Hierarchy

> CLAUDE.md is persistent project memory loaded automatically by Claude Code. A three-level hierarchy (user → project → directory) lets you set global defaults, team standards, and per-directory rules. Project-level files are version-controlled and shared. Use @import to keep CLAUDE.md modular.

**Domain:** D3 · Agent Operations (20% of CCA-F exam)
**Canonical:** https://claudearchitectcertification.com/concepts/claude-md-hierarchy
**Last reviewed:** 2026-05-04

## Quick stats

- **Hierarchy levels:** 3
- **File locations:** 2
- **Import syntax:** @import
- **Exam domain:** D3
- **Hard rule limit:** ,

## What it is

CLAUDE.md is a configuration file for Claude Code that defines project rules, conventions, and architectural decisions. It's not a .gitignore or a README, it's a working set of instructions that Claude reads every time it edits code or runs a command. The hierarchy has three levels: user (~/.claude/CLAUDE.md, your personal defaults), project (.claude/CLAUDE.md or root CLAUDE.md, shared rules), and path-specific (.claude/rules/*.md with glob frontmatter, rules for specific files).

The content is free-form Markdown but structured: stack info, test commands, code-style rules, key architectural decisions, gotchas, and @import directives that pull in modular rule files. Claude parses it as plain text, there's no schema validation, so mistakes in naming or structure cause silent ignores. The real power is reusability: rules travel with the code (version-controlled in .claude/), every teammate sees them on git clone, and new team members onboard faster.

Path-specific rules use YAML frontmatter with a paths glob array. When Claude edits a file matching the glob (e.g. /*.test.tsx), that rule file auto-loads alongside the project CLAUDE.md. This enables scoped rule enforcement without drowning the main CLAUDE.md in per-file details. A testing rule file specifies pytest/Jest conventions, coverage thresholds, naming, all loaded only when you touch a test file.

Production misuse centers on scope creep (main CLAUDE.md becomes 500 lines of every possible rule) and rule inheritance traps (team expects user rules to apply but they don't, user rules are personal, project rules are shared). A contributor clones the repo, uses their personal style from ~/.claude/CLAUDE.md, and produces inconsistent code. The fix is always: put team rules in .claude/CLAUDE.md, never in user files.

## How it works

When Claude Code starts, it loads CLAUDE.md in order: (1) reads user ~/.claude/CLAUDE.md (personal defaults); (2) reads project root .claude/CLAUDE.md or root CLAUDE.md (shared); (3) while editing a file, checks all .claude/rules/*.md files, tests the paths glob against the filename, and loads matches. All loaded content is concatenated and injected as context into Claude's system prompt. The result is a layered set of rules: personal, then project, then path-scoped.

When a .claude/rules/*.md file contains @import ./subdir/rules/testing.md, Claude resolves the import and inlines that file's content. This prevents the main CLAUDE.md from exploding; rules live in modular files and compose via import. Circular imports are not detected and will hang the load. A production gotcha if you @import a file that imports its parent. Keep the import graph acyclic.

Path-specific rules are scoped via glob frontmatter. A testing rule file declares paths: ["/*.test.tsx", "/*.spec.ts"]. When you create or edit a file matching either glob, the rule auto-loads. Token-efficient: irrelevant rules don't load, keeping context focused. A migration rule (paths: ["migrations/*.sql"]) only loads when you touch SQL files.

Claude reads CLAUDE.md once at startup, not continuously. Changes require a session restart (or a manual reload command in newer versions). This is a UX tradeoff: rules are stable within a session (no surprise mid-conversation changes), but editing CLAUDE.md does not take effect immediately. Plan edits before sessions, not during.

## Where you'll see it in production

### Open-source repo onboarding

New contributor clones the repo. Project CLAUDE.md auto-loads: stack, test commands, code-style rules, key decisions. Saves a 30-min onboarding email per contributor. Rules travel with the code; nobody works from outdated docs.

### Monorepo with subteam directories

Frontend team has rules in app/.claude/CLAUDE.md (component patterns, testing conventions); backend has api/.claude/CLAUDE.md (db migration discipline, error handling). Root CLAUDE.md holds shared rules. Editing inside app/ loads frontend rules; inside api/ loads backend rules.

### Personal vault across many projects

Solo dev keeps personal preferences in ~/.claude/CLAUDE.md (preferred indent, commit message format). Each project repo has its own root CLAUDE.md with stack details. Switching projects: project rules change automatically; personal style stays consistent.

## Code examples

### Project CLAUDE.md skeleton

```markdown
# Project: PrecisionCare Navigator

## Stack
- Python 3.11 + FastAPI + Postgres
- React 19 + ShadCN + Tailwind
- Claude Opus for medical NER
- AWS ECS + RDS, region us-east-1

## Commands
- Dev: `make dev` (FastAPI :8000, React :3000)
- Test: `pytest -v --cov=app`
- Lint: `ruff check . && black --check .`
- Deploy: `make deploy ENV=staging`

## Code style
- 4-space Python (Black), 2-space React (Prettier)
- Type hints on every function (mypy strict)
- Named exports only
- Server actions for mutations; route handlers for queries

## Key decisions
- All patient data encrypted at rest and in transit
- Never log PII (mask in middleware)
- Async background work via Celery + Redis (not asyncio in FastAPI)

## Modular rules
@import ./rules/testing.md
@import ./rules/healthcare-compliance.md
@import ./rules/api-design.md

## Don't
- Add new endpoints without a corresponding test
- Mock the database in integration tests
- Commit secrets (use .env.example as the template)

```

> Project CLAUDE.md should fit in ~1000-1500 tokens. Use @import for modular rule files. Lives at repo root, committed to git, shared with the whole team.

### Path-scoped rule file (loaded only when editing matching files)

```markdown
---
paths: ["tests/**/*.py", "**/test_*.py"]
---

# Test Rules, auto-loads only when editing test files

## Naming
- Files: test_<module>.py (mirrors source file path)
- Functions: test_<function>_<scenario>
- Fixtures live in conftest.py at the deepest applicable level

## Patterns
- Use pytest.parametrize for data-driven cases
- Each test asserts ONE behavior (fail message tells you what)
- Mock external services with respx (httpx) or responses (requests)

## Anti-patterns
- Tests that depend on execution order
- Tests that read `os.environ` without monkeypatch
- Snapshot tests checked in without explicit PR review
- `time.sleep` in tests (use freezegun)

## Coverage
- Floor 85% per module
- Branch coverage on policy-critical files (auth, refund, billing)

```

> Path-scoped rules in .claude/rules/*.md auto-load only when matching files are open. Keeps the always-on context lean while enforcing per-folder discipline.

## Looks-right vs actually-wrong

| Looks right | Actually wrong |
|---|---|
| Put all team rules in ~/.claude/CLAUDE.md so they live with each developer. | User-level files are personal and not in the repo. Team rules belong in project-level CLAUDE.md (root, committed). Otherwise new team members miss them. |
| Document every framework convention exhaustively in CLAUDE.md. | CLAUDE.md is appended to every prompt. Bloated files burn tokens and dilute attention. Keep it concise (~1500 tokens). Use @import for modular detail; link to long-form docs. |
| Embed API keys in CLAUDE.md so Claude has them on every session. | CLAUDE.md is committed to git. Secrets leak. Use environment variables and reference them in CLAUDE.md by name (e.g., 'OPENROUTER_API_KEY required in env'). |
| User CLAUDE.md overrides project CLAUDE.md when they conflict. | Order is the opposite. Project CLAUDE.md is loaded after user CLAUDE.md, so project rules take precedence on conflicts (later instructions in the prompt have stronger weight). A teammate's personal ~/.claude/CLAUDE.md cannot override a team rule, that's the whole point of the hierarchy. |
| Edit CLAUDE.md mid-session and Claude will pick up the changes immediately. | CLAUDE.md is loaded once at session start. Changes require either a new session or, in newer Claude Code versions, the /init reload command. Mid-session edits are silent no-ops; this is why teams discover that "my new rule isn't being followed", they edited but didn't restart. |

## Comparison

| Mechanism | Scope | Shared? | Loaded when | Best for |
| --- | --- | --- | --- | --- |
| ~/.claude/CLAUDE.md | All your projects | No (personal) | Every session | Personal preferences, indent style |
| ./CLAUDE.md (project) | One repo | Yes (in git) | Every session in repo | Stack, commands, team standards |
| .claude/rules/*.md | Path-glob scoped | Yes (in git) | When editing matching files | Per-folder conventions (tests, api/) |
| Skills (.claude/skills/) | Task-scoped | Yes (in git) | When task description matches | Reusable workflows (PR review, etc.) |
| @import directives | Inlined into parent CLAUDE.md | Inherits parent's git status | Loaded with parent at session start | Modular rule decomposition |
| AGENTS.md (override file) | Project-wide; non-Claude tools | Yes (in git) | Read by Claude Code at startup | Cross-tool agent instructions (Codex, Cursor, Claude) |

## Decision tree

1. **Does this rule apply to everyone on the team?**
   - **Yes:** Project CLAUDE.md (root) or .claude/rules/. Both committed to git.
   - **No:** Personal preference → ~/.claude/CLAUDE.md.

2. **Does the rule apply only to certain file types or directories?**
   - **Yes:** Use .claude/rules/<topic>.md with frontmatter paths: [...]. Loads on demand.
   - **No:** Project CLAUDE.md root.

3. **Is it a reusable workflow (e.g., PR review process)?**
   - **Yes:** Make a Skill in .claude/skills/, not a CLAUDE.md addition.
   - **No:** Embed in CLAUDE.md.

4. **Is the CLAUDE.md exceeding ~1500 tokens?**
   - **Yes:** Decompose into @import chunks: @import ./rules/testing.md, @import ./rules/security.md. Keeps the always-on context lean and lets you scope detailed rules to topics.
   - **No:** Inline is fine. Optimize for readability.

5. **Are you running other agentic tools (Codex, Cursor) on the same repo?**
   - **Yes:** Add an AGENTS.md file with cross-tool instructions and have CLAUDE.md include @AGENTS.md at the top. Single source of truth across tools.
   - **No:** Plain CLAUDE.md is sufficient.

## Exam-pattern questions

### Q1. A teammate's PRs use a different code style than yours. They have rules in ~/.claude/CLAUDE.md but not in the repo. Fix?

Move team rules to .claude/CLAUDE.md (project root, version-controlled). User-level rules are personal; only project rules are shared via git. Team standards belong in the repo.

### Q2. You add a rule to .claude/CLAUDE.md mid-session. Claude doesn't follow it. Why?

CLAUDE.md is loaded once at session start. Mid-session edits don't take effect until restart. End the session, restart, and the new rules apply.

### Q3. Your testing rule file sits in .claude/rules/testing.md but doesn't auto-load when editing test files. What's missing?

Check the YAML frontmatter paths glob. Make sure it matches your file paths exactly. Try paths: ["/*.test.tsx", "/*.spec.ts"] for broad coverage.

### Q4. You have @import ./shared.md in two CLAUDE.md files, and shared.md has @import ../main.md. Claude Code hangs on load. Why?

Circular import. Claude Code does not detect cycles. Refactor: don't have child rule files import their parents. Keep the import graph acyclic.

### Q5. A new contributor follows the README but writes code that violates project conventions. They don't read CLAUDE.md. Architectural fix?

CLAUDE.md auto-loads when they use Claude Code, no reading required. If they bypass Claude Code (write by hand), enforce conventions via linters and CI checks. CLAUDE.md complements but doesn't replace tooling.

### Q6. Your project root CLAUDE.md is 1,500 lines and Claude's responses are getting slower. Why?

CLAUDE.md is appended to every prompt. 1,500 lines is too much. Modularize: move detailed rules to .claude/rules/*.md with paths globs. Keep root CLAUDE.md to ~300 lines of universal team rules.

### Q7. A path-scoped rule file's paths: ["src//*.ts"] matches but the rules don't apply to a file in src/lib/utils.ts. What's wrong?

Glob syntax. matches multiple directory levels, so src//*.ts should match src/lib/utils.ts. If not, check for typos in the glob or restart Claude Code.

### Q8. You want different rules for api/ (backend) and app/ (frontend). Best structure?

Two path-scoped rule files: .claude/rules/backend.md with paths: ["api/"], .claude/rules/frontend.md with paths: ["app/"]. Keep root CLAUDE.md for shared rules. Each rule auto-loads only when relevant.

## FAQ

### Q1. What's the actual merge order when all three CLAUDE.md tiers exist?

User → Project → Path-specific. User loads first (broadest scope, weakest priority), project loads next, path-specific rules append last when you touch matching files. Later instructions win on conflict because LLMs weight recent context more strongly.

### Q2. How is @import resolved, file path or URL?

Local file path only, relative to the importing file's directory. @import ./rules/testing.md from CLAUDE.md reads ./rules/testing.md. URLs are not supported. Circular imports hang the loader, keep the import graph acyclic.

### Q3. Does CLAUDE.md content count toward the context window every turn?

Yes. CLAUDE.md is concatenated into the system prompt and sent on every API call. A 5,000-token CLAUDE.md costs you 5K tokens per turn unless cached. Mark stable rule files with cache_control via a wrapper, or keep CLAUDE.md under 1,500 tokens to begin with.

### Q4. Can I have multiple CLAUDE.md files in nested project directories?

Yes. Claude Code walks up from the current working directory and loads the nearest CLAUDE.md plus the project root one. Useful for monorepos where apps/web/CLAUDE.md adds frontend-specific rules on top of root rules.

### Q5. How do path-glob rules differ from CLAUDE.md @import?

@import is unconditional, the imported content is always loaded with the parent. Path-glob rules are conditional, they load only when an edit/read targets a file matching the paths: array in their frontmatter. Use imports for organization, glob rules for scoped policy.

### Q6. What's the relationship between CLAUDE.md and AGENTS.md?

AGENTS.md is the cross-tool standard (used by Codex CLI, Cursor, OpenCode, etc.). Claude Code reads it via @AGENTS.md import inside CLAUDE.md, or directly if present. Use AGENTS.md for tool-agnostic rules; use CLAUDE.md for Claude-specific patterns (skills, hooks, MCP).

### Q7. Should I commit .claude/settings.local.json?

No. settings.local.json is per-developer (your local permissions, env vars). The shared file is .claude/settings.json. Add settings.local.json to .gitignore; otherwise teammates inherit each other's accidental "allow all" permissions.

### Q8. How do I prevent CLAUDE.md from drifting between projects?

Two patterns: (1) template repo with a canonical CLAUDE.md skeleton; (2) shared rule package in a separate repo, projects import it via submodule and @import ./shared-rules/*.md. Drift management is the #1 reason large orgs adopt the modular import pattern.

### Q9. Can hooks defined in .claude/settings.json override CLAUDE.md instructions?

They live in different layers: CLAUDE.md is prompt-time guidance, hooks are execution-time enforcement. A hook can deterministically block a Bash command even if CLAUDE.md said it was fine; CLAUDE.md cannot override a hook's exit code. Hooks always win in execution.

### Q10. What happens when CLAUDE.md grows past the size budget?

Claude Code displays a warning (CLAUDE.md exceeds recommended size) and continues. The model still receives it but with degraded attention to any single rule. The fix is decomposition: move detailed rules to .claude/rules/*.md with path globs, keep the main CLAUDE.md as a high-level index of imports.

---

**Source:** https://claudearchitectcertification.com/concepts/claude-md-hierarchy
**Vault sources:** ACP-T03 §4.3; GAI-K04 §3; ASC-A01 Courses 2 + 4
**Last reviewed:** 2026-05-04

**Evidence tiers** — 🟢 official Anthropic doc / API contract · 🟡 partial doc / inferred · 🟠 community-derived · 🔴 disputed.
