[{"data":1,"prerenderedAt":235},["ShallowReactive",2],{"-docs-guide-triage":3,"-docs-guide-triage-surround":224},{"id":4,"title":5,"body":6,"description":214,"extension":215,"links":216,"meta":217,"navigation":218,"path":220,"seo":221,"stem":222,"__hash__":223},"docs\u002Fdocs\u002F2.guide\u002F4.triage.md","Triage",{"type":7,"value":8,"toc":204},"minimark",[9,22,27,39,67,71,82,100,104,115,119,122,166,169,173,186,190],[10,11,12,13,17,18,21],"p",{},"Findings live at the ",[14,15,16],"strong",{},"project level"," with ",[14,19,20],{},"branch attribution"," — not per-campaign. That means triage decisions carry across branches and across merges\u002Frenames, and \"show only NEW issues on this PR\" is first-class.",[23,24,26],"h2",{"id":25},"set-a-status","Set a status",[10,28,29,30,33,34,38],{},"Every human action records ",[14,31,32],{},"actor attribution"," (",[35,36,37],"code",{},"actor_user_id",", nullable for system\u002Fclient actions). Statuses you can set on a finding:",[40,41,42,49,55,61],"ul",{},[43,44,45,48],"li",{},[14,46,47],{},"Open"," — default for a newly discovered finding.",[43,50,51,54],{},[14,52,53],{},"Fixed"," — you believe it's resolved (a retest campaign can verify).",[43,56,57,60],{},[14,58,59],{},"Won't fix"," — accepted risk; stays suppressed on derivative branches.",[43,62,63,66],{},[14,64,65],{},"False positive"," — recorded with a reason; feeds back into dedupe tuning.",[23,68,70],{"id":69},"see-whats-new-on-a-pr","See what's new on a PR",[10,72,73,74,77,78,81],{},"The PR gate reports open findings whose ",[14,75,76],{},"earliest sighting is on the PR branch"," and, for incremental campaigns, at least one finding file intersects ",[35,79,80],{},"changed_paths",". Two residual false-positive sources, with mitigations:",[40,83,84,90],{},[43,85,86,89],{},[14,87,88],{},"Renames"," are absorbed by the alias\u002Fdedupe layer — a renamed file re-imports as KNOWN, not new.",[43,91,92,95,96,99],{},[14,93,94],{},"Model nondeterminism"," (a pre-existing issue the model simply never emitted on ",[35,97,98],{},"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\".",[23,101,103],{"id":102},"merge-duplicates","Merge duplicates",[10,105,106,107,110,111,114],{},"Findings are ",[14,108,109],{},"soft-merged"," — losers are repointed to the keeper via ",[35,112,113],{},"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.",[23,116,118],{"id":117},"trust-the-dedupe-layers","Trust the dedupe layers",[10,120,121],{},"Dedupe runs in tiers:",[123,124,125,131,137],"ol",{},[43,126,127,130],{},[14,128,129],{},"Exact fingerprint"," fast path (deterministic sha256).",[43,132,133,136],{},[14,134,135],{},"Heuristic candidate search"," — file\u002Fcategory overlap + trigram title match, ranked in app code with a deterministic scorer + stable tiebreak. Bounded candidates per finding.",[43,138,139,142,143,146,147,149,150,157,158,161,162,165],{},[14,140,141],{},"AI adjudication"," (paid lever) — fires only when a pair shares a file or category ",[14,144,145],{},"and"," heuristic confidence ≥ threshold ",[14,148,145],{}," the pair isn't cached. An incoming finding's eligible candidate pairs are adjudicated in ",[14,151,152,153,156],{},"batched requests of up to ",[35,154,155],{},"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\u002Fsuperset pair as the ",[14,159,160],{},"same"," finding, even when the broader report adds secondary defects or evidence. Deterministic fallback on any failure. On-prem uses ",[14,163,164],{},"your"," key; a platform key never ships in the image.",[10,167,168],{},"Heuristics-only is the free tier.",[23,170,172],{"id":171},"export-safely","Export safely",[10,174,175,176,179,180,185],{},"Model-derived text is treated as ",[14,177,178],{},"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 ",[181,182,184],"a",{"href":183},"\u002Fdocs\u002Fguide\u002Fdata-handling","Data handling",".",[23,187,189],{"id":188},"next-steps","Next steps",[40,191,192,199],{},[43,193,194,198],{},[181,195,197],{"href":196},"\u002Fdocs\u002Fguide\u002Fpr-gate","PR gate"," — surface triage into CI.",[43,200,201,203],{},[181,202,184],{"href":183}," — retention, isolation, right to delete.",{"title":205,"searchDepth":206,"depth":206,"links":207},"",2,[208,209,210,211,212,213],{"id":25,"depth":206,"text":26},{"id":69,"depth":206,"text":70},{"id":102,"depth":206,"text":103},{"id":117,"depth":206,"text":118},{"id":171,"depth":206,"text":172},{"id":188,"depth":206,"text":189},"Triage findings as a team with project-level identity and branch attribution","md",null,{},{"icon":219},"i-lucide-list-checks","\u002Fdocs\u002Fguide\u002Ftriage",{"title":5,"description":214},"docs\u002F2.guide\u002F4.triage","enBnftyDHZ15f3yDolXDWONOl_AvWfLwiKZskKZaOEM",[225,231],{"title":226,"path":227,"stem":228,"description":229,"icon":230,"children":-1},"Campaigns","\u002Fdocs\u002Fguide\u002Fcampaigns","docs\u002F2.guide\u002F3.campaigns","Create and run full, incremental, and retest campaigns in TheSpider","i-lucide-layers",{"title":197,"path":196,"stem":232,"description":233,"icon":234,"children":-1},"docs\u002F2.guide\u002F5.pr-gate","Gate pull requests without putting model runtime or secrets into CI","i-lucide-git-pull-request",1783955420376]