AZ-266: schema-compliant JSON logging entrypoint, level normalisation, handler-topology guard, format-error fallback (log_record_schema v1.0.0). AZ-269: env > YAML > defaults config loader, frozen Config dataclass, missing-var fail-fast with pointer to .env.example, component-block registry. AZ-277: GTSAM-backed SE3Utils (matrix<->SE3 + exp/log/adjoint) with strict orthogonality, dtype, and bottom-row contract enforcement. AZ-280: atomicwrites-backed write_atomic + independent verify + order-deterministic aggregate_hash; sidecar format strictness. pyproject.toml pins gtsam>=4.2,<5.0 and atomicwrites>=1.4,<2.0 (named-backend deps per the AZ-277 / AZ-280 contracts). 139 unit tests pass (44 new). Review verdict: PASS_WITH_WARNINGS; findings are perf-NFR + journald deferrals, no blocking issues. Co-authored-by: Cursor <cursoragent@cursor.com>
4.8 KiB
Batch Report — Cycle 1 · Batch 2
Tasks shipped: AZ-266, AZ-269, AZ-277, AZ-280
Date: 2026-05-11
Branch: dev
Review verdict: PASS_WITH_WARNINGS — see reviews/batch_02_review.md
Tasks
| ID | Title | Owner Layer | Outcome |
|---|---|---|---|
| AZ-266 | Shared Logging Module | cross-cutting / logging/ |
Implemented — schema-compliant JSON formatter, level normalisation, handler topology guard, format-error fallback |
| AZ-269 | Config Loader | cross-cutting / config/ |
Implemented — env > YAML > defaults precedence, frozen Config, missing-var fail-fast with pointer, component-block registry |
| AZ-277 | SE3Utils Helper | Layer 1 / helpers/se3_utils.py |
Implemented — GTSAM-backed matrix_to_se3 / se3_to_matrix / exp_map / log_map / adjoint with strict orthogonality + dtype contract |
| AZ-280 | Sha256Sidecar Helper | Layer 1 / helpers/sha256_sidecar.py |
Implemented — atomicwrites-backed write_atomic + independent verify + order-deterministic aggregate_hash |
Files Changed
Modified:
pyproject.toml (+4 lines : gtsam, atomicwrites pins)
src/gps_denied_onboard/config/__init__.py (re-exports)
src/gps_denied_onboard/config/loader.py (load_config impl)
src/gps_denied_onboard/config/schema.py (frozen dataclasses + component registry)
src/gps_denied_onboard/helpers/__init__.py (re-exports)
src/gps_denied_onboard/helpers/se3_utils.py (SE3 primitives)
src/gps_denied_onboard/helpers/sha256_sidecar.py (atomic write + sidecar verify)
src/gps_denied_onboard/logging/__init__.py (re-exports)
src/gps_denied_onboard/logging/structured.py (schema-compliant formatter)
tests/unit/test_logging_smoke.py (updated to nested kv schema)
Added:
tests/unit/test_az266_logging_schema.py
tests/unit/test_az269_config_loader.py
tests/unit/test_az277_se3_utils.py
tests/unit/test_az280_sha256_sidecar.py
_docs/03_implementation/reviews/batch_02_review.md
Test Results
$ pytest tests/unit -q --timeout=30
139 passed, 2 skipped in 5.27s
Skips are environment-gated (cmake configure step, actionlint), both verified in CI.
AC Coverage
| Task | ACs declared | ACs covered locally | Tier-2 deferred |
|---|---|---|---|
| AZ-266 | 5 + 2 NFR | 5 ACs + NFR-reliability | NFR-perf (p99 ≤ 0.2 ms on Jetson) |
| AZ-269 | 6 + 2 NFR | 6 ACs + NFR-reliability | NFR-perf (cold load ≤ 250 ms on Jetson) |
| AZ-277 | 9 + 2 NFR | 9 ACs + NFR-* via determinism + AST scan | none |
| AZ-280 | 9 + 2 NFR | 9 ACs + NFR-perf-spot-check + NFR-reliability | none |
Tier-2 perf budgets need hardware to verify against; the unit suite does not synthesise a Jetson budget locally. AZ-428..AZ-431 own the Tier-2 perf scenarios; the batch-2 modules are wired so those tasks plug in without further code changes here.
Dependency Pins
This batch amended pyproject.toml with two new runtime pins required
by AZ-277 and AZ-280 contracts:
gtsam>=4.2,<5.0— SE(3) backend per AZ-277 contractatomicwrites>=1.4,<2.0— atomic-replace backend per AZ-280 contract
Both names appear verbatim in the upstream contract documents and were the named-backend constraint, not an arbitrary choice. AZ-263 intentionally left these unpinned; the pins are added by the first batch that needs them.
Architecture Compliance
helpers/se3_utils.pyandhelpers/sha256_sidecar.pyimport only stdlib + named externals (numpy / gtsam / atomicwrites). Nogps_denied_onboard.components.*imports — enforced by AST scan in both helper test files.logging/structured.pyimports stdlib only (optionalsystemd-pythoninside the Tier-2 handler factory, lazy).config/loader.pyimports stdlib +pyyaml. Theregister_component_blockfunction is the only authorised path for a component to contribute a config block, satisfying AZ-269 § Risks Mitigation Risk 1.
No new circular imports. Verified by running the test suite (any cycle would fail collection).
Review Findings Summary
Verdict: PASS_WITH_WARNINGS. Four Low-severity findings:
- AC-2 test pivots on
fdr.queue_sizerather thanlog.level— clean test design choice givenLOG_LEVELis required-env. - NFR-perf microbenchmarks deferred to Tier-2 perf suite.
- Tier-2 journald handler unverified on macOS dev; runs in Jetson CI.
pyproject.tomldep amendment — by the consumer batch as designed.
Full details in reviews/batch_02_review.md.
Tracker Transitions
- AZ-266: To Do → In Progress → (batch close) In Testing
- AZ-269: To Do → In Progress → (batch close) In Testing
- AZ-277: To Do → In Progress → (batch close) In Testing
- AZ-280: To Do → In Progress → (batch close) In Testing