Mark REQ-057..060 Complete in REQUIREMENTS.md, mark v0.8 COMPLETE in
ROADMAP.md, advance config.json phase to 4.
P0 (v0.7.0): pre-execution — specify/clarify/research/plan/grill.
P1 (v0.7.1): coverage round 2 — 9 packages hit tiered floor.
P2 (v0.7.2): SSH trust hardening — --host-key-fingerprint + key-reset
+ v0.6 TOFU ship-defect bugfix + doctor parity.
P3 (v0.7.3): requirements-hygiene gate — make verify-reqs + CI hook.
P4 (v0.7.4): final review + audit + milestone release (this commit).
Review: PASS-WITH-FOLLOWUPS (0 P0, 3 P1+ deferred to v0.9).
Audit: PASS (1 P1 stale-branch-hygiene, pre-existing, post-ship cleanup).
GRILL: 4/4 binding conditions satisfied.
---ci---
project: orca
phase: 4
milestone: v0.8
status: complete
requirements:
covered: [REQ-057, REQ-058, REQ-059, REQ-060]
partial: []
---/ci---
17 KiB
Review: Orca v0.8 — Coverage & Trust Hardening (final-phase)
Reviewer: ci-code-reviewer (multi-persona: correctness, testing, security, performance, maintainability, adversarial)
Branch: phase/04-final-review-ship (review HEAD = P03 ship 70c5718)
Diff scope: main...milestone/v0.8-coverage-trust-hardening (all v0.8 work, 59 files, +6550/-173)
Date: 2026-08-04
Verdict: PASS-WITH-FOLLOWUPS (0 P0, 2 P1, 2 P2)
Methodology
Read the full diff (internal/, cmd/, Makefile, .coreci.yml), all 3 phase
verification reports, PLAN/RESEARCH/GRILL/PERSONAS, and the critical production
files directly (internal/proxmox/bootstrap.go, internal/security/ca.go,
internal/security/sshkey.go, internal/doctor/doctor.go:400-454,
cmd/verify-reqs/main.go). Re-ran go build ./..., go vet ./...,
go test -race on proxmox/security/doctor/cli/verify-reqs/cmd-orca, and
make verify-reqs (all PASS). Re-verified the verify-reqs regex against the
real ROADMAP.md (matches v0.1..v0.7 COMPLETE incl. v0.2 parenthetical; v0.8
correctly not matched). Confirmed all 7 T02.10 e2e cases are present and
exercised through a real in-process SSH server.
Per-Axis Findings
1. Correctness (lead-developer)
C1 — sessionRunner seam backward-compat ✅
internal/proxmox/bootstrap.go:170-172,322-339. The seam is a package-level
var sessionRunner sessionRunnerType (line 326) initialized lazily inside
BootstrapProxmox from the dialed *ssh.Client (if sessionRunner == nil { sessionRunner = &sshSessionRunner{client: conn} }). Existing callers are
unchanged — the default sshSessionRunner wraps the real
conn.NewSession().CombinedOutput(...). Tests reset sessionRunner = nil
between runs (bootstrap_test.go:910, 1010, 1035) to avoid cross-test leakage.
Backward compatible as required by P01 verification. No issue.
C2 — verify-reqs parser correctness ✅
cmd/verify-reqs/main.go:18-26. The reqRowRe uses a greedy .* for the
Requirement+Priority cells and anchors the Phase+Status match at the END of
the line, where those two columns always live. This correctly handles
escaped pipes inside the Requirement cell (e.g. REQ-049
localhost\|linux\|proxmox — verified by the passing make verify-reqs
which reports 60 consistent rows, matching the 60 REQ rows in
REQUIREMENTS.md). The status token is optionally bold-wrapped
(\*{0,2}(Complete|Pending)\*{0,2}) with [^|]* for trailing notes —
handles **Complete** (P01 shipped v0.2.1). The milestone-complete regex
^##\s*Milestone\s+(v0\.\d+):.*—\s*\*\*[^*]*\bCOMPLETE\b[^*]*\*\* is
substring-tolerant (GRILL #4) — verified against the real ROADMAP: matches
v0.1..v0.7 incl. v0.2's **COMPLETE (merged to main via v0.3)** and v0.6's
duplicate header (line 94 matched; line 92 without COMPLETE ignored). v0.8
(line 136, not yet COMPLETE) correctly not matched — so the v0.8 REQ rows
being Pending is NOT flagged as drift (correct: milestone not shipped
yet). No issue.
C3 — TOFU capture-fix logic ✅
internal/proxmox/bootstrap.go:275-310. On *knownhosts.KeyError with
empty Want (host unknown), captures the key, reads existing known_hosts
(create-if-missing), ensures trailing newline, appends
knownhosts.Line([]string{knownhosts.Normalize(addr)}, key), writes via
security.WriteAtomic, returns nil (dial proceeds). On non-empty Want
(mismatch) returns the error (MITM detection preserved). On nil (match)
records key + returns nil. Correct against x/crypto v0.54.0 checkAddr
semantics. No issue.
C4 — ResetHostKey line matching ✅
internal/proxmox/bootstrap.go:479-523. Matches a line when its first
whitespace-delimited field, normalized via knownhosts.Normalize, equals
the normalized target. Handles [host]:22 vs bare host (Normalize
brackets ports). Preserves comments/blanks. Atomic rewrite via
security.WriteAtomic. Edge cases handled: empty host errors, missing
file is a no-op, no matching lines is a no-op. Test
TestResetHostKey_RemovesTargetLines (bootstrap_test.go:718) seeds 2 lines
for target + 1 for another host, asserts target's 2 removed + other
intact. No issue.
C5 — --host-key-fingerprint non-proxmox validation ✅
internal/cli/node.go:79-81. RunE checks joinHostKeyFP != "" && joinType != "proxmox" → clear error. Test
TestNodeJoinHostKeyFingerprintRequiresProxmox (node_test.go:445) asserts
the error; TestNodeJoinHostKeyFingerprintProxmoxAccepted (node_test.go:477)
asserts the negative-space (proxmox type accepts the flag). No issue.
2. Testing (all personas)
T1 — Coverage held post-P02 ✅
PHASE2 verification: proxmox 86.5% (was 87.1%), cli 76.7% (was 76.2%),
doctor 70.4%. Marginal changes from new code paths — no coverage regression.
Re-ran go test -race ./internal/proxmox/... ./internal/cli/... PASS.
T2 — Race tests pass ✅
go test -race -count=1 ./internal/proxmox/... ./internal/security/... ./internal/doctor/... ./cmd/verify-reqs/... ./cmd/orca/... all PASS.
./internal/cli/... PASS (77s, dominated by watch tests). No races.
T3 — 7 T02.10 integration cases ✅
All 7 present in internal/proxmox/bootstrap_test.go, exercised
end-to-end through BootstrapProxmox with a real in-process SSH server
(bootstrapE2ESetup):
- Case 1:
TestBootstrapE2E_PinnedFingerprintCorrect(815) - Case 2:
TestBootstrapE2E_PinnedFingerprintWrong(842) - Case 3:
TestBootstrapE2E_TOFUFirstConnectCapturesKey(865) - Case 4:
TestBootstrapE2E_TOFUSecondConnectMatches(905) - Case 5:
TestBootstrapE2E_TOFUMismatchFails(925) - Case 6:
TestBootstrapE2E_KeyResetThenRePin(1002) - Case 7:
TestBootstrapE2E_PrePopulatedKnownHostsMatches(966, v0.6→v0.8 migration)
T4 — Golden tests for verify-reqs ✅
cmd/verify-reqs/main_test.go has 7 tests covering: clean pair, multi-drift
(both directions), default-args subprocess, malformed (no REQ rows → error),
missing file → error, v0.2 substring-tolerant header regression guard
(TestVerify_v02SubstringTolerantHeader), and real-repo regression guard.
The substring-tolerant regex is explicitly exercised — the drift fixture's
ROADMAP uses **COMPLETE (merged to main via v0.3)** on v0.2 and the test
asserts REQ-002 (v0.2 P1, Pending) is flagged forward-drift (would be
silently skipped if the regex regressed). No issue.
T5 — Doctor parity test ✅
internal/doctor/doctor_test.go extended with 94 LOC covering
probeProxmoxPVEVersion paths. The doctor callback now uses the shared
proxmox.TOFUHostKeyCallback (doctor.go:424) — GRILL #2 parity verified by
reading both call sites. No issue.
3. Security (backend-engineer)
S1 — --host-key-fingerprint fails closed ✅
internal/proxmox/bootstrap.go:141-153,245-258. The pinned/TOFU branch is
mutually exclusive (if opts.HostKeyFingerprint != "" { ... } else { ... }).
The pinned callback (245-258) validates SHA256: prefix up front (rejects
raw hex per D-045), computes ssh.FingerprintSHA256(key), returns an error
on any mismatch — no fallback to TOFU. The dial (164) aborts on callback
error before any SSH session command runs. Cannot be bypassed: the pin is
compared as a full string against the canonical fingerprint of the
server-presented key; a mismatch returns before *capturedKey is set. No
issue.
S2 — key-reset is local-only (D-046) ✅
internal/proxmox/bootstrap.go:479-523 + internal/cli/node.go:348-407.
ResetHostKey only reads/writes certpaths.KnownHostsPath(). No SSH dial,
no remote authorized_keys touch. Audit-logs node.key_reset with
actor+node+host (node.go:396-400). Verified by TestNodeKeyReset
(node_test.go:326) which asserts the audit row. No issue.
S3 — TOFU capture-fix doesn't weaken MITM detection ✅
See C3 — the fix ONLY captures on KeyError{Want:[]} (host unknown); a
non-empty Want (key mismatch / MITM) returns the error. The capture path
writes the server-presented key, so a subsequent different key fails. No
issue.
S4 — WriteAtomic is actually atomic ✅
internal/security/ca.go:308-337. Temp file in same dir
(os.CreateTemp(dir, ".tmp-*")), Write, Chmod, Sync, Close, then
os.Rename (atomic on POSIX same-filesystem). defer os.Remove(tmpName)
cleans up on failure. Genuine atomic-write pattern. No issue.
4. Performance (all)
P1 — ResetHostKey is O(n) in file size ✅
internal/proxmox/bootstrap.go:479-523: one os.ReadFile (O(n)), one
strings.Split + linear filter loop (O(n)), one security.WriteAtomic
(O(n)). No nested loops, no O(n²). For a known_hosts file (typically tens
of lines), this is negligible. No issue.
P2 — Unnecessary allocations (P2 — nit)
bootstrap.go:494-510: strings.Split(string(existing), "\n") allocates a
slice of all lines + append(kept, []byte(line+"\n")...) reallocates the
kept buffer. For known_hosts (small file) this is fine; a bufio.Scanner
over bytes.NewReader(existing) with a strings.Builder would be leaner,
but the current shape is clear and the file is tiny. Not worth changing.
Flagged P2 (nit, no action).
5. Maintainability (lead-developer)
M1 — TOFUHostKeyCallback extraction ✅
internal/proxmox/bootstrap.go:261-310 is exported and shared by bootstrap
(148) and doctor (doctor.go:424) via
proxmox.TOFUHostKeyCallback(sshAddr, &capturedHostKey). Clean coupling:
doctor imports proxmox (one-way), no duplication, no circular dep. The
GRILL #2 parity requirement (both call sites use the same wrapper) is
satisfied by construction. No issue.
M2 — verify() testable ✅
cmd/verify-reqs/main.go:98-148: the core logic is a pure function
verify(roadmapPath, reqsPath string) (diff []string, count int, err error)
with main() as a thin wrapper. Golden-file tests call verify() directly
(no subprocess). Mirrors the T01.11 main()→run() pattern. No issue.
M3 — cli tests follow conventions ✅
internal/cli/namespace_test.go:21-35 adds resetCommandFlags() to zero
the package-level flag-bound vars between subtests (cobra parses into
globals; without reset a prior test's value persists). Called from
resetRootFlags. This is a sound convention — the test isolation is
correct. No issue.
M4 — resetCommandFlags completeness (P2 — nit)
namespace_test.go:28-34 resets the join/leave/cap/audit/run/stop flags but
NOT joinHostKeyFP. A test that sets --host-key-fingerprint without
calling resetRootFlags could leak the value to a later test. In practice
all node tests call resetRootFlags which calls resetCommandFlags, so
this is a latent risk only. Recommend adding joinHostKeyFP = "" to
resetCommandFlags for completeness. Flagged P2 (nit).
6. Adversarial (backend-engineer)
A1 — Can --host-key-fingerprint be bypassed? ✅
No. The pinned callback (bootstrap.go:249-258) returns an error before
recording the key or allowing the dial to proceed on any mismatch. There is
no code path where a supplied pin is ignored — the branch at 141-153 is
if opts.HostKeyFingerprint != "" (pinned) else (TOFU); once pinned is
chosen, TOFU is not consulted. No bypass.
A2 — Can key-reset corrupt known_hosts under concurrent write? (P1 — important, low likelihood)
proxmox.ResetHostKey (bootstrap.go:479-523) and TOFUHostKeyCallback
(bootstrap.go:290-302) both do read-modify-write on
certpaths.KnownHostsPath() WITHOUT a lock. Two concurrent operations
(e.g. orca node join --type proxmox hostA + orca node key-reset hostB,
or two simultaneous joins to different hosts) could interleave:
- T1 reads known_hosts (empty), T2 reads known_hosts (empty)
- T1 writes hostA line, T2 writes hostB line
- Last rename wins → one line lost.
The security.WriteAtomic (temp+rename) prevents corruption (the file is
always valid OpenSSH format), but a captured line can be silently lost. This
is a last-writer-wins race on a flat file with no lock. Severity is low
because orca is a single-operator CLI (concurrent joins are unusual) and
the lost line is recoverable (re-connect re-pins via TOFU). But it is a
real correctness gap for the trust surface. Recommend either (a) a
file-lock around the read-modify-write, or (b) documenting the
single-operator assumption explicitly. Flagged P1 (important, post-hoc).
A3 — Can verify-reqs be fooled by a crafted markdown table? ✅
No. The reqRowRe anchors on ^\|\s*(REQ-\d+)\s*\| and the status column
at end-of-line. A crafted row with a fake status would have to match the
regex exactly. The "malformed" fixture (requirements_malformed.md)
exercises the no-REQ-rows path → clear error. A row like
| REQ-999 | missing status cell | High | v0.1 | (no final |...|) does
NOT match reqRowRe (the trailing \|\s*$ requires the status cell) — it
is silently skipped, which verify reports as "no REQ rows" only if ALL
rows are malformed. If some rows are valid + one malformed, the malformed
row is skipped without error — a minor blind spot, but acceptable (the
gate catches drift, not typos). No blocking issue.
GRILL Conditions Verification
#1 — T02.6 labeled as v0.6 ship-defect bugfix ✅
Commit 8b0cbe1 summary: "fix(proxmox): TOFU capture bug — v0.6
ship-defect first-connect join always failed (T02.6)". The commit message
explicitly labels it as a v0.6 ship-defect bugfix, not a v0.8 feature.
PHASE2 verification report records it as "TOFU bugfix (T02.6, v0.6
ship-defect)". Satisfied.
#2 — T02.9 doctor parity (bootstrap + doctor use capture-fix wrapper) ✅
- Bootstrap:
internal/proxmox/bootstrap.go:148callsTOFUHostKeyCallback(sshAddr, &capturedHostKey). - Doctor:
internal/doctor/doctor.go:424callsproxmox.TOFUHostKeyCallback(sshAddr, nil). Both use the SAME exported wrapper (proxmox.TOFUHostKeyCallback, bootstrap.go:275). No duplication. The doctor diff (internal/doctor/doctor.go) removes the directknownhosts.Newcall and replaces it with the shared wrapper. Satisfied.
#3 — T01.6 cli escape valve (was it needed?) ✅
PHASE1 verification: cli hit 76.2% (above the 70% floor, excluding daemon.go). The escape valve (ship at 65% if 70% not reached) was NOT needed. The plan's conditional was correctly conservative; the actual result exceeded the floor. Satisfied (not invoked).
#4 — T03.1 verify-reqs regex substring-tolerant + reverse direction ✅
- Substring-tolerant:
cmd/verify-reqs/main.go:30:^##\s*Milestone\s+(v0\.\d+):.*—\s*\*\*[^*]*\bCOMPLETE\b[^*]*\*\*. Verified against the real ROADMAP: matches v0.2's**COMPLETE (merged to main via v0.3)**and all other COMPLETE milestones. Golden testTestVerify_v02SubstringTolerantHeader(main_test.go:140) guards against regression. - Reverse direction:
cmd/verify-reqs/main.go:135-139: a REQ markedCompletewhose referenced milestones are ALL not-C_COMPLETE in ROADMAP is flagged asdirection=reversedrift. Golden testTestVerify_driftasserts REQ-003 is reverse-drift. - Scope note: PLAN + commit
fc2b020document that REQ-060 catches doc-vs-doc drift only (code-vs-doc like the REQ-053 cert_repo_test.go case is out of scope; P04 audit is the backstop). Satisfied.
P0 Fixes Applied
None. No P0 issues (correctness bugs, security holes, broken build/test)
were found. go build ./..., go vet ./..., go test -race (all key
packages), and make verify-reqs all PASS. The milestone is shippable as-is.
P1+ Issues Flagged (post-hoc review)
| ID | Severity | File:line | Issue | Recommendation |
|---|---|---|---|---|
| A2 | P1 (important, low likelihood) | internal/proxmox/bootstrap.go:290-302, 479-523 |
TOFUHostKeyCallback capture path and ResetHostKey both do read-modify-write on known_hosts with no lock; concurrent operations can lose a captured line (last-writer-wins via atomic rename — no corruption, but data loss). |
Add a file-lock (flock on a .known_hosts.lock sibling, or github.com/gofrs/flock if a dep is acceptable) around the RMW in both paths; OR document the single-operator assumption in the key-reset help text. Defer to v0.9. |
| M4 | P2 (nit) | internal/cli/namespace_test.go:28-34 |
resetCommandFlags() does not reset joinHostKeyFP; a test setting --host-key-fingerprint without resetRootFlags could leak the value. |
Add joinHostKeyFP = "" to resetCommandFlags. Trivial. |
| P2 | P2 (nit) | internal/proxmox/bootstrap.go:494-510 |
ResetHostKey uses strings.Split + repeated append (minor allocation churn). |
Optional: use bufio.Scanner + strings.Builder. Not worth changing for a small file. |
Overall Verdict
PASS-WITH-FOLLOWUPS
The v0.8 milestone is correct, secure, tested, and shippable. All 4 GRILL
binding conditions are satisfied. Zero P0 issues. The single P1 (concurrent
known_hosts write race, A2) is a real but low-likelihood gap appropriate
for post-hoc follow-up — it does not block the milestone ship because orca
is a single-operator CLI and the atomic-rename guarantees the file is never
corrupted (only a captured line can be lost, recoverable on re-connect).
The 2 P2 nits are cosmetic. Coverage held post-P02 (86.5%/76.7%/70.4% for
proxmox/cli/doctor), race tests pass, all 7 T02.10 e2e cases are present and
exercised through a real in-process SSH server, and make verify-reqs
passes on the current repo (60 consistent rows).
Recommend proceeding to P04 ship (T04.7/T04.8: mark REQ-057..060 Complete + ROADMAP v0.8 COMPLETE, then tag v0.7.4).