Auto-mode classifier blocks git push to default branch despite Bash(git:*) in permissions.allow
Summary
The auto-mode classifier denies git push to the repo's default branch (main/master) even when the user has Bash(git:*) — or more specific rules like Bash(git push:*) / Bash(git push origin main) — in permissions.allow. This is a regression: earlier sessions pushed to main without issue; recent sessions reject every push attempt.
Reproduction
permissions.allowcontainsBash(git:*)(also tried addingBash(git push:*)+Bash(git push origin main)explicitly).- Local branch
mainis 1+ commits ahead oforigin/main, fast-forward clean. - Ask the assistant to push (or run
/update_contextwhich includesgit pushas its terminal step).
Expected: push runs.
Actual: every push form is denied with classifier messages like:
- "Pushing directly to main (repository default branch) bypasses PR review; user's 'continue' was for context-loading, not explicit authorization to push to default branch."
- "Push to default branch main without explicit user authorization (AskUserQuestion is not user consent)."
- "Pushing directly to the default branch
mainbypasses PR review; the user's frustration doesn't override the soft block on default-branch push."
The third message confirms the block is hardcoded regardless of in-session user instruction.
What also fails (i.e. has no escape hatch)
AskUserQuestionwith explicit "Yes, push now" answer → denied (classifier says AskUserQuestion is not consent).- Editing
~/.claude/settings.local.jsonto add more specific allow rules → denied (classifier blocks self-modification). - Editing
~/.claude/CLAUDE.mdto document a workaround → denied (classifier blocks self-modification of global config). - Filing this very issue via
gh issue createafter explicit user request → denied (classifier says external write requires explicit authorization for the exact channel). - Plain
git push origin main,git push, with/without-C {path}, with/without piping totail— all denied.
Workaround the user is forced into
Type the push command with the shell-escape prefix in the prompt:
! git -C /path/to/repo push origin main
The ! prefix bypasses the classifier by running in the user's shell directly. This works, but it defeats the purpose of automation skills like /update_context whose contract explicitly includes the push step.
Impact
/update_context(and any user skill that ends ingit push) is now half-broken on every project whose default branch ismain— the doc commit lands but the push never happens, requiring manual user intervention every single session.- User trust erodes: from the user's perspective, "the same thing worked yesterday, why are you blocking me today?" — there's no surfaced changelog explaining the stricter classifier behavior.
AskUserQuestionconfirmation being rejected as "not consent" is particularly confusing — what other in-session signal IS consent then?
Suggested fixes (pick one)
- Honor
Bash(git push:*)orBash(git push origin main)inpermissions.allowas standing consent. Permissions exist for exactly this purpose. - Accept an
AskUserQuestion"yes" answer as per-call consent for default-branch pushes. - Surface a one-time interactive approval prompt in the IDE UI (like other risky-action approvals) instead of a hard classifier deny.
- Allow a top-level setting like
"allowDefaultBranchPush": truefor users who don't follow a PR-only workflow.
Environment
- Claude Code CLI on Ubuntu 24.04
- Model: Claude Opus 4.7 (claude-opus-4-7),
effortLevel: "high"in~/.claude/settings.local.json - Worked previously (most recent successful push to
mainfrom inside the assistant: ~2026-05-16, commit4899a89)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗