videoskilletdecisions Open the app ↗

0001 — A GPU hang rebuilds the device instead of ending the session

Status: accepted, 2026-08-07.

Context#

The render loop can tell that submitted work has stopped completing — it races onSubmittedWorkDone() against a deadline and scores strikes — but it cannot tell why. Two causes reach the same symptom and want opposite handling:

The original onHang assumed the first and went straight to a fatal "close this browser tab" screen. That reasoning was never tested, and it is unfalsifiable from where it sits: having refused to try a replacement, the code could never discover that a replacement would have worked.

The distinguishing evidence is available, just not at the moment of the fault. It is whether a device ever completed any work: a replacement born onto a wedged process never does, while a device that ran for minutes and then stopped obviously did.

Decision#

A hang takes the same path a device loss does — destroy, build a fresh device, hand back the controls, the sources and the audio graph.

The fatal screen is reached only after RebuildPolicy has spent its replacements on devices that never completed any work (RenderLoop.confirmedWork). A device that worked and then stopped is a one-off however many times it recurs, because each rebuild demonstrably fixed it; only a run of never-alive devices is evidence the fault is behind them.

Hangs and losses hold separate counts, so neither spends the other's budget.

Because a false positive now costs one rebuild rather than the session, the device is also probed on every lifecycle transition (kick) rather than only on the watchdog's beat.

Consequences#

Notes#

The mechanism this was originally built for — a discrete card runtime-suspending underneath a hidden tab's live device — was subsequently tested and does not happen (scripts/gpusleep.mjs; the card is pinned awake for as long as a device is open on it). The decision stands on its own: stopping a hang from ending the session is correct whatever the hang turns out to be. The full working-out, including the disproof, is in docs/handoffs/2026-08-05-freezes-and-the-worker.md.