Visual regression suites die of review fatigue: 300 changed snapshots after a design-token bump, and a human clicking "accept" on autopilot by number 40 — right past the one real regression. Put a vision model in front: it pre-classifies diffs into intentional, regression, or noise, and humans review only the ambiguous minority.
Tier: Core · Workflow area: Testing & quality
The failure mode of visual testing is not missed pixels — the tools catch everything. It is that catching everything buries the signal. Pre-classification is a triage layer, not a replacement judge: the model sorts, humans decide, and the accept button stops being a reflex.
toHaveScreenshot in CI), with animations disabled and data seeded in stories.Export the diff triples plus the intent. For each changed snapshot, collect baseline image, new image, and the diff overlay if your tool provides one — plus the one thing tools never use: what the PR meant to change:
PR intent: "Bump brand color token from #2563eb to #1d4ed8 and
increase Button horizontal padding from 12px to 16px. No other
visual changes intended."
Every visual platform exposes changed snapshots via API or build artifacts; a small script pulls the triples. The intent line comes from the PR description — and making engineers write it is itself a quiet win for review culture.
Classify with a constrained rubric, one judgment per snapshot.
You are triaging visual regression diffs. PR intent: <above>.
For this snapshot (baseline, new, diff overlay attached), respond in
JSON: { "verdict": "INTENTIONAL" | "REGRESSION" | "NOISE" | "AMBIGUOUS",
"confidence": 0-1, "evidence": "<one sentence naming the specific
visual change and where>" }
Rules: INTENTIONAL only if every visible change is explained by the
stated intent. REGRESSION if any change is outside the intent —
layout shift, clipped text, missing element, wrong color, overlap —
even if intent-related changes are also present. NOISE for
anti-aliasing, sub-pixel shifts, font rasterization differences with
no layout consequence. AMBIGUOUS whenever you are below 0.8 or the
intent does not clearly cover the change. Never mark INTENTIONAL by
assuming an unstated intent.
The asymmetry is deliberate: the model needs positive evidence to clear a snapshot, but any doubt routes to a human. A useful classifier says AMBIGUOUS often; a dangerous one never does.
Route by verdict — with different bars per verdict. REGRESSION: straight to the top of the human queue with the model's evidence sentence as the caption; these are reviewed first while attention is fresh. AMBIGUOUS: normal human review. INTENTIONAL (high confidence): batched into a collapsed "cleared" section — spot-check a random 10%, then bulk-accept. NOISE: accept, but count — a rising noise rate is your determinism rotting (fonts, animation timing, unseeded randomness) and step 6's input. Humans still press every accept button; the model only decides reading order and grouping.
Calibrate before you trust. For the first two weeks, run classification in shadow mode: the model labels, humans review everything as before, and you score the disagreements. The one number that matters: model-cleared-as-INTENTIONAL snapshots that a human called regression — that false-clear rate must be at or near zero before you collapse the cleared section, because a false clear is precisely the buried regression this playbook exists to prevent. Model-flagged-but-actually-fine costs minutes; tune the rubric wording and intent quality until the expensive direction is clean.
Seed-test the pipeline like you would a junior reviewer. Periodically plant a known regression — shift a padding, drop a border, clip a label — inside a large intentional batch and confirm it surfaces as REGRESSION at the top of the queue. A triage layer that has never been adversarially tested is a comfort blanket. This is also the demo that earns the team's trust in collapsing the cleared section.
Feed the verdicts back into suite health. The classification log is a dataset: stories with chronic NOISE verdicts need determinism fixes (freeze time, mock data, prefers-reduced-motion); components with frequent REGRESSION verdicts are fragile and deserve refactoring or tighter component tests; and intent statements that repeatedly produce AMBIGUOUS verdicts teach engineers to write better PR descriptions. Triage quality compounds when the inputs improve.
Chromatic's TurboSnap and similar change-detection features reduce how many snapshots get taken; this playbook reduces how many get human attention. They stack — capture less, classify what you capture, review only what deserves eyes.
toHaveScreenshot in CI: the DIY lane — failing test artifacts are your triples; the classifier comments its verdict table on the PR, and accepts become --update-snapshots commits.The intent statement is the highest-leverage line in this whole pipeline — a model judging "is this change intentional?" is only as good as the stated intention. Make "what should change visually, and what must not" a required PR-template field, and both your classifier and your human reviewers get sharper the same day.