Incorporates the completed de-risk POC (poc-summary.md, 28 tests passing)
into phase-0-findings.md:
- Marks OQ-CH-12 RESOLVED (lenient drop, validated by POC), OQ-CH-13
CONFIRMED +EV (do the BidiStreamSource refactor), and clarifies OQ-CH-14
with the AlknetClient context: a general downstream-facing client in
alknet-core paired with whichever ALPN handler a crate provides, with
server/client bidirectionality preserved (hub/worker can act as both,
each side fills its registry with the other's resources).
- Adds §POC-Validated Requirements carrying the POC's surfaced invariants
into Phase 1 as requirements (not open questions):
- REQ-CH-01..07: wire-level invariants for the channels crate spec
(shutdown emits zero-length sentinel, transport close drops all
senders, mux handle/runner split, lenient unknown channel_id, bounded
backpressure, two-pump shutdown-on-completion, PollSender adapter).
- REQ-CORE-01..04: the light alknet-core refactor to land alongside the
channels crate (BidiStreamSource trait, Connection::close fix,
AuthContext test helper, AlknetClient).
- Updates the De-risk POC section to COMPLETE status with what was
validated, what was surfaced, and what remains out of scope.
- Updates the opening revision note to reflect the POC pushed the core
mechanics beyond speculation into validated territory.
Adds docs/research/alknet-channels/poc-plan.md — a standalone three-step POC
plan that derisks the channels layer in isolation (no call protocol, no real
transport, no real adapters):
- Step 1: chunk format + N-channel demux/mux — generalizes TTY's 5-byte
ChunkReader/ChunkWriter to the 9-byte format, validates decompose→stream→
recompose for 3+ concurrent channels with the sync-core/async-shell split
pattern from TTY's REQ-TTY-01.
- Step 2: per-channel Connection presentation — wraps each reassembled
channel as Connection::from_stream and runs a minimal echo ProtocolHandler
through the full path. Validates the existing Connection abstraction is
sufficient; no core changes needed for the POC.
- Step 3: tunnel handler — opens a TcpStream and pumps bidirectionally,
reusing TTY's pump_session shape with two pumps. Validates the same
concepts behind the TTY crate work as a generic port proxy.
Stretch goals: WASM build of the sync core, mixed channel types on one
connection, hub relay sketch with channel_id remapping.
Adds three open questions to phase-0-findings.md:
- OQ-CH-12: unknown channel_id on demux (lenient drop vs strict error).
- OQ-CH-13: core BidiStreamSource trait — additive refactor to make
ChannelConnection a first-class peer of QUIC (many bidi streams) rather
than a bag of yield-once Connections. Likely +EV; not needed for the POC
but should be evaluated in Phase 1.
- OQ-CH-14: client-side channels endpoint — the symmetric ChannelClient
type (analogue of AlknetEndpoint vs CallClient). After the POC we're
probably going to need some light refactoring to the core to make these
easier; mostly additive and not breaking in major/pita ways.
Updates phase-0-findings.md De-risk POC section to point at the detailed
plan and adds the poc-plan to References.
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.