The three tiers
Deferred tools are registered in the registry but not bound until the model
activates them. They are searchable the whole time; they just do not occupy a
slot in the tool schema block sent with each request.
The discovery loop
1
Search
The model calls
search_tools("fetch a url"). This is a semantic search over
indexed tool descriptions, with a keyword fallback.2
Load
It picks names from the results and calls
load_tools(["webfetch:web_fetch"]).3
Call
The tool is now bound and can be called normally.
max_active. Past
that, the least-recently-used activated tool is evicted. The active set is
tracked in AgentState.active_tools and rendered in the TUI side pane.
unload_tools([...]) deactivates tools explicitly, to free context before the
LRU would.Namespaces and qualified names
Every tool is registered under a namespace, and its qualified name is<namespace>:<tool>:
tool_policy.yaml→core_toolspermissions.yaml→allow/ask/deny/dangerous_default_denyglobs- a subagent’s
*.agent.md→tools:andnamespaces: hooks.yaml→ thematcherglob forpre_toolandpost_tool
rag, rag:*, and the bare namespace
name all resolve to every tool registered in that namespace, preserving order and
de-duplicating. That is how a subagent can declare its rights as whole namespaces
rather than listing individual tools.
The model usually calls a tool by its unqualified name (
run_shell), which is
why hook matchers for it are written *run_shell.A disabled tool is not registered at all
This is the important consequence of the design. When a feature’s policy file saysenabled: false, the tool is never registered in the registry. It is
therefore:
- invisible to
search_toolsandlist_tools - impossible to activate with
load_tools - absent from the permission view a subagent inherits
The full tool surface
Why fs and fs_write are separate namespaces
Reads and writes are split so a permission policy can allow fs:* while
setting ask on fs_write:*. The read-only trio stays frictionless; every
mutation goes through the gate. fs_write also refuses the control plane by
default: secrets (.env, *.key, *.pem, ssh keys), *_policy.yaml,
permissions.yaml, hooks.yaml, .git, .github, and .ziro.
Configuring the tiers
fs or fs:* pulls in the whole namespace.
Subagents inherit, never widen
A spawned subagent’s tool rights are the intersection of the child’s own tool policy and the parent’s current rights: core tools, active tools, and permission grants. This is enforced by a filtered facade over the shared registry plus a predicate threaded into the meta-tools, so even progressive discovery cannot surface or activate an out-of-rights tool for a child. See Subagents.Next steps
Permissions
The gate every tool call passes through.
Shell and files
Running commands and editing files safely.
MCP
Bringing external tool servers into the same surface.