Triage

Triage findings as a team with project-level identity and branch attribution

Findings live at the project level with branch attribution — not per-campaign. That means triage decisions carry across branches and across merges/renames, and "show only NEW issues on this PR" is first-class.

Set a status

Every human action records actor attribution (actor_user_id, nullable for system/client actions). Statuses you can set on a finding:

  • Open — default for a newly discovered finding.
  • Fixed — you believe it's resolved (a retest campaign can verify).
  • Won't fix — accepted risk; stays suppressed on derivative branches.
  • False positive — recorded with a reason; feeds back into dedupe tuning.

See what's new on a PR

The PR gate reports open findings whose earliest sighting is on the PR branch and, for incremental campaigns, at least one finding file intersects changed_paths. Two residual false-positive sources, with mitigations:

  • Renames are absorbed by the alias/dedupe layer — a renamed file re-imports as KNOWN, not new.
  • Model nondeterminism (a pre-existing issue the model simply never emitted on main) is mitigated by keeping a reasonably fresh full scan of the default branch and reporting "new vs merge-base baseline" alongside "new to project".

Merge duplicates

Findings are soft-merged — losers are repointed to the keeper via merged_into_finding_id and alias rows are repointed too. A merged-away fingerprint re-imported later lands on the keeper deterministically. Triage state on the keeper wins.

Trust the dedupe layers

Dedupe runs in tiers:

  1. Exact fingerprint fast path (deterministic sha256).
  2. Heuristic candidate search — file/category overlap + trigram title match, ranked in app code with a deterministic scorer + stable tiebreak. Bounded candidates per finding.
  3. AI adjudication (paid lever) — fires only when a pair shares a file or category and heuristic confidence ≥ threshold and the pair isn't cached. An incoming finding's eligible candidate pairs are adjudicated in batched requests of up to AI_DEDUPE_BATCH_SIZE pairs, with strict per-entry validation, individual retry for missing or malformed entries, and truncation at the daily pair cap. The merge policy treats a substantial subset/superset pair as the same finding, even when the broader report adds secondary defects or evidence. Deterministic fallback on any failure. On-prem uses your key; a platform key never ships in the image.

Heuristics-only is the free tier.

Export safely

Model-derived text is treated as untrusted input. The web UI renders it as text only (no HTML interpolation) and exports escape it, so a prompt-injection payload in a finding title renders inert. See Data handling.

Next steps