Claude Code Plan Mode: A Practical Workflow from Plan to Implementation
Claude Code Plan Mode lets you inspect a repository and agree on an approach before authorising source edits. The useful part is the approval boundary: you can catch a bad assumption while it is still a sentence in a plan, rather than a change spread across several files. This tutorial takes a small Python repository from a recorded Git commit through planning, correction, implementation, diff review and interrupted-session recovery.
The workflow: record the baseline, start in plan mode, inspect the files, challenge assumptions, approve individual edits, check the diff against acceptance tests, then commit. It targets developers who want a repeatable process, not a collection of prompt tricks.
- Record a clean Git baseline and the exact Claude Code version.
- Request a file-specific plan without authorising edits.
- Correct the plan’s assumptions and agree measurable acceptance criteria.
- Choose manual edit approval, then inspect the working tree and run tests.
- Resume safely if the session ends halfway through.
Pin the CLI version before trusting the mode indicator
This walkthrough targets the interactive terminal CLI in Claude Code v2.1.314, released on 30 October 2026. It assumes a local Git checkout, Python 3, ordinary project permissions and no --dangerously-skip-permissions flag. Claude’s interface steps follow Anthropic’s current documentation; the Git fixture and test results below were verified separately. The suggested Claude prompts are a procedure to follow, not a fabricated agent transcript.
claude --version
claude --permission-mode plan
Starting with the flag removes ambiguity about the initial mode. In current interactive CLI versions, auto mode can be the default; Shift+Tab cycles between available modes, and some Windows terminals use Alt+M instead. Confirm the status bar says plan mode on before submitting the task. The /plan prefix can also plan a single prompt, but a dedicated planning session is easier to audit.
| Stage | Expected behaviour in this CLI workflow | Your check |
|---|---|---|
| Plan mode | Read files, explore with shell commands and prepare a plan. Ordinary source edits remain blocked until approval in a non-bypass session. | Check the mode indicator and compare the Git working tree with the baseline. |
| Approve manually | Leave plan mode and ask you to approve individual edits. | Read each requested file change before allowing it. |
| Approve with auto mode | Leave plan mode and let an automated classifier review eligible actions. | Review the finished diff yourself; approval is not a test result. |
Important limitation: plan mode is not a universal ban on command execution. With useAutoModeDuringPlan enabled, as it is by default where auto mode is available, a classifier can approve exploratory shell commands. Other configurations prompt for commands outside the built-in read-only set. Interactive sessions with bypass permissions available have different rules again. Shell commands may have side effects, so use a disposable checkout for unfamiliar work and do not enable bypass permissions for this exercise. Anthropic documents the version- and configuration-dependent rules in its Claude Code permission modes guide.
Reproduce a two-file repository at a recorded commit
Our example calculates basket totals in integer pence, with percentage discounts rounded using Decimal. The feature request is to add a fixed-amount coupon. It is deliberately small, but the order in which discounts are applied can change the result. That is the assumption we will force into the plan.
Recorded reference baseline: 224565cb863195aca4d7d6fe43c8c51264012a73. The reference patch was committed later as 586046250493ef506ecf3df3d4e753e4b286c448. These are real commits in the independently checked fixture. If you recreate the files and commit them yourself, your commit hashes will normally differ because Git records author and timestamp metadata.
Create a directory, initialise Git, and save the following two files. The example uses only Python’s standard library, so no dependency installation step is needed.
mkdir claude-plan-demo
cd claude-plan-demo
git init -b main
basket.py
from decimal import Decimal, ROUND_HALF_UP
def total_pence(unit_pence: int, quantity: int, percent_off: int = 0) -> int:
"""Return the order total in pence, rounded half up."""
if unit_pence < 0 or quantity < 0 or not 0 <= percent_off <= 100:
raise ValueError("Invalid basket values")
subtotal = Decimal(unit_pence * quantity)
discounted = subtotal * Decimal(100 - percent_off) / Decimal(100)
return int(discounted.quantize(Decimal("1"), rounding=ROUND_HALF_UP))
test_basket.py
import unittest
from basket import total_pence
class BasketTests(unittest.TestCase):
def test_order_total(self):
self.assertEqual(total_pence(250, 2), 500)
def test_percentage(self):
self.assertEqual(total_pence(100, 2, 10), 180)
def test_half_penny_rounds_up(self):
self.assertEqual(total_pence(5, 1, 10), 5)
def test_invalid_input(self):
with self.assertRaises(ValueError):
total_pence(-1, 1)
python -B -m unittest discover -v
git add basket.py test_basket.py
git commit -m "Baseline: percentage-only basket totals"
git rev-parse HEAD
git status --short
The reference baseline passed four tests and had a clean tracked working tree. The -B flag prevents Python bytecode files from being written during this exercise. If your git status --short shows unrelated work, do not continue in that checkout: you need to know which changes belong to Claude.
Ask for repository evidence, not a confident-looking plan
Launch Claude from the repository root with claude --permission-mode plan. Give it this task, leaving the discount policy open deliberately so it has to identify the missing decision:
Inspect basket.py and test_basket.py before proposing changes.
Add support for an optional fixed-amount coupon to total_pence.
Do not edit source files yet.
Your plan must state:
- The current function signature and the units it uses.
- Whether the coupon applies per unit or once per order.
- Where it sits relative to the percentage discount.
- The files you would change and the smallest tests needed.
- Any unanswered policy questions and your stop conditions.
Only use read-only inspection commands while planning.
Check that the plan names basket.py and test_basket.py, identifies the existing Decimal rounding rule, and admits that the coupon’s scope and ordering need a decision. A proposal to rewrite the pricing module, introduce a currency package or change the return type is outside this task.
Before considering approval, run git status --short in your own shell. A plan file or tool state may be stored separately from the repository; the check you care about is whether tracked source changed before you authorised it. A clean result is evidence for this run, not a guarantee about every Claude Code surface or custom integration.
Catch the assumption that makes the calculation wrong
A plausible but incorrect approach is to subtract the coupon from each item’s unit price. For two items at 100p each, a 150p coupon would then be applied twice or would require complicated per-item clamping. The required behaviour is simpler: subtract the coupon once from the order subtotal, clamp the result at zero, then apply the existing percentage discount and rounding.
If Claude’s plan proposes per-item subtraction, assumes the amount is in pounds, or leaves the sequence unspecified, choose No, keep planning and respond:
Revise the plan. coupon_pence is a non-negative integer in pence.
Apply it once to the whole order subtotal, before percent_off.
Clamp the discounted subtotal at zero, then preserve the
existing Decimal ROUND_HALF_UP behaviour.
Keep old positional calls working. Reject a negative coupon.
Change only basket.py and test_basket.py. No edits yet.
This is where planning earns its cost. You have settled behaviour that tests can prove. Do not accept a lengthy plan just because it lists many sensible steps. A recurring failure in agent-assisted development is approving a document nobody has checked closely. For this task, one clear calculation rule, a two-file scope and four acceptance conditions are enough.
Approve implementation without surrendering the review
Once the revised plan reflects those rules, choose Yes, manually approve edits. In v2.1.314, the alternative Yes, and use auto mode changes the post-approval permission policy; it is not equivalent to reviewing each edit. You can open the proposed plan in your text editor with Ctrl+G before committing to it.
The reference implementation changes the signature to add coupon_pence: int = 0, rejects negative coupons in the existing validation condition, and replaces the subtotal calculation with this expression:
subtotal = Decimal(max(0, unit_pence * quantity - coupon_pence))
Applying the coupon before percent_off preserves the original rounding method. Adding the optional parameter at the end preserves calls that pass one, two or three positional arguments. Neither a new dependency nor a second pricing function is needed. Approve only edits consistent with that shape; if the agent finds another genuine requirement, return to plan mode and renegotiate scope instead of accepting a surprise refactor.
Audit the diff against calculations, not the agent’s summary
After implementation, use /diff inside Claude Code or the following commands in a separate terminal. The Git commands are authoritative for the working tree, including edits that may not appear in an agent’s per-turn change view.
git status --short
git diff --check
git diff -- basket.py test_basket.py
python -B -m unittest discover -v
| Acceptance check | Expected outcome |
|---|---|
| Existing percentage call | total_pence(100, 2, 10) returns 180 |
| Coupon before percentage | total_pence(100, 2, 10, coupon_pence=150) returns 45 |
| Coupon exceeds subtotal | total_pence(100, 1, coupon_pence=150) returns 0 |
| Negative coupon | coupon_pence=-1 raises ValueError |
| Rounding regression | total_pence(5, 1, 10) still returns 5 |
| Change scope | Only basket.py and test_basket.py have intended changes |
The independently applied reference patch passed seven tests, including three new coupon cases, and passed git diff --check. These are fixture results, not a claim that an unattended Claude run will produce the same patch. If your diff is broader, the task has not met acceptance criteria even if tests pass. Inspect untracked files as well as modified ones; generated artefacts and unexpected dependencies can hide outside a simple two-file diff.
Only then commit the result. Keep the implementation commit separate from the baseline so the change remains reviewable. The larger discipline of small diffs and regression checks is covered in our Claude Code best practices guide.
See more of our reporting in Google Top Stories, AI Overviews and AI Mode.
Recover when approval or implementation is interrupted
Use this failure drill: imagine the terminal disconnects just after you approve the plan, before you receive the test report. You cannot infer from the last message whether the implementation started, finished or stopped midway. Don’t press approve again and hope the agent figures out what happened.
git status --short
git diff --check
git diff -- basket.py test_basket.py
python -B -m unittest discover -v
claude -c --permission-mode plan
The first four commands establish the state independently of conversation memory. The final command resumes the most recent session for that directory in plan mode, if it remains available. Ask Claude: “Inspect the existing diff and tests. State which accepted steps are complete, which are missing and whether any change was outside the approved files. Do not edit until I approve the recovery plan.”
If the working tree is unchanged, you can reconsider the approved plan. If one file changed but the regression tests are missing, ask for the missing work rather than repeating the whole feature. If the patch is wrong, save anything worth keeping before reverting selected files with Git. Claude’s /rewind can help with tracked agent edits, but it does not reliably restore every shell-created or subagent-created change. Git remains the dependable recovery record.
Use plan mode where the risk justifies another review step
Plan mode pays for itself when a mistake would alter money calculations, authentication, migrations or several coupled files. For a tiny, obvious fix with an existing failing test, starting in manual approval mode and reviewing one diff may be faster. Long planning conversations also consume usage allowance or API tokens, especially if the agent repeatedly rereads the repository; our Claude Code pricing guide explains the billing choices.
For work spanning several sessions, keep the accepted assumptions, file list and test commands in a short, version-controlled handoff note. That is more portable than relying on a long chat history. A separate reviewer can then challenge the implementation, whether your team uses Claude Code alone or a second coding agent. Our Claude Code vs OpenAI Codex comparison looks at those broader workflow differences.
Final check: do not leave planning until you can name the files, the rejected assumption and the tests that decide success. After approval, trust the actual diff and the command results, not the agent’s declaration that the job is done.


