# Code Review Report **Batch**: 72 — AZ-416, AZ-417, AZ-419 **Date**: 2026-05-16 **Verdict**: PASS ## Findings (none) ## Findings Sweep ### Phase 1 — Context Loading Loaded specs `AZ-416_ft_p_09_ap_signing.md`, `AZ-417_ft_p_09_inav.md`, `AZ-419_ft_p_11_cold_start_init.md`. Re-read existing `runner/helpers/mavproxy_tlog_reader.py` (AZ-406 surface to be filled in by AZ-416 per the docstring), `sitl_observer.py`, `fdr_reader.py`, `geo.py`. Read `fixtures/cold-boot/cold_boot_fixture.json` for FT-P-11 secondary path origin. Verified pymavlink ≥2.4 install + the `MAVLink.get_signed()` API surface in the venv. ### Phase 2 — Spec Compliance **AZ-416 (FT-P-09-AP)** | AC | Coverage | Status | |----|----------|--------| | AC-1 (signing handshake ≤5 s, no BAD_SIGNATURE) | `test_handshake_passes_when_first_signed_within_window`, `test_handshake_fails_when_no_signed_within_window`, `test_handshake_fails_when_signed_arrives_after_budget`, `test_handshake_fails_on_bad_signature_statustext`, scenario assertion via `observe_signing_handshake` | Covered | | AC-2 (GPS_INPUT ≥4.5 Hz for 5 Hz target) | `test_gps_input_rate_at_5hz_for_60s_passes`, `test_gps_input_rate_at_boundary_passes`, `test_gps_input_rate_below_minimum_fails`, scenario assertion via `compute_gps_input_rate` | Covered | | AC-3 (EK3_SRC1_POSXY == 3) | `test_validate_ek3_src1_posxy_passes_at_3`, scenario via `validate_ek3_src1_posxy(sitl_observer.read_ap_parameter(...))` | Covered | | AC-4 (GPS_RAW_INT healthy fraction ≥80 %) | `test_gps_raw_int_health_all_healthy_passes`, `test_gps_raw_int_health_at_80_pct_boundary_passes`, `test_gps_raw_int_health_below_80_pct_fails`, `test_gps_raw_int_health_eph_threshold_strict`, scenario via `evaluate_gps_raw_int_health` | Covered | | AC-5 (vio_strategy parameterization; `fc_adapter` fixed to `ardupilot`) | scenario uses `vio_strategy` fixture from conftest; `fc_adapter != "ardupilot"` is skipped — collection across 6 variants reduces to 3 active variants | Covered | | D-C8-9 (signing-handshake observability) | `traces_to` marker + handshake report includes `setup_signing_seen` | Covered | Also: AZ-416's `mavproxy_tlog_reader.iter_messages` body landed (previously raised NotImplementedError per the AZ-406 commit). 6 unit tests in `test_mavproxy_tlog_reader.py` exercise the parser against synthetic tlogs. **AZ-417 (FT-P-09-iNav)** | AC | Coverage | Status | |----|----------|--------| | AC-1 (TCP connect to inav-sitl:5760 ≤5 s) | scenario via `sitl_observer.observe_inav_tcp_handshake` (skip-gated) | Covered (gated) | | AC-2 (MSP2_SENSOR_GPS ≥4.5 Hz for 5 Hz target) | `test_compute_rate_at_target_passes`, `test_compute_rate_at_boundary_passes`, `test_compute_rate_below_minimum_fails`, `test_compute_rate_filters_function_id`, scenario via `compute_rate_hz` | Covered | | AC-3 (fix_type ≥3, provider=MSP, numSat matches emitted) | `test_evaluate_gps_state_passes_at_minimum_fix`, `test_evaluate_gps_state_fails_on_low_fix_type`, `test_evaluate_gps_state_fails_on_wrong_provider`, `test_evaluate_gps_state_fails_on_num_sat_mismatch`, scenario via `evaluate_inav_gps_state` | Covered | | AC-4 (vio_strategy parameterization; `fc_adapter` fixed to `inav`) | scenario uses `vio_strategy` fixture; skips when `fc_adapter != "inav"` | Covered | **AZ-419 (FT-P-11)** | AC | Coverage | Status | |----|----------|--------| | AC-1 (operator_manifest: estimate ≤50 m of A; FDR `cold_start_origin.set(source="manifest")`) | `test_evaluate_operator_manifest_passes_at_origin`, `test_evaluate_operator_manifest_passes_just_inside_budget`, `test_evaluate_operator_manifest_fails_just_outside_budget`, scenario assertion | Covered | | AC-2 (fc_ekf: estimate ≤50 m of FC EKF snapshot; FDR `source="fc_ekf"`) | `test_evaluate_fc_ekf_passes`, scenario assertion | Covered | | AC-3 (no origin → SUT refuses takeoff; FDR `cold_start_origin.unavailable`) | `test_evaluate_no_origin_passes_when_silent_and_fdr_records_abort`, `test_evaluate_no_origin_fails_when_sut_emits_anything`, `test_evaluate_no_origin_fails_when_fdr_missing_unavailable_signal`, dedicated scenario `test_ft_p_11_cold_start_no_origin_aborts` | Covered | | AC-4 (bounded-delta conflict: operator wins; source_label != satellite_anchored; FDR `gps_bounded_delta.reject`) | `test_evaluate_bounded_delta_conflict_operator_wins`, `test_evaluate_bounded_delta_fails_when_label_is_satellite_anchored`, scenario assertion (third parametrize variant) | Covered | | AC-5 (parameterization across `fc_adapter, vio_strategy, origin_source`) | scenario uses conftest's `fc_adapter` + `vio_strategy`; parametrizes `origin_source ∈ {operator_manifest, fc_ekf, bounded_delta_conflict}` separately | Covered | ADR-010 Principle #11 amended ("operator origin wins on bounded-delta conflict; FC GPS logged as suspect") explicitly encoded as `BOUNDED_DELTA_TRIGGER_M = 200.0` + the `c5.gps_bounded_delta.reject` record audit. ### Phase 3 — Code Quality * **Single responsibility**: `mavproxy_tlog_reader` only iterates/counts tlog frames (file I/O concern); `ap_contract_evaluator` only consumes `TlogMessage` iterables (analytics concern); `msp_frame_observer` only consumes captured MSP samples. `cold_start_evaluator` is one module because the three FT-P-11 variants share a single FDR record vocabulary + Manifest schema; splitting them would force the scenario to import three near-identical modules. * **No suppressed errors**: `mavproxy_tlog_reader.iter_messages` catches the narrow `BAD_DATA` + per-message `to_dict` exceptions (documented in pymavlink) and continues, but the file-not-found + connection-close paths raise / surface naturally. No bare `except` in any new module. * **AAA comment discipline**: every test uses `# Arrange / # Act / # Assert`; sections omitted when not needed. * **No narration comments**: docstrings explain non-obvious intent (AC mapping, why orphans excluded, why `materialize_to_list` exists, why `EK3_SRC1_POSXY = 3` is the only acceptance value). ### Phase 4 — Security * **No SUT imports**: confirmed by `test_no_sut_imports.py` (passing in the full suite). None of the new modules import from `src.gps_denied_onboard`. * **Signing handshake stance**: the helper does NOT validate signatures itself (that's pymavlink's job); it only counts signed-frame arrivals and `BAD_SIGNATURE` STATUSTEXT incidents. If signing fails in any way AC-1 fails — the scenario does NOT bypass to an unsigned channel (per spec "Forbidden" list). * **No secrets in source**: the AP scenario looks up `mavlink-test-passkey.txt` from the on-disk fixture (already verified by `test_passkey_files_match` in `test_directory_layout.py`). The passkey itself is the AZ-407 / AZ-408 fixture, NOT a production key. * **No SQL/shell injection surface**: all helpers operate on bytes / pathlib / dict; no subprocess calls in the helper layer (subprocess for `msp_gps_toy` is the SITL-observer's responsibility). ### Phase 5 — Performance * `mavproxy_tlog_reader.iter_messages` is a single pass over the tlog; pymavlink's `recv_match(blocking=False)` is the standard idiom. * `ap_contract_evaluator` consumes the materialised list ONCE per analyser; `collect_messages_to_list` is the documented choice (mavlink_connection's iterator closes on exhaustion so re-iteration isn't safe). For typical 60 s of mavproxy traffic at ~50 msg/s this is ≤3000 messages → trivial in memory. * `cold_start_evaluator._scan_fdr_for_cold_start` is one pass. * No nested loops over the same data. ### Phase 6 — Cross-Task Consistency * **Pattern parity with batches 69 + 70 + 71**: - Skip gate (`_*_harness_implemented` fixture) for missing upstream replay/SITL/FDR helpers — same pattern as `test_ft_p_02/04/05/07/08/10_*`. - `_NullSink` probe — same idiom as the prior 5 scenario files. - Evidence side-channel via `nfr_recorder.record_metric(name, value, ac_id=…)` — same pattern as `test_ft_p_01/04/05/07/08/10_*`. - Module-level constants (`UPPER_SNAKE`) for budgets — matches `multi_segment_evaluator`, `mre_evaluator`, `smoothing_evaluator`, `sharp_turn_detector`. - Helper modules importable from `runner.helpers.*`. * **No drift**: scenarios reuse the helper's constants (no magic numbers) — `HANDSHAKE_BUDGET_S`, `GPS_INPUT_MIN_RATE_HZ`, `MIN_FIX_TYPE`, `ACCURACY_BUDGET_M`, `BOUNDED_DELTA_TRIGGER_M`, `FDR_RECORD_*`, `FORBIDDEN_FIRST_LABEL_BOUNDED_DELTA`. * **No legacy NotImplementedError test left behind**: verified no test asserts `iter_messages` raises NotImplementedError (was AZ-406's surface contract; AZ-416 owns the body per docstring). ### Phase 7 — Architecture Compliance * **Public-boundary discipline**: confirmed by `test_no_sut_imports.py` (passing). Helpers consume pymavlink (a third-party MAVLink reference impl, not SUT internals) + FDR record schema (record_type + payload dict) + outbound estimate schema. The signing handshake observer specifically does NOT import the SUT's signing-key state per the spec "Forbidden" list. * **Directory layout**: new paths added to `test_directory_layout.py` parametrize list (`runner/helpers/{msp_frame_observer, ap_contract_evaluator, cold_start_evaluator}.py`, `tests/positive/test_ft_p_{09_ap_signing, 09_inav, 11_cold_start_init}.py`). All variants pass. * **Determinism**: all helpers are deterministic — no `time.time()`, no RNG; pymavlink parses bytes deterministically. ### Phase 8 — Test Suite Health * Total: **460 passed in 134.35 s** (was 393 at end of batch 71). * New tests this batch: **+67** (msp_frame_observer: 14; mavproxy_tlog_reader: 6; ap_contract_evaluator: 22; cold_start_evaluator: 19; directory_layout new entries: 6). * Pre-existing macOS-only `/e2e-results` plugin issue still present — affects scenario test invocation outside Docker only; unit suite unaffected. Out of batch scope. ## Cross-Task Consistency Verdict PASS — no cross-task drift, no duplicated logic across the four new helpers, shared `TlogMessage` type used consistently between `mavproxy_tlog_reader` and `ap_contract_evaluator`. ## Architecture Compliance Verdict PASS — public-boundary blackbox stance preserved; no SUT imports; pymavlink boundary correctly placed at the tlog reader. ## Final Verdict **PASS** — Batch 72 (AZ-416 + AZ-417 + AZ-419) ready for commit.