Spec docs should describe WHAT IS, not WHAT WAS. ADRs and OQ files are historical records by design and are left alone; the ADR-index Status column records ADR status (stable fact). What changed in the specs: - API code blocks no longer list removed methods. ChannelClient::connect_quic (channel-client.md) and CallClient::connect (client-and-adapters.md) are gone from the impl blocks; surrounding prose describes the current from_connection / spawn_dispatch primary + AlknetClient dial shape. - Amendment (ADR-093): stream_types field is removed blockquotes dropped from channel-client.md and channel-operations.md (the code already reflects the current state). - Historical is-removed / reversed-by / amended-by prose rewritten to current state across channels crate, call crate, hub, tls, core, endpoint, client READMEs, and the top-level README/overview. - Dropped the EndpointError — removed subsection from endpoint/README.md (the type doesn't exist anymore, so it shouldn't have a subsection). - Replaced stale connect() references in flow descriptions with the dial (in AlknetClient) since connect() is no longer a method. - Removed strikethrough ADR-028 / from_jsonschema-clause rows from client-and-adapters.md and operation-registry.md ADR tables. - Rewrote the ADR-066 update blockquote in operation-registry.md to describe FromJsonSchema's current shape. 19 files modified, net -116 lines. No ADRs or OQ files touched.
6.9 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-07-17 |
alknet-core
Shared types, auth, config, and identity for ALPN-based protocol
dispatch. Every handler crate depends on alknet-core for
ProtocolHandler, Connection, AuthContext, IdentityProvider, and
config types. The endpoint (AlknetEndpoint, HandlerRegistry) lives
in alknet-endpoint (ADR-083 Amendment
2026-07-15); core does not carry the accept-loop runner or its
transport deps (quinn, iroh, rcgen, rustls-acme).
Connection::from_quinn / from_iroh are in core's types.rs as
shared constructors (gated on core's quinn / iroh features).
ConnectionCredentials and RemoteIdentity live in alknet-core (per
ADR-091) — the transport-level credential bundle consumed by the dial
(alknet-client) and by server-side transport construction. There is no
call-protocol credential bundle; auth_token is a per-request payload
field on call.requested, not a transport credential.
Documents
| Document | Status | Description |
|---|---|---|
| core-types.md | draft | ProtocolHandler trait, HandlerError, Connection (Box<dyn BidiStreamSource> — ADR-070), BidiStreamSource trait, BiStream, StreamError |
| endpoint.md | deprecated | Endpoint spec — moved to alknet-endpoint (ADR-083 Am. 2026-07-15); this file is a stub |
| auth.md | draft | AuthContext (incl. anonymous constructor), 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 | HandlerRegistry, accept loop — endpoint extracted to alknet-endpoint per ADR-083 Am. 2026-07-15 |
| 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 |
| 065 | Connection::from_stream — Generic Single-Stream Connections |
from_stream/from_bidi accept any AsyncRead + AsyncWrite; yield-once accept_bi contract; unblocks TCP+TLS, SSH channels, WebTransport, wasm |
| 070 | BidiStreamSource Trait — Open Connection for Extension | Connection holds Box<dyn BidiStreamSource>; QUIC/iroh/stream wrap crate-private impls; from_source is the public constructor for downstream crates that implement the trait (channels, future transports) |
| 083 | Endpoint as accept-loop runner + crate extraction | The endpoint is extracted from core into alknet-endpoint; core loses quinn/iroh/rcgen/rustls-acme deps; Connection::from_quinn/from_iroh stay in core as shared constructors |
Relevant Open Questions
| OQ | Title | Status | Relevance |
|---|---|---|---|
| OQ-04 | Dynamic handler registration | resolved (start static) | HandlerRegistry is immutable at startup (now in alknet-endpoint) |
| OQ-05 | Multi-connectivity endpoint | resolved (quinn + iroh) | AlknetEndpoint supports both, both feature-gated (now in alknet-endpoint) |
| 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 | 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) |
| OQ-55 | AlknetClient / Client Establishment Extraction | resolved by ADR-089 | The native dial seam is extracted as alknet-client — the client-side analogue of AlknetEndpoint (now in alknet-endpoint). Three dial methods (QUIC + TCP+TLS via TlsClientConfig, iroh via key). |
Key Design Principles
- One trait, one dispatch point:
ProtocolHandleris the only abstraction handlers implement. No StreamInterface/MessageInterface split. - ALPN does the routing: The endpoint (in
alknet-endpoint) dispatches by ALPN string. No byte-peeking, no ListenerConfig enum. - Handlers own their wire format: Each handler manages its own protocol parsing. alknet-core provides the Connection, not the framing.
- Auth is hybrid: The endpoint provides what it can (TLS-level auth). Handlers complete what they need. AuthContext may be partial.
- WASM door preserved: BiStream is a trait, Connection is an opaque type. Core types don't assume tokio or quinn in public APIs.