Present the game runner's frames via Canvas2D putImageData, not a WebGPU canvas context
Context
Building glemy/game.gleam, the requestAnimationFrame runner tying io->pe->render together (development-plan.md, section 4), required deciding how the pixels glemy/render already produces actually reach a visible <canvas> element. The plan's original section 6 anticipated cs/render eventually handing the runner a GPU-resident buffer to present directly via a WebGPU-configured canvas context (context.configure, getCurrentTexture, format negotiation). That path is real but untested anywhere in this project so far, and this sandbox's headless Chromium has no GPU adapter at all (confirmed separately, see decision 0011), making it impossible for an agent in this environment to visually verify a new, unproven WebGPU-canvas code path before committing it.
Options considered
Decision
glemy/game_ffi.mjs's drawToCanvas blits render_entities_to_bytes's RGBA byte array onto a plain 2D canvas (canvas.getContext('2d').putImageData). No WebGPU canvas context is configured. glemy/render is unchanged; it still only produces an offscreen-texture readback.
Verification
Confirmed the ImageData(Uint8ClampedArray, width, height) constructor's exact contract (data type, argument order, width*height*4 length requirement) against MDN before writing the FFI. The full module/FFI import graph (index.html -> game.mjs -> game_ffi.mjs -> render.mjs -> ...) was loaded in a real (headless) Chromium via Playwright against a live deno file-server: zero uncaught exceptions, zero failed resource loads, canvas correctly sized from render.texture_width/height. Actual pixel output was not visually confirmed (no GPU adapter available in this sandbox, see decision 0011) -- that remains a manual step for a real GPU-capable browser.
Consequences
Every frame still does a full GPU-to-CPU-to-GPU(canvas) roundtrip -- fine for a small (64x64) offscreen texture and a simple demo, but the documented future optimization (section 6: GPU-resident STORAGE|VERTEX buffers shared between cs and render, presented without a CPU roundtrip) remains open and is now more clearly motivated: it would also mean switching this file from Canvas2D to a WebGPU canvas context. Revisit only once frame-rate/latency is an actual, measured problem, not preemptively.