Skip to content

ci: let the merge queue reuse a PR run of the exact same content - #605

Merged
yaacovcorcos merged 4 commits into
mainfrom
claude/ci-pr-queue-reuse-20261019
Oct 19, 2026
Merged

yaacovcorcos merged 4 commits into
mainfrom
claude/ci-pr-queue-reuse-20261019

Conversation

@yaacovcorcos

Copy link
Copy Markdown
Contributor

Problem

A queue entry runs the full CI matrix (about 25–45 minutes, and one of the queue's two build slots) even when its PR's own CI just passed on exactly the same content. Separately, #582's main-push reuse refused whenever several queue entries landed in one push: #597 and #598 landed together, so #598's push ran full CI with "Qualification receipt differs".

Resulting behavior

  • Queue reuse. A merge_group run reuses the PR's passing run only when that run tested the same content (tree) against the same base, its workflow ran from that tested merge, and the PR head already holds that content. In practice: the PR contained the latest main when its CI ran, nothing landed since, and nothing is queued ahead. The probe checks, via the API, that the queue commit merges exactly that PR head onto the group base and that the PR run's tested merge has the same tree and parents. It then republishes the run's seven reports.
  • Why the PR head must hold the content. Then the merge changes nothing, so Compute recipe sealing's path-limited git log follows the PR head and never a merge commit, whose timestamp differs between the PR's test merge and the queue's.
  • Required shard names. A matrix job skipped as a whole reports one unexpanded name, never Test Web 1–3 or Test Server 1–3. A reusing queue run therefore adds small jobs that report those required names.
  • PR receipts. Same-repository PR runs record a qualification receipt (schema 2: event, tested merge, base, tree). Fork PRs never do.
  • Multi-entry pushes. A main push reuses when each queue entry it lands qualified that exact commit from its first parent, back to the previous main, up to the queue's four-entry merge limit.
  • Mobile gate. It now diffs the event's base against the tested commit with Git on every event, like the compute and packaging gates, instead of a PR's live file list. That list could change during a run, and the API capped it at 300 or 3,000 files. It matches raw bytes, so newline or non-UTF-8 filenames can't hide a native source.
  • Fallback. Any missing, expired or mismatched evidence still runs normal CI.

Expected effect: of the last 27 merged PRs with a passing run on their final head, 6 met the queue condition (13 had an unchanged main, but only 6 of those also contained it). More PRs qualify when the latest main is merged into the branch before the final push.

Verification

  • node --test .github/scripts/ci-queue-reuse.test.cjs: 84 pass. The tests cover:
    • the queue path, two-entry and four-entry pushes, and one past the merge limit;
    • every mismatch and failure path refusing reuse without partial reports;
    • PR and queue receipts;
    • the workflow structure, including the stand-in shard names;
    • a behavioral test that runs the mobile gate's own script against commits built with Git plumbing.
  • Mutation checks: removing each of nine guards fails at least one test. Reverting the gate's newline mapping, byte matching or --no-renames each fails the behavioral test.
  • Real objects: PR test(server): keep server tests out of the source checkout #601's test merge has parents [main at test time, PR head]. Queue commit c145ae778f has parents [queue base, fix(citations): build each citation style's engine once #598 head].
  • Gate script on real commits: a ci.yml change and a Swift change report changed=true; a docs-only commit reports changed=false; a native rename reports true with both paths; a bad base fails open.
  • vp fmt --check, vp lint on the scripts, YAML parse, and git diff --check pass.
  • Not yet observed on hosted CI: a reusing queue run. This PR's own run will be the first to write a PR receipt, which checks that GITHUB_WORKFLOW_SHA equals the tested merge on pull_request. If GitHub reports another value, reuse simply never applies.

Independent review: Codex gpt-6.1-sol, five rounds. Round 1 found the mobile-gate and recipe-timestamp gaps, round 2 the live PR file list and the workflow binding, round 3 newline filenames, and round 4 non-UTF-8 filenames. Each was fixed in this branch. Round 5 approved, with no remaining P0–P2.

Documentation impact

Updated — docs/internals/ci.md (reuse rules, required shard names, mobile gate comparison).

Model and harness: Claude Opus 5.5 in Claude Code (Scient), with Codex gpt-6.1-sol as independent reviewer.

🤖 Generated with Claude Code

Yaacov and others added 4 commits October 19, 2026 18:34
A queue entry ran the full matrix even when its PR's CI had just passed on
the same content. Now a merge_group run reuses that PR run when it tested
the same tree against the same base and the PR head already holds that
tree: the PR contained the latest main when its CI ran, nothing landed
since, and nothing is queued ahead. Then the merge changes nothing, so the
PR's changed-file list equals the queue's diff for every change gate, and
Compute recipe sealing's path-limited history read follows the PR head,
never the merge commit, whose timestamp differs between the two merges.

- Same-repository PR runs record a qualification receipt (schema 2: event,
  tested merge commit, base, tree). Fork PRs never do.
- The queue probe checks the queue commit merges exactly that PR head onto
  the group base, and that the PR run's tested merge has the same tree and
  parents, then republishes its seven reports.
- A matrix job skipped as a whole reports one unexpanded name, so reusing
  queue runs add small jobs that report the required Test Web N and Test
  Server N names.
- A main push that lands several queue entries now reuses when each entry
  qualified from its first parent back to the previous main, up to the
  queue's four-entry merge limit. Before, #597 and #598 landing together
  made #598's push run full CI ("Qualification receipt differs").

Any missing, expired or mismatched evidence still runs normal CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a PR the mobile gate read the PR's live file list while the reuse receipt
records the run's original base and tested merge. Retargeting a PR during a
run could change that list, so the queue could reuse a run whose mobile lint
was skipped for content the queue would lint. It now diffs the event's base
against the tested commit with Git, like the compute and packaging gates, on
every event. This also drops the API's 300 and 3,000 file limits.

Reuse now also requires the PR run's workflow to come from its tested merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Turning Git's NUL-separated paths into lines split a filename containing a
newline in two, so a native source with such a name skipped mobile lint. An
embedded newline now becomes `?`. A behavioral test runs the gate's own
script on commits built with Git plumbing: unrelated, native, renamed into
and out of the native paths, a newline filename, and unresolvable bases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In the hosted runners' UTF-8 locale, grep's `.` does not match a byte that
is not valid UTF-8, so a native source whose name contains one could skip
mobile lint. The gate now matches in the C locale. Its behavioral test
commits raw-byte filenames through stdin and runs under C.UTF-8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.6 KiB 5.6 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 4.3 KiB 4.3 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.3 KiB 1.3 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 26.2 KiB 26.2 KiB 0 B (0.0%) 29.3 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.6 KiB 5.6 KiB −36 B (−0.6%) 6.8 KiB ✅
Claude Thread snapshot wire 4.3 KiB 4.3 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.3 KiB 1.3 KiB −36 B (−2.6%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 26.6 KiB 26.5 KiB −41 B (−0.2%) 29.3 KiB ✅
Claude Live turn messages 2 1 −1 (−50.0%) 8 ✅

Baseline: 129f4af · PR result: 6e16191 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Full compact HTTP snapshot with live cursor.

  • Codex decoded thread snapshot: 133.1 KiB
  • Claude decoded thread snapshot: 133.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@yaacovcorcos
yaacovcorcos added this pull request to the merge queue Oct 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 19, 2026
@yaacovcorcos
yaacovcorcos added this pull request to the merge queue Oct 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 19, 2026
@yaacovcorcos
yaacovcorcos added this pull request to the merge queue Oct 19, 2026
@yaacovcorcos
yaacovcorcos removed this pull request from the merge queue due to a manual request Oct 19, 2026
@yaacovcorcos
yaacovcorcos added this pull request to the merge queue Oct 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 19, 2026
@yaacovcorcos
yaacovcorcos added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit c2ff6eb Oct 19, 2026
77 of 79 checks passed
@yaacovcorcos
yaacovcorcos deleted the claude/ci-pr-queue-reuse-20261019 branch October 19, 2026 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant