Files
alkcall/src/channels/mod.rs
T
glm-5.3-flash 944c300c17 feat(channels): implement the single-publish fixes — S-01..S-04 (reviews 010/011; ADR-047 am. 4, ADR-052, ADR-053, ADR-022 am.)
S-01 — the marked-pub open contract (ADR-047 amendment 4):
- ChannelCore::register_pub_openable + PubOpenHandler (the put path's
  handler returns its result for the merged single response; the
  wrapper awaits inline, teardown is EOF-driven, handler_task stays
  None); register_openable* refuses Pub-typed specs; the wrapper entry
  points refuse unmarked/non-Pub shapes
- the reserved input key `channel_id` (the initiator-allocated id):
  stripped pre-validation by resolve_sink_handler (the single source of
  truth, P-08), handed to the wrapper via OperationContext.metadata, a
  missing key rejected INVALID_INPUT; adopt parity enforced
  (ManagerError::InvalidAdopt) and adopt failures answer
  channel:open_failed / adopt_failed
- zero call.published on marked ops: the first publish chunk on a
  marked op is rejected loudly (channel:publish_chunks_rejected) in
  both dispatch loops; the handler is never fed
- relay put-translation replaces RelayError::PubTypedOpen: hub
  allocates odd on the producer leg, opens the spoke op in the
  background (put-acks-in-result), one-direction pump, response-mirror
  with the producer's reserved key stripped
- ChannelClient::open_pub_channel + PubOpenReply (the initiator-
  allocates put open capability)

S-02 — channel/control implemented (ADR-052): establisher-contributed
ChannelControl (Establishment::with_control), manager-owned registry,
teardown removals, channel:no_control_handle capability answer.

S-03 — channel/resources/subscribe implemented (ADR-053): the
ResourceEnumerators registry (shared per peer), snapshot-then-changes
enumerators, scan-once aggregation, the empty seed; the
always-failing one-shot error stream removed.

S-04 — op/register forward-through (ADR-022 amendment): announced
unmarked Sub/Pub register the real streaming/sink forwarding shapes;
marked announcements refused with MARKED_SPEC_UNSUPPORTED; marked
specs refuse the generic registration path and register_imported
(Result-returning now).

Guard (review 010 action 3): tests/stub_guard.rs greps src/ for
not_implemented; the four pinned stub tests are deleted and the
marked-spec registration refusals are pinned by tests.

Verified: cargo test (696 + guard), clippy --all-targets -D warnings,
fmt --check, fuzz corpus replay.
2026-10-13 09:00:21 +00:00

62 lines
2.7 KiB
Rust

//! Channels protocol: N logical channels over one transport stream
//! (ADR-034, amended by ADR-035 — no `stream_type` concept).
//!
//! Channel 0 is pre-negotiated as `alk/call` (ADR-036); channels
//! 1..N are opened dynamically via per-ALPN open ops on channel 0
//! (ADR-047). The channels layer is a re-framing proxy: it converts
//! between "one transport stream carrying N channels" (the wire) and
//! "N independent `BiStream` handles" (what handlers see).
//!
//! ## Module layout
//!
//! - [`wire`]: the 8-byte chunk header (sync core, WASM-clean).
//! - [`reassembly`]: per-channel `MpscSendStream` / `MpscRecvStream` —
//! the reassembled `AsyncRead + AsyncWrite` pair the handler sees.
//! - [`mux`]: the mux (`MuxHandle` / `MuxRunner`) — frames per-channel
//! bytes back onto the transport.
//! - [`manager`]: `ChannelManager` + `ChannelState` + the channel map.
//! - [`source`]: `ChannelBidiStreamSource` — implements
//! `BidiStreamSource` for a single channel (yield-once `accept_bi`).
//! - [`adapter`]: `ChannelsAdapter` — `ProtocolHandler` for
//! `alk/channels` (the demux loop).
//! - [`operations`]: `ChannelOperations` — registers `channel/close`,
//! `channel/control`, `channel/resources/subscribe` on the call
//! `OperationRegistry`; the per-ALPN open ops are registered by the
//! ALPN crates via `ChannelCore` (ADR-047 §3).
//! - [`policy`]: `ChannelLifecyclePolicy` + `PerIdentityChannelPolicy`
//! (ADR-041, amended by ADR-047 §7 — opener ledger).
//! - [`pump`]: `pump_bidi` — the two-pump data-plane helper (alknet
//! ADR-078, pinned upstream by ADR-050).
//! - [`relay`]: `ChannelRelay` — the in-tree relay component (ADR-042
//! as amended by ADR-051): translate hop + `pump_bidi` byte-forward
//! hop for from_call-imported marked specs re-exposed on a hub's
//! consumer-leg channel-0 registry.
//! - [`resource`]: `ResourceEnumerators` — the enumerator registry
//! behind `channel/resources/subscribe`'s live subscription
//! (ADR-053).
//! - [`hub_leg`]: `HubLegTemplate` — the hub-leg install template
//! (ADR-051 §5): fork + generic channel ops + bootstrap discovery +
//! plain bundles + relay openables + serving identity, composed into
//! the `install_channel_zero` hook every hub side needs.
//! - [`client`]: `ChannelClient` — transport-agnostic
//! `from_connection` (ADR-043).
//! - [`self::env`]: `ChannelOperationEnv` extension trait (ADR-047 §4 —
//! keeps the call crate free of channels types).
//!
//! See `docs/architecture/` for the full specification.
pub mod adapter;
pub mod client;
pub mod env;
pub mod hub_leg;
pub mod manager;
pub mod mux;
pub mod operations;
pub mod policy;
pub mod pump;
pub mod reassembly;
pub mod relay;
pub mod resource;
pub mod source;
pub mod wire;