Path-specific rules are the conditional layer of Claude Code's instruction system — the mechanism by which different folders, file types, and subtrees can receive different coding conventions without forcing every project to live under a single monolithic CLAUDE.md. Task statement 3.3 of the Claude Certified Architect — Foundations (CCA-F) exam — "Apply path-specific rules for conditional convention loading." — sits inside Domain 3 (Claude Code Configuration & Workflows, 20 % weight) and is one of the most commonly under-prepared subtopics in the blueprint. Candidates who pass this task statement know exactly how the .claude/rules/ directory is discovered, how paths: glob patterns activate a rule file for a given target file, and how path-specific rules interact with the broader CLAUDE.md hierarchy rather than replacing it.
This study note walks through the full surface area a CCA-F candidate is expected to design at the architecture level: the rationale behind path-specific rules, the .claude/rules/ directory discovery model, the shape of a rule file (YAML frontmatter + rule body), paths: glob syntax, rule activation logic as Claude Code resolves conventions for the current file under consideration, convention isolation for framework-specific subtrees, test-file-only rules, monorepo package-scoped rules, precedence when multiple rule files match, the relationship to directory-level CLAUDE.md files, and how to debug which rules are actually active during a session. A final traps section and a five-question FAQ tie every abstract concept back to the code-generation-with-claude-code scenario that exercises Task 3.3 most heavily.
Path-Specific Rules — Applying Different Conventions Based on File Location
A CLAUDE.md at the project root is evaluated for every task in that project. That is a reasonable default for small, homogeneous codebases. The moment the codebase stops being homogeneous — a backend package uses one framework, the frontend uses another, a generated-code folder must never be hand-edited, test files use different assertion styles than production code — a single root-level CLAUDE.md becomes a wall of conditional text ("if you are editing src/api/* then ...; if you are editing tests/* then ...; unless the file ends in .generated.ts in which case ..."). Claude follows these conditionals less reliably than it follows unconditional instructions, and the file grows into an unmaintainable monolith.
Path-specific rules solve this by letting an architect express conventions conditionally on file location. Instead of stuffing an "if you are editing tests" branch into the root CLAUDE.md, the architect drops a small rule file under .claude/rules/ whose frontmatter declares "this rule only applies when Claude Code is working on files matching tests/**." Claude Code reads the rule into context only when the current target file matches one of the rule's paths: patterns. Irrelevant rules stay out of context, relevant rules are always present, and the root CLAUDE.md stays lean.
Why Path-Specific Rules Exist Architecturally
The design problem path-specific rules address is instruction relevance at the moment of editing. When Claude Code is about to edit apps/web/src/pages/index.astro, the Astro conventions matter and the Python backend's ruff formatting rules do not. Loading the backend rules into context for a frontend edit is pure noise — it costs tokens, increases the risk of cross-framework confusion, and dilutes the attention Claude gives to the rules that are relevant. Path-specific rules are Claude Code's answer: scope instruction loading to file location so that every task sees the minimal, correct set of conventions.
A path-specific rule in Claude Code is a YAML-frontmatter file (typically stored under .claude/rules/) whose paths: array declares a list of glob patterns. The rule body is loaded into Claude's context only when the current target file matches at least one of the declared patterns. Path-specific rules are the conditional layer on top of the unconditional CLAUDE.md hierarchy: CLAUDE.md files establish always-on context, and path-specific rules supplement it with instructions that matter only for specific subtrees.
Source ↗
How They Differ from CLAUDE.md Files
A CLAUDE.md file is always loaded when it sits above the current working directory in the hierarchy (global, project, directory). A path-specific rule is conditionally loaded based on whether the file Claude Code is about to touch matches a glob pattern. The two systems coexist: CLAUDE.md carries project-wide invariants ("we use TypeScript strict mode everywhere", "all public functions must have JSDoc"); path-specific rules carry subtree-specific conventions ("tests use vitest.describe grouping", "this directory is auto-generated, never hand-edit"). Treating them as interchangeable is a frequent CCA-F trap.
.claude/rules/ Directory — YAML Rule Files and Their Discovery
Claude Code looks for path-specific rules in a conventional location: the .claude/rules/ directory at the project root. Every file in that directory (typically with a .yaml, .yml, or .md extension depending on Claude Code version) is a candidate rule. Claude Code reads the frontmatter of each candidate at session start, indexes the paths: patterns, and evaluates them against each file the agent is about to read, write, or edit.
Directory Layout
my-project/
├── CLAUDE.md # project-wide, always loaded
├── .claude/
│ ├── rules/
│ │ ├── frontend.yaml # applies to apps/web/**
│ │ ├── backend.yaml # applies to services/api/**
│ │ ├── tests.yaml # applies to **/*.test.ts
│ │ └── generated.yaml # applies to **/*.generated.ts
│ └── commands/ # custom slash commands (task 3.2)
├── apps/
│ └── web/
│ └── CLAUDE.md # directory-scoped CLAUDE.md (task 3.1)
├── services/
│ └── api/
└── tests/
The rule files are lightweight — typically a handful of bullet points each. The directory is version-controlled so that every contributor and every CI run sees the same conventions.
User-Level vs Project-Level Rules
Claude Code's settings hierarchy distinguishes user-level rules (stored in ~/.claude/rules/ and applied across every project on the developer's machine) from project-level rules (stored in .claude/rules/ inside the repository and applied only to that project). User-level rules are useful for personal preferences that should not be imposed on teammates (preferred commit-message phrasing, personal aliases). Project-level rules are for team conventions that must apply for every contributor. CCA-F questions regularly test this distinction.
Discovery Is Automatic
Unlike custom slash commands, which must be invoked by name, path-specific rules require no explicit reference from the user. Claude Code discovers them at session start by walking the .claude/rules/ directory. No CLI flag, no import statement, no slash command — the rules are active the moment the session opens.
Rules in .claude/rules/ are discovered automatically; the user does not need to import them, reference them, or enable them. The only action required is to commit the rule file to the repository. If a rule is present in the directory but the correct paths: pattern is absent or mistyped, the rule silently fails to activate — there is no warning. CCA-F regularly penalizes answers that add a "load the rule" step to a workflow, because no such step exists.
Source ↗
YAML Rule File Structure — paths Frontmatter, Rule Body, Priority
Every path-specific rule file has the same two-part shape: a YAML frontmatter block and a rule body. The frontmatter controls when the rule applies; the body carries the actual instructions.
Frontmatter Fields
---
name: "Frontend Astro conventions"
description: "Astro + Tailwind conventions for apps/web"
paths:
- "apps/web/**"
- "apps/web/src/**/*.astro"
priority: 50
---
name— a short label used when Claude Code surfaces which rule applied.description— a one-line summary (helpful for team documentation; not required).paths— an array of glob patterns; the rule activates when the target file matches at least one pattern.priority— an optional integer that breaks ties when two rules both match the same file (higher priority wins).
The Rule Body
Below the --- delimiter, the rule body is freeform prose or bullet list describing the conventions. It is written exactly like a CLAUDE.md — imperative instructions, short, scannable.
---
paths:
- "apps/web/**"
---
## Astro component conventions
- Use `.astro` files for pages; colocate `.svelte` components under `src/components/`.
- Styles go in Tailwind utility classes; no inline `<style>` blocks in page files.
- Data fetching happens in the component frontmatter, never in a `<script>` tag.
- For i18n, use the `useTranslations(lang)` helper from `src/i18n.ts`.
Why YAML Frontmatter and Not Something Else
YAML frontmatter is the same convention used by static site generators (Astro, Jekyll, Hugo), by documentation tooling (MDX, Docusaurus), and by Claude Code's own slash commands and skills. The reuse matters: engineers already know the format, editors already syntax-highlight it, CI linters can validate it. Adopting a bespoke config syntax for this one feature would have been friction without benefit.
paths Glob Patterns — Matching src/**, tests/**, *.test.ts and Similar
The paths: array uses glob patterns, not regular expressions. This is the most frequently missed mechanical detail on CCA-F Task 3.3 questions.
The Glob Operators You Will See
*matches any sequence of characters within a single path segment (does not cross/).**matches any number of path segments, including zero.src/**matchessrc/a.ts,src/a/b.ts,src/a/b/c.ts.?matches exactly one character.[abc]matches any one of the characters inside the brackets.{json,yaml,yml}matches any one of the comma-separated alternatives (brace expansion).
Common Patterns and What They Match
paths:
- "src/**" # everything under src/
- "**/*.test.ts" # every .test.ts file anywhere
- "**/*.{test,spec}.ts" # every .test.ts or .spec.ts file
- "services/api/src/**" # only the backend package source tree
- "**/generated/**" # any generated/ folder anywhere in the tree
- "!**/node_modules/**" # negation — excludes node_modules
Patterns are evaluated relative to the project root (the directory containing the .claude/ folder). Absolute paths, ~ expansion, and environment variables are not supported.
Globs Are Not Regex
A glob src/*.ts matches only TypeScript files directly under src/. It does not match src/components/Button.ts. To match recursively you must use **. The regex src/.*\.ts would match both, but that is not how paths: is interpreted. Mixing the two mental models is one of the top-five CCA-F Domain 3 traps.
A glob pattern in the paths: frontmatter is a filesystem-matching expression with a fixed operator set: * for one path segment, ** for zero or more path segments, ? for one character, [abc] for character classes, {a,b} for brace alternatives, and ! at the start of a pattern for negation. Globs are not regular expressions — backslash metacharacters, quantifiers, and anchors are not recognized. Every pattern is evaluated relative to the project root (the directory that contains .claude/), and a rule activates when at least one of its patterns matches (respecting any negation patterns that appear later in the list).
Source ↗
Negation Patterns
A pattern prefixed with ! excludes files that would otherwise match. Negation is useful for rules that apply to "everything under src/ except generated files":
paths:
- "src/**"
- "!src/**/generated/**"
The evaluator processes patterns in order and the last match wins, so negations at the end of the list override earlier inclusions.
If you are not sure whether your glob matches what you think it does, build it up incrementally: test ** first, then add the file extension, then add directory scoping. A rule with a typo in its glob silently fails to apply — Claude Code will still work on the file but without the rule loaded. This is precisely the class of silent failure the exam will test you on.
Source ↗
Rule Activation Logic — How Claude Code Determines Which Rules Apply to the Current File
When Claude Code is about to read, write, or edit a file, it runs the following activation sequence:
- Compute the file's path relative to the project root.
apps/web/src/pages/index.astronormalizes relative to/my-project/. - Walk every rule file discovered in
.claude/rules/. For each rule, evaluate each pattern in thepaths:array against the relative path. - A rule activates when at least one of its
paths:patterns matches. Negation patterns can veto an earlier match within the same rule's list. - Activated rule bodies are loaded into Claude's context for the reasoning turn that will produce the edit or read.
- Non-activated rules are omitted entirely — they do not contribute tokens and do not influence the response.
Activation Happens Per-File, Not Per-Session
A long agent run may touch many files. Path-specific rule activation is evaluated per file (effectively per tool call that names a file). Editing apps/web/src/index.astro activates the frontend rule; the very next edit on services/api/src/main.ts activates the backend rule instead. Claude Code does not "lock in" a set of rules at session start and carry them through the entire session.
What Activation Looks Like in Practice
Imagine a session that starts by reading tests/login.test.ts, then reads src/auth.ts, then edits src/auth.ts, then runs bash pnpm test. The first Read tool call activates tests.yaml; the Read and Edit of src/auth.ts activate backend.yaml (or whichever rule targets src/**); the Bash call does not activate any file-path rule because it does not target a file. Four tool calls, three distinct rule activations, zero manual intervention from the user.
Why Per-File Activation Matters
Per-file activation means rules cannot leak across subtrees. When the agent moves from a Python package to a TypeScript package, the Python formatting rule stops being loaded and the TypeScript strict-mode rule takes its place. This is the architectural payoff for path-specific rules: the conventions in context are always the conventions that apply to the file being worked on.
Convention Isolation — Applying Framework-Specific Rules to Framework Directories
The clearest use case for path-specific rules is framework isolation inside a heterogeneous codebase. A project that uses Astro for its marketing site, Next.js for an internal dashboard, and FastAPI for a Python backend cannot sensibly cram all three framework's conventions into a single CLAUDE.md. The conventions contradict each other in places (React hook rules vs Astro islands, FastAPI dependency injection vs none of the above), and most of any given file's rules are irrelevant for any given task.
A Typical Three-Framework Layout
.claude/
└── rules/
├── astro.yaml # paths: ["apps/marketing/**"]
├── nextjs.yaml # paths: ["apps/dashboard/**"]
└── fastapi.yaml # paths: ["services/api/**"]
Each rule file carries only the conventions for its framework: component patterns, data-fetching idioms, styling approaches, testing libraries. When Claude Code is editing a marketing-site component, it sees only the Astro conventions. When it is editing a FastAPI route, it sees only the Python and FastAPI conventions. No cross-contamination, no conditional text inside a monster CLAUDE.md.
Isolation Reduces the Risk of Cross-Framework Confusion
Without path-specific rules, an architect trying to cover three frameworks in one CLAUDE.md has to write sentences like "when editing Astro files use Tailwind for styling; when editing Next.js files use CSS modules; when editing FastAPI files use nothing because it is Python." Each conditional is a cognitive load on Claude and a small probability that the wrong branch will be followed. Convention isolation via .claude/rules/ removes those conditionals entirely — the Astro rule is simply "use Tailwind utility classes for styling," no when editing guard needed, because the rule never activates outside Astro files.
Test-Specific Rules — Different Conventions for Test Files vs Production Code
Test files almost always deserve their own rule file. The conventions that make production code good (minimal comments, small functions, shared helpers, avoid duplication) are often exactly wrong for tests, where explicitness beats abstraction and repeated scaffolding is preferable to shared fixtures that hide the setup.
Typical Test-Specific Rule
---
name: "Test file conventions"
paths:
- "**/*.test.ts"
- "**/*.test.tsx"
- "**/*.spec.ts"
- "tests/**"
---
## Test conventions
- Use `describe` blocks to group related tests; one top-level `describe` per file.
- Every test's `it(...)` string should read as a sentence: "it returns null when input is empty."
- Prefer explicit arrange/act/assert sections with blank-line separators.
- Do NOT extract test setup into shared helpers unless it is used in 3+ files.
- Mocks are created inline inside each test, not hoisted to the top of the file.
Why a Separate Rule File Beats a CLAUDE.md Section
A section inside the root CLAUDE.md titled "When editing test files" depends on Claude remembering to apply the section. A separate rule file with paths: ["**/*.test.ts"] applies unconditionally when the target file is a test, and never applies when it is not. The latter is structurally more reliable.
The Code-Generation-With-Claude-Code Scenario
The CCA-F code-generation scenario exercises test-file rules directly. Expect scenario questions where the agent is asked to "add tests for the login flow" and the correct answer involves Claude Code loading the test-specific rule when it opens login.test.ts — not because the user named the rule, but because the glob activated it automatically.
Monorepo Use Case — Package-Specific Language and Framework Rules in a Single Repo
Large monorepos are the canonical home for path-specific rules. A company repo may contain a TypeScript web app, a Go CLI, a Python data pipeline, and a Rust service, each with completely different tooling, style guides, and testing conventions. The single root CLAUDE.md can carry cross-package invariants ("every commit message follows conventional commits"), and each package's conventions live in its own rule file.
A Realistic Monorepo Layout
mono/
├── CLAUDE.md # team-wide invariants
├── .claude/
│ └── rules/
│ ├── web-app.yaml # paths: ["packages/web/**"]
│ ├── cli-tool.yaml # paths: ["packages/cli/**"]
│ ├── data-pipeline.yaml # paths: ["packages/pipeline/**"]
│ └── rust-service.yaml # paths: ["services/gateway/**"]
├── packages/
│ ├── web/
│ ├── cli/
│ └── pipeline/
└── services/
└── gateway/
Why Rule Files Beat Package-Scoped CLAUDE.md Alone
A monorepo can also nest CLAUDE.md files per package (packages/web/CLAUDE.md, packages/cli/CLAUDE.md). That is legitimate and in many small cases sufficient. Where rule files add value is when a single convention must span multiple packages (for example, "all generated code uses this header comment regardless of package") or when a convention must apply to a file-extension slice of a package rather than the entire package. A path-specific rule with paths: ["**/*.generated.ts"] matches generated files across every package at once, something no single CLAUDE.md placement can achieve.
Monorepo Rule Hygiene
Keep rule bodies short. A monorepo with ten path-specific rule files and three hundred lines each will load hundreds of tokens of overhead for even trivial edits. Each rule body should be tight enough that an engineer can read it in thirty seconds, and specific enough that every bullet point is load-bearing.
In a monorepo, the correct architecture is a thin team-wide CLAUDE.md at the root plus a rule file per package under .claude/rules/. Do not attempt to encode every package's conventions in the root CLAUDE.md — it becomes an unmaintainable monolith and Claude's adherence to the conditional branches drops sharply as the file grows. The monorepo pattern is one of the most-tested scenarios in CCA-F Task 3.3.
Source ↗
Rule Conflicts — Precedence When Multiple Rules Match the Same Path
It is common and legitimate for a single file to match multiple rule files. tests/integration/auth.test.ts might match both tests.yaml (by **/*.test.ts) and an integration-tests.yaml (by tests/integration/**). Claude Code does not pick one and drop the others — it loads all matching rules. Conflict resolution matters when the rules' instructions contradict.
The Precedence Order
When two or more rules match the same file and their instructions conflict, precedence is resolved in this order:
- More specific
paths:pattern wins. A pattern that matches fewer files is treated as more specific.tests/integration/**is more specific thantests/**which is more specific than**. - Higher
priority:field wins. If specificity is equal, the rule whose frontmatter has a higherpriority:value overrides lower-priority rules. - Later-loaded rule wins as a final tie-breaker. Rule discovery order is deterministic (typically alphabetical by filename), and the later rule's instructions take precedence when all other resolution criteria are equal.
Rule precedence is the three-step resolution order Claude Code uses when two or more path-specific rules both activate for the same file and their instructions contradict: (1) the rule with the more specific paths: pattern wins; (2) among equally-specific rules, the higher priority: frontmatter value wins; (3) as a final tie-breaker, the later-loaded rule (alphabetically later filename in .claude/rules/) wins. Precedence is only invoked when rule bodies genuinely conflict — additive rules simply compose in context without any tie-breaking needed.
Source ↗
Non-Conflicting Composition
Most multi-rule activations are not conflicts — they are additive. A file that matches both tests.yaml and backend.yaml gets both sets of instructions in context, and they compose cleanly ("use describe/it + use structured error responses"). Conflict resolution only matters for genuine contradictions ("use Tailwind" vs "use CSS modules"). Architects should design rules to minimize contradictions rather than relying on precedence to sort them out.
Conflicts with CLAUDE.md
A path-specific rule that contradicts an instruction from a CLAUDE.md higher in the hierarchy does not silently win. CLAUDE.md instructions form the default convention set; path-specific rules supplement them. When the two genuinely disagree, treat the path-specific rule as a local exception and make that explicit in the rule body: "In this subtree we deviate from the project-wide rule that X, because Y. Follow the local rule here." Explicit framing avoids Claude guessing which to follow.
Interaction with Directory CLAUDE.md — Rules Layer on Top of CLAUDE.md Instructions
Path-specific rules do not replace directory-level CLAUDE.md files — they coexist. Understanding the layering is central to Task 3.1 and Task 3.3 both.
The Three-Layer Instruction Model
- Root CLAUDE.md — always loaded, carries project-wide invariants.
- Directory CLAUDE.md files — loaded when the current working directory is at or below the CLAUDE.md's directory. They add directory-specific unconditional context.
- Path-specific rules in
.claude/rules/— loaded conditionally based on the target file's path, independent of the current working directory.
All three layers stack. An edit on apps/web/src/index.astro can pull in the root CLAUDE.md, the apps/web/CLAUDE.md, and the .claude/rules/astro.yaml rule file simultaneously. The three together form the complete instruction context for that edit.
When to Use Each
- Use the root CLAUDE.md for invariants that apply to every file in the project. Examples: "we use pnpm, not npm," "commit messages follow conventional commits," "every PR must have tests."
- Use a directory CLAUDE.md when an entire subtree shares context that is always relevant in that subtree, independent of file extension or file type. Example:
apps/web/CLAUDE.mddocuments the web app's data-fetching patterns and routing conventions that apply to every file in the web app. - Use a path-specific rule when the applicability is conditional on file pattern (tests vs production, generated vs hand-written, one extension vs another) or when the rule must span multiple directories (all
*.generated.tsfiles regardless of package).
Why the Layering Is Important for the Exam
CCA-F distractor answers routinely conflate directory CLAUDE.md with path-specific rules. The two are related but not interchangeable. Directory CLAUDE.md is unconditional within a directory subtree; path-specific rules are conditional on glob patterns, independent of working directory. Mixing these mental models produces designs that are either under-scoped (too much in the root CLAUDE.md) or over-scoped (subtree-specific conditionals in a file that should have been path-specific).
Path-specific rules do not replace the CLAUDE.md hierarchy. Answers that frame .claude/rules/ as a new "instead of CLAUDE.md" system are wrong. CLAUDE.md files provide unconditional context; path-specific rules supplement them with conditional context. The exam frequently tests whether you know the two systems layer together rather than replacing each other.
Source ↗
Debugging Active Rules — Verifying Which Rules Are Applied for a Given File
Silent failure is the most common frustration with path-specific rules: the rule file is committed, the pattern looks right, but Claude is ignoring the convention. Being able to verify which rules are actually active for a given file is an operational skill every CCA-F candidate should have.
Three Ways to Check Active Rules
- Ask Claude directly. A session-level prompt like "Which rule files are currently loaded for
apps/web/src/index.astro? List each rule file's name and thepaths:pattern that matched" will produce an inventory Claude has visibility into. - Use Claude Code's diagnostic output. Depending on Claude Code version, the CLI exposes a command (or an equivalent slash command) that lists the active configuration including which rule files matched the current working file.
- Dry-run a representative edit. Ask Claude to explain how it would edit a target file; if the output reflects the rule's conventions, the rule is active. If it does not, inspect the
paths:pattern for typos.
Common Failure Modes
- Glob typo. Missing
**, wrong extension, misspelled directory name. Fix by iteratively narrowing the pattern. - Wrong base directory. Patterns are evaluated relative to the project root, not the current working directory.
src/**from a.claude/rules/file at the root matches./src/**, not./apps/web/src/**. - File in
.gitignore. Generated files that are gitignored still exist on disk and still match path-specific rules when Claude Code edits them — this is correct behaviour, but sometimes surprising. - User-level vs project-level location mismatch. A rule placed in
~/.claude/rules/applies only on one machine and is not committed to the repository. A rule placed in.claude/rules/inside the repo applies for every contributor. Mixing these up produces "it works on my machine" bugs.
Treat Rule Debugging as a First-Class Workflow
Rules are code. Treat the .claude/rules/ directory with the same discipline you treat any other code: commit atomic changes, review glob patterns in PRs, and include a representative sample of matching files in the PR description so reviewers can sanity-check the activation surface.
The three-layer instruction model in one line each:
- Root CLAUDE.md — always loaded, project-wide invariants.
- Directory CLAUDE.md — loaded when cwd is at or below, unconditional within subtree.
- Path-specific rules (
.claude/rules/*.yaml) — loaded conditionally onpaths:glob match against the target file.
Distractor cue: if an answer says path-specific rules "replace" the CLAUDE.md hierarchy, it is wrong. They layer on top. Source ↗
Plain-English Explanation
Abstract config surfaces become intuitive when you anchor them to physical systems most candidates already know. Three very different analogies cover the full sweep of path-specific rules.
Analogy 1: The Restaurant's Station-Specific Recipe Cards
Picture a large restaurant with several stations — the grill, the pastry bench, the cold station, the pizza oven. The head chef keeps a single master book of restaurant-wide standards ("we plate left-to-right," "we portion to the gram," "we call out allergens before service"). That master book is the root CLAUDE.md. But each station also has a laminated card above its workbench with instructions that apply only at that station — the pastry card says "temper chocolate to 31 °C," the pizza card says "oven at 485 °C for 90 seconds." Those cards are path-specific rules. A cook on the grill line does not read the pastry card — it is not visible from the grill — but it is always there for the pastry cook. The cards do not replace the master book; they supplement it with station-specific conventions. The path Claude Code is editing is the station the agent is working at; the rule files are the laminated cards that hang above each station. Both the master book and the relevant station card are in front of the cook simultaneously. No cook ever has to juggle every station's card at once.
Analogy 2: The Library's Section-Specific Signage
A public library has general rules posted at the entrance — "no food, no loud conversation, return books within 21 days." Those general rules are the root CLAUDE.md. Inside the library, specific sections post additional signage: the children's section has "please keep shoes off the story-time rug," the rare-books room has "no pens, pencils only, no photography," the computer lab has "30-minute sessions, no personal USB drives." Those section-specific signs are path-specific rules. A patron in the children's section sees the general rules plus the children's-section sign; a researcher in the rare-books room sees the general rules plus the rare-books sign. The general rules do not change — they apply everywhere — but each room adds its own conditional layer. A regex-style matching scheme would be like trying to write one master sign that encodes every section's exception in a single long conditional sentence. Nobody would read it, and nobody would follow it. Separate section-specific signs are more reliable, which is exactly why Claude Code separates path-specific rules into their own files under .claude/rules/.
Analogy 3: The Electrician's Wiring Code Overlay
A licensed electrician carries the national electrical code (the always-on rulebook — the root CLAUDE.md). But building codes are also local: a given city may have amendments that apply only within its jurisdiction; a given building type (hospital, data centre, residence) may have additional requirements that apply only to that building type; a given room (wet area, explosion-proof environment, outdoor installation) may have further requirements that apply only in that room. An electrician wiring a hospital operating theatre simultaneously follows the national code, the hospital code, and the wet-area code. None of the three overrides another — they stack. A wiring job in a residential kitchen follows the national code and the residential code but not the hospital code. The overlay is purely location-based. Claude Code's path-specific rules are exactly this kind of overlay: the file's location (matched by paths: globs) determines which conditional rule-books apply, layered on top of the unconditional project-wide CLAUDE.md.
Which Analogy Fits Which Exam Question
- Questions about why path-specific rules exist → restaurant station analogy (instruction relevance per workplace).
- Questions about how rules layer with CLAUDE.md → library signage analogy (always-on rules plus section-specific rules).
- Questions about monorepo/conditional applicability → electrician's code overlay analogy (jurisdiction-based stacking).
Common Exam Traps
CCA-F Domain 3 consistently exploits five recurring trap patterns around path-specific rules. All five are documented in community pass reports and appear disguised as plausible distractor choices.
Trap 1: paths Uses Regex Instead of Glob
paths: patterns are globs, not regular expressions. Distractor answers describe patterns using regex operators (.*, \d+, character classes as [^abc] for negation) and present them as correct. They are wrong. Glob uses *, **, ?, [abc], {a,b,c}, and !. If an answer treats paths: as regex, eliminate it.
Trap 2: Rules Replace the CLAUDE.md Hierarchy
Path-specific rules supplement the CLAUDE.md hierarchy; they do not replace it. Distractor answers frame .claude/rules/ as a "new modern alternative" to CLAUDE.md or recommend deleting CLAUDE.md in favour of path-specific rules. Both framings are wrong. The correct architecture is a lean root CLAUDE.md plus targeted path-specific rules for conditional subtrees.
Trap 3: A Rule Needs to Be Imported or Enabled
Path-specific rules are discovered automatically from .claude/rules/. No import statement, no CLI flag, no slash command invocation is needed to activate them. Distractor answers that add a "load the rule" step (a /load-rules slash command, an @import path/to/rule.yaml reference, an enabled: true field) are over-engineered and wrong.
Trap 4: User-Level Rules Apply to the Whole Team
Rules in ~/.claude/rules/ apply only on the local developer's machine; they are not committed to the repo and do not propagate to teammates or CI. Rules that must apply to every contributor belong under .claude/rules/ at the project root. Distractor answers that place team conventions in ~/.claude/rules/ or machine-specific preferences in the project rules directory are wrong in opposite directions.
Trap 5: Pattern Specificity Is the Only Tie-Breaker
When two rules both match a file, specificity of the paths: pattern is the first tie-breaker, but not the only one. The priority: frontmatter field breaks ties among equally-specific rules, and load order is the final tie-breaker. Distractor answers that say "whichever rule file has the longer path wins, always" ignore the priority: field and the explicit-override mechanism.
Practice Anchors
Path-specific rule concepts show up most heavily in one of the six CCA-F scenarios. Treat the following as the architecture spine for scenario-cluster questions.
Code-Generation-with-Claude-Code Scenario
This is the scenario that exercises Task 3.3 most directly. In it, Claude Code is used to generate and refactor code across a non-trivial codebase — typically a monorepo with multiple packages, a mix of frontend and backend, separate test directories, and generated or auto-managed files that must never be hand-edited. The scenario leans on path-specific rules heavily: expect questions where the correct architecture is a thin root CLAUDE.md for team-wide invariants, a per-package rule file under .claude/rules/ for framework-specific conventions, a **/*.test.ts rule for test conventions, and a **/generated/** or **/*.generated.ts rule that tells Claude the file is auto-managed. Distractor answers routinely cram every convention into a single root CLAUDE.md, ignore the generated-file rule (leading to Claude hand-editing code that will be overwritten on next generation), or place team rules in the user-level directory.
Also expect questions that test the precedence order when multiple rule files match the same file, questions that test the use of negation patterns (a rule that applies to "everything under src/ except generated files"), and questions on verifying rule activation — how an operator would confirm that the correct rule is loaded for a given target file. The developer-productivity-with-claude scenario also touches on path-specific rules when the agent works across heterogeneous codebases, though its primary weight is on Task 3.1 (CLAUDE.md hierarchy) rather than Task 3.3.
FAQ — Path-Specific Rules Top 5 Questions
What exactly is a path-specific rule in Claude Code?
A path-specific rule is a YAML-frontmatter file stored in .claude/rules/ whose paths: array declares a list of glob patterns. The rule body is loaded into Claude's context only when the current target file matches at least one of the declared patterns. Path-specific rules are the conditional layer on top of the unconditional CLAUDE.md hierarchy. Rule files are discovered automatically at session start — no import, no enable flag, no slash command is needed — and they coexist with root and directory CLAUDE.md files rather than replacing them. The canonical use cases are framework isolation in heterogeneous codebases, test-file conventions, generated-file protection, and package-scoped rules in monorepos.
Are paths in a rule file regex or glob patterns?
Glob, not regex. The operators you will encounter are * (one path segment, any characters), ** (zero or more path segments), ? (single character), [abc] (character class), {a,b,c} (brace alternation), and ! (negation). Attempting to use regex operators like .*, \d+, or anchored quantifiers inside paths: will silently fail to match. This distinction is one of the most frequently tested mechanical details on CCA-F Task 3.3. When building a rule, start with the coarsest pattern that works (** or src/**), verify activation on a representative file, then narrow the pattern if needed.
Do path-specific rules replace CLAUDE.md files?
No. Path-specific rules supplement the CLAUDE.md hierarchy — they do not replace it. The correct architecture is a lean root CLAUDE.md carrying project-wide invariants, optionally directory CLAUDE.md files for subtree-unconditional context, plus path-specific rules in .claude/rules/ for conditional subtree conventions. All three layers stack: an edit on a file can activate the root CLAUDE.md, a directory CLAUDE.md, and multiple path-specific rule files at the same time, all of which contribute to the instruction context Claude sees. CCA-F distractor answers that frame path-specific rules as a newer alternative to CLAUDE.md are wrong; the systems are complementary.
What happens when two rule files both match the same target file?
Both rule files activate and both rule bodies are loaded into context. If their instructions are merely additive (one covers testing conventions, the other covers backend error handling), they compose cleanly. If their instructions genuinely conflict, precedence is resolved in this order: (1) the rule with the more specific paths: pattern wins; (2) among equally specific rules, the higher priority: field wins; (3) as a final tie-breaker, the later-loaded rule wins. Architects should design rule files to minimize genuine conflicts rather than relying on precedence to sort them out — explicit "local exception" framing inside the more-specific rule is preferable to implicit override.
How do I verify which rules are active for a given file, and what causes silent activation failures?
Three methods work: (1) ask Claude directly inside the session ("which rule files are currently loaded for apps/web/src/index.astro?"); (2) use Claude Code's diagnostic output via the CLI; (3) dry-run a representative edit and check whether Claude's proposed change reflects the rule's conventions. The most common silent-failure causes are glob typos (missing **, wrong extension), patterns evaluated relative to the wrong base directory (paths resolve relative to the project root containing .claude/, not the current working directory), and placing team-wide rules in the user-level ~/.claude/rules/ directory instead of the project's .claude/rules/. Treat the rules directory as code: version it, review glob patterns in PRs, and include a representative matching file in the PR description so reviewers can sanity-check the activation surface.
Further Reading
- CLAUDE.md configuration — Claude Code Docs: https://docs.anthropic.com/en/docs/claude-code/claude-md
- Claude Code settings reference: https://docs.anthropic.com/en/docs/claude-code/settings
- Claude Code features overview: https://docs.anthropic.com/en/docs/claude-code/overview
- Custom slash commands and skills: https://docs.anthropic.com/en/docs/claude-code/slash-commands
Related ExamHub topics: Claude Code CLAUDE.md Hierarchy, Custom Slash Commands and Skills, Context Management — Large Codebase Exploration, Built-in Tools Selection and Application.