Skip to content

ce-compound: pre-resolved repo-name command (git ... | sed ...) blocked by Claude Code multi-operation permission check #795

@PwnZoner

Description

@PwnZoner

Bug Description

Component: Skill — ce-compound
Summary: Invoking /ce-compound from inside a git repo fails immediately because the pre-resolved "Repo name" command pipes git rev-parse into sed. Claude Code's permission system treats piped commands as multiple operations and refuses to auto-approve, so the substitution never runs and the skill aborts before Phase 1.

This is not the same issue as #730 (which was about being outside a git repo / missing || true). I'm in a normal git worktree with broad git permissions allowlisted; the failure is the multi-op check, not exit-code handling.

Environment

  • Plugin Version: compound-engineering 3.3.2 (from every-marketplace)
  • Agent Platform: Claude Code
  • OS: Darwin 24.6.0 (macOS, arm64)
  • Working dir: inside a git worktree (git rev-parse would succeed)

What Happened

Error: Shell command permission check failed for pattern
"!`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`":
This Bash command contains multiple operations. The following parts require approval:
  git rev-parse --path-format=absolute --git-common-dir
  sed -E 's|/\.git/?$||; s|.*/||'

Skill never executes. The other pre-resolved line (git rev-parse --abbrev-ref HEAD) works fine — it's the | sed chain that trips the check.

Root Cause

plugins/compound-engineering/skills/ce-compound/SKILL.md (around line 25):

**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`

Claude Code's bash permission layer splits piped commands and requires each segment to be individually allowlisted. Even with Bash(git rev-parse:*) permitted, the sed segment isn't, so the whole !...`` substitution is blocked rather than executed.

Suggested Fixes

Pick whichever fits the skill's defensive style; any of these avoids the pipe:

Option A — let git produce the basename directly (no second tool):

-**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`
+**Repo name (pre-resolved):** !`basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo '__REPO_UNRESOLVED__'`

(Still two commands, but basename is usually allowlisted; if not, swap for option B.)

Option B — emit the toplevel path and let the agent take the basename:

-**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`
+**Repo toplevel (pre-resolved):** !`git rev-parse --show-toplevel 2>/dev/null || echo '__REPO_UNRESOLVED__'`

Then update the "If the lines above resolved..." instruction to tell the dispatcher to take the basename of the path.

Option C — bundle into a single shell invocation (still one command from the permission system's perspective if wrapped):

-**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`
+**Repo name (pre-resolved):** !`sh -c 'd=$(git rev-parse --show-toplevel 2>/dev/null) && printf "%s" "${d##*/}"' 2>/dev/null || echo '__REPO_UNRESOLVED__'`

(Permission-fragile — depends on whether sh -c is allowlisted in a given environment.)

I'd recommend B — it's the simplest, matches the existing __*_UNRESOLVED__ sentinel pattern used in ce-commit/ce-commit-push-pr, and shifts the trivial string manipulation to the agent where it belongs.

Repro

  1. Open Claude Code in any git worktree.
  2. Run /ce-compound.
  3. Observe Shell command permission check failed ... contains multiple operations before any phase begins.

Additional Context

The companion line right below (git rev-parse --abbrev-ref HEAD) does not use a pipe and works correctly, which confirms the trigger is the | sed chain, not git itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions