Auditable architecture · Unit 9 of 9
The tool pipeline, made inspectable
ADR#13 starts from a simple thesis: first make the law that already governs visible. ToolRegistry::call() always ran resolve, validate, authorize, confirm, execute and audit in that order; what was missing was a way to see it without reading the source. coa:tools inspect builds an InvocationPlan that describes, step by step, what call() would REALLY do with a given tool, channel and wiring — it never invokes the callback nor mutates anything.
By the end, you'll be able to
- Read a tool's invocation as an inspectable InvocationPlan, not as eleven identical steps
- Tell Dormant (the rule exists but cannot fire) apart from Skipped (the subsystem isn't wired)
Understand
ADR#13 starts from a simple thesis: first make the law that already governs visible. ToolRegistry::call() always ran resolve, validate, authorize, confirm, execute and audit in that order; what was missing was a way to see it without reading the source. coa:tools inspect builds an InvocationPlan that describes, step by step, what call() would REALLY do with a given tool, channel and wiring — it never invokes the callback nor mutates anything.
The plan is the read-only counterpart of plan mode. ctx.mode='plan' is a branch inside ONE real call: the tool is resolved, validated and stopped before executing — it is still an invocation. The InvocationPlan invokes nothing: it walks the InvocationStepKind steps and marks each one's presence (Active, Conditional, Dormant, Skipped) for that tool+channel+wiring combination, like a full x-ray of the wiring instead of a rehearsal of a single call.
Dormant and Skipped look similar in the table but mean different things. Confirm is Dormant for settings_update (mutating:false, no requiresConfirmation): even on telegram, whose PolicyGate declares require_confirmation_for_mutating:true, the rule EXISTS but the tool's own #[Tool] makes it statically impossible to fire for this tool. Rate limit and Emit executing, in contrast, are Skipped when the host never wired a rateLimiter or a dispatcher — the rule isn't impossible, the subsystem simply isn't connected; wiring it in is enough to flip them to Active.
The honesty cuts into audit coverage too. AUDIT_SOURCE declares what tool.executed/tool.failed actually audit — validate-fail, authz-fail, rate-limit, cache-hit, execute success and failure — and what it does NOT audit: resolve-miss, plan-mode, confirm, veto. An inspect that claimed full coverage would be an aspirational model; ADR#13 requires the plan to describe what the runtime actually EXECUTES, gaps included.
See
Open the X-ray of the runtime — Invocation plan tab
Switch channel (coa, MCP, POST) and watch Confirm stay Dormant while only its justification changes; Rate limit and Emit executing flip from Skipped to Active only when the host's wiring connects them.
Do
Run the practice in your checkout and keep the output as evidence.
Verify
Show that you can apply the unit. Progress only advances once you pass the assessment.
Criteria assessed
- Explain why Confirm marks Dormant, not Active, for a tool with mutating:false, even on a channel that requires confirmation for mutations.
- Tell plan mode — a real call that stops before executing — apart from the InvocationPlan, which executes no call at all.
- Confirm that coa:tools inspect never fabricates an actor: an anonymous invocation shows the principal as null, not a made-up user.
Primary sources
Content verified: 2026-07-16