phase 1: architecture spec — overview, server/client, ADR-001..006
- ADR-001: inherit the alknet TLS design as the baseline; deviations recorded as alktls ADRs - ADR-002: TlsError ships the ADR-088 six-variant shape from day one (typed #[from] sources; NoqWrap; no string catch-all) - ADR-003: the QUIC feature is noq (iroh's extracted fork), pre- consumer rename; default = [] per the lean-crate convention (corrects the extracted code's default = ["quinn"]) - ADR-004: complete accessors — for_tcp_tls() adopted, rustls_config() adopted; server accessors borrow (&self), client accessors consume - ADR-005: identity + credentials + fingerprint types move into alktls; auth layer stays out - ADR-006: eight-module layout; seed tests + integration invariant pins (exact nine-scheme list, client enable_early_data) - specs: overview (transport picture, terminology), server.md (ACME lifecycle, invariants), client.md (verifier selection matrix, root- store fallback); open-questions.md promotes OQ-TLS-01..08 (all resolved at entry) - Cargo.toml: quinn feature -> noq (per ADR-003); AGENTS.md aligned Architecture review pass done: 0 critical, 2 major (ADR-002 AcmeConfig doc comment contradiction; ADR-003 unrecorded default deviation) and 8 minors all addressed; cross-references verified against alknet ADRs, rustls/noq/iroh sources. Verified: cargo test, test --all-features, clippy -D warnings, fmt --check, doc --no-deps
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
---
|
||||
status: accepted
|
||||
last_updated: 2026-09-10
|
||||
---
|
||||
|
||||
# ADR-003: The QUIC feature is `noq`, not `quinn`
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (2026-09-10)
|
||||
|
||||
## Context
|
||||
|
||||
The extracted crate's `quinn` feature (`for_quinn()` accessors,
|
||||
quinn-gated wrap) predates the noq split: iroh has extracted its
|
||||
internal quinn fork into the standalone, published `noq` project
|
||||
(`noq` / `noq-proto` / `noq-udp`; noq 1.2.0 on crates.io), and iroh
|
||||
1.1.0 is built on noq 1.2.0, re-exporting `noq::*` as public API.
|
||||
The alknet rewrite will standardize on noq for QUIC — both the bare
|
||||
QUIC transport and iroh's internal one — eliminating the duplicate
|
||||
QUIC implementations.
|
||||
|
||||
Phase 0 verified the seam is API-compatible with quinn 0.11
|
||||
(`docs/research/phase-0.md` §Prior art: noq):
|
||||
|
||||
- `noq_proto::crypto::rustls::QuicServerConfig::try_from(
|
||||
rustls::ServerConfig)` / `QuicClientConfig::try_from(
|
||||
rustls::ClientConfig)` — same constructor shape, same
|
||||
`NoInitialCipherSuite` failure type, different crate path.
|
||||
- noq 1.2 pins `rustls ^0.23.33`; iroh 1.1 pins `rustls 0.23.33` —
|
||||
the same 0.23 line this crate pins. One rustls tree across all
|
||||
paths.
|
||||
- noq's `rustls-aws-lc-rs` feature selects the aws-lc-rs provider;
|
||||
iroh's `tls-aws-lc-rs` does the same on the iroh side. The ADR-084
|
||||
posture composes unchanged.
|
||||
- noq's MSRV is 1.88 — the ecosystem floor (adopted 2026-09-10),
|
||||
so no MSRV tension remains.
|
||||
|
||||
The `quinn` feature has no published consumer: alktls is
|
||||
pre-consumer, and the alknet rewrite (its only planned consumer)
|
||||
targets noq. Carrying both features would double the accessor surface
|
||||
with nothing to transition.
|
||||
|
||||
## Decision
|
||||
|
||||
**The QUIC feature is `noq`.** The `quinn` feature never existed in a
|
||||
published alktls, so the rename is pre-consumer and free:
|
||||
|
||||
```toml
|
||||
[features]
|
||||
default = []
|
||||
noq = ["dep:noq", "dep:noq-proto"]
|
||||
tcp = ["dep:tokio-rustls"]
|
||||
acme = ["dep:rustls-acme"]
|
||||
|
||||
[dependencies]
|
||||
noq = { version = "1.2", optional = true, default-features = false, features = ["rustls"] }
|
||||
noq-proto = { version = "1.2", optional = true, default-features = false }
|
||||
```
|
||||
|
||||
`default = []` — all transport features opt-in, matching the
|
||||
inherited alknet spec's feature-gate shape and AGENTS.md convention 9
|
||||
(the default crate compiles lean; a consumer that never runs QUIC
|
||||
should not pull `noq` + `noq-proto`). Note the extracted code's
|
||||
`Cargo.toml` carries `default = ["quinn"]` — a silent deviation from
|
||||
the alknet spec that this port corrects rather than carries forward.
|
||||
The `noq` dep is enabled with `default-features = false,
|
||||
features = ["rustls"]` so noq's provider-selection features do not
|
||||
fight the crate's explicit provider posture; `noq-proto` rides along
|
||||
for the `NoqWrap` error source.
|
||||
|
||||
- `TlsServerConfig::for_noq(&self) -> Result<noq::ServerConfig,
|
||||
TlsError>` (feature-gated on `noq`) —
|
||||
`noq::ServerConfig::with_crypto(Arc::new(
|
||||
noq::crypto::rustls::QuicServerConfig::try_from(inner)?))`.
|
||||
- `TlsClientConfig::for_noq(self) -> Result<noq::ClientConfig,
|
||||
TlsError>` (feature-gated on `noq`) — the client-side mirror.
|
||||
- `TlsError::NoqWrap(#[from]
|
||||
noq_proto::crypto::rustls::NoInitialCipherSuite)` (ADR-002).
|
||||
- There is no `for_quinn()`, no `quinn` dependency, no quinn feature.
|
||||
- iroh remains key-not-config (ADR-001): iroh's endpoint is fed the
|
||||
Ed25519 secret key; the `noq` feature does not attempt to serve
|
||||
iroh's TLS, and iroh does not appear in this crate's dependency
|
||||
tree.
|
||||
- The `tcp` feature (`tokio-rustls`) and `acme` feature are
|
||||
unaffected.
|
||||
|
||||
Provider wiring on the QUIC path: the rustls configs this crate builds
|
||||
already carry the aws-lc-rs provider (every path constructs its own
|
||||
provider via `builder_with_provider`); noq's `rustls` feature
|
||||
consumes that provider from the config.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- One QUIC implementation across the bare-QUIC and iroh transports;
|
||||
no duplicate quinn/noq stacks in the rewrite's binaries.
|
||||
- `TlsError` never has a dead `QuinnWrap` variant.
|
||||
- The crate's MSRV floor (1.88) is honest for the whole tree rather
|
||||
than feature-dependent.
|
||||
|
||||
**Negative:**
|
||||
|
||||
- If a future consumer needs quinn (none is known), that is a new
|
||||
feature alongside `noq` — additive, cheap, and only paid if real.
|
||||
- noq is young (1.2.0, first release Feb 2026); its API may churn
|
||||
faster than quinn 0.11's frozen line (accepted — n0-computer owns
|
||||
both noq and iroh, and the rewrite rides their stack; pin `noq =
|
||||
"1.2"` and bump deliberately).
|
||||
|
||||
## References
|
||||
|
||||
- `docs/research/phase-0.md` §Prior art: noq — the verified seam facts
|
||||
- `/workspace/noq`, `/workspace/iroh` — the upstream clones inspected
|
||||
- ADR-001 — the inheritance baseline (quinn-era accessors inherited
|
||||
with deviations recorded here)
|
||||
- ADR-002 — `TlsError` (`NoqWrap`)
|
||||
- ADR-004 — accessor shapes (`&self` vs `self`)
|
||||
Reference in New Issue
Block a user