Phase 1 architecture for alknet-channels (multiplexing proxy on alknet/channels). Grounded in the completed de-risk POC (28 tests) and the landed ADR-070 (BidiStreamSource trait + Connection::from_source). ADRs: - 071: 9-byte chunk wire format (generalizes TTY's 5-byte) - 072: channel 0 pre-negotiated as alknet/call (no special control plane) - 073: channel lifecycle operations on the call protocol — channel/open, close, control, resources/subscribe; direction field pinned; subscribe from day one (not poll-for-v1 — StreamingHandler machinery exists) - 074: ChannelBidiStreamSource implements BidiStreamSource (ADR-070); into_sub_streams() typed accessor for TTY; accept_bi() generic path - 075: ChannelsAdapter + ChannelManager; REQ-CH-01..04 wire invariants - 076: bounded-buffer backpressure (1 MiB), 256-channel cap, monotonic IDs - 077: TTY inside channels uses sub-streams, not own wire format; amends ADR-052 scope to direct-connect TTY; channels feature on tty - 078: two-pump shutdown-on-completion contract (handler-level) - 079: hub relay translates channel 0, byte-forwards data channels - 080: ChannelClient (QUIC-only); AlknetClient core extraction deferred (OQ-55) Spec docs: overview, channels-wire, channels-connection, channels-adapter, channel-operations, channel-client. OQ-56 (full windowing) and OQ-57 (two-pump helper extraction) are genuine deferred(scope) deferrals with concrete blocking conditions; the contracts are decided, only the extensions are deferred. Hedging audit converted three research hedges into decisions: resources/subscribe (not poll), server-assigned IDs (not if-zero-RTT), bounded-buffer (not if-HOL-becomes-a-problem).
2.0 KiB
2.0 KiB
OQ-57: Two-Pump Helper Extraction to alknet-core
- Origin:
docs/research/alknet-channels/poc-summary.md§Issues Surfaced #7;docs/architecture/decisions/078-two-pump-shutdown-on-completion.md - Status: deferred(scope)
- Door type: two-way (additive — a helper function does not change any API surface; handlers that inline the pattern continue to work)
- Priority: low
- Blocked on: a second two-pump handler existing, so the shape
convergence is observable. The tunnel handler is the first two-pump
consumer; the SSH
direct-tcpipchannel will be the second. Extracting the helper from one consumer (the tunnel) would bake in a shape that the second consumer (SSH) might not fit — thefn pump_bidi<R, W>(recv: R, send: W, ...) -> impl Futuresignature is a cross-crate API surface if it lives inalknet-core. The trigger is: two real two-pump handlers exist and their inline implementations have converged on the same shape. - Resolution: Not yet decidable. The shutdown-on-completion contract
is decided (ADR-078) — a two-pump handler MUST shut down the opposite
sink when one pump completes, or it deadlocks. The helper extraction is
an implementation convenience: ~10 lines of inline code per handler vs. a
shared function in
alknet-core. The contract is pinned; only the extraction is deferred. The helper is extracted when two real consumers exist and their shapes converge, so the extraction is grounded in two implementations rather than guessed from one. - What does NOT block on this: the two-pump pattern is documented
(ADR-078) and the tunnel handler implements it inline. The SSH crate's
direct-tcpiphandler will implement it inline too. Both work without a shared helper. The friction is copy-paste with documentation (~10 lines), not a missing capability. - Cross-references: ADR-078 (the shutdown-on-completion contract),
ADR-074 (the
accept_bithat yields the stream pair the pumps operate on),docs/research/alknet-channels/poc-summary.md§Issues Surfaced #7