Last updated: 2026-10-20. Anchored to docs/completion/DEFINITION.md (frozen local-and-CI launch contract), docs/completion/SHIPLOG.md (launch gate GO on 2026-10-19), and the post-launch backlog tracked in #283 (children #284–#299 from the first research pass, #301–#310 from the second, and #321 from the follow-up). The reports, source notes and query logs are in the research archive.
Status note (2026-10-19): Source is at v0.2.3 (
0.2.2published on npm with unreleased changelog entries ahead of that tag). The binding launch gate indocs/completion/DEFINITION.mdis GO:mainis green acrosslint,build,test(Node 22 & 24),e2e,audit, anddocs-links;frontguard.devandwww.frontguard.devserve the livefrontguard-webWorker with/privacy,/terms, and/statusreturning HTTP 200 and no unbuilt$29hosted tier advertised on/pricing; D1 Time Travel restore, Worker rollback, and the red-mainCI failure alert (#280) have all been verified with captured evidence.Supersession of the
2026-06-29roadmap: Earlier revisions of this file describedpackages/cloud-api, Stripe billing, and the GitHub App / Slack / Vercel / Netlify integrations as a live, shipped cloud platform and listed$29/mo Pro/$49/mo Monitoring/$99/mo Businesspricing. Perdocs/completion/DEFINITION.md§0 and §4, Frontguard's completed scope is an excellent local-and-CI visual regression CLI. The cloud service and marketplace integrations exist as source in this repository and are not deployed (api.frontguard.devdoes not resolve; hosted plans are not generally available). Deployingcloud-apiis forbidden until the three hard gates in #293 are closed.
Visual regression testing fails in practice when teams either drown in subpixel rendering noise or hand pass/fail authority to an uncalibrated model that silently waves through real regressions. In 2026 a third failure mode matters as much: a coding agent that both edits the UI and approves the screenshot that proves it.
Two research passes on 2026-10-19 covered GitHub projects and trackers, arXiv papers, platform and vendor docs, CVEs, and practitioner posts on X. Searches were by category only. Every source cited in the children of #283 was re-fetched and matched to its claim before filing.
A bounded follow-up on 2026-10-20 checked the merged roadmap and open tracker, revisited primary sources, and executed the route-selection reproduction below. The published reports distinguish historical drafts from accepted scope. The X refresh was blocked by authentication and access errors; earlier X evidence retains its 2026-10-19 date, with no new demand claims from the follow-up.
-
Deterministic
pixelmatchstays the only pass/fail gate:-
GitHub landscape (first pass):
- Playwright's
toHaveScreenshotis backed bypixelmatch, with a per-pixelthresholddefault of0.2. -
BackstopJS (
6.3.25) uses Resemble.js withmisMatchThreshold: 0.1%, and is seeking a maintainer. -
reg-suitis a comparison CLI that expects caller-supplied images and external object storage. -
lost-pixel/lost-pixelwas archived on 22 April 2026 when the team joined Figma. Its last release wasv3.22.0on2024-11-14. -
storybookjs/test-runnerwas archived on 30 September 2026. -
Loki has not released since August 2024 (
v0.35.1). - Commercial platforms (Argos, Happo, Chromatic, Percy, Applitools) differentiate on hosted multi-user review and object storage. Argos uses deterministic pixel diffing, not AI-based comparison.
- Playwright's
-
Academic papers (2025–2026):
-
WUICC-bench (Beyond Pixel Diffs,
arXiv:2607.01728v1, July 2026; 9,906 human-verified synthetic single-rule edits on WebSight HTML):- Naive pixel diffing scores
0.00%no-change accuracy and100%change recall on visible non-meaningful edits. - Trained image-difference captioners (SEN
96.27% / 96.16%, ICT-Net97.01% / 93.80%, RSICCformer85.82% / 95.33%, RMNet97.39% / 93.55%) still miss 3.8%–6.5% of meaningful single edits, with low caption BLEU-4 ($\le 0.2571$ ). - Zero-shot VLMs either fail to suppress noise (Llama-3.2-11B-Vision-Instruct
21.64% / 79.39%) or miss a third of meaningful regressions (Qwen2-VL-7B-Instruct99.63% / 65.68%).
- Naive pixel diffing scores
-
LLMShot (
arXiv:2507.10062v2, July 2025; 17 forced iOS XCTest failures on Gemma 3 4B/12B):- 12B precision is only
66.67%(F174.42%). - The semantic-diff scalar swings wildly across model sizes (
0.921 ± 0.046on 4B vs0.079 ± 0.079on 12B). - Prompt-based ignore rules collapse (
13.79%and16.67%F1 on 4B).
- 12B precision is only
-
VisRefiner (
arXiv:2602.05998v1, Feb 2026) is a screenshot-to-code trainer whose self-refinement is non-monotone across models. -
XBIDetective (
arXiv:2512.15804v1, ICSE-SEIP 2026) reaches79%accuracy on cross-browser pairs, with ongoing dynamic-content false positives. -
UI-Lens (CVPR 2026) finds nine general multimodal models near chance on text overflow (
50.04%), cropped content (54.07%) and container overlap (54.14%).
-
WUICC-bench (Beyond Pixel Diffs,
-
Practitioner signals on X (2025-01 to 2026-10-19). These are low-reach but consistent:
- Pin the browser binary to the Playwright dependency rather than relying on drifting CI runner browsers (@karlhorky).
- Do not rely on a single global whole-image ratio.
pixelmatchv8.0.0, published 6 October 2026 (@mourner), adds OKLab + HyAB colour delta andwindowSizeto separate scattered anti-aliasing noise from localized edits. - Switching capture runners shifts baselines: one Storybook runner switch made 16 of 22 shots 1px off (@gregberge_).
- Never let the agent that edited the UI be the only approver of the new baseline (@gregberge_, @Antoniocoppe).
-
GitHub landscape (first pass):
-
What the second pass added:
-
Runners now ship screenshot assertions, with zero-pixel defaults.
- Vitest 4
toMatchScreenshot(experimental), Playwright, jest-image-snapshot, cypress-visual-regression and the archived Lost Pixel all default to a budget of zero differing pixels. Testplane v9 allows 4 pixels. - Lost Pixel's default gate was
pixelmatch;odiffwas opt-in. - Frontguard's
10%-of-pixels default is the outlier (#284). - None of these runners ships a local review-and-accept flow, except Testplane's html-reporter. Playwright closed its accept button and review CLI requests as not planned (#305).
- Vitest 4
-
Hosted vendors converge on approval semantics a git branch can copy.
- Baselines are selected from the merge base.
- Approvals are scoped to a PR and keyed by image content.
- Visual checks are re-run inside merge queues.
- GitHub requires the
merge_grouptrigger for required checks in a queue (#304, #306).
-
Renderers and comparators move under users.
- Playwright changed its Chromium screenshot path, moved to Chrome for Testing builds (1.57), and now forwards the device
screen(1.64). - WebdriverIO measured
pixelmatch8 moving differing-pixel counts by about −3% to +3% (#303).
- Playwright changed its Chromium screenshot path, moved to Chrome for Testing builds (1.57), and now forwards the device
- MCP.
-
Prompt injection.
- Instructions hidden in pixels reach vision agents (VPI-Bench; Brave).
- AI text rendered into PRs and chats has been an exfiltration channel in other tools (CamoLeak, CVE-2026-14898).
- The pixel gate is unaffected. Two related hardening items are tracked privately per
SECURITY.md.
- Layout research.
-
Demand is thin.
- X had no posts on merge queues, single-mode suites, or agents regenerating baselines.
- The largest GitHub demand sits in Playwright's tracker, where maintainers closed it as not planned: environment-consistent baselines (about 243 👍) and review-and-accept (about 149 👍).
-
Runners now ship screenshot assertions, with zero-pixel defaults.
-
Frontguard's architectural position:
-
Pass/fail is deterministic.
pixelmatchcontrols exit codes0 / 1 / 2. A deterministicssimFallbackoverride applies when structural similarity clearsssimThreshold: 0.98and no severe local cluster exists. -
AI is advisory and grounded. Vision models classify diffs after a pixel failure, attribute spatial diff clusters to DOM selectors, and propose CSS fixes that are re-rendered in an isolated sandbox. On the default compare path, model output never passes a failing pixel check or overwrites a baseline.
- Experimental judge mode (
--mode judge --experimental) reads no baselines. Its notes are advisory and do not set exit1. The protocol isdocs/judge-protocol.md. This repo has not published a Frontguard judge accuracy figure (#286).
- Experimental judge mode (
- Approval belongs to a human. The shipped agent skill and the Action do not enforce that yet (#287).
-
Pass/fail is deterministic.
-
The follow-up found a route-selection gap.
- Changing a public SVG used by
/alongside a source edit to/aboutselects only/about. The real parser and resolver reproduced the omission atmaincommit1eef667; the empty-set fallback does not protect a nonempty but incomplete selection (#321, executable evidence). No browser or end-to-end CLI verdict was measured. - Chromatic documents external assets that escape dependency tracing. The empirical VRT study reports non-local regressions; its review-time associations do not establish causality. #285 must measure omitted observable mutations separately from pixel-comparator misses.
- VISTA and UI2App separately assess visual resemblance and interaction behavior in generated apps. They support keeping evaluation dimensions separate, without validating a replacement regression gate. Their limits and relevance are recorded in the follow-up report.
- Changing a public SVG used by
Everything below ships in the published local-and-CI packages (@frontguard/cli, @frontguard/playwright, @frontguard/mcp, create-frontguard-plugin, and action.yml) and is covered by the green CI pipeline and launch-gate evidence.
- ✅ Pixelmatch gate + perceptual SSIM (
diff/pixel.ts,diff/ssim.ts)compareScreenshotusespixelmatchas the pass/fail gate, with exit codes0(pass / warning),1(regression / new page) and2(tool / config error).- The default CLI
thresholdis0.1, meaning10%of pixels across the image, unlike Playwright's per-pixel0.2. It can be overridden per route (routes: [{ path, threshold, ignore, viewport }]). - Includes full SSIM, chroma-SSIM, CW-SSIM,
ssimFallback: true(ssimThreshold: 0.98), connected-component 8-neighbour spatial diff clustering, and DOM bounding-box selector attribution.
- ✅ Deterministic anti-flake controls (
render/stability.ts,docker/)- Capture-time
freezeTime, Mulberry32seedRandom, theblockUrlsnetwork abort guard,waitForStabilityconsecutive-frame convergence,redactSensitiveinput masking, and CSS selector / coordinateignoremasks. - Optional multi-render consensus:
antiFlakeRenders, default1in practice, with opt-in3+renders viafindConsensusScreenshot(), which keeps the most common byte-identical frame. - Source for a pinned
linux/amd64Docker renderer (packages/cli/Dockerfile). - (Correction to the
2026-06-29roadmap:antiFlakeRendersdefaults to1, not3.)
- Capture-time
- ✅ Capture options (
render/playwright.ts) — Per-routeactions, a singlecolorSchemeper route or per run, PlaywrightstorageStateauth, andworkersconcurrency (default4). - ✅ Framework & Storybook discovery (
discovery/)- Filesystem route discovery for Next.js (App and Pages Router), Remix, SvelteKit and Nuxt.
- Storybook 8
/index.jsonand Storybook 7/stories.jsondiscovery. - A live BFS crawler fallback.
smartFilterchanged-file route scoping, with an automatic all-routes fallback. Lockfiles, configs, global CSS and token files force all routes. The README line"12/47 routes affected by changed files"is illustrative sample output, not a benchmark measurement.
- ✅ Multi-viewport & multi-browser capture (
render/) — Default viewports375 / 768 / 1440.chromiumby default, withfirefoxandwebkitsupported viaconfig.browsers. - ✅ Git orphan-branch baselines (
storage/git-orphan.ts) — Stores baseline PNGs and a SHA-256 manifest on an isolatedfrontguard-baselinesgit orphan branch via temporary worktrees, somainstays free of binary bloat. - ✅ Interactive local HTML workbench & PR reporter (
report/html.ts,report/github-pr.ts)- A self-contained 4-mode HTML diff inspector (
packages/cli/src/report/html.ts, 1,403 lines): Side-by-Side, Swipe Curtain, Onion Skin and Diff Heatmap, plus a spatial cluster table and keyboard navigation. - GitHub PR Markdown comments with
renderImageGrid()thumbnails backed byimageUpload(Cloudflare R2, AWS S3, GitHub Actions artifacts, or local disk).
- A self-contained 4-mode HTML diff inspector (
- ✅ CLI commands & onboarding (
cli/) —init,doctor(Node, browser, config and git diagnostics),run,update-baselines,monitor(--once,--watch/--interval,--history, webhook alerts),accept-fix,reject-fix,export-patternsandplugin. - ✅ 5 built-in plugins & 9 lifecycle hooks (
plugins/,create-frontguard-plugin):- Accessibility (
plugins/accessibility.ts) — An@axe-core/playwrightWCAG audit in the same render pass. Options areimpact,rules,excludeRulesandfailOnViolation; violations are warnings unlessfailOnViolation: true. Findings are fused into the optional AI analysis prompts. (The README and docs site currently show options that do not exist,failOnImpactandstandard; see #302.) - Performance budgets (
plugins/perf-budgets.ts) — LCP, CLS, FCP, TTFB and transfer-size budgets, correlated inline with visual diffs and run-over-run regressions (trackRegressions). - Third-party scripts (
plugins/third-party-scripts.ts) — Inventories external<script src>origins per route and flags newly added or removed third-party domains. - Figma design compliance (
plugins/figma.ts) — Compares live rendered routes against exported Figma frames. - Production URL monitor (
plugins/monitor.ts) — Scheduled or one-shot live URL drift checks, with webhook and Slack alerting.
- Accessibility (
- ✅ Optional BYOK AI triage, sandbox fix verification & experimental judge (
diff/ai-vision.ts,diff/ai-fix.ts,diff/model-judge.ts,sandbox/,storage/fix-patterns.ts)- Multi-provider BYOK vision analysis (OpenAI, Anthropic, Gemini, custom
baseUrl), with DOM text fenced as untrusted. - Candidate CSS patch generation, verified by re-rendering with local Playwright (
sandbox/local.ts) or Daytona (sandbox/daytona.ts). - A local SQLite fix-pattern store (
accept-fix/reject-fix/export-patterns). - Opt-in experimental judge mode (
--mode judge --experimental).
- Multi-provider BYOK vision analysis (OpenAI, Anthropic, Gemini, custom
- ✅ Demo & comparison guides (
demo/,apps/web/src/lib/docs-content.ts) — Committeddemo/frontguard-demo.gifanddemo/frontguard-demo.svgassets, plus comparison and migration guides (frontguard-vs-percy,frontguard-vs-chromatic,migrate-from-backstopjs,migrate-from-lost-pixel). (Closes the2026-06-29roadmap's demo-recording follow-up.)
- ✅
visualTest()andexpectVisual()assertions with__visual_baselines__/storage, SSIM calculation, connected-component cluster extraction, DOM selector attribution,mask/maskRegions,redactSensitive,freezeTime,seedRandom,blockUrlsandwaitForStable. OptionalcaptureAriaSnapshotandtextSnapshotstore a text file next to the PNG and diff it as text. A mismatch is reported on its own. It does not changepassed, and axe-core remains the accessibility plugin (#299).
-
✅ A stdio JSON-RPC 2.0 server, built on
@modelcontextprotocol/sdk^1.32.1, exposing eight tools withoutputSchemaandstructuredContent:- read tools:
list_regressions,inspect_diff_cluster_dom,get_suggested_fix,verify_css_patch(static, with a CSS policy),recent_runs, andlist_horizontal_overflow(report only; not an exit-code input); - write tools:
promote_baseline(requiresconfirm_reviewed: trueand refuses unconfirmed local-report orphan-branch overwrites) andaccept_baseline.
It works in both zero-cloud local
report.jsonmode and Cloud API mode. - read tools:
- Route entries that share a path, such as light and dark, or menu closed and open, share one baseline file (#301).
- The accessibility plugin's documented recipe uses options the plugin ignores, so serious violations never fail the run (#302).
- Experimental judge mode sets exit codes from model verdicts (#286).
skills/frontguard/SKILL.mdsteers agents toupdate-baselinesandpromote_baseline. Withupdate-baselines: true, the Action pushesfrontguard-baselinesfrom any event (#287).smartFiltercan omit an asset consumer when a public asset and a different mapped route change together. The executed reproduction covers route selection, with end-to-end pixel validation still required (#321).
Per docs/completion/DEFINITION.md §4, the following subsystems exist as tested source code in the monorepo but are not deployed as live production services. They must not be advertised as generally available until their post-launch gates are met:
- 🔒
packages/cloud-api(Hono / Cloudflare Worker, D1, R2, GitHub OAuth, Cron scheduler, Slack/email/PagerDuty alerting, hand-rolled OTLP/HTTP exporter insrc/otel/index.ts) — Not deployed (api.frontguard.devdoes not resolve). Hard-gated on #293:- (a) a user-data erasure path;
- (b) a restore-tested backup;
- (c) fixing the run-status path so a run can never report
completedwithout having compared.
- 🔒 Stripe billing & hosted pricing tiers (
packages/cloud-api/src/billing/) — Source only, with no live money path. Public/pricingonfrontguard.devstates that hosted plans are not generally available. - 🔒 Third-party marketplace listings (
integrations/github-app,integrations/slack-app,integrations/vercel,integrations/netlify) — Handler source and tests live inintegrations/*. External marketplace listings (CF-06) and production cloud hooks remain deferred untilcloud-apiclears #293.
4. Post-Launch Roadmap (Tracked in GitHub Issue #283)
All actionable post-launch engineering work is tracked under parent issue #283 ("Post-launch roadmap: keep pixelmatch as the only pass/fail gate"), ordered into Now, Next and Later. The order within each group is the working order. The second research pass (2026-10-19) added #301–#310, moved #288 to Next, and split #289. The follow-up added #321 to Now before validation. Two security hardening items are tracked privately per SECURITY.md and appear below only as placeholders. Delivery checkpoints state the evidence required between groups; they are not calendar estimates.
- #287 — Separate baseline writes from the agent that edited the UI.
- Rewrite the shipped skill so agents stop at evidence and hand promotion to a human.
- Make the Action refuse
update-baselinesonpull_request,pull_request_targetandmerge_groupwithout an explicit override. - Make the control a credential the agent does not hold: promotion after merge, or a protected environment.
confirm_reviewedstays as UX only.
- #286 — Publish an advisory judge evaluation and keep model output off exit codes.
- First change: judge verdicts stop setting exit
1. - Then an evaluation protocol with paired clean and attacked injection fixtures, scored in both directions with Clopper-Pearson bounds, plus UI-Lens classes as negative evidence.
- First change: judge verdicts stop setting exit
- #301 — Route entries that share a path overwrite each other's baselines.
- Reject duplicate baseline keys at config validation (exit
2) until named modes exist. - Document that
--color-schemecompares against the default scheme's baselines. - Warn when the run's effective color scheme differs from the scheme stored on the baseline. The warning does not change the exit code.
- Reject duplicate baseline keys at config validation (exit
- #302 — Accessibility plugin docs use options the plugin ignores.
- Fix the recipe to
impact+failOnViolation: true. - Warn on unknown option keys.
- Fix the recipe to
- #303 — Record the renderer and comparator in the baseline manifest.
- Record the Frontguard, Playwright, browser build/channel, OS/arch, device scale factor,
pixelmatchversion/options and effective screenshot options. - Warn on mismatch; exit
2only in strict mode. - Bound the
document.fonts.readywait. - Absorbs #289's runner-change warning. Lands before #284.
- Record the Frontguard, Playwright, browser build/channel, OS/arch, device scale factor,
- Private hardening item, tracked per
SECURITY.md. - #321 — Keep
smartFilterconservative for public assets in mixed changes.- Capture all routes when changed asset consumers cannot be proved, even if another route was selected.
- Cover mixed image, font and CSS-background edits; explain incomplete-analysis fallbacks.
- Retain scoping for proven route-only edits. Lands before #285's selection validation.
- #284 — Measure small-text misses under the 10% pixel budget and adopt
pixelmatch8 as the same gate.- Both packages depend on
pixelmatch^8.0.0. The 10% whole-image budget stays. A 16×16 window fails above 64 differing pixels. - A dimension mismatch is padded, then judged by that same gate.
- WebdriverIO's about ±3% count shift is their corpus. This repo does not publish a rate from it.
- Screenshot runs install the Playwright browser build that matches the capturing package (@karlhorky).
- Both packages depend on
- #285 — Re-run pixel validation on the current tree with true-positive fixtures.
- HTML/CSS mutation operators, with recall bucketed by how many viewports show the change.
- Seeded neighbour-moving faults, nuisance fixtures drawn from UI flaky-test causes, and the #303 fingerprint recorded.
- Compare full capture with filtered selection after #321, reporting omitted observable mutations and denominators separately from comparator misses.
- No implied rate of unreviewed acceptance.
- #288 — Block baseline updates on new serious
axe-coreviolations.update-baselinesruns the existing accessibility plugin before it writes. The audit uses the same storage state, color scheme, viewport height, wait, and route actions as the capture.failOnViolation: truerefuses the write at or aboveimpact, including when the pixel status is not a regression, and when an audit does not complete. The report lists the violations, says the baselines were not written, and leaves the pixel status unchanged. A clean audit does not clear a pixel regression.frontguard review(#305) must use this same refusal. CloudapproveRunstays off the production path (#306). - #304 — Run a verify-only full check in GitHub merge queues.
- Document
merge_group. - On queue runs, render all routes and refuse writes.
- Exit
1on regression, so the PR is removed from the queue. - Fix
smartFilter's hard-codedorigin/main...HEADbase on queue refs.
- Document
- #305 — Add a human
frontguard reviewcommand that accepts shots one at a time.- Accept, skip or quit per shot.
--froma downloaded CI artifact, byte for byte, refused on a fingerprint mismatch.- An audit line per acceptance, and no network calls.
- #306 — Design PR-scoped approvals and merge-base baseline selection for the orphan branch.
- A decision record plus a spike: pick baselines from the merge base, and key approvals by baseline and candidate SHA-256.
- Promotion happens after merge.
pixelmatchstays the only comparator.
- Private hardening item, tracked per
SECURITY.md. - #307 — Declare MCP tool annotations and mark promotion tools destructive.
- Read-only hints on the five read tools.
destructiveHintplus Claude Code'srequiresUserInteractiononpromote_baselineandaccept_baseline.- Documented as hints, not controls.
- #289 — Discover Ladle, Histoire and Storybook 9–11 stories.
- Discovery only.
- Fixtures for Storybook 9, 10 and the 11 alpha, now that
storybookjs/test-runneris archived. - Ladle via
meta.json, and Histoire discovery while its native visual testing is unreleased.
- #290 — Prune PNG history on the
frontguard-baselinesorphan branch.- Adds stale-shot removal.
- Never prunes from filtered or sharded runs, and always offers a dry run.
- Keeps every baseline set reachable as a merge base (#306).
- #291 — Split
pipeline.tsat 1,422 lines and drop the staleindex.tsxrefactor. Unchanged. - #292 — Enforce coverage thresholds in the CLI Vitest config. Unchanged; ratchets after the Now tests land.
- #293 — Close the three
cloud-apideployment gates without deploying.- The run-status path (
G-34), user-data erasure, and a restore-tested backup. - Does not deploy
api.frontguard.devor enable billing.
- The run-status path (
- #294 — Design a hosted review UI only after the
cloud-apigates. Blocked by #293 and #305: local review comes first. - #295 — Design S3-backed baseline storage only after the
cloud-apigates.- Blocked by #293, #290, #306 and #303.
- Distinct from
imageUpload, which already uploads PR diff thumbnails.
- #298 — Surface aged ignore masks for a human to drop. One vendor account asked for this.
frontguard ignores --older-than <days>lists rules whosesincedate is older than that, and the shots they cover. Shot coverage comes from configured routes. When routes are omitted, the command says coverage is unavailable and does not discover Storybook, crawl, or filesystem routes. Removing a rule is a config edit. No model, prompt, or flake heuristic removes a mask. - #299 — Add optional ARIA and non-image text snapshots that do not gate pixels. Optional
captureAriaSnapshotandtextSnapshot.json/textSnapshot.markdownstore a text file next to the PNG and diff it as text. A mismatch is reported on its own. It does not changecomparisonMethodfrom pixelmatch and does not pass a pixel regression. axe-core remains the accessibility plugin. Text diff is not a gate. - #308 — Report horizontal viewport overflow without gating.
scrollWidthvsinnerWidth, plus visible unclipped elements past the right edge, taken from the same settled state as the screenshot.- Never an exit-code input. The HTML report, JSON output, and
list_horizontal_overflowshow it. Precision forvalidation/fixtures/overflowis invalidation/results-overflow.md. The advisory judge has no Frontguard accuracy on that set (docs/judge-protocol.md).
- #309 — Add named capture modes with mode-keyed baselines (bet).
- Named bundles (
colorScheme,reducedMotion,forcedColors,contrast,locale,timezoneId). - Emulation probed before each capture, and a projected capture count.
- Demand is weak.
- Named bundles (
- #310 — Move the MCP server to SDK v2 before v1.x support ends, then list it in the registry.
- Dated: start the spike in December 2026 and ship before about 2027-01-27.
- Publish
server.jsonfrom the npm release job.
- #296 — Add CLI OpenTelemetry without deploying the
cloud-apiexporter. Unchanged. - #297 — Audit
apps/webaccessibility separately from the CLIaxe-coreplugin. Unchanged.
- #157 — Weekly npm audit (production tree): an automated weekly production dependency audit workflow.
- H-05 / G-44 — npm trusted publishing (OIDC without
NPM_TOKEN): recorded indocs/completion/HUMAN_ACTIONS.mdanddocs/completion/GAPS.mdwith expiry 2027-03-01. The current release workflow already enforces tag/version match,mainancestry, green CI on the exact SHA, and npm OIDC provenance attestation.
- Replacing
pixelmatchwithodiff,Resemble.js, a perceptual hash, a captioner or a VLM as the pass/fail gate, including prompt-based ignore rules.- No benchmark in the 2026 literature shows these outperforming
pixelmatchon UI accuracy. - WUICC-bench, LLMShot and UI-Lens show why models cannot serve as a deterministic regression gate.
- Noise handling stays inside the same gate (
windowSize,ignoreMask; #284).
- No benchmark in the 2026 literature shows these outperforming
- Selectable alternative comparators as gates. Playwright closed pluggable comparators as out of scope. Vitest declines to bundle perceptual comparators because there is no clear best one.
- A Vitest
toMatchScreenshotcomparator adapter, or a clone of a Storybook visual-test addon. There is no practitioner pull, and Chromatic already sells hosted Vitest visual testing. Frontguard is positioned as the local Storybook path instead (#289). - An in-house prompt-injection detector, more "ignore page instructions" prompt text, defenses that need model internals, or a dual-LLM rebuild of triage. Adaptive attacks bypassed 12 published defenses (arXiv:2510.09023). The pixel gate already fixes control flow.
- Skill or prompt wording as the thing that stops promotion, or an agent's own "looks good" verdict as a stop condition. The control is a credential the agent does not hold (#287).
- Auto-passing or switching off the visual check in merge queues, Checks API approve buttons (GitHub Apps only), auto-update on mismatch, or CI writes of missing baselines that pass.
- A browser-binary cache step in the Action. Playwright documents that restoring takes about as long as downloading. The Action already installs browsers from the CLI's own pinned Playwright.
- Determinism by flags. Not planned: font hinting by default, shared cross-OS baselines, or WebGL guarantees.
- Raw DOM collision or element-protrusion lists, small-range layout warnings, LLM CSS auto-repair, VLM layout gating, or cross-locale / cross-browser pixel comparison as a gate. Humans saw 9 of 43 collisions and 3 of 90 protrusions in VERVE's data. All 53 small-range reports there were false positives.
- A self-healing test agent. Playwright's healer covers that, and its documented scope excludes baselines.
- MCP Tasks, Sampling, Roots or logging, or Skills over MCP. The 2026-07-28 spec moves or deprecates them.
- Origin limits on MCP-triggered renders (the MCP server launches no browser) and a "fail closed on zero comparisons" issue (the CLI and Action already exit with an error when nothing was compared).
- Git LFS, or sharding as a headline feature. No in-window demand: sharding requests total 3 👍.
- Re-filing already-shipped local capabilities. These already ship: SSIM / chroma-SSIM / CW-SSIM (
ssimFallback), Storybook/index.jsondiscovery, CSS and coordinate ignore masks, the@axe-core/playwrightplugin, anti-flake controls (freezeTime,seedRandom,blockUrls,waitForStability), Firefox and WebKit capture,smartFilterchanged-file scoping, local MCPreport.jsoninspection, experimental judge mode, the external validation harness, and the 4-mode HTML diff report. - Stale god-file refactors (
apps/web/src/routes/index.tsx,html.ts,docs-content.ts).apps/web/src/routes/index.tsxis 91 lines. Onlypackages/cli/src/core/pipeline.ts(1,422 lines) is tracked for modularization (#291). - Premature cloud deployment, live billing, or marketplace submissions. Deploying
packages/cloud-api, turning on Stripe billing, or submitting GitHub App / Slack / Vercel / Netlify marketplace listings stays off the near-term backlog until #293 is closed. - Native mobile app screenshots (iOS Simulator / Android Emulator), a Puppeteer abstraction, browser extensions, or video-replay diffing. These are different rendering pipelines and audiences, and they dilute focus from deterministic Playwright-based web visual regression testing.
| Deferred | Trigger to revisit |
|---|---|
| Lost Pixel / BackstopJS config importers; Playwright / Vitest baseline import or export | A user asks. Migration guides already ship |
| JUnit XML and CTRF output | A user asks. No visual runner emits CTRF, and CTRF is pre-1.0 |
| Grouping repeated diffs across routes, shift-aware summaries, moved-element attribution | #285 measures reviewer load |
| A geometry-only width sweep | Geometry baselines exist |
| Pseudo-locale, HiDPI, forced-colors and RTL modes | #309 v1 ships |
| A remote Linux renderer for macOS and Windows | #305's --from proves insufficient |
| MCP rows with image paths and unscaled crops | Agents ask |
| An MCP App diff viewer with an app-only promote tool | #287 lands |
Reporting instability through the unused flaky status |
#285 measures how often multi-render consensus disagrees |