Auto-mode permission classifier misses git reset --hard when bundled in a multi-line Bash command, then false-positives on an unrelated later command
Summary: In auto-permission mode, the classifier that's supposed to block destructive git commands (e.g. git reset --hard) failed to catch one when it was the 3rd line of a multi-command Bash invocation, letting it execute and discard uncommitted working-tree changes with no confirmation prompt. A later, entirely read-only command (git status --short; git branch --show-current) was then blocked with the same "Irreversible Local Destruction" classification — a false positive, since the actual destructive command had already run.
Steps to reproduce:
- In a git repo with uncommitted (unstaged) modifications present.
- Issue a single Bash tool call containing multiple commands on separate lines, where
git reset --hard <ref>is not the first line, e.g.:
````
git checkout dev -- some/file
git clean -fd some/other/path
git reset --hard dev
git status --short
- Observe: the call executes without a permission prompt, and the uncommitted changes are silently discarded.
- Immediately after, issue a harmless follow-up call, e.g.
git status --shortalone. - Observe: this call gets blocked with reason
[Irreversible Local Destruction], even though it contains no destructive operation.
Expected: Step 2's command should have been blocked/prompted for approval, since it contains git reset --hard, regardless of its position within a multi-line script. Step 4's command should not be blocked at all.
Actual: The destructive command was missed; the safe command was blocked afterward instead.
Impact: This is a real safety-net failure for exactly the scenario auto mode is supposed to protect — the discarded changes had no git blob anywhere (never staged), so they were unrecoverable via any git mechanism (git fsck --unreachable, reflog, etc.).
Suggested fix: The classifier should scan every line/subcommand of a compound Bash invocation independently for destructive patterns, not just the overall command string or its first token. Consider also surfacing why a given call was flagged, so a false-positive block (as in step 4) can be distinguished from a legitimate one.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗