The crate-extraction findings Phase 6 deferred the alknet-http rework
on the grounds that the QuicStream wrapper (44 lines) is a necessary
adapter. The finding was right about the symptom, wrong about the
cause: the root is that the leaf type is split, so every consumer
re-joins or bypasses. Five abstractions exist for one concept
(BiStream trait vestigial in code, Connection, SendStream/RecvStream,
WsStream, MpscSendStream/MpscRecvStream).
ADR-092 resurrects ADR-007's BiStream as a concrete newtype leaf
(the bounds survive, the trait becomes a concrete struct for
Pin<&mut Self> projection), moves the join into core's quinn/iroh
BidiStreamSource impls once, and removes the per-handler wrappers:
- HttpAdapter::handle drops QuicStream (44 lines) and QuicStreamDuplex
(38 lines); serve_io is unchanged.
- WebSocket runs through Connection::from_bidi + the call-protocol
handler. WsBidiStream (~50-80 lines) implements AsyncRead/AsyncWrite
over axum WS binary messages. WsStream trait, drive_ws_session loop,
and ~150 lines of dispatch glue removed. ADR-044/048's 'WS message
stream is BiStream-satisfying' becomes literal.
- Tunnel/SSH handlers call tokio::io::split(bidi) for their two pumps
(same stdlib idiom as TcpStream/TlsStream). ADR-078 preserved.
- SendStream/RecvStream collapse to thin newtypes (quinn enum dispatch
gone); retained for ADR-074 into_sub_streams() and channels
reassembly (ADR-071 unidirectional sub-streams).
- 'VPN-like without being a VPN' over WS in v1 becomes real: the
webtransport.md path, over WS, now. WASM SSH parser implements
BiStream over a WS-message adapter on the browser side.
- WebTransport h3 extraction recorded as a future channels-variant
move enabled by the unification (out of scope per ADR-044).
Amends ADR-065 (from_bidi primary, from_stream escape hatch),
ADR-070 (accept_bi returns BiStream), ADR-074
(ChannelBidiStreamSource::accept_bi returns BiStream; into_sub_streams
unchanged). ADR-077 two-mode TTY design preserved. Resolves the
findings.md Phase 6 deferral.
Three open questions recorded with defaults (WsBidiStream home,
SendStream/RecvStream long-term home, from_stream vs from_bidi
primacy) — none blocking.