diff --git a/.claude/notes/automation.md b/.claude/notes/automation.md index 0bb32b54..fbd5c3f9 100644 --- a/.claude/notes/automation.md +++ b/.claude/notes/automation.md @@ -3,6 +3,35 @@ Lessons specific to Claude Code skills, slash commands, classifier interactions, and parallel-agent workflows in this repo. Newest-first. +### Match shell-command hooks by regex word-boundary, not substring + +Substring patterns like `*"gh pr create"*` fire on any command that +literally contains the target string (`echo gh pr create`, +`bash -c "git push test"`), producing high-volume false positives. +"Starts with" patterns miss compound forms (`cat > body && gh pr +edit`, `var=$(...) && git push`), producing high-cost false +negatives. A regex word-boundary match lands the balance — three +parts: a leading shell-separator boundary, the alternation, a +trailing boundary: + +``` +(^|[[:space:];&|]) # line start OR shell separator +(gh pr create|git push) # the actual targets +([[:space:]]|$) # space OR line end +``` + +For advisory hooks (surface a checklist, log a warning) bias toward +false positives — the cost of an extra fire is one acknowledgment; +a missed fire on a real action is worse. For blocking hooks (deny +the action via `permissionDecision: deny`) flip the bias: prefer +starts-with so an unrelated command isn't forcibly stopped. + +This trade-off generalizes to any agent hook matching shell commands +by content; PR commands are this entry's example, not its scope. + +Anchor: `.claude/settings.json` PR #80 commit `3c12d02`, +`PreToolUse.Bash.hooks[0].command` regex. + ### Don't escape backticks inside a single-quoted HEREDOC A `bash -c '...$(cat <<'EOF' ... EOF)...'`-style PR-body payload uses diff --git a/.claude/notes/skill-design.md b/.claude/notes/skill-design.md index 92c2cca5..bf49ad78 100644 --- a/.claude/notes/skill-design.md +++ b/.claude/notes/skill-design.md @@ -3,6 +3,27 @@ Lessons specific to authoring `.claude/skills//SKILL.md` files and related workflow scaffolding. Newest-first. +### Orchestrate multi-phase skills directly, not through plugin $ARGUMENTS + +Routing a skill's full prompt body through a plugin command's +$ARGUMENTS blows the Claude Code permission classifier when the +prompt grows past ~17 KB ("parser timeout, resource limit, or +over-length"). The original `pr-review-loop` skill delegated its +5-phase workload to a plugin's setup script and hit this wall in +real use; PR #73 dropped the dependency and re-routed the phases +to direct Agent-tool dispatches. + +For any new multi-phase skill with a large prompt body, orchestrate +inline. Plugin delegation remains fine when `$ARGUMENTS` stays well +under ~1 KB and the protocol is well-typed (small command + flags); +this lesson is about the multi-phase-with-large-prompt shape that +hits the classifier wall, not plugins in general. If a plugin is +the right shape but the prompt is heavy, pass it by file path — +never the whole body as one positional arg. + +Anchor: PR #73 commit `6ed4fa8`, `.claude/skills/pr-review-loop/SKILL.md` +"How the loop runs" section. + ### Mechanism-test a skill before declaring it ready Manual walkthrough of a multi-step skill protocol misses substitution