|
| 1 | +# Runway Workflow |
| 2 | + |
| 3 | +Runway is the landing service: it owns VCS operations — mergeability checking and landing — on behalf of SubmitQueue. The orchestrator subscribes to two inbound topics (`merge-conflict-checker`, `merger`) and publishes results to two outbound topics (`merge-conflict-checker-signal`, `merger-signal`). It is a consumer-only service with no gateway; work arrives via topic queues and results leave via topic queues. |
| 4 | + |
| 5 | +## Merge-conflict check and merge |
| 6 | + |
| 7 | +The two queues operate at different granularities: |
| 8 | + |
| 9 | +- **merge-conflict-check** is request-level. A merge request carries an ordered sequence of steps (changes + merge strategy). Runway performs a read-only trial merge and publishes per-step mergeability results back. |
| 10 | + |
| 11 | +- **merge** is batch-level. A merge request carries the same payload but Runway commits the result and reports the revisions it produced (per-step output IDs). |
| 12 | + |
| 13 | +A third operation — **promote** — pushes a commit to a ref as-is (`--ff-only`). The primary use case is forwarding a landed SHA from `main` to `verified/main` without creating a new merge commit. Promote reuses the merge queue with the `PROMOTE` merge strategy; Runway fast-forwards the target ref and reports the same SHA back as the output ID. |
| 14 | + |
| 15 | +These are independent input-output flows. A merge-conflict check can run without a merge ever running, and a merge does not depend on a prior check. |
| 16 | + |
| 17 | +## Branch serialization |
| 18 | + |
| 19 | +The partition key `repo/target` on both inbound topics serializes all VCS operations for a given branch. The message queue delivers messages with the same partition key to the same consumer in order, so at most one merge-conflict check or merge operation is in flight for any given branch at any time. |
| 20 | + |
| 21 | +The outbound topics partition by SubmitQueue queue name, matching SubmitQueue's fan-out model where state updates for the same queue are serialized. |
| 22 | + |
| 23 | +## Workflow |
| 24 | + |
| 25 | +``` |
| 26 | + ┌─────────────────────────────────────────────────────┐ |
| 27 | + │ submitqueue orchestrator │ |
| 28 | + └──────────┬───────────────────────────┬──────────────┘ |
| 29 | + │ │ |
| 30 | + MergeRequest (dry run) MergeRequest (commit) |
| 31 | + │ │ |
| 32 | + ▼ ▼ |
| 33 | + [merge-conflict-checker] [merger] |
| 34 | + │ │ |
| 35 | + merge-conflict-check ctrl merge ctrl |
| 36 | + (read-only) (apply + commit) |
| 37 | + │ │ |
| 38 | + MergeResult MergeResult |
| 39 | + │ │ |
| 40 | + ▼ ▼ |
| 41 | + [merge-conflict-checker-signal] [merger-signal] |
| 42 | + │ │ |
| 43 | + ▼ ▼ |
| 44 | + ┌──────────┬───────────────────────────┬──────────────┐ |
| 45 | + │ merge-conflict-check- merge-signal ctrl │ |
| 46 | + │ signal ctrl (update batch state, │ |
| 47 | + │ (update request fan out to conclude) │ |
| 48 | + │ mergeability) │ |
| 49 | + │ submitqueue orchestrator │ |
| 50 | + └─────────────────────────────────────────────────────┘ |
| 51 | +``` |
| 52 | + |
| 53 | +## Per-controller summary |
| 54 | + |
| 55 | +| Controller | In | Out | One-line role | |
| 56 | +|---|---|---|---| |
| 57 | +| **merge-conflict-check** | MergeRequest | MergeResult -> merge-conflict-checker-signal | Dry-run merge: check mergeability of ordered steps against the target branch (read-only) | |
| 58 | +| **merge** | MergeRequest | MergeResult -> merger-signal | Apply, commit, and report per-step output IDs | |
| 59 | + |
| 60 | +The merge-conflict-check controller always publishes a result — even when all steps are mergeable — so SubmitQueue receives a definitive answer. On infrastructure error it nacks for retry. |
| 61 | + |
| 62 | +The merge controller publishes a conflict result (and acks) when the merge detects a conflict; SubmitQueue handles rebatching. On infrastructure error it nacks for retry. On success it publishes per-step outcomes (output IDs of the revisions produced) so SubmitQueue can update its request state. |
| 63 | + |
| 64 | +## Idempotency |
| 65 | + |
| 66 | +Runway has no persistent state — no request store, no job store, no database. Idempotency is achieved through the VCS contract: merge detects already-pushed changes (revisions reachable from HEAD) and treats them as already-landed. Merge-conflict check is read-only and naturally idempotent. |
| 67 | + |
| 68 | +## Ownership by service |
| 69 | + |
| 70 | +### Orchestrator |
| 71 | + |
| 72 | +The orchestrator is the only service. It subscribes to two inbound topics (`merge-conflict-checker`, `merger`), performs VCS operations through a pluggable extension, and publishes results to two outbound topics (`merge-conflict-checker-signal`, `merger-signal`). It owns no persistent data. |
| 73 | + |
| 74 | +### Shared: the messaging queue |
| 75 | + |
| 76 | +Runway communicates with SubmitQueue only through the messaging queue. The inbound topics are owned by runway; the outbound topics are owned by SubmitQueue. |
0 commit comments