1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! 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 `alk/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.
//! - **Gateway** (module `gateway`, feature `gateway`): the transport-neutral
//! dispatch spine and `services/schema` disclosure guard — the
//! deadline-bounded, re-rooted-context invoke surface for HTTP
//! gateways, hub relays, and other transport front-ends (ADR-048).
//! - **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`, `pump_bidi` (the
//! two-pump helper, ADR-050). Channel 0 is
//! pre-negotiated as `alk/call`; channels 1..N are opened via
//! per-ALPN open ops (`channels/<alpn>/sub`, `channels/<alpn>/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 `alk/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
//! (alk/alknode) wires protocol crates' producers into registries
//! and consumers into clients.
pub use OperationRegistryBuilder;