Review: Convention: PreToolUse hook matchers must use separate entries, not pipe-separated
Verdict: READY
Template Completeness
- [x] Lineage — present (discovered scope from GroupMe incident remediation)
- [x] Repo — present (forgejo_admin/claude-custom)
- [x] User Story — present (As platform operator...)
- [x] Context — present (detailed finding with root cause and cost)
- [x] File Targets — present (settings.json + convention note, plus NOT-touch list)
- [x] Acceptance Criteria — present (4 checkboxes)
- [x] Test Expectations — present (manual test noted, N/A for automated)
- [x] Constraints — present (3 constraints: PostToolUse OK, only ask affected, may be Claude Code bug)
- [x] Checklist — present
- [x] Related — present (references #160, #164, project-pal-e-agency)
Note: Issue uses "### Type" header (Feature) which is not in the template but is used by check-issue-template.sh for type detection. Harmless addition.
File Targets
- [x]
settings.json— verified exists at~/claude-custom/settings.json(symlinked to~/.claude/settings.json) - [x] GroupMe matchers already split — verified: lines 113-137 show three separate entries for
mcp__groupme__send_message,mcp__groupme__add_member,mcp__groupme__remove_member(fix already applied during incident) - [x]
Write|Edit|NotebookEditpipe-separated matcher (line 91) — verified: hooks returndenyorexit 2, neverask. NOT affected by this bug. No split needed. - [x]
mcp__forgejo__create_issue|mcp__forgejo__create_issue_and_branchpipe-separated matcher (line 158) — verified: hooks returndenyorallow, neverask. NOT affected by this bug. No split needed. - [x] Convention note
convention-hook-matcher-pattern— to be created in pal-e-docs (new artifact, not a file modification)
Repo Placement
OK. The settings.json audit belongs in
forgejo_admin/claude-custom, which is where the Forgejo issue is filed. The convention note creation is a pal-e-docs write (via MCP tool), not a file in the repo. Single-repo scope is correct.Dependencies
claude-custom#160(GroupMe incident fix) — CLOSED. The immediate fix (splitting GroupMe matchers) is already merged. This ticket documents the convention and audits remaining matchers.claude-custom#164(auto-pull hook) — CLOSED. Related but independent — ensures hooks stay current across sessions.- Board item #357 (
claude-custom#160, story:GM-5, type:incident-fix) — indonecolumn. No blocking dependency. - Board item #375 (
claude-custom#164) — indonecolumn. No blocking dependency. - No items in
in_progressornext_upblock or are blocked by this ticket.
Acceptance Criteria
All 4 acceptance criteria are verifiable:
- [x] "All PreToolUse matchers that return permissionDecision: ask use separate entries" — agent can grep settings.json for pipe-separated matchers and cross-reference with hook scripts returning "ask". Audit already done in this review: only remaining pipe-separated matchers (Write|Edit|NotebookEdit and create_issue|create_issue_and_branch) do NOT return "ask", so they pass.
- [x] "Convention note convention-hook-matcher-pattern created" — agent can verify via get_note(slug="convention-hook-matcher-pattern")
- [x] "Convention documents the specific failure mode" — verifiable by reading note content
- [x] "Existing pipe-separated PreToolUse matchers audited" — the audit result is already known: 2 pipe-separated matchers remain, neither uses "ask", both are safe
Test expectations are manual (session-level verification in bypass mode). Appropriate for a convention + config change.
Blast Radius
- SubagentStart matcher uses pipes too —
"qa|dev|general-purpose|dottie|penny"(line 278). This is NOT a PreToolUse hook and does NOT return "ask", so it is NOT affected. The ticket's constraints correctly scope this to PreToolUse + ask only. - PostToolUse matchers — None use pipes currently. The ticket correctly notes PostToolUse pipes "appear to work fine" and advises not splitting those unnecessarily.
- No sibling services affected — settings.json is a single global config. No other repos have their own hook matcher configs.
- Potential future risk — Any new PreToolUse hook added with pipe-separated matchers AND "ask" would silently fail. The convention note is the mitigation.
Recommendation
No action needed — scope is solid. The audit is already effectively complete (verified in this review). The remaining work is:
- Create the convention note in pal-e-docs
- Optionally add a comment to settings.json near the pipe-separated matchers noting they are safe because they don't use "ask"
Points (2) are appropriate for the remaining convention-note creation + minor config annotation work.