feat: validation-gate hook blocks done without validation proof #229
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/claude-custom!229
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "210-validation-gate-hook"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds a PreToolUse hook that enforces the right-side kanban gate: items cannot move to "done" without a passing validation note in pal-e-docs. Also updates the post-merge hook to route items to the "validation" column instead of "done".
Changes
hooks/gate-validation-done.sh(NEW) -- PreToolUse hook that interceptsupdate_board_itemandbulk_move_board_itemscalls targeting "done". Queries pal-e-docs forvalidation-{issue-num}-*notes withpasstag. Denies if none found. Handles both single and bulk moves. Fails open on network errors and for items withoutforgejo_issue_url.settings.json-- Addedgate-validation-done.shto the existingupdate_board_item|bulk_move_board_itemsmatcher's hooks array (alongsidecheck-board-advance.sh).hooks/board-item-on-merge.sh-- Changed target column from"done"to"validation". Updated all comments and fallback messages to reflect the new target.Test Plan
echo '{"tool_name":"mcp__pal-e-docs__update_board_item","tool_input":{"board_slug":"board-pal-e-agency","item_id":123,"column":"in_progress"}}' | bash hooks/gate-validation-done.shsettings.jsonparses as valid JSONbash -nReview Checklist
Related Notes
sop-board-workflow-- defines the validation column semanticstemplate-validation-- defines the validation note format the hook checks forRelated
forgejo_admin/pal-e-api#223(validation column enum)/validate-ticketskill (tracked separately)Add PreToolUse hook that intercepts update_board_item and bulk_move_board_items calls targeting the "done" column. The hook queries pal-e-docs for a validation note (validation-{issue-num}-* with pass tag) and denies the move if none exists. Items without a forgejo_issue_url fail open (note-type items are not gated). Also updates board-item-on-merge.sh to route merged items to the "validation" column instead of "done", ensuring every item passes through the validation gate before completion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>PR #229 Review
DOMAIN REVIEW
Tech stack: Bash shell hooks + JSON (settings.json). Reviewing against shell scripting best practices, hook architecture patterns established in this repo (specifically
check-board-advance.shas the reference implementation), and fail-open safety requirements.gate-validation-done.sh (NEW, 200 lines)
The hook follows the established patterns from
check-board-advance.shclosely and correctly:set -eo pipefail+trap 'exit 0' ERR+command -v jq &>/dev/null || exit 0-- identical to the reference hook. Correct.if [[ "$TARGET_COLUMN" != "done" ]]; then exit 0). No false positives on non-done column moves. Correct.forgejo_issue_urlfail open (line 114 inextract_issue_num_from_item). Correct -- note-type board items are not gated.|| exit 0/|| return 1patterns. Correct.GET /notes?tags=validation,passthen filters by slug prefixvalidation-{issue-num}-*. This is a two-step filter (API tag filter + local slug prefix match) which is sound and avoids false positives from unrelated validation notes.--argjsonused for numeric IDs coming from.idfields -- consistent withcheck-board-advance.shpattern.board-item-on-merge.sh (MODIFIED)
All 7 occurrences of "done" correctly changed to "validation":
'{"column": "validation"}'additionalContext-- also adds helpful guidance about creating validation notes. Good UX for the agent.settings.json (MODIFIED)
The new hook is appended to the existing
mcp__pal-e-docs__update_board_item|mcp__pal-e-docs__bulk_move_board_itemsmatcher's hooks array, alongsidecheck-board-advance.sh. No duplicate matcher entry created. Both hooks fire on the same events --check-board-advance.shgates left-side transitions (backlog->todo, todo->next_up), andgate-validation-done.shgates the right-side transition (validation->done). They are complementary and non-overlapping in their target columns.BLOCKERS
None.
NITS
Unused
boards-config.shsource (line 30 ofgate-validation-done.sh): The hook sourcesboards-config.shbut never references theBOARDSarray. The board slug comes fromtool_input.board_slugin both the single and bulk code paths. This is harmless (the source just defines an array variable) but is dead code. The reference hookcheck-board-advance.shalso does not sourceboards-config.sh, so this is inconsistent with the pattern. Consider removing the source line and the shellcheck directive on line 29.ITEMS_PARAMstringification (line 148 of the new hook):jq -r '.tool_input.items // empty'-- when.tool_input.itemsis a JSON array,jq -routputs the raw JSON representation (same as without-rfor non-string types). This works, but-ris semantically for "raw string output" and is misleading on array values. This is a pre-existing pattern fromcheck-board-advance.shline 149, so not introduced by this PR -- just noting for awareness.SOP COMPLIANCE
210-validation-gate-hookfollows{issue-number}-{kebab-case-purpose}conventionfeat: validation-gate hook blocks done without validation proof)PROCESS OBSERVATIONS
forgejo_admin/pal-e-api#223(validation column enum) as a dependency. This hook will deny moves to "done" once deployed, but the post-merge hook needs the API to accept "validation" as a valid column value./validate-ticketskill is noted as discovered scope and tracked separately. Good discipline.VERDICT: APPROVED