docs(merge-gate-watcher): an empty run list satisfies "everything finished" - #346
Conversation
…ished"
A tag push or a merge does not create the workflow runs at once. For a second
or two the runs endpoint answers {"workflow_runs": []} for a SHA that will
carry several, so a loop asking "does any run have a status other than
completed" is vacuously true on its first tick and returns a settled verdict
for work that has not started.
The extracted-value guard documented one section above does not cover it: the
extraction succeeds, it just yields a count of zero from an honest empty list.
The reflex repair -- "and the list is not empty" -- is the part worth writing
down, because it looks correct and is not. As a SECOND API call the two
conditions describe two different instants: the runs appear between them, the
first sees none unfinished because it sees none at all, the second sees them
and reports non-empty, and the loop exits on its first pass. Observed
2026-09-22 on netresearch/ldap-manager v1.7.0, where the loop returned
instantly and printed a queued and an in_progress run as its result.
Both facts must come from one response. The jq predicate given is verified in
both directions against the live API -- true for the settled commit, false for
a SHA with no runs -- and the section closes on the better tool where the
workflow is known: resolve the run id once and `gh run watch <id>
--exit-status`, which fixes the subject and carries the conclusion in its exit
code.
Learning-Id: retro-20260922-empty-run-list-watcher
Assisted-by: claude-code:claude-opus-5
Agent-Session: https://claude.ai/code/session_013GWpRpyiM13Rh1NMQMBJo5
Agent-Host: 0493f0
Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe watcher documentation now prevents empty run lists from causing premature completion. It derives non-empty and all-completed checks from one API response. For known workflows, it resolves the specific run ID, uses Priority: ⬇️ Low Change: Other Merge Risk: ⚪ Minimal · up to This documentation-only change clarifies safe workflow-run monitoring and introduces no production behavior change. It is ready to merge. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
Self-review: 4160133 The bot review this pull request demands is unsatisfiable (Copilot quota wall or repeated bot failures on this head). The diff on this head was reviewed by the PR author; this comment is the on-the-record attestation the merge gate reads back. It stops matching on the next push. |



Merging this adds one subsection to
references/merge-gate-watcher.md, on a watcher that reports "settled" before the runs it watches exist. Documentation only; no script changes.The defect
A tag push or a merge does not create the workflow runs at once. For a second or two
actions/runs?head_sha=...answers{"workflow_runs": []}for a SHA that will carry several. A loop asking "does any run have a status other thancompleted" is therefore vacuously true on its first tick: it exits immediately and reports a settled verdict for work that has not started.The extracted-value guard one section above does not cover this. That one is about an extraction that comes back empty; here the extraction succeeds and yields a count of zero from an honest empty list.
Why the obvious repair is the part worth writing down
Adding "and the list is not empty" looks correct. As a second API call it is not: the two conditions describe two different instants, the runs appear between them, and both pass. The diff shows the shape.
Observed 2026-09-22 on
netresearch/ldap-managerv1.7.0 - the loop returned on its first pass and printedRelease: nullandCI: nullas its result, which are aqueuedand anin_progressrun.What the section says to do instead
Take both facts from one response, with the predicate in a single jq expression. Verified in both directions against the live API while writing it:
truefor the settled commita5e669f,falsefor a SHA with no runs. Then, where the workflow is known, the better tool - resolve the run id once and hand it togh run watch <id> --exit-status, which fixes the subject and carries the conclusion in its exit code. The id-resolution snippet guards on an empty and anullid before it is used.Not touched
Every other section of the file, including the
head_sha=server-side filter above it and the extracted-value guard it builds on. No script, nopr-status.shbehaviour.Assisted by claude-code:claude-opus-5 - Session