Skip to content
Academy
0/20

Routes

On this page

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.

Intermediate to senior35 min

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.

terminal
$php coa coa:tools inspect settings_update --channel=web
$php coa coa:tools inspect settings_update --channel=web --json

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.

Graded assessment

Solve the 3 scenarios. This unit requires 3 of 3 correct answers.

0 attempts
Question 1 of 3The telegram channel declares require_confirmation_for_mutating:true in its PolicyGate, but settings_update carries mutating:false in its #[Tool]. Why does coa:tools inspect mark the Confirm step as Dormant, not Active, on that channel?
Question 2 of 3Someone claims ctx.mode='plan' and coa:tools inspect are interchangeable because "both avoid executing the tool." What is the correct architectural difference between the two?
Question 3 of 3A documentation draft claims ToolRegistry::call() audits absolutely every terminal path, including pending confirmation and veto. Running coa:tools inspect, what does AUDIT_SOURCE reveal about that claim?

Grading validates answers in this browser; it doesn't certify identity.

Primary sources

Content verified: 2026-07-16