Permission system UX: compound command blocking, rule accumulation, undiscoverable Bash(*) fix

Open 💬 5 comments Opened Mar 6, 2026 by ThatDragonOverThere

Summary

The permission system has a compounding UX problem that makes "autonomous" agent usage impractical for long-term users. After 3 months of daily use, I accumulated 150+ narrow permission rules in settings.local.json — and compound commands (cd /my/project && git status) still prompted for approval every time because they don't match the individually-allowed patterns.

This is not one bug — it's a system-level UX failure across permission matching, compound command handling, and discoverability.

The Experience

  1. Month 1: Click "Always allow" on every git status, ls, python script.py prompt. Accumulate 50+ rules.
  2. Month 2: Still getting prompted on compound commands. Click "Allow" hundreds more times. 100+ rules now.
  3. Month 3: 150+ rules. Compound commands STILL prompt with security warnings like "bare repository attack prevention" — on my own project directory that I've been working in for months. Agent autonomy is fiction.
  4. Discovery: Learn about Bash(*) from reading source code. Replace 150 rules with 8 broad wildcards. Problem solved instantly. This should have been offered on day 1.

The Four Compound Command Blockers

These fire constantly when working in your own trusted project:

  1. "Compound commands with cd and git require approval to prevent bare repository attacks"
  2. "Compound command contains cd with output redirection - manual approval required to prevent path resolution bypass"
  3. "Compound commands with cd and git require approval" (variant)
  4. General compound command security checks

These assume adversarial scenarios (cloning untrusted repos, path traversal) that don't apply to users working in their own project root. They cannot be disabled without discovering Bash(*).

Evidence: My settings.local.json Before Cleanup

150+ entries including:

  • Every individual command: Bash(python:*), Bash(git status:*), Bash(ls:*), Bash(cd:*), Bash(git log:*), etc.
  • One-off commands that got permanently saved: Bash(RUN_OVERNIGHT_ANALYSIS.bat core), individual for loop fragments, multi-line Python heredocs with full escaped source code as permission patterns
  • Compound commands that were allowed once but the pattern was too specific to match again

Despite all of this, cd /project && git status still prompted.

The Fix (Trivial but Undiscoverable)

{
  "permissions": {
    "allow": ["Bash(*)", "Read(*)", "Write(*)", "Edit(*)", "Glob(*)", "Grep(*)"],
    "ask": ["Bash(rm -rf:*)", "Bash(git push --force:*)", "Bash(git reset --hard:*)"]
  }
}

8 rules replace 150+. Dangerous commands still prompt. Everything else just works. Real safety comes from hooks (RAM auditing, pre-commit validation), not permission prompts on ls.

Related Issues (13 reports, same root cause)

Compound command blocking:

  • #28183 — Compound commands of individually-allowed commands still prompt
  • #29491 — Compound bash commands should evaluate each command's permissions independently
  • #20985 — Feature request for smart permission matching on compound shell commands
  • #30435 — Feature request to suppress bash safety heuristic prompts via settings
  • #30524 — Windows: unnecessary cd prepended to commands triggers bare repository prompt

Permissions not sticking / wildcards broken:

  • #27139 — Broad wildcard permissions in settings.local.json not respected
  • #29400 — "Don't ask again" doesn't persist
  • #11380 — Continually asks for permission after "always allow"
  • #10629 — Asking permission too often
  • #3428 — Bash:* wildcard not working

Trust model:

  • #29285 — Feature request to permanently trust a directory
  • #28784 — Security: Bash(cd:*) allows arbitrary execution via && chaining

Token injection:

  • #15742 — Multi-line bash __NEW_LINE__ token appears in saved permission patterns

Proposed Solutions

  1. Offer "trust this project" during first session — a first-class option that sets Bash(*) + dangerous-only ask list
  2. Make Bash(*) discoverable — surface it in /permissions, in the "Always allow" dialog, and in docs
  3. Compound command permissions should decomposecd /path && git status should check Bash(cd:*) AND Bash(git status:*) individually, not treat the compound as a new unique pattern
  4. Scope security checks to actual risk — bare repository attack protection should only apply when entering directories outside the project root, not when cd-ing within your own working tree
  5. Periodic permission cleanup prompt — after 50+ rules accumulate, suggest consolidation

Environment

  • Claude Code v2.1.70
  • Windows (MSYS2/Git Bash)
  • Daily user since December 2025
  • 11 custom agents, hooks for RAM safety / pre-commit / compaction recovery

View original on GitHub ↗

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