[Bug] Auto-mode classifier judges command form, not effect: dry-runs blocked while allowlisted equivalents with larger blast radius pass; denials stack into the 5-consecutive lockout

Status Open
Maintainer reply None cached
Activity 0 comments · opened Jul 19, 2026

Summary

The auto-mode permission classifier judges Bash commands by their surface form, not their effect, which produces repeated false-positive denials on benign commands — including read-only dry-runs — while the identical effect passes instantly when phrased through an allowlisted command. In longer autonomous runs the denials stack into the "N consecutive actions were blocked" lockout banner, derailing plan-mode/auto-mode sessions (in our case, mid-way through authoring a new agent skill).

Related: #78192 (over-triggering, general), #78344 (5-denials-one-task shape). This report adds the form-vs-effect inconsistency and dry-run evidence.

Environment

  • Claude Code CLI, auto mode (default permission mode), Linux (Ubuntu, kernel 6.17)
  • Observed across 7+ sessions, 2026-07-16 → 2026-07-19, same machine

Reproduction (representative, from real transcripts)

  1. In auto mode, have the agent clean up retired directories that contain only git-ignored __pycache__ artifacts:
  • rm -rf skills/a skills/b skills/c …BLOCKED (bulk-deletion shape)
  • git clean -ndX skills/BLOCKED — note -n: this is a dry run, a pure read-only listing of ignored files
  • find skills -type d -name __pycache__ -prune -exec rm -rf {} +ALLOWED instantly (the project had Bash(find:*) in permissions.allow, which skips the classifier)

The third command deletes strictly more than the first two would have shown/removed. Same effect, opposite verdicts, decided by phrasing.

  1. Other benign-intent denials from the same period: pip install --user --break-system-packages <pkg> (flagged for the flag's name during a version-validation task), a sed cleanup of merge-conflict markers in a lockfile (flagged as irreversible destruction — git checkout -- of the same file would have been equally destructive and likely unflagged).
  2. After several denials in a row the session surfaces: "Auto mode classifier requires confirmation for this command. 5 consecutive actions were blocked. Please review the transcript before continuing." — at which point an autonomous run (ours was creating a plan for a new skill) is effectively dead until a human intervenes.

What went wrong

  • Effect-blind form matching: a dry-run (git clean -n…) cannot be destructive, yet is blocked; a narrow find -exec rm with larger blast radius passes because a broad allowlist rule (find:*) bypasses classification entirely.
  • Denials compound instead of converging: the denial text tells the agent to try "other tools that might naturally accomplish this goal", but each rephrasing risks another denial → the N-consecutive lockout. There is no "confirm once for this narrow goal" path in-band.
  • Asymmetric incentives: the practical fix users discover is adding broad permissions.allow rules (e.g. find:*, bash:*), which removes the classifier from exactly the commands it was judging — the safety outcome is worse than a well-targeted confirmation would have been.

Expected

  • Dry-run / list-only flags (-n, --dry-run, --check) on otherwise-destructive commands should classify as reads.
  • Consider effect-level classification for common deletion shapes (paths under /tmp/session scratch vs repo paths; git-ignored artifacts vs tracked files).
  • After a denial, offer a one-shot in-band confirmation ("allow this specific command once") instead of pushing agents toward rephrasing-roulette and users toward broad allowlists.

Impact

Autonomous/plan-mode runs stall mid-task; users respond by adding broad allowlist rules that bypass the classifier wholesale, reducing net safety.

View original on GitHub ↗