Claude Code · Intermediate/Lesson 02 of 08~5 min

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.

The Third Way engineering team||Verified against Claude Code v2.1.285 (stable), October 2026

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:

  1. 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.
  2. 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.
↳What loads, and when
Instruction fileLoads
CLAUDE.md at the project root; a rule without paths:When the session starts
A file named in an @path importWith the file that imports it
A rule with paths: frontmatterWhen Claude reads or edits a matching file
Auto memory — the notes Claude keeps for itselfThe first 200 lines or 25KB of its index, at start
The context cost of instructions is a design decision now, not an accident of file length.

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

  1. 01Add an import to CLAUDE.md — a real document your team keeps, or the manifest: a line like "- npm scripts: @package.json". Commit it.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
↳The import, and the rule
CLAUDE.md:
## Commands
- npm scripts: @package.json
 
.claude/rules/testing.md:
---
paths:
- "test/**/*.js"
---
# Testing
- Use node:test and node:assert/strict.
- No other test libraries.
The import organizes; the rule waits until a test file is touched. The load log is an InstructionsLoaded hook appending .load_reason and .file_path to a file, run via claude --settings.

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.

↳Check yourself
Q1

Claude ignored an instruction. What do you check first?

  1. AReword it more strongly
  2. BRaise the effort level
  3. CWhether the file holding it loaded at all
→Check your answer
Answer: C

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.

Q2

What does an @path import in CLAUDE.md save you?

  1. ANothing — it is organization only
  2. BContext: the file loads on demand
  3. CIt bypasses workspace trust
→Check your answer
Answer: A

The imported file loads alongside CLAUDE.md at start. Imports keep the root file short; scoped rules are the tool that actually defers loading.

Q3

A rule with paths: "test/**/*.js" loads when…

  1. AThe session starts, like any rule
  2. BClaude runs a shell command mentioning tests
  3. CClaude reads or edits a matching file with its file tools
→Check your answer
Answer: C

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.

The Third Way engineering team
Delivery engineering
Work with us