Skip to content

feat(forge): merge-queue provider with Trunk and a queue sweep (RIG-5183) - #2210

Merged
mattwilkinsonn merged 3 commits into
compass-forge/rig-5182-pr-fieldsfrom
compass-forge/rig-5183-merge-queue
Oct 12, 2026
Merged

mattwilkinsonn merged 3 commits into
compass-forge/rig-5182-pr-fieldsfrom
compass-forge/rig-5183-merge-queue

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Status board T15 (RIG-5183): a modular queue provider interface, with Trunk as the first provider. Its state is stored on the PR and kept current by a sweep.

  • forge.MergeQueue (Name, Entries) and forge.Trunk over POST /v1/getSubmittedPullRequests, at most 50 PRs per call. Request and response shapes follow Trunk's public OpenAPI reference, "Get several submitted pull requests from a merge queue".
  • State mapping:
    • not_ready and pending map to queued.
    • testing and tests_passed map to testing.
    • failed and pending_failure map to failed.
    • cancelled maps to removed, and merged to merged.
    • A queued or testing entry with isCurrentlySubmittedToQueue: false maps to removed.
    • A PR listed in notFound is absent.
  • PullRequestHydrator.Hydrate sets PullRequest.merge_queue after GetPullRequest. A queue error is logged and never fails the hydrate. A repo with no configured queue makes no Trunk call.
  • MergeQueueSweeper.Run runs on the serve errgroup. Every 2 minutes it reads the open PRs of each configured repo, writes pr.mergeQueue with jsonb_set only when the value differs, and republishes linked issues only on a change.
  • Config:
    • --forge-merge-queues / COMPASS_FORGE_MERGE_QUEUES (owner/name=trunk:branch, comma-separated) sets forge_repo_subscriptions.merge_queue and merge_queue_branch at boot and clears repos that are not listed.
    • --forge-trunk-token-secret names a declared server-only secret.
    • The sweeper is built only when at least one repo is configured.

Deviations from the record

  • ingest.QueueConfigs gains MergeQueueRepos(ctx) and MergeQueueHost(), so the sweep enumerates repos from the same stored config the hydrator reads.
  • Store.OpenPullRequests takes the forge host.
  • MergeQueueSink.PublishPullRequestMergeQueue takes an observedAt. Queue writes are ordered by when the provider was asked (pull_requests.merge_queue_observed_at), so a slow sweep can neither clear a newer entry nor restore an older one. PR upserts never write mergeQueue.
  • Queue config does not create subscriptions. A configured repo must already be watched.

Tests

  • TestTrunkEntriesMapsStatesAndRequest and TestTrunkEntriesMapsCancelledSubmissionToRemoved cover the state table, including removed and absent. Mutating the removal condition fails the test.
  • TestPullRequestHydratorMergeQueue: a queue error leaves the hydrate green, and an unconfigured repo makes no Trunk call.
  • TestMergeQueueSweeperPublishesConfiguredEntries, TestMergeQueueSweeperClearsMissingEntries.
  • pgtests:
    • TestSetPullRequestMergeQueueChangesOnlyOnDifferentEntry
    • TestPublishPullRequestMergeQueueUpdatesLinkedIssueOnlyWhenChanged
    • TestServeMergeQueueSweeperPersistsChangedEntryWithinOneTick: a running Serve with a fake Trunk persists a changed entry.
  • Flag parsing: TestValidateMergeQueueConfigs, TestResolveForgeMapping.

Stacked on #2194 (T14).

…183)

forge.MergeQueue reads queue state per repo; Trunk implements it over
getSubmittedPullRequests (50 PRs per call). Hydrate attaches the entry to
PullRequest.merge_queue; a queue error never fails the hydrate. Queue
moves send no GitHub webhook, so a sweep re-reads open PRs of each
configured repo every 2 minutes and republishes linked issues only on
change. --forge-merge-queues sets forge_repo_subscriptions.merge_queue and
merge_queue_branch at boot; --forge-trunk-token-secret names the token.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@linear-code

linear-code Bot commented Oct 11, 2026

Copy link
Copy Markdown

RIG-5183

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-forge-rig-5183-merge.compass-eng-docs.pages.dev

Deployed from compass-forge/rig-5183-merge-queue at 37a9f7f.

Changed pages:

Keep terminal Trunk failures failed, treat a missing queue entry as null,
reject stale queue writes, stop forwarding the Trunk token across redirects
and copying response bodies into errors, and stop queue config from
enrolling repositories in board ingest.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka added this pull request to stack #2220 October 12, 2026 01:28
Entries and clears now carry the time the provider was asked. A write older
than the stored observation is dropped, so a slow sweep can neither clear a
newer entry nor restore an older one. PR upserts never touch the queue entry.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka

Copy link
Copy Markdown
Contributor Author

Review status at head 37a9f7f2: clean. The first review pass had six medium findings (terminal failed state, missing/null churn, queue-only enrolment, token on redirects and response bodies in logs, recurring-sweep test, self-host docs); all are fixed in 15a53c9d. The follow-up high finding (a stale clear or entry could win a race) is fixed in 37a9f7f2 by an observation watermark, and its re-review is clean. Two lows were dismissed with reasons: unknown Trunk states fail closed, and production paths never hydrate disabled repos.

@rigel-mintaka
rigel-mintaka marked this pull request as ready for review October 12, 2026 03:22
@mattwilkinsonn
mattwilkinsonn merged commit a7a709e into main Oct 12, 2026
18 checks passed
@mattwilkinsonn
mattwilkinsonn deleted the compass-forge/rig-5183-merge-queue branch October 12, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants