What You Need to Know
A CLAUDE.md file is a Markdown file of instructions for Claude Code. Claude Code reads these files at three levels: user (one person), project (the whole team) and directory (one folder). @ path imports (references to other files by their path) and the .claude/rules/ directory split instructions across several files.
This lesson uses one made-up example throughout: an osteopath practice whose two developers use Claude Code on its booking website. Every session should follow the practice's naming rules and testing requirements. One developer likes short answers. The booking API package has its own REST conventions.
The Three-Level Hierarchy
User-level: ~/.claude/CLAUDE.md
This file applies only to you. It is in your home directory, outside any repository. So it is not version-controlled, and git never shares it. A new teammate who clones the repo will not get these instructions. Keep this level for strictly personal preferences: verbosity settings, a preferred output style, your own shortcuts. The developer who likes short answers says so here.
Project-level: .claude/CLAUDE.md or root CLAUDE.md
This file applies to everyone on the project. It is in the repository and is version-controlled. Every developer who clones or pulls the repo gets these instructions automatically. Team-wide standards belong here: naming conventions, error handling patterns, testing requirements, architecture decisions, code review checklists. Both .claude/CLAUDE.md (inside the .claude directory) and a CLAUDE.md at the repository root are valid project-level locations. The practice's naming rules belong here.
Directory-level: subdirectory CLAUDE.md files
These files apply when you work in that specific directory. Use them for package-specific conventions that differ from the project root. For example, a /packages/api/CLAUDE.md might hold REST conventions that the frontend package never needs. The booking API's REST conventions belong in that package's CLAUDE.md.
Loading Order and Conflict Handling
The Anthropic memory docs are explicit: "All discovered files are concatenated into context rather than overriding each other". Every applicable file loads into the same context window.
CLAUDE.md files do not form a configuration with strict precedence: the docs describe a load order. The files load in order from the broadest scope to the most specific, so a project instruction appears after a user instruction. Across the directory tree, "content is ordered from the filesystem root down to your working directory". So "instructions closer to where you launched Claude are read last". When you start a session in the booking API package, Claude reads the user file, then the project file, then the package file.
A file that Claude reads last does not win a conflict: nothing marks one file as the winner. The docs say it directly: "if two rules contradict each other, Claude may pick one arbitrarily". CLAUDE.md is delivered as a user message, not as part of the system prompt. Anthropic says "there's no guarantee of strict compliance". Treat CLAUDE.md as guidance that the model usually follows, not as a configuration layer with deterministic overrides.
So do not depend on CLAUDE.md scoping for a rule that must apply on every run. Examples of such a rule are a blocked tool, a required formatter and a permission policy. Put that rule in settings.json. The client enforces settings.json regardless of what Claude decides. Or use a hook, which runs at a fixed lifecycle event. The docs say so directly: "Settings rules are enforced by the client regardless of what Claude decides to do. CLAUDE.md instructions shape Claude's behavior but are not a hard enforcement layer". A tool that the practice must always block belongs in settings.json.
Don't confuse CLAUDE.md with settings.json
settings.json has a strict precedence chain (managed policy > local > project > user, with managed always winning). CLAUDE.md does not: files are concatenated and conflicts may resolve arbitrarily. For "which CLAUDE.md wins on a conflict?", the answer that matches the docs is "neither is guaranteed to; move the rule to settings.json or a hook". Watch for options claiming "more specific scope wins" or "user-level overrides project-level". The official docs say neither.
Modular Organisation with @ path imports
When one CLAUDE.md grows past a few hundred lines, it becomes hard to maintain. The @ syntax lets you split it across several files and reference those files from the main file. The directive is simply @ followed by a path. There is no @import keyword, even though many pages online write it that way.
For example:
# .claude/CLAUDE.md
Coding standards:
@./standards/naming-conventions.md
@./standards/error-handling.md
@./standards/testing-requirements.mdAt load time, the file that each @<path> line names is inlined into the CLAUDE.md. Per-package CLAUDE.md files can import only the standards that apply to them. The API package imports API conventions and the frontend package imports component rules. No standard is duplicated. The practice's booking API does the same.
The docs say that imported files load alongside the CLAUDE.md that references them. The file is inlined at the moment that Claude reads your CLAUDE.md, as if you had pasted its text there. Splitting a 600-line CLAUDE.md into six 100-line imports makes the source nicer to work in. But the context stays the same size. To make the context of each session smaller, use .claude/rules/ with path-scoped frontmatter (a block of settings at the top of the file that lists the paths it applies to) (Task Statement 3.3). Those files only load when Claude works in matching paths.
CLAUDE.local.md, local-only overrides
CLAUDE.local.md is next to CLAUDE.md at any level in the hierarchy, and it loads in the same way. Three small differences separate it from CLAUDE.md.
- Loading order.
CLAUDE.local.mdis appended afterCLAUDE.mdat the same level, so your personal notes are the last thing Claude reads there. That is load order, not precedence: the file that Claude reads last does not win a contradiction. If two instructions conflict, Claude may still pick either one. - Gitignored by convention. The
.localsuffix marks files that you do not want to commit. Most teams addCLAUDE.local.mdto.gitignoreso personal changes stay personal. - What it's for. The shared
CLAUDE.mdholds the team's rules. TheCLAUDE.local.mdnext to it holds your personal preferences for this repo, for example a favourite scratchpad path, a verbose explanation that you paste again and again, a temporary debugging note that you will delete next week.
CLAUDE.local.md is a project-scoped version of ~/.claude/CLAUDE.md. A team rule belongs in CLAUDE.md instead. A practice developer's scratchpad path belongs in CLAUDE.local.md. The testing requirements do not.
The .claude/rules/ Directory
Instead of a single CLAUDE.md, the .claude/rules/ directory can hold topic-specific rule files.
testing.md: test naming, assertion patterns, fixture usageapi-conventions.md: endpoint naming, request/response schemasdeployment.md: deployment checklist, environment configuration
Each file can optionally include YAML frontmatter with path scoping (Task Statement 3.3). Without frontmatter, rules files load for all sessions, so the practice's testing.md would load in every session.
What Survives Compaction
When /compact summarises a long session, the project-root CLAUDE.md is loaded again in full. Its location gives it no special status. After compaction, Claude reads it again from disk and injects it into the context again. Your instructions were never part of the conversation history, so the summariser has nothing there to compress.
Two things are not loaded again automatically: nested CLAUDE.md files in subdirectories, and .claude/rules/ files with paths: frontmatter. Both load on demand. So they load again when Claude next reads a matching file, not when compaction ends. When an instruction seems to disappear after /compact, this is usually the reason. The other possible cause is an instruction that only ever existed in the conversation. Compaction can summarise that instruction. A naming rule typed only into a chat at the practice has no file that Claude can read again.
Diagnosing What Loaded: /memory and /context
When behaviour differs between sessions or developers, check which memory files each session loaded. If Claude Code follows the conventions for one practice developer and ignores them for the other, that check gives the answer.
Current state (checked 6 October 2026): Claude Code splits the job across two commands. /memory lists your CLAUDE.md, CLAUDE.local.md and auto-memory locations, and opens any of them in your editor. /context reports what loaded at launch, under Memory files. To confirm that a file is loaded, run /context and read that list. The docs say: "check the list under Memory files to verify the CLAUDE.md and CLAUDE.local.md files that should load at launch". Two kinds of file load on demand, so they are not on that list. They are a CLAUDE.md in a subdirectory of your working directory and a rule with paths frontmatter (Task Statement 3.3). When one of these files loads, a Loaded line with its path appears in the terminal.
Key Concept
Neither command loads anything. They show which files are already loaded. Configuration loads automatically, based on its level and its location. Use these commands to diagnose, not to activate.
In the exam
The exam tests again and again which level applies where, and whether you can spot the wrong level. Either project-level path may appear.
The favourite trap for Task Statement 3.1 is a new team member not receiving instructions. For months, Claude Code has followed the team's conventions for one teammate. A new teammate clones the repository and gets inconsistent results that ignore those conventions. The root cause is always a configuration hierarchy problem. The conventions are in the first teammate's user-level config (~/.claude/CLAUDE.md), not the project-level config. User-level config is not shared via git, so the new teammate never received the conventions. The fix is to move the conventions to project-level configuration. At the practice, the naming rules would have been in one developer's home directory.
Diagnose this case immediately: when a question pairs "new team member" with "inconsistent behaviour", check where the configuration is stored.
The exam also tests that the diagnostic commands load nothing.
On the exam, answer /memory
The exam guide (v1.0) is older than the split between the two commands. It treats /memory as the command that shows which files are loaded. Give /memory as the right answer. In real use, run /context.
Source for the /memory and /context details: Claude Code memory docs.
Exam Traps
New team member not receiving Claude Code instructions despite working on the same repo and branch
The instructions are in user-level config (~/.claude/CLAUDE.md) instead of project-level. User-level is not version-controlled or shared via git. Move to .claude/CLAUDE.md for team-wide application.
Thinking /memory triggers configuration loading
The exam guide treats /memory as a diagnostic command that shows which files are loaded. Current docs (October 2026) say /memory lists memory file locations and /context shows what loaded at launch. Neither activates anything; files load by their place in the hierarchy.
Assuming directory-level CLAUDE.md is the best solution for cross-directory conventions
Directory-level CLAUDE.md applies to one directory only. For conventions spanning many directories (like test files spread throughout a codebase), use path-specific rules in .claude/rules/ with glob patterns instead.
Practice Scenario
Developer A's Claude Code follows the team's API naming conventions perfectly. Developer B, who joined last week, gets inconsistent naming from Claude Code. Both are working on the same repo, same branch. What is the most likely root cause?
Build Exercise
Build a Multi-Level CLAUDE.md Configuration
What you'll learn
- Understand the three-level CLAUDE.md hierarchy (user, project, directory) and when to use each
- Configure modular project standards using @ path imports
- Use .claude/rules/ for topic-specific rule files
- Diagnose configuration scoping issues with /context (the exam guide names /memory)
- Identify root cause when a new team member does not receive instructions
- Create a project-level .claude/CLAUDE.md with universal coding standards: naming conventions, error handling patterns, and a code review checklist
Why: Project-level configuration is where team-wide standards belong. The exam tests whether you place shared conventions here rather than in user-level config, which is the most common misconfiguration scenario.
You should see: A .claude/CLAUDE.md file at the repository root containing at least three sections: naming conventions, error handling patterns, and a code review checklist. Running /context in the project root lists this file under Memory files.
- Create a directory-level CLAUDE.md in a /packages/api/ subdirectory with API-specific conventions (REST endpoint naming, request/response schema requirements)
Why: Directory-level configuration scopes conventions to a specific package. The exam tests whether you know that directory-level CLAUDE.md applies only within that directory, not across the entire project.
You should see: A CLAUDE.md file inside /packages/api/ containing REST-specific conventions. When you start Claude Code from /packages/api/, /context lists both the project-level and directory-level files under Memory files.
- Create .claude/rules/testing.md with test-specific conventions (test naming pattern, assertion style, fixture usage)
Why: The .claude/rules/ directory holds topic-specific rule files that can optionally include YAML frontmatter for path scoping. Understanding this mechanism is tested alongside path-specific rules in Task Statement 3.3.
You should see: A testing.md file inside .claude/rules/ containing at least three test conventions. Running /context lists this rules file under Memory files.
- Use an @ path import in the project-level CLAUDE.md to reference a shared standards file at ./standards/naming.md
Why: The @ import syntax enables modular organisation of conventions. There is no @import keyword — a path prefixed with @ on its own line is the import. Each package can import only relevant standards, reducing duplication and differences between copies in the source files. The exam tests whether you know the mechanism exists and how the syntax actually looks.
You should see: The project-level .claude/CLAUDE.md contains a line beginning with @ pointing to ./standards/naming.md. A separate file at .claude/standards/naming.md (or standards/naming.md relative to the CLAUDE.md) exists with naming conventions. Running /context confirms the imported content is loaded inline.
- Run /context in different directories to verify the correct files are loaded in each context
Why: The exam tests that the diagnostic command reveals loaded files but does not trigger loading — configuration loads automatically based on location. The guide names /memory for this. Current state (checked 6 October 2026): Claude Code reports the loaded set under /context, so that is what you run here.
You should see: Started from the project root, /context shows the project-level CLAUDE.md and rules files under Memory files. Started from /packages/api/, it also lists the directory-level CLAUDE.md. The imported standards file content appears as part of the project-level configuration.
- Move one convention from project-level to user-level (~/.claude/CLAUDE.md) and verify that a different user session does NOT pick it up — confirming the scoping boundary
Why: This is the exam favourite trap scenario. When conventions are in user-level config, new team members who clone the repo do not receive them. Proving this boundary experimentally helps you remember the concept.
You should see: After moving a convention to ~/.claude/CLAUDE.md, your own /context shows it loaded. A simulated second user session (or a fresh clone without your home directory config) does NOT show that convention. This confirms the scoping boundary.