Skip to content

Explainable Provenance

trails.explain traces PROV-O provenance chains and produces human-readable explanations of how a result was derived. It builds citation graphs, propagates confidence scores through derivation chains, and supports counterfactual analysis ("what would change if this source were removed?").

Operates entirely on existing provenance triples -- no AI/LLM dependency.

See ADR-0038 for the full design rationale.

Quick start

from trails.explain import (
    explain_result,
    citation_graph,
    propagate_confidence,
    counterfactual,
    format_explanation,
)

# Trace an activity and get a structured explanation
explanation = explain_result(store, activity_iri, max_depth=10)
print(f"Confidence: {explanation.confidence:.2f}")
print(f"Citations: {len(explanation.citations)}")

# Render as markdown or plain text
print(format_explanation(explanation, fmt="markdown"))

# Build a citation graph: {node_iri: [activities that used it]}
cites = citation_graph(store, activity_iri)

# Walk derivation chains and compute confidence per node
confidences = propagate_confidence(store, node_iri, base_confidence=0.9)
# {"node_iri_1": 0.9, "derived_node": 0.81, ...}

# Counterfactual: what breaks if we remove a source?
affected = counterfactual(store, remove_iri="urn:source:42", activity_iri=root_iri)
for entry in affected:
    print(f"  Activity {entry['activity']} depends via {entry['dependency_path']}")

Key types

Type Description
Citation Reference from an activity to a source node: node_iri, node_type, relevance, accessed_by
ReasoningStep One step in a reasoning chain: step_number, action, cited_nodes, confidence_contribution
Explanation Structured result: answer, citations, confidence, reasoning_chain, provenance_iris

API

Function Signature Description
explain_result (store, activity_iri, *, max_depth=10) -> Explanation Trace provenance and produce a structured explanation
citation_graph (store, activity_iri, *, max_depth=10) -> dict[str, list[str]] Map of {node_iri: [activities that used it]}
propagate_confidence (store, node_iri, base_confidence=1.0, *, max_depth=10) -> dict[str, float] Walk derivation chains, compute per-node confidence
counterfactual (store, remove_iri, activity_iri, *, max_depth=10) -> list[dict] Estimate impact of removing a source node
format_explanation (explanation, fmt="text") -> str Render as "text", "markdown", or "json"