[AZ-329] [AZ-330] [AZ-523] [AZ-524] Batch 44 atomic refactor

Implements two new C12 services and rebalances the C11/C12 boundary
in one atomic commit:

* AZ-329 PostLandingUploadOrchestrator — gates C11 upload on the
  `flight_footer` FDR record's `clean_shutdown` field; 4 refusal
  modes; new FdrFooterReader Protocol + LocalFdrFooterReader.
* AZ-330 OperatorReLocService — AC-3.4 visual-loss re-localization
  hint; reuses shared LatLonAlt; OperatorCommandTransport Protocol
  cut (E-C8 owns the future pymavlink concrete); new FDR record
  kind `c12.reloc.requested`; log redaction (lat/lon 5 decimals,
  reason 200 chars).
* AZ-523 C11 internal flight-state gate removed (SRP refactor):
  `confirm_flight_state` / `FlightStateSignal` use /
  `FlightStateNotOnGroundError` deleted from C11; TileUploader
  contract bumped to v2.0.0 (frozen) with migration note; AZ-317
  superseded.
* AZ-524 Package rename `c12_operator_tooling` →
  `c12_operator_orchestrator` across source, tests, pyproject,
  CMake, Dockerfile, compose, CI, runtime-root services class
  (`OperatorOrchestratorServices`) + factory function
  (`build_operator_orchestrator`), logger namespaces, config slug,
  docs, and the E-C12 epic title.

Tests: 1543 passed, 80 skipped (all environment gates). Targeted
AC suite (AZ-329 + AZ-330 + FdrFooterReader): 37 passed. Cold-start
NFR-perf still ≤ 500 ms p99.

Tracker: AZ-317 → Done (superseded); AZ-319 v2.0.0 contract bump
comment; AZ-329/AZ-330 → In Testing; AZ-253 epic renamed; AZ-523
+ AZ-524 created and closed as audit-trail tickets.

See `_docs/03_implementation/batch_44_cycle1_report.md`.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-13 19:42:46 +03:00
parent 2d88d3d674
commit 5fe67023b2
112 changed files with 3409 additions and 1311 deletions
+15 -15
View File
@@ -221,7 +221,7 @@ Bootstrap reference: `_docs/02_tasks/todo/AZ-263_initial_structure.md`. Architec
- Composition root: `runtime_root/c10_factory.py` (`build_engine_compiler`, `build_backbone_specs`, `build_manifest_builder`, `build_manifest_verifier`, `build_descriptor_batcher` + the C6→C10 adapters `c6_tile_metadata_store_to_tiles_batch_query`, `c6_tile_store_to_pixel_opener`, `c6_descriptor_index_to_rebuilder`)
- **Owns**: `src/gps_denied_onboard/components/c10_provisioning/**`, `tests/unit/c10_provisioning/**`
- **Imports from**: `_types` (cross-component DTOs `EngineCacheEntry`, `BuildConfig`, `PrecisionMode`, `OptimizationProfile`, `HostCapabilities`, `TileMetadata`, etc.), `_types.inference_errors` (AZ-507 typed-error envelope for `EngineBuildError` + `CalibrationCacheError`), `helpers.sha256_sidecar`, `helpers.engine_filename_schema`, `helpers.wgs_converter`, `config`, `logging`, `fdr_client`. The `InferenceRuntime.compile_engine` surface (c7) and the `TileMetadataStore.query_by_bbox` surface (c6) are obtained via constructor-injected consumer-side structural Protocol cuts (the `CompileEngineCallable` cut already lives in `engine_compiler.py`; AZ-323 / AZ-324 will define analogous `query_by_bbox` cuts inside `c10_provisioning/`). NEVER `from gps_denied_onboard.components.c6_tile_cache import ...` or `from gps_denied_onboard.components.c7_inference import ...` inside `c10_provisioning/*.py`.
- **Consumed by**: `c12_operator_tooling`, `runtime_root` (operator binary only — excluded from airborne via `BUILD_C10_PROVISIONING=OFF` for airborne build per ADR-002)
- **Consumed by**: `c12_operator_orchestrator`, `runtime_root` (operator binary only — excluded from airborne via `BUILD_C10_PROVISIONING=OFF` for airborne build per ADR-002)
### Component: c11_tile_manager
@@ -235,12 +235,12 @@ Bootstrap reference: `_docs/02_tasks/todo/AZ-263_initial_structure.md`. Architec
- `satellite_provider_uploader.py` (post-landing batch upload, D-PROJ-2 ingest contract)
- **Owns**: `src/gps_denied_onboard/components/c11_tile_manager/**`, `tests/unit/c11_tile_manager/**`
- **Imports from**: `_types`, `helpers.sha256_sidecar`, `helpers.wgs_converter`, `config`, `logging`, `fdr_client`. The c6 storage surface (`TileStore`, `TileMetadataStore`) is obtained via constructor-injected consumer-side structural Protocol cuts (see AZ-507 cross-component rule below); composition root wires the concrete c6 strategy in. NEVER `from gps_denied_onboard.components.c6_tile_cache import ...` inside `c11_tile_manager/*.py`.
- **Consumed by**: `c12_operator_tooling`, `runtime_root` (operator binary only — `BUILD_C11_TILE_MANAGER=OFF` for airborne)
- **Consumed by**: `c12_operator_orchestrator`, `runtime_root` (operator binary only — `BUILD_C11_TILE_MANAGER=OFF` for airborne)
### Component: c12_operator_tooling
### Component: c12_operator_orchestrator
- **Epic**: AZ-253 (E-C12 Operator Pre-flight Tooling)
- **Directory**: `src/gps_denied_onboard/components/c12_operator_tooling/`
- **Epic**: AZ-253 (E-C12 Operator Pre-flight Orchestrator)
- **Directory**: `src/gps_denied_onboard/components/c12_operator_orchestrator/`
- **Public API**:
- `__init__.py` (re-exports `CacheBuildWorkflow`, `OperatorReLocService`)
- `interface.py`
@@ -248,9 +248,9 @@ Bootstrap reference: `_docs/02_tasks/todo/AZ-263_initial_structure.md`. Architec
- `cache_build_workflow.py` (CLI orchestrator)
- `operator_reloc_service.py` (CLI; GUI deferred per epic)
- `sector_classifier.py` (operator sets `SectorClassification` → C6)
- **Owns**: `src/gps_denied_onboard/components/c12_operator_tooling/**`, `tests/unit/c12_operator_tooling/**`
- **Imports from**: `_types`, `helpers.wgs_converter`, `config`, `logging`, `fdr_client`. The c6 / c10 / c11 surfaces (`TileStore`, `TileMetadataStore`, `CacheProvisioner`, `TileDownloader`, `TileUploader`) are obtained via constructor-injected consumer-side structural Protocol cuts (see AZ-507 cross-component rule below); composition root wires the concrete c6/c10/c11 strategies in. NEVER `from gps_denied_onboard.components.c6_tile_cache import ...`, `from gps_denied_onboard.components.c10_provisioning import ...`, or `from gps_denied_onboard.components.c11_tile_manager import ...` inside `c12_operator_tooling/*.py`.
- **Consumed by**: `runtime_root` (operator binary only — `BUILD_C12_OPERATOR_TOOLING=OFF` for airborne)
- **Owns**: `src/gps_denied_onboard/components/c12_operator_orchestrator/**`, `tests/unit/c12_operator_orchestrator/**`
- **Imports from**: `_types`, `helpers.wgs_converter`, `config`, `logging`, `fdr_client`. The c6 / c10 / c11 surfaces (`TileStore`, `TileMetadataStore`, `CacheProvisioner`, `TileDownloader`, `TileUploader`) are obtained via constructor-injected consumer-side structural Protocol cuts (see AZ-507 cross-component rule below); composition root wires the concrete c6/c10/c11 strategies in. NEVER `from gps_denied_onboard.components.c6_tile_cache import ...`, `from gps_denied_onboard.components.c10_provisioning import ...`, or `from gps_denied_onboard.components.c11_tile_manager import ...` inside `c12_operator_orchestrator/*.py`.
- **Consumed by**: `runtime_root` (operator binary only — `BUILD_C12_OPERATOR_ORCHESTRATOR=OFF` for airborne)
### Component: c13_fdr
@@ -330,7 +330,7 @@ Bootstrap reference: `_docs/02_tasks/todo/AZ-263_initial_structure.md`. Architec
- **Directory**: `src/gps_denied_onboard/helpers/wgs_converter.py`
- **Purpose**: WGS84 ↔ local-tangent-plane conversion utilities (`04_helper_wgs_converter.md`).
- **Owned by**: AZ-264.
- **Consumed by**: c4_pose, c5_state, c6_tile_cache, c8_fc_adapter, c10_provisioning, c11_tile_manager, c12_operator_tooling.
- **Consumed by**: c4_pose, c5_state, c6_tile_cache, c8_fc_adapter, c10_provisioning, c11_tile_manager, c12_operator_orchestrator.
### shared/helpers/sha256_sidecar
@@ -379,7 +379,7 @@ Bootstrap reference: `_docs/02_tasks/todo/AZ-263_initial_structure.md`. Architec
- **File**: `src/gps_denied_onboard/runtime_root.py`
- **Purpose**: Composition root — config → strategy resolution → graph wiring (ADR-009). The ONLY place that may import concrete strategy classes across components. Per-binary CMake `BUILD_*` flags + composition root validator enforce ADR-002 build-time exclusion. Hosts `compose_root(config)` (airborne), `compose_operator(config)` (operator), and `compose_replay(config)` (replay-cli).
- **Owned by**: AZ-263 (Bootstrap stub); per-component additions that wire a new strategy are owned jointly by the bootstrap epic and the consuming component task (touching `runtime_root.py` is allowed only via the explicit "wire-in" task in each component's epic). The `compose_replay` extension is owned by AZ-265 child task #4.
- **Consumed by**: the airborne binary entrypoint + the operator-tooling binary entrypoint + the research/comparative binary entrypoint + the replay-cli binary entrypoint.
- **Consumed by**: the airborne binary entrypoint + the operator-orchestrator binary entrypoint + the research/comparative binary entrypoint + the replay-cli binary entrypoint.
### shared/cli/replay
@@ -393,7 +393,7 @@ Bootstrap reference: `_docs/02_tasks/todo/AZ-263_initial_structure.md`. Architec
- **File**: `src/gps_denied_onboard/healthcheck.py`
- **Purpose**: Importable healthcheck callable used by Dockerfile `HEALTHCHECK CMD` and CI smoke.
- **Owned by**: AZ-263.
- **Consumed by**: companion-tier1 Dockerfile, operator-tooling Dockerfile, CI smoke job.
- **Consumed by**: companion-tier1 Dockerfile, operator-orchestrator Dockerfile, CI smoke job.
## Allowed Dependencies (Layering)
@@ -402,7 +402,7 @@ Read top-to-bottom; an upper layer may import from a lower layer but NEVER the r
| Layer | Components / Modules | May import from |
|-------|---------------------|-----------------|
| 5. Entry / Composition | `runtime_root`, `cli/replay`, `healthcheck` | 1, 2, 3, 4 |
| 4. Adapters | c8_fc_adapter (incl. `tlog_replay_adapter` + `replay_sink`), c11_tile_manager, c10_provisioning, c12_operator_tooling, `frame_source/VideoFileFrameSource` + `frame_source/LiveCameraFrameSource` | 1, 2, 3 (limited — see notes) |
| 4. Adapters | c8_fc_adapter (incl. `tlog_replay_adapter` + `replay_sink`), c11_tile_manager, c10_provisioning, c12_operator_orchestrator, `frame_source/VideoFileFrameSource` + `frame_source/LiveCameraFrameSource` | 1, 2, 3 (limited — see notes) |
| 3. Domain (runtime path) | c1_vio, c2_vpr, c2_5_rerank, c3_matcher, c3_5_adhop, c4_pose, c5_state, c13_fdr | 1, 2 |
| 2. Infrastructure | c6_tile_cache, c7_inference | 1 |
| 1. Foundation (shared) | `_types`, `config`, `logging`, `fdr_client`, `helpers/*`, `frame_source` (interface only), `clock` | (none) |
@@ -415,7 +415,7 @@ Read top-to-bottom; an upper layer may import from a lower layer but NEVER the r
## Build-Time Exclusion Map (ADR-002)
Four binaries are built from this codebase: **airborne** (Tier-1 + Tier-2 production), **research** (IT-12 comparative-study, links every strategy), **operator-tooling** (pre-flight workflows on operator workstation), **replay-cli** (offline `gps-denied-replay` against video + tlog; AZ-265).
Four binaries are built from this codebase: **airborne** (Tier-1 + Tier-2 production), **research** (IT-12 comparative-study, links every strategy), **operator-orchestrator** (pre-flight workflows on operator workstation), **replay-cli** (offline `gps-denied-replay` against video + tlog; AZ-265).
| CMake flag | Components / native libs gated | Airborne | Research | Operator-tooling | Replay-cli |
|-----------|-------------------------------|----------|----------|------------------|------------|
@@ -427,7 +427,7 @@ Four binaries are built from this codebase: **airborne** (Tier-1 + Tier-2 produc
| `BUILD_PYTORCH_RUNTIME` | c7_inference/pytorch_fp16_runtime | OFF | ON | OFF | OFF |
| `BUILD_C10_PROVISIONING` | c10_provisioning | OFF | OFF | ON | OFF |
| `BUILD_C11_TILE_MANAGER` | c11_tile_manager | OFF | OFF | ON | OFF |
| `BUILD_C12_OPERATOR_TOOLING` | c12_operator_tooling | OFF | OFF | ON | OFF |
| `BUILD_C12_OPERATOR_ORCHESTRATOR` | c12_operator_orchestrator | OFF | OFF | ON | OFF |
| `BUILD_GTSAM_BINDINGS` | cpp/gtsam_bindings (used by c4_pose + c5_state) | ON | ON | OFF | ON |
| `BUILD_FAISS_INDEX` | c6_tile_cache `FaissDescriptorIndex` (faiss-cpu wheel; runtime gate at `runtime_root.storage_factory` — no native target) | ON | ON | ON | OFF (replay reads pre-built cache only) |
| `BUILD_VIDEO_FILE_FRAME_SOURCE` | `frame_source/VideoFileFrameSource` (AZ-265) | OFF | OFF | OFF | ON |
@@ -456,7 +456,7 @@ Build-time exclusion is enforced by:
## Self-Verification Checklist
- [x] Every component in `_docs/02_document/components/` has a Per-Component Mapping entry (14 components: c1_vio, c2_vpr, c2_5_rerank, c3_matcher, c3_5_adhop, c4_pose, c5_state, c6_tile_cache, c7_inference, c8_fc_adapter, c10_provisioning, c11_tile_manager, c12_operator_tooling, c13_fdr).
- [x] Every component in `_docs/02_document/components/` has a Per-Component Mapping entry (14 components: c1_vio, c2_vpr, c2_5_rerank, c3_matcher, c3_5_adhop, c4_pose, c5_state, c6_tile_cache, c7_inference, c8_fc_adapter, c10_provisioning, c11_tile_manager, c12_operator_orchestrator, c13_fdr).
- [x] Every shared / cross-cutting concern has a Shared section entry (_types, config, logging, fdr_client, frame_source, clock, helpers/* × 8, runtime_root, cli/replay, healthcheck).
- [x] Layering table covers every component; foundation at Layer 1.
- [x] No component's `Imports from` list points at a component in a higher layer (back-channel exception for C8 → C1/C5 documented as interface-at-producer pattern).