Domain 3: Claude Code Configuration & Workflows (20%)Lesson 13 of 30

3.1 CLAUDE.md Hierarchy & Scoping

3.1.1 How Claude Code Remembers Your Project

Every Claude Code session starts with a blank slate — a fresh context window that knows nothing about your project's conventions, build commands, or architecture. So how do you avoid re-explaining 'we use 2-space indentation' and 'run npm test before committing' every single session? The answer is a CLAUDE.md file: a plain markdown file where you write down the persistent instructions you want Claude to have in every conversation. Task Statement 3.1 is about where these files live, how they combine, and the scoping rules that decide who gets which instructions.

Think of CLAUDE.md like the onboarding notes you'd leave for anyone joining your project — 'here's how we build, here's where things live, here's what to always do.' Claude reads these notes at the start of every session, the way a new collaborator would read the README before touching anything. Write them once, and Claude carries them into every conversation.

The subtlety the exam tests is that CLAUDE.md isn't one file in one place — it's a HIERARCHY of files at different levels, and where you put an instruction decides who it reaches. Put it in the wrong place and a teammate silently doesn't get it. Let's build up that hierarchy and the rules for how the files combine.

CLAUDE.md = persistent onboarding notesfresh sessionknows nothing yetreads CLAUDE.mdyour standing instructionsworks your wayconventions appliedloaded at the start of EVERY session — write once, applied always

CLAUDE.md is the project's persistent onboarding notes: Claude reads it at the start of every session and applies your conventions without being re-told.

ℹ️

The one idea to hold onto

CLAUDE.md is where you write instructions you'd otherwise re-explain every session. Claude loads it at the start of every conversation. WHERE you place it in the hierarchy decides who receives those instructions.

3.1.2 The Three Levels of the Hierarchy

CLAUDE.md files live at different LEVELS, and the level controls scope — who sees the instructions. The exam focuses on three: user, project, and directory.

USER level (~/.claude/CLAUDE.md) is YOUR personal file, applying across all your projects — but private to you. It's perfect for personal preferences ('I like verbose commit messages') and never shared with teammates. PROJECT level (./CLAUDE.md or ./.claude/CLAUDE.md) lives in the repository, so it's checked into version control and shared with the whole team — the home for project architecture, coding standards, and build commands everyone needs. DIRECTORY level (a CLAUDE.md inside a subdirectory) scopes instructions to just that part of the codebase — useful when one package or module has its own conventions.

The crucial distinction — and the one the exam tests hardest — is user vs project. User-level lives in your home directory and is NOT shared via version control. Project-level lives in the repo and IS shared. Confuse them and instructions land in the wrong audience.

LevelLocationScopeShared with team?
User~/.claude/CLAUDE.mdAll your projectsNo — private to you
Project./CLAUDE.md or ./.claude/CLAUDE.mdThis projectYes — via version control
Directorysubdir/CLAUDE.mdThat subdirectoryYes (it's in the repo)
Local./CLAUDE.local.mdThis project, just youNo — gitignored

The hierarchy by scope. User = personal/all projects; project = team-shared; directory = one part of the codebase; CLAUDE.local.md = personal project notes (gitignored).

3.1.2 — Key Concept

Three levels: user (~/.claude/CLAUDE.md — personal, all projects, NOT shared), project (./CLAUDE.md or .claude/CLAUDE.md — team-shared via version control), and directory-level (a subdirectory's CLAUDE.md — scoped to that area). User-level is private; project-level is shared.

3.1.3 How the Files Combine — Concatenation, Not Override

When multiple CLAUDE.md files apply, how do they interact? This is where intuition often misleads. You might assume a more specific file OVERRIDES a broader one — like CSS, where the most specific rule wins. That's wrong, and the exam tests the misconception directly.

CLAUDE.md files are CONCATENATED, not overriding. Claude walks up the directory tree and stacks all the applicable files together into context, ordered broad to specific: the user file, then the project file, then any directory file, with CLAUDE.local.md appended last at each level. Nothing replaces anything — it all gets combined. So if your user file says 'use tabs' and the project file says 'use 2-space indentation,' both instructions are present, and because they CONFLICT, Claude may resolve the contradiction arbitrarily. The lesson: don't rely on one file 'beating' another; instead, keep instructions consistent across files and review them for conflicts.

There's a deeper point hiding here, and it's the most important caveat in this lesson. CLAUDE.md is delivered to Claude as a regular user message after the system prompt — it is CONTEXT, not enforced configuration. Claude reads it and tries to follow it, but there is NO guarantee of strict compliance, especially for vague or conflicting instructions. So if a rule absolutely MUST be honored — 'never push to main,' 'always run lint before commit' — CLAUDE.md is the wrong tool. Use a hook (Domain 1.5) or settings.json, which enforce deterministically. CLAUDE.md guides behavior; hooks guarantee it.

3.1.3 — Key Concept

CLAUDE.md files are CONCATENATED broad→specific (not overriding); conflicting instructions may be resolved arbitrarily. And because CLAUDE.md is context (a user message), not enforced config, there's no strict-compliance guarantee — for must-honor rules use a hook or settings.json, not CLAUDE.md.

3.1.4 Modular Organization: Imports and Rules

A CLAUDE.md that grows past ~200 lines starts to hurt — it eats context and, counterintuitively, REDUCES how reliably Claude follows it (more text, less adherence). Two mechanisms keep things modular as a project grows.

IMPORTS: the @path syntax pulls in another file inline. Writing `@./standards/naming.md` or `@README` in your CLAUDE.md inlines that file's contents at launch. This is great for ORGANIZATION — splitting a big file into readable pieces, or pointing at an existing AGENTS.md so multiple tools share one source. But note the catch the exam likes: imports do NOT reduce context. The imported file is loaded in full at launch, just like the rest — so @import organizes, it doesn't shrink your token footprint.

RULES: the .claude/rules/ directory holds topic-specific files (testing.md, api-conventions.md, security.md), each covering one area. By default these load at launch with the same priority as .claude/CLAUDE.md — so out of the box they're just a tidier way to organize the same always-on instructions. (Their real power, conditional path-based loading, is the subject of the next lesson, 3.3.) Finally, the /memory command is your diagnostic tool: it lists exactly which CLAUDE.md and rules files are loaded in the current session — invaluable when instructions seem to be ignored and you need to confirm a file is actually being read.

MechanismWhat it doesWatch out for
@path importInlines another file at launchDoes NOT reduce context — loads in full
.claude/rules/Topic files, loaded like CLAUDE.mdPath-scoping (3.3) is what makes them conditional
/memoryLists which files are loadedDiagnostic only — doesn't load files

Imports organize (but don't shrink context); rules modularize; /memory tells you what's actually loaded. The conditional power of rules comes in Lesson 3.3.

ℹ️

3.1.4 — Key Concept

Keep CLAUDE.md under ~200 lines (context + adherence). Use @path imports to organize (they inline at launch and do NOT reduce context) and .claude/rules/ to modularize by topic. Use /memory to verify which files are actually loaded.

3.1.5 The Exam Traps

The 3.1 traps cluster around three misconceptions: that user-level is shared, that more-specific files override, and that CLAUDE.md can enforce a hard rule. Anchor on the three corrections and they fall away.

The signature scenario: a new teammate clones the repo but isn't getting the team's conventions. Why? Because those conventions live in someone's USER-level config (~/.claude/CLAUDE.md), which is private and not in version control. The fix is to move them to the PROJECT level (./CLAUDE.md or .claude/CLAUDE.md) and commit them, so everyone gets them on clone. Whenever you see 'a teammate isn't getting instructions,' suspect user-vs-project scope.

MisconceptionReality
User-level config is shared with the teamUser-level (~/.claude) is private; only project-level is shared via git
A more specific CLAUDE.md overrides a broader oneFiles are CONCATENATED; conflicts resolve arbitrarily
CLAUDE.md can guarantee a rule is followedIt's context, not enforced — use a hook/settings for must-honor rules
@import reduces contextImported files load in full at launch

Four 3.1 misconceptions and their corrections. The teammate-not-getting-conventions scenario is the most common, and the answer is always 'move it to project scope.'

⚠️

3.1.5 — Exam Trap

When a teammate isn't receiving conventions, the cause is user-level (private) config — move it to project-level and commit. Reject answers implying user-level is shared, that specificity overrides (it concatenates), or that CLAUDE.md enforces hard rules (use a hook). And there is no '.claude/config.json with a commands array.'

3.1.6 Put It Together: Build a Configuration Hierarchy

You now understand what CLAUDE.md is, the three scope levels, how files concatenate (and why they don't enforce), and how to organize with imports, rules, and /memory. The exercise has you prove the scoping boundary that the exam tests — by watching an instruction reach or not reach depending on where you put it.

3.1.6 — Build Exercise (30 min)

(1) Create a project-level CLAUDE.md with universal standards and verify it's applied. (2) Add a directory-level CLAUDE.md in a subpackage with its own convention; confirm it only applies there. (3) Use @import to pull a standards file into CLAUDE.md, and verify with /memory that it's loaded. (4) Prove the scoping boundary: put a 'team' convention in your USER-level ~/.claude/CLAUDE.md, then check (e.g. in a fresh clone or second machine simulation) that a teammate wouldn't get it — then move it to project-level and confirm it now applies. (5) Take a rule that MUST always run (e.g. lint before commit) and note why it belongs in a hook, not CLAUDE.md.

CLAUDE.md is the always-on layer of configuration. The next lesson, 3.2, covers the on-demand layer — custom slash commands and skills, which package workflows you invoke when you need them rather than loading them every session.

ℹ️

Where this shows up on the exam

3.1 questions almost always involve a teammate missing conventions (→ move to project scope) or a misunderstanding about override/enforcement. Anchor on 'user is private, project is shared, files concatenate, and CLAUDE.md guides but doesn't enforce.'

Key Takeaways

  • CLAUDE.md holds persistent instructions Claude loads at the start of every session; where you place it in the hierarchy decides who receives those instructions.
  • Three levels: user (~/.claude/CLAUDE.md — personal, all your projects, NOT shared), project (./CLAUDE.md or .claude/CLAUDE.md — team-shared via version control), and directory-level (a subdirectory's CLAUDE.md). CLAUDE.local.md = personal, gitignored.
  • Files are CONCATENATED broad→specific, not overriding; conflicting instructions across files may be resolved arbitrarily, so keep them consistent.
  • CLAUDE.md is context (a user message), not enforced configuration — no strict-compliance guarantee; for must-honor rules use a hook or settings.json, not CLAUDE.md.
  • Keep files under ~200 lines (more text reduces adherence); @path imports organize but load in full at launch and do NOT reduce context; .claude/rules/ modularizes by topic.
  • /memory lists which CLAUDE.md and rules files are loaded — the diagnostic for 'why isn't Claude following this?'
  • Signature exam scenario: a teammate isn't getting conventions because they live in user-level (private) config — fix by moving to project-level and committing.

Check Your Understanding

Test what you learned in this lesson.

Q1.A new team member clones the repo but isn't receiving the team's coding conventions that everyone else has. What's the most likely cause?

Q2.How do multiple applicable CLAUDE.md files interact?

Q3.You need to GUARANTEE that lint runs before every commit. Where should this live?

Q4.Your CLAUDE.md is over 300 lines and adherence is dropping. You use @import to split it into several files. What happens to context usage?

Practice This Lesson