From 97e87271cc8092f0cf5f72b08bc3433253f78adb Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 30 Jul 2026 10:16:04 -0500 Subject: [PATCH] fix(hybrid-gate): resolve the trailer tip on push events, not just pull_request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit check-trailer read `github.event.pull_request.head.sha` unconditionally. That context is populated on pull_request events only, so on a push the variable is empty and `git log -1 --format=%b ""` exits 128. The step dies before writing its `found` output, full-gate-build never runs because its `if:` reads that output, and the gate job fails with none of its three success conditions met. Regression from the #2399 tip-binding fix, which correctly stopped an ancestor's trailer riding through to a green check but referenced a PR-only context without a push fallback. The same file already guards this exact hazard twice — the docs-only and ai-attribution steps each carry a BASE_REF -> EVENT_BEFORE -> HEAD~1 chain with a WHY comment saying every push to a default branch failed the gate. This restores that pattern in the one place it was missed. #2399's property is preserved: on a pull_request the tip is still head.sha; on a push, HEAD is the tip. Surfaced by aletheia, the only consumer whose caller adds `push: branches: [main]` alongside `pull_request:` — every other consumer triggers on pull_request only and never reaches the empty variable. --- .github/workflows/hybrid-gate.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/hybrid-gate.yml b/.github/workflows/hybrid-gate.yml index 9891327..8d16cfd 100644 --- a/.github/workflows/hybrid-gate.yml +++ b/.github/workflows/hybrid-gate.yml @@ -235,9 +235,17 @@ jobs: # WHY: head.sha reaches the script via env, not shell interpolation. PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | - body=$(git log -1 --format="%b" "$PR_HEAD_SHA") + # WHY the fallback: github.event.pull_request.* is populated on + # pull_request events ONLY. On a push, PR_HEAD_SHA is empty and + # `git log -1 --format=%b ""` dies with exit 128, which crashes this + # step before it writes `found` and fails the whole gate — the same + # event-shape hazard the docs-only and ai-attribution steps above + # already guard with their own fallback chains. On a push, HEAD IS + # the tip, so #2399's tip-binding property is preserved either way. + tip="${PR_HEAD_SHA:-HEAD}" + body=$(git log -1 --format="%b" "$tip") if echo "$body" | grep -q "^Gate-Passed:"; then - echo "Found gate attestation on PR tip: $(echo "$body" | grep '^Gate-Passed:' | head -1)" + echo "Found gate attestation on tip ($tip): $(echo "$body" | grep '^Gate-Passed:' | head -1)" found=true else found=false