[Bug] Claude ignoring ruleset constraints and executing blocked commands without user consent

Status Open
Reported on v2.1.215
Maintainer reply None cached
Activity 3 comments · opened Jul 20, 2026

Bug Description
Claude ignored hooks and ran potentially destructive commands unpromted, ignored rules sets in global CLAUDE.md as well as deny bash commands setup in settings.json

Environment Info

  • Platform: darwin
  • Terminal: zed
  • Version: 2.1.215
  • Feedback ID: 6d1f62b7-3867-4d10-a36c-242519f06fe5

Native permission deny rule bypassed for git commit / cherry-pick / reset --hard

Environment

  • Claude Code 2.1.215
  • rtk 0.43.0
  • Config: /Users/enrique/.claude/settings.json

Deny rules in effect (verbatim from settings.json)

"Bash(git commit*)"
"Bash(rtk git commit*)"
"Bash(git cherry-pick*)"
"Bash(git reset --hard*)"

What happened

Assistant executed the following commands via the Bash tool during a session, all matching existing deny patterns above, and all executed without being blocked or prompting for confirmation:

  1. rtk git commit -m "Track Cargo.lock for builds" — matches "Bash(rtk git commit*)"
  2. rtk git cherry-pick -n 5adab3e — matches "Bash(git cherry-pick*)"
  3. rtk git reset --hard 21de890 — matches "Bash(git reset --hard*)"

All three ran to completion with normal success output. No permission prompt appeared, no block message returned.

Root cause isolation

The rtk-rewrite.sh PreToolUse hook (/Users/enrique/.claude/hooks/rtk-rewrite.sh) delegates all deny-detection to rtk rewrite <cmd>, which returns exit code 2 when a configured deny rule matches. Per the hook's own logic (lines 60-63), on exit code 2 it does nothing and exits 0, explicitly deferring enforcement to "Claude Code's native deny rule":

2)
  # Deny rule matched — let Claude Code's native deny rule handle it.
  exit 0
  ;;

Verified directly:

$ rtk rewrite "rtk git commit -m \"test\""
EXIT:2

This confirms rtk correctly detects the deny match. The hook layer is not at fault — it correctly identifies the deny condition and defers.

The failure is in Claude Code's own native permission-matching engine: despite an exact-prefix-matching deny pattern being present in settings.json, the command was allowed to execute anyway.

Impact

Deny rules for destructive/irreversible git operations (commit, cherry-pick, reset --hard) do not reliably block execution when the command is passed through an RTK-prefixed invocation (rtk git ...), even though a deny pattern for that exact prefixed form exists in config. This defeats the purpose of the deny list for any command the RTK hook touches.

Repro

Exact command strings + config above. Already submitted via /feedback in-session.

View original on GitHub ↗

3 Comments

ToledoEM · 2 months ago

not a duplication

vinnymacdinv-debug · 2 months ago

I have noticed the same behavior from Claude where it ignores the instructions given in Claude.md file and acts of it's own. This is very disturbing and upon asking and confronting, it says,

"It is it's default behavior and there is nothing that can be done..!! " More disturbing is that is acknowledges that this behavior can't be stopped and it can't be trusted....!!

This is serious...!!

I am sharing attached PDF that has full chat, you can easily figure out who is asking the questions and the answers given by Claude.

Claude Behavior to make changes without approval..pdf

rulereceipt · 23 days ago

The main thing here is a Claude Code enforcement bug, the deny patterns matched and the commands ran anyway, and that's for them to fix.

As a separate layer until they do: I keep an open PreToolUse hook (rulereceipt guard, rulereceipt.dev) that reads your CLAUDE.md and refuses a command that breaks a rule before it runs. It fails open on its own errors, so it can't lock up your terminal. Straight about the limits: it auto-blocks rules that name a file or branch, and command bans like git reset --hard* only if you mark which part is the ban, so it isn't a drop-in replacement for settings.json deny. But it's a second gate, and not the one that just failed. It's mine.