Validation: merge hook false positive (3 hooks parsing .tool_response.result)

validation-173-2026-03-27 Validation

validation pass

Verdict: PASS

Ticket

forgejo_admin/claude-custom#173 — Fix merge_approved_pr post-hook false positive: 3 hooks fail to parse MCP-wrapped tool_response.result

Environment

Local checkout: ~/claude-custom on main branch, commit a742d5f (PR #177 squash-merged). Validated after git pull brought local up to date.

Checks

# Criterion How Verified Result Evidence
1 Hook correctly detects merged: true in MCP response Read all 3 hooks — verified two-stage jq parsing PASS All 3 hooks now: (1) try <code>.tool_response.merged</code> directly, (2) if empty/null, try <code>.tool_response.result</code> piped through second jq for <code>.merged</code>. This handles both direct JSON and MCP-wrapped string responses.
2 Hook does NOT emit false positive failure on successful squash merge Traced logic: when MCP wraps response, first jq returns empty, fallback parses .result string and finds merged:true PASS The if-guard <code>[[ -z "$MERGED" || "$MERGED" == "null" ]]</code> correctly falls through to the .result parser when the direct path fails
3 Hook still correctly reports actual merge failures (405, 409, etc.) Traced logic: on real failure, neither path yields "true", so MERGED != "true" triggers failure branch PASS remind-update-docs.sh emits failure message; post-mcp-merge-rebase.sh silently exits; board-item-on-merge.sh silently exits — all correct per their roles
4 All 3 hooks have identical parsing pattern diff between the 5-line jq parsing blocks across all 3 files PASS remind-update-docs.sh (lines 20-24), post-mcp-merge-rebase.sh (lines 12-16), board-item-on-merge.sh (lines 36-40) are character-identical
5 Pattern matches label-on-pr.sh reference implementation Read label-on-pr.sh lines 30-35 PASS label-on-pr.sh uses same .tool_response.result fallback pattern (line 34). The merge hooks adapted this pattern for the .merged field specifically.

Regression Check

All other functionality in the 3 hooks is unchanged:
  • remind-update-docs.sh: success/failure message injection unchanged (lines 26-42)
  • post-mcp-merge-rebase.sh: git fetch, update-ref, worktree detection all unchanged (lines 18-62)
  • board-item-on-merge.sh: PR fetch, branch parsing, board search, item move all unchanged (lines 46-144)

Discovered Issues

None.