Course · Claude Code · Planning
Make the agent research and propose before it builds
Plan mode is the Claude Code setting in which the agent reads your code and proposes a change but edits nothing until you approve. The other permission modes (default, accept-edits, auto, bypass) govern what the agent may do while it works. Plan mode governs when the work starts: the design arrives before the first edit, so you can argue with it while changing your mind still costs nothing.
This chapter is a task chapter. It takes one design-heavy change through the whole loop: enter plan mode, interrogate and correct the proposal, keep the plan on disk, and see how a build like this one runs in the cloud. Every page restates the facts it needs, so you can enter at any of them.
The task this chapter plans
Section titled “The task this chapter plans”The worked example is a small TypeScript payments service (Express, tests under tests/, run with npm test). The ticket: make POST /payments idempotent, so a client that retries a completed request can never be charged twice. An idempotency key is a client-supplied identifier for one logical request; a server that sees the same key twice should recognize the retry instead of charging again.
The service already has a helper for this, and the helper is where the defect lives. src/utils/idempotency.ts exports checkIdempotency, which records a key as seen at first check, before the payment has done any work. The function meant to record completion, markProcessed, exists in the same file and is never called. So a key becomes “used” the moment it is looked at. Whatever fails between the check and a finished payment, a declined charge downstream or a crash, finds the key already burned: the client’s legitimate retry is rejected as a "duplicate payment", and that rejection cannot tell the caller whether the original request succeeded.
Two more facts frame the design space. In src/index.ts, the route reads the Idempotency-Key header and hands it to processPayment(req.body, key), and nothing requires the header to exist. In src/payments/processor.ts, the dedup check runs only when a key was supplied, so a caller who omits the header is never deduplicated at all. The keys live in an in-memory map, so nothing survives a process restart.
And nothing is red. The suite passes six tests out of six; the duplicate-key test passes because the code does reject a second call with the same key. The defect is a set of questions no test asks. What happens with no key? What happens when a failed payment is retried? What survives a restart? When a key becomes “used” is the central design decision, and the code answers it by accident. There is no failing test to steer you. There is a decision to make, with more than one defensible answer.
When to plan, and when to just build
Section titled “When to plan, and when to just build”Plan mode has a cost, a research pass and a round of review before anything moves, so spend it where it pays. Small and obvious tasks, a rename, a one-file fix, a change you could describe in a single sentence, do not need it: let the agent build and review the diff after. Big, cross-cutting, or ambiguous tasks do: many files, more than one reasonable design, or wiring you do not yet understand well enough to correct mid-diff.
A usable test: if you would want a junior engineer on your team to write a short design note before starting this change, you want plan mode for it. The idempotency ticket passes that test three times over. It touches the route, the processor, and the helper, and every question in the previous section has more than one defensible answer.
The route this chapter takes
Section titled “The route this chapter takes”There is no public starter checkpoint to clone for this chapter. Follow along in a disposable copy of a service with the same shape, or read each page as a decision to practice on a change in your own repository. If you want to see the helper traced by an agent first, the clear-context lesson in Sessions & context does that as a read-only task; it is optional background, not a prerequisite.
The path has four moves:
- Enter plan mode: three ways in, and exactly what the mode allows while the agent researches your code
- Review the proposal and choose how it executes: correct the plan while corrections are still cheap, then approve it into the build mode the work deserves
- Save the plan to disk and resume it: so the agreed approach outlives the conversation that produced it
- Take the build to the cloud: Claude Code on the web, for a change you would rather run and review in a browser
By the end, the idempotency fix has a researched, corrected, approved plan on disk, and the implementation is deliberately yours to run, with npm test as the check. This chapter plans the fix; it does not claim to land it.
Start with entering plan mode.