Auto-mode classifier blocks git push to default branch despite Bash(git:*) in permissions.allow

Resolved 💬 3 comments Opened May 17, 2026 by tomekkerber Closed May 21, 2026

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

  1. permissions.allow contains Bash(git:*) (also tried adding Bash(git push:*) + Bash(git push origin main) explicitly).
  2. Local branch main is 1+ commits ahead of origin/main, fast-forward clean.
  3. Ask the assistant to push (or run /update_context which includes git push as 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 main bypasses 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)

  • AskUserQuestion with explicit "Yes, push now" answer → denied (classifier says AskUserQuestion is not consent).
  • Editing ~/.claude/settings.local.json to add more specific allow rules → denied (classifier blocks self-modification).
  • Editing ~/.claude/CLAUDE.md to document a workaround → denied (classifier blocks self-modification of global config).
  • Filing this very issue via gh issue create after 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 to tail — 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 in git push) is now half-broken on every project whose default branch is main — 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.
  • AskUserQuestion confirmation being rejected as "not consent" is particularly confusing — what other in-session signal IS consent then?

Suggested fixes (pick one)

  1. Honor Bash(git push:*) or Bash(git push origin main) in permissions.allow as standing consent. Permissions exist for exactly this purpose.
  2. Accept an AskUserQuestion "yes" answer as per-call consent for default-branch pushes.
  3. Surface a one-time interactive approval prompt in the IDE UI (like other risky-action approvals) instead of a hard classifier deny.
  4. Allow a top-level setting like "allowDefaultBranchPush": true for 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 main from inside the assistant: ~2026-05-16, commit 4899a89)

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗