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
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.
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
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 reduceagent.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.
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.
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.
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.
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.
PR #3281 landed
stella_tools::gated::GatedToolSet, the decorator that asks anAuthzGatebefore 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.rsis 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 ofdriver.rs, is the exemplar — and that extraction is its own logical change, touching session assembly on the hot path.Definition of done
agent.rsinto a sibling module (e.g.crates/stella-cli/src/agent/tool_stack.rs), which should reduceagent.rs's line count. Both assembly sites, plussubsession.rs:736andcandidate_ws.rs:495,514, should end up building the chain through one function.GatedToolSet, abovePolicyToolSet. The stack diagram incrates/stella-tools/src/gated.rs's module docs is the intended order.stella_core::ports::NoAuthz, chosen by name — behaviour must be unchanged for every existing session. Do not add a nullable slot.Principalhonestly per surface:Principal::Userfor an interactive session,Principal::SubAgent(id)for a spawned child,Principal::Role(role)for a pipeline stage.the_production_tool_stack_forwards_sub_agent_spendinstella-cliis the shape to copy. A gate layer that swallowsdrain_sub_agent_spend_usdwould silently drop money out of the budget;GatedToolSetforwards 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
DenyAllgate blocks a call that the same chain withNoAuthzallows.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
agent.rsorcommand_deck.rs.GatedToolSetenforces atexecute()and deliberately does not filterschemas()— see its module docs. Do not "fix" that here.NoAuthzmust be byte-identical to today, including the advertised tool list (invariant Package for Homebrew + curl|sh via cargo-dist #7).Refs #2716, #3246.