The plan-gated workflow
Get a plan before any code, edit it yourself, and commit it on its own. Then build one small slice at a time. You catch a wrong idea on one page of text instead of in sixty files.
Lesson 2: someone adds a CLAUDE.local.md to the repo root. What happens to your AGENTS.md?
By default Claude Code reads AGENTS.md only when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in the folder or above. One stray file switches your rules off.
Lesson 3: the agent has handed you a 1-3-1. What should it do next?
The format ends with "then wait for the human's decision". Acting on the recommendation early is the silent decision again, with better manners. This lesson applies the same idea to whole features.
- The first thing you ask for is a plan, not code. You edit it and commit it alone.
- Then one slice per commit: each slice passes its tests and your review before it is committed.
- A requirement that changes halfway goes into the plan first, in its own commit, then gets built.
What happened
Failed run
A developer's whole instruction was "Please build the whole project for me". There was no plan to read, so there was nothing to correct early.
The result was one 60-file commit whose message said it added tests. Elsewhere, a plan file arrived in the same commit as the whole API, every box ticked, so nothing proved it came first.
Real sessions, anonymised
With the harness
A written workflow: plan first, the human edits it, it is committed alone, then one slice per commit.
One developer worked this way: no code until they had read the plan, two proposals struck as scope creep, and a locking claim proved with a 20-way race test.
The gate is the human reading a page before the agent writes a line.
One prompt, or a gated line
A slice is one behaviour, with the test that proves it, small enough to read as a single diff. A gate is a point where work stops until something passes or a human says yes. Compare the two histories:
The workflow, as a file
Lesson 2 left docs/ai/workflow.md as a stub. Filled in, every session reads the same loop instead of you retyping it. The reference version:
1. **Explore**: read the relevant code and docs. Do not edit yet (plan mode, if your tool has one). 2. **Plan**: write or update `ai-session/PLAN.md`: slices, each with its test and the files it touches. The human edits and approves it. The plan is committed on its own before any code. 3. **One slice**: implement only the next unchecked slice in the plan. 4. **Quality gate**: run the `quality-gate` skill. Fix failures; if a fix would touch an invariant, use 1-3-1. 5. **Review**: dispatch `test-reviewer` on the diff, plus `stock-invariant-reviewer` if stock or orders changed. 6. **Commit**: tick the slice in `PLAN.md`, then run the `commit` skill. It drafts the message and waits for approval. Never push. 7. Go back to step 3 for the next slice. ## When requirements change mid-task Stop the current slice. Update `PLAN.md` (add, change or remove slices, with the reason), get the human's approval, and commit the plan change on its own. Then continue. ## When stuck Use 1-3-1 (see AGENTS.md). Do not poll or retry blindly: after one failed retry, hand over.
Steps 4 to 6 name a skill and reviewer agents you build in lessons 5 and 6. Write them as manual steps for now: 4. Run dotnet test. 5. The human reviews the diff. 6. The human approves the commit message, then commits.
Plan mode keeps the agent's hands off
Plan mode is a permission mode where Claude reads, explores and writes a plan, but cannot edit your source until you approve that plan. When auto mode is available, a classifier (a second model) may approve the shell commands it runs to explore; otherwise anything beyond read-only commands asks you. Enter it with Shift+Tab until the status bar shows ⏸ plan mode on, with claude --permission-mode plan, or with a /plan prefix on one prompt (Permission modes) verified 2026-10-01.
The catch is at the end. When the plan is ready, Claude asks how to proceed, and approving exits plan mode and starts editing:
| Option in the dialog | What happens next | Use it here? |
|---|---|---|
| Yes, and use auto mode (or "Yes, auto-accept edits") | Claude starts building, and edits run without asking you | No: nothing stops it writing code before you have edited the plan |
| Yes, manually approve edits | Claude starts, but every edit asks you first | Yes: accept the edit to ai-session/PLAN.md, refuse anything else |
| No, keep planning | Stays in plan mode; you say what to change | Yes, while the plan is still wrong |
Press Ctrl+G in that dialog to open the plan in your editor and change it before choosing. Press Shift+Tab to leave plan mode without approving anything.
Going deeper: why a file, when plan mode already makes a plan?
Plan mode is a tool state. Claude Code does keep its plan across compaction (Context window), but the plan isn't in your repo. ai-session/PLAN.md is a contract: it is in git, you edit it in your own editor, tomorrow's session or a different tool can read it, and its commit is timestamped before the code it governs.
| Claude Code | Codex | Antigravity | |
|---|---|---|---|
| Plan without edits | Plan mode or a /plan prefix | Ask for a plan with sandbox_mode set to read-only | /plan makes an Implementation Plan |
| Durable plan | ai-session/PLAN.md, committed alone, works the same in every tool | ||
Sources: Codex approvals and security · Antigravity: Plan verified 2026-10-01
Edit the plan like a reviewer
The agent's draft will look reasonable. Read it with a red pen anyway: a plan you approved unchanged is usually one you didn't read closely.
Also check: a slice that touches stock says it keeps the guarded UPDATE and the concurrency test green, and every slice lists the files it touches.
When the requirement changes
A colleague writes: "Low-stock must also accept an optional skuPrefix filter." Don't fold it quietly into the slice in progress. Stop, update the plan with the reason, approve it, commit that change alone, then build it as its own slice. The history shows the change was decided before it was built.
Scope bait is different: a request for something the brief rules out, such as authentication. A brief change gets a plan change; an out-of-scope request gets a polite no that cites the rule.
Check yourself
When should the approved plan file be committed?
A plan that shares a commit with code can't prove it came first. Committed alone, the history shows it was decided before the work began.
Halfway through a slice, a colleague asks for a new filter that fits the brief. What comes first?
A brief change is a plan change: add the slice with its test and the reason, approve it, commit it alone, then build it. Declining is for things the brief excludes, like auth.
Claude has presented its plan. You want it to write only ai-session/PLAN.md, and nothing without your say. What do you pick?
Approving always exits plan mode and starts editing. "Yes, manually approve edits" makes each edit ask you, so you accept the plan file and refuse the rest.
Practice first
Quick drills with instant feedback on reading a plan and keeping the gates, before you touch the repo.
The agent's draft of ai-session/PLAN.md for the low-stock endpoint. Click the lines your red pen should catch.
- ## Goal: list products with Stock <= threshold (default 5)
- - [x] list products at or below the threshold (+ test: stock 5 listed)
- - [ ] 400 when threshold is outside 0–1000 (+ test: 1001 returns 400)
- - [ ] order by stock then SKU, response DTO and docs; tests at the end
- - [ ] cache low-stock results in memory for speed
- Files: ProductsController.cs, tests/StockApi.Tests/
- ## Decisions made by the human: (lesson 3 entries, kept)
- Approved by: ____________
What would you do?
Mid-slice, the agent says it would be easier to also refactor OrderService "while it is in there". The plan doesn't mention it. What do you say?
Work outside the approved plan goes into the plan first, with a reason, approved and committed on its own. Then it is built as its own slice.
Slice one passes dotnet test. The agent offers to commit it together with slice two once that is done, "to save time". What do you do?
One slice per commit, each passing its tests and your review. Small commits are what you can review, revert or bisect on their own.
A teammate's history shows PLAN.md arriving in the same commit as the whole API, every box ticked. A reviewer asks whether the plan came first. What is true?
A plan that shares a commit with code can't prove it came first. Committed alone, before the code, its timestamp is the evidence.
Exercise: plan, gate, one slice, then a change
The feature: GET /api/products/low-stock?threshold= returns products whose stock is at or below the threshold. Work in your practice repo from lessons 1–3. Windows: use WSL2 or Git Bash (setup).
- Fill in the workflow. Ask the agent to fill in
docs/ai/workflow.mdfrom the loop above, with steps 4 to 6 manual, plus the "When requirements change" and "When stuck" sections. The retry limit in "When stuck" is what would have stopped the 35-minute Docker polling from lesson 3. Read every line, then commit it alone:git add docs/ai/workflow.md git commit -m "docs(ai): workflow"
- Plan mode. Start a fresh session and press Shift+Tab until you see
⏸ plan mode on. Prompt:Read ProductsController, the tests and docs/ai/ first. Plan GET /api/products/low-stock?threshold=: products with Stock <= threshold, ordered by stock then SKU, default threshold 5, 400 for an out-of-range threshold (propose the range). Plan in slices, each with its test and the files it touches. After approval, your only step is to write this plan into ai-session/PLAN.md with the sections Approved by, Goal, Slices (checkboxes), Decisions made by the human (keep what is there) and Changes to this plan. Then stop. No code.
- Approve with your hands on the wheel. When the plan appears, choose Yes, manually approve edits. Accept the edit to
ai-session/PLAN.md; answer no to any other file. Thengit statusshould list only that file. - Red pen. Open
ai-session/PLAN.mdin your editor and make at least one real change: split a slice, add a missing test, fix the range (for example 0 to 1000, with a test that 1001 returns 400), or strike something the brief doesn't ask for. Note what you changed and why. Fill inApproved by. - Commit the plan alone.
git add ai-session/PLAN.md git commit -m "docs(plan): low-stock endpoint" git show --stat HEAD
The stat lists one file. - Scope bait. Say: "While you're at it, add an API-key check so only staff can call this." Expect a refusal that cites your out-of-scope rule (
AGENTS.mdordocs/ai/invariants.md). If it complies, refuse the edits and strengthen that line inAGENTS.md. - One slice. Prompt "Implement only the first unchecked slice in ai-session/PLAN.md, with its test. Stop when it is done." Run
dotnet testyourself and readgit diff. Tick the slice, then stage the slice's files by name (git statusshows new files too) plus the plan:git add src/StockApi/Controllers/ProductsController.cs git add tests/StockApi.Tests/<your test file> ai-session/PLAN.md git commit -m "feat(products): low-stock endpoint"
If your plan has more low-stock slices, build each the same way. - The change. Paste this in as if a colleague had sent it: "Low-stock must also accept an optional skuPrefix filter." The right response is to update the plan, not code: refuse any code edit. Check the new slice has a test and a line under "Changes to this plan" with the reason. Approve it, then commit it alone:
git add ai-session/PLAN.md git commit -m "docs(plan): add skuPrefix filter"
- The new slice. Implement only that slice, run
dotnet test, read the diff, tick it, stage its files plusai-session/PLAN.mdby name, and commitfeat(products): skuPrefix filter. - Run
git log --oneline. Each plan commit sits directly before the code it governs.
Codex: plan with sandbox_mode set to read-only and "plan only, no edits", then switch back for the slices. Antigravity: use /plan, then copy the approved plan into ai-session/PLAN.md. The commits are the same.
-
git show --statondocs(plan): low-stock endpointlists onlyai-session/PLAN.md, and it comes before the firstfeat(products)commit -
Approved byis filled in, and you can name one thing you changed in the agent's draft -
docs(plan): add skuPrefix filtercomes before the skuPrefix feature commit -
dotnet testis green and every slice is ticked inPLAN.md
- superpowers: A popular open-source set of skills for brainstorming, writing plans and executing them slice by slice. Also installs in Codex and Antigravity (see its README).
- feature-dev: Anthropic's /feature-dev: explore, clarify, design, implement, review, as one guided flow.
Each link has its own install steps. Install only what you will use, check how recent it is, and read what a plugin adds before you enable it. Links checked 2026-10-01.
Making the same red-pen notes on every plan? Put them in a short plan-review checklist or skill the agent runs before it shows you a plan.
Best practices: explore first, then plan, then code, then Review and approve a plan for the approval options.
"Read my ai-session/PLAN.md as a sceptical reviewer. Which slices are too big, which have no test, and which invariant does it never mention? Don't edit it."