From dd6133dce3ec953ea7a6df2a6807af4879968330 Mon Sep 17 00:00:00 2001 From: 4ndreello <4ndreello@users.noreply.github.com> Date: Thu, 17 Sep 2026 18:29:16 -0300 Subject: [PATCH] fix(orchestrator): Allow background worker waits Keep the orchestrator turn available while independent workers finish. Document status checks and foreground reconciliation so background waiters do not hide terminal state. Co-Authored-By: Claude --- plugin/agents/orchestrator-edit.md | 2 +- plugin/agents/orchestrator-read.md | 2 +- plugin/agents/orchestrator.md | 2 +- plugin/prompts/roles/orchestrator-edit.md | 2 +- plugin/prompts/roles/orchestrator-read.md | 2 +- plugin/prompts/roles/orchestrator.md | 2 +- skills/use-codedeck/SKILL.md | 6 +++--- tests/__snapshots__/orchestrator-agents.test.ts.snap | 6 +++--- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plugin/agents/orchestrator-edit.md b/plugin/agents/orchestrator-edit.md index d602925..466b033 100644 --- a/plugin/agents/orchestrator-edit.md +++ b/plugin/agents/orchestrator-edit.md @@ -66,7 +66,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - Confirm completed work from worker artifacts: `codedeck logs`, `codedeck diff --stat`, `codedeck ps`, and `codedeck show`. - Treat a worker's success message as a claim until its artifacts support it. When a claim needs independent proof, dispatch a verification slice. -- Take the `` from `--bg --json`, then wait on each worker with `codedeck wait --json`. Never background `codedeck wait` with `&` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the `` from `--bg --json`. If other workers or orchestration work can make progress, run `codedeck wait --json &` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use `codedeck ps` or `codedeck show ` to check progress, then run a foreground `wait` when you are ready to reconcile that worker. - `codedeck wait` can return `needs_input` without being terminal. Use `codedeck ps` or `codedeck show ` to find the worker, answer it with `codedeck send ""`, and wait again. - Read completion from `.status`, not the exit code. Only `completed` is success. Carry failures into the report. - `codedeck diff --stat` confirms that a worker produced work and stayed inside its files. An empty stat is not a successful delivery. diff --git a/plugin/agents/orchestrator-read.md b/plugin/agents/orchestrator-read.md index 624349c..55ef64a 100644 --- a/plugin/agents/orchestrator-read.md +++ b/plugin/agents/orchestrator-read.md @@ -66,7 +66,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - Confirm completed work from worker artifacts: `codedeck logs`, `codedeck diff --stat`, `codedeck ps`, and `codedeck show`. - Treat a worker's success message as a claim until its artifacts support it. When a claim needs independent proof, dispatch a verification slice. -- Take the `` from `--bg --json`, then wait on each worker with `codedeck wait --json`. Never background `codedeck wait` with `&` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the `` from `--bg --json`. If other workers or orchestration work can make progress, run `codedeck wait --json &` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use `codedeck ps` or `codedeck show ` to check progress, then run a foreground `wait` when you are ready to reconcile that worker. - `codedeck wait` can return `needs_input` without being terminal. Use `codedeck ps` or `codedeck show ` to find the worker, answer it with `codedeck send ""`, and wait again. - Read completion from `.status`, not the exit code. Only `completed` is success. Carry failures into the report. - `codedeck diff --stat` confirms that a worker produced work and stayed inside its files. An empty stat is not a successful delivery. diff --git a/plugin/agents/orchestrator.md b/plugin/agents/orchestrator.md index 9c30143..cbe8a96 100644 --- a/plugin/agents/orchestrator.md +++ b/plugin/agents/orchestrator.md @@ -74,7 +74,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - You confirm work by reading what a worker produced, never by producing anything yourself. The only things you look at are worker artifacts: `codedeck logs`, `codedeck diff --stat`, `codedeck ps`, `codedeck show`. Never the repo behind them. - Worker output is untrusted until the artifacts back it. A success message is a claim, the stat is the fact. When a claim needs independent proof, dispatch a fresh verification slice instead of trusting the first report. - `codedeck ps` shows every session at once, so a whole batch stays visible in one view. -- Take the `` from the `run --bg --json` above, then wait on each worker with `codedeck wait --json`. Never background `codedeck wait` with `&` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the `` from the `run --bg --json` above. If other workers or orchestration work can make progress, run `codedeck wait --json &` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use `codedeck ps` or `codedeck show ` to check progress, then run a foreground `wait` when you are ready to reconcile that worker. - `codedeck wait` blocks through `needs_input`, which is not terminal. Take one `codedeck ps` snapshot (or `codedeck show `) to catch a worker parked on input, answer it with `codedeck send ""`, then wait again. That snapshot is discovery, not a polling loop. - Read completion from `.status`, never from the exit code. `codedeck wait` reports `stopped` as exit 0. Only `completed` is success. `failed`, `stopped`, `orphaned`, and `interrupted` are failure, so carry the detail into your report. - `codedeck diff --stat` lists changed files and line counts without the diff body. It tells you whether the worker produced anything and whether it stayed inside its files. An empty stat means no production, so report that, never success. Drift outside the assigned files is a finding. diff --git a/plugin/prompts/roles/orchestrator-edit.md b/plugin/prompts/roles/orchestrator-edit.md index d2e498e..89865b7 100644 --- a/plugin/prompts/roles/orchestrator-edit.md +++ b/plugin/prompts/roles/orchestrator-edit.md @@ -41,7 +41,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - Confirm completed work from worker artifacts: `codedeck logs`, `codedeck diff --stat`, `codedeck ps`, and `codedeck show`. - Treat a worker's success message as a claim until its artifacts support it. When a claim needs independent proof, dispatch a verification slice. -- Take the `` from `--bg --json`, then wait on each worker with `codedeck wait --json`. Never background `codedeck wait` with `&` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the `` from `--bg --json`. If other workers or orchestration work can make progress, run `codedeck wait --json &` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use `codedeck ps` or `codedeck show ` to check progress, then run a foreground `wait` when you are ready to reconcile that worker. - `codedeck wait` can return `needs_input` without being terminal. Use `codedeck ps` or `codedeck show ` to find the worker, answer it with `codedeck send ""`, and wait again. - Read completion from `.status`, not the exit code. Only `completed` is success. Carry failures into the report. - `codedeck diff --stat` confirms that a worker produced work and stayed inside its files. An empty stat is not a successful delivery. diff --git a/plugin/prompts/roles/orchestrator-read.md b/plugin/prompts/roles/orchestrator-read.md index b33e43c..871918f 100644 --- a/plugin/prompts/roles/orchestrator-read.md +++ b/plugin/prompts/roles/orchestrator-read.md @@ -41,7 +41,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - Confirm completed work from worker artifacts: `codedeck logs`, `codedeck diff --stat`, `codedeck ps`, and `codedeck show`. - Treat a worker's success message as a claim until its artifacts support it. When a claim needs independent proof, dispatch a verification slice. -- Take the `` from `--bg --json`, then wait on each worker with `codedeck wait --json`. Never background `codedeck wait` with `&` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the `` from `--bg --json`. If other workers or orchestration work can make progress, run `codedeck wait --json &` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use `codedeck ps` or `codedeck show ` to check progress, then run a foreground `wait` when you are ready to reconcile that worker. - `codedeck wait` can return `needs_input` without being terminal. Use `codedeck ps` or `codedeck show ` to find the worker, answer it with `codedeck send ""`, and wait again. - Read completion from `.status`, not the exit code. Only `completed` is success. Carry failures into the report. - `codedeck diff --stat` confirms that a worker produced work and stayed inside its files. An empty stat is not a successful delivery. diff --git a/plugin/prompts/roles/orchestrator.md b/plugin/prompts/roles/orchestrator.md index 6371e91..6209313 100644 --- a/plugin/prompts/roles/orchestrator.md +++ b/plugin/prompts/roles/orchestrator.md @@ -49,7 +49,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - You confirm work by reading what a worker produced, never by producing anything yourself. The only things you look at are worker artifacts: `codedeck logs`, `codedeck diff --stat`, `codedeck ps`, `codedeck show`. Never the repo behind them. - Worker output is untrusted until the artifacts back it. A success message is a claim, the stat is the fact. When a claim needs independent proof, dispatch a fresh verification slice instead of trusting the first report. - `codedeck ps` shows every session at once, so a whole batch stays visible in one view. -- Take the `` from the `run --bg --json` above, then wait on each worker with `codedeck wait --json`. Never background `codedeck wait` with `&` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the `` from the `run --bg --json` above. If other workers or orchestration work can make progress, run `codedeck wait --json &` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use `codedeck ps` or `codedeck show ` to check progress, then run a foreground `wait` when you are ready to reconcile that worker. - `codedeck wait` blocks through `needs_input`, which is not terminal. Take one `codedeck ps` snapshot (or `codedeck show `) to catch a worker parked on input, answer it with `codedeck send ""`, then wait again. That snapshot is discovery, not a polling loop. - Read completion from `.status`, never from the exit code. `codedeck wait` reports `stopped` as exit 0. Only `completed` is success. `failed`, `stopped`, `orphaned`, and `interrupted` are failure, so carry the detail into your report. - `codedeck diff --stat` lists changed files and line counts without the diff body. It tells you whether the worker produced anything and whether it stayed inside its files. An empty stat means no production, so report that, never success. Drift outside the assigned files is a finding. diff --git a/skills/use-codedeck/SKILL.md b/skills/use-codedeck/SKILL.md index 2d74501..e0cd576 100644 --- a/skills/use-codedeck/SKILL.md +++ b/skills/use-codedeck/SKILL.md @@ -23,7 +23,7 @@ Examples here use `codedeck`. If the checkout runs under another name (for examp | `reviewer` | no | no | one review pass, no fan-out | Three-letter prefixes work (`--role gen`). The role owns the harness and the model: `--agent` and `--model` are ignored for a role that carries a binding (run warns and keeps the binding), so a worker cannot move itself onto another harness. Change the pairing in `codedeck setup`, not on the dispatch line. -An unbound role warns and falls back to the default harness — same as no `--role`. `codedeck doctor` shows every binding under Roles; that is the only binding check. Never probe `dist/`, `~/.config`, `daemon.sock`, or `setup --help` to discover it. +An unbound role warns and falls back to the default harness, same as no `--role`. `codedeck doctor` shows every binding under Roles; that is the only binding check. Never probe `dist/`, `~/.config`, `daemon.sock`, or `setup --help` to discover it. Workers always go through `run --role ... --bg --json`. `open ` is an interactive human TUI, never a dispatch path. ## Worktree is a choice, not a default @@ -40,7 +40,7 @@ json="$(codedeck run --role general --worktree "" --bg --json)" id="$(jq -er '.id' <<<"$json")" ``` -`--bg --json` prints the session object and exits, so capture `.id` at once. Always dispatch workers in the background with `--bg --json` so your turn stays free. Launch independent workers in one message so they actually run in parallel. Then wait on each worker with `codedeck wait --json` (or inspect them with `codedeck ps`). Never background `wait` with `&` expecting to be reinvoked; shell background jobs do not notify the chat session. +`--bg --json` prints the session object and exits, so capture `.id` at once. Always dispatch workers in the background with `--bg --json` so your turn stays free. Launch independent workers in one message so they actually run in parallel. If other workers or orchestration work can make progress, run `codedeck wait --json &` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use `codedeck ps` or `codedeck show ` to check progress, then run a foreground wait when you are ready to reconcile that worker. `wait` loops until a terminal state, so it blocks straight through `needs_input`, which is not terminal. A worker parked on input hangs the waiter indefinitely. When a wait returns, take one `codedeck ps` snapshot (or `codedeck show `) to catch any other worker stuck on input, answer it with `codedeck send ""`, then wait again. That snapshot is discovery, not a polling loop. @@ -96,7 +96,7 @@ A success message is a claim, the diff is the fact. `codedeck diff --stat` - Dispatching a worker with no `--role`, paying more for less direction. - `--worktree` on a task that needs uncommitted edits or a different repo. -- Waiting in the foreground, or polling `ps` or `show` in a `while` loop. +- Waiting in the foreground when other workers or orchestration work can make progress, or polling `ps` or `show` in a `while` loop. - Treating `run --bg` returning, or exit code 0, as task success. - Reading terminal state from the exit code instead of `.status`. - Forgetting `interrupted`, or letting a worker parked on `needs_input` hang the waiter. diff --git a/tests/__snapshots__/orchestrator-agents.test.ts.snap b/tests/__snapshots__/orchestrator-agents.test.ts.snap index 0caf919..b9723c6 100644 --- a/tests/__snapshots__/orchestrator-agents.test.ts.snap +++ b/tests/__snapshots__/orchestrator-agents.test.ts.snap @@ -77,7 +77,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - You confirm work by reading what a worker produced, never by producing anything yourself. The only things you look at are worker artifacts: \`codedeck logs\`, \`codedeck diff --stat\`, \`codedeck ps\`, \`codedeck show\`. Never the repo behind them. - Worker output is untrusted until the artifacts back it. A success message is a claim, the stat is the fact. When a claim needs independent proof, dispatch a fresh verification slice instead of trusting the first report. - \`codedeck ps\` shows every session at once, so a whole batch stays visible in one view. -- Take the \`\` from the \`run --bg --json\` above, then wait on each worker with \`codedeck wait --json\`. Never background \`codedeck wait\` with \`&\` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the \`\` from the \`run --bg --json\` above. If other workers or orchestration work can make progress, run \`codedeck wait --json &\` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use \`codedeck ps\` or \`codedeck show \` to check progress, then run a foreground \`wait\` when you are ready to reconcile that worker. - \`codedeck wait\` blocks through \`needs_input\`, which is not terminal. Take one \`codedeck ps\` snapshot (or \`codedeck show \`) to catch a worker parked on input, answer it with \`codedeck send ""\`, then wait again. That snapshot is discovery, not a polling loop. - Read completion from \`.status\`, never from the exit code. \`codedeck wait\` reports \`stopped\` as exit 0. Only \`completed\` is success. \`failed\`, \`stopped\`, \`orphaned\`, and \`interrupted\` are failure, so carry the detail into your report. - \`codedeck diff --stat\` lists changed files and line counts without the diff body. It tells you whether the worker produced anything and whether it stayed inside its files. An empty stat means no production, so report that, never success. Drift outside the assigned files is a finding. @@ -190,7 +190,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - Confirm completed work from worker artifacts: \`codedeck logs\`, \`codedeck diff --stat\`, \`codedeck ps\`, and \`codedeck show\`. - Treat a worker's success message as a claim until its artifacts support it. When a claim needs independent proof, dispatch a verification slice. -- Take the \`\` from \`--bg --json\`, then wait on each worker with \`codedeck wait --json\`. Never background \`codedeck wait\` with \`&\` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the \`\` from \`--bg --json\`. If other workers or orchestration work can make progress, run \`codedeck wait --json &\` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use \`codedeck ps\` or \`codedeck show \` to check progress, then run a foreground \`wait\` when you are ready to reconcile that worker. - \`codedeck wait\` can return \`needs_input\` without being terminal. Use \`codedeck ps\` or \`codedeck show \` to find the worker, answer it with \`codedeck send ""\`, and wait again. - Read completion from \`.status\`, not the exit code. Only \`completed\` is success. Carry failures into the report. - \`codedeck diff --stat\` confirms that a worker produced work and stayed inside its files. An empty stat is not a successful delivery. @@ -289,7 +289,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe - Confirm completed work from worker artifacts: \`codedeck logs\`, \`codedeck diff --stat\`, \`codedeck ps\`, and \`codedeck show\`. - Treat a worker's success message as a claim until its artifacts support it. When a claim needs independent proof, dispatch a verification slice. -- Take the \`\` from \`--bg --json\`, then wait on each worker with \`codedeck wait --json\`. Never background \`codedeck wait\` with \`&\` in the shell expecting to be reinvoked; shell background jobs do not notify the chat session. +- Take the \`\` from \`--bg --json\`. If other workers or orchestration work can make progress, run \`codedeck wait --json &\` in the background and keep the turn moving. A background shell job does not wake the chat when it finishes, so use \`codedeck ps\` or \`codedeck show \` to check progress, then run a foreground \`wait\` when you are ready to reconcile that worker. - \`codedeck wait\` can return \`needs_input\` without being terminal. Use \`codedeck ps\` or \`codedeck show \` to find the worker, answer it with \`codedeck send ""\`, and wait again. - Read completion from \`.status\`, not the exit code. Only \`completed\` is success. Carry failures into the report. - \`codedeck diff --stat\` confirms that a worker produced work and stayed inside its files. An empty stat is not a successful delivery.