Files
Oleksandr Bezdieniezhnykh 06f655d8fb [AZ-335] C1 warm-start hint persistence + F8 reboot recovery wiring
Adds JsonSidecarWarmStartHintStore (atomic JSON + SHA-256 sidecar via
AZ-280) inside c1_vio, plus the cross-strategy WarmStartWiredStrategy
wrapper + prime_warm_start_from_disk / prime_warm_start_from_fc hooks
at runtime_root. AC-7 post-reset covariance inflation and AC-8 "no
fake confidence" baseline floor are enforced at the wiring layer so
no strategy module needed edits. Adds three c1_vio config fields
(warm_start_store_dir, warm_start_save_period_frames,
post_reset_covariance_inflation_factor) and registers the new FDR
kind vio.warm_start. 34 unit tests cover all 10 ACs + 3 NFRs.

Verdict PASS_WITH_WARNINGS — see
_docs/03_implementation/reviews/batch_56_review.md for the four
non-blocking documentation findings (F1 cold-start log kind shorthand,
F2 strategy-frame pose semantics, F3 dev-hardware perf smoke, F4
runtime_root importing c1-internal _facade_spine for shared FDR
conventions).

Closes AZ-335; depends on AZ-528 (batch 55).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 03:30:46 +03:00

6.6 KiB

Code Review Report — Batch 56

Batch: 56 Tasks: AZ-335 (C1 Warm-Start Hint Persistence + F8 Reboot Recovery) Date: 2026-05-14 Verdict: PASS_WITH_WARNINGS Mode: Full (per-batch)

Phase Summary

Phase Result
1. Context Loading OK
2. Spec Compliance OK (10/10 ACs implemented + tested; 3 NFRs covered)
3. Code Quality OK
4. Security Quick-Scan OK
5. Performance Scan OK
6. Cross-Task Consistency OK
7. Architecture Compliance 1 Low note (F4)

Findings

# Severity Category File:Line Title
1 Low Style runtime_root/warm_start_wiring.py:82 AC-3 spec text says log kind c1.warm_start.cold_start; impl uses c1.warm_start.cold_start_no_hint
2 Medium Maintainability runtime_root/warm_start_wiring.py:267-272 Per-frame save uses VioOutput.relative_pose_T directly as WarmStartPose.body_T_world without explicit baseline composition
3 Low Spec-Gap tests/unit/c1_vio/test_az335_warm_start.py:TestStoreNfrPerf NFR perf tests are dev-hardware smoke; full Tier-2 NVMe perf is deferred to C1-PT-01
4 Low Architecture runtime_root/warm_start_wiring.py:54 runtime_root imports c1-internal _facade_spine (bias_norm, now_iso)

Finding Details

F1: AC-3 log kind shorthand vs source-suffixed kind (Low / Style)

  • Location: src/gps_denied_onboard/runtime_root/warm_start_wiring.py:82, mirrored in _emit_prime_log k-builder
  • Description: AZ-335 spec AC-3 requires INFO log kind="c1.warm_start.cold_start". The spec Outcome § also names the cold-start source tag as cold_start_no_hint (line 44 of AZ-335_c1_warm_start_recovery.md). The implementation builds the log kind as f"c1.warm_start.{source}" to keep the family namespace consistent (so all three sources — f2_takeoff_fc, f8_reboot_disk, cold_start_no_hint — produce log kinds that match their FDR source field). The result is c1.warm_start.cold_start_no_hint, which is more discriminating than the AC-3 shorthand but doesn't match it character-for-character.
  • Suggestion: Either (a) tighten AC-3's spec text in the next revision of AZ-335_c1_warm_start_recovery.md to say c1.warm_start.cold_start_no_hint, or (b) emit c1.warm_start.cold_start and keep the FDR record's source field as cold_start_no_hint. Option (a) preferred — the source-suffixed kind is genuinely more useful for log filtering.
  • Task: AZ-335

F2: Per-frame save uses strategy-frame pose as body_T_world (Medium / Maintainability)

  • Location: src/gps_denied_onboard/runtime_root/warm_start_wiring.py:267-272 (_save_hint_from_output)
  • Description: AZ-335 spec line 41 says "every emitted VioOutput from process_frame is converted into a WarmStartPose (relative-pose chained against the prior baseline by the runtime root, plus the latest imu_bias from the same VioOutput)". Per _types.nav.VioOutput docstring, relative_pose_T is "the strategy's current pose ... expressed in the strategy's own internal frame". The implementation passes out.relative_pose_T straight into WarmStartPose.body_T_world without composing against a takeoff baseline. This is semantically defensible because the strategy's "internal frame" persists across F8 reload: at F2 takeoff the FC EKF seeds the strategy's frame to world, and on F8 reload the saved hint reinstalls that same frame's most-recent pose so the strategy "continues from where it left off". But the spec phrasing implies an explicit baseline-compose step that the wiring layer would own. No AC tests this composition, so the gap is informational, not contractual.
  • Suggestion: Either (a) document the design choice inline in _save_hint_from_output (a 3-line comment explaining why the strategy-frame pose IS the right hint without explicit composition), or (b) revise the spec line 41 prose in cycle 2 to match the as-built behaviour. Recommend (a) — adds zero runtime cost, prevents future maintainers from "fixing" the gap.
  • Task: AZ-335

F3: NFR perf tests are dev-hardware smoke (Low / Spec-Gap)

  • Location: tests/unit/c1_vio/test_az335_warm_start.py::TestStoreNfrPerf
  • Description: Spec NFR-perf-save (p99 ≤ 50 ms) and NFR-perf-load (p99 ≤ 20 ms) are explicitly Tier-2-NVMe budgets. The unit test uses 200 iterations on whatever filesystem tmp_path resolves to (developer hardware) and asserts the p99 is below the same threshold. This is sufficient to catch egregious regressions but is NOT the production NFR check.
  • Suggestion: Tier-2 measurement is the responsibility of C1-PT-01 (Tier-2 perf gate; deferred to E-BBT). Keep the dev smoke as-is; do not expand here.
  • Task: AZ-335

F4: runtime_root imports c1-internal _facade_spine (Low / Architecture)

  • Location: src/gps_denied_onboard/runtime_root/warm_start_wiring.py:54
  • Description: runtime_root/warm_start_wiring.py imports bias_norm and now_iso from gps_denied_onboard.components.c1_vio._facade_spine. Per module-layout.md §6 + §9, runtime_root is the composition root and may import any component's internal modules — so this is allowed. The note is recorded because importing an underscore-prefixed (c1-internal-by-convention) module from runtime_root is unusual: most runtime_root files only import each component's interface.py plus the concrete strategy modules.
  • Rationale for the choice: the AZ-335 wiring emits vio.warm_start FDR records that share the same kind="vio.*" namespace and timestamp/bias-norm conventions as the c1-strategy-internal vio.health records (AZ-528 / _facade_spine). Sharing the producer functions guarantees forensic logs across the family stay byte-identical in formatting. Inlining the two helpers in warm_start_wiring.py would introduce 6 lines of duplication and a future drift risk.
  • Suggestion: Keep the import. If a future cycle wants to formalize, promote bias_norm + now_iso into a shared helper module (e.g., helpers/iso_timestamps.py already exists for ISO-8601 handling per AZ-526; bias_norm could move to helpers/imu_bias.py).
  • Task: AZ-335

Verdict logic

  • 0 Critical, 0 High → not FAIL
  • 1 Medium + 3 Low → PASS_WITH_WARNINGS
  • All findings are non-blocking and documented for cycle-2 follow-up.

Auto-fix Gate

Not applicable (no FAIL findings). All notes are informational / documentation-tightening.