From 09e42538a7c101002a4560db7428993aa36d6ae3 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Mon, 26 Oct 2026 10:22:09 -0700 Subject: [PATCH] quest: plan landing through a merge state GitHub is still computing Co-Authored-By: Claude Opus 5.5 --- quest/m0/helpers/README.md | 1 + quest/m0/helpers/merge-state-race.md | 42 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 quest/m0/helpers/merge-state-race.md diff --git a/quest/m0/helpers/README.md b/quest/m0/helpers/README.md index 95beb81f..5e26f6d5 100644 --- a/quest/m0/helpers/README.md +++ b/quest/m0/helpers/README.md @@ -62,6 +62,7 @@ commands from Sep-Oct. Session counts in each child come from that window. ## Required +- [Merge state race](/quest/m0/helpers/merge-state-race.md) - `--land` and merge jobs land a PR whose merge state GitHub is still computing, on the first try - [Landing rules](/quest/m0/helpers/landing.md) - land only heads that contain the current base, ask on a missing review, one design checkpoint - [Wait and status accuracy](/quest/m0/helpers/wait-accuracy.md) - wake on edited bot comments, honest `checks:passed`, review rounds in `quest status` - [Status holds](/quest/m0/helpers/status-holds.md) - `quest status` shows a PR's `quest:*` hold diff --git a/quest/m0/helpers/merge-state-race.md b/quest/m0/helpers/merge-state-race.md new file mode 100644 index 00000000..bee0a3b5 --- /dev/null +++ b/quest/m0/helpers/merge-state-race.md @@ -0,0 +1,42 @@ +# [S] Land through a merge state GitHub is still computing + +## Goal + +`quest merge --land ` and a kix merge job land a PR on the +first try while GitHub still reports its merge state as `UNKNOWN`. Each merges +at once when nothing is left to wait for and enables auto-merge otherwise, +always pinned to ``, and neither fails with "Pull request is in clean +status". Labels on merged PRs are out of scope. + +## Plan + +Decided 2026-10-26 (user), from the merge of +[kixelated/quest#222](https://github.com/kixelated/quest/pull/222): its first +`--land` failed with "Pull request is in clean status", and the same command +merged it on a re-run. `land()` in `src/cli/hold.ts` and `landPullRequest` in +`cloudflare/src/github/service.ts` each pick `mergePullRequest` only when one +read of `mergeStateStatus` is `CLEAN`, `HAS_HOOKS`, or `UNSTABLE`; a state +GitHub has not computed yet reads `UNKNOWN` and falls through to +`enablePullRequestAutoMerge`, which GitHub refuses for a clean PR. + +- **Retry on refusal (user).** Keep enabling auto-merge pinned to the head + when the state is not known to be immediate. When GitHub refuses it because + the PR is clean, re-read the state once and merge at once, still pinned to + the head, if it is now `CLEAN`, `HAS_HOOKS`, or `UNSTABLE`; otherwise report + the refusal. Rejected: re-reading while `UNKNOWN` (a timed poll), and trying + `mergePullRequest` first (an admin token merges past required checks). +- **CLI and Worker (user).** Fix both in this quest, sharing the decision + rather than keeping two copies of `IMMEDIATE` if the Worker can import it. +- **Labels stay (user).** A merged PR keeps its `quest:merge` label, as every + merged PR does today; no cleanup and no backfill. +- Test each path: an `UNKNOWN` state that GitHub refuses as clean merges at + once, an `UNKNOWN` state that accepts auto-merge stays on auto-merge, and a + refusal for any other reason is reported unchanged. +- [kixelated/quest#229](https://github.com/kixelated/quest/pull/229) adds a + gated branch to `land()` ahead of this choice; whichever lands second merges + the other in. + +## Related + +- [Landing rules](/quest/m0/helpers/landing.md) - also changes what `quest merge --land` refuses +- [Batched merge gate: quest land](/quest/m0/helpers/land.md) - gated bases always enable auto-merge, so this choice applies only to ungated ones