SIGN IN SIGN UP

pbz: Chunk 30 round-five — the close code, and the scar tissue

Two reviewers this round, and both found real things.

Adversarial: alive()'s die() destroyed the close code. That branch fires
in exactly one window — readyState flipped, close event not yet
dispatched — which is precisely when the REAL close event carrying
(code 1006) is queued and about to land. die() is first-cause-wins, so
claiming the cause there permanently replaced it with a generic
sentence, for the thrower and every parked waiter. 1006 versus 1000 is
the one bit separating a device that dropped from a clean hangup, and
protocol.mjs's own comment says that must not be lost. It now throws
without claiming the cause and lets the close event speak, one task
later. No test drove that sequence, which is why five rounds missed it;
one does now.

The source-level drift guard caught one of seven spellings of the drift
it exists to catch, and false-FAILED on cosmetic reformatting of the
table or the union. A guard that quietly stops guarding is worse than
none. Rewritten to match any quoting and spacing, to check both
directions (an orphaned message now fails too), and to fail loudly if
its own scraping breaks.

Also: isExtensible did not cover a non-writable or getter-only `device`,
and round four had moved that assignment out of the try, so those
replaced the real error — the exact outcome the guard exists to prevent.
defrag's host interpolations were bare while DEVICE_LEFT's were quoted.
The chunk-size test leaked a live idle timer, costing the protocol file
five seconds.

Maintainer review: the code is not over-defended, the commentary was.
Two comments contradicted themselves in consecutive sentences (one still
described main's .catch(), one duplicated the paragraph below it), two
made opposite claims about send(), and the class header's read-vs-read
guarantee was the same kind of over-claim a previous round had just
corrected on the read-vs-write axis. Cut the archaeology, kept the
counter-intuitive facts that stop someone tidying a message back into a
falsehood. Deleted two subsumed tests, merged three throw-type tests
into a table that gains the frozen-Error case — which had NO coverage
while carrying the most emphatic comment in the function. Dropped a test
that pinned a wart as a contract. Trimmed the plan entry from a review
changelog back to a design record.

237 tests, typecheck green.

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