How a rule reaches you
Lesson 1. How a coding rule written once in this repository reaches a Claude Code session editing a file, and why it arrives as three tiers rather than one.
Assumes: you have used Claude Code and know a CLAUDE.md file exists, but
have never traced how a rule below that file actually loads.
Covers: the three tiers, what a rule's paths glob gates, and the path
from where a rule is written to where a session reads it.
Sources: this repository's own CLAUDE.md, ARCHITECTURE.md, and one live
rule, cited at the foot.
One file would have been simpler
The obvious design is a single CLAUDE.md holding every rule this project has ever written. That design was tried here first, and it grows without bound: every session pays to read every rule, whether or not the file being edited has anything to do with most of them.
What replaced it is three tiers, split by one question: does this fact need to be true for every session, or only for the session touching the one file it governs?
The three tiers
CLAUDE.md and .claude/ARCHITECTURE.md load into every session, every time, with no condition attached. This is where a cross-domain rule belongs, the kind that has to be true regardless of what is being edited.
A rule under .claude/rules/ carries frontmatter, and that frontmatter
can name a paths: glob. A rule with a glob loads only
when a session edits a file matching it. A rule with no glob loads
every session anyway, the same as tier 1, since nothing in its
frontmatter narrows when it applies.
A file under .claude/context/<domain>.md carries narrative a session opens by choice, not automatically. .claude/context/index.md lists every entry so a session can find the one it needs before touching that domain, rather than never learning the entry exists.
What the glob is actually for
A rule such as governance/rules/core/010-testing.md carries
no paths: key at all, so it behaves like tier 1: every
session gets it, whatever file is open. A rule scoped to one language or
one folder narrows itself with a glob, so a TypeScript naming convention
never loads into a session editing a Python file that has nothing to
gain from reading it.
The glob is read once, when a session starts editing a matching path, and the rule's body is injected into that session's context from then on. It is not re-evaluated per line, and it does not restrict which files the session may touch. A rule is advisory text that arrives at the right moment, not a permission system.
From where a rule is written to where a session reads it
This repository authors a rule once, at
governance/rules/<stack>/<nnn>-<slug>.md.
Nothing reads that path directly during a session. What a session
actually loads is .claude/rules/, a generated copy of the
authoring root, regenerated by bun run check and checked
for drift on every push.
Two paths for one rule sounds like duplication, and the reason it is not
comes down to who edits which copy. The authoring root is what this
project's own maintainers write and review. The consumed copy under
.claude/ is what every session, in this repository and in
any project that ran canon gov sync, actually reads.
Writing straight into the consumed copy would mean editing a generated
file by hand, which the next regeneration silently overwrites.
The test that decides a fact's tier
Three questions separate the tiers, and none of them is about how important the fact is:
-
Does it fire on a specific edit, or does it apply regardless?
A fact tied to one kind of file belongs behind a glob. A fact true of the whole project belongs in tier 1.
-
Does violating it ship silently?
A rule delivered at the moment of the matching edit competes for attention with far less, which is what makes a glob-matched rule more likely to actually be followed than the same text buried in a large eager file.
-
Does it change often enough that a stale copy would mislead?
A rule installed through governance sync still carries a later fix to every project that installed it. A fact hand-copied into a seed file at scaffold time stays exactly as wrong as it was the day it was copied.
What does not decide it. How important the fact feels to the person writing it. A rule per gotcha, added because each one felt worth remembering, is exactly what rebuilds the single unbounded file the three tiers exist to avoid.
Retrieval check
Answer before scrolling back. Getting one wrong and then reading why is worth more than a clean pass.
1. What loads into every session regardless of which file is being edited?
paths: key has nothing narrowing when it
applies, so it reaches every session the same way the two eager
files do. A context entry is the opposite case: it never loads on
its own, glob or none.
2. What does a rule's frontmatter paths: glob actually
gate?
3. Where does this repository's own copy of a rule that a session actually reads live?
4. Why does a .claude/context/<domain>.md entry not load automatically the way CLAUDE.md does?