Organize project memory, and see what loaded
A two-hundred-line CLAUDE.md is a tax every session pays in full. Imports organize it; scoped rules make most of it conditional — and there is a way to see exactly what loaded.
01The goal
Split a project’s instructions into imports and scoped rules, and — when Claude ignores one — find out whether its file loaded before you blame the wording.
02The idea
Beginner lesson 5 left you with a CLAUDE.md. It grows. Every line of it loads into every session, whether that session touches the code it describes or not, and a long memory file is slow for everyone. Two tools split it up:
- 01An import — a line such as @docs/conventions.md inside CLAUDE.md — pulls another file in alongside it. It organizes the file; it saves no context.
- 02A rule — a Markdown file in .claude/rules/ — loads unconditionally, unless you give it paths: frontmatter. A rule with paths: loads only when Claude touches a matching file with its file tools.
| Instruction file | Loads |
|---|---|
| CLAUDE.md at the project root; a rule without paths: | When the session starts |
| A file named in an @path import | With the file that imports it |
| A rule with paths: frontmatter | When Claude reads or edits a matching file |
| Auto memory — the notes Claude keeps for itself | The first 200 lines or 25KB of its index, at start |
An import’s path runs until the first space, so no period straight after it — @package.json. works, @package.json. does not. Rules patterns are relative to the project root and may use globs and braces, src/**/*.{ts,tsx} being the usual shape. The debugging stance is the part to keep: when an instruction is ignored, the first question is not "how do I word this stronger" but "did its file load at all" — and there is a hook that answers it. It is called InstructionsLoaded, and this lesson is the first place you meet hooks, two lessons before they take centre stage.
03The walkthrough
- 01Add an import to CLAUDE.md — a real document your team keeps, or the manifest: a line like "- npm scripts: @package.json". Commit it.
- 02Add a scoped rule for your tests, as .claude/rules/testing.md, with paths: matching where your tests live — test/**/*.js in the shape below — and one or two conventions in the body.
- 03Borrow the load log. Save this hook file somewhere outside your committed settings (a scratch path is fine) and start the session with it: claude --settings ./load-log.json. Each time an instruction file loads, the hook appends the reason and the path to a log.
- 04Run /context all and read the memory-files list: CLAUDE.md is there, the import is there. The scoped rule is not — nothing has touched a test file yet.
- 05Ask Claude to read a test file with its Read tool, by name: "Use your Read tool to read test/config.test.js, then tell me in one sentence what it checks." Naming the tool matters — Claude sometimes reads through a shell command instead, which does not trigger scoped rules.
- 06Read the log: session_start for CLAUDE.md, include for the import, and now path_glob_match for the rule. Three loads, three reasons, all visible.
04Your turn
A teammate’s rule never takes effect; find out why. Save a rule as .claude/rules/cli.md with a deliberately misspelled pattern — source/**/*.js when your code lives in src/ — and one convention in the body. Start a logged session, ask Claude to use its Read tool on src/cli.js, and read the log: no path_glob_match line, because no file matches the pattern. Fix the pattern, start a fresh logged session, repeat, and see the load appear. Then commit CLAUDE.md and .claude/rules/, and delete the log hook when you are done with it.
Two more tools for the same instinct. /doctor prompt-audit reads your instruction files and flags instructions written for older models, references to files or commands that no longer exist, and files that contradict each other — proposing edits and changing nothing until you ask. And an import that reaches outside your working directory, such as @~/notes.md, asks for approval once per project; if you decline it, it stays off.
Claude ignored an instruction. What do you check first?
- AReword it more strongly
- BRaise the effort level
- CWhether the file holding it loaded at all
→Check your answer
Diagnosis before blame: an InstructionsLoaded log or /context all tells you whether the file is even in the session. If it loaded, the wording — or a contradiction — is the suspect.
What does an @path import in CLAUDE.md save you?
- ANothing — it is organization only
- BContext: the file loads on demand
- CIt bypasses workspace trust
→Check your answer
The imported file loads alongside CLAUDE.md at start. Imports keep the root file short; scoped rules are the tool that actually defers loading.
A rule with paths: "test/**/*.js" loads when…
- AThe session starts, like any rule
- BClaude runs a shell command mentioning tests
- CClaude reads or edits a matching file with its file tools
→Check your answer
Scoped rules trigger on the file tools — which is why the exercise asks for the Read tool by name; a cat through the shell does not fire them.