# Findings

A Finding is Provon's core artifact: a supported, actionable problem distilled from agent
conversation evidence. It is more specific than a trace error and more durable than an alert.

Use this page for the conceptual model, then see:

- [Quickstart](../get-started/quickstart.md) — first trace-to-Finding flow.
- [Repair loop](../get-started/repair-loop.md) — turn supported failures into scoped repair work.
- [Repair handoff and connectors](./repair-handoff.md) — GitHub, GitLab, Linear, and Jira work items.
- [Findings API](../api/findings.md) — HTTP contract for automation.
- [Trace diagnosis with CLI](../cli/diagnose.md) — local, non-persisted diagnosis.
- [Get started troubleshooting](../get-started/troubleshooting.md) — no findings, false positives, and work-item errors.

## Rule, Run, Finding, Occurrence

Provon keeps diagnosis in three layers:

| Layer      | Responsibility                                                   | Persistent result                                        |
| ---------- | ---------------------------------------------------------------- | -------------------------------------------------------- |
| Rule       | Defines which signals to detect and the publication thresholds   | Project configuration                                    |
| Run        | Applies one Rule to one conversation activity snapshot           | Queued, running, completed, skipped, or failed execution |
| Finding    | Groups the same supported failure mechanism across conversations | Review and resolution aggregate                          |
| Occurrence | Records one concrete observation of a Finding                    | Durable evidence, activity revision, and evidence window |

The execution path is:

```mermaid
flowchart LR
  spans["OTel spans"] --> facts["Conversation facts"]
  facts --> signals["Diagnostic signals"]
  signals --> adjudication["Adjudication"]
  adjudication --> candidates["Finding candidates"]
  candidates --> occurrences["Finding occurrences"]
  occurrences --> findings["Finding clusters"]
```

A Rule Run can complete without publishing a Finding. That is the expected result for healthy
conversations or candidates below the configured thresholds.

## In The Workbench

The **Findings** page shows clusters ranked by diagnostic score. Use the filter scope to switch
between **active**, **dismissed**, **resolved**, and **all**.

The **Diagnostic rules** popover in the Findings page lists the five built-in Rules:

| Rule                | Detects                                                                                       |
| ------------------- | --------------------------------------------------------------------------------------------- |
| Runtime reliability | Runtime errors, incomplete termination, and false success after execution failures            |
| Tool correctness    | Failed tool loops, ignored negative results, and incorrect tool-result interpretation         |
| Task fulfillment    | Missing required actions, skipped verification, constraint failures, and premature completion |
| Answer grounding    | Unsupported final answers and unsupported external claims                                     |
| Conversation health | Runaway context growth and trajectories that fail to converge                                 |

Each Rule can be enabled or disabled, and each exposes:

- **Keywords**: only evaluate conversations containing at least one configured keyword.
- **Publication confidence** (`minDiagnosticConfidence`): the minimum confidence required to publish
  a candidate as a Finding. Default `0.25`.
- **Minimum signal score** (`minSignalScore`): the minimum score for a signal to enter diagnosis.
  Default `0.25`.
- **Adjudication mode**: `auto` (deterministic signals plus model adjudication) or
  `deterministic-only` (no model calls).
- **Adjudication model**: override the deployment default for signals that need judgment.
- **Signal overrides**: enable or disable individual category kinds and override their severity.

See [Diagnostic rules](#rule-run-finding-occurrence) on this page for the full category reference and tuning guidance.

## Automatic And Manual Runs

Automatic scheduling is disabled when a project is first created. Enable **Auto-diagnose** on the
Findings page to schedule Runs for newly ingested conversations.

Automatic behavior:

1. New trace activity is mapped to a stable conversation identifier.
2. Enabled Rules are queued for that conversation activity snapshot.
3. Each Run becomes available after **10 minutes of inactivity**.
4. Newer activity supersedes an older automatic snapshot.
5. Duplicate Runs for the same Rule, conversation, and activity snapshot are not created.

For existing data, open **Diagnostic rules** and run an enabled Rule against the last 24 hours. The
API also supports explicit time-window backfills and on-demand Runs.

## Reading A Finding

The inbox ranks Finding clusters by diagnostic score and then by creation time. Review state and
repair state remain visible separately rather than changing the canonical score ordering.

Expand a row to inspect:

- **Severity**: `critical`, `high`, `medium`, `low`, or `info`.
- **Diagnostic score**: the strength and impact used to rank the diagnosed problem.
- **Diagnostic confidence**: how strongly the available evidence supports the diagnosis.
- **Cause assessment**: the most likely supported cause.
- **Remediation hint**: a focused repair direction, not an automatic code change.
- **Latest occurrence evidence**: trace, span, or aggregate references with locations and quotes.
- **Evidence window**: the activity used for the latest occurrence.
- **Occurrence count**: distinct observations grouped under the same cross-conversation failure
  mechanism.

Score and confidence are separate. A high-impact problem can still have low confidence, and a
well-supported issue can be low severity.

## Review And Repair Lifecycle

Review state and repair state are deliberately independent:

```mermaid
flowchart LR
  unreviewed["reviewStatus: unreviewed"] --> confirmed["reviewStatus: confirmed"]
  unreviewed --> dismissed["reviewStatus: dismissed"]
  confirmed --> issue["Finding work item"]
  issue --> verify["awaiting verification"]
  verify --> resolved["resolved"]
  resolved --> regressed["new later occurrence"]
```

- **Confirm** accepts the Finding as actionable.
- **Dismiss** removes it from the default inbox without deleting its evidence.
- **Create work item** creates a provider issue and confirms the Finding in one action.
- **Resolve manually** closes a Finding even when no external tracker is connected.
- **Retry**, **Replace**, and **Abandon** recover failed or disconnected handoffs without deleting
  their history.
- **Resolved** means repair was verified automatically or explicitly by a user.
- **Regressed** means a new occurrence was observed after `resolvedAt`.

Important constraints:

- A Finding with an active work item (`provisioning`, `planned`, or `in_progress`) cannot be
  dismissed or manually resolved.
- Creating a work item automatically confirms the Finding.
- Replaying the same activity revision is idempotent and does not increase the occurrence count.
- Historical backfills cannot regress a Finding resolved after that historical evidence.

Provon never checks out the repository or applies a patch. A user, Claude Code, Codex, or another
controlled coding-agent workflow consumes the external work item and produces the repair.

## Repair Handoff

Repair handoff supports GitHub, GitLab, Linear, and Jira. Configure an enabled project connector
with a default destination before creating a work item.

Each issue contains:

```text
Goal
What is wrong
Cause assessment
Evidence
Verification
Provon correlation metadata
```

All supported providers receive a stable marker derived from the Finding work-item ID so retries
can recover a remotely created issue after a local commit failure. GitHub can automatically verify
a merged pull request with successful checks. GitLab, Linear, and Jira completion enters
`awaiting_verification` until a user verifies the repair.

See [Repair handoff and connectors](./repair-handoff.md) for OAuth, token, and repository configuration.

## Data Requirements

Diagnosis works best when telemetry preserves:

- a stable `gen_ai.conversation.id`;
- the user's goal and constraints;
- ordered assistant, model, and tool events;
- tool inputs, results, failures, and retries;
- a terminal answer or explicit non-completion;
- trace and span identifiers for evidence links.

If conversation identity or raw span evidence is missing, Provon may still show telemetry while
skipping diagnosis because no usable trajectory can be reconstructed.

See [Diagnosis-ready tracing](../tracing/best-practices.md) for the practical review workflow and
[Trace model and instrumentation](../tracing/trace-model.md) for boundary guidance.

## CLI Diagnosis

`provon diagnose <source>` runs the same built-in Rule definitions over a trace source. Results are
returned to the caller only: they are not persisted, do not enter the Findings inbox, and cannot
create a repair issue. Persisted Findings are produced separately by server-side Rule Runs over
ingested project evidence.

See [Trace diagnosis with CLI](../cli/diagnose.md) for deterministic screening and hash-bound Agent
adjudication.
