pub async fn execute_tool(
name: &str,
args: &Value,
workspace: &str,
color: bool,
tool_output_lines: usize,
caveats: &Caveats,
mcp: &mut dyn McpTools,
build_check_cmd: Option<&str>,
note_sink: Option<&mut dyn NoteSink>,
recall_source: Option<&dyn RecallSource>,
memory_source: Option<&dyn MemorySource>,
permission_gate: Option<&mut dyn PermissionGate>,
exec_floor: Option<&Scope<String>>,
git_tool: Option<&dyn GitTool>,
crew_runner: Option<&dyn CrewRunner>,
scratchpad_store: Option<&dyn ScratchpadStore>,
code_search: Option<CodeSearch<'_>>,
experience_store: Option<&dyn ExperienceStore>,
step_ledger: Option<&dyn StepLedger>,
) -> StringExpand description
Execute a single tool call and return the result string sent back to the model.
run_command is routed through agent-bridle’s Caveats-confined, brush-backed
shell tool: the WHOLE command runs inside the leash (echo ok && rm -rf /
no longer slips rm past an echo grant — every external spawn passes the
interceptor’s before_exec / before_open gate). The fs tools
(read_file / write_file / list_dir) keep enforcing the same caveats
via permits_* — rerouting them is out of scope.
note_sink backs the save_note tool (Step 19.3), recall_source the
recall tool (Step 17.5), and memory_source the memory_fetch tool
(progressive-disclosure memory, #319). None ⇒ the tool was never
advertised, so a call here is treated like any unknown tool.
permission_gate is the #263 prompted-grant seam: when present, a
capability denial consults the human (allow once / session allow / deny)
before failing; an allow re-executes the denied call under the gate’s
freshly minted caveats. None (the default, and every headless caller)
keeps every denial exactly as it was — bit-for-bit. #721’s
request_permissions tool also rides this gate: it lets the MODEL proactively
request a grant (vs. only reacting to a denial), and reports “no operator
available” when the gate is None.
INTERIM (#297): when ocap_disabled is asserted (--disable-ocap /
--yolo / NEWT_DISABLE_OCAP=1), run_command skips the confined shell
and runs on the plain host shell with the same venv/PATH prefix and an
envelope of the same shape — nothing is denied, so the #263 gate is never
consulted for exec. Every other tool (fs fence, web_fetch leash) is
unaffected. Removed when brush upstreams CommandInterceptor
(agent-bridle#20).
exec_floor (issue #307) is the named-permission-preset clamp acting as
a hard authority FLOOR over exec. None (every existing caller, and the
no-preset case) leaves the --disable-ocap bypass exactly as it was —
bit-for-bit. Some(scope) makes the bypass conditional: an out-of-floor
command does NOT take the unconfined host path, it falls through to the
confined shell, which enforces the already-clamped caveats and denies it.
This is what makes a deliberately-restricted on-call/triage mode win over a
--yolo flag — the preset clamp is consulted as a ceiling the bypass
cannot cross.