Get Started
Reference

Concepts and glossary

Short definitions for campaigns, slices, findings, and the rest

Audit structure

TermMeaning
ProjectOne repo in one org. All four profiles live here, and so do the findings.
Audit profilesecurity, bugs, hygiene, or pipeline. Owns methodology versions, campaigns and model enablement. See Audit profiles.
MethodologyAn immutable config version: buckets, passes, scopes, prompt sections.
CampaignOne audit of a branch and commit, pinned to one profile and one methodology version.
ParticipantA model code at one effort, such as anthropic/claude-opus-5-5 at xhigh. A binding with no effort is the model's default participant. Projects enable participants, and every per-model count is per participant. See Compare models and efforts.
SliceThe smallest job: one pass × one bucket × one participant. Pending, running, completed, failed, skipped or cancelled (see statuses). failed is retryable until its attempts are spent: invalid runner output does not count as coverage.
LeaseA time-boxed claim on a slice. If it expires, the slice goes back on the queue. First valid accepted result wins.
ReportOne observation parsed out of a model's stdout.

Campaign and slice statuses

A campaign is new (planned, nothing claimed), running, completed or cancelled. completed and cancelled are both terminal. A campaign completes when no slice is outstanding. It is cancelled when a member cancels it, at any point while it is new or running. Cancelled is sticky: completion, a top-up, a repair, a claim and a late result never move a campaign out of it, and a completed campaign cannot be cancelled. Neither can a new or running one with no unfinished slice left: the server answers 409 campaign_terminal ("nothing left to cancel") instead of relabelling it.

Slice statusMeaningClaimableOutstanding (keeps the campaign open)
pendingPlanned, never claimed.yesyes
runningHeld by a lease, live or expired and not yet reclaimed.once its lease expires, with attempts leftyes
completedA valid result won.nono
failedA run produced no valid coverage. Retryable while attempts remain (retryable); once they are spent it is final and no longer outstanding, and the campaign reads degraded.while attempts remainonly while retryable
skippedIts model was disabled (models disable). Revived to pending if the model is re-enabled and a campaign top-up runs.nono
cancelledIts campaign was cancelled while it was pending, running, or failed with attempts left. Final: nothing revives it.nono

skipped and cancelled are both "never to be audited", and a campaign that ends with either is degraded: the gate and wait never read it as a clean pass. They are counted separately in the cancelled key, but for compatibility with agents that predate cancel, skipped is the sum of the two: every API count and the CLI's JSON (wait and progress, on the campaign and on each model row) report skipped = model-disabled + cancelled, with cancelled as an additive subset key. To get the model-disabled part, compute skipped - cancelled. (The cancel preview, and the slices block of campaigns cancel --json, are the exception: their skipped is the model-disabled count alone.) Agent 0.6.0 and older do not know the cancelled key, so for a cancelled campaign they print the "model disabled" wording and count killed slices as failed; their exit code is still not 0, apart from one narrow race where a cancel lands on the last result (see Cancel a campaign).

A cancelled campaign gives its identity back: the next create at the same branch, commit, profile and config version starts a fresh campaign with new slices, which are billed again. Slices already claimed in the cancelled campaign stay billed. The gate reads a cancelled campaign as degraded with reason: "campaign_cancelled", or fail on a new finding from a slice that finished before the cancel.

Finding identity

TermMeaning
FindingThe de-duplicated issue the team triages. Project-wide, not per campaign or branch.
FingerprintA stable hash of the scrubbed report. Used to recognize the same issue again.
AliasAnother fingerprint that was judged to be the same finding (wording drifted, files renamed).
Sighting"We saw this finding in this campaign, on this branch, at this commit." Comparisons use sightings.
KeeperThe finding that stays after a merge.
Soft mergeThe losing finding is pointed at the keeper, not deleted.

A finding can show up in several profiles and on several branches. It still has one triage status. The discovery bucket (discovered_bucket_code) is first-discovery provenance, not a merge boundary. Equivalent reports from different models or buckets can merge. A compound report that covers two or more existing findings (same files, broader root-cause text) is attached to those findings instead of creating a combined one, and those parts are recorded as distinct so a later pass does not fold them back together. Related pairs that do not auto-merge appear on GET /v1/projects/:id/findings/merge-suggestions. A finding whose starter categories belong to Hygiene or Pipeline never merges automatically with one whose categories belong to a different profile; findings with empty or custom categories are not covered by that guard.

Raw reports vs canonical fields

Reports are evidence and are never rewritten: each keeps the model's own severity, categories, text and raw stdout. The finding carries the canonical values the team works with, computed from all of its reports: severity (the highest any report assigned, never lowered by a merge), a display bucket and category (moved only when every report's categories agree on another bucket, otherwise flagged for review), and an evidence basis (demonstrated, speculative for a hardening note, or unclassified). Each canonical value records where it came from (reports, manual, legacy) and why, and every change is kept in the finding's classification history. A person can override any of them; the override stays until it is cleared.

None of these values affect identity. Fingerprints and candidate selection for de-duplication still read the reports' own categories, titles and text. One canonical value does reach the AI de-duplication adjudicator: it receives each finding's canonical severity as input data, now the normalized highest severity (high, not High). The adjudicator prompt is unchanged, so its prompt version (DEDUPE_PROMPT_VERSION) is unchanged and cached pair decisions stay valid.

Identity is decided on arrival and re-checked afterwards. Two models can describe one root cause differently enough that neither report matches the other when it lands; once both findings hold their reports, the pair can become an obvious duplicate, and the later of the two is merged into the keeper then. Triage follows the keeper, and the merged-away fingerprint keeps resolving to it.

Campaign comparison

TermMeaning
BaselineThe "before" campaign. Named explicitly, or the previous one. A cancelled campaign is never a baseline.
NewSighted now, not in the baseline.
ResolvedSighted in the baseline, not now. Do not trust this while slices are still running.
Carried forwardOpen in both.
GateA cheap pass / fail / pending / degraded read for CI. CI does not run models. A cancelled campaign is never pass or pending.

Fixes and retests

TermMeaning
Fix recordDescription, PR, ticket, and one or more commits.
False-positive recordReason, who decided, optional commit it applies through.
Retest campaignRuns the finding's bucket and the passes that match its files.
Fix verificationconfirmed (covered retest did not reproduce it) or regressed (it came back).

Who does what

TermMeaning
ServerPrompts, parsing, fingerprints, de-duplication, triage, storage.
AgentLocal process: git metadata, claim, run a command, upload stdout.
RunnerThe command bound to a model code at one effort. Reads a prompt file, writes marker-delimited JSON.
ArtifactStored prompt, output, or stderr, for provenance.

See campaigns, the runner contract, or the API.

Copyright © 2026