Skip to content

docs(rfc): queue-scoped speculation design#413

Merged
behinddwalls merged 2 commits into
mainfrom
speculation-rfc
Jul 23, 2026
Merged

docs(rfc): queue-scoped speculation design#413
behinddwalls merged 2 commits into
mainfrom
speculation-rfc

Conversation

@behinddwalls

@behinddwalls behinddwalls commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Why?

A merge queue that verifies one change at a time is bounded by its slowest build. Speculation builds a batch early against a guess at how its unresolved dependencies will resolve, so a matching build is ready when reality settles while merging stays strict. Getting that right on an eventually consistent, transactionless store needs an explicit design for how a path is represented, which paths build under a bounded CI budget, what is persisted, and where each decision lives.

What?

This RFC designs speculation for SubmitQueue end to end. Each queue change fires one run per queue: the speculate controller reads the current facts once, reconciles path state, refutes broken bets, finalizes verdicts, asks one pluggable extension which paths to build or preempt, and writes the result. Only chosen paths are persisted; every other possibility is recomputed each run.

The Speculator is the only controller-facing extension. It chooses which paths to build and which running ones to cancel, while verdicts and correctness cancels remain controller rules. The default Speculator internally composes a Generator, which produces a lazy best-first candidate stream, and an Allocator, which spends the CI budget and settles in-flight paths by ID; alternate Speculators need not preserve that split.

A path is self-describing: it carries an included, excluded, or dropped bet on every dependency. Its identity hashes the head plus its bets, build dispatches are replayed idempotently by path and attempt, and pending, building, and cancelling paths continue to charge the hard CI budget until terminal. The design also covers conflict relaxation and bypassing a large dependency once passed builds cover every possible resolution.

The RFC fills the previously empty doc/rfc/submitqueue/speculation.md.

@behinddwalls
behinddwalls marked this pull request as ready for review July 21, 2026 03:28
@behinddwalls
behinddwalls requested review from a team and sbalabanov as code owners July 21, 2026 03:28
@behinddwalls
behinddwalls force-pushed the speculation-rfc branch 2 times, most recently from e0ac903 to 55dd290 Compare July 21, 2026 21:21

@sbalabanov sbalabanov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

back to you based on brainstorming session

Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
// dependency appears exactly once, in queue order, so the path is self-describing.
type SpeculationPath struct {
Head string // the batch being built
Bets []DependencyBet // one bet per dependency of Head, in queue order

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't it duplicate SpeculationPath ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just captures all deps, regardless of dropped or being excluded in a path so finalization and bypassing logic can make those decisions based on the bet itself.. as when we relax, Batch.Deps would be different from what Bet gets

Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md Outdated
Comment thread doc/rfc/submitqueue/speculation.md
Comment thread doc/rfc/submitqueue/speculation.md Outdated
## Summary

### Why?

A merge queue that verifies one change at a time is bounded by its slowest build. Speculation builds a batch early against a guess at how its unresolved dependencies will resolve, so a matching build is ready when reality settles while merging stays strict. Getting that right on an eventually consistent, transactionless store needs an explicit design for how a path is represented, which paths build under a bounded CI budget, what is persisted, and where each decision lives.

### What?

This RFC designs speculation for SubmitQueue end to end. Each queue change fires one run per queue: the speculate controller reads the current facts once, reconciles path state, refutes broken bets, finalizes verdicts, asks one pluggable extension which paths to build or preempt, and writes the result. Only chosen paths are persisted; every other possibility is recomputed each run.

The Speculator is the only controller-facing extension. It chooses which paths to build and which running ones to cancel, while verdicts and correctness cancels remain controller rules. The default Speculator internally composes a Generator, which produces a lazy best-first candidate stream, and an Allocator, which spends the CI budget and settles in-flight paths by ID; alternate Speculators need not preserve that split.

A path is self-describing: it carries an included, excluded, or dropped bet on every dependency. Its identity hashes the head plus its bets, build dispatches are replayed idempotently by path and attempt, and pending, building, and cancelling paths continue to charge the hard CI budget until terminal. The design also covers conflict relaxation and bypassing a large dependency once passed builds cover every possible resolution.

The RFC fills the previously empty `doc/rfc/submitqueue/speculation.md`.
@behinddwalls
behinddwalls merged commit b8a31fd into main Jul 23, 2026
14 checks passed
@behinddwalls
behinddwalls deleted the speculation-rfc branch July 23, 2026 22:55
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.

3 participants