Skip to content

Make coordinator lifecycle event-driven and restart-durable #9228

Description

@e-jung

Summary

Orca persists orchestration tasks, dispatches, and messages, but the coordinator run loop is still poll-driven and keeps important campaign state in memory. A successful worker_done, escalation, or decision gate may remain unseen until an explicit inbox check or the next coordinator poll; if the coordinator/runtime restarts, an in-flight campaign does not reconstruct all of its state and resume deterministically.

Introduce a durable, event-driven coordinator contract: lifecycle-message persistence should wake the owning coordinator, and a restarted coordinator should reconstruct its complete campaign state from the orchestration database without manual re-dispatch.

User-visible failures this would unify

These have separate immediate causes, but they violate the same invariant: every terminal lifecycle outcome must deterministically advance the durable task graph and wake its owner.

Source evidence on current main

  • src/main/runtime/orchestration/coordinator.ts runs tick() followed by sleep(pollIntervalMs); messages are read on the next tick rather than waking the loop when persisted.
  • The coordinator's completed tasks, failed tasks, escalations, and stop state are held in process memory.
  • runFromExistingRun() can reopen a coordinator run row, but restart convergence does not reconstruct the complete prior in-memory state, active wait position, and escalation context.
  • lifecycle-reconciliation.ts reconciles lifecycle messages, but it is not a durable process/session supervisor and does not turn every endpoint exit into an authoritative task transition.

Expected invariants

  1. Persisting worker_done, escalation, decision_gate, heartbeat, or endpoint-exit state wakes the owning coordinator immediately.
  2. Every dispatched attempt reaches one durable terminal outcome: completed, failed, retryable, blocked, or explicitly cancelled.
  3. A coordinator restart reconstructs completed/failed sets, active gates, unresolved escalations, attempts, and dependencies from durable state.
  4. Delivery and lifecycle authority are keyed by stable dispatch/pane identity rather than a transient terminal handle.
  5. Duplicate/replayed messages are idempotent.
  6. Aggregate runtime health reflects whether the orchestration subsystem can service a trivial request for the current generation.

Suggested acceptance tests

  • Persist worker_done while the coordinator is sleeping; assert it wakes and advances the dependent task without an explicit inbox poll.
  • Kill a dispatched worker; assert the dispatch and task converge on an explicit failed/retry state and an escalation is emitted.
  • Restart Orca with a three-task DAG containing one completed task, one active decision gate, and one dispatched worker; assert the coordinator resumes exactly once with the same dependency and escalation state.
  • Remint a terminal handle while preserving pane/dispatch identity; assert lifecycle messages still route to the correct coordinator.
  • Replay the same completion message after restart; assert no duplicate completion or worker launch.
  • Make orchestration RPC health fail while the runtime socket remains reachable; assert orca status reports a degraded orchestration subsystem rather than aggregate ready.

Related implementation work

This issue is intended as the durable/event-driven contract tying those paths together, not a replacement for their focused fixes. Prepared with AI assistance from source inspection and live orchestration failures. Reporter: @ericjung.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priority: bug or day-to-day user frustration

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions