Two review findings on checkDoneValue's metering and the wire-mirror binding:
- The string/key byte check used a decoded-length lower bound and then called
JSON.stringify, which materializes the ~6x escaped copy before the over-budget
check — the hundreds-of-MB spike the metered walk exists to avoid. Add
jsonStringBytesUpTo, a non-allocating scan that computes the exact escaped
UTF-8 size (matching JSON.stringify byte for byte, including surrogate pairs
vs lone surrogates) and bails the instant it crosses the remaining budget; use
it for both string values and object keys.
- The frame roster in WIRE_FRAME_FIELD_ROLES was hand-written, so a frame added
to ChildToHost/ReplyMessage without a roster entry slipped past. Introduce
WireFrameShapes (name -> interface) as the canonical roster the roles map is
bound against, plus a WireFrameShapesCoverUnions compile-time assertion that
every message-union member appears in it (verified: adding a frame to a union
without a WireFrameShapes entry fails typecheck).