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