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.
56 lines
3.4 KiB
Markdown
56 lines
3.4 KiB
Markdown
# OQ-55: AlknetClient / Client Establishment Extraction
|
|
|
|
- **Origin**: `docs/research/alknet-channels/phase-0-findings.md` OQ-CH-14
|
|
(the `AlknetClient` clarification); `docs/research/alknet-channels/poc-summary.md`
|
|
§"Issues Surfaced" #1 (the `BidiStreamSource` finding that motivates
|
|
separating the client-extraction question from the `Connection` extension
|
|
question).
|
|
- **Status**: resolved (ADR-089)
|
|
- **Door type**: one-way (crate existence + dial seam — ADR-089)
|
|
- **Priority**: medium
|
|
- **Resolution**: `AlknetClient` is extracted as a new crate
|
|
`alknet-client` — the client-side analogue of `AlknetEndpoint`
|
|
(ADR-083). Three dial methods: `dial_quic` / `dial_tcp_tls` (both
|
|
build a `TlsClientConfig` via ADR-087 and call their transport's
|
|
connector) + `dial_iroh` (the key-not-config exception, shares the
|
|
`Ed25519SecretKey`). The dial produces a `Connection` for 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
|
|
sharing `TlsClientConfig`. ADR-087 broke the circular hedge
|
|
(`TlsClientConfig` is 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 — `AlknetClient` is 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`) and `ChannelClient`'s transport-agnostic
|
|
take-over (`from_connection`, ADR-080) are decided; the
|
|
`connect` / `connect_quic` convenience constructors are **removed**
|
|
per ADR-089 §5 (not delegated — the dial is centralized in
|
|
`AlknetClient`, and the protocol crates shed their TLS/transport deps).
|
|
- **Cross-references**: ADR-089 (the resolution — `AlknetClient` native
|
|
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 in `TlsClientConfig::new`), ADR-065
|
|
(server-side transport generalization — the client-side analogue
|
|
this OQ's deferral avoided preempting, now completed), ADR-070 (the
|
|
`BidiStreamSource` extension point — orthogonal to the client
|
|
establishment question), OQ-CH-14 in
|
|
`docs/research/alknet-channels/phase-0-findings.md` (the research-scope
|
|
question this core-scope OQ carried forward). |