[Bug]: `worker_done` with null taskId/dispatchId silently fails to complete the task
- Dominant language
- TypeScript
- Stars
- 71.3k
- Forks
- 4.7k
- Avg merge
- 17h 8m
- Merged PRs (30d)
- 475
Description
**Short summary**
The orchestration auto-complete contract for `worker_done` is real but is enforced only softly, only at reconcile time, and is undocumented in the CLI. A `worker_done` that arrives without `taskId` / `dispatchId` is silently dropped with a warning log — before any terminal-based reconciliation — so any worker that does not follow the stock preamble verbatim (custom harness, non-LLM agent, hand-typed command) silently fails to complete its task. There is no error at `send` time and no terminal fallback.
**What happened**
Ran a coordinator-managed DAG with 8 parallel worker terminals (one per worktree), each dispatched via `orca orchestration dispatch`. Every worker finished and emitted `worker_done`, but all 8 arrived with:
taskId: null
dispatchId: null
None of the 8 tasks auto-completed; each had to be closed by hand with `orca orchestration task-update --status completed`. The workers were driven through a custom harness that did not run the stock preamble verbatim, so this is partly on my side — but the failure mode is entirely silent, which is the actual problem.
**How to reproduce**
1. `orca orchestration task-create --title demo` → `task_`
2. `orca orchestration dispatch --task --terminal --inject`
3. Have the worker complete the work and emit `worker_done` without explicitly setting `taskId` / `dispatchId` (e.g. a custom harness that hand-crafts `--payload '{}'`, or any worker that does not follow the stock preamble verbatim).
4. `orca orchestration task-list` → the task stays in dispatched/running state; it never auto-completes.
**What the code does today** (context for whoever picks this up)
- `reconcileWorkerDoneMessage` (`src/main/runtime/orchestration/lifecycle-reconciliation.ts`) is a four-factor authority check: payload `taskId` non-empty, payload `dispatchId` non-empty, the dispatch context's `assignee_handle` equals `msg.from_handle`, and that dispatch is the current in-flight one. If either id is missing/empty, it returns `{ action: 'ignored' }` with a `Warning: worker_done without taskId/dispatchId from ` log line, **before** the terminal-ownership check — so a null-id `worker_done` is dropped even when it came from the terminal that owns the live dispatch.
- The dispatch preamble (`buildDispatchPreamble` in `src/main/runtime/orchestration/preamble.ts`) does hardcode the real `--task-id` / `--dispatch-id` into the example `orchestration send` command, so a worker that runs the stock preamble sends the ids. The gap is everything else.
- `dispatch --help` / `send --help` (`src/cli/specs/orchestration.ts`) do not document that `worker_done` must carry the matching ids for auto-complete.
- `taskId` / `dispatchId` are not on the `SendParams` / `MessageRow` schema (`src/main/runtime/rpc/methods/orchestration.ts`, `src/main/runtime/orchestration/types.ts`) — `payload` is an opaque `string | null`. The ids exist only as CLI flags assembled into the JSON blob with no validation.
- There is no `--require-payload-ids` opt-in or any `send`-time rejection of null-id lifecycle messages.
**Expected**
At least one of (the first two are the highest leverage):
- reject null-id `worker_done` (and other lifecycle types) at `send` time with a clear error, so a misbehaving worker fails loudly instead of silently;
- when a `worker_done` arrives with null ids, reconcile against the single in-flight dispatch on `msg.from_handle` and complete that, instead of dropping;
- document the auto-complete contract in `dispatch --help` / `send --help` (that `worker_done` must carry the matching `taskId` + `dispatchId`).
**Anything else that might help**
- Orca v1.4.121, macOS (Apple Silicon)
- 8 parallel workers, custom harness (did not run the stock preamble verbatim)
- Related issues (different axis — terminal lifecycle/reuse, not contract enforcement): #6478, #7377
Contributor guide
Assessment
This issue has not been assessed yet.