返回 CodeWhale
WORKFLOW_AUTHORING.md
根目录 / docs / WORKFLOW_AUTHORING.md
1 # Workflow Authoring
2
3 > 阅读简体中文版:[zh_hans/WORKFLOW_AUTHORING.md](zh_hans/WORKFLOW_AUTHORING.md)。
4
5 > **Ordinary multi-agent work does not require this file.** In Operate, send
6 > normal messages. Small work stays direct; multiple delegated steps use a
7 > compact Workflow plan with dependencies, bounded scopes, and completion
8 > evidence. Fleet manages the same sub-agents and roles. One bounded,
9 > independent task can use a direct agent, with `followup` for continued work.
10 > Act/Agent may also use optional soft-auto launch. See
11 > [Automatic Workflows](AUTOMATIC_WORKFLOWS.md).
12
13 Workflow has one runtime boundary: authored source lowers to typed
14 Rust `WorkflowSpec`, Rust validates the IR, and the scheduler/headless worker
15 runtime executes leaves. Authoring languages do not get hidden authority to own
16 files, shell, network, providers, cancellation, or TUI state.
17
18 Compatibility launch paths on the `workflow` tool:
19
20 | Input | When to use |
21 |-------|-------------|
22 | `plan` | Structured goal / phases / children (preferred agent path) |
23 | `script` | Short inline JS the model owns |
24 | `source_path` | Checked-in `.workflow.js` / `.workflow.ts` in the workspace |
25
26 Use `agent(action="roster")` to inspect the saved Fleet models and roles before
27 assigning children. Native plan children accept `model` for a saved shortlist
28 selector, or `role`/`profile` for a saved assignment. Named Exact Fleets keep
29 their member routes fixed and reject per-step model overrides. Plan children
30 also accept `cwd`, a repository-relative working directory — required in
31 multi-repository workspaces so the child (and worktree isolation) resolves the
32 right repository, mirroring `task({cwd})`.
33
34 For a guided walkthrough from fleet task specs to Workflow authoring and
35 monitoring, see [fleet + Workflow Tutorial](FLEET_WORKFLOW_TUTORIAL.md).
36
37
38 ## Access model
39
40 The Workflow script is a **coordinator only**. It has no filesystem or shell of
41 its own. Real work happens in sub-agents the script launches.
42
43 | Layer | What it can access |
44 |-------|--------------------|
45 | Workflow script (JS VM) | Script variables, branching/loops, `task()` / `parallel()` / `pipeline()`, `phase` / `log`, `budget` / `args`. **No** direct FS, shell, network, env, imports, clock, or randomness. |
46 | Workflow-spawned sub-agents | Normal tool surface (read/search/edit/write, shell, web, MCP) subject to role posture, allowlists, and parent policy. File edits for write-capable roles auto-accept under Workflow; shell / web / MCP still require parent auto-approve or fail closed. |
47 | Parent session | Working directory, configured tools/MCP, permission mode, sandbox/network rules. |
48
49 ### Scale
50
51 - Up to **16 concurrent** live agents in one run (additional spawns wait for a slot).
52 - Up to **1_000 agents per run** (VM lifetime spawn cap).
53 - Configured `max_children` and `max_concurrent` can narrow these limits.
54 - Automatic launch is model-judged on scope; the host enforces only the hard `max_children` / `max_depth` ceilings.
55 - Plan the population the work needs and let the host queue and clamp it.
56 These ceilings are enforcement, not a reason to pre-shrink a valid plan.
57
58 See the Workflow JS sandbox tests for the fail-closed host surface inventory.
59
60 ## Language Choice
61
62 | Surface | Strength | Tradeoff | Stance |
63 |---|---|---|---|
64 | YAML / JSON IR | Simple, reviewable, no runtime | Verbose for generated workflows | Keep as interchange/debug format |
65 | JavaScript | Familiar object syntax and easy agent generation | Unsafe if executed as a general runtime | First-class authoring through declarative compile-only subset |
66 | TypeScript | Best editor/types story for workflow SDK | Needs stripping/typechecking if full TS is supported | Same compile-only subset for now; richer SDK later |
67
68 The default high-capability path is TypeScript/JavaScript authoring, but only as
69 a compile step. The compiler accepts a JSON-compatible object inside
70 `workflow({...})` from `.workflow.js` or `.workflow.ts`, lowers it to
71 `WorkflowSpec`, and runs the Rust validation gate. (Starlark authoring was a
72 bootstrap reference and has been removed; Workflow authoring is JS-only.)
73
74 ## Contract
75
76 Accepted source shape:
77
78 ```js
79 export default workflow({
80 "id": "issue-audit-js",
81 "goal": "Audit an issue fix with parallel agents",
82 "nodes": [
83 {
84 "branch": {
85 "id": "parallel-audit",
86 "children": [
87 { "agent": { "id": "code-audit", "prompt": "Review code", "agent_type": "review" } },
88 { "agent": { "id": "test-audit", "prompt": "Review tests", "agent_type": "verifier" } }
89 ]
90 }
91 },
92 { "reduce": { "id": "summary", "inputs": ["code-audit", "test-audit"], "prompt": "Summarize" } }
93 ]
94 });
95 ```
96
97 Supported node wrappers: `agent`, `branch`, `sequence`, `reduce`,
98 `teacher_review`, `loop_until`, `cond`, and `expand`. Raw `WorkflowNode` JSON IR
99 with `kind` / `spec` also remains valid.
100
101 An `agent` node may declare `"profile": "reviewer"` to run as a named fleet
102 roster profile. The name is trimmed and lowercased at compile time and must be
103 a single token (no whitespace, quotes, or `=`); the saved roster is resolved at
104 dispatch time, and explicit fields on the agent override profile defaults.
105
106 The runtime `task()` surface also accepts `cwd` for an existing repository-
107 relative working directory. This is required when a workflow is launched from
108 a multi-repository workspace and the child needs shell or file access. `cwd`
109 is validated by the host, does not grant mutation authority, and should be
110 paired with `worktree: true` when the child needs an isolated checkout.
111
112 The compiler rejects effectful constructs such as `import`, `require`, `fetch`,
113 `process`, `Deno`, `Bun`, `child_process`, file reads/writes, `eval`, `async`,
114 and `await`. This is intentionally stricter than JavaScript: workflow source is
115 a familiar declaration format, not a second execution runtime. The denied
116 effects are not denied to the run — put them in a child worker, which has
117 the full tool surface, and keep the script to coordination.
118
119 ## Verification
120
121 - `cargo test -p codewhale-workflow --locked javascript`
122
123 Current example: `workflows/issue_audit.workflow.js`.
124
125 ## Agent-Written fleet Workflows
126
127 The primary product flow is not "ask the user to write a script." The main
128 agent should decide when a task deserves workflow orchestration, draft the
129 Workflow source, show the plan for the current permission mode, and then let
130 the runtime compile and monitor it.
131
132 Workflow owns the plan: phases, branches, loops, reducers, and intermediate
133 results. fleet owns the durable roster, member identity, semantic role, and
134 saved provider/model pins or inheritance. Runtime owns tool posture, launch
135 concurrency, leases, heartbeats, logs, receipts, and resume/stop/restart
136 controls. In other words, a workflow selects fleet members and monitors their
137 Runtime runs; it isn't an executor, because the script has no shell or
138 filesystem of its own — effects live in the workers.
139
140 Workflow-to-Runtime launch validation applies a conservative default shape
141 before any Workflow IR is lowered to selected workers:
142
143 - up to 1,000 total worker agents per Workflow run;
144 - up to 16 live worker agents at once; larger populations queue (block) on the
145 host's per-run concurrency gate until a live slot frees, then select through
146 fleet and execute through Runtime;
147 - Workflow IR structural nesting no deeper than 5;
148 - Runtime child delegation defaults to 3 levels and has an opt-in hard ceiling
149 of 8; that execution budget is independent of Workflow IR shape;
150 - loops require `max_iterations`;
151 - dynamic `expand` nodes require `max_children` and a template.
152
153 Those limits distinguish population from instantaneous launch concurrency. A
154 valid 1,000-agent Workflow can still drain through a smaller Runtime worker
155 pool. Model selection stays per member: a DeepSeek preset can suggest
156 `deepseek-v4-pro` for the orchestrator and `deepseek-v4-flash` for nearby
157 workers, but users and agents may override any slot when the task calls for it.
158
159 ## Experimental search is a Workflow option
160
161 Experimental search generalizes the existing best-of-N recipe without adding a
162 new product mode, scheduler, or sub-agent API. The proposed search spec would
163 freeze the objective, baseline, model request and resolved version, public
164 evidence, evaluator hash, hard gates, scoring rule, budgets, write scope,
165 rounds, and review-only integration policy before admission; it is a design,
166 not shipped code.
167
168 The current JS starter supports structured generation and read-only review with
169 `strategy: "search"`. Runtime-owned command gates, hidden evaluation, benchmark
170 scoring, and clean-baseline replay are an explicit host seam still to wire; a
171 candidate's self-verdict must never be promoted into evaluator truth. See
172 [Workflow Experimental Search](WORKFLOW_EXPERIMENTAL_SEARCH.md).
173
173 lines MARKDOWN