Review: Convention enforcement
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] ### Type — Feature
- [x] ### Lineage
- [x] ### Repo
- [x] ### User Story
- [x] ### Context
- [x] ### File Targets
- [x] ### Acceptance Criteria
- [x] ### Test Expectations
- [x] ### Constraints
- [x] ### Checklist
- [x] ### Related
Traceability
- [x] story:pm-scope label — PM scoping story
- [x] arch:enforcement label — enforcement architecture component
- [x] Forgejo issue — forgejo_admin/claude-custom#166, open
File Targets
- [x]
settings.json— verified at~/claude-custom/settings.json. Contains the PreToolUse matchers described. - [ ] GroupMe matcher status — ISSUE: The ticket states the GroupMe entries are "already split (fixed during incident)" but they are NOT split. Line 103 still reads
"mcp__groupme__send_message|mcp__groupme__add_member|mcp__groupme__remove_member"as a single pipe-separated matcher. The agent implementing this will need to split them. - [x]
mcp__forgejo__create_issue|mcp__forgejo__create_issue_and_branch(line 130) — verified present. Returns"deny", NOT"ask". Per the Constraints section, only"ask"matchers are affected, so this one is safe. Issue body correctly identifies it as an audit target. - [x]
Write|Edit|NotebookEdit(line 81) — verified present. Returns"deny", NOT"ask". Safe per the same constraint. - [x] pal-e-docs convention note — to be CREATED as
convention-hook-matcher-pattern. Deliverable is clear.
Repo Placement
Issue filed on
forgejo_admin/claude-custom — correct for settings.json changes. The second deliverable (convention note in pal-e-docs) is created via MCP API, not a repo change, so single-repo placement is acceptable.Dependencies
- Board #357 (claude-custom#160, GroupMe incident) —
done. This is the incident that exposed the bug. No blocking dependency. - Board #375 (claude-custom#164, auto-pull hook) —
done. Related but not blocking. - Board #395 (claude-custom#167, story label upgrade) —
done. Related enforcement work, not blocking. - No active blockers found.
Acceptance Criteria
- [x] AC1: "All PreToolUse matchers that return permissionDecision: ask use separate entries" — Testable. Agent can grep for pipe + ask patterns.
- [x] AC2: "Convention note convention-hook-matcher-pattern created in pal-e-docs" — Testable via API.
- [x] AC3: "Convention documents the specific failure mode" — Testable by reading note content.
- [x] AC4: "Existing pipe-separated PreToolUse matchers audited" — Testable. The full audit is: only the GroupMe matcher (line 103) uses pipe + ask. The two deny matchers (lines 81, 130) are safe.
Criteria are testable and complete.
Blast Radius
- Agent config files (
agents/penny.md,agents/dottie.md,agents/qa.md) use pipe-separated PreToolUse matchers, but all return"deny", not"ask". The Constraints section correctly limits scope to "ask" matchers only. - PostToolUse matchers with pipes (e.g., line 185
mcp__forgejo__create_issue_and_branch) are explicitly excluded by the Constraints section. No blast radius concern. - SubagentStart matcher (line 246) uses pipe — this is neither PreToolUse nor returns "ask". Safe.
Recommendation
One factual error must be corrected before this is READY:
- Fix the GroupMe claim: The issue body says the GroupMe entries are "already split (fixed during incident)" — this is false. Line 103 of
settings.jsonstill has the pipe-separated matcher. Update the File Targets section to say the GroupMe matcher NEEDS splitting (not that it's already done). This is important because an implementing agent reading "already split" may skip the split and only audit the other two matchers.
Once that correction is made, verdict upgrades to READY. The scope is clean, all other targets are verified, and the work fits in a single agent pass.