June 25, 2026
Claude Code Blocks Destructive Git. Keep Your Rules
Auto mode blocks destructive git and IaC commands now. It's a probabilistic classifier, not a deterministic rule, so your deny rules

By Rapls
4 min read
Claude Code now blocks the git command that almost cost me a day's work. I'm keeping my deny rules anyway.
A while back I asked an agent to roll back to my last push so I could glance at some old code. It reached for git reset --hard and took my uncommitted work with it. After that near-miss I started adding deny rules to my settings.json by hand: the boring lines that refuse the destructive git commands I never want run without me asking for them by name.
This month, Claude Code shipped the guardrail I had been building by hand. According to the June 19, 2026 changelog, auto mode now blocks the destructive ones by default. git reset --hard, git checkout -- ., git clean -fd, and git stash drop are refused when you didn't ask to discard local work. git commit --amend is blocked when the commit wasn't made by the agent this session. And terraform, pulumi, and cdk destroy are blocked unless you named the specific stack.
My first reaction was to delete my own lines. The default now does the thing I had been doing manually, so why keep the maintenance? Then I read what the guard actually is, and I put my deny rules back.
The guard is real, and it's a classifier, not a rule
Here is the part that changed my mind. In auto mode, Claude Code doesn't ask you to approve each command. A safety classifier, a second model reading the conversation, decides in real time whether each action is safe. The new guardrail lives inside that classifier. When it blocks git reset --hard, it isn't matching a fixed pattern. It is inferring, from the transcript, that you didn't ask to throw work away.
That inference is good, and it is welcome, and it is not the same thing as a rule. A classifier judges intent, which means it can also misjudge it. The honest tell is in the failure mode: when the classifier model is temporarily unavailable, auto mode fails closed and blocks commands until it comes back. Failing closed is the right call, and it is also a reminder that this protection is a live inference with a dependency, not a static line that is simply true whether or not a model is reachable.
Three reasons my hand-written lines stayed
The first is mode. This guardrail is an auto-mode feature. If you run Claude Code with normal permission prompts, or in any setup where the auto-mode classifier isn't the thing gating commands, the default isn't doing this for you. A deny rule in settings.json, or a PreToolUse hook, runs regardless of mode. It doesn't care how you happen to be driving the agent today.
The second is determinism. The classifier infers whether you asked; a deny rule matches whether you did. For most commands, inference is fine, and for the one command that would cost me a day, I want the boring certainty of a pattern that either fires or doesn't. PreToolUse hooks also run before the permission system, so they catch things that slip past softer checks. Inference raises the floor. A matched rule is the floor.
The third is scope. The new guard covers git and infrastructure-as-code. That is exactly the right place to start, and it is not the whole map. It does not stand between an agent and rm -rf, a dropped database, a force-push to main, or a secret read out of a file and sent somewhere. Some of the near-misses I worry about most aren't git at all, and for those, the default did nothing, because it was never meant to.
Inference is not the only layer, and neither is the sandbox
It is worth saying that the sandbox doesn't cover this either, for a subtle reason. Auto mode's sandboxing isolates the filesystem and network, but git reset --hard looks safe to a sandbox: it only touches files inside your project directory. The boundary was never crossed. The work is just gone. Destructiveness and containment are different questions, and a tool can answer one perfectly while leaving the other open.
So I stopped thinking of these as competing options and started stacking them. The built-in classifier is intent inference. My deny rules and hooks are deterministic enforcement. The sandbox is containment. Each one misses what the others catch, and the cheapest near-miss to prevent is the one three layers refuse instead of one.
What I actually changed
I didn't delete the lines the guard now duplicates. I left them as the deterministic backstop under a probabilistic improvement, which is what defense-in-depth is. What I did change is where I spent the attention the new default freed up: on the gaps it doesn't cover. The git case is handled three ways now. The rm -rf, the database, and the secret-exfiltration cases are the ones still leaning on rules I wrote, so that's where the next hour of config goes.
A note to my next self
A better default is a reason to audit your config, not to delete it. When the floor rises, check what is now redundant, keep it anyway as a backstop, and move your effort to whatever the new default still doesn't reach. The day the classifier is uncertain about your intent, or the command isn't a git command at all, the only thing standing between you and lost work is the deterministic line you wrote back when you didn't trust anything to catch it for you.
The auto-mode safety details (the blocked git and IaC commands, the "didn't ask to discard" condition, the amend rule) are from the official Claude Code changelog, June 19, 2026: https://code.claude.com/docs/en/changelog . The near-miss is mine. Behavior and version specifics change quickly, so confirm against the current changelog before relying on any of it. Disclaimer: The experiences and decisions in this post are my own. English isn't my first language, so I use an AI assistant to help draft and edit the writing.
Disclaimer: The experiences and decisions in this post are my own. English isn't my first language, so I use an AI assistant to help draft and edit the writing.
Originally published at https://dev.to on June 25, 2026.