---
name: two-runs-per-sha-notification-trap
description: A CI failure notification can cite a DIFFERENT run than the one you dispatched — push and workflow_dispatch both fire the golden workflow at the same sha; check the run id and the event before triaging.
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 4dc44016-b3d5-40c6-a592-a99f070b1e1a
  modified: 2026-08-02T04:33:07.989Z
---

Pushing a golden head fires the `golden` workflow on `push`, and dispatching it fires the SAME workflow again on `workflow_dispatch`. Both run at the same sha, created seconds apart. The CI notifier reports whichever fails — which may not be yours.

2026-08-01, DOORBELL head 13e94d5: CI-KITSUBITO reported failure on run 30720655534. The run I dispatched (twohost=true) was 30720656689. Different run, same sha, two seconds apart. Triaging the notified one as if it were mine would have attributed a red to the wrong instrument and, worse, hidden that the authoritative run had not reported yet.

**How to apply:** before triaging any CI failure notice, run `gh run view <id> --json workflowName,event,headSha,headBranch` and confirm `event` and the run id match what you dispatched. A `push` run is incidental auto-CI; the `workflow_dispatch` run with your inputs is the one that gates. Inputs differ between them (twohost=true was only on mine), so their results are not interchangeable even when both are the same workflow at the same sha.

Corollary for the green gate: a job that is ABSENT is not a pass. Gate on every job present BY NAME and completed-success — a missing two-host leg means untested-on-that-seam, not passing. See [[gh-run-poll-jobs-not-status]].

**SUPERSEDED IN PART (2026-08-01, v0.51.0, doyle-ruled on deployah's structural find):** the "workflow_dispatch run is the one that gates" sentence above is retired. golden.yml's twohost condition (`event != 'workflow_dispatch' || inputs.twohost`, lines 598/677 at 65d2c98) means a PUSH runs ALL nine jobs including both twohost legs — the dispatch input only ever subtracts, and only on dispatch. So push+dispatch at one sha are job-identical and the dispatch is a duplicate full window (they queue serially: concurrency `golden-<ref>`, cancel-in-progress false). **Standing rule: the PUSH run IS the golden run** — pin its id at push time (`gh run list --commit <sha> --event push`) and gate on that id. Reflexive dispatch is dropped from the runbook; dispatch remains for no-new-push same-sha reruns (post-red triage) and deliberate twohost=false isolation. Cancelling a zero-job queued duplicate destroys no evidence (ADR-0050 protects earlier evidence from later runs). Codified in releases#105 with the golden.yml line citations as load-bearing.
