auto-mode classifier vetoes commands present in permissions.allow (no override path)
Summary
In auto-mode (default permission mode) sessions, the content-based classifier vetoes commands that are explicitly present in ~/.claude/settings.json permissions.allow. The allow-list entry has no effect — the classifier's category-based blocklist runs first and denies the command regardless.
Concrete case: Bash(git worktree remove:*) is in permissions.allow, and every single git worktree remove <path> call from an auto-mode session is blocked with Permission for this action was denied by the Claude Code auto mode classifier. Reason: [Irreversible Local Destruction].
Reproduction
~/.claude/settings.jsonincludes underpermissions.allow:
``json``
"Bash(git worktree remove:*)"
(verified at line 35 of my settings.json)
- Start an auto-mode session in Claude Code CLI 2.1.267 (macOS 15.6/Darwin 25.6.0, zsh).
- Ask Claude to run either of these — even against a clean (
git status --porcelainempty) worktree:
````
git -C /path/to/parent-repo worktree remove /path/to/worktree
git -C /path/to/parent-repo worktree remove --force /path/to/worktree
- Observed: assistant's Bash tool call returns
````
Permission for this action was denied by the Claude Code auto mode classifier.
Reason: [Irreversible Local Destruction].
- Expected: the
permissions.allowentry short-circuits the classifier, and Bash executes normally (as it does in non-auto-mode when a matching allow-rule exists).
Verification the rule is actually being loaded
Ran an idempotent applier over ~/.claude/settings.json:
= Bash(git push --force-with-lease:*) (already present)
= Bash(git commit --amend:*) (already present)
= Bash(git rebase:*) (already present)
= Bash(git worktree remove:*) (already present)
= Bash(git worktree prune:*) (already present)
= Bash(git branch -D:*) (already present)
...
Added 0 new rules to permissions.allow
All classifier-blocked shapes are already present in permissions.allow. Zero effect on auto-mode classifier behavior.
Workaround
The only paths that currently work from an auto-mode session for these command classes:
- Operator runs the command from their own terminal (bypasses harness classifier entirely — a 36-worktree drain executed in ~5 seconds via one pasted
python3 -c "..."callinggit worktree removein a loop). - Operator switches permission mode away from auto-mode for the specific session.
Neither permissions.allow additions nor the documented settings.json patch mechanism unblocks these categories in auto-mode.
Impact
I hit this ~4 times in one week doing infrastructure work — WIP-drain of merged git worktrees, git rebase --onto for cascading upstream merges, git push --force-with-lease after a base-branch advance, and DNS/cert operations via Railway MCP. Each incident costs a round-trip to the human operator (who has to paste the command from their terminal), which defeats the purpose of auto-mode for a solo operator whose stated intent is "do the work autonomously against my infra."
There is a documented permissions.allow mechanism that reads as if it should unblock these — the schema at https://json.schemastore.org/claude-code-settings.json documents permissions.allow as an override, and the existing behavior for non-auto-mode confirms that shape works there. The auto-mode classifier appears to sit in front of the allow-list rather than consulting it.
Suggested fix (any of these)
- Consult
permissions.allowbefore applying the auto-mode content classifier, so exact-match / wildcard-match shapes short-circuit the veto (this is what a user would expect from reading the settings.json schema). - Or: add a documented
permissions.allowOverridesAutoModeClassifier: trueopt-in, so operators can opt into the interaction they need. - Or: document explicitly which classifier categories are non-overridable, so operators stop authoring no-op settings.json patches thinking they'll unblock these commands.
Environment
- Claude Code CLI: 2.1.267
- macOS: Darwin 25.6.0 (macOS 15.6)
- Shell: zsh
- Permission mode: auto-mode (default)
- Settings file:
~/.claude/settings.json(JSON, not JSONC)
Related classifier categories I've observed the same behavior on
Same permissions.allow no-op behavior verified for:
[Irreversible Local Destruction]— blocksgit worktree removeandgit branch -Ddespite allow entries[Git Destructive]— blocksgit rebase,git commit --amend,git push --force-with-leasedespite allow entries[DNS / Domain / Cert Changes]— blocksmcp__railway__generate_domainetc. despite allow entries[Auto-Mode Bypass]— blockscurl … api.cloudflare.comshapes underdoppler rundespite the parentdoppler runallow wildcard