# Batch 53 — Cycle 1 Report **Date**: 2026-05-14 **Tasks**: AZ-333 (C1 VINS-Mono Strategy) **Verdict**: COMPLETE — PASS_WITH_WARNINGS ## Summary Implemented `VinsMonoStrategy`, the research-only loosely-coupled comparative VIO that participates in the IT-12 comparative-study research binary only. Mirrors the AZ-332 OKVIS2 facade pattern deliberately so the AZ-331 factory can treat both strategies as drop-in substitutable. Native binding is a pybind11 skeleton compiled behind `BUILD_VINS_MONO=ON` (default OFF for airborne / operator-tooling / replay-cli); estimator wiring is the Tier-2 follow-up. ## Files added / modified ### Added (4) - `src/gps_denied_onboard/components/c1_vio/vins_mono.py` — Python facade, 533 lines. - `src/gps_denied_onboard/components/c1_vio/_native/vins_mono_binding.cpp` — pybind11 binding skeleton, ~275 lines. - `tests/unit/c1_vio/test_vins_mono_strategy.py` — AC-1..AC-10 + tier2 perf/honesty tests, 518 lines, 17 tests (15 pass, 2 skip). - `_docs/03_implementation/reviews/batch_53_review.md` — code review report. ### Modified (4) - `src/gps_denied_onboard/components/c1_vio/__init__.py` — export `VinsMonoConfig`. - `src/gps_denied_onboard/components/c1_vio/config.py` — add `VinsMonoConfig` dataclass + `vins_mono` field on `C1VioConfig`; `__all__` updated; `KNOWN_STRATEGIES` already had `vins_mono`. - `cpp/vins_mono/CMakeLists.txt` — replaced AZ-263 placeholder with full pybind11 + linker wiring; gated by `BUILD_VINS_MONO`; ROS-strip flag forced OFF (Risk-1); links Eigen from `cpp/_third_party/eigen/` shared with OKVIS2 (Risk-2). - `tests/unit/c1_vio/conftest.py` — extend with `FakeVinsMonoBackend` + 3 fake exception types + `fake_vins_mono_binding` fixture. - `tests/unit/c1_vio/test_protocol_conformance.py` — drop `vins_mono` from `_STRATEGIES_WITHOUT_PY_MODULE` so the existing parametrised factory test routes through the new strategy correctly (the "module missing" branch is now strictly `klt_ransac`-only until AZ-334 lands). ## AC coverage (AC-1..AC-10 + NFR-perf-document) All 10 ACs mapped to passing tests (see `batch_53_review.md` Phase 2 table). AC-9 + NFR-perf are tier2-tagged per the carry-over plan; they skip on macOS dev + GitHub Actions Linux runner with `Tier-2-only test; set GPS_DENIED_TIER=2 to run`. ## Test results ### Focused suite — `tests/unit/c1_vio/` ``` 72 passed, 4 skipped in 1.14s ``` The 4 skips are the 2 OKVIS2 tier2 tests + the 2 new VINS-Mono tier2 tests (`test_ac9_*` and `test_nfr_perf_*`). ### Adjacent regression — config / compose-root / inference shim ``` 22 passed in 2.87s ``` (`test_az269_config_loader.py`, `test_az270_compose_root.py`, `test_az507_inference_errors_shim.py` — all green; the new `VinsMonoConfig` registration did not break the schema-loader or compose-root layered-import guards.) ### Full suite ``` 1 failed, 1788 passed, 82 skipped in 79.15s ``` The single failure is a pre-existing environment-dependent perf flake: - `tests/unit/c12_operator_orchestrator/test_cli_console_script.py::test_cold_start_under_500ms_p99` — measures CLI cold-start wall-clock; reports `worst-after-trim 997.4 ms` vs the `≤ 500 ms` NFR target. macOS dev runner cannot hit this on a cold spawn; the test is environment-bound to Linux CI hardware. No touchpoint to c1_vio. Reported to the user. ## Architectural decisions - **Mirroring OKVIS2 1:1**: the constructor / state machine / except ladder in `vins_mono.py` is a deliberate copy of `okvis2.py`. The AZ-331 factory + IT-12 harness require shape-compatibility; doing the consolidation now (before AZ-334's KltRansac shape is visible) would over-fit. Tracked as Low-severity finding F1 in the review; scheduled for the post-AZ-334 hygiene PBI (precedent: AZ-340 → AZ-527 for c2_vpr). - **Test fake mirroring**: same logic for `FakeVinsMonoBackend` vs `FakeOkvis2Backend`. The shared `ScriptedOutput` dataclass and `_make_default_payload` helper ARE reused (the productive cut); the backend class duplication is the deferred-consolidation slice. - **CMakeLists ROS-strip + Eigen pin**: explicit Risk-1 mitigation (`VINS_MONO_USE_ROS=OFF` forced), Risk-2 mitigation (Eigen pin from the shared `cpp/_third_party/eigen/`), Risk-3 mitigation (the binding never builds when `BUILD_VINS_MONO=OFF`, so deployment binaries stay clean). - **Skeleton binding throws on first frame**: matches OKVIS2 — a research binary that loads the `.so` before tier-2 wires the real `vins_estimator::Estimator` cannot silently emit misleading poses (`VinsMonoFatalException` from `_drive_estimator`). - **NFR-perf is recorded, not bounded**: per task spec, VINS-Mono is exempt from C1-PT-01's 80 ms p95. The tier2 perf test asserts only that `process_frame` completes 200× without deadlock and that p95 is below a loose 5-second sanity ceiling. The Step 9 / E-BBT comparative-study report consumes the actual p50/p95 number. ## Out of scope / deferred - Real `vins_estimator::Estimator` wiring inside the binding — Tier-2 follow-up; not required for the AZ-333 facade ACs. - KltRansac strategy (AZ-334) — separate batch. - Warm-start hint persistence (AZ-335) — separate batch, depends on AZ-333 + AZ-334. - Strategy-facade consolidation hygiene PBI — informally tracked, formal PBI to be raised by the next cumulative review (batches 52-54) once all three c1_vio strategies are landed.