//! alkcall: Call + channels RPC — operations, streaming, service discovery, //! and N-channel multiplexing over one transport stream. //! //! This crate is the unification of the call protocol (structured JSON RPC: //! operations, streaming subscriptions, service discovery) and the channels //! protocol (multiplexing proxy: N logical channels over one transport //! stream, channel 0 pre-negotiated as `alknet/call`). Both halves share //! the vendored core types and the call protocol's `OperationRegistry` — //! channel lifecycle is orchestrated by call operations on channel 0 //! (ADR-047: openable ALPNs are operations). //! //! ## Architecture //! //! - **Vendored core types** ([`core`]): `Connection`, `ProtocolHandler`, //! `BiStream`, `BidiStreamSource`, `AuthContext`, `IdentityProvider`, //! `Capabilities`, `OwnershipProvider` — the home for these types //! going forward. //! - **Registry** ([`registry`]): operation specs, context, dispatch, and //! the operation registry — the call half's dispatch core. //! - **Protocol** ([`protocol`]): wire format, streams, adapter, dispatch //! loop, pending requests, abort cascade — the call half's wire layer. //! - **Client** ([`client`]): `CallClient`, `from_call`, `OperationAdapter` //! — the call half's outbound surface. //! - **Channels** ([`channels`]): the channels protocol — 8-byte chunk //! wire format, demux/mux, `ChannelManager`, `ChannelsAdapter`, //! `ChannelBidiStreamSource`, `ChannelOperations`, //! `ChannelLifecyclePolicy`, `ChannelClient`. Channel 0 is //! pre-negotiated as `alknet/call`; channels 1..N are opened via //! per-ALPN open ops (`channels//sub`, `channels//pub`) //! on channel 0 (ADR-047). //! //! ## Downstream composition //! //! alkcall is a pure protocol crate — no networking, no transport //! dependencies. Downstream crates compose on top of it in a layered //! dependency chain. See `docs/architecture/README.md` §"Roles and //! Composition" for the full layering diagram and role definitions. //! //! ### The four roles //! //! | Role | Call protocol | Channels protocol | //! |------|---------------|-------------------| //! | **Producer** | Registers ops on an `OperationRegistry`, runs a `Dispatcher` | Runs a `ChannelsAdapter`, registers openable ALPNs via `ChannelCore::register_openable` | //! | **Consumer** | Uses `CallConnection` to call ops, uses `from_call` to discover/import remote ops | Uses `ChannelClient` to open channels via `call_open_op` + `open_channel` | //! | **Hub** | Both: runs a `Dispatcher` for ops it produces, holds `CallConnection`s to spokes for ops it consumes | Both: runs a `ChannelsAdapter` for inbound connections, holds `ChannelClient`s to spokes | //! | **Spoke / Worker** | Both: produces ops (its own services), consumes hub ops | Both: produces channels (TTY, tunnel), may consume hub channels | //! //! A single process can be a producer of some ops, a consumer of others, //! a channel opener for TTY, and a channel acceptor for tunnels — all on //! the same `alknet/channels` connection. //! //! ### Pattern for protocol crates //! //! A protocol crate (e.g. alktty, alktunnels) depends only on alkcall //! and provides two halves: //! //! 1. **Producer half** — a `register_*()` function that takes an //! `&mut OperationRegistry` and registers ops with their handlers. //! For channels-based protocols, an `OpenHandler` factory registered //! via [`channels::operations::ChannelCore::register_openable`]. //! 2. **Consumer half** — a typed client wrapper around //! [`protocol::connection::CallConnection`] (or //! [`channels::client::ChannelClient`]) that exposes the crate's ops //! as async methods. //! //! The protocol crate doesn't know whether it's running on a hub, a //! spoke, or a standalone process. The networking + composition layer //! (alknet/alknode) wires protocol crates' producers into registries //! and consumers into clients. pub mod channels; pub mod client; pub mod core; pub mod protocol; pub mod registry; pub use registry::registration::OperationRegistryBuilder;