Skip to content

Commit ef0321a

Browse files
catomeanclaude
andauthored
fix(ci): drain the merge queue oldest-first, not newest-first (#275)
`gh pr list` returns newest-first, and the sweep merges the first eligible PR then stops. So the newest green PR wins every sweep, and an older one can wait indefinitely. Observed in maonakamoto/fleetcrown on 2026-08-06: two consecutive sweeps merged the two newest PRs while three older green ones sat untouched and were never even evaluated. With several agent sessions opening PRs continuously that is starvation — and it starves the worst candidate, since the longest-waiting PR is the one whose checks were proven against the most now-stale base. PR numbers increase monotonically with creation, so sorting ascending is FIFO. The ordering was never a decision, just whatever gh happened to return. Fixed upstream first (fleetcrown #182) and verified in production there: the sweep immediately after it landed correctly took the oldest open PR rather than the newest. This is that one-line change, applied to the fleet. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 3e0b81b commit ef0321a

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

scripts/ci/auto-merge-sweep.sh

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
# a red or pending PR simply waits, and a draft waits forever. To hold a ready
2121
# PR back, mark it a draft or add one of the hold labels below.
2222
#
23-
# ONE PR PER SWEEP, AND ONLY ONTO A GREEN BASE
24-
# --------------------------------------------
23+
# ONE PR PER SWEEP, OLDEST FIRST, AND ONLY ONTO A GREEN BASE
24+
# ----------------------------------------------------------
2525
# A PR's checks prove *that PR against the base it branched from* — not against
2626
# the other PRs sitting next to it. Merging a batch in one pass would put a
2727
# combination onto the base that nothing ever built. So this script merges at
@@ -98,7 +98,16 @@ fi
9898

9999
merged_any=0
100100

101-
for number in $(printf '%s' "$prs_json" | jq -r '.[].number'); do
101+
# OLDEST FIRST. `gh pr list` returns newest-first, and this loop merges the
102+
# first eligible PR and stops — so the newest green PR wins every sweep and an
103+
# older one can wait indefinitely. Observed in maonakamoto/fleetcrown on
104+
# 2026-08-06: two consecutive sweeps merged the two newest PRs while three
105+
# older green ones were never even evaluated. With several agent sessions
106+
# opening PRs continuously, "newest wins" is starvation, and it starves the PR
107+
# whose checks were proven against the most now-stale base.
108+
#
109+
# PR numbers increase monotonically with creation, so sorting ascending is FIFO.
110+
for number in $(printf '%s' "$prs_json" | jq -r 'sort_by(.number) | .[].number'); do
102111
pr=$(printf '%s' "$prs_json" | jq -c --argjson n "$number" '.[] | select(.number == $n)')
103112
title=$(printf '%s' "$pr" | jq -r '.title')
104113

0 commit comments

Comments
 (0)