Skip to content

Make Trunk merge-queue use mandatory on main — bypass merges reset in-flight batches and skip cross-PR testing #3027

Description

@phil-opp

Make Trunk merge-queue use mandatory on main — bypass merges reset in-flight batches and skip cross-PR testing

Summary

Merging to main is managed by the Trunk merge queue, but queue use does not
appear to be enforced: PRs are still landing directly. Every such merge costs
twice — it invalidates every batch currently in flight, and it skips the
combination testing that is the queue's entire purpose.

Proposal: require the merge queue in main's branch protection and disallow
bypass, with an explicit documented break-glass (see "Freeze interaction" below).

Evidence — bypass merges

On 2026-08-04, #2953 and #3005 each landed on main alone while the
trunk-merge/pr-2853 and trunk-merge/pr-3016 batches were mid-flight.

Trunk was demonstrably batching 3-4 PRs at the time (pr-2940 carried #2940,
#2754, #2864, #3010), and a batch cycle is ~37 check runs taking well over
30 minutes. A trunk-merge/pr-2953 branch never appeared in any 3-minute poll
across that window.

Caveat: this is inferred from polling, not from the audit log —
gh api repos/dora-rs/dora/branches/main/protection returns 403 to a
fine-grained PAT, so the protection rules could not be inspected directly.
Someone with admin access should confirm before acting.

Cost 1 — every bypass resets every in-flight batch

Trunk re-creates a batch branch from scratch whenever main moves, discarding
all completed checks. Measured on 2026-08-04:

Batch Batch SHAs burned Carrying
trunk-merge/pr-2853 4 #2972, #3012, #3011
trunk-merge/pr-3016 3 #3000, #3016, #3017, #3014

Two single-PR merges 40 minutes apart (#2953 at ~15:45, #3005 at ~16:12) each
sent both batches back to 0 of ~37 checks. #3000 — a one-line fix for the
dora-core build break in #2995, which is why nightly's MSRV check is red —
has been in flight roughly 15 hours without landing.

This compounds with runner contention: the discarded work has to re-queue
behind an already-saturated pool.

Cost 2 — bypasses skip the testing that catches cross-PR breakage

The queue caught a real defect on 2026-08-04 that no per-PR check could:

Both are green in isolation. Together they do not compile. The pr-3016 batch
failed on exactly this, which is the queue working correctly. Had either been
merged directly, main would have broken.

Two individually-green PRs that conflict semantically is precisely the failure
mode an optional queue does not protect against.

Proposed settings

On main branch protection:

  • Require the merge queue for all merges.
  • Disallow bypassing the required checks, including for admins/maintainers.
  • Keep .trunk/trunk.yaml's required_statuses as the gating list (unchanged).

Freeze interaction — needs a decision

#1625 documents an explicit escape hatch during the 1.0 freeze: "Critical
security patches: ping @heyong4725 directly. We can land CVE-level fixes during
the freeze with admin bypass."

Enforcing "disallow bypass including admins" removes that path. Suggested
resolution: keep bypass technically available to admins but treat it as
break-glass — i.e. enforce the queue for everyone by default and require that
any bypass be recorded in the PR. That preserves the CVE path while ending
routine bypassing, which is the actual problem. If the project prefers a hard
block, #1625 should be updated to describe the new escape hatch.

Related

  • Batch-reset thrash is worsened by optimistic merging being off in the Trunk
    dashboard. Mandatory queue use removes bypass resets; optimistic merging
    removes the resets caused by legitimate batch-after-batch merges. Both are
    needed to actually fix throughput.
  • Runner starvation from nightly.yml running on every push to main is
    tracked separately and compounds all of the above.

Filed from an automated repo watch on 2026-08-04; batch counts and timings come
from 3-minute polling of the trunk-merge/* refs and the Actions API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions