Add architecture specs for the alknet-call crate:
- call-protocol.md: CallAdapter, EventEnvelope wire format, bidirectional
stream model with ID-based correlation, PendingRequestMap, protocol
operations (call/subscribe/batch/schema), per-request identity resolution,
connection/stream lifecycle, error codes
- operation-registry.md: OperationSpec, async Handler type, OperationRegistry,
AccessControl with trusted call bypass, OperationEnv with context
propagation (parent_request_id, identity inheritance), service discovery,
irpc integration layering, naming convention (no leading slash in names)
- ADR-012: Call protocol uses bidirectional QUIC streams with EventEnvelope
framing and ID-based correlation. Protocol is stream-agnostic and symmetric.
Resolves OQ-07.
Key design decisions:
- Handler type is async (Fn returning Pin<Box<dyn Future>>)
- OperationEnv::invoke propagates parent context (identity, metadata,
parent_request_id)
- Identity resolution is per-request, not per-connection
- Operation names without leading slash (fs/readFile, not /fs/readFile)
- Batch is a client-side pattern, not a protocol primitive (OQ-14)
- Phase 1 uses service/op paths, node prefix added later (OQ-13)
Also: promote ADR-010 and ADR-011 from Proposed to Accepted, add OQ-13
and OQ-14 to open-questions.md.
iroh uses RFC 7250 raw Ed25519 public keys for TLS instead of X.509
certificates. rustls already supports this. This means the quinn
endpoint can also use raw public keys — same key-based identity model
as iroh, but with direct QUIC over UDP. X.509 is optional, needed
only for domain-facing identity (browser/WebTransport clients).
Update StaticConfig with TlsIdentity enum (X509, RawKey, SelfSigned)
and add iroh_relay field. Remove 'iroh deferred' language — iroh is
a first-class connectivity mode.
iroh's Endpoint natively supports ALPN negotiation and set_alpns(). Our
HandlerRegistry dispatches exactly like iroh's own ProtocolMap/Router
pattern, but shared across both quinn and iroh connection sources. We
use iroh::Endpoint directly (not iroh::Router) because our HandlerRegistry
and AuthContext are shared across sources.
Correct the conflation of quinn/TLS/iroh as interchangeable transports.
They are complementary connectivity modes serving different deployment
contexts: quinn (public IP + TLS), iroh (NAT traversal via relay), TCP
(handler-specific, not core). Clarify that TLS cert = network identity,
not auth identity. Map stealth mode to HTTP handler on standard ALPNs
instead of byte-peeking. Resolve OQ-05 as one-way door. SendStream/
RecvStream now use internal enum dispatch for both quinn and iroh
streams.