Learn Claude Code: Prompting Mastery CLAUDE.md Architecture: The Four Scopes

CLAUDE.md Architecture: The Four Scopes

Advanced 🕐 14 min Lesson 2 of 12
What you'll learn
  • Identify the four CLAUDE.md scopes and their file paths, sharing scope, and intended use cases
  • Explain how CLAUDE.md files load at session start, concatenate in priority order, and load on demand for subdirectories
  • Distinguish between CLAUDE.md as probabilistic context and hooks as deterministic enforcement, and know when to use each

Where Do Your Instructions Actually Come From?

When you open a Claude Code session, instructions arrive from multiple places before you type anything. You might have personal preferences stored in your home directory, project conventions committed to the repository, personal overrides that should never reach your teammates, and organization-wide policies pushed by IT. All of these can coexist, and Claude Code reads them all — in a specific order that determines which instructions take precedence.

Understanding this architecture is the foundation for everything else in this track. Once you know which file belongs where and why, writing effective instructions becomes much more straightforward.

The Four Scopes

CLAUDE.md files can live in four locations, each with a different scope:

Managed policy macOS: /Library/Application Support/ClaudeCode/CLAUDE.md — organization-wide, managed by IT or DevOps, cannot be excluded by individuals
User instructions ~/.claude/CLAUDE.md — your personal preferences across all projects on your machine
Project instructions ./CLAUDE.md or ./.claude/CLAUDE.md — team-shared conventions committed to version control
Local instructions ./CLAUDE.local.md — personal project overrides, added to .gitignore, never shared

Each scope serves a different purpose. Managed policy delivers compliance requirements and security standards that every developer in the organization must follow. User instructions hold preferences that apply to all your projects — your preferred commit message style, your testing workflow, your personal tool shortcuts. Project instructions hold team standards committed to git so every developer working on the project gets the same context. Local instructions hold things that are personal and project-specific, like your sandbox URL or your local test database credentials.

Load Order and Concatenation

Claude Code loads CLAUDE.md files by walking up the directory tree from your current working directory. If you run Claude Code in foo/bar/, it loads foo/bar/CLAUDE.md, foo/CLAUDE.md, and any CLAUDE.local.md files alongside them. It also loads user-level and managed policy files.

The load order runs from broadest scope to most specific. Managed policy loads first, user instructions load second, project instructions load after that. This means project-level instructions appear later in the context window and carry more weight — they are the last thing Claude reads before you start the conversation. Within each directory level, CLAUDE.local.md is appended after CLAUDE.md, so your personal notes at that level are the very last thing loaded.

Critically, these files do not override each other. They concatenate. All discovered CLAUDE.md and CLAUDE.local.md files are combined into a single context block. If your user-level CLAUDE.md says to use 4-space indentation and your project CLAUDE.md says to use 2-space indentation, both instructions are present. Claude will likely follow the project instruction because it appears later, but the conflict is a problem worth fixing — conflicting rules can cause Claude to pick one arbitrarily.

On-Demand vs Launch-Time Loading

Not all CLAUDE.md files load at session start. Files at the project root and in ancestor directories load at launch. But CLAUDE.md files in subdirectories under your working directory load on demand — they enter the context window only when Claude reads files in those subdirectories.

This is an important distinction for large projects. If you have a src/api/CLAUDE.md with API-specific conventions, those instructions are not in context when Claude is working on frontend code. They load the moment Claude opens a file in src/api/. This keeps context lean when Claude is working in parts of the codebase where those specific instructions are not relevant.

CLAUDE.md vs Auto Memory

CLAUDE.md files are not the only source of persistent instructions. Auto memory is a parallel system that Claude writes itself, based on corrections and patterns it notices during your sessions. Both systems load at the start of every session, but they serve different purposes:

  • CLAUDE.md: instructions you write — standards, conventions, commands, preferences
  • Auto memory: learnings Claude accumulates — build commands it discovered, debugging patterns it noticed, preferences you corrected it on

Auto memory is covered in depth in lesson 6. For now, the key distinction is this: CLAUDE.md is what you write intentionally. Auto memory is what Claude writes based on what you implicitly teach it.

The Critical Mental Model: Context, Not Configuration

This is the most important thing to understand about CLAUDE.md: it is delivered to Claude as a user message, after the system prompt. It is not the system prompt. It is not enforced configuration. It is context — probabilistic input that Claude reads and tries to follow, but without any guarantee of strict compliance.

Claude treats CLAUDE.md the same way it treats everything else in the context window: as information to use in making decisions. If a CLAUDE.md instruction is vague, Claude may interpret it differently than you intended. If there are conflicting instructions, Claude may pick one arbitrarily. If the file is too long, important rules get lost in the noise. The quality of your CLAUDE.md instructions determines the quality of the compliance you get.

This also means that CLAUDE.md is not the right tool for actions that must happen with zero exceptions. If you need Claude to always run a linter before every file edit, regardless of what it decides to do, that is a hook — a deterministic script that fires at lifecycle events. The distinction matters: CLAUDE.md shapes behavior, hooks enforce it. Use CLAUDE.md for guidance and conventions. Use hooks for requirements.

For situations where you need instructions to reach the actual system prompt rather than arriving as a user message, the --append-system-prompt CLI flag inserts your text directly. This is best suited to automation scripts and CI workflows where you control every invocation — it is not practical for interactive sessions where you would need to pass the flag every time.

The /memory Browser

To see exactly which CLAUDE.md, CLAUDE.local.md, and rules files are loaded in your current session, run /memory. This command lists every loaded file and lets you open any of them directly in your editor. It also shows the auto memory toggle and provides a link to open your auto memory folder.

If Claude is not following an instruction, /memory is the first debug tool to reach for — it tells you whether the file is actually loaded. If the file does not appear in the /memory list, Claude cannot see it, no matter how well-written the instruction is.

Key takeaways
  • CLAUDE.md files load in four scopes — managed policy, user, project, and local — concatenating from broadest to most specific so project instructions appear last and carry most weight
  • CLAUDE.md is delivered as a user message after the system prompt — it is probabilistic context, not enforced configuration, and compliance degrades when files are too long or instructions conflict
  • Subdirectory CLAUDE.md files load on demand when Claude reads files in that directory, not at session start — this keeps context lean when Claude works in unrelated parts of a large codebase
  • Use --append-system-prompt when you need true system-prompt injection in automation scripts, not for interactive sessions where passing the flag every time is impractical
  • Run /memory to verify which files are loaded in your current session — if a file does not appear in the list, Claude cannot see it regardless of where the file is located