Decision Explanation
Explain why a decision occurred, including which policies triggered, which policy won, and which policies did not apply.
Decision Explanation answers "why did this happen" for one decision: which policies fired, which of those won, and — the harder question — which published policies could have fired on this call but didn't. It renders as a drawer inside the Decisions Log rather than its own page, backed by GET /api/dp/v1/decisions/{id}/explain, which lives in the gateway package rather than in the telemetry module itself.
The winner and any triggered-but-lower-priority rules come straight from the decision's own matched_rules data — the enforcer tags each match with an outcome (winner or triggered_lost) at evaluation time. Decision rows written before that tagging existed carry no outcome tag at all; those are treated as winners for backward compatibility rather than surfaced as an unexplained gap.
Not-triggered policies are computed on demand rather than stored — persisting them for every decision would make a 50-plus-rule bundle's worth of rows dominate storage. The lookup scans every published rule bound to the call's MCP server, or to any tool, resource, table, or column beneath it, and subtracts whatever already triggered. Each leftover rule gets a coarse, attach-type-derived reason — "call didn't invoke this tool," "subject didn't match this rule's selector" — rather than a full re-run of the evaluator against that rule.
The verdict reason string itself prefers the enforcer's own explanation, recorded on the invocation at decision time, falling back to the decision's separately recorded effective context only when the primary field is empty.
Reference
Features
- description
- The single matched rule whose priority won the decision, tagged 'winner' by the enforcer at evaluation time.
- description
- Rules that also matched the call but were outranked by the winner — tagged 'triggered_lost' — shown so an operator can see what almost decided the call.
- description
- Every published rule bound to the call's MCP server, or to a tool, resource, table, or column beneath it, that did not match — computed on demand from the current rule set with a coarse reason for each, rather than stored per decision.
- description
- The decision's explanation string, taken from the enforcer's own reasoning when present, otherwise from the decision's recorded effective context.

Docs