Glass Box Terrarium, explained from the inside

Last updated · Latest source on GitHub ↗

Claude CodeLesson

Path-specific rules

An agent can't follow an instruction it never sees, and a CLAUDE.md that holds every instruction about every file grows too long to follow. A path-specific rule puts an instruction in front of the agent when it works on the files the instruction is about.

Know path-specific rules already? Skip to In Terrarium.

Outside the box · General

The concept

Claude Code reads each Markdown file in a project's .claude/rules/ folder, including its subfolders, as a rule. A rule without a paths field loads at the start of every session, like CLAUDE.md. A rule whose frontmatter lists paths loads only when Claude works with a file that one of its globs matches: when it reads, writes or edits that file with its own tools, or views it with a simple shell read such as cat on that one file.

---
paths:
  - "src/api/**/*.ts"
---
# API handlers

- Validate every request body before you use it.

paths is the only frontmatter field Claude Code reads. It ignores any other field without an error, and removes the frontmatter before the rule reaches Claude's context.

Full referenceClaude Code docs: Path-specific rules

Looking inside

In Terrarium

Terrarium gives each instruction one home, chosen by what it is about. An instruction about certain files is a in .claude/rules/ whose paths match those files. An instruction every session needs, or one tied to an action such as a commit or a PR, stays in CLAUDE.md. For example, .claude/rules/tenant-layers.md matches each Tenant layer's nuxt.config.ts, tenant.config.ts and app/ folder, so an agent editing a learns that a layer's CSS loads on every page:

.claude/rules/tenant-layers.md ↗1–26as of
1---
2paths:
3  - "nuxt.config.ts"
4  - "layers/*/nuxt.config.ts"
5  - "layers/*/tenant.config.ts"
6  - "layers/*/app/**"
7---
8# Tenant layers
⋯<!-- … -->
25- **A layer is not a sandbox.** Its `css:` loads on every page (scope it under
26  the wrapper class), its plugins and `nuxt.config` flags apply app-wide (keep
⋯<!-- … -->

Every has a summary rule too, adr-NNNN.md. It gives the ADR's key parts as instructions and says when to read the whole ADR. Its paths list the files the ADR governs, so the decision arrives when an agent works on something it governs. Only a summary whose ADR is relevant to every session has no paths, and it loads at session start.

scripts/gate/validate-adr-rules.ts, part of pnpm validate:content and so of the , fails any rule other than an ADR summary that has no paths. How it also keeps each summary in step with its ADR is in Decision records.

Two hooks fill the gaps where Claude Code loads no rule. Running a reads no file, so scripts/hooks/skill-rules-hint.ts adds the rules whose paths name that Skill's folder. A piped or chained shell command is not a simple read, so scripts/hooks/bash-rules-hint.ts adds the rules for the files such a command read. .claude/settings.json wires both in, and both fail open: an error adds nothing and never blocks the call.

Why it's built this way

  • Rules find the agent. CLAUDE.md lines like "before you edit X, read Y" were often skipped. A loads by itself when the agent touches its files, so file-specific instructions moved there. The cost: a rule arrives after a file is touched, so an agent can edit before reading the full ADR; a hint after each write points it there. ADR-0029 (docs/adr/0029-instructions-load-with-the-files-they-govern.md).
  • Short ADR summaries. A short summary rule brings each ADR's key parts to the files it governs, for the reasons Decision records gives. ADR-0029 (docs/adr/0029-instructions-load-with-the-files-they-govern.md).
  • One home per instruction. CLAUDE.md loads every session, and no file pattern matches an action such as a commit, so those instructions stay there. Other rules loading at session start would give two homes and drifting copies, so only ADR summaries may skip paths; the gate fails any other. ADR-0029 (docs/adr/0029-instructions-load-with-the-files-they-govern.md).
  • Hooks as backstop. Some ways an agent reads files load no rule, such as a chained shell command or running a . Two hooks add the missing rules, as hints only: working out paths from a shell command is a guess, and a broken hint must never block a session. ADR-0029 (docs/adr/0029-instructions-load-with-the-files-they-govern.md).

What to watch for

  • A rule can't order a step. Why, and where such steps go instead: CLAUDE.md.
  • A piped or chained shell read loads no rule by itself. scripts/hooks/bash-rules-hint.ts fills that gap.
  • A rule change waits for a person. Every file in .claude/rules/ is on the list, so an agent may edit a rule but not merge the change.

Try it in your project

Find one line in your CLAUDE.md about a particular set of files. Move it into a file in .claude/rules/ whose paths match those files, and delete the line from CLAUDE.md.

Where next

Walkthroughs through this Lesson

Last updated · Latest source on GitHub ↗

Something went wrong

This content couldn’t be loaded. Reloading the page usually fixes it.

Technical details
route: /t/glassbox/guide/claude-code/path-scoped-rules