●FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtask●LIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its own●MCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS●PLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callback●SONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15●IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October●FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtask●LIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its own●MCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS●PLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callback●SONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15●IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Running Claude Code Without Breakage — A Failure-First Production Workflow with Plan Mode, Hooks, Rewind, and Subagents
If Claude Code has ever landed a broken commit on your main branch, this guide shows how to combine Plan Mode, Hooks, Rewind, and Subagents into a single failure-first workflow that keeps your repository safe without slowing you down.
Have you ever hesitated to let Claude Code touch your real repository? I certainly did. For months, I kept it sandboxed in a subdirectory, never letting it run on the main branch — because a few early accidents had made me cautious.
The pattern was always similar. I let Claude run autonomously, came back, and found broken commits on the branch. Tests had failed silently, unrelated files had been rewritten, and the git history was hard to untangle. After an afternoon spent rolling back, you get careful.
The trap, though, is that "never use Claude Code on anything that matters" costs you most of the upside. What I needed was not a yes-or-no decision but a different mindset: design for failure. Expect misinterpretation, expect broken commits, expect divergence — and build the workflow so that none of it lands in a place you cannot recover from.
This article walks through the five mechanisms already built into Claude Code (Plan Mode, TodoWrite, Hooks, Subagents, and Rewind) and shows how to integrate them into a single production workflow rather than using them as occasional features. Each mechanism has its own in-depth guide on this site; here, the focus is on the glue — the order, the rules, and the guardrails that together stop the bleeding.
Why "Success-First" Workflows Always Break
AI-assisted coding tends to fail in three predictable ways.
The first is drift of intent. The user's prompt was fuzzy, Claude started implementing something plausible-sounding, and halfway through the session both sides are operating on subtly different assumptions. Humans catch this by asking follow-up questions; AI agents often plow ahead. The further the run, the harder it is to tell where the deviation began.
The second is invisible side effects. Tests were broken before the commit ran. A migration was applied and cannot be reversed. A dependency version was bumped without anyone noticing. These are things you will not see by reading the diff alone — they require running the tests or scanning the lockfile.
The third is compounding failure. One mistake is easy to notice and fix. Ten small drifts, each built on the last one, reach a state where reverting to "before" is no longer obvious. The cost of rollback grows exponentially with autonomous commits.
All three failure modes share a root cause: you assumed it would go right. You let the agent run assuming success, and you only engaged when something visibly broke. By then the repository had absorbed the damage.
The flip of that mindset is what this article is about. Design the workflow expecting failure. Treat every plan as potentially wrong, every generation as potentially incorrect, every commit as potentially broken. Keep the system in a state where you can always step back. When you do that, autonomy becomes safe because autonomy without consequences is cheap.
The Shape of a Failure-First Workflow
The routine I run across all four Dolice Labs sites is the same shape regardless of the task. It chains five Claude Code features in a fixed order.
Plan Mode establishes what will happen and why before any code changes. TodoWrite breaks that plan into checkpoints small enough to undo individually. Hooks physically block destructive commands so no amount of Claude confusion can run rm -rf /. Subagents isolate high-blast-radius work into a separate context so a failed attempt does not contaminate the main session. Rewind gives you a clean escape hatch when nothing else caught the problem.
The important part is not using these occasionally. It is applying them every time, in this order, regardless of how small the task feels. Standardizing the routine removes the dependency on memory and attention — which is exactly what you cannot trust during a long session.
The next sections walk through each step with concrete code and configuration you can drop in today.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦Developers who have had Claude Code leave broken commits, green-washed tests, or unexpected file rewrites in their repo will walk away with a repeatable routine that eliminates those incidents.
✦You will learn how to integrate Plan Mode, TodoWrite, Hooks, Subagents, and Rewind as one workflow (not isolated features), complete with production-ready shell hooks and subagent definition files you can drop in today.
✦You'll be able to use Claude Code confidently on a real main branch, shipping faster without sacrificing reversibility, reviewability, or the trust of anyone else reading the git log.
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Plan Mode is Claude Code's dedicated planning mode. Toggle it with Shift+Tab or type /plan. Instead of acting, Claude produces a plan you explicitly approve before any tool call fires.
The reason this matters as a workflow gate — not just a feature — is that it forces a readback of intent. If Claude understood the request slightly differently, the plan will show it. You catch drift before a single file is modified.
Before approving any plan, I check for three specific things:
Are the affected file paths listed by name? ("related files in the auth module" is not enough — I want src/auth/session.ts and src/auth/middleware.ts.)
Is the change order decomposed into reversible steps? (Migrations before code, code before tests, refactors split from feature work.)
Is the test strategy explicit? (Which existing tests validate the change? What new tests will be added?)
If any of those is missing, I push back with "rewrite the plan with these three points" before accepting. This is the single highest-leverage habit in the whole workflow. Most drift is caught here, for the cost of five minutes.
Once the plan is approved, it gets written into TodoWrite, Claude Code's built-in task tracker. Tasks move through pending → in_progress → completed as the session proceeds.
In a failure-first workflow, TodoWrite exists for one reason: to keep the session in a state where you can always stop and resume from a known point. If a step fails, only that step needs to be redone, and the granularity of the list tells you exactly what to rerun.
Three rules shape how I decompose tasks:
Each task should complete in five to fifteen minutes. Larger tasks accumulate more damage when they fail.
Every implementation task is followed by a verification task (test run, diff review, typecheck).
The final task is always "human reviews diff before commit." That last task is not optional.
The last rule is the one people skip. If you let Claude Code commit automatically after task completion, you have just opened the door to the exact failure mode you were trying to prevent. Keep the commit behind a human gate — even a ten-second look is enough to catch most problems.
Step 3: Hooks Block Destructive Commands at the Source
Hooks let you run a script when Claude Code fires specific events. The PreToolUse hook intercepts tool calls before they execute — which means you can physically block a dangerous Bash invocation no matter what led Claude to attempt it.
In the failure-first workflow, Hooks are the safety net that does not trust human attention. You can write the most careful plan in the world, but if the implementation calls git push --force on your main branch, you are still recovering from a disaster. Hooks put a hard floor under the worst outcomes.
Here is the hook I actually use, at ~/.claude/hooks/pre-tool-use-guard.sh. PreToolUse hooks receive JSON on stdin with the tool name and arguments; exit code 2 tells Claude the call was blocked.
#!/usr/bin/env bash# ~/.claude/hooks/pre-tool-use-guard.sh# PreToolUse hook: block destructive commands before Bash invocations run.set -euo pipefailpayload=$(cat)tool_name=$(printf '%s' "$payload" | jq -r '.tool_name // ""')# Only inspect Bash; Read/Write/Edit are allowed through for productivity.if [ "$tool_name" != "Bash" ]; then exit 0ficommand=$(printf '%s' "$payload" | jq -r '.tool_input.command // ""')# Blacklist the small set of truly destructive patterns.forbidden_patterns=( 'rm[[:space:]]+-rf[[:space:]]+/' 'rm[[:space:]]+-rf[[:space:]]+~' 'git[[:space:]]+push[[:space:]]+.*--force' 'git[[:space:]]+push[[:space:]]+.*-f([[:space:]]|$)' 'git[[:space:]]+reset[[:space:]]+--hard[[:space:]]+HEAD~' 'git[[:space:]]+filter-branch' 'git[[:space:]]+checkout[[:space:]]+\.' 'chmod[[:space:]]+-R[[:space:]]+777' ':\(\)\{.*\};:' # fork bomb)for pattern in "${forbidden_patterns[@]}"; do if printf '%s' "$command" | grep -Eq "$pattern"; then # Exit 2 tells Claude the command was refused, with a reason. printf 'BLOCKED by pre-tool-use-guard: %s\n' "$pattern" 1>&2 printf 'Command was: %s\n' "$command" 1>&2 exit 2 fidoneexit 0
Wire it into Claude Code by adding an entry to ~/.claude/settings.json:
You can verify it works by asking Claude inside a session to "rm -rf this repo and regenerate it." The hook should return BLOCKED by pre-tool-use-guard on stderr, and Claude will receive a clear rejection reason that lets it pivot to safer operations (deleting specific files one at a time).
Why regex-match rather than hard-code specific strings? Because Claude varies the command shape depending on context. rm -rf ./ and rm -rf /home/user/project are technically different strings, but both deserve blocking. A whitelist approach (only allow known-safe commands) is tempting, but it also breaks the flexibility that makes Claude Code useful during real development. A small, carefully-curated blacklist hits the sweet spot.
Hooks also let you attach automatic test runs before commits, force checkpoints on long sessions, or log every tool call to a file for audit. Start with Claude Code Hooks: Automation Techniques once you have the guard hook working.
Step 4: Subagents Contain the Blast Radius
Subagents are separate Claude Code instances invoked from the main session via the Task tool. Each runs with its own context window, its own tool permissions, and its own result — which is returned as a single message to the main session.
What makes subagents powerful in a failure-first design is containment. Risky work — dependency upgrades, large-scale refactors, experimental code generation — runs in the subagent's context. If it fails, the main session never sees the mess; it just receives a report that says "tried, could not finish." The parent context stays clean.
Here is a real subagent definition I use at ~/.claude/agents/dependency-upgrader.md:
---name: dependency-upgraderdescription: Attempts npm/pnpm minor+patch upgrades in bulk. Reports type errors and test failures. Never commits.tools: Bash, Read, Edit, Grep, Glob---You are a specialized dependency-upgrade agent. Follow these rules strictly.# GoalUpgrade packages in package.json to the latest minor/patch versions without bumping any major version.# Steps1. Run `npm outdated --json` to collect the diff.2. Exclude any package whose major version would change.3. Run `npm update` to upgrade the remaining set in one pass.4. Run `npm run typecheck` and save the result.5. Run `npm test -- --run` and save the result.6. For any failure, revert only the offending package to its prior version.# Forbidden- Never edit package.json by hand — only via npm commands.- Never commit, never push — output a report only.- Do not propose major-version upgrades.- Do not modify node_modules directly.# Output formatReturn the outcome in this structure:## Succeeded- <package>: <old> → <new>## Reverted- <package>: <reason>## Next StepsBullet list of diffs the human should review.
From the main session, you invoke it with @dependency-upgrader try minor updates. The subagent runs in a fresh context and returns a report. Even though its tools list includes Bash, the prompt explicitly forbids commits and pushes — if the subagent misbehaves, the worst-case state is a dirty node_modules and a modified package-lock.json, nothing in your git history.
The design principle for subagents in a failure-first workflow: minimize permissions, fix the output shape. Expanding permissions feels convenient, but "helpful" subagents that improvise are also the ones that land surprise changes. A subagent that returns a predictable report every time is more valuable than one that tries to be clever. More on this in Claude Code Subagent Patterns.
A second subagent: the pre-commit diff reviewer
One subagent I have found unexpectedly valuable is a read-only "diff reviewer" that evaluates a set of changes without permission to modify anything. Its sole job is to look at git diff and report concerns it finds. Here is the definition at ~/.claude/agents/diff-reviewer.md:
---name: diff-reviewerdescription: Reviews the current staged and unstaged diff for correctness, security issues, and leftover debug code. Never modifies anything.tools: Bash, Read, Grep, Glob---You are a read-only code reviewer. You must not modify any file.# GoalExamine the current git diff and report:1. Logic issues (off-by-one, missing null checks, wrong conditional direction)2. Security issues (hardcoded secrets, unvalidated input, injection vectors)3. Leftover debug code (console.log, print, pdb, TODO/FIXME markers added in this diff)4. Inconsistent style vs. the rest of the file# Steps1. Run `git diff --cached && git diff` to gather all pending changes.2. For each modified file, read the full file to get context beyond the diff.3. Group findings by severity: critical / warning / note.4. Do not propose patches; only describe issues.# Forbidden- Do not run Edit or Write.- Do not run any command that modifies files or git state.- Do not summarize by saying "looks good" unless you actually inspected every hunk.# Output format## Critical- <file:line>: <issue>## Warning- <file:line>: <issue>## Note- <file:line>: <issue>If no issues in a category, write "None."
Invoking it as @diff-reviewer check the current diff before committing acts as a second pair of eyes — the main session's Claude has context about what was intended, while the reviewer comes in fresh and reads only the code. The two perspectives catch different classes of issue. I find it especially useful for security review: the reviewer subagent has no stake in what the code does, so it is quick to flag an unvalidated parameter or a leaked secret that the implementing session had adopted.
Step 5: Rewind Is Your Last-Resort Reversal
Rewind is Claude Code's checkpoint feature. Every message and file state during a session is captured; /rewind lists them, and selecting any one returns the session to that exact moment.
In the failure-first workflow, Rewind handles the class of failures that slips past every other layer: context-level drift. Claude might use every tool correctly, pass every hook, return clean subagent reports, and still produce something that is not what you wanted — because somewhere along the way its interpretation shifted. No hook catches this. The individual tool calls all look legitimate. Only when you step back and look at the whole do you see the gap.
I use Rewind deliberately in three situations:
When I sense the work has diverged from the plan, I rewind to just after Plan Mode approval.
When a commit happens with failing tests, I rewind to the last known-green state.
When a subagent result was applied to the main session and then proved incorrect, I rewind to before the application.
The mental shift required is to stop treating Rewind as "the panic button." The earlier you use it, the smaller the damage and the faster the next attempt. Rewinding after 30 minutes of drift is painless; rewinding after three hours is a headache you gave yourself. Full mechanics are in Claude Code /rewind & Checkpoint Complete Guide.
The Unified Workflow: Five Steps, One Routine
Put together, the routine I run every time looks like this:
[0] Repo is clean. (git status shows no changes.) ↓[1] Plan Mode produces a plan. (/plan) - Plan must list affected paths, reversible step order, and test strategy. - Rewrite the plan if any are missing. ↓[2] TodoWrite decomposes the plan. - 5–15 min tasks. - Verification task after each implementation task. - Final task is "human reviews diff" — always. ↓[3] Implementation begins. (Hooks are now active.) - PreToolUse guards block destructive commands automatically. - High-blast-radius work is delegated to subagents. ↓[4] After each task, the verification task runs. - Sense drift? /rewind immediately. - Test failure? Rewind to last green state. ↓[5] Final task: human reviews `git diff`, writes commit message, commits. - Claude does not commit on its own. Ever.
The critical element is the last one. Automate implementation, automate testing, automate documentation generation — but do not automate the commit itself. One human pair of eyes on the diff, once per task, is what keeps broken work from ever reaching the branch.
On my own repositories, this routine took Claude-Code-caused incidents from one or two per month to essentially zero over the past quarter. The cost is about five extra minutes of planning and review per session, which is a rate I am happy to pay.
Common Pitfalls and How to Avoid Them
Three problems tend to emerge when teams first adopt this workflow.
Skipping the plan review
This is the single most common cause of incidents. Plan Mode only works if a human actually reads the plan. On busy days the temptation is to thumbs-up the plan and move on — and then an hour is lost to rollback.
The fix I use is mechanical: a five-minute timer I start when Plan Mode output arrives. Until the timer rings, I do not approve. In practice I use those five minutes to get coffee or read a related doc; it prevents the reflexive "looks fine, continue" response.
Hooks so strict they block legitimate work
Over-tightened hooks stop development. The classic failure is blocking git reset --hard entirely, which then also blocks the legitimate resets needed after a Rewind to re-sync working state.
The fix is to keep the blacklist focused on three categories: root-level destruction, history rewriting, and permission escalation. In the script above, only HEAD~ suffixes on reset --hard are blocked — git reset --hard HEAD (which just discards uncommitted work) passes through. Keep a log of legitimate commands that got blocked and revisit the patterns monthly.
Trusting subagent output without verifying
Because subagents run in isolated context, their returned report is the only ground truth the main session has. If the output format is loose, the main session's Claude will plow on based on what it thinks happened.
The fix has two parts: fix the subagent's output format with explicit field requirements (as in the example above), and make the main session explicitly re-check. Ask "list the exact files changed according to the subagent report" before proceeding. If the answer is vague, rewind and re-invoke the subagent.
Documentation drift in the CLAUDE.md memory file
A subtler failure mode: the project's CLAUDE.md memory file becomes stale, and Claude confidently acts on out-of-date context. You refactored the auth module three weeks ago, but CLAUDE.md still describes the old interface, so every plan references the wrong function names.
The fix is to treat CLAUDE.md like any other piece of production code — include it in the same review workflow. When a task rewrites an API or moves a file, the final verification task should check whether CLAUDE.md still describes reality. A one-line grep in the verification step (grep -n "oldFunctionName" CLAUDE.md) is usually enough to surface drift before it accumulates.
A Concrete Case Study: Shipping a Premium Paywall Feature
Here is an abbreviated log of how the workflow played out on a real change I shipped to claudelab.net — adding per-article purchase support that gates premium content behind a paywall.
The session began at 10:12 AM. I typed /plan with the prompt: "Add a per-article purchase option so users can unlock a single premium article without buying a full membership. Stripe metadata should distinguish article from pro and premium."
Plan Mode returned a plan at 10:14. It listed seven files across src/lib/premium.ts, src/app/api/checkout/route.ts, src/app/api/verify-session/route.ts, and two components. The test strategy mentioned extending the existing Stripe webhook mock. I read it twice, spotted that the plan did not mention updating the article_purchases cookie schema to accumulate multiple slugs (it was proposing single-slug overwrite, which would silently lose prior purchases), and pushed back.
At 10:19 the revised plan came back with accumulation logic specified. I accepted and let TodoWrite create eleven tasks, the last three being "run Stripe webhook mock tests," "run full test suite," and "human review diff."
Implementation ran from 10:22 to 11:41. Two hook blocks fired during that window — once when the implementation tried to rm -rf a generated cache directory that happened to be at the repo root (the hook caught the root-relative pattern), and once when it attempted git reset --hard HEAD~1 after a test failure (which I wanted to review before reverting). Both were correct blocks; in both cases Claude pivoted to safer alternatives (rm -rf ./src/generated/.cache and leaving the reset for me).
The subagent was invoked once, for the Stripe webhook test extension, because that file had broken in subtle ways twice before and I wanted the changes isolated. The subagent returned a report showing three new test cases added and all existing ones still passing. I applied the changes.
At 11:43 the "human review diff" task surfaced. git diff showed 280 lines changed across seven files. I caught one small issue — an environment variable name had a typo (STRIPE_ARTICLE_PRICE_I instead of STRIPE_ARTICLE_PRICE_ID) — fixed it by hand, and committed at 11:51.
Total session: one hour thirty-nine minutes. Two hook interventions, one subagent delegation, one human-caught bug at the final review. Zero rollbacks, zero incidents. That is roughly the shape of every session I run now.
How the Workflow Scales Across Four Sites
Running the same workflow across four independent repositories (claudelab.net, gemilab.net, antigravitylab.net, rorklab.net) adds one more consideration: consistency. If each repo has a different hook configuration, a different subagent set, and a different plan-approval habit, the whole benefit evaporates.
I solved this by centralizing the Claude Code configuration. The hooks script lives in a shared location and is symlinked into each project. Subagent definitions are also shared — all four sites use the same dependency-upgrader, the same test-runner, the same diff-reviewer. Per-project overrides live in the project's .claude/ directory and are kept minimal (usually just repo-specific path hints).
The outcome is that my working memory about "how Claude Code behaves" transfers across all four sites. I do not have to remember which repo has which safety net, because they are all the same safety net. For solo developers running multiple projects, this is as important as any individual hook or agent.
Why Failure-First Matters Beyond Claude Code
The discipline this article describes is not Claude-specific. Any autonomous agent tool — Cursor, Windsurf, Gemini CLI, any of them — benefits from the same shape. Plan before acting. Decompose into verifiable chunks. Block destructive operations at the tool layer. Isolate risk. Keep a reversal path.
The reason I spend most of my tooling time on Claude Code specifically is that its primitives (Plan Mode, hooks, subagents, rewind) are unusually well-suited to this discipline. Plan Mode is a first-class feature, not a prompt trick. Hooks receive structured JSON, not brittle stdout parsing. Subagents have explicit permission scoping. Rewind captures filesystem state, not just conversation.
But the ideas travel. If your next AI tool doesn't have Rewind, invest in snapshot branches. If it doesn't have hooks, write a git pre-commit. If it doesn't have subagents, use separate git worktrees. The features matter less than the discipline of assuming failure and designing for reversal.
Closing: The Smallest Next Step
You do not have to adopt all five layers at once. Add them in the order they give the highest return.
Start with Plan Mode. It requires no configuration — just a habit of typing /plan before every task. On its own, it catches about half the drift cases I used to hit.
Next, add the PreToolUse guard hook. Thirty minutes of setup, and you have a hard floor against destructive Bash calls forever after.
Subagents and Rewind pay off later, once the first two are rock-solid. Adopting everything simultaneously hides which layer is actually helping.
The smallest possible next step: in your next Claude Code session, type /plan before writing the prompt. Spend five minutes reading the plan before approving. That single change, every session, is the highest-leverage investment you can make in preventing AI-coding incidents.
Share
Thank You for Reading
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.