Raxol.Agent.CommandHook implementation that consults an agent's
declared sandbox/0 list before allowing a directive to fire.
How it works
The hook reads the agent's sandbox list via context.agent_module
at pre-execute time -- callbacks defined on the agent module are
the source of truth. For each directive type it can authorize
(Async, Shell, SendAgent), it builds the action atom and
payload shape expected by Raxol.Agent.Sandbox.Chain.authorize/4
and walks the chain.
Wiring
Consumers prepend this module to the agent's command_hooks/0
list at startup. The Raxol.Agent.effective_hooks/1 helper does
the prepending automatically:
hooks = Raxol.Agent.effective_hooks(MyAgent)
Raxol.Agent.Session.start_link(
id: :my_agent,
app_module: MyAgent,
hooks: hooks
)When the agent declares no sandbox/0 (returns []), the chain
walk is trivially :ok and the hook is a no-op pass-through.
Telemetry
On deny, emits [:raxol, :agent, :sandbox, :denied] with
metadata %{agent_id, agent_module, action, reason} so
Raxol.Agent.ThreadLogRouter (or any other handler) can route
the denial as durable audit.