cd+git prompts are the git-hooks security control, not an allowlist gap (reframe of the cd-wrapper idea)
@TimZander is already working on this.
Since Jul 24, 2026.
- Dominant language
- Python
- Stars
- 0
- Forks
- 1
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 7
Description
Problem
The read-only allowlist (#183 / PR #198) matches bare commands like git status, git log, git diff. But in day-to-day worktree-heavy work the agent habitually wraps them:
cd "C:/Users/tzander/Documents/repos/GrandCentral" && git status
Claude Code splits compound commands and requires every segment to match an allow rule. The leading cd "…" segment is not allowlisted, so the whole compound prompts — even though the actual work (git status) is on the allowlist. The equivalent git -C <path> status form has the same problem: it starts with git -C, not git status, so it doesn't match the prefix either.
Net: we allowlisted the commands, but not the shapes the agent actually emits.
Evidence (transcript analysis, 27 active days)
Residual still-prompting Bash+MCP calls after the allowlist ≈ 271/active day (upper bound). Breakdown:
| Bucket | /day | Share of residual |
|---|---|---|
cd "path" && … compounds |
135.4 | ~50% |
| MCP mutating (should prompt) | 47.4 | |
| git/gh/az mutating (should prompt) | ~39 | |
| read utils, python, build, misc | ~49 |
For comparison the allowlist currently eliminates ~59/day (bare commands). So the cd-wrapper alone is more than double what the allowlist recovers — the single biggest remaining lever, and it's the same safe commands prompting only because of the wrapper.
Options
- Allow
cd(Bash(cd:*)). Safe by construction: compound-splitting meanscd path && <x>auto-approves only if<x>is independently allowlisted —cd path && rm -rf ystill prompts.cditself has zero mutation/exfiltration capability. Blocker to verify first: does Claude Code's matcher enforce a token boundary for a 2-char prefix? A raw-prefix match could catchcdrecord/cdparanoia/cdda2wav. Deferred pending that check. - Handle
git -C <path>— if kept as a habit, the allowlist would need a rule form that matches it (harder;git -Cinterposes a flag before the subcommand). - Steer the agent (soft,
standards/CLAUDE.md): prefer the tool's own cwd overcd … &&prefixing. Guidance, not enforcement — lower reliability.
Why this matters
The allowlist's measured benefit (~59/day) understates its potential ceiling. Closing the cd-wrapper gap would roughly halve the residual prompt load (~135/day) without adding any mutation surface — the highest-leverage follow-up to #183.
Acceptance criteria
- Verify the matcher's token-boundary behavior for short prefixes (does
Bash(cd:*)over-matchcdrecordetc.?). - If safe: add
Bash(cd:*)tostandards/settings.jsonand re-measure residual (expect ~135/day recovered). - Decide on the
git -C <path>shape (allowlist rule vs. steer away). - If steering: add a
standards/CLAUDE.mdnote to avoidcd … &&prefixing when the tool's cwd suffices.
Related
- #183 / PR #198 — the allowlist this extends.
- #166 — worktree/context theme; the worktree fragmentation finding (per-directory
settings.local.json) is why cd-prefixing is so common here.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.