From cd12cb5e2c7fd1ac2125ccea5214c9c64dfa6305 Mon Sep 17 00:00:00 2001 From: Timmy Date: Tue, 12 May 2026 12:46:34 +0100 Subject: [PATCH] fix: Bash(:*) is invalid; use unconstrained Bash instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude Code rejects "Bash(:*)" with "Prefix cannot be empty before :*" — the rule is silently skipped, which since 5b48f0d0 left no Bash entry in the allowlist at all. Every coder agent's Bash call has been auto-denying since that commit landed (~840 of 1.4k denials in the sled log). The canonical form for "allow all bash commands" is the tool name alone: "Bash" (no parens). Apply it in three places that 5b48f0d0 touched: - .claude/settings.json (project root, inherited by new worktrees) - server/src/io/fs/scaffold/templates.rs (huskies init template) - server/src/io/fs/scaffold/tests.rs (assertion now checks "Bash") The gateway settings.json at ~/Desktop/huskies/.claude/settings.json and the four live worktrees (810, 888, 890, 894) were also corrected — not in this commit since they live outside the repo. Surfaced via /doctor; reported with rule "Invalid permission rule Bash(:*) was skipped: Prefix cannot be empty before :*". Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/settings.json | 2 +- server/src/io/fs/scaffold/templates.rs | 2 +- server/src/io/fs/scaffold/tests.rs | 16 +++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index f3e82c03..4107b35e 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,7 +1,7 @@ { "permissions": { "allow": [ - "Bash(:*)", + "Bash", "Read", "Edit", "Write", diff --git a/server/src/io/fs/scaffold/templates.rs b/server/src/io/fs/scaffold/templates.rs index bd0ba577..0dfe204b 100644 --- a/server/src/io/fs/scaffold/templates.rs +++ b/server/src/io/fs/scaffold/templates.rs @@ -70,7 +70,7 @@ setup wizard instructions and guide the user through it conversationally.\n"; pub(super) const STORY_KIT_CLAUDE_SETTINGS: &str = r#"{ "permissions": { "allow": [ - "Bash(:*)", + "Bash", "Read", "Edit", "Write", diff --git a/server/src/io/fs/scaffold/tests.rs b/server/src/io/fs/scaffold/tests.rs index 855a6378..42e7b76b 100644 --- a/server/src/io/fs/scaffold/tests.rs +++ b/server/src/io/fs/scaffold/tests.rs @@ -614,13 +614,15 @@ fn scaffold_story_kit_claude_settings_uses_canonical_bash_syntax() { ); } - // The wildcard `Bash(:*)` must be present — covers all bash commands. - // (Previously this asserted a curated per-command list; replaced with a - // single wildcard since coders kept hitting auto-deny on patterns the - // list missed, and the per-command gate offers no real safety in this - // trusted single-user deployment.) + // The unconstrained `Bash` rule must be present — covers all bash commands. + // (Previously this asserted a curated per-command list; replaced with the + // tool-only form since coders kept hitting auto-deny on patterns the list + // missed, and the per-command gate offers no real safety in this trusted + // single-user deployment. The earlier `Bash(:*)` form was tried and + // rejected by Claude Code — empty prefix before `:*` is invalid and + // silently skipped.) assert!( - settings.contains(r#""Bash(:*)""#), - "settings.json missing wildcard Bash allowlist: {settings}" + settings.contains(r#""Bash""#), + "settings.json missing unconstrained Bash allowlist: {settings}" ); }