Skip to content

v0.8.61: Give workers role-based tool profiles, permissions, and model routes #3217

@Hmbown

Description

@Hmbown

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

  1. Introduce an effective worker runtime profile. Create a single resolved struct, e.g. EffectiveWorkerRuntimeProfile, containing:

    • worker id / run id / role
    • SubAgentType
    • resolved model/provider route
    • permission profile
    • allowed/disallowed tools
    • shell policy: none, read-only, background allowed, write allowed
    • network policy
    • max steps / token budget / timeout
    • spawn depth and max child delegation depth
  2. 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.

  3. Replace shell boolean with permission profiles. allow_shell should 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.

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

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

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

  7. 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?”

  8. 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.
  • Tests proving child profiles cannot exceed parent/session permissions.
  • Tests proving read-only shell and background shell are distinct from write shell.
  • Tests proving Fleet and agent_open resolve the same effective profile for equivalent inputs.
  • Test a provider/model mismatch: worker auto-routing should pick a valid configured model instead of inheriting an invalid parent default.
  • Dogfood six-worker fanout with mixed roles and verify every worker profile is visible in inspection output.

Related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    Backlog

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions