Assessment and reports
How hypotheses are assessed, how a report reaches its conclusion, what the report contains, and how human resolutions are recorded separately.
What makes an explanation testable
| Field | Purpose |
|---|---|
id, statement | A stable identity and a falsifiable explanation. |
causal_path | Entities in the incident graph, starting where the fault originates. |
evidence_needed | Registered query IDs whose facts cover the predictions and falsifiers. |
predictions | Facts expected if the explanation holds. |
falsifiers | Facts that would contradict it. |
Assessment
A hypothesis is supported only if every prediction is supported by a usable fact and no falsifier holds. Contradiction takes precedence. Missing, conflicting or degraded facts leave it unresolved.
| State | Meaning |
|---|---|
supported | The facts agree with it. This is evidence support, not causal proof. |
contradicted | A prediction fails, or a falsifier holds. |
unresolved | The facts are missing, degraded, conflicting or not enough to decide. |
How a report reaches its conclusion
A diagnosis requires the supported explanations to agree on one root cause. A Kubernetes resource that hosts a service counts as that service. If two supported explanations name different roots, the conclusion is insufficient_evidence and both are listed: Lumis does not invent a ranking. With no usable evidence, the conclusion is insufficient_evidence or requires_human_expert.
What the report contains
| Field | Content |
|---|---|
context | The incident, scoped graph, queries and evidence. |
findings | Each check's finding with its assessment. |
assessments | Each candidate hypothesis and its state. |
receipts | Redacted records of every query and tool call. |
suggestions | Tentative, text-only next steps for a person. |
unresolved_questions | What the evidence could not settle, and why candidates were dropped. |
route | deterministic, agent or human. |
conclusion | supported_diagnosis, insufficient_evidence or requires_human_expert. |
stop_reason | Why the investigation ended. |
metrics | Model requests, tokens, tool attempts, evidence queries and probes. |
truth_state, requires_human_review | Always unconfirmed_hypothesis and true. |
The report does not store the model's raw reasoning or the full provider conversation. Callers that need it for evaluation can read PydanticInvestigator.messages in memory.
Audit records and human resolutions
IncidentStore.save(report) writes the report, evidence and receipts to SQLite in one transaction. Saving the same incident ID twice is refused. After a person has dealt with the incident, they can append a separate resolution record:
{
"id": "review-001",
"incident_id": "api-001",
"reviewer": "operator",
"recorded_at": "2026-10-05T12:00:00Z",
"summary": "Restarted the API after the report; health checks recovered.",
"applied_change": "Manual restart by the on-call engineer; not executed by Lumis.",
"outcome": "resolved",
"evidence_references": []
}lumis record-resolution --store incidents.sqlite --resolution resolution.json --confirmOutcomes are resolved, not_resolved or inconclusive. A resolution never changes the diagnosis, executes anything or creates a new rule.
Source: Incident investigation ↗ in the SDK repository.