Skip to content

Findings API

The Findings API exposes Finding clusters, diagnostic settings, built-in Rules, on-demand analysis Runs, time-window backfills, and provider-neutral repair work items.

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

Base URL:

text
https://api.provon.dev/v1

Project API keys need diagnostics:read for read routes and diagnostics:write for mutation routes. Signed-in Workbench sessions can use the same project-qualified routes when the user has the corresponding project permission.

Findings#

Method Path Purpose
GET /projects/:projectId/diagnostics/findings List Finding clusters
GET /projects/:projectId/diagnostics/findings/:findingId Read one Finding and its primary work item
PATCH /projects/:projectId/diagnostics/findings/:findingId Update review or resolution state
POST /projects/:projectId/diagnostics/findings/discover Analyze the latest conversation activity snapshot
GET /projects/:projectId/diagnostics/findings/:findingId/work-items List work items for a Finding
GET /projects/:projectId/diagnostics/findings/:findingId/work-items/:workItemId Read one work item
POST /projects/:projectId/diagnostics/findings/:findingId/work-items Create and confirm a repair handoff

List query parameters:

Parameter Type Notes
reviewStatus unreviewed, confirmed, or dismissed Optional filter
resolutionStatus unresolved, awaiting_verification, resolved, regressed Optional filter
severity critical, high, medium, low, info Optional filter
minDiagnosticScore number from 0 to 1 Optional filter
lastDetectedAfter Unix milliseconds Inclusive lower bound
lastDetectedBefore Unix milliseconds Exclusive upper bound
limit integer from 1 to 500 Page size
cursor opaque string Cursor from prior result

lastDetectedAfter must be earlier than lastDetectedBefore.

List responses include findings, each with its primary workItem, plus pagination.limit and pagination.nextCursor.

Read a Finding#

http
GET /v1/projects/:projectId/diagnostics/findings/:findingId

Response:

json
{
  "id": "fnd_...",
  "clusterFingerprint": "...",
  "fingerprintVersion": "finding-cluster-v1",
  "reviewStatus": "unreviewed",
  "resolutionStatus": "unresolved",
  "severity": "high",
  "diagnosticScore": 0.85,
  "diagnosticConfidence": 0.82,
  "title": "Required verification was skipped",
  "summary": "The agent claimed completion without running the required verification.",
  "causeAssessment": "The first uncorrected fault is the omitted verification step.",
  "remediationHint": "Run and report the required verification before claiming completion.",
  "metadata": {
    "categoryKey": "goal_not_verified",
    "diagnosticRule": {
      "ruleId": "rule_...",
      "ruleKey": "task-fulfillment"
    }
  },
  "firstDetectedAt": 1760000000000,
  "lastDetectedAt": 1760000000000,
  "conversationId": "conv_123",
  "diagnosticAnchor": {
    "conversationId": "conv_123",
    "traceId": "trace_123",
    "spanId": "span_123",
    "stepIndex": 8,
    "quotes": [{ "quote": "I have completed the task." }]
  },
  "evidence": [
    {
      "ref": "span_123",
      "kind": "span",
      "title": "verify-answer",
      "summary": "Verification span was never executed.",
      "url": null,
      "location": {
        "traceId": "trace_123",
        "spanId": "span_123",
        "stepIndex": 8,
        "quotes": [{ "quote": "I have completed the task." }]
      }
    }
  ],
  "evidenceWindow": {
    "startMs": 1760000000000,
    "endMs": 1760000100000,
    "conversationIds": ["conv_123"]
  },
  "analysisRevision": "drv_...",
  "evidenceSnapshotRevision": "cesr_...",
  "evidenceThroughMs": 1760000100000,
  "createdAt": 1760000200000,
  "updatedAt": 1760000200000,
  "reviewedAt": null,
  "resolvedAt": null,
  "regressedAt": null,
  "workItem": null
}

Update review or resolution#

Supported PATCH fields (send one at a time):

json
{
  "reviewStatus": "confirmed"
}
json
{
  "resolutionStatus": "resolved"
}

reviewStatus can be unreviewed, confirmed, or dismissed. Manual resolution uses resolutionStatus: "resolved" | "unresolved". Dismissal atomically clears resolution state. reviewStatus and resolutionStatus cannot be updated in the same request.

A Finding with an active work item (provisioning, planned, or in_progress) cannot be dismissed or manually resolved. The API returns 409 ACTIVE_WORK_ITEM or 409 WORK_ITEM_NOT_DONE.

Discover latest Findings#

Queue diagnostic discovery for the latest activity snapshot of one conversation:

http
POST /v1/projects/:projectId/diagnostics/findings/discover

Response:

json
{
  "conversationId": "conv_123",
  "outcome": "findings_found",
  "findings": []
}

outcome is findings_found or no_findings. This endpoint is synchronous: it analyzes the latest conversation snapshot and returns the produced Findings directly. It is not a backfill.

Work Items#

Work-item creation accepts provider: "github" | "gitlab" | "linear" | "jira" and an optional provider destination object. The configured connector default is used when destination is omitted.

http
POST /v1/projects/:projectId/diagnostics/findings/:findingId/work-items
json
{
  "provider": "github",
  "destination": {
    "owner": "provon",
    "repo": "provon"
  }
}

Lifecycle actions:

text
POST .../work-items/:workItemId/sync
POST .../work-items/:workItemId/retry
POST .../work-items/:workItemId/replacements
POST .../work-items/:workItemId/abandon
  • Retry only works for a failed provisioning attempt (status: provisioning, externalId: null, syncState: error).
  • Replace creates a new work item in another provider and accepts the same provider and destination body as creation.
  • Abandon only detaches the local handoff; it does not close the external issue.
  • Sync returns { outcome, finding }. outcome can be updated, unchanged, failed, not_syncable, or not_current.

Settings#

Method Path Purpose
GET /projects/:projectId/diagnostics/settings Read automatic scheduling settings
PATCH /projects/:projectId/diagnostics/settings Enable or disable automatic scheduling

Patch body:

json
{
  "automaticSchedulingEnabled": true
}

Rules#

Method Path Purpose
GET /projects/:projectId/diagnostics/rules List built-in Rules and configuration
GET /projects/:projectId/diagnostics/rules/:ruleId Read one Rule
PATCH /projects/:projectId/diagnostics/rules/:ruleId Enable/disable or reconfigure one Rule
POST /projects/:projectId/diagnostics/rules/:ruleId/backfill-requests Queue a time-window backfill

Patch either enabled:

json
{
  "enabled": false
}

or configuration:

json
{
  "configuration": {
    "keywords": ["checkout", "payment"],
    "minSignalScore": 0.25,
    "minDiagnosticConfidence": 0.5,
    "adjudicationMode": "auto",
    "adjudicationModel": null,
    "signalOverrides": {
      "runtime_error": { "enabled": true, "severity": "high" }
    }
  }
}

adjudicationMode can be auto or deterministic-only. Signal override severities can be critical, high, medium, low, or info.

Backfill body:

json
{
  "startMs": 1760000000000,
  "endMs": 1760086400000,
  "maxConversations": 100
}

Backfill responses use 202 when Runs are queued. Include an Idempotency-Key header to avoid duplicate backfills for the same rule and window. The default maxConversations is 10,000 and the maximum is 100,000.

On-Demand Runs#

Queue enabled Rules for one conversation activity snapshot:

http
POST /v1/projects/:projectId/diagnostics/analysis-runs
json
{
  "conversationId": "conv_123",
  "lastActivityAt": 1760000000000,
  "traceIds": ["trace_123"]
}

conversationId and lastActivityAt are required. traceIds is optional and is filtered to string values. Response:

json
{
  "enabledRules": 5,
  "runsCreated": 1
}

Common Errors#

HTTP Code When
400 INVALID_FILTER Unsupported enum value, malformed cursor, or lastDetectedAfter >= lastDetectedBefore.
404 FINDING_NOT_FOUND Finding or referenced work item does not exist.
404 DIAGNOSTIC_RULE_NOT_FOUND Rule does not exist.
404 DISCOVERY_CONVERSATION_NOT_FOUND No recent conversation found for discovery.
409 DISCOVERY_CONVERSATION_NOT_READY Latest conversation is not ready for analysis.
409 ACTIVE_WORK_ITEM Cannot dismiss a Finding with an active work item.
409 WORK_ITEM_NOT_DONE Cannot resolve a Finding whose work item is not done.
409 WORK_ITEM_ALREADY_EXISTS A primary work item already exists for this Finding.
409 WORK_ITEM_NOT_CURRENT The work item was replaced or is no longer primary.
409 WORK_ITEM_NOT_RETRYABLE The work item is not a failed provisioning attempt.
409 FINDING_DISMISSED Cannot create a work item for a dismissed Finding.
503 WORK_ITEM_PROVIDER_UNAVAILABLE Connector is missing, disabled, or default destination is unset.
503 DIAGNOSTIC_RULES_UNAVAILABLE Diagnostic rule service is not mounted in this deployment.
503 FINDING_WORK_ITEMS_UNAVAILABLE Work item service is not mounted in this deployment.