Files
orca/.ciagent/PHASE2_VERIFICATION_v0.8.md
T
Jon Chery f4192be5d1 verify(P02): 4-layer verification PASS — REQ-058, REQ-059 + TOFU bugfix
---ci---
project: orca
phase: 2
milestone: v0.8
status: verify
requirements:
  covered: [REQ-058, REQ-059]
  partial: []
---/ci---
2026-08-04 12:07:56 +00:00

4.2 KiB

Phase 2 Verification — v0.8 Coverage & Trust Hardening

Phase: P02 — SSH trust hardening Milestone: v0.8 REQs: REQ-058, REQ-059 (+ latent TOFU bugfix closure) Date: 2026-08-04 Result: PASS (all 4 layers)

Layer 1 — Structural

  • go build ./... PASS
  • go vet ./... PASS
  • No TODOs/stubs in new production code
  • All new exports resolve: security.SSHFingerprintSHA256, security.WriteAtomic, proxmox.TOFUHostKeyCallback, proxmox.ResetHostKey, proxmox.pinnedHostKeyCallback, proxmox.Options.HostKeyFingerprint, cli.nodeKeyResetCmd
  • Backward compatible: existing BootstrapProxmox callers work (the TOFU fix changed failure→success on first connect, which is the bugfix)

Layer 2 — Behavioral

  • go test ./internal/proxmox/... ./internal/cli/... ./internal/doctor/... ./internal/security/... PASS
  • go test -race ./internal/proxmox/... ./internal/doctor/... PASS
  • Coverage held post-P02: proxmox 86.5% (was 87.1% in P01 — marginal change from new code paths), cli 76.7% (was 76.2%), doctor 70.4% (unchanged)
  • T02.10: all 7 end-to-end integration cases PASS (pinned correct/wrong, TOFU first/second/mismatch, key-reset+re-pin, pre-populated migration path)
  • T02.11: --host-key-fingerprint non-proxmox validation PASS

Layer 3 — Security

  • REQ-058: --host-key-fingerprint fails closed on mismatch (pinnedHostKeyCallback returns error on any mismatch; bootstrap aborts before any SSH session command runs). SHA256: prefix validated up front. No downgrade to TOFU when pin supplied.
  • REQ-059: orca node key-reset is local-only (D-046) — only rewrites ~/.orca/known_hosts via security.WriteAtomic (atomic temp+rename, AD-029); does NOT touch remote authorized_keys. Audit-logs node.key_reset with actor+node+host.
  • TOFU bugfix (T02.6, v0.6 ship-defect): first-connect now captures + writes the key (was silently failing). Mismatch detection preserved (MITM protection). The TOFUHostKeyCallback is shared between bootstrap (T02.6) and doctor (T02.9) — GRILL condition #2 parity satisfied.
  • STRIDE: no new spoofing surface (pin is operator-supplied, fail-closed); no tampering (atomic rewrite); no repudiation (audit log); no info disclosure (fingerprint is a hash, not the key); no DoS (no network change); no elevation (local file ops only).
  • No secrets in test code (fake SSH keys generated in-test).

Layer 4 — Quality

  • Tests follow existing conventions (table-driven, fakeSSHServer fixture reused, sshDialer/sessionRunner seams injected)
  • TOFUHostKeyCallback extracted to a shared helper (no duplication between bootstrap + doctor) — clean coupling (proxmox doesn't import doctor)
  • P0 issues: none. P1+ issues: none flagged.

Requirement Coverage

REQ Status Evidence
REQ-058 Complete --host-key-fingerprint flag (T02.3) + pinnedHostKeyCallback (T02.5) + Result.HostKeyFingerprint (T02.7) + e2e tests (T02.10) + validation (T02.11)
REQ-059 Complete orca node key-reset <node> (T02.8) + proxmox.ResetHostKey atomic rewrite + audit log + e2e test (T02.10 case 6)
(TOFU bugfix) Complete T02.6 fixes v0.6 ship-defect (first-connect knownhosts.New KeyError{Want:[]} treated as dial failure); T02.9 doctor parity

GRILL Conditions Check

  • #1 (T02.6 labeled v0.6 ship-defect): commit 8b0cbe1 summary "TOFU capture bug — v0.6 ship-defect first-connect join always failed"
  • #2 (T02.9 doctor parity): both bootstrap (8b0cbe1) and doctor (2dcb143) use the shared proxmox.TOFUHostKeyCallback wrapper

Lessons

  • The v0.6 TOFU bug was a latent ship-defect: knownhosts.New returns KeyError{Want:[]} on first connect without writing, and the original code treated this as a dial failure. This means first-connect Proxmox join has been broken since v0.6 shipped — a strong argument for P01's coverage uplift (the 5.1% proxmox coverage hid this). v0.8 P03's verify-reqs would not have caught this (it's code-vs-doc drift, not doc-vs-doc) — P04 audit is the backstop.
  • Extracting TOFUHostKeyCallback to a shared helper was the right call for GRILL condition #2 — duplicating the wrapper in doctor would have created drift risk.