- HostKeyPolicy trait: async, dyn-compatible (Arc<dyn> handle, the
alkcall injected-handle pattern) — decide(&self, &PresentedHostKey)
-> bool with host/port/fingerprint as the decision input
- Verdict type pinned to the russh 0.65 check_server_key shape:
bool is the trust decision; decline reasons stay with the policy
(declines are dispositions, not errors). Flagged for the wave-1 gate
- Built-in default RejectAll: fail-closed reject-all (russh's default,
kept); no accept-all option exists in the crate
- async-trait 0.1 added for the dyn-compatible async handle
(alkcall-precedented; tree-deduped). Flagged for the wave-1 gate
- Tests: default rejects; custom verdict honored; both through the dyn
handle; the whole presented context reaches the policy
Verified: cargo test (14), cargo test --all-features, cargo clippy
--all-targets -- -D warnings, cargo fmt --check, taskgraph validate
- KeySourceError with exactly five variants (Locked, Absent,
Decryption, UnknownKeyVersion, Decode) — ADR-005 decision 4's
failure matrix as distinct shapes, the vault taxonomy reshaped
never collapsed; no catch-all, no Other/Unknown
- payload shapes pinned: Locked/Absent payload-free;
Decryption/UnknownKeyVersion carry the vault's opaque messages;
Decode carries a message so the RC-pinned ssh-key error type
never enters the public API (flagged for the wave-1 gate)
- each variant doc-commented with ADR-005 semantics + fail-closed
consequence; module stays engine-blind (no vault/russh types)
- no From<VaultServiceError>: non-mappable vault variants would
force a collapse; w1-key-sources maps explicitly at its seam
- exhaustive-match + Display/Debug/Clone unit tests
Verified: cargo test (default + all-features), cargo clippy
--all-targets --all-features -- -D warnings, cargo fmt --check,
cargo doc --no-deps, taskgraph validate