You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current sub-agent / fleet-worker wiring is not logical enough for v0.8.61. A worker can be “headless” but still inherit the wrong model, wrong tool surface, or wrong permission behavior. That makes fanout unreliable: workers may lack shell access when they need it, get too much access when they should be read-only, or use a model/provider route that does not match the role.
This is separate from the parent-freeze problem in #3216. #3216 fixes parent blocking; this issue fixes what each worker is allowed and configured to do.
Current code to inspect
crates/tui/src/tools/subagent/mod.rs
agent_open / agent_eval runtime
SubAgentType, role aliases, worker records, model wait states
AgentWorkerToolProfile and worker specs
crates/tui/src/tools/registry.rs
ToolRegistryBuilder::with_agent_tools(allow_shell) currently behaves like a broad on/off switch
tests already prove allow_shell=false excludes shell and allow_shell=true includes shell
crates/tui/src/core/engine.rs
sub-agent runtime construction uses inherited config, model overrides, max depth, and parent completion channel
crates/tui/src/fleet/worker_runtime.rs
fleet_task_to_worker_spec maps fleet task specs to AgentWorkerSpec
fleet_role_to_agent_type maps role strings to SubAgentType
fleet_tool_profile maps task worker profiles to AgentWorkerToolProfile
apply_exec_hardening partially filters explicit tools but inherited profiles are still deferred
codewhale_config::FleetExecConfig and [subagents] config
depth ceiling, max turns, allowed/disallowed tools, model overrides, timeout caps
Desired behavior
Every worker should have an explicit effective runtime profile before it starts: role, model route, permission profile, tool profile, shell policy, recursion depth, budget, and whether it can spawn more workers. The parent and TUI should be able to display that effective profile.
Concrete implementation plan
Introduce an effective worker runtime profile. Create a single resolved struct, e.g. EffectiveWorkerRuntimeProfile, containing:
Resolve profile before spawn. Both agent_open and Fleet worker launch should call the same resolver. Do not let one path use with_agent_tools(true/false) while another path uses fleet tool_profile with different semantics.
Make role defaults explicit. Define default profiles for explorer/reviewer/planner/implementer/verifier/tool-agent/general. For example, reviewer/explorer can default to read-only tools, implementer can get edit/write tools when parent permission allows it, verifier can get verifier + read-only shell/background shell, and tool-agent can get narrowly requested tools only.
Preserve parent safety. A child can only get capabilities that the parent/session permission profile allows. Child role profiles narrow or specialize access; they must not silently escalate.
Route models by role and availability. Integrate with v0.8.61: Add route-effective model inventory and auto fleet model selector #3205 so worker model choice is route-effective: configured provider keys, fleet config, role preferences, model context window, and current parent model all matter. Avoid inheriting an invalid parent model/provider pair.
Expose the profile. Sidebar/inspect/logs should show each worker’s effective role, model route, tool profile, shell policy, and depth. This is important for debugging “why did the worker do nothing?” and “why did it get blocked?”
Make inherited profiles concrete. By the time a worker starts, AgentWorkerToolProfile::Inherited should be resolved into an explicit effective tool set or named permission profile. The fleet path should not defer unknown inherited semantics into spawn-time surprises.
Tests / verification
Unit tests for role → profile resolution for explorer/reviewer/planner/implementer/verifier/tool-agent/general.
Problem
The current sub-agent / fleet-worker wiring is not logical enough for v0.8.61. A worker can be “headless” but still inherit the wrong model, wrong tool surface, or wrong permission behavior. That makes fanout unreliable: workers may lack shell access when they need it, get too much access when they should be read-only, or use a model/provider route that does not match the role.
This is separate from the parent-freeze problem in #3216. #3216 fixes parent blocking; this issue fixes what each worker is allowed and configured to do.
Current code to inspect
crates/tui/src/tools/subagent/mod.rsagent_open/agent_evalruntimeSubAgentType, role aliases, worker records, model wait statesAgentWorkerToolProfileand worker specscrates/tui/src/tools/registry.rsToolRegistryBuilder::with_agent_tools(allow_shell)currently behaves like a broad on/off switchallow_shell=falseexcludes shell andallow_shell=trueincludes shellcrates/tui/src/core/engine.rscrates/tui/src/fleet/worker_runtime.rsfleet_task_to_worker_specmaps fleet task specs toAgentWorkerSpecfleet_role_to_agent_typemaps role strings toSubAgentTypefleet_tool_profilemaps task worker profiles toAgentWorkerToolProfileapply_exec_hardeningpartially filters explicit tools but inherited profiles are still deferredcodewhale_config::FleetExecConfigand[subagents]configDesired behavior
Every worker should have an explicit effective runtime profile before it starts: role, model route, permission profile, tool profile, shell policy, recursion depth, budget, and whether it can spawn more workers. The parent and TUI should be able to display that effective profile.
Concrete implementation plan
Introduce an effective worker runtime profile. Create a single resolved struct, e.g.
EffectiveWorkerRuntimeProfile, containing:SubAgentTypeResolve profile before spawn. Both
agent_openand Fleet worker launch should call the same resolver. Do not let one path usewith_agent_tools(true/false)while another path uses fleettool_profilewith different semantics.Replace shell boolean with permission profiles.
allow_shellshould become an implementation detail of a higher-level permission profile. Read-only shell, detached/background shell, write shell, and no-shell are different capabilities. This should align with v0.8.61: Add first-class permission profiles and nonblocking execution defaults #3211 and v0.8.61: Default independent shell and verifier work to background jobs #3212.Make role defaults explicit. Define default profiles for explorer/reviewer/planner/implementer/verifier/tool-agent/general. For example, reviewer/explorer can default to read-only tools, implementer can get edit/write tools when parent permission allows it, verifier can get verifier + read-only shell/background shell, and tool-agent can get narrowly requested tools only.
Preserve parent safety. A child can only get capabilities that the parent/session permission profile allows. Child role profiles narrow or specialize access; they must not silently escalate.
Route models by role and availability. Integrate with v0.8.61: Add route-effective model inventory and auto fleet model selector #3205 so worker model choice is route-effective: configured provider keys, fleet config, role preferences, model context window, and current parent model all matter. Avoid inheriting an invalid parent model/provider pair.
Expose the profile. Sidebar/inspect/logs should show each worker’s effective role, model route, tool profile, shell policy, and depth. This is important for debugging “why did the worker do nothing?” and “why did it get blocked?”
Make inherited profiles concrete. By the time a worker starts,
AgentWorkerToolProfile::Inheritedshould be resolved into an explicit effective tool set or named permission profile. The fleet path should not defer unknown inherited semantics into spawn-time surprises.Tests / verification
agent_openresolve the same effective profile for equivalent inputs.Related issues