ship-queue verify: build the freeze record from the one GitHub read that decided to freeze

freezeQueue took a second prState read per unverified slot and filed anything
but an exact MERGED under unmerged, so a slot that read MERGED at stopped()
and was unreadable a moment later was recorded as unmerged (the record half of
train 24's #3453 misfile). stopped() now reads each unverified slot once and
passes those states in; a MERGED slot stays merged, and a slot unreadable
beside a merged one is kept out of unmerged and named in the reason. The
fixture's gh shim gains a per-PR vanish count so a test can change GitHub's
answer between two reads.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-27 17:16:07 +00:00
1 parent 73a678eb89
commit 5905c768f7
6 files changed
+49 -13

No files matched your search

+5 -1
View File
@@ -620,7 +620,11 @@ backstop run. A slot GitHub reports MERGED counts as merged in that record,
verified tree or not, so the rebuild after the repair never seats it again
(the reason says "merged on GitHub without a verified tree"); a first slot
whose squash GitHub reports MERGED but whose tree fails the post-merge check
freezes the same way, since main already holds the unverified squash. When
freezes the same way, since main already holds the unverified squash. The
record comes from the one GitHub read that decided to freeze, never a second
one: a slot that read MERGED stays merged even when GitHub stops answering
before the record is written, and a slot unreadable beside a merged one is
kept out of `unmerged` and named in the reason until it can be read. When
whether a slot merged on GitHub cannot be read, verify refuses
(`QUEUE_PROOF_MISSING`, "whether #<n> merged on GitHub could not be read")
and asks to be rerun once `gh pr view` answers; an unreadable state is never
+6 -1
View File
@@ -4349,7 +4349,12 @@ prefix no gate covered on its own. The `QUEUE_TRAIN_FROZEN:` line lists the
merged PRs (a slot GitHub reports MERGED counts as merged, verified tree or
not, and the reason then says `merged on GitHub without a verified tree`, so
the repair's rebuild never seats it again), main's tree and the backstop run
dispatched on main's SHA. The
dispatched on main's SHA. The record is built from the one GitHub read that
decided to freeze: a slot that read MERGED stays merged even when `gh pr view`
stops answering a moment later, and a slot whose state could not be read when
another slot had merged is kept out of `unmerged` and named in the reason
(`#<n> unreadable on GitHub, kept out of unmerged until read`), so the
rebuild after the repair never seats a PR that may already be in. The
freeze lives in local state and on `refs/notes/gstack-trains`. Ordinary
trains and other trains' merges are refused until a repair lands.