2026-06 · DevOps
Most players arrive on a phone and the QA team is me. A nightly LLM-judged smoke sweep files issues; a deterministic Playwright gate blocks merges. Both start from a cold profile, because that is the only state where the worst bug lived.
33
games in the manifest, swept in 2D and 3D
0
secrets the merge gate needs
2
rungs: judgment and enforcement, split
before
No capture of the install prompt sitting over a game's control dock survives from before the rig existed. The bug lives on as the gate's dock-reachability assertion, which fails if anything ever covers a control again.
during

The frame the nightly judge reads: cold profile, cover state, nothing dismissed.
2026-09-20 · The smoke harness's own capture: headless Chromium with SwiftShader WebGL, a fresh browser context, 390 by 844 at 3x
after

Playing state in 3D on software WebGL, the dock unobstructed: the invariant the gate asserts.
2026-09-20 · The smoke harness's own capture: headless Chromium with SwiftShader WebGL, a fresh browser context, 390 by 844 at 3x
Walkthrough video: coming soon.
The site ships an install prompt that stays dismissed for thirty days. On my warm, logged-in profile every game looked fine. A first-time visitor on a cold profile got the prompt layered over the in-game control dock, and the taps that should have built a tower hit the prompt instead. Nobody files a bug for that. They leave.
CI runners have no GPU, and the flag that disables it gives you a black canvas. No human visits every game in both render modes from a clean profile on a phone every day. And an LLM's opinion can never be the thing that blocks a merge.
Two rungs, built with different tools because they answer different questions. A nightly smoke sweep boots headless Chromium at an iPhone-class viewport with software WebGL, screenshots every game in 2D and 3D from a fresh browser context per shot, writes a report of console errors and failed assets, then hands the shots to Claude Code, which judges them against a written invariant list and files one labeled issue per failing game. A deterministic Playwright gate encodes the same invariants as hard assertions on every pull request: dock unobstructed, board large enough, WebGL context alive, scripted interaction error-free.
Rejected
One LLM loop that both judges and blocks
A non-deterministic gate trains people to re-run until green. The judge files evidence; the gate blocks by determinism and uploads traces, so a failure is replayable, not arguable.
Test from my own logged-in profile
That profile had dismissed the install prompt. Every shot uses a fresh context, so the cold-profile bug can never be masked by a tester who already dismissed it.
The capture harness, the nightly workflow that hands the shots to Claude Code and files issues, the per-PR gate with a reference spec, a stale-game advisory mode, and an operator that drains the playtest backlog into reviewed pull requests.
The gate then broke for the runner's reasons twice: one game's Claim button never stabilized and blocked every pull request (#1415), and the runner ran out of disk, not memory (#2381). Each was its own fix, because a gate that is red for the wrong reason is a gate people learn to skip.
npm run playtest:gatenpm run playtest:smokeWire up the playtest games QA harness and gate
#722 · 2026-06-07 · feature
Add stale-game advisory mode to the playtest harness
#725 · 2026-06-07 · feature
playtest smoke: inspect WebGL after the game starts, not at the cover screen
#742 · 2026-06-07 · feature
Agents Store: ship the game-builder operator — games.fix drains the playtest backlog
#1002 · 2026-06-11 · bugfix
the-pull: fix the Claim button never stabilizing (unblocks the playtest gate)
#1415 · 2026-06-18 · bugfix
Playtest gate: the runner runs out of disk, not memory
#2381 · 2026-09-18 · feature
Checked at build against the published corpus.
www.jakelawrence.xyz/research/case-study-library/playtest-rig
Cite: Lawrence, J. (2026). An autonomous mobile QA rig for a thirty-game library. jakelawrence.xyz case study library.
I design and ship AI tools, full-stack apps, and data pipelines — end to end, to production. Tell me the problem in a sentence; I'll give you an honest read on fit within a day.
Work with me →