How rules are loaded
In the /debug lifecycle, we saw the scene where "opening a .ts file brings the TypeScript rule along." This chapter digs into that mechanism on its own.
There are two kinds of rules
~/.claude/rules/ holds Markdown files of norms (34 of them in this environment). The important thing is that they split into two kinds by when they are loaded.
- Always loaded (7): injected into the context at startup without fail. The core that applies to every response
- path-scoped (27): loaded only when you open a specific file
The always-loaded set is narrowed down to just the core you "want enforced in any work." Foundations like verification-first (fact-check.md), structure your questions (ask-user-question.md), and the commit convention (git-workflow.md).
The switch is decided by the frontmatter paths:
What divides the two kinds is whether the frontmatter at the top of the rule file has paths:. If paths: is present, the rule is loaded only when you open a file matching that glob; if absent, it is always loaded. This switching mechanism is Claude Code standard (📦); the contents of the 34 rules are the author's own (🔧).
---
name: typescript-strict
description: Consolidated TypeScript type rules (...)
paths:
- "**/*.ts"
- "**/*.tsx"
- "**/*.vue"
---
In this paths: glob you can use ** (any depth), * (any character), and {a,b} (brace expansion that matches either). It says: open any of .ts / .tsx / .vue, and this rule is injected.
You can also scope it to design files only
Depending on the paths: specification, you can even make "a rule that applies only when you touch the harness's design files." For example, spec-first-pipeline.md is loaded only when you open a design file under ~/.claude/, such as rules or hooks.
paths:
- "**/.claude/rules/**"
- "**/.claude/agents/**"
- "**/.claude/hooks/**"
- "**/.claude/skills/*/SKILL.md"
- "**/.claude/references/**"
---
It does not come up in everyday app development, and steps forward only when you are designing the harness itself. The advantage of path-scoped is that you can pinpoint a norm to "the situation where you want it to apply."
Carrying all 34 at once would fill the context with norms and crowd out the actual work that matters. On top of that, seeing the Terraform norm while you are writing Vue becomes noise for your judgment. A design that surfaces "only the norms relevant to the file you are touching right now" lowers cognitive load.
If a single file matches the paths: of multiple rules, all of them are loaded. There is no priority or conflict-detection mechanism. Open a .tsx and both typescript-strict and react-component apply, for example. The responsibility to write norms so they do not conflict lies with the designer.
Rules carry their "origin"
Finally, one point about the contents rather than the loading mechanism. Many rule files in this environment have an "origin" section that records which failure gave birth to this norm. Things like "explicit instruction in the 2026-04-20 session" or "the history of catching recurring plain questions with a hook."
Norms are not increased on a whim; they are the result of making real failures permanent one at a time. When the origin is written down, it also becomes material for later judging "is this norm still needed?" This way of growing them is covered in detail in Ratchet.
The key points:
- Rules split into "always loaded: 7" and "path-scoped: 27"
- The split is decided by whether the frontmatter
paths:(glob) is present - Loading only when you open a matching file keeps cognitive load down while still enforcing norms
- On multiple matches, all rules are loaded (no priority)
- Rules record their "origin," so you can later trace which failure each norm came from
Next, in How hooks work, we look at the overall picture of the deterministic mechanisms.