Skip to content

feat(orchestration): add worker-start --spec to create and dispatch in one call - #13540

Open
S-jooyoung wants to merge 3 commits into
stablyai:mainfrom
S-jooyoung:feat/worker-start-spec
Open

feat(orchestration): add worker-start --spec to create and dispatch in one call#13540
S-jooyoung wants to merge 3 commits into
stablyai:mainfrom
S-jooyoung:feat/worker-start-spec

Conversation

@S-jooyoung

@S-jooyoung S-jooyoung commented Aug 10, 2026

Copy link
Copy Markdown

Summary

Adds --spec (and optional --task-title) to orca orchestration worker-start, so a supervised worker can be created and dispatched in one call instead of the two-mutation task-createworker-start id-shuttle.

Closes #13360.

  • --spec <text> creates the Task runtime-side inside the same workerStart call, then enters the existing dispatch flow. Exactly one of --task or --spec is required; --task-title is only valid with --spec.
  • Inline Task creation is atomic with dispatch acceptance: createStartingWorkerDispatch creates the --spec Task inside its existing BEGIN IMMEDIATE transaction, so a rejected preflight persists nothing, and a rejected or crashed acceptance rolls the Task back together with the dispatch row and mutation receipt — no orphan Task, and no duplicate Task on an unknown-result retry. --retry-of requires --task (a just-created Task can never satisfy retry validation, so the combination is rejected up front).
  • The --task path is unchanged (backward compatible). Tasks needing --deps/--parent keep using task-create.
  • The Task is resolved/created before the local/federated split, so --spec also works with --on <server> — the Task is created on the Run home, exactly as with task-create.
  • Flag names mirror task-create (--spec, --task-title), keeping the CLI surface consistent.

Screenshots

No visual change.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added or updated high-quality tests that would catch regressions, or explained why tests were not needed

New tests:

  • src/main/runtime/rpc/methods/orchestration-worker-start-spec.test.ts — runtime: --spec creates the Task in the Run and dispatches to ready; a failed dispatch (dispatch_input) still returns the created taskId and the Task remains queryable; a rejected local or federated preflight persists no Task; an in-transaction acceptance failure and a mutation-receipt conflict roll the inline Task back; existing --task path still resolves; schema rejects --task+--spec, neither, --task-title without --spec, and --retry-of with --spec.
  • src/cli/handlers/orchestration-worker-cli.test.ts — CLI: forwards spec/taskTitle to the RPC, capability-gates --spec against old runtimes, and rejects the invalid flag combinations client-side before any RPC call.

AI Review Report

Reviewed by the AI agent that authored the change, explicitly checking:

  • Cross-platform (macOS/Linux/Windows): no shortcuts, labels, file paths, shell invocations, or Electron platform branches are touched — the change is pure RPC schema/handler + CLI flag plumbing, identical on all three platforms.
  • Remote wire compatibility: spec/taskTitle are new optional RPC fields (safe per docs/reference/remote-wire-compatibility.md). Because an older host would strip them via zod and then reject the call as missing --task, the CLI gates --spec behind a new static capability orchestration.worker-start-spec.v1 (same pattern as worker-launch-preferences.v1) and fails with a clear "update Orca" error instead.
  • SSH/remote/federation: the Task is created on the Run home before startFederatedWorker, so federated placement semantics are unchanged; no local-only assumptions added.
  • Supported agents/integrations: agent-neutral — no agent- or provider-specific logic touched.
  • Performance: one extra status.get only when --spec is used (shared with the existing --model/--effort probe when both apply); task creation reuses the existing db.createTask insert. No hot-path work added.
  • Flagged & resolved during review: initial draft validated only in the CLI; moved the exactly-one-of rule into WorkerStartParams.superRefine too, so direct RPC callers get the same contract. CodeRabbit then flagged that the first revision created the Task before pre-dispatch validation, and that inline creation needed to be atomic with dispatch acceptance — the Task is now created inside createStartingWorkerDispatch's transaction (rolled back with the dispatch row and mutation receipt on failure), with no-orphan tests for preflight rejections, in-transaction acceptance failures, and receipt conflicts.

Security Audit

  • Input handling: spec/taskTitle go through the same zod OptionalString validation and the same parameterized db.createTask insert as task-create — no new parsing, no string interpolation into SQL.
  • No command execution, path handling, auth, secrets, or dependency changes.
  • IPC/RPC surface: two optional fields on an existing authenticated mutation; creator authority is recorded via the existing getOrchestrationDispatchAuthority path, identical to task-create.

Notes

  • New static runtime capability: orchestration.worker-start-spec.v1 (advertised unconditionally by hosts that ship this change).
  • Old client + new host: unaffected (--task path unchanged). New client + old host: clear incompatible_runtime error instead of a confusing Missing --task.
  • Docs updated: skill-guides/orchestration.md and the CLI usage/notes in src/cli/specs/orchestration-worker-specs.ts.

🤖 Generated with Claude Code

…n one call

Exactly one of --task or --spec is required; --task-title labels the
created Task. The Task is created runtime-side inside the same
workerStart call, so a failed dispatch surfaces the created taskId in
its receipt instead of leaving an untracked orphan ready task. The
--task path is unchanged, and --spec is capability-gated
(orchestration.worker-start-spec.v1) so older runtimes fail with a
clear error instead of stripping the field.

Closes stablyai#13360

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

worker-start now accepts either an existing task or an inline specification. The CLI and RPC schema validate task-source combinations, task titles, retry options, and runtime capability support. Runtime logic validates existing tasks or creates tasks transactionally from specifications before dispatch. Tests cover successful dispatch, rollback, capability failures, invalid inputs, task lookup, and dispatch failures. Documentation describes the new command usage.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The implementation satisfies issue [#13360], including inline task creation, validation, atomicity, retry safety, compatibility, and unchanged --task behavior.
Out of Scope Changes check ✅ Passed The changes are limited to the requested CLI, RPC, transaction, capability, test, and documentation updates for worker-start --spec.
Title check ✅ Passed The title clearly and concisely describes adding worker-start --spec to create and dispatch tasks in one call.
Description check ✅ Passed The description covers the required summary, visual change, testing, AI review, security audit, and notes sections with relevant details.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e3d57cdd-6812-4b0c-b526-1fa1d5047ad6

📥 Commits

Reviewing files that changed from the base of the PR and between 14dc499 and fc3ce4c.

📒 Files selected for processing (10)
  • skill-guides/orchestration.md
  • src/cli/bundled-skill-guides.ts
  • src/cli/handlers/orchestration-worker-cli.test.ts
  • src/cli/handlers/orchestration.ts
  • src/cli/specs/orchestration-worker-specs.ts
  • src/main/runtime/rpc/methods/orchestration-worker-start-schema.ts
  • src/main/runtime/rpc/methods/orchestration-worker-start-spec.test.ts
  • src/main/runtime/rpc/methods/orchestration-worker-start-validation.ts
  • src/main/runtime/rpc/methods/orchestration-workers.ts
  • src/shared/protocol-version.ts

Comment thread src/main/runtime/rpc/methods/orchestration-workers.ts Outdated
…light

A preflight rejection (launch validation, worktree/terminal checks,
federation capability probe) used to leave an orphan ready Task with no
receipt, and because worker-start's mutation receipt is only recorded at
dispatch acceptance, a retried preflight failure re-created the Task on
every attempt. --task validation stays first, so existing error
ordering is unchanged; the Task is now created immediately before
createStartingWorkerDispatch in both the local and federated paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/runtime/rpc/methods/orchestration-worker-start-validation.ts (1)

47-59: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Inline task creation still needs to be atomic with dispatch acceptance.

createStartingWorkerDispatch(...) wraps dispatch and mutation-receipt acceptance transactionally, but it only reads an existing taskId and rolls back only the dispatch-side inserts; it does not make createTask() part of that same retry-safe boundary. Since createWorkerStartTaskFromSpec() creates the task outside this transaction, a crash or duplicate unknown-result retry can still leave a task without a durable pending acceptance.

Move inline task creation into an atomic operation or add a durable acceptance record with rollback semantics for pre-dispatch task creation at the inline create path. Add a test that simulates failure after task creation but before dispatch acceptance.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd0db852-4658-44c8-8a02-5ec30ea11059

📥 Commits

Reviewing files that changed from the base of the PR and between fc3ce4c and b8d3868.

📒 Files selected for processing (5)
  • src/main/runtime/rpc/methods/orchestration-federated-worker-start.ts
  • src/main/runtime/rpc/methods/orchestration-migration-behavior.test.ts
  • src/main/runtime/rpc/methods/orchestration-worker-start-spec.test.ts
  • src/main/runtime/rpc/methods/orchestration-worker-start-validation.ts
  • src/main/runtime/rpc/methods/orchestration-workers.ts

createStartingWorkerDispatch now accepts createTask and creates the
inline task inside its BEGIN IMMEDIATE transaction, so a rejected or
crashed acceptance rolls the task back together with the dispatch row
and mutation receipt instead of leaving a receiptless orphan or a
duplicate on unknown-result retry. --retry-of now requires --task: a
just-created task can never satisfy retry validation, so the combination
only manufactured failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@S-jooyoung

Copy link
Copy Markdown
Author

@coderabbitai Addressed the outside-diff caution (inline task creation vs. dispatch acceptance atomicity) in c3a1a8338.

  • createStartingWorkerDispatch now accepts createTask and creates the inline --spec Task inside its existing BEGIN IMMEDIATE transaction, immediately after the mutation-receipt insert. A rejected acceptance (receipt conflict, retry validation) or a crash rolls the Task back together with the dispatch row and the pending receipt, so no receiptless orphan and no duplicate Task on an unknown-result retry.
  • The handler no longer writes the Task before the call — buildWorkerStartTaskInput is a pure argument builder, and both the local and federated paths pass taskId XOR createTask through to the transactional method.
  • --retry-of now requires --task (schema + CLI): a just-created Task can never satisfy retry validation (prior.task_id match + failed/blocked status), so the combination could only manufacture a failure after creating the Task.
  • Added the requested tests: an in-transaction acceptance failure (createTask + invalid retryOf) and a mutation-receipt conflict, each asserting listTasks stays empty afterward.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git show --stat --oneline --decorate --no-renames c3a1a8338
git diff c3a1a8338^ c3a1a8338 -- \
  src/main/runtime/rpc/methods/orchestration-worker-start* \
  src/main/runtime/rpc/methods/orchestration-workers.ts \
  src/cli/handlers/orchestration.ts \
  src/cli/specs/orchestration-worker-specs.ts

printf '\n--- candidate symbols ---\n'
rg -n -C 4 \
  'createStartingWorkerDispatch|buildWorkerStartTaskInput|createTask|retryOf|retry-of|mutation.?receipt|listTasks' \
  src/main/runtime/rpc/methods src/cli/handlers/orchestration.ts src/cli/specs/orchestration-worker-specs.ts

printf '\n--- outlines ---\n'
fd -a '^orchestration-(worker-start|workers|federated-worker-start).*\.ts$' src/main/runtime/rpc/methods \
  -x ast-grep outline {} --items all --view expanded

Length of output: 131459


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- createStartingWorkerDispatch definition and surrounding transaction ---'
rg -n -A180 -B20 \
  'createStartingWorkerDispatch\s*\(' \
  src/main/runtime/orchestration/db.ts

printf '%s\n' '--- createTask and mutation receipt helpers ---'
rg -n -A100 -B15 \
  'createTask\s*\(|beginMutationReceipt\s*\(|BEGIN IMMEDIATE|COMMIT|ROLLBACK' \
  src/main/runtime/orchestration/db.ts

printf '%s\n' '--- federated worker dispatch acceptance path ---'
sed -n '70,145p' src/main/runtime/rpc/methods/orchestration-federated-worker-start.ts

printf '%s\n' '--- all createStartingWorkerDispatch call shapes after the change ---'
rg -n -A12 -B3 'createStartingWorkerDispatch\(\{' src --glob '*.ts'

Length of output: 235051


@S-jooyoung Confirmed. createStartingWorkerDispatch now creates the inline Task inside its BEGIN IMMEDIATE transaction, after receipt insertion. Rollback removes the Task, pending receipt, and dispatch writes when acceptance fails.

Both local and federated paths pass taskId XOR createTask to this method. The new tests cover retry validation failure and mutation-receipt conflict with no persisted Task. The CLI and schema also reject --retry-of with --spec.

The atomicity concern is addressed.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: worker-start --spec — create the task and dispatch it in one call

4 participants