Home › Study guides › CCAR-F › Domain 3 › Lesson 3.3
CCAR-F · Domain 3 · 20% of the exam · Lesson 3.3 · 20 min read
Path-specific rules: conventions that follow the file
How .claude/rules/ files with a YAML paths field load only for matching files, how glob patterns pick files by type, and when they beat a directory CLAUDE.md.
Written against task statement 3.3 of the official CCAR-F exam guide (Version 1.0, effective July 2026). An independent resource, not affiliated with Anthropic; the practice questions are written from scratch.
3.3.1 Why one instruction file cannot know which file you are editing
Picture a team that uses Claude Code, Anthropic's command-line coding assistant, to build a web application. Their project holds several kinds of file, and each kind has its own house rules. React components (the pieces each screen is built from) live in src/components/ and follow one style. API handlers in src/api/, the code that answers the app's requests for data (API stands for application programming interface), follow another, with a fixed way of reporting errors. Database models in src/db/ follow a third, the repository pattern (a fixed way of organising the code that reads and writes data). A terraform/ folder holds Terraform files, which describe the team's cloud servers, with naming rules of their own.
Then there are the tests. Every component, handler and model has a test file sitting right beside it: Button.test.tsx next to Button.tsx, in every folder of the project. The .test.tsx ending is what marks a file as a test, and all tests follow one set of conventions wherever they sit.
The obvious move is to write all of that into the project's CLAUDE.md, the instruction file Claude Code reads at the start of every session (one run of Claude Code, from launch to exit). Then the conventions are always present, and that is the problem. Everything loaded sits in the context window, everything the model can see at once, and every word there costs tokens, the small pieces of text that usage is measured in. A request to change a Terraform file drags the React, API, database and testing rules along on every turn. Worse, once a CLAUDE.md passes about 200 lines, Claude follows it less reliably, because instructions that are always loaded compete for attention.
What the team wants is instructions that behave like a good colleague: silent until the relevant file is open, then precise. Claude Code has exactly this mechanism. A rule file in the .claude/rules/ folder can state, in a short block at its top, which files it applies to. It names them with glob patterns, file paths with wildcards in them, such as **/*.test.tsx for "every test file, wherever it is". Claude Code then loads the rule only when Claude works with a file that matches. These are path-specific rules, which the docs also call path-scoped rules.
3.3.2 A rule file and its paths front matter
Start with the question every builder asks first: what does one of these files look like, and where does it go? A rule is an ordinary Markdown file (plain text, with # for headings and - for bullets) in the project's .claude/rules/ folder. The team commits it with the rest of the project, so everyone shares it. Claude Code finds every .md file in that folder, including files in subfolders, so rules can be sorted into folders such as frontend/ and backend/. Those subfolders are only for tidiness; a folder name does not limit where a rule applies. Each file should cover one topic and carry a descriptive name: testing.md, api-handlers.md, terraform.md.
What turns an ordinary rule into a path-specific one is its YAML front matter: a small block of settings at the very top of the file, fenced by two lines of three hyphens (---). The opening --- must be the file's first line. YAML (a recursive acronym for "YAML Ain't Markup Language") is the plain-text format for those settings: a name, a colon, then a value, with list items on lines starting with -. A rule needs only one setting, paths, whose value is a list of glob patterns. Here is the team's rule for test files. The four lines from --- to --- are the whole mechanism; everything below them is the instruction text Claude will see.
---
paths:
- "**/*.test.tsx" # every .tsx test file, in any folder
---
# Test conventions
- Use React Testing Library; query by role, never by CSS class.
- Never mock the component under test.
- Keep each test file beside the component it tests.
The front matter is for Claude Code, not for Claude. Claude Code reads paths to decide when the rule loads, then removes the block, so the model only ever sees the instructions. The paths field is the only setting Claude Code reads from a rule, and it ignores any other name without an error. The list can be written one item per line, as above, or on one line in square brackets, the form the exam guide uses: paths: ["terraform/**/*"]. Both are the same YAML list.
A rule file with no paths field is not broken. It is unconditional: Claude Code loads it at launch in every session, with the same priority as the project's .claude/CLAUDE.md. That is right for a rule every task needs, such as the team's commit message format, and wrong for a Terraform-only one. The same happens when the YAML between the markers has a typo and cannot be read. Claude Code ignores the block and loads the rule as if it had no paths.
With that shape in hand, the team writes one rule per convention. Three of them are enough to show the pattern.
Three rules, three scopes
testing.md
**/*.test.tsxthe paths fieldapi-handlers.md
src/api/**/*.tsthe paths fieldsrc/api/ onlywhen it loadsterraform.md
terraform/**/*the paths fieldterraform/ onlywhen it loads3.3.3 What loads when a developer opens Button.test.tsx
Now the runtime question: what actually happens during a session? A developer asks Claude Code to add a test for a new option on the Button component. To do that, Claude asks Claude Code to open src/components/Button.test.tsx, and that read is the trigger. Claude Code checks the file's path against the paths of every rule and loads the ones that match, at that moment rather than at session start. The rules that do not match stay on disk and cost nothing.
Which rules load for Button.test.tsx
CLAUDE.md and rules without paths loadsrc/components/Button.test.tsxthe triggertesting.md matches**/*.test.tsxapi-handlers.md skippedsrc/api/**/*.tsterraform.md skippedterraform/**/*Matching is purely about the path, so one file can satisfy several rules at once. Suppose the team also has a react-components.md rule scoped to src/components/**/*.tsx. The test file matches that too, because it is still a .tsx file under src/components/, so both rules load and both apply. That is usually what you want. If two loaded rules ever contradict each other, though, Claude may follow either one, so keep overlapping rules consistent.
The payoff comes in two halves. First, less irrelevant context: while the developer is in a test file, the model is not reading about Terraform naming or database models, so the instructions it does see stand out. Second, lower token usage: the whole context goes to the model with every request, so a rule that stays on disk until it is needed saves tokens on every turn it would otherwise have padded.
One practical detail helps when a rule seems not to fire. Run /context in a session and look at the list under Memory files, which shows the CLAUDE.md and rules files loaded so far. If testing.md is missing after Claude has read a test file, the pattern is wrong. A wrong pattern does not produce an error; it quietly matches nothing.
3.3.4 Glob patterns: choosing files by type, not by place
The paths field is only as good as the patterns in it, so let's be precise about what a glob pattern is. It is a file path with wildcards, symbols that stand for "anything here". A single * stands for any run of characters inside one folder or file name, so it never crosses a /. A double ** stands for any number of folders, including none. Put them together and you can describe a set of files by their type, their location, or both.
Think of a glob as a postal address with blanks in it. The pattern terraform/**/* says "any house on any street in the Terraform district". The pattern **/*.test.tsx says "any house whose name ends in .test.tsx, in any district". The first is scoped by location and the second by type, and the second is what reaches the team's scattered test files in one line.
| Pattern | What it matches | Typical use |
|---|---|---|
**/*.test.tsx |
Every .test.tsx file in any folder, at any depth |
Test conventions that follow the file |
terraform/**/* |
Every file under terraform/, at any depth |
Conventions bound to one area of the project |
src/api/**/*.ts |
Every .ts file under src/api/ |
A rule for one subsystem |
src/components/*.tsx |
.tsx files directly in src/components/, no deeper |
A single flat folder |
*.md |
Markdown files in the project root only | Root documentation rules |
src/**/*.{ts,tsx} |
Both .ts and .tsx files under src/ |
Several extensions in one pattern |
Memorise the two patterns the exam guide uses, terraform/**/* and **/*.test.tsx, and the difference between * and **. Recognise the rest. Braces, as in {ts,tsx}, let one pattern cover several extensions. The paths list can also hold several patterns, so one rule can cover **/*.test.tsx and **/*.test.ts together. For the team's database models, src/db/**/*.ts is enough; for the API handlers, src/api/**/*.ts.
The most common mistake is a single star where a double star was needed. src/components/*.test.tsx matches src/components/Button.test.tsx. It does not match src/components/forms/Input.test.tsx, because * stops at the next /. Test files sit at every depth, so the pattern must be **/*.test.tsx. Patterns are written relative to the project root, which is why *.md on its own means Markdown files at the top level only.
3.3.5 Why a glob beats a directory CLAUDE.md for scattered files
Here is the comparison this task statement turns on. Claude Code offers a second way to scope instructions: a CLAUDE.md placed inside a subfolder. If you start Claude Code from the project root, that file does not load at launch; it loads when Claude reads a file in that subfolder. So the team could put the API conventions in src/api/CLAUDE.md and the Terraform conventions in terraform/CLAUDE.md, and both would behave sensibly. When is that the right choice, and when is a rule better?
The deciding fact is that a directory CLAUDE.md is bound to its folder. It knows nothing about file types; it applies to whatever Claude reads in that folder. That suits conventions that live in one place, and it fails for conventions that follow a KIND of file wherever it goes. The team's test files sit beside components, beside handlers, beside models, and in every nested folder under those.
To reach them all with directory files, the team would need a CLAUDE.md in every folder that holds a test. Each copy would say the same thing, and copies drift apart as people update some and forget others. Each would also load for the non-test files in its folder, so the scoping is wrong anyway. A single rule with paths: ["**/*.test.tsx"] fixes both problems, and changing the convention becomes one edit in one file.
Three ways to scope the test conventions
CLAUDE.mdalways loaded, costs tokens on every taskCLAUDE.md in every folder with testsduplicated, drifts, loads for non-test files too.claude/rules/testing.md with **/*.test.tsxone file, matched by type, loaded on demandNone of this makes directory CLAUDE.md files wrong, and the docs give a clean rule of thumb. A per-directory file suits a folder whose owners maintain their own conventions and want them kept beside that code. A monorepo (one repository holding many separately owned packages) is the classic case. A path-scoped rule suits conventions you want kept in one place, or one convention that applies to many scattered paths. The team's Terraform conventions could go either way; the test conventions only work as a rule.
| Approach | Where it lives | When it loads | Best for |
|---|---|---|---|
Project CLAUDE.md |
Project root or .claude/ |
Every session, at launch | Rules that apply to every task |
Directory CLAUDE.md |
Inside the subfolder | When Claude reads a file there (or at launch, if started there) | Conventions owned with one area's code |
| Path-scoped rule | .claude/rules/, central |
When Claude works with a file matching paths |
Conventions that follow a file type across the project |
Memorise the last two rows: a directory file is bound to a folder, a path-scoped rule to a file pattern, and scattered files need the pattern.
3.3.6 The exam traps
The mistakes in this task statement all come from putting an instruction in the wrong place: somewhere it loads too often, too narrowly, or only if Claude happens to pick it up. Questions usually describe a team with a symptom (tokens wasted, a convention ignored, a dozen copies of the same file) and ask for the fix.
- ✗ Writing every convention into the project
CLAUDE.md, under a heading per area. ✓ Move file-specific conventions into.claude/rules/files withpathsfront matter. Headings still load in every session, and they leave Claude to infer which section applies. Apathspattern is an explicit match on the file path. - ✗ Copying a
CLAUDE.mdinto every folder that holds test files. ✓ One rule withpaths: ["**/*.test.tsx"]. A directoryCLAUDE.mdis bound to its folder, while a glob selects by file type across the whole project, in one file that cannot drift. - ✗ Packaging standing conventions as a skill. ✓ Use a rule. A skill (a packaged set of instructions in
.claude/skills/) comes into play when someone invokes it or when Claude judges it relevant. A path-scoped rule loads on a file-path match, with no judgement call involved. - ✗ Scoping with a single star,
src/components/*.test.tsx. ✓ Use**/*.test.tsx. A single*stops at the next/, so nested test files are missed, and a pattern that matches nothing fails silently. - ✗ Leaving out or misspelling the
pathsfield and expecting the rule to be conditional. ✓ Putpathsfront matter at the very top of the file. Without it, a rule loads at launch likeCLAUDE.md, which is right for global rules and wrong for a Terraform-only one.
3.3.7 Put it together: scope the team's conventions
You now have every piece. The .claude/rules/ folder holds the rules, and the paths front matter decides when each one loads: when Claude reads a matching file. The difference between * and ** decides which files match, and a glob beats a directory CLAUDE.md for files spread across the project. The quickest way to make it stick is to build a small rule set and then watch a broken rule fail.
Path-specific rules settle what Claude knows while it works on each file. The rest of the domain turns to how the work gets done. Plan mode versus direct execution (3.4) decides whether Claude plans before it edits. Iterative refinement (3.5) improves a result over several passes. Continuous integration (3.6), the automated checks that run on every code change, puts the same configuration to work with no one at the keyboard.
Key takeaways
- ✓ Everything in the project
CLAUDE.mdloads every session, so conventions that matter for only some files waste context and tokens there, and a long file is followed less reliably. - ✓ A rule is a Markdown file in
.claude/rules/; YAML front matter with apathslist of glob patterns makes it path-specific, and a rule withoutpathsloads at launch. - ✓ A path-specific rule loads when Claude reads a matching file, normally just before editing it, so conventions for files Claude is not touching cost nothing.
- ✓
*matches within one folder or file name and**crosses any number of folders, so**/*.test.tsxpicks every test file by type andterraform/**/*picks one area. - ✓ A directory
CLAUDE.mdis bound to its folder; for conventions that follow a file type across many folders, one glob-scoped rule replaces a copy in every folder. - ✓ Headings in the root
CLAUDE.mddepend on Claude inferring what applies and a skill on being invoked or judged relevant; a path-scoped rule matches on the file path itself.
Check your understanding
4 questions written for this lesson, then one from the CCAR-F question bank on the same topic. Every answer option is explained, including the ones you did not pick. Nothing is stored.
72 CCAR-F questions on Domain 3, free
Every question in the bank is tagged to a domain, so you can drill 72 questions on Claude Code Configuration & Workflows alone, or sit the full 60-question timed simulator.
Open the CCAR-F question bank → Back to Domain 3 →
The question bank is free. It asks for an account only because the quiz engine has to store answers to score them and show which domains are weak. The questions on this page need nothing.