← All decisions

This dev sandbox cannot run real-browser WebGPU, even headless and even in software

webgpuplaywrightenvironmentverification

Context

While building the game runner (glemy/game.gleam), wanted to visually verify actual pixel output (falling/colliding circles, click-to-spawn) in a real browser before calling the work done, per this project's standing verify-important-decisions practice. A Playwright-managed Chromium (Google Chrome for Testing 151.0.7922.34) was already present on this machine. Section 9 of development-plan.md already flagged Playwright's WebGPU support as experimental/unreliable in general, based on research; this investigation tested the specific, narrower question of whether it works at all in this specific sandboxed container, as a one-off manual-equivalent check -- not as a proposal to adopt Playwright for ongoing automated testing (Deno already covers that, decision 0008).

Options considered

navigator.gpu.requestAdapter() with default headless Chromium launch args — rejected
navigator.gpu was undefined entirely when evaluated against a bare/non-navigated page context.
Add --enable-unsafe-webgpu --enable-unsafe-swiftshader --use-vulkan=swiftshader --disable-gpu-sandbox flags — rejected
No change to the outcome. Separately, navigating to an actual page (rather than about:blank) did make navigator.gpu appear (present: true), but requestAdapter() still resolved to null ("No available adapters", Chromium's own console warning) regardless of these flags.
Investigate root cause via /dev/dri, Vulkan tooling, Mesa/lavapipe presence — chosen
Confirmed there is no /dev/dri or any GPU device node in this container at all (unlike the host WSL2 install, which does have WSLg's GPU passthrough mounted at /mnt/wslg -- this sandboxed execution context does not inherit it). Chromium's GPU process has no device to bind to, hardware or software (SwiftShader's own bundled Vulkan ICD is present in the Playwright Chromium install but still didn't produce an adapter). Deno's WebGPU (wgpu-native/Rust) succeeding in this same container (confirmed: 106 passing tests including real compute/render-pass execution) shows the constraint is specific to Chromium's GPU process architecture, not a blanket absence of any software rendering path in the container.

Decision

Real-browser (even headless, even software-rendered) WebGPU visual verification is not available to an agent in this sandbox. For glemy/game/glemy/game_ffi.mjs (the one module with no Deno-testable equivalent), verification was scoped down to what remains genuinely checkable here: the full ESM/FFI import graph resolves with zero errors under a real Chromium, main() runs without throwing, and the loop's error-handling path (skip-drawing on a render Error) was exercised for real via the actual requestAdapter() == null condition. Pixel-level confirmation is left as an explicit manual step for the user, called out directly in development-plan.md section 4 rather than silently assumed.

Verification

Directly reproduced: navigator.gpu present but requestAdapter() null, across multiple flag combinations (--enable-unsafe-webgpu, --enable-unsafe-swiftshader, --use-vulkan=swiftshader, --disable-gpu-sandbox, --headless=new, --no-sandbox). Confirmed absence of /dev/dri and any GPU-related /dev node. Confirmed Deno's independent WebGPU stack (wgpu-native) does work in this same container via the existing, passing test suite -- ruling out 'no GPU access at all' as the explanation and narrowing it to Chromium's GPU process specifically.

Consequences

Any future browser-only (non-Deno-testable) WebGPU code added to this project -- a real WebGPU canvas context being the most likely next case, per decision 0010's deferred future work -- will have the same verification gap: an agent in this sandbox cannot visually confirm it, only structurally/statically. Keep such changes as small and well-researched as possible (matching how game_ffi.mjs was scoped down to a single, well-established Canvas2D call), and be explicit in commit/doc summaries about what remains manually-unverified rather than implying full confidence.

References