feat(engine): assertSwiftShader chrome://gpu validator#767
Conversation
64d6c02 to
ee866de
Compare
15f8ef2 to
e9e6359
Compare
miguel-heygen
left a comment
There was a problem hiding this comment.
Clean utility with solid test coverage.
The dual-gate (exact vendor match + case-insensitive renderer substring) is the right call — vendor alone would false-positive on ANGLE backends that share the Google umbrella string. Injectable readInfo makes this fully testable without Chrome, and the SwiftShaderAssertionError.code field gives Temporal retry policies a clean classification target.
One small observation: readWebGlVendorInfo navigates to chrome://gpu with a 30s timeout, which is generous but fine for a post-launch one-shot. If this ever runs in a hot path, that timeout could be tightened — but for Phase 3's boot-time assertion it's appropriate.
Test matrix covers the important edge cases: empty strings, wrong vendor + right renderer, right vendor + wrong renderer, reader errors propagating unwrapped.
LGTM.
— Magi
vanceingalls
left a comment
There was a problem hiding this comment.
Strengths:
- Pulling structured
browserBridge.gpuInfo_.graphics_info.basic_infofromchrome://gpu(assertSwiftShader.ts:78) instead of scraping the DOM is the right call — the DOM layout has drifted across Chrome versions and the structured payload has been stable. - Both-checks-required logic (
assertSwiftShader.ts:101-102): exact vendor match"Google Inc. (Google)"AND case-insensitiveswiftshadersubstring in renderer. The comment atassertSwiftShader.ts:46-50correctly justifies why neither check alone is sufficient — a third-party renderer string with "SwiftShader compatible" would otherwise pass. readInfoinjectable onassertSwiftShader(page, readInfo?)(assertSwiftShader.ts:111) cleanly separates the "what we check" from the "how we read it," so the 9 unit tests can drive failure cases without a real Chrome.SwiftShaderAssertionError.codeis a typed literal (assertSwiftShader.ts:32) — Temporal/Step Functions retry policies key off it, matching the Phase-2 plan §9.3 contract.
Findings:
nit: assertSwiftShader.ts:78 page.goto("chrome://gpu", { waitUntil: "domcontentloaded", timeout: 30_000 }) — chrome://gpu populates browserBridge.gpuInfo_ asynchronously after DOMContentLoaded (Chrome posts the basic_info rows from a separate IPC). On a slow worker, the await page.evaluate(...) may run before basic_info is populated and return empty vendor/renderer strings — which the assertion already correctly treats as failure (good), but the error message would then claim "Chrome reported a non-SwiftShader WebGL backend" when in fact the info hadn't arrived. Consider polling browserBridge?.gpuInfo_?.graphics_info?.basic_info for non-empty rows up to a short timeout, or distinguishing the empty-string case in the error message. Caller will read the error in production logs and "vendor="" renderer=""" is harder to diagnose than "chrome://gpu info not populated within 5s." Not blocking — current behavior fails closed and tests pin the empty-string case.
nit: assertSwiftShader.ts:55 SWIFTSHADER_VENDOR_SIGNATURE = "Google Inc. (Google)" — Chrome occasionally emits this as "Google Inc." without the trailing (Google) on some platforms (older Linux builds). The literal pin will reject those. If hf supports old base images, worth a comment noting the pin is tight to current Chrome. If not, ignore.
Verdict: APPROVE
Reasoning: Validator is well-encapsulated, both-check-required logic is sound, tests cover the rejection matrix; the timing-on-page-load nit is a soft-edges concern that fails closed today.
— Vai
Part of Phase 2 of the distributed rendering plan (determinism hardening).
See DISTRIBUTED-RENDERING-PLAN.md §5.2 (browserGpuMode row) and §9.3
(BROWSER_GPU_NOT_SOFTWARE typed failure).
Adds packages/engine/src/utils/assertSwiftShader.ts:
- assertSwiftShader(page, readInfo?) — navigates to chrome://gpu, reads
the GL_VENDOR / GL_RENDERER rows from browserBridge.gpuInfo_, throws
SwiftShaderAssertionError ({ code: "BROWSER_GPU_NOT_SOFTWARE" }) if
the active backend isn't SwiftShader.
- readWebGlVendorInfo(page) — extracted helper so tests can stub the
info read without spinning up real Chrome.
- SwiftShaderAssertionError + BROWSER_GPU_NOT_SOFTWARE constant exposed
so the Phase 3 distributed adapter can match typed non-retryable
failures.
Re-exported from packages/engine/src/index.ts. No caller invokes it yet;
Phase 3 renderChunk() will run it post-launch.
In-process behavior is unchanged — assertSwiftShader is a new pure utility.
Producer regression baselines remain byte-identical.
This is part of a stack of 10 PRs; this is PR 2 of 10.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
e9e6359 to
d8486a7
Compare
ee866de to
2d6372a
Compare
The base branch was changed.

What
New utility
packages/engine/src/utils/assertSwiftShader.tsthat navigates a PuppeteerPagetochrome://gpu, parses the GL_VENDOR / GL_RENDERER rows, and throwsSwiftShaderAssertionError(withcode: "BROWSER_GPU_NOT_SOFTWARE") if the active WebGL backend is anything other than SwiftShader. Re-exported frompackages/engine/src/index.ts.Why
Part of Phase 2 of the distributed rendering plan (determinism hardening), §5.2 (
browserGpuModerow) and §9.3 (BROWSER_GPU_NOT_SOFTWAREtyped failure).Distributed renders launch Chrome with
--use-gl=swiftshader --use-angle=swiftshaderso every worker has the same pure-software GL implementation. Those flags are advisory: a misconfigured base image, a missing SwiftShader library, or achrome://gpublocklist override can silently downgrade to system GL — and distributed retries would no longer be byte-identical. The validator catches the downgrade post-launch, before any frame is rendered.How
readWebGlVendorInfo(page)implementation that pulls structuredbrowserBridge.gpuInfo_.graphics_info.basic_inforows fromchrome://gpu(more stable across Chrome versions than the DOM layout of the GPU page).Google Inc. (Google)) and a case-insensitiveswiftshadersubstring in the renderer string. Either alone is insufficient.assertSwiftShader(page, readInfo?)accepts an injectablereadInfoso unit tests can drive the assertion without spinning up real Chrome.SwiftShaderAssertionErrorcarries the offending vendor + renderer strings on the error for diagnostic surfacing.Test plan
assertSwiftShader.test.tscovers the canonical accept case, case/whitespace tolerance, the NVIDIA / Intel fallthrough rejects, empty-string failure, propagation of reader errors, and a third-party vendor + "SwiftShader compatible" renderer is still rejected.renderChunk()will run it after browser launch.bun run --cwd packages/engine test— 9 new tests + all existing pass.bun run --cwd packages/engine typecheckclean.bunx oxlint+bunx oxfmt --checkclean.This is part of a stack of 10 PRs; this is PR 2 of 10. Stacked on top of #766.
🤖 Generated with Claude Code