Know exactly what your AI did, and why

Signed events become structured incidents with root cause, blast radius, and a next step - and explain() tells you the verdict before you ever send the prompt.

Root cause

Scored, not guessed

Blast radius

Users, tools, spend

Next step

Named per incident

0 side effects

explain() dry runs

An answer, not an alert

Violations escalate themselves

A policy hit becomes a structured incident, not a log line, and routes to Slack or PagerDuty.

policy block · PII · auth abuse · runaway loop

Root cause, scored

Each incident names the determining rule and the events behind it, with a confidence score on the correlation.

determining rule · contributing events · confidence

Blast radius

Users, sessions, tools, models, and spend hit by an incident, computed straight from the signed trail.

users · sessions · tools · spend

Recommended actions

A concrete next step per incident, with the whole open, acknowledged, resolved lifecycle recorded.

open → acknowledged → resolved

Signed incident reports

Export the full timeline with root cause, MTTR, and notified parties, ready for a 72-hour GDPR Article 33 filing.

incident-response.md · export-ready

Pivot on anything

Select any user, tool, or model and see everything else it touched across the trail.

cross-reference from the same signed events

INC-20260501-a1b2 · PII Detectedacknowledged
Root causeMRN present in model output · rule phi-redaction disabled 3 days ago
Confidence0.94 on the correlation
Blast radius2 sessions · 1 user · gpt-4o · $0.41 spend
Recommended actionRe-enable PHI Redaction on project acme-clinical
Evidence7 signed events · seq 118-124 · sealed by root 2026-05-01

Illustrative incident. Every field is computed from the signed trail.

The dry run for governance

explain() answers the counterfactual

The same PII scan and policy evaluation a real call would run, returning the verdict without sending anything anywhere.

decision · rule_id · rules_hash · pii · shadow_outcome

No side effects, by construction

No quota consumed, no events emitted, no approvals filed, and anything not evaluated is named rather than silently omitted.

not_evaluated: ['customer_hook', 'multi_turn_injection']

Byte-identical policy hashes

Node and Python derive the same rules_hash from the same rules, so explain() in CI proves a policy change did what you intended.

@obsvr/sdk · obsvr (Python) · identical rules_hash

explain · no call sent
const verdict = explain('My key is sk-live-abc123, is it valid?')

decision block
rule_id ex-block-secrets
rules_hash e8c53c78786308e7
pii detected: true · types: ['api_key']
✓ no quota consumed · no events emitted

One surface for every governed call

One live event stream

Every governed call lands on one timeline with model, latency, verdict, and incident reference, so exceptions stand out against the baseline.

model · latency · verdict · incident ref

Policies edited live

Dashboard edits reach live SDKs within minutes with no redeploy, and each change is itself a signed, diffable event.

edit · propagate in minutes · diffed and signed

Drift is an event

Model swaps, SDK upgrades, and config changes are logged and diffed, with unauthorized changes flagged.

model versioning · config drift · SOC 2 CC7.5

The question that gets asked a quarter later

Reconstruct any moment

Which model version and policy were live last quarter comes from the anchored trail, not a dashboard that ages out.

obsvr-provenance --at 2026-01-14

Right to explanation

The model, policy state, inputs, and output behind any automated decision are reproducible long after the fact.

EU AI Act Art. 86 · GDPR explainability