A tiny CPU-only test of the readback trap:
read = () => [0, 0]
deepEqual(read(), read()) passes.
deepEqual(read(), [17, 29]) fails.
Matching outputs don't validate the observer. Keep an independent expected pattern.
Lesson from Nefayran:
That check was in the suite and passed: zero steps between save and load, RNG arrays equal byte for byte. Both sides went through the same GPU readback, which was silently returning zeros, so zeros matched zeros. Now that readback throws on a buffer it can't copy from.етя