| 1 | # Fleet + Workflow Tutorial |
| 2 | |
| 3 | Fleet and Workflow are meant to work together, but they solve different parts |
| 4 | of the problem: |
| 5 | |
| 6 | - **Fleet** configures and manages the same sub-agents: reusable roles, model |
| 7 | routes, permissions, logs, artifacts, and status/restart/stop controls. |
| 8 | - **Workflow** describes orchestration: phases, branches, reducers, loops, and |
| 9 | agent leaves that can dispatch through the fleet/sub-agent runtime. |
| 10 | |
| 11 | **Default product path:** ask in natural language. Operate handles small or |
| 12 | tightly coupled work directly under the active posture. Multi-step delegation |
| 13 | uses a compact Workflow plan with named steps, dependencies, bounded scopes, |
| 14 | and completion checks; results and evidence pass to the steps that need them. |
| 15 | One bounded, independent task can use a direct background agent. Reuse that |
| 16 | agent with `followup` for continued work. Background work keeps the composer |
| 17 | available, and ordinary multi-agent work does not require workflow files. Details: |
| 18 | [Automatic Workflows](AUTOMATIC_WORKFLOWS.md). |
| 19 | |
| 20 | This tutorial covers the **manual** fleet task-spec / checked-in Workflow path |
| 21 | for operators who want durable host workers and reviewable specs. A |
| 22 | one-sentence request should still not silently generate `tasks.json`; worker |
| 23 | cards and permission posture make dispatch visible without exposing authoring |
| 24 | mechanics. |
| 25 | |
| 26 | The examples use `codewhale fleet` and `/fleet`. |
| 27 | On-disk paths, config keys, and the Workflow `--fleet` flag use the Fleet name. |
| 28 | |
| 29 | ## 1. Prepare The Workspace |
| 30 | |
| 31 | Run fleet from the workspace you want workers to inspect or modify: |
| 32 | |
| 33 | ```sh |
| 34 | codewhale fleet init |
| 35 | ``` |
| 36 | |
| 37 | This creates the workspace ledger at `.codewhale/fleet.jsonl`. Worker logs and |
| 38 | bounded artifacts live under `.codewhale/fleet/`; host adapter logs live under |
| 39 | `.codewhale/fleet-host/`. |
| 40 | |
| 41 | If you want named reusable workers, open the TUI and run: |
| 42 | |
| 43 | ```text |
| 44 | /fleet setup |
| 45 | ``` |
| 46 | |
| 47 | Pick a role, choose whether that profile inherits the operator route or pins a |
| 48 | specific provider/model, choose where the profile lives (**This project** → |
| 49 | `.codewhale/agents/<role>.toml`, or **Personal** → |
| 50 | `$CODEWHALE_HOME/agents/<role>.toml`, available across repositories while a |
| 51 | same-id project profile remains the higher-priority override), then review the |
| 52 | exact file, permissions/tools/route posture, and save. The save control names |
| 53 | its effect ("Save to this project" / "Save as Personal profile"), and |
| 54 | replacing an existing file always asks for a second confirmation. fleet task |
| 55 | specs can reference either resolved profile with `worker.agent_profile` or the |
| 56 | shorter `worker.profile` alias. |
| 57 | |
| 58 | This makes the fleet definition cross-repository, not the authority of one |
| 59 | running session. For a multi-repository operation, launch Codewhale from a |
| 60 | shared parent workspace. Profile availability does not grant filesystem access; |
| 61 | the session's workspace, explicit trusted paths, trust mode, and permission |
| 62 | posture remain authoritative. |
| 63 | |
| 64 | ## 2. Write A fleet Task Spec |
| 65 | |
| 66 | `codewhale fleet run` accepts JSON or TOML. The checked-in |
| 67 | `docs/examples/fleet-dogfood.toml` file is the realistic manual smoke example; |
| 68 | the JSON below shows the same authoring shape with one read-only reviewer and |
| 69 | one bounded docs-note worker. The live Runtime policy controls secrets and |
| 70 | trust; fleet identity carries neither. |
| 71 | |
| 72 | ```json |
| 73 | { |
| 74 | "name": "docs readiness check", |
| 75 | "labels": { |
| 76 | "kind": "tutorial" |
| 77 | }, |
| 78 | "tasks": [ |
| 79 | { |
| 80 | "id": "map-docs", |
| 81 | "name": "Map current docs", |
| 82 | "objective": "Find the docs that describe fleet and Workflow.", |
| 83 | "instructions": "Read docs/FLEET.md and docs/WORKFLOW_AUTHORING.md. Report the command surfaces, current limitations, and any confusing gaps.", |
| 84 | "worker": { |
| 85 | "role": "reviewer", |
| 86 | "profile": "reviewer", |
| 87 | "tools": ["rg", "sed", "git"], |
| 88 | "model": "deepseek-v4-flash" |
| 89 | }, |
| 90 | "workspace": { |
| 91 | "required_files": ["docs/FLEET.md", "docs/WORKFLOW_AUTHORING.md"], |
| 92 | "writable_paths": [], |
| 93 | "environment": { |
| 94 | "required": [], |
| 95 | "allowlist": [] |
| 96 | } |
| 97 | }, |
| 98 | "input_files": ["docs/FLEET.md", "docs/WORKFLOW_AUTHORING.md"], |
| 99 | "expected_artifacts": ["log", "report"], |
| 100 | "scorer": { |
| 101 | "kind": "manual" |
| 102 | }, |
| 103 | "retry_policy": { |
| 104 | "max_attempts": 1 |
| 105 | } |
| 106 | }, |
| 107 | { |
| 108 | "id": "draft-gap-note", |
| 109 | "name": "Draft gap note", |
| 110 | "objective": "Draft a short local note for any missing tutorial steps.", |
| 111 | "instructions": "Write a concise Markdown note with the missing fleet + Workflow tutorial steps. Do not edit public docs unless explicitly asked.", |
| 112 | "worker": { |
| 113 | "role": "builder", |
| 114 | "tools": ["rg", "sed"] |
| 115 | }, |
| 116 | "workspace": { |
| 117 | "required_files": ["docs/FLEET.md"], |
| 118 | "writable_paths": [".codewhale/fleet"], |
| 119 | "environment": { |
| 120 | "allowlist": [] |
| 121 | } |
| 122 | }, |
| 123 | "expected_artifacts": ["log", "report"], |
| 124 | "scorer": { |
| 125 | "kind": "manual" |
| 126 | } |
| 127 | } |
| 128 | ] |
| 129 | } |
| 130 | ``` |
| 131 | |
| 132 | Save it as `tasks.json`. |
| 133 | |
| 134 | Common task fields: |
| 135 | |
| 136 | | Field | Purpose | |
| 137 | | --- | --- | |
| 138 | | `id`, `name` | Stable task identity and display name. | |
| 139 | | `objective`, `instructions` | The worker goal and exact operating instructions. | |
| 140 | | `worker.role` | Built-in or custom role intent, such as `reviewer`, `builder`, `read-only`, or `smoke-runner`. | |
| 141 | | `worker.profile` / `worker.agent_profile` | Saved fleet roster profile resolved from project `.codewhale/agents/`, personal `$CODEWHALE_HOME/agents/`, or `[fleet.profiles]`. | |
| 142 | | `worker.tools` | Tool names the task expects the worker to use. | |
| 143 | | `worker.model` | Preferred explicit model pin. Route resolution still owns provider/model validation. | |
| 144 | | `worker.model_class`, `worker.loadout` | Compatibility routing hints for older task specs; prefer `worker.profile` plus saved profile route pins for new specs. | |
| 145 | | `workspace.required_files` | Files that must exist before the task starts. | |
| 146 | | `workspace.writable_paths` | Paths the task is allowed to write when the effective runtime posture allows writing. | |
| 147 | | `workspace.environment` | Required or allowlisted environment variables, by name only. | |
| 148 | | `input_files`, `context` | Extra files and strings to thread into the task prompt. | |
| 149 | | `expected_artifacts` | Artifact kinds to expect: `log`, `report`, `patch`, `test_result`, `checkpoint`, or `receipt`. | |
| 150 | | `scorer` | Deterministic or manual verification rule. | |
| 151 | | `retry_policy`, `timeout_seconds`, `budget` | Retry and budget controls. | |
| 152 | |
| 153 | Do not put `security_policy` or worker `trust_level` in a new fleet task spec. |
| 154 | Those legacy fields remain readable only for old ledger replay and new-run |
| 155 | validation rejects them. Project trust, filesystem/network reach, secrets, |
| 156 | approvals, sandboxing, and tool authority are Runtime policy inputs. |
| 157 | |
| 158 | ## 3. Start And Monitor fleet |
| 159 | |
| 160 | Launch the run: |
| 161 | |
| 162 | ```sh |
| 163 | codewhale fleet run tasks.json --max-workers 4 |
| 164 | ``` |
| 165 | |
| 166 | The command prints the run id and worker ids. In another terminal, monitor the |
| 167 | ledgered state: |
| 168 | |
| 169 | ```sh |
| 170 | codewhale fleet status |
| 171 | codewhale fleet inspect <worker-id> |
| 172 | codewhale fleet logs <worker-id> |
| 173 | codewhale fleet artifacts <worker-id> |
| 174 | ``` |
| 175 | |
| 176 | Use typed controls when a worker needs intervention: |
| 177 | |
| 178 | ```sh |
| 179 | codewhale fleet interrupt <worker-id> |
| 180 | codewhale fleet restart <worker-id> |
| 181 | codewhale fleet resume <run-id> |
| 182 | codewhale fleet stop --all |
| 183 | ``` |
| 184 | |
| 185 | `resume` is for restart recovery after a manager exit, laptop sleep, or stale |
| 186 | lease. It replays the ledger and reconciles stale work without creating a new |
| 187 | run. |
| 188 | |
| 189 | ## 4. Author A Workflow |
| 190 | |
| 191 | Workflow source is declarative JavaScript or TypeScript that lowers to typed |
| 192 | Rust `WorkflowSpec`. It is not a general JavaScript runtime: imports, process |
| 193 | access, filesystem reads/writes, network calls, `eval`, `async`, and `await` |
| 194 | are rejected. |
| 195 | |
| 196 | Create a checked-in file such as `workflows/docs_readiness.workflow.js`. The |
| 197 | repo also includes `workflows/issue_audit.workflow.js` as a maintained example. |
| 198 | |
| 199 | ```js |
| 200 | export default workflow({ |
| 201 | "id": "docs-readiness", |
| 202 | "goal": "Inspect fleet and Workflow docs, then synthesize a readiness note", |
| 203 | "nodes": [ |
| 204 | { |
| 205 | "branch": { |
| 206 | "id": "parallel-docs-audit", |
| 207 | "parallel": true, |
| 208 | "children": [ |
| 209 | { |
| 210 | "agent": { |
| 211 | "id": "fleet-docs", |
| 212 | "prompt": "Inspect docs/FLEET.md for command and task-spec coverage.", |
| 213 | "agent_type": "review", |
| 214 | "mode": "read_only", |
| 215 | "profile": "reviewer", |
| 216 | "file_scope": ["docs/FLEET.md"] |
| 217 | } |
| 218 | }, |
| 219 | { |
| 220 | "agent": { |
| 221 | "id": "workflow-docs", |
| 222 | "prompt": "Inspect docs/WORKFLOW_AUTHORING.md for Workflow authoring coverage.", |
| 223 | "agent_type": "review", |
| 224 | "mode": "read_only", |
| 225 | "profile": "reviewer", |
| 226 | "file_scope": ["docs/WORKFLOW_AUTHORING.md"] |
| 227 | } |
| 228 | } |
| 229 | ] |
| 230 | } |
| 231 | }, |
| 232 | { |
| 233 | "reduce": { |
| 234 | "id": "readiness-summary", |
| 235 | "inputs": ["fleet-docs", "workflow-docs"], |
| 236 | "prompt": "Summarize the exact docs gaps and the safest next edit." |
| 237 | } |
| 238 | } |
| 239 | ] |
| 240 | }); |
| 241 | ``` |
| 242 | |
| 243 | Current Workflow node wrappers are `agent`, `branch`, `sequence`, `reduce`, |
| 244 | `teacher_review`, `loop_until`, `cond`, and `expand`. `agent.profile` names a |
| 245 | fleet roster profile; explicit agent fields override profile defaults. |
| 246 | |
| 247 | The model-facing `workflow` tool can start, run, inspect, or cancel a workflow |
| 248 | from inline source or a `source_path`. When Codewhale uses this path, ask it to |
| 249 | show the plan first if the workflow will launch multiple workers or touch files. |
| 250 | |
| 251 | ## 5. Natural Language Intake |
| 252 | |
| 253 | A good prompt today is: |
| 254 | |
| 255 | ```text |
| 256 | Draft a fleet task spec for this goal, but do not run it yet. |
| 257 | Show the proposed tasks, worker profiles, writable paths, expected artifacts, |
| 258 | scorers, and security policy. Keep secrets disabled unless I explicitly grant |
| 259 | them. |
| 260 | ``` |
| 261 | |
| 262 | After reviewing the generated spec, save it as `tasks.json` and run the fleet |
| 263 | commands above. For workflows, ask Codewhale to draft a `.workflow.js` file, |
| 264 | show the plan, and use the workflow tool path only after approval. |
| 265 | |
| 266 | This review step is intentional. It keeps provider routing, DeepSeek or other |
| 267 | model support, writable paths, network access, and secret use explicit before |
| 268 | durable workers start. |
| 269 |