Workspaces
Governance rule loading
Lesson 1 of 1

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

Tier 1, eager

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.

Tier 2, glob-matched

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.

Tier 3, on demand

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.

The three context tiers, ordered by how they load, with what governs the middle one CLAUDE.md loads every session .claude/rules/*.md loads on a paths: match or every session with none .claude/context/*.md reads only on request Every rule under governance/rules/core/ that carries no paths: glob reaches every session the same way tier 1 does, since every stack this toolkit ships depends on the base stack that installs it whole.
The middle tier is the only one with a condition attached, and the condition lives in the rule's own frontmatter rather than in code that reads it.

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.

1Authoredgovernance/rules/core/005-behavior.md, reviewed and committed like any other source file.write once
2Regeneratedbun run check copies it to .claude/rules/core/005-behavior.md, the same content, a different address.every check
3LoadedA session editing a file under this rule's glob, or any session at all if it carries none, reads the consumed copy.per session

The test that decides a fact's tier

Three questions separate the tiers, and none of them is about how important the fact is:

  1. 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.

  2. 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.

  3. 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?

Correct: CLAUDE.md, ARCHITECTURE.md, and any glob-free rule. A rule with no 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?

Correct: whether the rule loads at all. The glob is a loading condition, not a permission boundary and not a severity setting. A rule with no glob simply has no condition, so it loads unconditionally rather than never shipping.

3. Where does this repository's own copy of a rule that a session actually reads live?

Correct: .claude/rules/. governance/rules/ is where a maintainer writes and reviews a rule; .claude/rules/ is the consumed copy a session, in this repository or in any target that ran canon gov sync, actually loads. Editing the consumed copy by hand loses the edit at the next regeneration.

4. Why does a .claude/context/<domain>.md entry not load automatically the way CLAUDE.md does?

Correct: it is opt-in by design. Loading every context entry eagerly rebuilds the one large file the tiers were split to avoid. The index at .claude/context/index.md is what keeps an entry discoverable without loading it, so a session picks what it needs before touching that domain.