generation 5: review-impl — spec-conformance gate passed, API frozen

Checklist (all six PASS):
1. API surface == ADR-004 — every accessor signature verified verbatim
2. TlsError == ADR-002 — six variants, #[non_exhaustive], typed sources,
   AcmeConfig holds exactly the two config-mismatch cases
3. Invariants: all five server invariants + client 0-RTT half +
   fail-closed structure, each with a passing behavioral test at unit
   and integration level
4. Deltas vs extraction: all ADR-pinned; two surfaced divergences
   recorded as ADR amendments — zero un-pinned divergences remain
5. Feature hygiene: default = [] lean, tokio subset (no full),
   doc comments on public API, no inline // comments, no panics
6. Docs sync: ADR-002 + ADR-003 amendment notes; overview/server/client
   Draft → Reviewed; README carries the API-freeze lifecycle note

5 findings, all low severity, all resolved forward (table in task Notes)

Verification: cargo test (81), cargo test --all-features (92),
clippy -D warnings, fmt --check, doc --no-deps,
publish --dry-run — all green. API FROZEN for the alknet rewrite.
This commit is contained in:
2026-09-10 15:05:01 +00:00
parent 87b69e19e6
commit 8a15978c41
7 changed files with 172 additions and 23 deletions
+20 -9
View File
@@ -1,13 +1,14 @@
---
status: draft
status: reviewed
last_updated: 2026-09-10
---
# alktls — Architecture
The authoritative architecture spec for the alktls crate (Phase 1 of
the SDD process). All docs are **Draft** pending the architecture
review pass; statuses update here as docs advance.
the SDD process). The spec docs advanced **Draft → Reviewed** at the
Phase 2 implementation review gate (see the lifecycle note at the end);
statuses update here as docs advance.
All docs follow the SDD process conventions: specs reference ADRs and
OQs by number, ADRs explain WHY, `open-questions.md` tracks what is
@@ -17,9 +18,9 @@ unresolved.
| Doc | Status | Scope |
|-----|--------|-------|
| [overview.md](overview.md) | Draft | Purpose, transport picture, API surface, ADR/OQ index |
| [server.md](server.md) | Draft | `TlsServerConfig`, resolvers, ACME path, server invariants |
| [client.md](client.md) | Draft | `TlsClientConfig`, verifier selection, client auth, root-store fallback |
| [overview.md](overview.md) | Reviewed | Purpose, transport picture, API surface, ADR/OQ index |
| [server.md](server.md) | Reviewed | `TlsServerConfig`, resolvers, ACME path, server invariants |
| [client.md](client.md) | Reviewed | `TlsClientConfig`, verifier selection, client auth, root-store fallback |
| [open-questions.md](open-questions.md) | live | The authoritative OQ tracker (all Phase 0 OQs resolved at entry) |
## ADRs
@@ -41,6 +42,13 @@ Accepted at write time and never revert (supersede instead).
`open-questions.md` is the authoritative tracker; the Phase 0 doc's
OQ statuses are the historical record.
**API-freeze note (2026-09-10):** the Phase 2 implementation review
gate (`tasks/review-impl.md`) passed with zero un-pinned divergences
(two ADR amendments recorded — 002's verifier-error path, 003's noq
provider feature). **The public API surface — the `lib.rs` re-export
block per ADR-004/005/006 — is frozen as of that review**; the alknet
rewrite compiles against it. Additive evolution only.
## Phase status
- **Phase 0** (complete, 2026-09-10): `docs/research/phase-0.md`
@@ -48,6 +56,9 @@ OQ statuses are the historical record.
OQ-TLS-01..08.
- **Phase 1** (this directory): all Phase 0 OQs resolved at entry —
six via ADR-001..006, two as documented behavior (OQ-TLS-02,
OQ-TLS-06); review pass pending.
- **Phase 2** (next): decomposition into `tasks/` — the port guided by
ADR-006's module map and seed tests.
OQ-TLS-06). **Reviewed 2026-09-10** at the Phase 2 gate.
- **Phase 2** (complete, 2026-09-10): decomposition into `tasks/` +
execution — the eight-task port graph landed crate-init →
port-identity/fingerprint/pem-signing → port-server/port-client →
integration-suite → this review gate. The crate is ready for the
rewrite to consume.
+1 -1
View File
@@ -1,5 +1,5 @@
---
status: draft
status: reviewed
last_updated: 2026-09-10
---
@@ -64,9 +64,11 @@ pub enum TlsError {
Rustls(#[from] rustls::Error),
/// `WebPkiServerVerifier::builder(_with_provider)..build()` — the
/// unknown-X.509-remote client path.
/// unknown-X.509-remote client path. Re-exported by rustls at
/// `rustls::client` (the `rustls::webpki` module is private at the
/// pinned 0.23.44; same type, public path).
#[error("building webpki verifier: {0}")]
VerifierBuild(#[from] rustls::webpki::VerifierBuilderError),
VerifierBuild(#[from] rustls::client::VerifierBuilderError),
/// QUIC config wrapping — the one path where `for_noq()` fails
/// (`NoInitialCipherSuite`, not a `rustls::Error`). noq-gated.
@@ -139,6 +141,14 @@ reintroduce the fold this ADR removes.
error churn (accepted — rcgen 0.13 is stable and the coupling is
what ADR-088 chose).
**Amendment (2026-09-10, from the Phase 2 implementation):** the
`VerifierBuild` source's reachable path at the pinned rustls 0.23.44
is `rustls::client::VerifierBuilderError`, not
`rustls::webpki::VerifierBuilderError` — the `rustls::webpki` module
is private at that version and the type is publicly re-exported at
`rustls::client` (same type; the implementation carries it that way,
with the path noted in the variant's doc comment).
## References
- alknet ADR-088 — the recorded target shape and its rationale
@@ -109,6 +109,22 @@ consumes that provider from the config.
both noq and iroh, and the rewrite rides their stack; pin `noq =
"1.2"` and bump deliberately).
**Amendment (2026-09-10, from the Phase 2 implementation):** the
pinned TOML block's `features = ["rustls"]` was written against the
noq 1.2 API; the lockfile resolves `noq-proto 1.3.0`, where
`ServerConfig::with_crypto(crypto)` — the single-arg constructor the
`for_noq` accessor calls — is `#[cfg(any(feature = "aws-lc-rs",
feature = "ring"))]` (the retry-token key lives in noq's
`ring_like` module, which needs one of the two provider features).
The `noq` dependency therefore ships with
`default-features = false, features = ["rustls", "aws-lc-rs"]`.
This does not reopen the provider decision: the config's internal
provider is still the crate's explicit
`rustls::crypto::aws_lc_rs::default_provider()` on every path (ADR-084
via ADR-003's provider paragraph — noq consumes the provider from the
config), and `aws-lc-rs` (not `ring`) is the feature matching that
posture.
## References
- `docs/research/phase-0.md` §Prior art: noq — the verified seam facts
+1 -1
View File
@@ -1,5 +1,5 @@
---
status: draft
status: reviewed
last_updated: 2026-09-10
---
+1 -1
View File
@@ -1,5 +1,5 @@
---
status: draft
status: reviewed
last_updated: 2026-09-10
---