返回 CodeWhale
AUTOMATIC_WORKFLOWS.md
根目录 / docs / AUTOMATIC_WORKFLOWS.md
1 # Automatic Workflows
2
3 You do **not** need to write a `.workflow.js` file to coordinate agents. Operate
4 handles small or tightly coupled work directly. Multi-step delegation starts
5 with a compact Workflow plan: named steps, dependencies, bounded scopes, and
6 completion checks. Workflow runs the same sub-agents that Fleet configures and
7 manages, passing results and evidence between dependent steps. One bounded,
8 independent task can use a direct background agent; follow-up work should reuse
9 that agent with `followup`. Act/Agent can still use the optional soft-auto
10 policy described below.
11
12 Related docs:
13
14 - [Workflow Authoring](WORKFLOW_AUTHORING.md) — checked-in scripts and IR
15 - [Fleet + Workflow Tutorial](FLEET_WORKFLOW_TUTORIAL.md) — manual fleet paths
16 - [Configuration](CONFIGURATION.md) — `[workflow]` knobs
17 - [Sandbox](SANDBOX.md) — what the Workflow VM cannot do
18
19 ## Soft-auto in Act/Agent
20
21 1. **You ask naturally** — “audit every crate for unsafe,” “scout then implement,”
22 “compare these two providers in parallel.”
23 2. **Codewhale decides in Act/Agent** — broad, independent, or staged work can
24 trigger Workflow; one-file edits, simple commands, and pure Q&A do not.
25 3. **It tells you first** — e.g. “This looks set up for a Workflow — three scouts
26 then one verifier.”
27 4. **Optional setup** — if one or two facts would change the plan (read-only vs
28 writes, scope, child count), it opens the **`request_user_input`** modal
29 (structured multiple choice, not a long free-form interview).
30 5. **Launch** — structured `plan` JSON (goal / phases / children) or a short
31 inline script. Parallel branches use `parallel()` partial-success semantics.
32
33 In Operate, those same asks use a compact Workflow plan when they need multiple
34 delegated steps. The plan makes parallel work, dependency handoffs, and the
35 evidence needed to finish visible together. Small or tightly coupled work can
36 stay in the parent under the active tool and approval policy; one bounded,
37 independent task can use a direct agent. Continue an existing agent with
38 `followup` when the task remains the same. You can always type `/workflow` to
39 request orchestration explicitly.
40
41 ## Read-only auto-start vs write approval
42
43 `[workflow]` config (see `config.example.toml`):
44
45 | Knob | Default | Meaning |
46 |------|---------|---------|
47 | `automatic` | `true` | Soft-auto orchestration is enabled |
48 | `auto_start_read_only` | `true` | Read-only plans may start without a write-approval card |
49 | `require_approval_for_writes` | `true` | Gates the plan-approval card for writes / elevated starts |
50 | `max_children` / `max_concurrent` / `max_depth` | `1000` / `16` / `5` | Task count, concurrent children, and plan structure ceilings |
51 | `default_token_budget` | `0` | Shared admission cap for a run and its children; `0` = none — set it or pass `token_budget` on the call to bound spend |
52
53 Elevated work (writes, shell beyond read-only, network, secrets, worktrees, high
54 budget) surfaces an approval card with goal, child summary, capability flags,
55 and budget before launch (#4126) when `require_approval_for_writes` is on.
56 That flag only gates the card. Session-level auto-approve (YOLO / Full Access /
57 `bypass`) still skips it, the same as other ordinary `Required` tools.
58 Writes inside a running VM `task()` step are the VM runtime contract
59 (sandbox, `writeAuthority`, parent tool policy) — this flag does not re-ask
60 for each child write.
61
62 Worktree isolation and write ownership are separate. A write-capable `task()`
63 declares `writeAuthority: "workspace_write"` or `"worktree_write"` plus at
64 least one repo-relative `writeRoots`, `exactFiles`, or
65 `coordinationContracts` value. `worktree: true` selects isolation but does not
66 silently grant mutation authority. A prompt-only general task is read-only.
67 `dependencies` and `acceptance` carry bounded child-specific prerequisites and
68 observable completion checks; they are not a parent-transcript copy.
69
70 When a workflow runs from a workspace containing multiple repositories, a
71 child that needs shell or file access must set `cwd` to the repository-relative
72 directory it should use. The host validates that the directory exists inside
73 the parent workspace before dispatch. Use `worktree: true` for isolated writes;
74 `cwd` selects an existing checkout and does not grant write authority or
75 isolation by itself.
76
77 ## Controlling a run
78
79 `/workflow status [run_id]`, `/workflow cancel [run_id]`, and `/workflow
80 settings` are answered by Codewhale itself from the run journal and the live
81 run state — they never spend a model turn, so a status check is free and a
82 cancel lands even while the model is busy. `/workflow cancel` with no id stops
83 the only running workflow.
84
85 Starting work is review-first. `/workflow <objective>` and bare `/workflow`
86 ask the model for a bounded, tool-less proposal; `/workflow run
87 <path/to/x.workflow.js>` prepares a review of that exact checked-in source.
88 Neither form executes anything. After reviewing the proposal, run `/workflow
89 confirm` to launch the latest reviewed draft. The `[workflow]` table above is
90 read from your `config.toml` for every launch decision (auto-start,
91 write-approval card, child limits); `/workflow settings` prints the effective
92 values with what each one does. Reloading `config.toml` refreshes that table
93 for both settings and the workflow tool.
94
95 `/workflows` opens the run dashboard: every run this workspace's journal
96 keeps for the session — running and finished — newest first. Each row shows
97 the status token, the run's label, elapsed time, child count, and latest
98 progress; `Enter` opens the detail pane (run id, phases, the child roster
99 with per-child state, recent progress, and the error/result summary). `x`
100 cancels the selected running run through the same host path as `/workflow
101 cancel`, `r` re-reads the journal, and `Esc` closes. The dashboard never
102 launches anything — orchestration authority stays with `/workflow`.
103
104 ## What you see while it runs
105
106 - **Workflow panel** — phases, children, status, budget
107 - **Compact history card** — one calm row that expands for detail
108 - **One artifact per delegated unit** — no duplicate “delegate + tool card”
109 - **Typed child identity** — labels/roles; no “unknown child” in the default UI
110
111 Cancel stops the run and child agents. Completed activity can persist across the
112 session (and across restarts when configured).
113
114 ## Sandbox guarantees
115
116 The Workflow JS VM has **no** filesystem, shell, network, env, imports, clock, or
117 randomness. Allowed host calls: `task`, `parallel`, `pipeline`, `phase`, `log`,
118 `budget`, `args`. Real work happens in sub-agents / fleet under normal tool and
119 approval policy. See [Sandbox](SANDBOX.md).
120
121 ## Synthesis and compatibility
122
123 - Prefer `responseSchema` on children that must return structured fields.
124 - Ordinary failed parallel slots become `null` (partial success); filter them
125 before synthesizing one operator-facing summary. A `responseSchema` mismatch
126 is a contract failure and intentionally fails the run instead of being
127 silently converted to `null`.
128 - A `null` slot is no longer anonymous. `parallel()` and `pipeline()` attach a
129 non-enumerable `errors` array to the result — `[{ index, kind, message }]`,
130 ordered by index — so a synthesizer can say *why* a slot is missing. The
131 array's own contents and JSON encoding are unchanged.
132 - `kind` is one of `admission`, `budget`, `cancelled`, `agent`, `schema`,
133 `driver` (assigned by the host where the failure happened) or `script` (the
134 script threw it). Read it from the thrown `Error`'s `.kind`; it is never
135 inferred from message text, so a child's own prose cannot forge a kind.
136 - `opts.mode` selects the contract: `settled` (default — today's behavior),
137 `fail-fast` (reject the whole fan-out with the first non-fatal slot error),
138 or `partial` (resolve every non-cancellation failure to
139 `{ __taskError: { index, kind, message } }`). An unrecognized mode throws
140 rather than quietly reading as `settled`.
141 - A run whose every task failed is recorded as **failed**, not as a partial
142 success, even when the script itself returned a value.
143 - Workflow token budgets govern admission and aggregate accounting. Once
144 exhausted they reject later or descendant spawns, but children already
145 running in parallel can reconcile aggregate usage above the hint because
146 providers report usage only at response boundaries.
147 - Compatibility paths remain: `script`, `source_path` (checked-in
148 `.workflow.js` / `.workflow.ts`), and structured `plan`.
149
150 ## When automatic stays off
151
152 Automatic Workflow is suppressed for:
153
154 - One-file edits and tiny one-step asks
155 - Simple commands / factual questions
156 - Highly interactive design conversations
157 - Risky writes without a clear decomposition
158 - Plans that would exceed `max_children` / `max_depth` (refused before launch)
159
160 In those cases Codewhale uses direct tools or a single `agent` instead.
161
162 ## Example scenarios (#4131)
163
164 Checked-in example workflows cover four automatic-Workflow scenarios:
165
166 1. Read-only repo audit
167 2. Staged bug fix with worktree implementer + verifier
168 3. Partial failure and synthesis
169 4. Cancellation mid-run
170
171 Fixtures: [`docs/examples/dogfood-automatic/`](examples/dogfood-automatic/).
172 Panel regression tests use the `dogfood_` prefix in
173 `crates/tui/src/tui/widgets/workflow_panel.rs`.
174
174 lines MARKDOWN