Spec-Driven Dev
Coding Agents·Module 1 · The Brief·L1·55 minBrief

CLAUDE.md: The Standing Brief

Write the CLAUDE.md the agent reads every session: five sections, imports for what every task needs, a line for every mistake the agent breaks, and nothing the code already shows.

Before this: L0 How a coding agent works

What you'll learn
  • Explain what a CLAUDE.md is, when the agent reads it, and the three places it can live (project, user, local).
  • Write the five sections a good brief has: what the project is, how to run and test it, conventions, boundaries, and where to look.
  • Use imports to keep the brief short and point at longer docs.
  • Apply the rule-the-agent-breaks test to decide what earns a line in the brief.
  • Recognize brief bloat and prune it.

Why this matters

Omar's first CLAUDE.md for Shelf is 900 lines long. He pasted in the whole README, the style guide, and an architecture document from 2023. He felt thorough. Then he asked Quill to build CR-110, the low-stock badge. Quill ran npm test instead of make test, so the lint never ran. It put the new test in src/inventory/__tests__/, where nobody would find it. And every session now started with a third of the context window already spent on a document Quill mostly ignored. Jun opened the file, deleted 850 lines, and added four. The next session used make test, put the test in tests/inventory/, and had room to think. This lesson is about those four lines and the 850 that had to go.

1. What a standing brief is

A standing brief is the set of instructions an agent reads at the start of every session, before it reads a single line of your code. In Claude Code, the standing brief is a file named CLAUDE.md. Quill reads it when a session starts, and its contents sit in the context for the whole session. It is the only thing Quill knows about Shelf before it starts opening files.

Recall from L0 that the agent has no memory of yesterday. Every session begins from nothing, and whatever you told it last week is gone. The standing brief is how you stop repeating yourself. Think of it as the note a lead engineer leaves for a contractor on their first morning: not the whole codebase, not the history of every decision, but the handful of things a smart stranger would get wrong without being told.

2. Where it lives

Claude Code reads memory files from three places. Each has a different owner and a different job.

FileWho it is forCommitted to git?Holds
CLAUDE.md in the repo rootEveryone on the teamYesProject memory: what Shelf is, how to test it, conventions, boundaries
~/.claude/CLAUDE.mdYou, on every projectNo, it lives in your home folderUser memory: your own working preferences
CLAUDE.local.md in the repo rootYou, on this projectNo, ignored by gitLocal memory: your personal notes about this repository

Project memory is the file this lesson is about. It is shared, reviewed, and committed like code. When Jun changes it, the whole team's sessions change.

User memory lives in your home folder and applies to every repository you open. It holds preferences that are about you, not about any one project.

Local memory is for things that are true for you on this project and for nobody else: the path to a database on your laptop, a reminder about a branch you are nursing.

There is one more place. A CLAUDE.md in a subfolder is read when the agent works in that folder. Shelf could keep src/giftcards/CLAUDE.md with the money rules, so those lines cost context only when Quill is in gift-card code.

3. The five sections

A good project brief has five sections. Each answers a question the agent would otherwise guess at.

  1. What it is. Two sentences. What the app does and who uses it.
  2. How to run and test. Exact commands. This is the command reference: the strings the agent should type, not descriptions of them.
  3. Conventions. The rules a linter cannot enforce. A convention is a way of doing things the team agreed on: where files go, how errors are handled, where a constant lives.
  4. Boundaries. What the agent must never touch, and what it must ask about first. A boundary is a rule about what the agent may not do on its own.
  5. Where to look. The key folders, and the docs that explain them.

Here is Shelf's brief after Jun's edit, in full.

# Shelf

Shelf is Bramble Books' web app: inventory, online orders, gift cards, and
customer email for three stores. TypeScript, Vitest, one Makefile.

## Run and test
- `npm run dev` starts the app.
- `make test` runs build, tests, and lint. Run it before you say a task is done.
- `npm run typecheck` and `npm run lint` run alone when you need them.

## Conventions
- Tests live in `tests/<area>/`, next to nothing else. Never in `__tests__`.
- Thresholds and limits live in `src/<area>/config.ts`, not in components.
- Stock is counted per store, never as one total.
- @docs/testing.md

## Boundaries
- Never edit files under `migrations/`. Ask Jun for a migration.
- Never write to `tests/` while fixing a bug; tell Omar what the test should say.
- Ask before touching `src/email/`. Priya owns it. Read `docs/email.md` first.
- Ask before adding a dependency.

## Where to look
- `src/orders/`, `src/giftcards/`, `src/inventory/`, `src/email/`: one folder per area.
- `docs/email.md`: the sending rules and the consent filter.
- `docs/review-checklist.md`: what Jun checks in every PR.

Twenty-six lines on disk, about fifty in Quill's context once the testing guide is imported. Each line gives an exact command, names a rule the code cannot show, or tells Quill where to fetch more.

4. Imports and pointers

A brief should be short, but some of what it relies on is long. Two tools keep the brief small: imports and pointers.

An import is a line of the form @docs/testing.md. Claude Code replaces that line with the contents of the file when it reads the brief. The file becomes part of the standing brief, loaded every session.

A pointer is a plain sentence: "Read docs/email.md before touching src/email/." Nothing is loaded up front. The agent fetches the file when a task makes it relevant.

The choice comes down to one question: is this needed in every session, or only in some?

Import (@file)Pointer (a sentence)
LoadedEvery sessionWhen the agent decides it needs it
Context costAlways paidPaid only when used
Use forRules that apply to every taskRules that apply to one area
Shelf exampledocs/testing.mddocs/email.md

5. The rule the agent breaks

How do you decide what earns a line? Use one test: every line in the brief names a mistake the agent made, or would make, without it. Call it the rule-the-agent-breaks test. If you cannot say which mistake a line prevents, the line is decoration.

The test does two things. It keeps the brief short, because most facts about a project do not correspond to a mistake. And it makes every line defensible, because the reason travels with it.

Run the Shelf brief through the test:

  • "make test runs build, tests, and lint." Mistake prevented: Quill ran npm test and skipped lint.
  • "Tests live in tests/<area>/." Mistake prevented: three tests landed in __tests__ folders.
  • "Stock is counted per store." Mistake prevented: Quill summed stock across stores in an early CR-110 attempt, and the badge lit up for the wrong titles.
  • "Never edit migrations/." Mistake prevented: a migration without a rollback, written during CR-101, that Jun had to unpick by hand.

6. Brief bloat

Brief bloat is what happens when the brief grows past what the agent can use. Omar's 900-line file is the extreme case, but bloat starts small: a paragraph here, a pasted doc there.

Bloat costs twice. First, context. Every line of the brief occupies the window on every turn of every session, so a long brief leaves less room for code and conversation, and long sessions drift sooner (L0, section 3). Second, attention. The four rules that matter are buried among 896 that do not. An agent reading "use two-space indentation" for the fortieth time is not more likely to notice "never touch migrations/".

Pruning has three cuts:

  1. Delete anything the code shows. The folder layout, the language, the framework, the dependency list. Quill reads code faster than it reads prose about code.
  2. Delete anything a tool enforces. Formatting rules the formatter fixes. Type rules the compiler checks. Lint rules the linter catches. If the tool will complain, the brief does not need to.
  3. Delete anything only true today. "The cr-110 branch is in progress." "Priya is out this week." Those belong in CLAUDE.local.md or a task brief, and they expire.

7. Keeping it alive

A brief is not written once. It changes when the team learns something, and the place the team learns things is the review. L5 teaches the rule: every finding in a review of an agent's diff becomes a test, a hook, or a line in the brief.

  • A test when the finding is about behavior: the badge showed the wrong count.
  • A hook when the finding is about an action that must be enforced: Quill edited a test during a bug fix. L4 covers hooks.
  • A brief line when the finding is about a habit: Quill keeps naming test files .spec.ts instead of .test.ts.

The brief line is the cheapest of the three and the weakest. It is advice, not enforcement. If the agent keeps breaking a rule after the line is in place, promote the rule to a hook.

The brief also shrinks. When a convention becomes a lint rule, delete the line. When a folder is removed, delete the pointer. Each time the brief is edited, ask the same question of every line: which mistake does this still prevent?

Summary

  • The standing brief, CLAUDE.md, is read at the start of every session and is the only thing the agent knows about your project before it reads code.
  • It lives in three places: the project file (committed, shared), the user file in ~/.claude/ (your preferences everywhere), and CLAUDE.local.md (personal, ignored by git); a subfolder CLAUDE.md adds area-specific rules.
  • Five sections: what it is, how to run and test, conventions, boundaries, where to look. Exact commands, rules no tool enforces, and a named person for every "ask first".
  • Import (@docs/testing.md) what every task needs; point at what only some tasks need. Every line must pass the rule-the-agent-breaks test or be deleted.
  • Bloat costs context and attention; prune what the code shows, what a tool enforces, and what is only true today. The brief grows when a review finds a repeated habit and shrinks when a rule moves into a tool.

Key terms in this lesson

Check your understanding

Pick an answer to see why it is right or wrong. These are graded in code, instantly.

1.When does Quill read the project CLAUDE.md, and what does that make it?
2.Omar wants to note that his dev database lives at ~/shelf-dev.sqlite. Which file should hold that line?
3.Which of these lines belongs in the Boundaries section of Shelf's brief?
4.docs/testing.md is 25 lines and applies to every task. docs/email.md is 140 lines and applies only to email work. How should the brief handle each?
5.What does the rule-the-agent-breaks test say about a line in CLAUDE.md?
6.Omar's 900-line brief hurt CR-110 in two ways. What were they?

Apply it

Write your answer in your own words. Eve grades it against a rubric and gives you feedback, the same way an LLM judge works in Lesson 5.

Short answerGraded by Eve · 4 criteriaup to ~150 words

Name two lines you would add to a CLAUDE.md for a project you know, and the mistake each prevents.

0 words
Free responseGraded by Eve · 5 criteria

Jun's four-line rewrite kept: the test command, the test folder rule, the email boundary, and the low-stock threshold source. Explain why each earned its place under the rule-the-agent-breaks test, and name one thing from the 900-line version that did not.

0 words

Homework 1 - Write the CLAUDE.md for Shelf

Write a complete CLAUDE.md for Shelf, Bramble Books' web app, in under 60 lines.

Shelf is a TypeScript app with src/orders/, src/giftcards/, src/inventory/, src/email/, tests/ (Vitest), migrations/, a Makefile with make test (build, tests, lint), and npm run dev, npm run lint, npm run typecheck, npm test. Gift cards hold money, so Priya's payment rules apply. Customer email holds personal data, so Priya's privacy rules apply. Jun reviews every PR. Quill runs on Claude Code.

Your brief must have:

  1. The five sections: what it is, how to run and test, conventions, boundaries, where to look.
  2. Exact commands in the run-and-test section, not descriptions of commands.
  3. At least one import of the form @docs/<file>.md, and a sentence saying why that file is imported rather than pointed at.
  4. At least two boundaries: one that starts with "never" and one that starts with "ask before". The ask-first boundary names the person to ask.
  5. A short note under each section (a comment line or an indented sentence) saying which mistake the lines in that section prevent. Use the rule-the-agent-breaks test: if you cannot name the mistake, cut the line.

Do not include anything the code already shows (the folder layout beyond the where-to-look pointers, the language, the framework) or anything a tool already enforces (formatting, types, lint rules).

Paste the file below as a single markdown code block, followed by a two-sentence note on what you left out and why.

Homework submissionGraded by Eve · 7 criteria

Paste your homework write-up below. Include every deliverable.

0 words
Instructor notes(for whoever is teaching this lesson)

Talking points

  • Omar's 900-line brief is the thread. Open with the two visible failures (npm test instead of make test, tests in __tests__) and ask what the brief should have said. Both answers are one line each.
  • The brief is read at the start of every session and is the only thing the agent knows before it opens code.
  • Three files, three owners: project (committed, shared), user (~/.claude/CLAUDE.md, follows the person everywhere), local (CLAUDE.local.md, ignored by git). Headline the mistake of a personal path in the shared file.
  • Five sections. Commands are exact strings. Conventions are rules no tool enforces. Boundaries come in two strengths, never and ask first, and ask first needs a name.
  • Import what every task needs, point at what only some tasks need.
  • The rule-the-agent-breaks test is the lesson in one sentence: a line earns its place by naming the mistake it prevents. Bloat costs context and attention. Three cuts: code shows it, a tool enforces it, only true today.

Live demo idea

Bring a real repository with no CLAUDE.md. Run /init and read the draft aloud. Go line by line and ask the room which mistake each line prevents. Delete every line that gets silence; a 60-line draft usually comes down to 15. Then add two lines the draft could not know: the real test command and one boundary with a named person. Commit that. If time allows, ask the agent for a small change and watch whether it uses the command you named.

Common misconceptions

  • "A longer brief is a safer brief." Each added line dilutes the ones already there and costs context on every turn.
  • "The brief is read once and remembered." It is read every session because nothing is remembered between sessions.
  • "Importing a doc is free." An imported file is in context on every turn. Pointers are free until used.
  • "A line in the brief is a rule." It is advice. If the agent keeps breaking it, the line was right and needs a hook (L4).
  • "The style guide belongs in the brief." The formatter and linter enforce it, so it is the first cut.

Timing

Fifty-five minutes: story and section 1, seven; where it lives, six; the five sections with the Shelf brief on screen, ten; imports and pointers, six; the rule the agent breaks, nine; brief bloat and Jun's edit, nine; keeping it alive, five; homework briefing, three.

If you only have 20 minutes

Show the Shelf brief in full and name the mistake behind each line (seven minutes). Run the /init demo with the delete-on-silence rule (eight minutes). Close with the three pruning cuts and assign sections 2, 4, and 7 as reading before the homework (five minutes).