Files
alknet/docs/architecture/crates/core
glm-5.2 2aa6363e57 docs(arch): sync specs to transport generalization sweep (ADR-064, ADR-065)
Three code commits landed a clean sweep discovered when building an
external app against the crates. This syncs the architecture specs to
match the codebase and amends the affected decisions.

ADR-064 (supersedes ADR-005): irpc was never integrated — no .rs file in
the workspace ever imported it. The wire protocol (wire.rs) is hand-rolled
length-prefixed JSON; the EventEnvelope shape was derived from the
@alkdev/pubsub TypeScript prior art (ADR-013), not from irpc. ADR-005's
premise ('irpc as the call protocol foundation') was never implemented as
stated. Superseded with a clear header; the body is kept as historical
record.

ADR-065: Connection::from_stream / from_bidi — Connection now accepts any
AsyncRead + AsyncWrite pair via ConnectionKind::Stream (yield-once
accept_bi contract: QUIC yields many streams, everything else yields one
then ConnectionClosed). Unblocks TCP+TLS, SSH channel dispatch,
WebTransport streams, and wasm streams through the same HandlerRegistry
as QUIC connections, with zero handler code changes. MockConnection /
ConnectionKind::Mock removed (tests use from_stream with sink/empty).
Stream-level Mock variants renamed to Stream (they were already generic).

Amended ADRs: ADR-003 (irpc removed from dep table), ADR-007 (from_stream
opens the server-side door; MockConnection removed), ADR-010 (TCP+TLS can
now dispatch through the registry via from_bidi; iroh 1.0 migration noted).

Updated specs: core-types.md (Connection/SendStream/RecvStream sections),
endpoint.md (TCP section, iroh note), call-protocol.md, operation-registry
(irpc Integration section replaced), overview.md, http-server.md,
webtransport.md, call README. OQ-09 (WASM) resolution amended: the
Connection door is now open via from_stream; the accept-loop runtime door
remains closed (tokio doesn't run on WASM).

See docs/research/transport-generalization/findings.md for the full trace.
2026-07-09 07:40:51 +00:00
..

status, last_updated
status last_updated
draft 2026-06-27

alknet-core

Core library for ALPN-based protocol dispatch. Every handler crate depends on alknet-core.

Documents

Document Status Description
core-types.md draft ProtocolHandler trait, HandlerError, Connection, BiStream, StreamError
endpoint.md draft ALPN router, HandlerRegistry, accept loop, graceful shutdown
auth.md draft AuthContext, Identity, IdentityProvider, AuthToken, resolution flow, PeerEntry, CredentialStore
config.md draft StaticConfig, DynamicConfig, ArcSwap, ConfigReloadHandle, AuthPolicy.peers

Applicable ADRs

ADR Title Relevance
001 ALPN-Based Protocol Dispatch Core architectural model
002 ProtocolHandler Trait The trait every handler implements
003 Crate Decomposition alknet-core's position in the crate graph
004 Auth as Shared Core IdentityProvider in core
006 ALPN String Convention ALPN format, one-ALPN-per-connection
007 BiStream Type Definition Connection, BiStream trait, SendStream, RecvStream
009 One-Way Door Framework Decision classification
010 ALPN Router and Endpoint Endpoint, HandlerRegistry, accept loop
011 AuthContext Structure AuthContext fields and resolution flow
015 Privilege Model and Authority Context Per-request identity on OperationContext; admin scope for config reload
030 PeerEntry and Identity.id Decoupling authorized_fingerprints → peers: Vec<PeerEntry>; Identity.id = peer_id (stable)
031 CredentialStore Repo Trait Second repo trait in core; InMemoryCredentialStore default adapter
033 Storage Boundary and Repo/Adapter Pattern Core defines traits + in-memory defaults; persistence adapters are separate crates

Relevant Open Questions

OQ Title Status Relevance
OQ-04 Dynamic handler registration resolved (start static) HandlerRegistry is immutable at startup
OQ-05 Multi-connectivity endpoint resolved (quinn + iroh) AlknetEndpoint supports both, both feature-gated
OQ-11 Handler-level auth resolution observability resolved Handlers store resolved identity on Connection; two identity scopes (connection-level for observability, per-request for ACL)
OQ-33 PeerId — logical id vs crypto identity resolved by ADR-030 PeerId = Identity.id = PeerEntry.peer_id (stable across key rotation)
OQ-34 Persistent peer registry (storage boundary) resolved by ADR-030+031+033 Core defines repo traits + in-memory defaults; persistence adapters are separate crates
OQ-35 API key asymmetry dissolved PeerEntry supports multiple credential paths; ApiKeyEntry is for tokens that ARE the identity
OQ-36 Concrete persistence adapter shapes resolved by ADR-035 Read-sync / write-async split (IdentityStore); SQLite adapter caches in memory, honker NOTIFY for no-restart cache invalidation; alknet-store-sqlite crate
OQ-37 X.509 outgoing-only case resolved by ADR-034 Three remote roles (public X.509 endpoint, transport relay, hub); PeerEntry asymmetry correct; client-side verifier by PeerEntry presence (CA vs fingerprint pin)

Key Design Principles

  1. One trait, one dispatch point: ProtocolHandler is the only abstraction handlers implement. No StreamInterface/MessageInterface split.
  2. ALPN does the routing: The endpoint dispatches by ALPN string. No byte-peeking, no ListenerConfig enum.
  3. Handlers own their wire format: Each handler manages its own protocol parsing. alknet-core provides the Connection, not the framing.
  4. Auth is hybrid: The endpoint provides what it can (TLS-level auth). Handlers complete what they need. AuthContext may be partial.
  5. WASM door preserved: BiStream is a trait, Connection is an opaque type. Core types don't assume tokio or quinn in public APIs.