Skip to content

feat(contract): add runway merge queue contract + typed queue primitives#244

Open
behinddwalls wants to merge 2 commits into
mainfrom
preetam/runway-contract
Open

feat(contract): add runway merge queue contract + typed queue primitives#244
behinddwalls wants to merge 2 commits into
mainfrom
preetam/runway-contract

Conversation

@behinddwalls

@behinddwalls behinddwalls commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Why?

Both the merge-conflict check and the merge run as asynchronous round-trips with a separate service, runway. A check is a dry run of a merge, so one contract serves both. The contract lives in a neutral top-level package so SubmitQueue can talk to runway without importing the runway domain — a domain never imports another domain.

What?

Adds the cross-service queue contract and the typed primitives it builds on:

contract/runway/messagequeue — runway's queue contract: the MergeRequest/MergeResult payloads (MergeStep, and StepResult with VCS-neutral OutputIDs), plus the ConflictCheck (dry-run) and Merge (committing) operations that pair each request queue with its result queue. Clients (e.g. SubmitQueue) import this contract; they never import the runway domain. The ordered step list encodes base-layering so one request expresses both "candidate vs target branch" (one step) and "candidate + in-flight vs target" (N steps).

core/consumer — generic typed-queue primitives: Topic[T] (a one-way queue bound to its payload type, with Encode/Decode) and Operation[Req, Res] (an async request/response pair of Topics). These give compile-time payload binding for any queue — a producer can't put the wrong type on a queue, and a consumer always reads the type the queue is declared to carry.

Also updates the CLAUDE.md queue-payload rule: cross-domain contracts live in a neutral contract/{owner} package, not the owner's domain package.

Test Plan

bazel test //contract/... //core/consumer/... (round-trip serialization tests pass)
bazel build //...

Issues

Stack

  1. @ feat(contract): add runway merge queue contract + typed queue primitives #244
  2. feat(mergeconflict): make merge-conflict check asynchronous via runway #245
  3. feat(merge): make merge asynchronous via runway #247

…trategy

## Summary

### Why?

The land-merge strategy enum lived in `submitqueue/entity` as `RequestLandStrategy`, but the upcoming runway merge-conflict contract needs the same type, and runway must not import `submitqueue/entity`. Mirroring the `Change` promotion in #240, the strategy belongs in the shared top-level `entity/` so both domains reference one type with no per-domain enum or mapping.

### What?

Moves `RequestLandStrategy` and its constants out of `submitqueue/entity/request.go` into a new top-level `entity/mergestrategy` package as `MergeStrategy` (`MergeStrategyUnknown/Rebase/SquashRebase/Merge`). `Request.LandStrategy` now has type `mergestrategy.MergeStrategy`. All references across the gateway and orchestrator controllers, entities, and tests are updated to the shared type. Pure mechanical refactor — no behavior change.

## Test Plan

✅ `bazel build //...`
✅ `bazel test //... --test_tag_filters=-integration,-e2e` (51 tests pass)
✅ `make gazelle` clean
@behinddwalls behinddwalls force-pushed the preetam/runway-contract branch from ddbb5ab to edf7ab9 Compare June 16, 2026 03:36
@behinddwalls behinddwalls force-pushed the preetam/mergestrategy-promote branch from 20db3b8 to bf357a5 Compare June 16, 2026 03:38
@behinddwalls behinddwalls force-pushed the preetam/runway-contract branch from edf7ab9 to 3e8071d Compare June 16, 2026 17:09
@behinddwalls behinddwalls changed the title feat(runway): add merge-conflict check wire contract and topic keys feat(runway): add merge wire contract and topic keys Jun 16, 2026
Comment thread runway/entity/merge_conflict_check.go Outdated
// MergeConflictCheckRequest is the payload a client publishes to the
// TopicKeyMergeConflictCheck queue. The ID is owned by the client so it can
// record the in-flight check before publishing and correlate the asynchronous
// result; runway echoes it back unchanged.

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.

nit: capitalize Runway so a reader recognizes this is the name

Comment thread runway/entity/merge_conflict_check.go Outdated
QueueName string `json:"queue_name"`
// Steps is the ordered application sequence: in-flight steps first, the
// candidate last. A single-element slice expresses "candidate vs target
// branch".

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.

"A single-element slice expresses "candidate vs target
// branch""
AI generated, hard to read

Comment thread runway/entity/merge_conflict_check.go Outdated
// ID echoes the client-owned correlation id from the request.
ID string `json:"id"`
// Mergeable is true if the whole ordered step sequence applied cleanly.
Mergeable bool `json:"mergeable"`

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.

may be use enum for future extensibility even if now it is binary

Comment thread runway/entity/merge_conflict_check.go Outdated
// Mergeable is true if the whole ordered step sequence applied cleanly.
Mergeable bool `json:"mergeable"`
// Reason is a human-readable explanation when Mergeable is false. Empty when mergeable.
Reason string `json:"reason"`

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.

Why need if there are reasons in StepConflict ?

Base automatically changed from preetam/mergestrategy-promote to main June 16, 2026 19:15
Introduce contract/runway/messagequeue holding runway's cross-service
merge contract: the MergeRequest/MergeResult payloads and the
ConflictCheck (dry-run) and Merge (committing) operations that pair each
request queue with its result queue. The contract lives at a neutral top
level so a client (e.g. SubmitQueue) imports it without depending on the
runway domain.

Add the generic typed-queue primitives it builds on to core/consumer:
Topic[T] (a one-way queue bound to its payload type, with Encode/Decode)
and Operation[Req, Res] (an async request/response pair of Topics), giving
compile-time payload binding for any queue contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
@behinddwalls behinddwalls force-pushed the preetam/runway-contract branch from 3e8071d to cd798f6 Compare June 16, 2026 20:12
@behinddwalls behinddwalls changed the title feat(runway): add merge wire contract and topic keys feat(contract): add runway merge queue contract + typed queue primitives Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants