mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 01:41:13 +00:00
[AZ-623] [AZ-625] Phase E: c282_ransac + c5 helpers; split handle work
Wire 4 stateless / cached helpers into airborne_bootstrap.build_pre_constructed: c282_ransac_filter, c5_imu_preintegrator (cached on calibration path), c5_se3_utils (helpers.se3_utils module as namespace handle), c5_wgs_converter. The original AZ-623 5th deliverable (c5_isam2_graph_handle) hit an unresolvable construction-order conflict between c4_pose (consumes the handle) and c5_state (creates it inside build_state_estimator's tuple return) under the umbrella's "MUST NOT touch any per-component factory signature" constraint. Per AZ-623 spec's escalation gate, scope was split: AZ-625 captures the handle ordering work; AZ-624 dependency edge updated to require both. Tests: tests/unit/runtime_root/test_az623_pre_constructed_phase_e.py adds 7 tests covering AC-623.1..3 (4 new keys + correct types, IMU preintegrator caching, operator-actionable error messages for empty / unreadable / malformed calibration paths). Autouse stubs added to test_az619/620/621/622 so prior phase tests remain isolated from new builders. Quality gates: ruff format clean, ruff lint clean, 24/24 phase tests pass, 247/247 runtime_root + c5_state regression suite passes. Code review verdict PASS_WITH_WARNINGS (3 Low findings; full report in _docs/03_implementation/reviews/batch_94_review.md). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# Batch Report
|
||||
|
||||
**Batch**: 94
|
||||
**Tasks**: AZ-623 (Phase E narrowed: build_pre_constructed seeds c282_ransac_filter + c5_imu_preintegrator + c5_se3_utils + c5_wgs_converter; `c5_isam2_graph_handle` work split out to AZ-625)
|
||||
**Date**: 2026-05-19
|
||||
**Cycle**: 1
|
||||
|
||||
## Task Results
|
||||
|
||||
| Task | Status | Files Modified | Tests | AC Coverage | Issues |
|
||||
|------|--------|----------------|-------|-------------|--------|
|
||||
| AZ-623_pre_constructed_phase_e_ransac_c5_helpers (narrowed) | Done | 7 files | 24 passed | 4/4 ACs covered | 0 blocking |
|
||||
|
||||
Original AZ-623 had a 5th deliverable (`c5_isam2_graph_handle`) that uncovered an unresolvable construction-order conflict between `c4_pose` (consumes the handle) and `c5_state` (creates the handle inside `build_state_estimator`'s tuple return) under the umbrella's "MUST NOT touch any per-component factory signature" constraint. Per the AZ-623 spec's own escalation gate ("if the resolution requires a Protocol seam change, escalate"), the question was surfaced; user chose to **split scope**:
|
||||
|
||||
- This batch lands the 4 stateless / cached helpers (narrowed AZ-623).
|
||||
- New PBI **AZ-625** ("AZ-618 Phase E.5: c5_isam2_graph_handle ordering", 3pt, parent AZ-618) holds the handle work.
|
||||
- **AZ-624** dependency edge updated to require both AZ-623 AND AZ-625.
|
||||
|
||||
## Files Changed
|
||||
|
||||
### Production
|
||||
- `src/gps_denied_onboard/runtime_root/airborne_bootstrap.py` — added imports (`json`, `pathlib.Path`, `numpy`, `_types.calibration.CameraCalibration`, `helpers.imu_preintegrator.{ImuPreintegrator, make_imu_preintegrator}`, `helpers.ransac_filter.RansacFilter`, `helpers.wgs_converter.WgsConverter`); added module-level `_IMU_PREINTEGRATOR_CACHE` dict + `clear_imu_preintegrator_cache()` helper; added `_load_camera_calibration` (mirrors `_replay_branch._load_camera_calibration` but raises `AirborneBootstrapError`); added 4 builders `_build_c282_ransac_filter`, `_build_c5_imu_preintegrator` (cached on calibration path), `_build_c5_se3_utils` (returns the `helpers.se3_utils` module as a namespace handle, matching existing C5 estimator's MagicMock fixture pattern), `_build_c5_wgs_converter`; extended `build_pre_constructed` to populate the 4 new keys after the existing AZ-619..AZ-622 keys.
|
||||
|
||||
### Tests
|
||||
- `tests/unit/runtime_root/test_az623_pre_constructed_phase_e.py` (NEW, 7 tests):
|
||||
- `test_ac_623_1_adds_c282_ransac_and_c5_helpers` — AC-623.1 (4 keys + correct types).
|
||||
- `test_ac_623_1_keeps_existing_keys_intact` — additivity invariant (AZ-619..AZ-622 keys still present).
|
||||
- `test_ac_623_2_imu_preintegrator_cached_across_calls` — AC-623.2 (cache short-circuit via per-test counter).
|
||||
- `test_ac_623_2_imu_preintegrator_per_path_cache` — AC-623.2 (per-path cache isolation).
|
||||
- `test_ac_623_3_empty_calibration_path_raises_named_error` — AC-623.3 (operator-actionable error).
|
||||
- `test_ac_623_3_unreadable_calibration_path_raises_named_error` — AC-623.3 (file not found path).
|
||||
- `test_ac_623_3_malformed_json_raises_named_error` — AC-623.3 (JSON decode wrap).
|
||||
- `tests/unit/runtime_root/test_az619_pre_constructed_phase_a.py` — added autouse `_stub_c5_builders`.
|
||||
- `tests/unit/runtime_root/test_az620_pre_constructed_phase_b.py` — added autouse `_stub_c5_builders`.
|
||||
- `tests/unit/runtime_root/test_az621_pre_constructed_phase_c.py` — added autouse `_stub_c5_builders`.
|
||||
- `tests/unit/runtime_root/test_az622_pre_constructed_phase_d.py` — added autouse `_stub_c5_builders`.
|
||||
|
||||
### Specs
|
||||
- `_docs/02_tasks/todo/AZ-623_*.md` → narrowed (handle work removed); ARCHIVED to `_docs/02_tasks/done/`.
|
||||
- `_docs/02_tasks/todo/AZ-624_*.md` — Dependencies updated (AZ-625 added).
|
||||
- `_docs/02_tasks/todo/AZ-625_c5_isam2_graph_handle_ordering.md` (NEW) — 3pt, parent AZ-618, holds the handle ordering work.
|
||||
|
||||
## AC Test Coverage: 4 of 4 covered
|
||||
|
||||
| AC | Test | Status |
|
||||
|----|------|--------|
|
||||
| AC-623.1 | `test_ac_623_1_adds_c282_ransac_and_c5_helpers` + `test_ac_623_1_keeps_existing_keys_intact` | Covered |
|
||||
| AC-623.2 | `test_ac_623_2_imu_preintegrator_cached_across_calls` + `test_ac_623_2_imu_preintegrator_per_path_cache` | Covered |
|
||||
| AC-623.3 | `test_ac_623_3_empty_calibration_path_raises_named_error` (+ 2 variants for unreadable/malformed) | Covered |
|
||||
| AC-623.4 | File `tests/unit/runtime_root/test_az623_pre_constructed_phase_e.py` exists | Covered |
|
||||
|
||||
## Code Review Verdict: PASS_WITH_WARNINGS
|
||||
|
||||
Full report: `_docs/03_implementation/reviews/batch_94_review.md`. Three Low findings:
|
||||
|
||||
1. **F1 (Low / Maintainability)** — `_load_camera_calibration` duplicates `_replay_branch._load_camera_calibration` (different exception class). Defer to a hygiene PBI (~2pt) bundled with batch 93's F2 leftover.
|
||||
2. **F2 (Low / Maintainability)** — empty-path check duplicated across `_build_c5_imu_preintegrator` and `_load_camera_calibration` (defense-in-depth). No change recommended.
|
||||
3. **F3 (Low / Style)** — `c5_se3_utils` returns a Python module as a namespace handle. Documented; matches existing C5 test fixture pattern. YAGNI — defer Protocol introduction.
|
||||
|
||||
No Critical / High / Medium findings. Auto-fix not invoked.
|
||||
|
||||
## Auto-Fix Attempts: 0
|
||||
|
||||
## Stuck Agents: None
|
||||
|
||||
## Test Run Summary
|
||||
|
||||
- Targeted test set (AZ-619..AZ-623): **24 passed** in 1.07s.
|
||||
- Regression check (`tests/unit/runtime_root/` + `tests/unit/c5_state/`): **247 passed** in 1.78s.
|
||||
|
||||
## Scope-Split Decision Trail
|
||||
|
||||
The split was driven by an irreconcilable construction-order issue between two umbrella constraints:
|
||||
|
||||
- **Constraint A** (umbrella AZ-618): "MUST NOT touch any per-component factory signature" + "All changes confined to runtime_root/airborne_bootstrap.py, runtime_root/__init__.py, and the new test file."
|
||||
- **Constraint B** (existing seam): `build_state_estimator` returns `(StateEstimator, ISam2GraphHandle)` as a tuple — the handle is a structural side-product of the estimator, not separately constructable.
|
||||
- **Constraint C** (existing seam): C4's `build_pose_estimator` consumes `c5_isam2_graph_handle` from `pre_constructed`, so `compose_root` topologically requires it to exist before C4 runs, which is before C5 runs.
|
||||
|
||||
Possible resolutions all touched at least one of A/B/C; the user-approved Option B preserves all three constraints by:
|
||||
|
||||
- Keeping the **C4 ↔ C5 seam intact** (no Protocol changes).
|
||||
- Promoting the (estimator, handle) build into `airborne_bootstrap`, where AZ-618 explicitly permits orchestration.
|
||||
- Documenting the strategy in AZ-625's spec § "Decision" with full rationale.
|
||||
|
||||
## Tier-2 / Deferred Work
|
||||
|
||||
- AZ-625 (3pt) — handle ordering work, blocks AZ-624.
|
||||
- Hygiene PBI to consolidate `_load_camera_calibration` between airborne_bootstrap and `_replay_branch` (F1) and `_is_build_flag_on` triple-duplication (batch 93 F2). Bundle as ~2pt cleanup PBI post-AZ-618.
|
||||
|
||||
## Next Batch
|
||||
|
||||
- **Batch 95**: AZ-625 (Phase E.5: c5_isam2_graph_handle ordering) — 3pt.
|
||||
- **Then Batch 96**: AZ-624 (Phase F: wire main() + AC-1..AC-5 verification incl. Jetson tier-2) — 2pt.
|
||||
- **Cumulative review window**: next due at batch 96 (K=3 from last cumulative at 88-92).
|
||||
Reference in New Issue
Block a user