Permission rules don't match individual commands in chained expressions

Resolved 💬 3 comments Opened Mar 26, 2026 by Deluvio Closed Mar 29, 2026

Problem

When using chained commands like git commit -m "msg" && git status, permission rules such as Bash(git:*) don't match — even though both individual commands would be allowed. The entire string is evaluated as one unit, causing an unnecessary permission prompt every time.

This defeats the purpose of granular permission rules and forces users to approve every chained command manually.

Reproduction

  1. Add permission: Bash(git:*)
  2. Claude runs: git commit -m "msg" && git status
  3. Expected: Auto-approved (both commands match git:*)
  4. Actual: Permission prompt shown

Current workaround

A PreToolUse hook that blocks && and || entirely, forcing Claude to use separate tool calls:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "jq -r '.tool_input.command' | grep -qE '&&|\\|\\|' && echo '{\"decision\":\"block\",\"reason\":\"Blocked\"}' || true"
      }]
    }]
  }
}

This works but is a blunt instrument — it blocks all chaining even when it would be safe.

Proposed solution

Parse chained commands (&&, ||, ;) and match each sub-command individually against the permission rules. Only auto-approve if all sub-commands match.

View original on GitHub ↗

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