Skip to content

Diagnostic Rules

Provon ships five built-in Diagnostic Rules. Each Rule runs its signal detectors over the normalized conversation trajectory, applies thresholds, and decides which candidates need model review. Rules are configured per project: enable or disable a Rule, tune its thresholds, and override individual finding types.

View as Markdown Open the plain-text version of this page.

The unified finding taxonomy#

The catalog uses one set of 14 finding types; a detected type is exported verbatim with no remapping layer. Each type sits on three orthogonal axes:

  • type — what went wrong (the user-facing defect class);
  • stage — where in the agent loop it surfaced (6 stages);
  • attribution — who is responsible: agent, environment, or input.

A weak causal role prior (root / symptom) seeds root-cause ranking; actual causality comes from detector-declared edges and shared evidence. The Detector column distinguishes types a deterministic family can close (signal) from types reachable only through model discovery (review).

Type Label Stage Attribution Causal role Detector
goal-misunderstood Goal Misunderstood planning agent root review
plan-step-omitted Plan Step Omitted execution agent symptom signal
constraint-violated Constraint Violated execution agent root signal
capability-mismatch Capability Mismatch execution agent root signal
capability-unavailable Capability Unavailable execution environment root review
invalid-tool-precondition Invalid Tool Precondition execution agent root signal
tool-result-misread Tool Result Misread verification agent root signal
retrieval-insufficient Retrieval Insufficient execution agent root review
unsupported-claim Unsupported Claim final-answer agent symptom signal
safety-policy-block Safety Policy Block runtime environment root signal
runtime-interruption Runtime Interruption runtime environment root signal
input-underspecified Input Underspecified understanding input root review
incoherent-answer Incoherent Answer final-answer agent symptom signal
repetition-no-progress Repetition / No Progress execution agent root signal

Stages, in agent-loop order: understanding, planning, execution, verification, final-answer, runtime.

Built-in Rules#

Rule Key Finding types
Runtime reliability runtime-reliability runtime-interruption, safety-policy-block, incoherent-answer
Tool correctness tool-correctness tool-result-misread, invalid-tool-precondition, repetition-no-progress
Task fulfillment task-fulfillment goal-misunderstood, plan-step-omitted, retrieval-insufficient, capability-mismatch, input-underspecified
Answer grounding answer-grounding unsupported-claim
Safety safety constraint-violated

capability-unavailable is not bound to a built-in Rule's signal set; it can be proposed by model discovery (whole_trajectory policy) and reviewed like any other candidate. Signal overrides apply only to types the Rule actually detects; overrides for unknown types are ignored.

What the pure-rule sweep can recall#

On the no-model rule-signals profile (provon diagnose --mode rule-signals), a candidate publishes only when a detector closes it from structured or lexical evidence. The deterministic sweep covers:

  • safety-policy-block — an explicit provider content-filter error (content filter, Azure content-management policy, jailbreak detected) or a self-reported rendered gate (anti-bot challenge page).
  • repetition-no-progress — the same operation repeated past a threshold, or a blind run of consecutive operations returning no usable observation.
  • incoherent-answer — a terminal answer that is empty, garbled, or an uncontextualized bare value with no sentence structure; a surface-form test, so a task that genuinely needs a bare value is not a defect.
  • unsupported-claim, invalid-tool-precondition, tool-result-misread, plan-step-omitted, constraint-violated, and capability-mismatch in their high-confidence closed cases.

The remaining types require semantic or causal inference and are reachable only via model discovery or review: goal-misunderstood, retrieval-insufficient, input-underspecified, capability-unavailable, and the bulk of tool-result-misread. A budget marker ("max time/rounds reached") is detected, but whether it is the independent root cause versus a symptom needs attribution, so it is reviewed rather than auto-published.

Configuration options#

Option Default Where set Description
keywords [] Popover + API One per line; when non-empty, the Rule only evaluates conversations containing at least one keyword (case-insensitive over captured conversation text)
minDiagnosticConfidence 0.25 Popover + API Minimum diagnostic confidence to publish a candidate; lower candidates are filtered
reviewModel null Popover + API Override the deployment-default reviewer model; null uses the default
signalOverrides {} Popover signal list Per-type enabled: false or severity override
lexicon {} Popover lexicon section Locale selection, built-in cue ids to disable, and extra cues appended to lexicon tables; the supported way to add product/domain wording
minSignalScore 0.25 API Minimum signal score to enter the pipeline; lower signals discarded before review and grouping
reviewerDiscoveryPolicy candidates_only API candidates_only reviews only Rule-produced candidates (clean conversations make no call; fail-closed); whole_trajectory also scans the full trajectory (one model call even on a clean conversation)
detectorSettings {} Popover field (must stay empty) + API Reserved for internal detector thresholds and switches. Only an absent/empty object is accepted; the popover field renders but must be left empty, and any populated group is rejected by the API. No public per-detector tuning groups exist in this build

A Rule PATCH sends a complete configuration object (it replaces the stored configuration rather than merging), so include every key together. Production Rules always run the reviewed-diagnosis profile; the no-model deterministic screen is only available locally through provon diagnose --mode rule-signals.

Signal triage and admission#

Each signal passes two deterministic layers. The detector-layer triage reads only the signal's own evidence and uses no review vocabulary:

  • admissible with an evidence kind:
    • mechanical_predicate — the Rule can establish the finding mechanically;
    • verifiable_predicate — the finding holds once its deterministic proof closes;
    • lexical_lead — a concrete lexical seed the Rules cannot close themselves.
  • proof_not_closed — the deterministic proof for a verifiable_predicate signal does not close.
  • withheld with an objective mechanical reason (below threshold, recovered, no precise evidence, no terminal impact, and so on).

The outer admission layer applies runtime policy:

  • model review enabled: every admissible signal goes to the reviewer (mechanical/verifiable ones for confirmation; lexical leads for closure judgment);
  • no-model rule-signals profile: mechanical_predicate and closed verifiable_predicate signals publish as deterministic; a lexical_lead is withheld as model_review_unavailable.

Evidence requirements apply per review family (the signal's evidence-collection strategy), not per type. Production is fail-closed: no available model withholds as model_review_unavailable; a throwing call or execution failure becomes model_review_error; a model returning no definite verdict becomes model_review_inconclusive. No candidate is promoted, and the run retains audit counters.

Publication funnel#

Every diagnosis reports an unambiguous, model-first funnel returned on the discovery API, printed by provon diagnose (funnel), emitted as diagnostics.* span attributes, and aggregated in eval metadata.

Layer / Field Meaning
profile rule-signals / reviewed-diagnosis; aggregate of unlike runs reports mixed; carried on the result, never guessed
candidate.ruleCount Candidates from the deterministic detector sweep
candidate.modelDiscoveredCount Candidates from the conversation-level discovery pass that survived the deterministic post gate; 0 when nothing new is proposed
candidate.mergedCount Deduped union entering the gate
mechanicalGate.filteredCount Candidates stopped by score/confidence/evidence/impact/corroboration before review or publication
mechanicalGate.verifiedCount Candidates that cleared the gate
mechanicalGate.weakLeadWithheldCount Weak one-event lexical leads withheld for insufficient corroboration; never surfaced even as a lead
mechanicalGate.withheldReasons Per-reason breakdown keyed by stable reason code
publication.publishedCount Confirmed Findings actually recorded; provider failure leaves this 0 while counters remain
publication.deterministicPublishedCount Findings confirmed deterministically, no model adjudication
publication.leadCount Credible-but-unclosed leads in the non-scored review tier
publication.postFilteredCount Verified candidates absorbed by causal grouping or the publication cap
publication.rejectionReasons Per-reason breakdown (reviewer dismiss/duplicate plus deterministic rejection)
review.* Structured-review outcomes; absent entirely in rule-signals mode; holds reviewed/accepted/rejected/abstained/failure counters, model usage flags, and error

Reconciliation: under reviewed mode, review.acceptedCount = publication.publishedCount + review.postGateRejectedCount. A one-event lexical lead without corroboration is withheld at the mechanical gate as insufficient_corroboration (weakLeadWithheldCount); it differs from model_review_unavailable, the fail-closed withhold of a candidate the review boundary never closed.

How to tune#

Reduce false positives#

  1. Increase minDiagnosticConfidence for the Rule.
  2. Disable noisy finding types with signalOverrides.
  3. Add keywords so the Rule only runs on relevant conversations.

Example API patch (the whole configuration is replaced):

json
{
  "configuration": {
    "keywords": ["payment", "refund"],
    "minSignalScore": 0.25,
    "minDiagnosticConfidence": 0.7,
    "reviewerDiscoveryPolicy": "candidates_only",
    "reviewModel": null,
    "signalOverrides": {
      "repetition-no-progress": { "enabled": false },
      "incoherent-answer": { "severity": "info" }
    },
    "lexicon": {},
    "detectorSettings": {}
  }
}

Control cost in high-volume pipelines#

The default candidates_only policy bounds cost: a clean conversation where no Rule fired makes no model call; any conversation with a candidate is still reviewed.

  • Switch to whole_trajectory only when you want issues the Rules never hinted; it makes one model call on every conversation, including clean ones.
  • Production Rules always run the reviewed-diagnosis profile; there is no server-side no-model option. Use the local rule-signals profile for deterministic screening.

CI screening#

provon diagnose --mode rule-signals skips the model and publishes only signals confirmable from structured evidence; expect lower recall for review-gated types such as unsupported-claim. Server-side Rules stay on the candidates_only default for persisted Findings.

Severity levels#

Severity When to use
critical Agent produced a wrong or harmful outcome with high confidence
high Clear failure mechanism likely affecting user value
medium Detected problem that may be recoverable or context-dependent
low Minor degradation, noise, or best-practice violation
info Observation that does not require immediate action

Limitations#

  • Review-only types never publish under the local deterministic profile; absence locally is not absence on the reviewed server profile.
  • Keyword filters narrow scope but also suppress every type on unmatched conversations.
  • A high-confidence deterministic signal still follows the Rule's configured confidence and publication gates.