gh shim: bot pr enqueue/dequeue for its own PRs (manifest v23)

Merged
AF
1d ago
+1533-80

Bot merge-queue support for the bot's own pull requests, behind manifest v23. Nothing changes until a signed v23 manifest is active; under v22 the shim never sends these actions (tested).

  • Add to the queue: gh pr merge <number or URL> --match-head-commit <40-hex sha> (with or without --auto, no direct-merge or admin flags) maps to Plexus pr enqueue pinned to that head. The shim never fetches the head itself and never sends a direct merge in its place, even on a repo without a merge queue.
  • Remove from the queue: gh pr dequeue <number or URL>, a shim-only command, because upstream gh has none (--disable-auto calls disablePullRequestAutoMerge, cli/cli pkg/cmd/pr/merge/http.go:106-119). --disable-auto keeps its existing classification.
  • Refused: jump (operator-only), a missing or malformed sha, extra flags, more or fewer than one PR. Worker shells refuse every write, these included, with the approved worker text.
  • Contract: Plexus's request and reply vectors at plexus 3a702b4dc39eca2013407c8bed82b2adc5bc968b vendored byte-for-byte with per-file sha256 provenance; every request vector is judged and every reply round-trips through the real shim.
  • Manifest: scripts/prepare-gh-shim-v23.py builds the unsigned v23 draft from the signed v22 payload (sha256 pinned): v22 plus the two governed rows for macOS and Linux, version 22 to 23. Nothing is signed or activated here.

The five new refusal texts wait on Ufuk's approval; this PR stays out of the merge queue until then. Verified on the build server: 552 gh_shim library tests and the Windows target check.


Summary by cubic

Adds merge-queue support for the bot's own pull requests to the gh shim, behind a not-yet-signed manifest v23. Under v22 and unsigned manifests behavior is unchanged; the shim never routes these actions until a signed v23 draft is installed.

  • gh pr merge <number> --match-head-commit <40-hex sha> (optionally --auto) maps to Plexus pr enqueue pinned to that head; direct merges, --admin, and --disable-auto keep their existing classifications.
  • Adds the shim-only gh pr dequeue <number> (upstream gh has no dequeue command); without a signed v23 declaration it stays an unclassified passthrough.
  • Refuses jump, missing or malformed SHAs, extra flags, and more or fewer than one PR; worker shells refuse every write.
  • Vendors Plexus's 159 request vectors byte-for-byte with sha256 provenance, runs all 27 reply vectors through the real shim (queue replies now included), and adds CLI golden tests plus a preparer script that builds the unsigned v23 draft from the reviewed v22 baseline.

Relay robustness

  • Governed writes now wait 160 s for Plexus's reply (120 s claim lease plus vendor timeout and margin) under a 210 s exchange ceiling; reads keep their short budget.
  • Only transport_unknown and lease_expired pre-read failures retry once with the same nonce; a not_sent refusal is safety evidence, not a retry policy, and uncertain writes are never resent.
  • Unreachable preflight and binding-read failures retry once after 4 s; the queue rows are declared only on the v22 platforms (macos, linux).

Migration
No signed or installed manifest is produced here; scripts/prepare-gh-shim-v23.py only writes an unsigned draft and digest. Two relay refusal goldens (enqueue-not-own and enqueue-without-a-queue) now carry main's approved refusal wording; the five queue-parser refusal texts still await approval before merge.