Summary
Gracefully stopping and resuming a ship cluster after a validator rejection fails closed on the last VALIDATION_RESULT, even though the restored agent configurations explicitly register handlers for that topic.
The failed resume leaves the cluster stopped and strands the preserved worktree/ledger, so a stalled validator cannot be recovered through the documented stop + resume path.
Environment
Reproduction
The cluster had completed three worker iterations. During validation iteration 3:
validator-code published a rejected VALIDATION_RESULT with five findings.
validator-requirements remained executing but produced no persisted Codex session event for more than 71 minutes.
- Cluster state remained
running, with no failureInfo.
Graceful stop succeeded:
$ zeroshot stop rapid-bastion-82
Stopping cluster rapid-bastion-82...
Cluster stopped successfully
Detached resume:
$ zeroshot resume rapid-bastion-82 -d
✓ Preflight checks passed
Resuming cluster rapid-bastion-82...
Agent junior-conductor started (role: conductor)
Agent senior-conductor started (role: conductor)
Agent git-pusher started (role: completion-detector)
Agent planner started (role: planning)
Agent worker started (role: implementation)
Agent validator-requirements started (role: validator)
Agent validator-code started (role: validator)
[Orchestrator] Resuming stopped cluster rapid-bastion-82 (no failure)
[Orchestrator] Last workflow trigger: VALIDATION_RESULT (2026-07-17T13:49:38.942Z)
Error resuming: Cannot resume cluster rapid-bastion-82: Found trigger VALIDATION_RESULT but no agents handle it. Check agent trigger configurations.
The immediately preceding startup log contradicts that error:
git-pusher | ▶ started (listening for: VALIDATION_RESULT)
worker | ▶ started (listening for: PLAN_READY, WORKER_PROGRESS, VALIDATION_RESULT, PUSH_BLOCKED)
After the command exits:
- cluster state is still
stopped;
- cluster PID is null;
failureInfo is null;
- the ledger remains present;
- message count changed from 906 to 913 during the failed resume;
- persisted per-agent fields still show the interrupted validator as
executing_task.
No existing open issue matched the exact error. #711 concerns stale detached worktree bases and is unrelated.
Expected
Resume must reconstruct the workflow from the durable ledger and dispatch the rejected validation to the registered repair handler. In this state, the worker should receive the rejection and begin the next implementation iteration without losing or duplicating validator evidence.
If resume cannot safely reconstruct the state, it must fail before starting agents or appending resume events, and persist an actionable failureInfo.
Impact
- A normal documented recovery path cannot recover a stalled validation run.
- Valid ship work, ledger history, and an isolated worktree are stranded.
- Operators are pushed toward force-killing, ledger surgery, or launching duplicate clusters.
- The error claims no handler exists while two handlers are visibly registered, obscuring the real state-reconstruction defect.
Acceptance criteria
- Add an integration test that stops a cluster after one validator publishes a rejected
VALIDATION_RESULT while a sibling validator is still executing.
- Resume reconstructs the aggregate validation state and routes the rejection to the worker exactly once.
- Handler discovery uses the fully restored runtime agent configuration; a topic visibly registered by an agent cannot be reported as unhandled.
- The resumed cluster reaches
running, clears stale interrupted-task state, and starts the next worker iteration in the same worktree.
- No duplicate
VALIDATION_RESULT, worker iteration, restart, or completion side effects are appended.
- If reconstruction is impossible, resume fails atomically before agents start or ledger state changes and records actionable
failureInfo.
- Cover foreground and detached resume parity.
Summary
Gracefully stopping and resuming a ship cluster after a validator rejection fails closed on the last
VALIDATION_RESULT, even though the restored agent configurations explicitly register handlers for that topic.The failed resume leaves the cluster stopped and strands the preserved worktree/ledger, so a stalled validator cannot be recovered through the documented
stop+resumepath.Environment
6.6.0the-open-engine/zeroshotrapid-bastion-82ship/Users/tom/.zeroshot/worktrees/rapid-bastion-82Reproduction
The cluster had completed three worker iterations. During validation iteration 3:
validator-codepublished a rejectedVALIDATION_RESULTwith five findings.validator-requirementsremained executing but produced no persisted Codex session event for more than 71 minutes.running, with nofailureInfo.Graceful stop succeeded:
Detached resume:
The immediately preceding startup log contradicts that error:
After the command exits:
stopped;failureInfois null;executing_task.No existing open issue matched the exact error. #711 concerns stale detached worktree bases and is unrelated.
Expected
Resume must reconstruct the workflow from the durable ledger and dispatch the rejected validation to the registered repair handler. In this state, the worker should receive the rejection and begin the next implementation iteration without losing or duplicating validator evidence.
If resume cannot safely reconstruct the state, it must fail before starting agents or appending resume events, and persist an actionable
failureInfo.Impact
Acceptance criteria
VALIDATION_RESULTwhile a sibling validator is still executing.running, clears stale interrupted-task state, and starts the next worker iteration in the same worktree.VALIDATION_RESULT, worker iteration, restart, or completion side effects are appended.failureInfo.