Prune the channels spec to reflect the stream-unification resolution
(docs/research/stream-unification/findings.md): the channels wire format
goes from 9 bytes to 8 bytes, the channels layer no longer carries a
stream_type concept, into_sub_streams() is removed, and TTY always uses
its 5-byte format (carried transparently in the channels payload).
ADR-093 is the umbrella decision (the channels-layer consequence of
ADR-092's BiStream handler leaf): every channel is a BiStream, the
handler owns its sub-stream multiplexing, the channels layer routes by
channel_id only. Amends ADR-071 (8-byte header, no stream_type),
ADR-074 (into_sub_streams removed, accept_bi yields BiStream), reverses
ADR-077 (TTY always 5-byte), and the channels-facing clauses of
ADR-072/073/075/076/080/081. Adds ADR-092 forward-reference note
(into_sub_streams preservation subsequently reversed by ADR-093) and
the missing ADR-092 cross-reference on ADR-070.
Adds OQ-68 (add/strip API shape — built-in vs utility; the contract is
decided in ADR-093, the function surface is open; two-way door, low
priority, decision-ready when the channels crate's implementation
begins).
Rewrites the 7 channels spec docs (README, overview, channels-wire,
channels-connection, channels-adapter, channel-operations, channel-client)
to describe the post-amendment shape as current, with the 8-byte header,
the add/strip composition, single accept_bi accessor, BiStream per
channel, and TTY-always-5-byte.
Touch-up cross-references in hub README, client README, ADR-085, and
the OQ-45/47/65 question files (TTY-internal stream_type 3 →
STREAM_CTRL_IN; channels 9-byte → 8-byte).
Two refinements from the review:
1. Control stream_types (3/4/5) carry ALPN-specific payloads, not
JSON. The channels layer is blind to what control stream_types carry —
it reassembles bytes and delivers them to the handler. TTY happens to
use JSON for its control channel because its control messages map
cleanly to JSON; another ALPN might use a binary format. The channels
layer does not mandate JSON on control stream_types, the same way it
doesn't mandate a format for data stream_types. This prevents the
TTY/PTY JSON constraint from becoming a binding constraint on all
future channel types. (ADR-071, channels-wire.md)
2. Hub and worker are consumers of channels, not sub-crates. The existing
alknet-hub crate IS the channels hub — it depends on channels-call and
uses channels as its substrate, with the relay logic (ADR-079) living
in alknet-hub. A worker is any crate that uses ChannelClient to dial.
There are no channels-hub or channels-worker sub-crates. The dependency
direction is: alknet-hub → channels-call → channels-core → alknet-core;
worker → channels-call → channels-core → alknet-core. The channels
crate has no dependency on alknet-hub or any worker crate. (ADR-081,
overview.md)
Three simplifications to the channels spec, all flowing from the review:
1. Substrate simplification (ADR-071 revised): the 9-byte chunk header is
used in ALL substrates — in-line (TCP+TLS, WebTransport), native (QUIC
bidi streams), and multi-connection. The ChannelsAdapter reads headers
off every bidi stream it accepts; the transport's native multiplexing
is a performance optimization (independent flow-control windows), not a
protocol change. One wire format, one code path, one handler experience.
The channel_id in the header is the correlation key across substrates.
2. Stream_type decomposition (ADR-071 revised): every stream_type is
unidirectional. Bidirectionality is two stream_types (write + read), not
one 'bidirectional' stream_type. Grouped in threes: 0/1/2 = data
write/read/err, 3/4/5 = control write/read/err, % 3 formula. This
resolves the TTY control channel's 'not actually bidirectional' flaw —
control is now 3 (write, client→server) + 4 (read, server→client), each
with its own reassembly buffer and EOF. Channel 0 uses [0,1] (call frames
bidirectional via 0=in, 1=out). TTY uses [0,1,2,3,4]. ADR-072, 073, 074,
077 updated for the new stream_type assignments.
3. Sub-crate decomposition (ADR-081 new): channels-core (pure multiplexer —
wire format, demux/mux, ChannelBidiStreamSource, ChannelManager; depends
on alknet-core only, no call dependency, ALPN-blind) / channels-call
(channel 0 pre-negotiation + lifecycle op registrations; depends on
channels-core + alknet-call) / channels-hub (relay) / channels-worker
(ChannelClient). Isolates the call-protocol coupling from the pure
multiplexer so the dependency graph is honest.
ADR-077 (TTY inside channels) updated: TTY now uses 5 sub-streams [0,1,2,3,4]
with control properly bidirectional via 3/4; amends ADR-052's stream_type
assignments for direct mode too (direct alknet/tty now uses 0-4, not 0-3).
Spec docs updated: channels-wire, channels-connection, channels-adapter,
channel-operations, overview, README.