Files
msd-core/capabilities/claude-orchestration/fragments/execute-wave-post.md
Tom Boucher e3262d94d3 feat(capabilities): add claude-orchestration capability (Workflow backend) (#1143)
Default-off, BETA, claude-only capability adopting Claude Code's Workflow tool
(/effort ultracode, Agent SDK >= v0.3.149) as an optional parallel-execution
backend for the GSD loop. Restores the wave parallelism + plan-checker + verifier
that #853 forces inline on Claude Code, and folds gsd-ultraplan-phase under one
runtime gate.

- Pure fail-closed core (src/claude-orchestration.cts): detectWorkflowBackend
  (gate ladder: enabled -> Claude -> backend != inline -> nested+background host
  -> valid Agent SDK -> SDK >= floor; every miss degrades to inline) and
  emitWorkflowScript (waves -> parallel() barriers, plans -> gsd-executor +
  worktree, files_modified overlap -> separate stages, resumeFromRunId, budget).
  All interpolated identifiers validated script-safe; briefs JSON-quoted.
- claude-orchestration command family (gsd-tools claude-orchestration
  detect-backend|emit-workflow) for orchestrator invocation.
- Two gated loop contributions at wired points (execute:wave:post, plan:post);
  federated config keys (enabled/execution_backend/min_agent_sdk_version).
- ADR-1143 implementation amendment; CONTEXT.md glossary entry; explanation doc.

On any runtime lacking the Workflow tool, behaviour is byte-identical to today.

closes #1143
2026-07-06 15:18:23 -04:00

3.2 KiB

Claude orchestration — Workflow execution backend (BETA)

Injected at execute:wave:post into: executor only when claude_orchestration.enabled is true. Default-off; onError: skip.

When this contribution is active

The Claude orchestration capability is default-off and BETA. It activates only when ALL of the following hold:

  1. claude_orchestration.enabled is true in .planning/config.json, AND
  2. the active runtime is Claude Code (the Workflow tool is Claude / Agent SDK-specific), AND
  3. claude_orchestration.execution_backend resolves to workflow — either explicitly, or via auto — and the Agent SDK version is >= claude_orchestration.min_agent_sdk_version (default 0.3.149). The SDK floor applies in both auto and workflow modes (fail-closed: a pre-release or older SDK never activates the preview backend).

Detection is fail-closed: any miss degrades to inline, manual, one-agent-per- message dispatch — exactly today's behaviour. On a non-Claude runtime this contribution is a no-op.

What the executor does when the Workflow backend is active

Instead of the orchestrator fanning out one Agent(subagent_type=gsd-executor, isolation=worktree, run_in_background=true) per message (which on Claude Code cannot nest further subagents — #853 — and so degrades to sequential inline execution), execute-phase emits a generated Workflow script and lets the main loop orchestrate it:

  • waves → parallel() barriers — each wave is one barrier; the next wave waits for the previous to complete.
  • plans → agent(brief, { agentType: 'gsd-executor', isolation: 'worktree' }) — the SAME executor agent and worktree isolation the inline path uses, so the produced SUMMARY.md and commits are identical.
  • files_modified overlap → separate sequential stages — two plans that touch the same file are placed in different stages within the wave (the same overlap rule execute-phase already applies inline).
  • resumeFromRunId — wired to the phase run id, so an interrupted phase resumes without re-running completed plans.
  • budget(tokens) — a shared token pool across the whole phase when the orchestrator passes a budgetTokens value to emitWorkflowScript (it is a function parameter, not a config key; the orchestrator decides the budget).

The emitter is a pure function exposed through the capability command surface: gsd-tools claude-orchestration emit-workflow --waves <manifest.json> --run-id <id> [--phase-dir <dir>] [--budget <n>] (or require('gsd-core/bin/lib/claude-orchestration.cjs').emitWorkflowScript directly). It maps the phase's wave/plan manifest to the Workflow script string and never invokes the Workflow tool itself; the orchestrator runs the emitted script. Use gsd-tools claude-orchestration detect-backend to resolve whether the Workflow backend should activate for the current runtime.

Fallback contract

If detection resolves to inline (tool absent, SDK too old, runtime not Claude, or the capability disabled), execute-phase MUST proceed with the standard inline wave dispatch. The executor MUST NOT assume parallelism, a shared budget, or resume-from-run-id semantics in that mode.