Introduction
By the end of this course, one real, previously-annoying task in your own repo runs end to end using only the configuration you build across these 5 lessons — a CLAUDE.md, a hook, a subagent, and (if you go that far) a CI integration, working together. Today: the file everything else builds on top of.
Objective
What you're building
A CLAUDE.md for a repo you actually work in, verified to change Claude Code's behavior — not written once and forgotten, and not copy-pasted from someone else's project.
Signal vs. noise: what actually belongs in this file
A CLAUDE.md should tell Claude Code things it can't figure out by reading your code
The test for any line you're about to add: "would Claude Code figure this out anyway by reading package.json / looking at the test files / running the linter?" If yes, it's noise — it costs context budget and adds nothing. If no ("we use uv run pytest, not bare pytest, because of how our virtualenv is set up" or "never touch legacy/, it's frozen pending a migration"), it's exactly the kind of thing worth writing down, because it's a real constraint the code alone doesn't reveal.
# Project: [your repo name]
## Commands
- Test: `uv run pytest` (not bare `pytest` -- see .venv setup below)
- Lint: `uv run ruff check .`
- Dev server: `npm run dev` (runs on :5173, not the Vite default :5174)
## Conventions
- API routes go in `src/api/`, never `src/routes/` (legacy naming, being phased out)
- Never touch files in `legacy/` -- frozen pending Q3 migration, changes there are silently reverted by CI
## Gotchas
- `tests/fixtures/` is regenerated by a script, don't hand-edit
Notice every line here is something you'd only know from working in this specific repo -- not generic advice ("write clean code," "add tests") that applies to literally any project and therefore tells Claude Code nothing it doesn't already assume.
Prove it, don't assume it
"I wrote a CLAUDE.md" and "my CLAUDE.md actually works" are different claims
Ask Claude Code a question your CLAUDE.md's content is the ONLY way to answer correctly — "what test command should I use here?" in a fresh conversation, with no other hints. If it correctly says uv run pytest instead of guessing pytest or npm test, the file is doing real work. If it guesses wrong, the file either isn't being read (check the file location) or isn't specific enough to override the default assumption.
You write a CLAUDE.md with 40 lines describing your team's entire coding philosophy, style preferences, and history of past architectural decisions. Claude Code's behavior doesn't seem to change measurably. What's the most likely issue?
This is the same "signal vs. noise" distinction from earlier in this lesson: a long file full of generic best-practices philosophy doesn't change behavior because Claude Code already defaults to reasonable practices — what actually moves behavior is repo-specific facts (exact commands, real constraints, real gotchas) it has no way to infer from reading the code alone. Length isn't the lever; specificity is.
What you're building today
CLAUDE.md for your own real repo, containing only repo-specific commands/conventions/gotchas — verified with a real before/after test: ask a question in a fresh Claude Code session before adding the file (or with it temporarily renamed), then again after, and confirm the answer changed correctly.