| 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 |