{"record":{"id":"8fc8dda201bcdc34","repo":"Hmbown/CodeWhale","slug":"fleet-task-is-write-capable-but-declares-no-w","errorCode":null,"errorMessage":"fleet task '{}' is write-capable but declares no workspace.writable_paths or metadata.coordination_contracts","messagePattern":"fleet task '(.+?)' is write-capable but declares no workspace\\.writable_paths or metadata\\.coordination_contracts","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/worker_runtime.rs","lineNumber":241,"sourceCode":"    requested_runtime.provider = explicit_fleet_provider_id(agent_profile);\n    if let Some(reasoning_effort) = effective_fleet_reasoning_effort(agent_profile) {\n        requested_runtime.reasoning_effort = Some(reasoning_effort);\n    }\n    if let Some(agent_profile) = agent_profile\n        && let Some(profile_depth) = agent_profile.profile.delegation.max_spawn_depth\n    {\n        requested_runtime.max_spawn_depth = requested_runtime.max_spawn_depth.min(profile_depth);\n    }\n    let runtime_profile = parent_runtime_profile\n        .map(|parent| parent.derive_child(&requested_runtime))\n        .unwrap_or(requested_runtime);\n    let writable_roots = fleet_write_roots(task_spec)?;\n    let coordination_contracts = fleet_coordination_contracts(task_spec)?;\n    if runtime_profile.permissions.write\n        && writable_roots.is_empty()\n        && coordination_contracts.is_empty()\n    {\n        bail!(\n            \"fleet task '{}' is write-capable but declares no workspace.writable_paths or metadata.coordination_contracts\",\n            task_spec.id\n        );\n    }\n    let session_name = format!(\"fleet-{}-{}\", worker_id, task_spec.id);\n    let launch_manifest = ChildLaunchManifest {\n        owner_session: run_id.to_string(),\n        child_id: worker_id.to_string(),\n        profile: runtime_profile.clone(),\n        prompt: objective.clone(),\n        cwd: Some(workspace.display().to_string()),\n        worktree: worker_workspace_is_isolated(coordination_workspace, workspace),\n        writable_roots,\n        writable_files: Vec::new(),\n        coordination_contracts,\n        expected_artifact: None,\n        token_budget: task_spec\n            .budget","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/worker_runtime.rs#L223-L259","documentation":"The worker's effective runtime profile allows writes (permissions.write = true, possibly derived from a parent profile or the role's default), but the task declares neither `workspace.writable_paths` nor `metadata.coordination_contracts`. The fleet refuses write-capable tasks with no declared write surface: there would be no bounded, auditable place for the worker to write or coordinate. This check sits in the sub-agent worker spec builder (crates/tui/src/fleet/worker_runtime.rs) before any launch manifest is minted.","triggerScenarios":"A task using a write-capable role/agent type with only `workspace.readonly_paths` set; a parent runtime profile with write=true derived into the child while the task omits both fields; metadata present but missing the `coordination_contracts` key.","commonSituations":"Copying a read-only task template and flipping the role to an implementer type without adding write scoping; assuming role defaults count as a declared scope — they do not.","solutions":["Add `writable_paths` under `[workspace]` listing the repo-relative roots the task may write (e.g. \"src\", \".codewhale/fleet\").","If the task coordinates through contracts instead, add `metadata.coordination_contracts = [\"...\"]` (array of short strings).","If the task genuinely needs no writes, switch it to a read-only role/profile so permissions.write is false."],"exampleFix":"# before\n[[tasks]]\nid = \"refactor-core\"\nrole = \"implementer\"\n# no workspace.writable_paths, no coordination_contracts\n\n# after\n[[tasks]]\nid = \"refactor-core\"\nrole = \"implementer\"\n[workspace]\nwritable_paths = [\"src\"]","handlingStrategy":"validation","validationCode":"fn write_scope_declared(task: &FleetTaskSpec) -> bool {\n    let writable = task.workspace.as_ref().is_some_and(|w| !w.writable_paths.is_empty());\n    let contracts = task\n        .metadata\n        .get(\"coordination_contracts\")\n        .and_then(|v| v.as_array())\n        .is_some_and(|a| !a.is_empty());\n    writable || contracts\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat 'write-capable role' as implying 'must declare writable_paths' in every task template.","Lint specs: if role is an implementer/writer type, require a non-empty workspace.writable_paths.","Keep read-only review tasks on read-only roles so the check never engages."],"tags":["fleet","permissions","workspace","validation","rust"],"backgroundTag":"missing-permission-scope","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}