Chapter 06 · Section II · 12 min read
Destructive-operation guardrails
Some operations cannot be undone. Claude Code is careful about these by design, and you should be even more careful. A practical map of what is destructive, what the tool does about it, and where you still need to think.
Not every action is reversible. Deleting a file, force-pushing a branch, dropping a table — these classes of operations do not get undone by Ctrl-Z. Claude Code treats them with extra caution, and so should you. This section is a short atlas of the danger zones and the specific habits worth building around each one.
What counts as destructive
The categories worth naming out loud:
- File deletion.
rm,git clean -f, removing directories. - Git history rewrites.
git reset --hard,git rebase -i,git push --force,git branch -D. - Database mutation.
DROP,TRUNCATE, un-scopedDELETEorUPDATE. - External-side-effect operations. Sending an email, posting to Slack, closing a PR, publishing an npm package.
- Package/dependency changes.
npm uninstall, dropping a version, editing lockfiles by hand. - Config that changes shared state. Modifying CI/CD pipelines, GitHub repo settings, environment variables in the deployment target.
How Claude Code handles them
By default, the assistant will:
- Prompt before running any of the above, regardless of your permission mode’s leniency for other tools.
- Refuse to skip hooks (
--no-verify,--no-gpg-sign) unless you have explicitly authorised it. Hook failures are almost always telling you something. - Investigate before destroying. If Claude finds a lockfile it does not recognise, it will ask about it rather than delete it, because it might be part of your in-progress work.
- Prefer non-destructive alternatives. For instance, resolving a merge conflict by editing files rather than by discarding one side wholesale.
That said — the assistant is cautious, not incapable. You can still approve a destructive command. Approval means it runs.
The habits worth building
- Read the exact command before approving.
rm -rf dist/andrm -rf .gitdiffer by a single character. The prompt shows you the full command; use that fact. - Prefer scoped over broad.
rm -rf ./distis scoped to a directory;rm -rf ~/*is a career event. Push back if Claude proposes something broader than the task requires. - Never approve
git push --forceonmain. For your own branches, force-push is sometimes okay. For shared branches, it is destroying other people’s work. - Verify uncommitted state before
git reset --hard. If there is astashyou could take first, take it.
When you legitimately want to loosen
- In a throwaway environment. Nuke and reclone if it goes wrong.
- For your own personal branches you have not shared. Rebasing is expected.
- When automated (hooks, CI). Explicit checks compensate for less human review.
Even then: keep the destructive operations denied at the permission-mode level, and require your own explicit approval each time. Muscle memory saves you from the day you were tired.
Check your understanding
Quick check
—