fix(agent): stop reservation collisions silently stranding review-driven redispatches #1163

Merged
coilyco-ops merged 1 commit from issue-1149 into main 2026-07-13 03:59:41 +00:00
Member

closes #1149

ward.workflow: pull-request-and-merge

Closes the ward#987/#927 silent-stranding path from three sides, matching the issue's ask (release-at-outcome, wait-instead-of-fail-once, and an owner for the marker):

  • Terminal outcome supersedes the reservation at check time. freshReservationComment and reservationClaims now treat a terminal WARD-OUTCOME comment (done, submitted, merge-ready, blocked, failed) posted at/after the reservation as retracting it, so a review-driven follow-up dispatched right after a run reports out no longer collides with the finishing run's hold or races the reaper's release comment. submitted joins terminalReservationOutcome since it is the pull-request workflow's final visible outcome.
  • A collision defers instead of failing once and stopping. A forwarded dispatch that still hits a live hold posts the needs-redispatch marker WITHOUT the release marker (the hold belongs to the run still working), and no longer docker-stops the issue-scoped container (same-harness, that is the live run itself) or unlocks the sealed thread. The reaper also keeps the terminal release comment off a thread a newer reservation already re-holds, so it cannot retract a follow-up run's live hold.
  • <!-- ward-needs-redispatch --> finally has an owner. The director heartbeat's refresh sweeps parked entries (submitted / merge-ready / blocked / failed) whose newest thread signal is an unhandled marker and re-queues them, bounded by redispatchAttemptCap so a repeat-failing dispatch parks blocked instead of looping. The director queue view's redispatch signal keys on the marker alone, so collision deferrals classify there too.

Docs: release semantics and the sweep are recorded in docs/agent-reservation.md and docs/agent-director-dispatch.md.

Per the issue's note, PR #987 / issue #927 themselves are left untouched: #987 should be closed as superseded once a pr close verb exists (agentic-os#488).

closes #1149 ward.workflow: pull-request-and-merge Closes the ward#987/#927 silent-stranding path from three sides, matching the issue's ask (release-at-outcome, wait-instead-of-fail-once, and an owner for the marker): - **Terminal outcome supersedes the reservation at check time.** `freshReservationComment` and `reservationClaims` now treat a terminal `WARD-OUTCOME` comment (done, submitted, merge-ready, blocked, failed) posted at/after the reservation as retracting it, so a review-driven follow-up dispatched right after a run reports out no longer collides with the finishing run's hold or races the reaper's release comment. `submitted` joins `terminalReservationOutcome` since it is the pull-request workflow's final visible outcome. - **A collision defers instead of failing once and stopping.** A forwarded dispatch that still hits a live hold posts the needs-redispatch marker WITHOUT the release marker (the hold belongs to the run still working), and no longer docker-stops the issue-scoped container (same-harness, that is the live run itself) or unlocks the sealed thread. The reaper also keeps the terminal release comment off a thread a newer reservation already re-holds, so it cannot retract a follow-up run's live hold. - **`<!-- ward-needs-redispatch -->` finally has an owner.** The director heartbeat's refresh sweeps parked entries (submitted / merge-ready / blocked / failed) whose newest thread signal is an unhandled marker and re-queues them, bounded by `redispatchAttemptCap` so a repeat-failing dispatch parks blocked instead of looping. The `director queue` view's redispatch signal keys on the marker alone, so collision deferrals classify there too. Docs: release semantics and the sweep are recorded in `docs/agent-reservation.md` and `docs/agent-director-dispatch.md`. Per the issue's note, PR #987 / issue #927 themselves are left untouched: #987 should be closed as superseded once a `pr close` verb exists (agentic-os#488).
fix(agent): stop reservation collisions stranding review-driven redispatches
All checks were successful
test / test (pull_request) Successful in 31s
d1444cce49
Closes the ward#987/#927 silent-stranding path from three sides:

- A terminal WARD-OUTCOME (done, submitted, merge-ready, blocked, failed)
  now supersedes the reservation at check time, in freshReservationComment
  and reservationClaims, so a follow-up dispatched right after a run
  reports out no longer collides with the finishing run's hold or races
  the reaper's release comment. submitted joins terminalReservationOutcome
  since it is the pull-request workflow's final visible outcome.
- A forwarded dispatch that still collides with a live hold now defers
  instead of failing: it posts the needs-redispatch marker WITHOUT the
  release marker (the hold belongs to the run still working), and no
  longer docker-stops the issue-scoped container - which, same-harness,
  is the live run itself - or unlocks the sealed thread. The reaper also
  keeps the terminal release comment off a thread a newer reservation
  already re-holds, so it cannot retract a follow-up run's live hold.
- The needs-redispatch marker finally has an owner: the director
  heartbeat's refresh sweeps parked entries (submitted / merge-ready /
  blocked / failed) whose newest thread signal is an unhandled marker and
  re-queues them, bounded by redispatchAttemptCap so a repeat-failing
  dispatch parks blocked instead of looping. The queue view's redispatch
  signal keys on the marker alone, so collision deferrals classify too.

closes #1149
Sign in to join this conversation.
No description provided.