Review of the three new crates (alknet-tls, alknet-endpoint, alknet-client) + revised core found compile-blocking inconsistencies, stale claims, and dep-graph contradictions. All resolved: Critical: - C1: CallClient::connect / ChannelClient::connect_quic REMOVED (not delegated) — keeping them as thin wrappers over AlknetClient::dial_quic would make protocol crates depend on alknet-client, contradicting the dep graph. Callers compose dial + take-over (2 lines). - C2: alknet-client feature gates now pull alknet-core/quinn + alknet-core/iroh (for Connection::from_quinn_with_alpn / from_iroh). - C3: rustls-native-certs + webpki-roots added to alknet-tls deps (always-present, not feature-gated — CA-verify path is transport-agnostic). Warning: - W1: CallCredentials/RemoteIdentity moved to alknet-core (from alknet-call) — the dial must not depend on the call protocol; not a two-way-door, it determines the dep graph. - W2: webpki-roots fallback implemented in spec (ADR-088 §5 added) — the code claimed a fallback that never existed; now the store is never empty, NoRootAnchors unreachable, containerized deployments work. - W3: EndpointError removed entirely (BindFailed + HandlerNotFound both vestigial after ADR-083); shutdown() is now infallible. - W4: FingerprintPinVerifier moved to alknet-tls (from alknet-call) — alknet-call sheds quinn/rustls/rustls-pemfile/rustls-native-certs entirely; CallClient becomes a pure protocol crate. Plus: ClientError removed (only produced by removed connect); S1 (CallCredentials → ClientVerifierContext mapping + auth_token stripped at TLS boundary documented); amendment notes on ADR-017, ADR-069, ADR-080, ADR-082, ADR-087, ADR-090; overview crate graph + README index updated. 29 files, consistency-reviewed.
3.4 KiB
3.4 KiB
OQ-55: AlknetClient / Client Establishment Extraction
- Origin:
docs/research/alknet-channels/phase-0-findings.mdOQ-CH-14 (theAlknetClientclarification);docs/research/alknet-channels/poc-summary.md§"Issues Surfaced" #1 (theBidiStreamSourcefinding that motivates separating the client-extraction question from theConnectionextension question). - Status: resolved (ADR-089)
- Door type: one-way (crate existence + dial seam — ADR-089)
- Priority: medium
- Resolution:
AlknetClientis extracted as a new cratealknet-client— the client-side analogue ofAlknetEndpoint(ADR-083). Three dial methods:dial_quic/dial_tcp_tls(both build aTlsClientConfigvia ADR-087 and call their transport's connector) +dial_iroh(the key-not-config exception, shares theEd25519SecretKey). The dial produces aConnectionfor the protocol take-overs (CallClient::spawn_dispatch,ChannelClient::from_connection) to consume — it does not run protocols. - Why the deferral collapsed: the blocking condition ("a second
transport's real dial existing") is met within the native endpoint
type (ADR-086): QUIC + TCP+TLS (both rustls-consuming via
TlsClientConfig) + iroh (key-based) — three dial shapes, two sharingTlsClientConfig. ADR-087 broke the circular hedge (TlsClientConfigis a prerequisite, not a consequence of the dial). ADR-083 made the server-side shape a clean accept-loop runner, giving the client-side shape by symmetry. The dial seam is extractable from two different transport implementations, not guessable from one. - Scope of the resolution: the native transport-polymorphic
dial. The web/browser client (WebSocket, HTTP — the browser
bidirectional path per ADR-044/048) was never what this OQ was
about — it is a different client surface (the JS SDK / wasm), not a
Rust dial, and does not use
AlknetClient. Non-Rust native clients (Node/Deno/Bun, Python, wasm) that negotiate TLS against an X.509 endpoint and implement the wire protocols directly are also out of scope —AlknetClientis the Rust native client, one of several possible native clients sharing the same wire protocols. - What does NOT block on this (unchanged): each crate building its
own client standalone with a shared
TlsClientConfig(ADR-087), and each transport-specific dial helper.CallClient's transport-agnostic take-over (spawn_dispatch) andChannelClient's transport-agnostic take-over (from_connection, ADR-080) are decided; theconnect/connect_quicconvenience constructors are removed per ADR-089 §5 (not delegated — the dial is centralized inAlknetClient, and the protocol crates shed their TLS/transport deps). - Cross-references: ADR-089 (the resolution —
AlknetClientnative dial seam), ADR-083 (the server-side shape mirrored), ADR-086 (endpoint types — native has QUIC + TCP+TLS + iroh), ADR-087 (TlsClientConfig— the prerequisite the dial consumes), ADR-034 (verifier selection — centralized inTlsClientConfig::new), ADR-065 (server-side transport generalization — the client-side analogue this OQ's deferral avoided preempting, now completed), ADR-070 (theBidiStreamSourceextension point — orthogonal to the client establishment question), OQ-CH-14 indocs/research/alknet-channels/phase-0-findings.md(the research-scope question this core-scope OQ carried forward).