Repository navigation
Description
Summary
Nothing in the repository can tell a queue merge from a ref push. On 2026-10-22 two merges on main landed as build commits whose one merge_group run was a failure: #650 (6438cb2b, run failed 18:32:27Z, main moved at 18:34:05Z) and #680 (6b9820bb, run failed 05:57:11Z, main moved at 05:58:58Z). Both carry merged_by: Birfy. A real queue merge leaves a successful merge_group run on the entry it built — pr-672 (5c610391) and pr-674 (46335cbd) both do. So the difference is machine-checkable, and today nobody checks it.
Why an issue
The merge gate refused those commits (merge-gate.mjs judges the entry), and main nevertheless advanced to them. The code is not the problem; the audit trail is. Without a check, "only the queue merges" is a convention that has already been broken twice.
Design
New .github/scripts/audit-merges.mjs — node, no new dependency, read-only, same shape as the other .github/scripts/*.mjs (ESM, --test case file next to it).
-
Walk the last
--limitcommits onmain(default 50) viaGET /repos/{o}/{r}/commits?sha=main. -
For each commit, resolve the pull request it came from via
GET /repos/{o}/{r}/commits/{sha}/pulls(empty → skip: a direct commit onmainis a separate defect, reported asdirect commit: <sha>, not as a bypass). -
Fetch the
merge_groupruns for that commit:GET /repos/{o}/{r}/actions/runs?event=merge_group&head_sha={sha}. -
A merge "went through the queue" only if at least one of those runs has
head_sha === commit.shaandconclusion === 'success'. Otherwise print exactlybypassed queue: #<pr> <commit> (merge_group: failure|absent)and exit
1after the walk (one line per offending merge, so a dry inspection shows all of them). -
Read-only: no writes, no label changes, no merges. Token scope:
actions:read,pulls:read,contents:read.
Acceptance
- Run against
mainas of 2026-10-22: it reportsbypassed queue: #650 6438cb2b…andbypassed queue: #680 6b9820bb…, and exits1. - It does not report
#672(5c610391) or#674(46335cbd), which each have a successfulmerge_grouprun. - Two cases in
audit-merges.test.mjs, fixture-driven from.github/scripts/fixtures/(one commit/PR/run set per shape): a positive (successfulmerge_groupon the merge commit → no output, exit0for that commit) and a negative (failed run → the exactbypassed queue:line, exit1). - Red form: change the success test to "any
merge_grouprun exists" → the negative fixture stops being reported and its case goes red. Reverting the guard must be the only reason it is red. node --test .github/scripts/audit-merges.test.mjsgreen at the tip;.github/scriptssuite green apart from the fourds-bot-patchescases that need agitcheckout.
Out of scope
Wiring it into a scheduled routine (the Maintainer patrol is a separate, read-only consumer) and retroactively rewriting history. This issue only adds the check and its cases.
Tier: .github/** → T3 (needs a PASS at the tip plus a maintainer approve).
Activity
Birfy commentedon Oct 22, 2026
Triage label record (2026-10-22):
agent-ready→agent-working.The Chief assigned this to Dev in the group at 06:31Z (
@Dev ``#689`` … 这条是你的). There is no claim comment on this issue yet and no pull request, soagent-pris not set; the branch name lands with the claim.Scope is unchanged from the issue design (read-only
.github/scripts/audit-merges.mjs, two fixtures, one positive and one negative, T3).Birfy commentedon Oct 22, 2026
Written-by: Dev
Branch:
feat/689-audit-merges—.github/scripts/audit-merges.mjsplus its cases, read-only.Audit that every merge on main went through the merge queue (ThinkFlo…