Plan Mode: Build a Real Page
Twenty-five minutes from an empty folder to a sign-up page you can defend line by line.
run explore → plan → code → commit end to end, and change the plan before a single file is written
- Claude Code installed and logged in (Lab 01)
- git working in your terminal (Lab 00)
- Node 20+ installed (Lab 00)
- A terminal you can open twice
In the next twenty-five minutes you go from an empty folder to a working sign-up page. The most valuable thing you do will not be typing. It will be reading a plan — and changing one line of it before a single file exists.
Anthropic’s guide gives the order in four words: explore, plan, implement, commit — plan mode does the first two (best practices). The reason is arithmetic: one bad line of research becomes many bad lines of plan, and one bad line of plan becomes hundreds of bad lines of code. Hence HumanLayer’s rule — review the research and the plan, not only the diff (advanced context engineering).
A plan is short enough to read end to end. Its diff is long enough that you will skim it. Read the cheap one.
You are building the first real version of QAIRU Event Sign-up: one page, one event, a form that reserves a seat, a counter that runs down. One file, no framework, no build step.
Nine steps from an empty folder to a commit
Make the folder a repo before the agent touches it
mkdir qairu-event cd qairu-event git initExpected:
Initialized empty Git repositoryand a path ending inqairu-event/.git/. On Windows PowerShell chain the three with;, not&&—&&there printsThe token '&&' is not a valid statement separator.Do not skip
git init. Claude Code snapshots files before its own edit tools touch them, but checkpoints do not track changes made by Bash commands, most subagent edits, or files you change in another window (checkpointing). Checkpoints are local undo. Git is permanent undo.Start in plan mode, and prove you are in it
claude --permission-mode planThe first run in a new folder shows a workspace-trust dialog; accept it. Then read the status bar under the input box. It must say
plan mode on.Already in a session? Press
Shift+Tabuntil it does. The count varies: on Pro, Max and Team plans a terminal session now starts in auto mode, so the first press goes to Manual, then accept edits, then plan — three presses. A session that started in Manual needs two presses (which mode a session starts in). On some Windows setups the shortcut isAlt+M.Hand it the whole job in one prompt
Paste this exactly. Swap in your own event details, or leave them.
Build the QAIRU Event Sign-up landing page in this folder as one file: index.html. No frameworks, no build step, no new dependencies. All CSS and JS inside index.html. The page shows ONE event and lets a visitor reserve a seat: - event title, date, time, place, and two sentences about it - a reservation form: name, email, one Reserve button - a "seats left" counter that starts at 40 and drops by one per reservation - a list of people who have reserved, newest first - at 0 seats: the form is disabled and the page says the event is full - reservations survive a page reload - empty name, empty email, or an email with no "@" is rejected with a visible message Do not write any code yet. 1. Tell me what is already in this folder and what you plan to reuse. 2. Show me the plan: ordered steps, the file each step touches, and for each step the exact thing I should click in the browser and the exact thing I should see. 3. List what you will NOT do, and any assumption you need me to confirm. Stop and wait for my approval. When I approve, save the approved plan as PLAN.md before you change anything else.It reads the folder, runs a read-only command or two, and comes back with findings and a numbered plan. It will not create
index.html: in plan mode source edits are blocked until you approve (plan mode). While it works,Ctrl+Ttoggles its to-do checklist andCtrl+Oopens the transcript viewer.Read the plan like it is the only thing you will read today
Three questions.
- Does every step name a check I can run? “Implement the reservation form”, with no way to tell whether it worked, is a wish rather than a step. Giving the agent a check it can run itself is the habit that pays most in this course (best practices).
- Does it say what it will not touch? An agent with no stated boundary reorganises things you never asked about.
- Is there a step I could not explain to the person next to me? That is the one that hurts later.
Two bad answers means “No, keep planning”, with the reason:
Steps 3 and 5 have no browser check. Rewrite them with what I click and what I should see.Change one line before you approve
Press
Ctrl+G. The proposed plan opens in your text editor. Add this, save, close.- Every string a visitor can see exists in Kazakh and English. A KK / EN button in the header switches between them and remembers the choice. Kazakh is the default.That constraint is the one thing this project has that a generic sign-up form does not, and the agent will not invent it for you. The plan you approve is now partly yours — which is the difference between supervising a build and watching one.
Approve it the slow way
Claude offers three answers: use auto mode, approve edits manually, or keep planning. Where auto mode is unavailable the first reads “Yes, auto-accept edits”.
Pick “Yes, manually approve edits”. Read one diff end to end — the JavaScript that handles the form submit, because that is where the rules you wrote either exist or do not. Approve the rest at whatever speed you like. Simon Willison’s main anti-pattern for agent work is this same rule one size up: never open a pull request with code you have not reviewed yourself (anti-patterns).
Expected:
PLAN.mdwritten first, thenindex.html, and nothing else in the folder.Run it yourself
Leave Claude running. Open a second terminal in the same folder.
npx -y serveIt prints a local address such as
http://localhost:3000. Read the port off your own screen — the terminal always tells you which door it opened. Open it and try to break the page, in this order: reserve a seat (counter drops, name appears at the top), reload (the name is still there), submit an empty form (a visible message, not silence), press KK / EN (every visible string changes).Offline, or
npxhangs? Openindex.htmlstraight from your file manager — fine today, but get used tohttp://, because that is how the page runs once it leaves your laptop.Find the one thing that does not work, and say it precisely
There is always one. Never write “it’s broken”. Write symptom, location, definition of done.
Bug: [what you see]. Expected: [what should happen]. Where: index.html, [the function or block you suspect]. Fix it with the smallest change that works, then tell me the exact steps to check it in the browser. Do not touch anything else.Expected: a small diff and a list of test steps. If it starts rewriting half the file, press
Esc— it stops and keeps the work so far — then ask again, narrower.Commit before you like it too much
Type
!at the start of an empty line for shell mode, so the output lands in the conversation where Claude can see it.! git statusCommit everything in this folder. Write one descriptive message in the form type(scope): summary, saying what this page does. Then show me git log --oneline and git status.Expected: one commit, one line, something like
feat(signup): event landing page with seat counter, and a cleangit status. Anthropic’s harness work says it plainly: commit after every unit of progress with a descriptive message, so a later session — or you tomorrow — can return to a state that worked (harnesses for long-running agents).
Four ways this goes wrong, and the move for each
- It explores forever. Unscoped investigation reads hundreds of files and fills the window — the guide’s name for it is “infinite exploration”. Scope it to named files, or hand it to a subagent.
- You have corrected the same thing twice. Stop: the context is now mostly failed attempts.
/clearand write a better first prompt (best practices). - It says done and it is not. The guide calls this the trust-then-verify gap. Ask for evidence, not assertions — the command it ran and the output it got.
- It is quietly cheating. Kent Beck’s warning signs: it loops, it adds functionality nobody asked for, or it disables and deletes tests to get green (augmented coding).
Want the last ten minutes back? Esc Esc on an empty input opens the rewind menu: restore code, conversation, or both. It will not undo what a Bash command did. That is what your commit is for.
Go deeperWhen to skip the plan entirely
Plan mode is not free — exploration and the plan both spend context. The rule from the docs: if you could describe the resulting change in one sentence, skip the plan and ask. A typo, a log line, a rename. Planning pays when the approach is uncertain, the change spans files, or the code is unfamiliar (best practices).
Go deeperMaking plan mode the default for a project
For a repo where you always want a plan first, put {"permissions": {"defaultMode": "plan"}} in its .claude/settings.json; every session there starts in plan mode, and Shift+Tab still leaves without approving anything (permission modes).
Nine moves, three questions to ask any plan, and four failures with their fixes — the loop you run for every feature from here on.
git log --oneline shows your commit, the page opens in a browser, and you can point at the line in PLAN.md that you wrote yourself.