Skip to content

Wire GatedToolSet into the shipped session stack — the authz seam is currently constructed by its tests only #3283

Description

@macanderson

PR #3281 landed stella_tools::gated::GatedToolSet, the decorator that asks an AuthzGate before every tool dispatch. Nothing in the shipping binary constructs it. Until this issue is done, the authorization plane exists as a type and enforces nothing in a real session.

This is the wiring issue AGENTS.md requires to accompany scaffolding, and it is the one that makes #2716's seam real.

Why it was not done in #3281

The production stack is assembled in crates/stella-cli/src/agent.rs (PolicyToolSet::new(&customs, session_tool_policy(cfg)) around line 360, and a second site around line 1690). agent.rs is a grandfathered god file closed to growth (scripts/file-size-baseline.txt), so new lines must not land in it. The prescribed pattern is to extract into a sibling submodule — crates/stella-core/src/driver/settlement.rs, split out of driver.rs, is the exemplar — and that extraction is its own logical change, touching session assembly on the hot path.

Definition of done

  1. Extract the tool-chain assembly out of agent.rs into a sibling module (e.g. crates/stella-cli/src/agent/tool_stack.rs), which should reduce agent.rs's line count. Both assembly sites, plus subsession.rs:736 and candidate_ws.rs:495,514, should end up building the chain through one function.
  2. Wrap the outermost layer in GatedToolSet, above PolicyToolSet. The stack diagram in crates/stella-tools/src/gated.rs's module docs is the intended order.
  3. Default the gate to stella_core::ports::NoAuthz, chosen by name — behaviour must be unchanged for every existing session. Do not add a nullable slot.
  4. Construct the Principal honestly per surface: Principal::User for an interactive session, Principal::SubAgent(id) for a spawned child, Principal::Role(role) for a pipeline stage.
  5. Pin the composition the way the existing decorator-forwarding tests do — the_production_tool_stack_forwards_sub_agent_spend in stella-cli is the shape to copy. A gate layer that swallows drain_sub_agent_spend_usd would silently drop money out of the budget; GatedToolSet forwards all six port methods, and the test should prove it through the real stack rather than a hypothetical one.

Witness

A test that builds the production chain and asserts a DenyAll gate blocks a call that the same chain with NoAuthz allows. crates/stella-tools/src/gated.rs's unit tests are the in-crate version; this one must go through the assembled session stack, because the entire point is that the seam is reachable in a real session.

Constraints

  • Do not add lines to agent.rs or command_deck.rs.
  • GatedToolSet enforces at execute() and deliberately does not filter schemas() — see its module docs. Do not "fix" that here.
  • Behaviour with NoAuthz must be byte-identical to today, including the advertised tool list (invariant Package for Homebrew + curl|sh via cargo-dist #7).

Refs #2716, #3246.

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageUntyped request — convert by adding bug / feature / epic

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions