Cross-process suite for the WebSocket read loop's frame envelope — what
each spine answers to a frame before anything dispatches, pinned over a real
upgrade. The HTTP twin is rpc_adversarial's envelope cases
(create_rpc_envelope_cases); a socket classifies its frames in its own
loop (TS register_action_ws, Rust fuz_realtime's ws_endpoint), so the
HTTP pins say nothing about it.
- a parse error — a frame that is not JSON answers
parse_error with
id: null, and the socket keeps serving - a non-object frame — a JSON scalar answers
invalid_request with
id: null (the scalar is not read as its own id) - a batch array — answers one
invalid_request with id: null; batches
are not supported on either transport - a notification — a string method with no id answers no frame
- a stray response — a
{id, result} frame matching no server-initiated
request answers no frame (it demuxes as a peer response and is dropped) cancel — the notification answers no frame: for an unknown id, for
malformed params, and for a request in flight, which keeps running and
answers under its id once it completes (neither spine's peer/ping
observes its signal, so the cancel's effect is invisible here; consumer
suites with a signal-observing seam pin it)
Silence is asserted positively: each case marks the received-message
count, sends its frames, then round-trips a heartbeat probe and reads back
everything after the mark. The socket is ordered, so a frame that should
produce nothing leaves exactly the probe's response, and the probe doubles as
proof the socket survived the frame.
Wire codes are independent copies of the producers' constants — parity by
test. Gated on capabilities.ws; the in-flight cancel also on
capabilities.peer_request (it holds a request with peer/ping).
Cross-process only: create_ws_transport needs a real bound socket, so wire
it from a *.cross.test.ts file.