Files
alktls/docs/architecture/decisions/006-module-layout-and-tests.md
T
glm-5.3-flash d74a27f764 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
2026-09-10 05:37:55 +00:00

103 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: accepted
last_updated: 2026-09-10
---
# ADR-006: Module layout and test surface
## Status
Accepted (2026-09-10)
## Context
The extracted crate is organized as four modules plus the error
(`lib.rs`, `server.rs`, `client.rs`, `pem.rs`, `signing.rs`) with all
tests as in-module `#[cfg(test)]` blocks. alktls adds three modules of
moved types (ADR-005) and, per the repo's conventions, needs a
decided module map and test layout before the port starts.
Two shape questions need answers: where the moved types live
relative to the config constructors, and how the seed tests port
(no external workspace exists here, so in-module tests are the only
cross-module surface a full-crate crate has).
## Decision
**Module layout** (one module per file, re-exported from `lib.rs`):
```
src/
├── lib.rs — crate docs, TlsError (ADR-002), re-exports
├── identity.rs — TlsIdentity, Ed25519SecretKey, AcmeDirectory (ADR-005)
├── credentials.rs — ConnectionCredentials, RemoteIdentity (ADR-005)
├── fingerprint.rs — fingerprint_from_cert_der, extract_ed25519_raw_key_from_spki,
│ DER parser (ADR-005)
├── server.rs — TlsServerConfig, build_rustls_server_config,
│ RawKeyCertResolver, AcceptAnyCertVerifier,
│ SelfSignedCert / generate_self_signed_cert
├── client.rs — TlsClientConfig, select_server_verifier,
│ build_client_auth, RawKeyClientCertResolver,
│ NoClientCertResolver, FingerprintPinVerifier,
│ load_platform_root_cert_store
├── pem.rs — load_cert_chain, load_private_key
└── signing.rs — Ed25519SigningKey (rustls SigningKey + Signer)
```
Public API surface is `lib.rs` re-exports only (AGENTS.md convention
12); modules are `pub` for discoverability but the re-export block is
the documented surface.
**Feature gates stay on types and accessors, not modules.** The
`noq` feature gates `for_noq()` + `NoqWrap`; the `tcp` feature gates
`for_tcp_tls()`; the `acme` feature gates the ACME branch of
`TlsServerConfig::new` + the spawned task + the `futures` dep. Unlike
the alktunnels/alktty backends, there are no substrate modules to
gate — the transport-specific code is accessor-shaped.
**Test surface:**
- Port the extracted crate's in-module tests as the seed (they assert
the behavior-preservation invariants: `max_early_data_size` on the
server paths, `enable_early_data` on the client config, the
nine-scheme list, resolver behavior, PEM error paths, signing).
- Add `tests/` integration tests for the cross-module surfaces a
single crate has: `TlsServerConfig::new``for_noq()` /
`for_tcp_tls()` round-trips per identity variant;
`TlsClientConfig` verifier selection matrix (`Some`/`None` ×
raw-key/X.509); the root-store fallback against an empty platform
store; `acme-tls/1` append on the ACME path only.
- Pin the exact nine-scheme list in an integration test
(Phase 0 OQ-TLS-05's regression-proof shape — the extracted
in-module test only checks membership of two schemes), and pin
`enable_early_data = true` on the client config (the client half
of the 0-RTT invariant).
- `TlsIdentity::Acme`'s `unreachable!` in
`build_rustls_server_config` becomes a config error (the extracted
code relies on an internal dispatch invariant; the port replaces
the `unreachable!` with the `AcmeConfig` variant, keeping
no-panics-in-library-code).
## Consequences
**Positive:**
- The port is mechanically guided: module map + seed tests make the
Phase 2 port a diff against the extracted source.
- The invariant assertions move from "documented" to "tested" at both
unit and integration level.
**Negative:**
- Integration tests that wrap real QUIC endpoints are out of scope
(they belong to transport crates); the seam tests assert config
construction, not handshakes — the scope boundary holds.
## References
- AGENTS.md conventions 1, 9, 12 — comments, feature gates, module
structure
- `docs/research/phase-0.md` §Gaps #5, OQ-TLS-05 — the test-surface
question
- ADR-002 — `TlsError` (no `Config(String)` catch-all)
- ADR-005 — the moved modules