What happened
Every stage job in reusable-dispatch.yml (triage, code, review, fix, retro, prioritize, harness fan-out) runs in a concurrency group keyed on the work item with cancel-in-progress: true. A second push, comment, label, or title edit on the same item cancels the in-flight job and a fresh job repeats all the work on a new VM and sandbox. #1014, #4960, #6573 quantify the token waste on review bursts; #1207 is the same problem from the other side (triage misses the update that arrived while it ran).
Proposed change
Keep the runs; steer the running agent.
- Runtime
Steerer capability. Claude Code (-p --input-format stream-json) and pi (--mode rpc, streamingBehavior: steer) take a second user message at the next tool boundary inside the running turn; Codex has no live channel in exec, so interrupt the turn and codex exec … resume <thread_id> - with the message. All three verified on the pinned versions (2.1.258/259, 0.84.4, 0.152.1).
- Follow-up run watcher in the runner. GitHub Actions cannot deliver input to a running job, but every legitimate update already produces a shim run whose
Route job applied ADR 0054 and selected a stage. The runner lists shim runs created after its own start (job token, Actions read) and accepts one only on server-side provenance: shim path + event allowlist, referenced_workflows equal to its own run's, Route job success (not the run conclusion: queue: single cancels superseded pending stage jobs), my stage job not skipped, bound to my work item, consumed once by run id. The runner never calls the permission API.
- Dispatch.
cancel-in-progress: false on the stage jobs (default queue: single is the burst debounce), a queued-run skip check that reads the in-flight run's "consumed follow-up run N" marker, a run-name: on the per-repo shim carrying the item number, and a /fs-steer route arm (+ fullsend steer <url> "<text>" posting that comment with the gh auth token).
- Fleet backstop (agents repo, separate PR): end-of-run head/comment re-check with
FULLSEND_RUN_HEAD_SHA / FULLSEND_RUN_STARTED_AT.
Scope: per-repo installs and this repo (per-org mode is deprecated, ADR 0044). GitLab already queues; only the runner side and the skip check apply there.
Validation criteria
- A push during an in-flight review produces one review on the settled head, with the steer visible in the transcript and the queued run exiting on the skip check.
- A fork author's
/fs-steer is ignored (every stage job skipped in its run); an authorized /fs-steer reaches the session.
- No stage regresses when
harness.steer is off (default).
Related: #1014, #4960, #1422, #6573, #1207, #1637, #459, #6932, #5445, #2399.
What happened
Every stage job in
reusable-dispatch.yml(triage, code, review, fix, retro, prioritize, harness fan-out) runs in a concurrency group keyed on the work item withcancel-in-progress: true. A second push, comment, label, or title edit on the same item cancels the in-flight job and a fresh job repeats all the work on a new VM and sandbox. #1014, #4960, #6573 quantify the token waste on review bursts; #1207 is the same problem from the other side (triage misses the update that arrived while it ran).Proposed change
Keep the runs; steer the running agent.
Steerercapability. Claude Code (-p --input-format stream-json) and pi (--mode rpc,streamingBehavior: steer) take a second user message at the next tool boundary inside the running turn; Codex has no live channel inexec, so interrupt the turn andcodex exec … resume <thread_id> -with the message. All three verified on the pinned versions (2.1.258/259, 0.84.4, 0.152.1).Routejob applied ADR 0054 and selected a stage. The runner lists shim runs created after its own start (job token, Actions read) and accepts one only on server-side provenance: shimpath+ event allowlist,referenced_workflowsequal to its own run's,Routejobsuccess(not the run conclusion:queue: singlecancels superseded pending stage jobs), my stage job notskipped, bound to my work item, consumed once by run id. The runner never calls the permission API.cancel-in-progress: falseon the stage jobs (defaultqueue: singleis the burst debounce), a queued-run skip check that reads the in-flight run's "consumed follow-up run N" marker, arun-name:on the per-repo shim carrying the item number, and a/fs-steerroute arm (+fullsend steer <url> "<text>"posting that comment with thegh authtoken).FULLSEND_RUN_HEAD_SHA/FULLSEND_RUN_STARTED_AT.Scope: per-repo installs and this repo (per-org mode is deprecated, ADR 0044). GitLab already queues; only the runner side and the skip check apply there.
Validation criteria
/fs-steeris ignored (every stage job skipped in its run); an authorized/fs-steerreaches the session.harness.steeris off (default).Related: #1014, #4960, #1422, #6573, #1207, #1637, #459, #6932, #5445, #2399.