Explainability
Every decision Cortex makes carries provenance — the rule that fired, the episodes that contributed, the confidence label, the agent version, the world version. The explainability surface exposes that provenance as a callable API so your app renders “why did Cortex suggest this?” with substrate-grounded reasoning, not LLM-generated post-hoc rationalization.
The five tools
meta.why_this_action(action_id)— for any action Cortex proposed or executed, returns the rule summary, contributing episodes, confidence label, and version stamps.meta.why_this_notification(notification_id)— for any notification Cortex surfaced, returns the triage class (interrupt_now/surface_at_transition/daily_digest/handle_silently), the contributing signals, and the rule that fired.meta.what_rules_fired(decision_id)— for any decision, returns the full list of rules that participated with their weights and confidence labels.decision.inspect(decision_id)— generalizesmeta.*across decision classes (triage, action_proposed, rule_fired, trust_transition). Returns the reasoning shape, ledger linkage, and occurred_at.decision.history(filter)— paginated read across all decisions for a counterparty, action class, or time window.
Why this is a moat surface, not a marketing claim
Every agent product can claim “explainable AI.” Most ship post-hoc LLM rationalization — ask the model after the fact, render whatever string comes back. That breaks the first time the LLM hallucinates a plausible-but-wrong reason, which is the first time it matters.
Cortex's explainability is substrate-grounded: the rule_id maps to a concrete row in the rulebook; the contributing episodes are real episode_id references you can pull via memory.inspect; the agent_version + world_version pair makes the decision reproducible. There is no LLM in the explainability read path.
Example: rendering a “why?” affordance under a draft
// User taps "Why did Cortex suggest this?" under a draft message
const explanation = await cortex.tools.call('meta.why_this_action', {
action_id: draftedAction.id,
});
// Render the rule summary + confidence + linked episodes
return (
<Explanation>
<p>{explanation.rule_summary}</p>
<Confidence label={explanation.confidence} />
<ProvenanceList episodes={explanation.contributing_episodes} />
</Explanation>
);What you don't get
- No LLM inference. Reads are Postgres / Aurora only. They count against the
daily_substrate_read_callsquota, notdaily_tool_calls. - No latency from external model calls. The provenance is already materialized in
action_ledger+triage_decisionsat decision time. - No reasoning drift. The same
decision_idreturns the same provenance every time.world_versionis the reproducibility key.
Cross-references
- Tool:
meta.why_this_action - Tool:
decision.inspect - Concept: Counterparty depth — pairs naturally with explainability for “why this counterparty?” reasoning.
- ADR-0021 §read-API (Family A — Explainability), ADR-0020 (per-tool boundary).