SIGN IN SIGN UP

pbz: Chunk 30 round-four fixes — the readyState check ate a good frame set

The pattern held for a fourth time: round three's fix broke a healthy
path. Making alive() refuse on a closed-but-unannounced socket was
right, but collectFrames' teardown send was guarded only on isDead, so
it started throwing AFTER a complete frame set was already in hand. That
destroyed the "a complete set survives the drop" property Chunk 29 was
built to provide, broke samplePreview (and so pbz power) as a pure read,
and made save() report a frozen wall on a device that had just delivered
all 150 frames. The teardown is best-effort by its own comment and now
actually is.

The id in the recovery command is file-supplied — import() passes the
.epe's own id through as opts.id — so a hostile file could have put a
backtick into a command a user pastes. Host and id are both shell-quoted
now. The comment claiming an id "cannot be eaten by argv as a flag" was
true only for generated ids.

withDeviceState's try/catch had made its own type guard unobservable,
re-vacuuming the test round three had rewritten precisely because it was
vacuous. The device assignment moved out of the try, with an
isExtensible check, so a frozen error is refused up front rather than
silently losing the property that README documents as meaning "the wall
was never touched".

Also: sendBytecode checks liveness per chunk, since a death partway
through delivered chunk 1 of N and still returned — which callers read
as "every chunk is on the socket", on the largest write pbz makes.
alive()'s refusal now marks the connection dead, so parked waiters fail
fast instead of timing out. defrag's two restore commands were missing
--host, the same wrong-device hazard at the largest blast radius in the
tool. And the class header's concurrency note was both over-narrow and
under-stated.

Live verification: every printed command runs verbatim, both maybe-paused
recoveries work, and pbz info reads fps 0.00 exactly as claimed.

37 new tests, 229 total, typecheck green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZnUXRsLLnt2A7pR3X4Luj
T
Tarek Rached committed
52a09314f5d59b35b76aac6b92dd4962f7d3438f
Parent: bf0214e