The Gist of Claude Code
Learning objectives
By the end of this chapter, you will be able to:
- Describe the role of the project directory as the unit Claude Code reasons about: where you launch it from determines what memory it discovers.
- Explain what `/init` does, what goes into the generated `CLAUDE.md`, and when to re-run it.
- Name the four scope levels for `CLAUDE.md` (managed / user / project / local) and the order in which Claude concatenates them into context.
- Use the permission prompt deliberately: pick between Yes / Yes-don't-ask-again-this-session / No, and explain what each does to your permission rules.
- Add an MCP server with `claude mcp add` and pick the right `--scope` (local / project / user) for the situation.
- Use plan mode (Shift+Tab) to drive a spec-driven design pass — research and plan in plan mode, implement against the resulting spec file.
Before we start — Claude Code, MCP, plan mode, and spec-driven design in plain language
If you already know what Claude Code is, what MCP servers do, what plan mode is, and what a "spec" means in this context, skim this and move on. If any of those terms are new, read it first — every section below assumes them.
Claude Code is Claude wrapped in a terminal-resident agent that works on a project on your machine. You launch it from a project directory (claude in the terminal, or via an IDE integration), and Claude reads your files, writes files, runs shell commands, and asks you when it's about to do something risky. It's the same Claude you might chat with in a browser — but with a working directory, a permission system, and a memory it carries between sessions.
A CLAUDE.md is a plain markdown file Claude reads at the start of every session. You write it once, Claude reads it every time. It's how you encode the things you would otherwise have to re-explain in every conversation — your build commands, your conventions, your "always do X" rules.
MCP stands for Model Context Protocol. It's an open standard for connecting an agent (like Claude Code) to external tools — a browser automation framework, a database, an issue tracker, a monitoring dashboard. Think of MCP servers as plug-ins for the agent. You add one with a command, the agent gains a new capability, and you never have to copy-paste data from another tool into the chat again.
Plan mode is a Claude Code mode you toggle with Shift+Tab. In plan mode, Claude can read files and run read-only shell commands to research, but it cannot edit your source files. You stay in plan mode while you and Claude figure out what to do; you leave plan mode when you're ready to actually do it.
Spec-driven design is the pattern of writing a small specification file before writing code, then asking Claude to implement against that spec. The spec acts as a stable, high-signal piece of context — short enough to fit in a prompt, structured enough that Claude can follow it across many turns.
Why this chapter matters
Chapter 1 was theory — why context engineering matters and what the four strategies are. This chapter is the practical setup pass. By the end, you'll have done the four things you do at the start of every Claude Code project: drop a CLAUDE.md in, decide what to allow and what to gate, plug in the MCP tools you actually need, and write the spec that anchors the build. Every later chapter assumes you can do these without thinking.
Lesson
1. Land in the project — the working directory matters more than you think
Claude Code is launched from a directory. That directory — and the directories above it, walking up the tree — is what Claude considers "the project." Anthropic's docs put it plainly: "Claude Code reads CLAUDE.md files by walking up the directory tree from your current working directory, checking each directory along the way for CLAUDE.md and CLAUDE.local.md files." All files found along the way are concatenated into the session's context, root-first.
The book builds a small Next.js app called HookHub as its running example. You don't need to follow that stack — the lessons apply to any project, in any language, of any size. What matters is that there's a directory, and that you launch Claude Code inside it.
A few practical consequences of "walk up only":
- The walk never visits siblings. Launching in
~/code/hookhub/will not load aCLAUDE.mdfrom~/code/other-project/. - The walk does visit ancestors. Launching from a subdirectory like
~/code/hookhub/src/still finds the project-rootCLAUDE.mdin~/code/hookhub/— you don't have to be at the root to pick up its rules. - Launching from a directory above your real project (in
~/code/instead of~/code/hookhub/) is the bigger risk. Claude treats~/code/as the project, misses any~/code/hookhub/CLAUDE.md, and picks up anyCLAUDE.mdyou happen to have in~/code/or higher — which is usually not what you want. - Anything in subdirectories under your launch point is loaded on demand — only when Claude reads a file in that subdirectory. So putting a
CLAUDE.mddeep insidesrc/components/is fine; it'll load the moment Claude touches that area.
When in doubt, run /memory inside Claude Code. It lists every memory file currently loaded for this session — the fastest way to confirm Claude is reading what you think it's reading.
Analogy — checking in at the front desk Walking into a hotel through the staff entrance versus the main lobby gets you two completely different welcome packets. Same hotel, same room — but the front desk only knows what to hand you if you check in at the right counter. Where you launch Claude Code is your check-in counter.
2. /init and your first CLAUDE.md
The first command to run in a new project is /init. Claude scans the codebase — tech stack, directory layout, build/test commands, conventions it can infer — and generates a starter CLAUDE.md at the project root. You review it, approve the write (Claude asks before every file write — see §3), and commit it.
What /init puts in the file:
- Project goal and short description
- Tech stack and major frameworks
- Build, run, and test commands it discovered
- Directory layout
- A handful of conventions it noticed
That's the floor. You then add to it as the project teaches you what Claude needs to know. Anthropic's docs frame this neatly: "Treat CLAUDE.md as the place you write down what you'd otherwise re-explain." Specifically — add to it when:
- Claude makes the same mistake twice in a row.
- A code review catches something Claude should have known.
- You type the same correction into chat that you typed last session.
- A new teammate would need the same context to be productive.
Keep it under ~200 lines. Longer files consume more context and reduce adherence — Anthropic's own guidance. If your CLAUDE.md is growing past that, that's a signal to split it into path-scoped rules (see §5).
Four scopes for CLAUDE.md. The book introduces project-level CLAUDE.md. In practice there's a hierarchy of locations Claude reads, from broadest to most specific. Claude concatenates them all into the session — instructions accumulate, they don't override each other in a strict precedence order:
You'll mostly live at level 3. Level 4 (CLAUDE.local.md) is the right home for personal preferences that shouldn't be checked into source control — your sandbox URLs, your favorite test data. Level 2 carries across every project on your machine. Level 1 is for IT/DevOps to deliver instructions that apply to everyone in the organization — and per the official docs, a managed-policy CLAUDE.md "cannot be excluded by individual settings".
Memory ≠ settings.CLAUDE.mdfiles are instructions — context Claude reads. They accumulate: every loaded file ends up in the same context together. If two of them give Claude conflicting advice, the result isn't predictable, so don't rely on overriding a managed instruction by adding a contrary one at project or local level. If you need an enforceable rule — "Claude must never rungit push --force," "Claude cannot read.env" — that lives in.claude/settings.jsonas a permission rule, not inCLAUDE.md. Settings have a real precedence chain: managed > command-line > local > project > user, with managed always winning. §3 covers permissions next.
Analogy — house rules on the fridge /init writes the "house rules" sign and tapes it to the front door. Every visitor — that is, every Claude Code session — reads it before doing anything else. The four scope levels are like notes at four altitudes: building rules (managed), your own habits (user), this household's rules (project), and post-it notes you leave for yourself that other people don't need to see (local). They all get read together; if two notes contradict each other, the visitor has to guess. Real rules — the ones that must be obeyed — get a different mechanism (permissions in §3).
3. The permission system — every risky action runs through a gate
Claude Code is built around the assumption that you should be in the loop for anything that changes your machine. The first time Claude wants to write a file, edit a file, run a shell command, or call an MCP tool, you get a prompt:
Do you want to make this edit to CLAUDE.md?
1. Yes
2. Yes, and don't ask again this session (shift+tab)
3. No, and tell Claude what to do differently (esc)
Three options, each doing exactly one thing:
- Yes — approve this single action. The next time Claude tries the same thing, it asks again.
- Yes, and don't ask again this session — approve this and add an allow rule that lasts until you exit the session (for bash commands, the rule persists across sessions for that project + command combination).
- No, and tell Claude what to do differently — block it and explain why. The "tell Claude what to do differently" part matters: a curt "no" with no reason leaves Claude guessing.
The book frames this as practicing safe agentic coding, and it's exactly right: a fully autonomous Claude with no gate will, eventually, do something you didn't want. The gate is the safety net.
Underneath the prompt is a richer rule system. Anthropic's docs list three rule types — allow (no approval needed), ask (always prompt), deny (block outright) — that you can encode in .claude/settings.json. Rules are evaluated in a fixed order: deny → ask → allow, first match wins. So a deny rule from any settings layer beats an allow rule from any other layer. That's the property that makes managed-policy denies actually enforceable.
The rule syntax is path-aware and command-aware:
{
"permissions": {
"allow": ["Bash(npm run *)", "Bash(git commit *)", "Read(./src/**)"],
"deny": ["Bash(git push *)", "Read(.env)"]
}
}
You don't need to write these by hand at the start. Every time you pick "Yes, don't ask again," Claude Code records a rule for you. Over the first few sessions on a project, the file grows naturally.
Permission modes. Claude Code also has session-level modes that change the default behavior of the gate — default (prompt on first use), acceptEdits (auto-approve file edits in your working directory), and the one you'll meet again in §6, plan (read-only — Claude can read files and run read-only commands, but cannot edit). Modes are a thicker discussion that the book picks up properly in Chapter 3.
Analogy — a hotel keycard at the front desk A guest with a basic keycard can open their room. To open the spa, they ask the front desk; the desk decides whether to grant a temporary upgrade. Picking "Yes, don't ask again this session" is the desk saying "go ahead, your card now opens the spa for the rest of your stay." Picking "No, and tell me what to do differently" is the guest saying "don't bother — and here's why."
4. Extending Claude Code with MCP — Playwright as the worked example
Out of the box, Claude Code has a useful but bounded set of tools: read files, edit files, run shell commands, search the web. The moment you want it to drive a browser, query your database, file a Jira ticket, or scrape a Figma board, you need MCP.
MCP — Model Context Protocol — is an open standard for AI-tool integrations. Each MCP server is a small program (local or remote) that exposes a set of capabilities. You wire it into Claude Code with one command, and Claude can now call those capabilities the same way it calls its built-in tools.
The book's worked example is Playwright MCP — a browser-automation server. Useful for asking Claude to "open this page, click the button, screenshot the result, tell me if it broke." The setup is one line — using the current official CLI syntax:
claude mcp add --scope user playwright -- npx @playwright/mcp@latest
Four things to notice in that command:
| Piece | What it does |
|---|---|
--scope user | The scope: install this server for every Claude Code session you start on this machine. Short form -s user works too. |
playwright | The name Claude Code will use to refer to this server. |
-- | The separator. Required for stdio (local) servers — anything after -- is passed to the server process untouched, so Claude doesn't try to parse the server's own flags as its own. |
npx @playwright/mcp@latest | How to run the server — fetch and execute it via npx. |
Three MCP scopes. Per Anthropic's docs, your scope choice is one of three:
| Scope | Loads in | Shared with team | Stored in |
|---|---|---|---|
local (default) | Current project only | No | ~/.claude.json (under that project's entry) |
project | Current project only | Yes — via version control | .mcp.json at the project root |
user | Every project on your machine | No | ~/.claude.json |
Rule of thumb:
- Personal tools you use everywhere (Playwright for browsing, a personal note-taking server) →
--scope user. - Team tools the whole project depends on (a shared database server, an internal API server) →
--scope project. Commit.mcp.jsonto git. Teammates approve the server the first time they run Claude Code in the repo. - Experimental or credentialed servers that aren't ready to share → leave it at the default
local.
Verify the connection with /mcp. Inside a Claude Code session, type /mcp. You'll see every connected server, its status, and the tool count it exposes. If a server says "pending approval," it's a project-scoped server from .mcp.json waiting for you to confirm.
Permissions still apply. MCP tools go through the same permission gate (§3). The first time Claude tries to drive Playwright to cnn.com, you'll get a prompt asking whether to allow it. That's by design — an external tool is more worth gating than a built-in tool, not less.
Trust the server you're adding. Anthropic's docs are blunt about this: "Verify you trust each server before connecting it. Servers that fetch external content can expose you to prompt injection risk." An MCP server that fetches arbitrary web pages can return content that tries to redirect Claude's behavior. Treat MCP install like installing any other dependency: check the source, check the maintainer, check whether you actually need it.
Analogy — adding USB devices to a laptop The laptop has built-in keyboard, screen, speakers — useful, but limited. Plug in a USB scanner and suddenly the laptop can scan documents. Plug in a USB microscope and it can see at 1000×. MCP servers are the USB devices for Claude Code. You add the ones you need; you don't add the ones you don't trust.
5. Memory beyond a single CLAUDE.md — auto-loaded vs reference files
The auto-generated CLAUDE.md at the project root is what Claude reads automatically every session. But the book shows two patterns that need files Claude doesn't read automatically — and that distinction is the core of this section.
Pattern 1 — frontend persona. The book imports a Cursor-style rule ("You are a senior frontend developer specialized in React, Next.js, TypeScript…") into a file at memory/frontend/CLAUDE.md. It then asks Claude "what are you expert in?" and Claude answers with a generic "AI assistant specialized in software engineering." The persona didn't load.
That's not a bug. That file isn't in any of the four auto-load scopes from §2 — it's inside an arbitrary memory/ directory that Claude has no reason to read on startup. The book's word for this style is reference memory: a file you maintain for Claude, but that Claude reads only when something explicitly points at it.
Pattern 2 — the spec file. The book also writes a project spec to memory/spec/CLAUDE.md. Same situation: not auto-loaded, and that's intentional. The spec is a heavyweight document. You don't want it in every prompt; you want it in the implementation prompt, and not before.
So how do you bring those files into context when you need them? Two mechanisms:
@ imports inside an auto-loaded CLAUDE.md. Anthropic's docs document this directly: you can write @path/to/file.md anywhere in a CLAUDE.md and Claude expands the import at session start. Imports can chain up to four hops deep. So you can keep the root CLAUDE.md short and pull in topic files on demand:
# Project Context
This is the HookHub Next.js project.
## Stack
@memory/frontend/CLAUDE.md
## Spec
@memory/spec/CLAUDE.md
Inline @ references in a prompt. Inside a Claude Code session, typing @memory/spec/CLAUDE.md write the main page from the spec injects that file's content directly into the prompt. No tool call, no search — just paste-into-context.
.claude/rules/ for path-scoped rules. Anthropic's docs introduce a third mechanism: .claude/rules/*.md files that you can scope with YAML frontmatter to specific path globs. The file loads automatically — but only when Claude is touching matching files:
---
paths:
- "src/api/**/*.ts"
---
# API rules
- All endpoints validate input.
- All responses use the standard error envelope.
That keeps your frontend persona out of context when you're editing backend code, and out of context when you're not editing code at all. It's the same idea as the memory/frontend/ trick, with first-class tooling.
The book ends up with this final layout:
hookhub/
├── memory/
│ ├── frontend/CLAUDE.md ← reference; loaded only when you point at it
│ └── spec/CLAUDE.md ← reference; loaded only when you point at it
├── CLAUDE.md ← auto-loaded every session
└── ...
Once you understand the auto-load vs reference distinction, that layout reads naturally. The root CLAUDE.md is the always-on context. The memory/ directory is the reference library Claude pulls from on demand.
Analogy — a project binder with auto-load tabs and reference tabs Picture a project binder. Some tabs are dog-eared and the binder falls open to them — those are the rules everyone reads at the start of every meeting. Other tabs are tucked further back; you flip to them only when the meeting topic calls for them. The rootCLAUDE.mdis dog-eared. Thememory/files are the reference tabs in the back.
6. Plan mode and spec-driven design
The chapter's most important pattern is don't vibe-code an MVP — write a spec first, then implement against it. The two tools that make this practical are plan mode and the spec file pattern from §5.
Plan mode (Shift+Tab or /plan). Plan mode is one of the permission modes from §3. In plan mode, Claude is restricted to read-only tools: it can read files, run read-only shell commands (ls, grep, cat, git status), and search the web. It cannot edit your source files. The goal is to give Claude room to research and think before it acts. You enter plan mode by pressing Shift+Tab to cycle modes, or by prefixing a single prompt with /plan.
When you ask Claude in plan mode to "help me write a spec for HookHub, a place to display Claude hooks," it will:
- Search for what's out there (the book's example: it web-searches for "Claude hooks" and fetches Anthropic's docs).
- Read whatever files in your project look relevant.
- Synthesize a draft spec covering project overview, MVP scope, data model, UI/UX, technical architecture, user stories, future considerations.
- Present the plan to you for approval before writing anything.
When the plan is ready, Claude shows it and asks how to proceed. Two ways out of plan mode: press Shift+Tab again to leave without approving (you stay in conversation, no files written), or approve the plan — approval automatically exits plan mode and switches the session to the permission mode you pick at the approval prompt (review each edit, accept edits, etc.). To plan again later, cycle back with Shift+Tab or prefix a prompt with /plan.
Why a spec is good context engineering. Recall Chapter 1's framing: context engineering is finding the smallest possible set of high-signal tokens. A good spec is exactly that — a few hundred words that capture the goal, the data model, and the constraints, written once, referenced many times. Every implementation prompt that points at the spec inherits that signal for free.
The book's spec lives at memory/spec/CLAUDE.md — a reference file (per §5), not an auto-load file, because you don't want the whole spec in context for every small task. You bring it in only when you're implementing against it:
@memory/spec/CLAUDE.md please implement the main page grid as specified in the spec file
Pick the right model for each phase. The book makes one model-routing recommendation worth keeping: use the heavier reasoning model (Opus, at the time of writing) for the planning pass, and the faster model (Sonnet) for the implementation pass. Switch with /model. The planning pass benefits from depth and creativity; the implementation pass benefits from speed and consistency, with the spec doing the heavy lifting on direction.
Watch the context window during the build. As Chapter 1 taught you, every prompt and tool result fills the window. By the time you've gone plan → approve → implement → debug → tweak, the conversation is long. The book's suggested pattern is to /exit the session and restart for the implementation pass — a hard reset. You can also use /clear or /compact (Chapter 1, §4.3 of the lesson) for lighter resets.
One useful guarantee: Anthropic's docs note that project-root CLAUDE.md survives compaction — after /compact, Claude re-reads it from disk and re-injects it. So your project rules don't disappear when you compact. Anything you stuffed into the conversation (rather than into CLAUDE.md) is fair game to get summarized away — which is one more reason to write durable rules into CLAUDE.md rather than retyping them every session.
Analogy — blueprint before concrete Plan mode is the architect's pass: walk the site, sketch the blueprint, get the client to sign off. The spec file is the blueprint. The implementation pass is the contractor reading the blueprint and pouring concrete. You don't want the contractor inventing the building as they pour. You also don't want the architect on site with a jackhammer. Two phases, two modes, one stable artifact bridging them.
The whole chapter in one image — onboarding a new contractor
Analogy — pedagogical summary, drawing on all six sections.
Bringing Claude Code into a project is like the first day with a new contractor on site.
You meet them at the front gate, not in the parking lot down the street — that's launching from the right directory (§1). You hand them a one-page rulebook with the things you'd otherwise have to repeat all week: where the materials live, what you do and don't do on this site, who to call about what. That's CLAUDE.md, generated by /init (§2).
You walk them through the lockboxes. Some doors are open. Some doors have a code they get once and remember. Some doors require a call to you every time. That's the permission gate — allow / ask / deny, with Yes / Yes-session / No on the prompt (§3).
If they need a tool you don't have, they bring it: a laser level, a moisture meter, a specific saw. You confirm it's safe, you let it on site. Those are MCP servers — claude mcp add, with a scope decision for whether the tool is just for this site, every site you own, or every contractor on the crew (§4).
You hand them the binder. Pinned at the front are the rules — they read those every morning. In the back are the reference materials — the load calcs, the supplier specs — that they flip to only when the work calls for them. That's the difference between auto-loaded CLAUDE.md and reference files in memory/ (§5).
And before they pour any concrete, you walk the blueprint together and sign off. That's plan mode and the spec (§6). Once you sign off, they switch from architect mode to builder mode. The blueprint stays on the wall the whole time.
That's Chapter 2. Every later chapter assumes the contractor is already on site and knows the drill.
Activity — Audit a project you already work in
10 minutes, individual work.
Pick a small project you already work on — or one you're about to start. Spend ten minutes thinking through:
- Where would you launch Claude Code from? Write down the absolute path. Is it the right one — would Claude pick up the right
CLAUDE.mdfiles from there? - What four to six rules would go in the project
CLAUDE.md? Use the "what would you re-explain every session" heuristic. Constraints. Build/test commands. Naming conventions. "Always do X." Resist the urge to write more than ten. - Which
--scopewould each MCP server you actually use need? Pick two MCP servers (real or hypothetical — Playwright, a database server, a Slack server, a Figma server). Decide local vs project vs user for each. Justify in one sentence. - **What would belong in
CLAUDE.mdvsmemory/*vs.claude/rules/?** Sort your rules from (2). Anything that always matters → rootCLAUDE.md. Anything that only matters for a specific folder →.claude/rules/with apaths:glob. Anything heavy or reference-style → amemory/file you import with@.
Capture your answers in a short note — you'll use them in the practical exercise below if you want a shortcut, and again in Chapter 3.
Practical exercise — Drive the Chapter 2 setup in Claude Code
~30–45 minutes. Hands-on follow-up to the lesson. Prerequisites: Claude Code installed and authenticated, a terminal, and a text editor. You'll work in a throwaway scratch folder — nothing in this exercise touches the training repo or any real project of yours. If you also have Node.js installed, you can do the optional Playwright step at the end; if not, skip it.
You've read the theory. Now run the four Chapter 2 setup moves — /init, permission prompt, MCP install, spec-driven design — on a tiny sandbox project.
Setup (3 min)
mkdir -p ~/ch2-exercise/src
cd ~/ch2-exercise
Create README.md:
# Linkroll
A tiny CLI that reads a list of URLs from `urls.txt` and prints them in a table with status codes.
Create urls.txt:
https://example.com
https://httpbin.org/status/200
https://httpbin.org/status/404
Create src/linkroll.py:
import sys
print("not implemented yet")
sys.exit(1)
Now start Claude Code in the project directory:
claude
You should see Claude Code's prompt. Leave it open — every step below either runs there or edits a file in your editor.
Step 1 — /init your first CLAUDE.md (5 min)
Goal: see what Claude infers about your project on its own.
1.1 In Claude Code, type:
/init
1.2 Watch what Claude does. It will list files, read README.md and src/linkroll.py, infer a stack (Python CLI), and propose a CLAUDE.md.
1.3 Approve the write when prompted (you'll get the permission prompt from §3 — pick "Yes" or "Yes, and don't ask again this session").
1.4 Open CLAUDE.md in your editor.
Expected outcome:
CLAUDE.mdexists at~/ch2-exercise/CLAUDE.md.- It mentions Python, the CLI nature of the project, and the
urls.txtinput file. - It's under ~50 lines (a small project shouldn't generate a long file).
Reflection: read the file. Where did Claude guess (and could be wrong)? Edit the file to fix anything inaccurate.
Step 2 — Add a real rule to CLAUDE.md (5 min)
Goal: practice the "what would you re-explain every session" heuristic.
2.1 In your editor, add a rule to CLAUDE.md:
## Conventions
- The CLI must exit non-zero if any URL returns a 4xx or 5xx status.
- Use only the Python standard library. No third-party HTTP clients.
- Write a one-line entry to `CHANGELOG.md` for every behavioral change.
2.2 Back in Claude Code, ask:
Implement linkroll.py per the spec in README.md, following the conventions in CLAUDE.md. Then create CHANGELOG.md with the first entry.
2.3 You'll get one or more permission prompts as Claude edits files. Practice each option at least once across the session: pick "Yes" for one edit, "Yes, and don't ask again this session" for another, and "No" + a redirect for a third if you want to course-correct Claude mid-implementation.
Expected outcome:
src/linkroll.pyuses onlyurllib.request(or similar stdlib) — norequests, nohttpx.- A
CHANGELOG.mdexists with at least one dated entry. - Running
python src/linkroll.pyagainst yoururls.txtexits non-zero (because of the404).
Reflection: if you'd left out the "standard library only" rule, would Claude have reached for requests? Try a clean /clear and ask Claude to "rewrite linkroll.py" without that rule in CLAUDE.md to see the contrast. The rule is exactly the kind of thing you'd otherwise re-explain.
Step 3 — Plan mode and a spec file (10 min)
Goal: drive a spec-driven design pass end to end.
3.1 In Claude Code, press Shift+Tab until the status line shows you're in plan mode. (If your build doesn't surface a status line, type /help and look for plan mode in the listed commands.)
3.2 Ask:
I want to add an HTML report mode to linkroll. Write a short spec for it before we touch any code. Cover: CLI flag, output filename, what the HTML contains, what stays unchanged. Don't write any files yet — just propose the spec content.
3.3 Claude will respond with a draft spec — but won't write files (plan mode blocks edits). Review it. If it's wrong, refine: "actually, the flag should be --html not --report, and the file should go in out/ not the project root."
3.4 When you're happy with the draft, leave plan mode (press Shift+Tab again to leave without approving, or approve the plan — approval automatically exits plan mode and switches the session to whichever permission mode you pick at the approval prompt). Now ask Claude to write the spec to memory/spec/html-report.md. Approve the file write.
3.5 Open a fresh thought by typing /clear. Then implement against the spec:
@memory/spec/html-report.md implement the HTML report mode per this spec. Update CHANGELOG.md when done.
Expected outcome:
memory/spec/html-report.mdexists with the agreed spec.src/linkroll.pyhas the new--htmlflag.- An HTML report is produced when you run
python src/linkroll.py --html. CHANGELOG.mdhas a second entry.
Reflection: notice you used @memory/spec/html-report.md to pull the spec into the implementation prompt. Why didn't you just write the spec into CLAUDE.md directly? (Two reasons: it's big, and it's task-specific — see §5 on auto-load vs reference files.)
Step 4 (optional) — Add an MCP server (5 min)
Goal: see claude mcp add and /mcp work end to end. Skip this step if you don't have Node.js installed.
4.1 Quit Claude Code (/exit). Then in your shell:
claude mcp add --scope user playwright -- npx @playwright/mcp@latest
4.2 Verify the install:
claude mcp list
You should see playwright listed.
4.3 Restart Claude Code:
claude
4.4 Inside Claude Code:
/mcp
You should see playwright connected, with a tool count > 0.
4.5 Ask Claude to use it:
Open https://example.com and tell me the page title.
You'll get a permission prompt for the Playwright tool — approve it.
Expected outcome: Claude opens a browser via Playwright, reads the page, and reports the title (Example Domain).
Reflection: the install used --scope user, so Playwright is now available in every Claude Code session on this machine. If this had been a tool only your team needed, which scope would you have picked instead? (See §4.)
Step 5 — Reset and verify continuity (5 min)
Goal: confirm that CLAUDE.md survives a context reset.
5.1 In Claude Code, type /compact. Wait for the summary.
5.2 Ask:
What are the conventions in this project?
Expected: Claude lists the rules from CLAUDE.md — including the "stdlib only" and "CHANGELOG entry per change" ones. Project-root CLAUDE.md survives compaction.
5.3 Now type /clear. Ask the same question.
Expected: Claude still lists the rules. /clear resets the conversation; CLAUDE.md is re-read at the start of the next request.
5.4 Finally, type /exit, then start a fresh session with claude. Ask the same question one more time.
Expected: still works. CLAUDE.md is durable across all three reset levels — and that's exactly the property that makes "write down what you'd re-explain" worth doing.
Success checklist
- [ ]
~/ch2-exercise/CLAUDE.mdexists, generated by/init, then hand-edited with conventions. - [ ] You triggered the permission prompt at least three times and used all three options (Yes / Yes-session / No-with-redirect) at least once each.
- [ ]
memory/spec/html-report.mdexists, produced via plan mode then written after approval. - [ ]
src/linkroll.pyimplements both the original CLI and the--htmlmode, using only the standard library. - [ ]
CHANGELOG.mdhas at least two dated entries. - [ ] (optional)
claude mcp listshowsplaywright, and/mcpconfirms it's connected. - [ ] Asking "what are the conventions in this project?" after
/compact,/clear, and a fresh session all return the sameCLAUDE.mdrules.
Common pitfalls - Wrong working directory. IfCLAUDE.md"doesn't seem to load," check what directory you launchedclaudefrom. Run/memoryinside Claude Code — it lists every memory file currently loaded. - MCP server "pending approval". Project-scoped servers in.mcp.jsonwait for you to approve them the first time. Runclaudeinteractively and accept the prompt. - Plan mode keeps editing files. You probably left plan mode without noticing. Shift+Tab toggles; the status line shows the current mode. -@filenot pulling content. Make sure the path is relative to where you launched Claude Code, and there's a space between the filename and the rest of your prompt.
Knowledge check — try the quiz
Once you have read the lesson and finished the activity, take the chapter quiz from the navigation bar. Six questions: five from the book chapter, one synthesis question grounded in the Anthropic docs enrichment. You can retake the quiz until you are confident.
Further reading & enrichment sources
- Anthropic docs — "How Claude remembers your project" (
https://code.claude.com/docs/en/memory). Source for the four-scope ladder (managed / user / project / local), the load-order rules, the "what you'd otherwise re-explain" framing, the ~200-line guidance,@import syntax (4-hop max), and the.claude/rules/path-scoped pattern. Also confirms that project-rootCLAUDE.mdsurvives/compact. - Anthropic docs — "Connect Claude Code to tools via MCP" (
https://code.claude.com/docs/en/mcp). Source for theclaude mcp addsyntax variants (http / sse / stdio / websocket), the three MCP scopes (local / project / user) and where each is stored, and the prompt-injection warning on third-party servers. - Anthropic docs — "Configure permissions" (
https://code.claude.com/docs/en/permissions). Source for the deny → ask → allow evaluation order, the rule syntax (Bash(npm run *),Read(./.env),WebFetch(domain:...)), the six permission modes, and the rule that permissions are enforced by Claude Code (not the model), with sandboxing as the OS-level complement.
Knowledge check
6 questions. Passing score: 5.
Instructor notes & source coverage
Source Ledger — Chapter 2: The Gist of Claude Code
Primary source (the book)
- Source PDF:
source-pdfs/02-chapter-02.pdf - Extracted source:
extracted-chapters/02-chapter-02.txt(raw, form-feed page boundaries preserved) - Extraction tool:
pdftotext -layout -enc UTF-8(Poppler, shipped with Git for Windows) - OCR needed: No — extraction was clean text.
Enrichment sources
The lesson silently incorporates material from three official Anthropic documentation pages. Per project convention, no inline > Source: or > Enrichment — ... labels appear in the learner-facing lesson — the labels caused visual confusion in Chapter 1 and were dropped. This source ledger is the single source of provenance: every per-section mapping below tells you which paragraphs came from the book, which from Anthropic docs, and which were authored as pedagogical scaffolding for this training.
- [E1] Anthropic docs — How Claude remembers your project —
https://code.claude.com/docs/en/memory - [E2] Anthropic docs — Connect Claude Code to tools via MCP —
https://code.claude.com/docs/en/mcp - [E3] Anthropic docs — Configure permissions —
https://code.claude.com/docs/en/permissions - [E4] Anthropic docs — Choose a permission mode —
https://code.claude.com/docs/en/permission-modes(added on the post-launch audit pass — needed to accurately describe plan-mode entry/exit and the approval flow) - [E5] Anthropic docs — Settings —
https://code.claude.com/docs/en/settings(added on the post-launch audit pass — used in the §2 memory-vs-settings callout to cite the actual settings precedence chain) - [E6] Anthropic docs — Commands —
https://code.claude.com/docs/en/commands(added on the post-launch audit pass — used to confirm canonical slash-command names like/modelsingular and to confirm/exit-plan-modeis not a documented command)
The user explicitly asked for enrichment "only where needed — do not overcomplicate." Three sources is intentional: it's enough to cover the chapter's three load-bearing topics (memory, MCP, permissions) with depth the book doesn't have, without adding noise.
Pedagogical enrichment by the training author
The following additions are not from the book and not from Anthropic — they are pedagogical material written for this training. They are inventoried here so a reviewer can audit them separately. No inline labels are placed in the learner-facing lesson; only the > Analogy — ... callouts carry an in-lesson label.
- Newcomer preface (
## Before we start — Claude Code, MCP, plan mode, and spec-driven design in plain language). Defines Claude Code, CLAUDE.md, MCP, plan mode, and spec-driven design in plain English for readers new to agent engineering. - Per-section analogies. Seven
> Analogy — ...callouts: one per numbered lesson section (§1 hotel check-in, §2 house rules on the fridge, §3 hotel keycard, §4 USB devices, §5 binder tabs, §6 blueprint), plus one closing whole-chapter analogy. - Whole-chapter analogy (
## The whole chapter in one image — onboarding a new contractor). A sustained "new contractor on site" analogy that re-frames the chapter's six sections for less-technical readers. - Three SVG diagrams authored for this training (not reproduced from the book's figures, which we do not have rights to):
- Figure P.1 — "The four things Chapter 2 wires up around Claude Code" (preface): memory, MCP, plan mode, permission gate.
- Figure 2.A — "CLAUDE.md scope ladder" (§2): managed → user → project → local with load order arrow.
- Figure 2.B — "Every tool call passes through the gate" (§3): the deny → ask → allow evaluation flow.
- Each figure has a
figcaptionthat explicitly notes it is pedagogical and not from the book. - Practical exercise — "Drive the Chapter 2 setup in Claude Code." A ~30–45 minute hands-on walkthrough that takes the learner through
/init, hand-editingCLAUDE.mdwith conventions, exercising all three permission-prompt options, plan-mode-driven spec writing, implementation against the spec via@reference, optional MCP install withclaude mcp add ... -s user, and a continuity check across/compact//clear//exit. Built on a Linkroll sandbox project (a Python stdlib CLI) the learner creates locally. Deliberately swapped from the book's Next.js / HookHub stack to keep the prerequisite footprint small (Python is on most machines; Node is gated to an optional step). - Sandbox swap rationale. The book's HookHub project requires Node, npx, npm permissions, and a Next.js scaffolding pass before the learner reaches the Claude Code mechanics. The Chapter 2 exercise keeps the focus on the Claude Code mechanics by using a Python stdlib CLI instead — same lessons, fewer install steps. Learners who want the full HookHub experience can follow the book's setup directly; nothing in the training contradicts it.
Quiz items and learning objectives remain grounded in the book chapter and the labeled Anthropic enrichment sources — none of the pedagogical analogies, diagrams, or exercise steps are themselves assessed.
Objective → Source Mapping
| Learning Objective | Source Section | Confidence | Notes |
|---|---|---|---|
| Project directory as Claude's unit of context — launch location matters. | Book §"Initializing Claude code" (pp. ~5–6 of extracted text) + [E1] §"How CLAUDE.md files load" | High | Book introduces the idea via /init; [E1] formalizes the up-walk discovery rule. |
Explain /init and what it generates. | Book §"Initializing Claude code" (pp. ~5–7) | High | Book lists the exact contents Claude infers: project goal, business problem, run command, frameworks, folder structure. |
| Name the four CLAUDE.md scope levels and load order. | [E1] §"Choose where to put CLAUDE.md files" | High | Book introduces project-level only; the four-level ladder (managed/user/project/local) is enrichment. |
| Use the permission prompt deliberately — Yes / Yes-session / No semantics. | Book §"Contents of the CLAUDE.md file" → permission prompt block (p. ~7) | High | Three-option prompt is quoted verbatim from the source. |
claude mcp add with --scope choice. | Book §"Connecting Playwright MCP to Claude Code" (pp. ~9–10) + [E2] §"MCP installation scopes" | High | Book introduces -s user; [E2] adds the three-scope table and the storage locations. |
| Plan mode + spec-driven design workflow. | Book §"Using spec-driven design" + §"Implementing the main page using the SPEC" (pp. ~15–20) | High | The Shift+Tab toggle, the Opus-for-planning / Sonnet-for-implementation switch, and the @spec reference at implementation time are all from the book. |
| (enrichment) deny → ask → allow evaluation order. | [E3] §"Manage permissions" | High | Source of quiz Q6. |
(enrichment) Project-root CLAUDE.md survives /compact. | [E1] §"Instructions seem lost after /compact" | High | Mentioned in §6 as the reason CLAUDE.md rules persist through context resets. |
Lesson Section → Source Mapping
| Lesson section | Source location | Confidence |
|---|---|---|
| §1 — launching from the right directory | Book "Initializing Claude code" framing + [E1] up-walk discovery rule | High — corrected on review. The walk goes up only; siblings are never visited; launching from a subdirectory still finds the project-root CLAUDE.md. The real risks (launching too high, missing project, inheriting unintended parent rules) are sourced from [E1] §"How CLAUDE.md files load". /memory is documented as the inspect command. |
§2 — /init and what it produces (contents listed) | Book §"Contents of the CLAUDE.md file" (p. ~7) — quoted directly | High |
| §2 — when to add to CLAUDE.md (the four triggers) | [E1] §"When to add to CLAUDE.md" | High |
| §2 — under-200-lines guidance | [E1] §"Write effective instructions → Size" | High |
| §2 — four-scope ladder (accumulates, doesn't override) | [E1] §"Choose where to put CLAUDE.md files" — table reproduced (with project marked as /init target). Lesson explicitly notes that CLAUDE.md files accumulate (concatenated into context together), and that managed-policy CLAUDE.md "cannot be excluded by individual settings" per [E1] §"Manage CLAUDE.md for large teams". | High |
| §2 — memory ≠ settings callout (instructions accumulate; permissions enforce) | Memory accumulation behavior from [E1]; settings precedence (managed > command-line > local > project > user) from Anthropic docs §Settings; permission deny → ask → allow from [E3] | High — corrected on review. Previous lesson incorrectly implied a project CLAUDE.md could "override" a managed policy. |
| §3 — three-option permission prompt | Book p. ~7 — quoted verbatim | High |
| §3 — practicing safe agentic coding rationale | Book p. ~8 — quoted nearly verbatim | High |
| §3 — three rule types (allow/ask/deny) and evaluation order | [E3] §"Manage permissions" | High |
§3 — rule syntax (Bash(npm run *), Read(.env), etc.) | [E3] §"Permission rule syntax" | High |
| §3 — permission modes (default / acceptEdits / plan / auto / dontAsk / bypassPermissions) | [E3] §"Permission modes" | High |
| §4 — what MCP is, in one line | [E2] header — quoted | High |
| §4 — MCP install command syntax | [E2] §"Option 3: Add a local stdio server" — current syntax claude mcp add --scope user playwright -- npx @playwright/mcp@latest. The -- separator is required for stdio servers per [E2] ("the -- (double dash) separates Claude's own options … from the command and arguments that run the server"). Book p. ~10 shows the older -s user form; lesson explicitly notes the short form still works. | High |
| §4 — three MCP scopes (local / project / user) and storage locations | [E2] §"MCP installation scopes" — table reproduced | High |
§4 — /mcp verifies connections | Book p. ~10 + [E2] §"Managing your servers" | High |
| §4 — "verify you trust each server before connecting" | [E2] front-matter warning — quoted | High |
§5 — memory/frontend/CLAUDE.md not auto-loaded | Book §"Creating a frontend memory context" (pp. ~13–14) — note from the source quoted | High |
§5 — @ import syntax (4-hop max, paths relative to importing file) | [E1] §"Import additional files" | High |
§5 — .claude/rules/ with paths: glob frontmatter | [E1] §"Organize rules with .claude/rules/" + §"Path-specific rules" | High |
§5 — final book layout memory/{frontend,spec}/CLAUDE.md | Book p. ~20 — reproduced verbatim | High |
§6 — plan mode (entry Shift+Tab or /plan, read-only tools only) | Book §"Using spec-driven design" (p. ~16) + [E4] §"Analyze before you edit with plan mode" — verbatim entry instructions | High |
| §6 — leaving plan mode (Shift+Tab again, or approve plan → exits to chosen permission mode) | [E4] verbatim: "Press Shift+Tab again to leave plan mode without approving a plan" / "Approving a plan exits plan mode and switches the session to the permission mode each approve option describes." [E6] confirms /exit-plan-mode is not in the canonical command list. | High — corrected on review. Previous lesson referenced /exit-plan-mode. |
§6 — Opus for planning, Sonnet for implementation, /model to switch | Book p. ~17 — Opus/Sonnet routing. Command name corrected to /model (singular) per [E6] canonical commands table. | High — corrected on review. Previous lesson used /models (plural). |
§6 — spec at memory/spec/CLAUDE.md, referenced with @ at implementation time | Book pp. ~18–20 — verbatim | High |
§6 — /exit + restart pattern for a hard reset | Book pp. ~19–20 — verbatim | High |
§6 — project-root CLAUDE.md survives /compact | [E1] §"Instructions seem lost after /compact" | High |
Quiz Items → Source Mapping
| Quiz ID | Item | Source | Confidence |
|---|---|---|---|
| q1 | /init is the first command; produces project goal, tech stack, build/run commands, structure | Book p. ~7 | High |
| q2 | Three-option permission prompt is the practical embodiment of safe agentic coding | Book pp. ~7–8 | High |
| q3 | --scope user flag scopes MCP install to every project on this machine, just you (short form -s user also works) | [E2] scopes table + [E2] §"Option 3: Add a local stdio server" for the -- separator. Prompt updated on post-launch audit to use current official syntax. | High |
| q4 | Files in memory/ are not auto-loaded — must be referenced explicitly | Book p. ~14 — quoted note | High |
| q5 | Spec-driven workflow: plan mode + Opus → spec file → fresh session + @ reference + Sonnet | Book pp. ~16–20 | High |
| q6 | deny → ask → allow evaluation; user-level deny beats project-level allow | [E3] §"Manage permissions" + §"Settings precedence" — synthesis | High |
Figures Referenced In Source (not reproduced in training)
| Figure | Caption (paraphrased) | Status |
|---|---|---|
| 2.1 | project/hookhub branch | Referenced in source; not reproduced. |
| 2.2 | Default Next.js application running on localhost:3000 | Referenced; not reproduced. |
| 2.3 | Claude Code opened via Cursor Integration | Referenced; not reproduced. |
| 2.4 | "Booping" in Cursor Integration | Referenced; not reproduced. |
| 2.5 | Generated CLAUDE.md file with project overview and commands | Referenced; described in prose (§2 lists the contents). |
| 2.6 | Running Claude Code CLI in the terminal | Referenced; not reproduced. |
| 2.7 | Verifying MCP Server Connections in Claude Code | Referenced; described in prose (§4 mentions /mcp). |
| 2.8 | Playwright MCP Permission Prompt to Open a Browser | Referenced; described in prose (§3 covers prompt). |
| 2.9 | Browsing Cursor Directory for Next.js Rules | Referenced; not reproduced. |
| 2.10 | Generic Claude Response Without Loaded Project Context | Referenced; described in prose (§5 covers the "Claude answered generically" demo). |
| 2.11 | Claude's Proposed Plan for HookHub MVP Specification | Referenced; described in prose (§6 lists the plan's contents). |
| 2.12 | HookHub Product Specification in CLAUDE.md | Referenced; not reproduced. |
| 2.13 | Claude Implementation Summary After Code Generation | Referenced; not reproduced. |
| 2.14 | Basic Next.js application | Referenced; not reproduced. |
Unsupported Or Unclear Items
| Item | Issue | Action |
|---|---|---|
| Exact pages for book section headings | The PDF extraction does not preserve printed book page numbers — references in this ledger are PDF page positions in the extracted text. | Confidence ranges based on extracted-text page positions. Cross-check with the printed book if exact pagination is required. |
/security-review sub-agent mention in source | Book mentions a /security-review sub-agent appearing after restart; the source defers depth to Chapter 3. | Lesson §3 mentions modes briefly and defers permission-mode depth to Chapter 3 to match the book's own deferral. |
| Cursor Integration screenshots | Book uses Cursor as the IDE wrapper. Training is IDE-agnostic — terminal-only is sufficient for the lesson and the exercise. | Lesson never claims Cursor is required. |
Optional Enrichment
None added beyond the three labeled enrichment sources. The user's explicit guidance was to keep enrichment minimal and "only where needed."
Source PDF: source-pdfs/02-chapter-02.pdf
Extracted source: extracted-chapters/02-chapter-02.txt