Captures the single-stream flow-control ceiling as a known constraint with
the recursive-composition escape hatch: parallel throughput comes from N
independent channels connections (client optimization), not cross-connection
tokens or channels-layer coordination. Pins that the channels layer does no
cross-connection channels, no cross-connection primitives, and no parallel-
transfer optimization — those are downstream client concerns.
Adds three sections filling the conceptual gaps in the phase-0 findings:
- Hub Motivation: The Multi-Transport Collapse — diagnoses the
O(protocols × transports × spokes) mess the hub crate faces and shows how
channels collapses it to one connection per leg with channel-by-channel
byte forwarding, reusing the call protocol's auth/forwarded-for model.
- Channel Open Negotiation — concrete channel/open, channel/close,
channel/control, channel/resources operation payloads with field tables,
error codes as CallError strings, bidirectional open semantics, and the
end-to-end ACL flow for browser→hub→spoke. No new wire framing; all four
operations register on the call protocol's existing OperationRegistry.
- Channel Manager and Connection Internals — the ChannelsAdapter/
ChannelManager split, ChannelManager state sketch, ChannelsAdapter::handle
read/demux loop with channel 0 preinstall, the channel/open handler
closure threading into OperationRegistry, ChannelConnection as a
Connection via the existing from_stream path, the hub relay as
ChannelManager-to-ChannelManager byte pumping, and the boundary
(ChannelManager holds no handlers, no ALPN parsing, no auth, no transport
coupling).
Also adds four new open questions (OQ-CH-08 through OQ-CH-11) on resource
staleness, responder-to-initiator lifecycle, typed destructure ownership,
and hub relay channel_id remapping; two new POC stretch goals (hub relay,
channel/resources); and updates the opening to note the revision scope.
Channel 0 is not a special control plane with its own framing. It is
simply the alknet/call ALPN, pre-negotiated so both sides route it to
the CallAdapter without an explicit channel/open exchange. Every channel
works the same way: reassemble chunks into a stream, look up the ALPN
in the HandlerRegistry, hand off to the handler. Channel open is
bidirectional — either side can initiate.
Generalizes TTY's chunk format into a universal channel multiplexer
(alknet-channels) that serves as a transparent proxy between the call
protocol (control plane) and data-plane protocols (TTY, SSH, tunnels).
Key design: 9-byte chunk header (channel_id + stream_type + length),
ChannelConnection implementing the existing Connection interface, and
ACL inherited from the call protocol's OperationContext.