- **D2.** `maxDiffPixelRatio` value. Defer to operator preference; 0 is
the strictest and what we currently use implicitly via Playwright
defaults. 0.001-0.01 is a reasonable cushion.
- **D3.** Do we also harden `preview-smoke.yml`? It already runs as a
blocking gate (no `continue-on-error`); no change needed. This convoy
is scoped to `visual-diff.yml` only.
## Risks
| # | Risk | Mitigation |
|---|---|---|
| 1 | Re-seeded baseline drifts on next runner-image update | Watchtower's weekly update cycle (CT 111) could shift Chromium subpixel rendering. Mitigate via D2's `maxDiffPixelRatio` cushion |
| 2 | Step 1's baseline PR fails its own `Screenshot diff` | Expected — the new baseline IS the visual change. Use `pipeline: skip visual` directive in the PR body OR open the baseline PR with the `skip-metrics` label equivalent for visual-diff (currently none — would need a new bypass mechanism). Cleaner: land the baseline PR via the `tests/visual/**` path filter, which DOES trigger visual-diff but the new screenshot vs new baseline should match by construction |
| 3 | Step 2 lands but a third party reverts `continue-on-error` later | Add a 9th check to `forbidden-patterns` in `ci.yml`: `grep -n 'continue-on-error' .github/workflows/visual-diff.yml` should return zero |
## Non-goals
- Adding more visual baselines (login page, dashboard, etc.) — out of
scope. The single homepage baseline is the smoke test of the
visual-diff pipeline; deeper coverage is per-feature work.
- Switching to a hosted visual-regression service (Percy, Chromatic,
Argos) — handles the platform problem cleanly but adds a paid
dependency. Local + axiom is free and works.
## Acceptance
-`visual-diff.yml` gates merge (failed diff = red required check).
- Baseline regenerable via a reviewable Git-native workflow (no SSH
required, no Mac-overwrite-Linux footgun).
-`AGENTS.md` + `tests/visual/homepage.spec.ts` docblock no longer
describe the gate as advisory.
- Optional 9th forbidden-patterns check locks the gate in place.