AnthropicClaude Certified Architect – Foundations2026-103.3 Apply path-specific rules for conditional convention loading
Match conventions to dispersed file types
Completed by the knowledge check
Learning objective
Apply glob patterns to conventions spanning dispersed directories and file types.
Core idea
A convention can follow a filename pattern rather than a directory owner. Tests beside components, handlers, and shared utilities can all need the same instruction even though they have no dedicated test directory. A rule with paths: ["**/*.test.tsx"] selects that file type across the project.
The important decision is the set of files the pattern describes. A valid glob can still be too narrow, missing nested tests, or too broad, activating test-only guidance for production code. Choose the scope from the convention’s meaning, then check positive and negative examples against it.
See 3.3.1 for frontmatter parsing and activation. This lesson concentrates on the selector: directory depth, filename suffixes, multiple patterns, and brace expansion. See 3.3.3 for where the convention should live when that selected set crosses package ownership.
How it works
Separate directory depth from file type
Claude Code documents globs in the paths field for extensions, directories, and combinations of both. A single * matches within a path segment; it does not cross a directory separator. Recursive ** reaches across directory levels. The following patterns illustrate the scope choices:
| Pattern | Selected files | Important boundary |
|---|---|---|
*.md | Markdown files in the project root | Does not reach nested documentation |
src/components/*.tsx | .tsx files directly in src/components/ | Does not reach src/components/forms/ |
**/*.test.tsx | Files ending in .test.tsx across directories | Does not select .test.ts files |
terraform/**/* | Files under terraform/ at different depths | Selects by location, not only .tf extension |
src/api/**/*.ts | .ts files under src/api/ at different depths | Does not select .tsx files or another subsystem |
src/**/*.{ts,tsx} | .ts and .tsx files under src/ | Does not reach a separate lib/ tree |
The suffix matters as much as the wildcard. **/*.tsx includes both component source and test files. **/*.test.tsx narrows the selection to the specified test naming convention. Neither recognizes a test by reading its contents: the trigger is the file path.
For Terraform, terraform/**/* is appropriate if the convention applies to every file in that tree. If it applies only to Terraform source files wherever they occur, a file-type pattern such as **/*.tf expresses a different scope. Do not choose a directory glob merely because the first example happens to live there.
Combine patterns for one convention
One rule can contain multiple patterns. Use separate entries when the convention applies to several file types or disjoint locations. For example, a team can give .claude/rules/testing.md this illustrative condition and body:
---
paths:
- "**/*.test.ts"
- "**/*.test.tsx"
---
# Test conventions
- Cover the public behavior affected by the change.
- Keep test names specific to the expected result.The two entries reach either suffix; a file does not have to satisfy both. This replaces a scope that names only one extension while the repository uses two. It also reaches tests added under another package without requiring a separate rule for that package.
Brace expansion can express the same extension alternatives as **/*.test.{ts,tsx}. Claude Code documents patterns such as src/**/*.{ts,tsx} for multiple extensions. Use braces for compact alternatives when that improves readability; use separate list entries when each selected area needs explicit review.
Several rule files can also match the same path. An API test can match src/api/**/*.ts and **/*.test.ts. Keep their instruction bodies consistent. If their instructions contradict each other, Claude may pick one arbitrarily. Do not assume the test rule automatically overrides the API rule because its glob looks more specific.
Keep expansion bounded and syntax valid
Each brace group multiplies the number of expanded patterns. src/*.{ts,tsx} expands to two patterns; {a,b}/{c,d}/*.{ts,tsx} expands to eight. Claude Code gives a rule’s whole paths list a shared expansion budget of 1,000 patterns and 4 MiB. Patterns without braces do not count against that budget.
If expanding a pattern would exceed the budget, Claude Code uses it unexpanded, and its literal braces match no files. This is a selection failure, not a promise that the pattern will be partially expanded. Keep ordinary convention selectors small rather than generating large combinations of package names and extensions.
Brackets also have glob meaning. [ starts a bracket expression such as [abc]. An invalid expression, such as photos [2024/**, matches nothing while the rule’s other patterns keep working. To match a literal opening bracket, escape it as photos \[2024/**. Treat unusual directory names as syntax cases to inspect, not evidence that the convention’s instruction text is ineffective.
Key distinctions and trade-offs
Location scope versus type scope: terraform/**/* follows one tree. **/*.test.tsx follows one suffix across trees. Combine location and type only when both are part of the intended convention.
Single-level versus recursive matching: src/components/*.tsx fits a flat folder. src/components/**/*.tsx fits nested component folders. Recursive scope is useful only if deeper files should receive the same guidance.
Multiple selectors versus multiple rules: Several patterns in one file select several areas for one instruction body. Separate rule files are appropriate when the bodies teach different conventions. Adding patterns does not create different instructions per pattern.
A broad glob reduces maintenance when matching files move or packages are added, but can activate guidance for unintended files. A narrow glob limits that exposure, but requires updates when the intended scope grows. Review examples on both sides of the boundary rather than equating brevity with correctness.
Architecture / decision scenario
A Claude Code generation workflow updates a web component and its tests. Tests live at src/components/Button.test.tsx, src/components/forms/Input.test.tsx, and packages/api/order.test.ts. The team’s rule uses src/components/*.test.tsx, so it reaches the first test but misses both the nested component test and the API test.
Changing the condition to **/*.test.tsx repairs the directory-depth problem and reaches .test.tsx files across packages. It still misses order.test.ts because the suffix is different. The team uses the two-pattern list in the example, or **/*.test.{ts,tsx}, for the shared convention. It checks src/components/Button.tsx as a negative example: component production code should not independently trigger the test-only rule.
A separate Terraform convention selects terraform/**/*. That reaches terraform/main.tf and terraform/modules/network/main.tf, while the test rule follows test suffixes rather than infrastructure location. An API convention can use src/api/**/*.ts when its subject is that subsystem’s TypeScript files.
The team does not replace these selectors with **/* to fix every miss. It identifies the intended set, adds the missing depth or extension, and checks overlapping instruction bodies for consistency. Matching access activates the rule through the mechanisms in 3.3.1; the glob defines which paths qualify.
Common exam traps
- Using a single
*when nested directories must match. - Assuming
**/*.test.tsxalso covers.test.tsfiles. - Using
**/*.tsxfor a convention intended only for tests. - Treating several
pathsentries as conditions that all must match. - Assuming a more specific pattern overrides another matching rule.
- Building brace combinations without accounting for the shared expansion budget.
Where the exam guide differs
The exam guide frames glob-scoped rules as loading “only when editing matching files.” Claude Code also activates them on matching Read and Write calls and qualifying Bash reads, as well as Edit. The glob decides which paths qualify, not which tool call triggers loading; interpret the exam wording as conditional file scope and test activation through the access mechanisms in 3.3.1.
What to remember
Select by the convention’s actual scope: location, suffix, or both. Recursive ** reaches nested files; a single * stays within one segment. Multiple patterns and brace alternatives can cover disjoint file types, but each rule still has one instruction body. Check intended matches, intended non-matches, and overlapping guidance.
Knowledge check
A rule uses paths: ["src/api/*.ts"]. Claude follows its conventions in src/api/users.ts but not in src/api/orders/refunds.ts. The convention must reach every depth under src/api/ and stay in one rule. What is the fix?
src/api/**/*.tssrc/api/orders/src/api/orders/CLAUDE.md with a copysrc/api/*.{ts,tsx}* matches within one path segment and does not cross a directory separator; ** reaches nested directories. One corrected pattern covers every depth, whereas an extra rule or a copied CLAUDE.md duplicates the convention, and adding an extension leaves the depth problem in place.Tests sit at src/components/forms/Input.test.tsx and packages/api/order.test.ts. The test rule uses **/*.test.tsx and misses the API test. It must not load for production files such as src/components/Button.tsx. Which paths value fits?
["**/*.{ts,tsx}"]["src/**/*.test.{ts,tsx}"]["**/*.test.tsx", "*.test.ts"]["**/*.test.{ts,tsx}"].test selects production code, prefixing src/ misses packages/ , and a bare *.test.ts matches only the project root. Separate entries are alternatives — a file has to match only one of them.packages/api/order.test.ts matches both an API rule (packages/api/**/*.ts) and a test rule (**/*.test.ts). The two bodies give conflicting instructions about mocking, and Claude follows one or the other unpredictably. What should the team do?
.claude/rules/paths fieldReferences
- Anthropic, How Claude remembers your project
- Anthropic, Claude Certified Architect – Foundations Exam Guide