What explain tells you
explain evaluates one specific tool call against the agent’s composed card, so the request names the tool: pass request_snippet.tool_name. A request that names no tool is rejected with 400 missing_tool_name — a toolless call has nothing to check, so it isn’t offered a verdict.
trace— the rawEvaluationResultfrom@mnemom/policy-engine. Carriesverdict(pass/warn/fail),violations[],warnings[],card_gaps[],coveragereport,policy_id,policy_version.reasoning— care-framed prose summarizing the verdict + counts.suggested_remediations[]— per-finding structured hints. Each carries:for:violation/warning/card_gapindex: position in the corresponding trace arrayremediation: a care-framed prose remediationmethod+url(optional): the sub-resource verb that would resolve it
The four violation types
The policy engine surfaces four classes ofPolicyViolation.type. Each maps to a deterministic remediation template.
forbidden
A tool the agent is using matches a pattern in enforcement.forbidden_tools[].
POST /v1/agents/{agent_id}/exemptions (if the agent legitimately needs this action).
capability_exceeded
The agent invoked a tool that isn’t mapped to any capability’s tools[] list.
tools) replaces the existing array wholesale rather than appending to it — include every tool the capability should end up with, not just the new one.
unmapped_denied
The agent used a tool that has no capability mapping, AND enforcement.allow_unmapped_tools: false (the default).
- The principled path: add the tool to an appropriate capability via
PATCH /capabilities. - The escape hatch: set
enforcement.allow_unmapped_tools: trueviaPATCH /enforcement. This loosens the default surface — only use it for sandbox / development agents.
gateway_hook_missing_receipt
A tool the agent invoked matches a catalog gateway hook (e.g., policy_attentiveness binds on financial tools), but the required receipt (e.g., think) wasn’t present in the conversation history.
think consultation before invoking the gated tool. See governance signals and the policy engine for the receipt mechanism.
Warnings
Warnings don’t block; they surface drift the operator may want to address.Card gaps
card_gaps[] flag capabilities that exist but whose action surfaces aren’t fully declared.
LLM enrichment
If you want long-form prose explanations (useful for non-technical reviewers), pass"enrich": true:
reasoning always renders.
Enrichment consumes the per-principal LLM budget (10/hour/user; 100/hour/org). Off by default.
Hypothetical explain — what would happen?
Explain a hypothetical tool call against the agent’s current composed card by naming the tool:The request body also accepts
turn_id, but the endpoint does not yet use it to load historical spec state or replay a specific past evaluation — every explain call evaluates against the agent’s current composed card. Only request_snippet.tool_name affects the verdict; a request_snippet.tool_args value is accepted but not evaluated.The full debug-and-fix flow
- Run
explainagainst the agent. - For each
suggested_remediation, check themethod+urlhint. - Apply the sub-resource PATCH with the suggested change.
- Re-run
explainto confirm the finding is gone. - Repeat until
verdict: "pass".
What explain doesn’t do
- It doesn’t write anything. It’s a read-style POST.
- It doesn’t replace the simulate endpoint — explain is about the current spec; simulate is about a hypothetical call against that spec.
- It doesn’t run the protection card’s policy. V1 returns a
Phase 5 deferredshape onPOST /v1/protection/agent/<id>/explainuntil the dedicated protection evaluator ships.
Related reading
- Sub-resource verbs — the PATCH surface remediations point at.
- Simulate before commit — for testing a hypothetical call.
- Policy engine — the evaluator explain is reformatting.
- Governance signals — the receipts gateway hooks bind on.