mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-21 05:41:13 +00:00
[autodev] Step 13 partial: arch + module-layout cycle-1 sync
Item 1 of the deferred Step 13 refresh set per _docs/02_document/ripple_log_cycle1.md. architecture.md: - Components C1: KltRansac is the cycle-1 operational default while AZ-332/AZ-333 are BLOCKED awaiting Tier-2 prerequisites; ADR-001 / ADR-002 unchanged (the seam holds; the selection shifted). - Principle #3: same KltRansac note (cross-link to Components). - § Technology Stack: OpenCV pin row reflects the cycle-1 relaxation to >=4.11.0.86,<4.12 with the leftover-file pointer; OKVIS2 + VINS- Mono rows note BLOCKED with AZ-592 / AZ-593 follow-ups. - § NFR: Dependency CVE pinning row notes the relaxation and the CVE-2025-53644 re-validation owed before close. - § ADR-001: cycle-1 operational note (KltRansac default; AZ-332/333 facade-only; AZ-589/590 closed Won't-Fix). - § ADR-009: new Cycle-1 implementation subsection covers _STRATEGY_REGISTRY + register_strategy (AZ-591) and the pre_constructed kwarg + build_pre_constructed (AZ-618 umbrella; Phases A-F including AZ-625 / AZ-687). module-layout.md: - shared/runtime_root entry: package layout (was single file in the Plan-era sketch); new public-surface table covering __init__.py, airborne_bootstrap.py, _replay_branch.py, and the per-component factory modules; ownership rows extended (AZ-591, AZ-618, AZ-625, AZ-687). system-flows.md: intentionally not modified — F2 / F8 narratives are at the component-flow abstraction level and do not reference compose_root / pre_constructed mechanics, so they have not drifted. Items 2-4 of the ripple-log refresh set (C1 description, the other 13 components, 8 helpers, tests/*.md) remain deferred to subsequent sessions. State: Step 13 stays in_progress; sub_step advanced to phase 6 (component-doc-updates). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,7 +11,7 @@ The system is a **Jetson Orin Nano Super-hosted onboard companion** that deliver
|
||||
|
||||
### Components — intent-level (formal decomposition belongs to Step 3)
|
||||
|
||||
- **C1 — Visual / Visual-Inertial Odometry**: pluggable `VioStrategy` (Okvis2 default, VinsMono in research builds only, KltRansac mandatory simple-baseline), config-selected at startup, not hot-swappable mid-flight.
|
||||
- **C1 — Visual / Visual-Inertial Odometry**: pluggable `VioStrategy` (Okvis2 architecturally-nominated production-default, VinsMono in research builds only, KltRansac mandatory simple-baseline), config-selected at startup, not hot-swappable mid-flight. **Cycle-1 operational reality**: AZ-332 (Okvis2) and AZ-333 (VinsMono) shipped as facade-only — both require Tier-2 prerequisites (CI build env + Jetson hardware + DBoW2 vocab artifact) that cycle 1 did not deliver, so the production-default selection is **KltRansac** (AZ-334) until AZ-592 / AZ-593 (Tier-2 follow-ups) land. ADR-001 / ADR-002 are unchanged — the seam holds; the *selection* shifted.
|
||||
- **C2 — Visual Place Recognition**: pre-cached satellite-tile retrieval (UltraVPR primary, MegaLoc secondary, MixVPR / SelaVPR / EigenPlaces / NetVLAD / SALAD additional candidates), all behind a single `VprStrategy` interface; concrete implementation chosen by config at startup.
|
||||
- **C2.5 — Top-N inlier-based re-rank**: re-ranks the top-K=10 VPR candidates by single-pair LightGlue inlier count down to top-N=3.
|
||||
- **C3 — Cross-domain matcher**: DISK+LightGlue (D-C3-1 = (a)) over the N=3 retained candidates; ALIKED+LightGlue secondary; XFeat alternate.
|
||||
@@ -31,7 +31,7 @@ The system is a **Jetson Orin Nano Super-hosted onboard companion** that deliver
|
||||
|
||||
1. **Camera-specific math enters only via a `Camera calibration artifact` JSON** (intrinsics + distortion + body-to-camera extrinsics + acquisition method `factory_sheet | checkerboard_refined | hybrid`). No hard-coded camera math anywhere; test fixtures (`adti26`) and production deployments (`adti20`) load different artifacts on the same code path.
|
||||
2. **VioStrategy is selected at startup via config; not hot-swappable mid-flight.**
|
||||
3. **Build-time exclusion of unused `Strategy` implementations.** A given binary links only the implementations it actually uses at runtime. The default deployment binary links the production-default strategies (e.g. OKVIS2 on C1) plus the engine-rule-mandatory simple-baseline (KltRansac on C1); the IT-12 comparative-study binary links all C1 implementations side-by-side. The mechanism is per-component CMake `BUILD_*` flags (`BUILD_VINS_MONO`, `BUILD_SALAD`, …) plus the per-binary composition root choosing among the linked implementations at startup. **Justification is technical** — binary size on the 8 GB shared Jetson, boot/load time inside the AC-NEW-1 30 s budget, deployed dependency / attack surface, and accidental-selection risk reduction (a binary with only OKVIS2 + KltRansac linked cannot be misconfigured into running VINS-Mono). **Component licenses do not drive this decision** — see ADR-002. CI emits both the deployment binary and the research binary on every PR.
|
||||
3. **Build-time exclusion of unused `Strategy` implementations.** A given binary links only the implementations it actually uses at runtime. The default deployment binary links the production-default strategies (architecturally OKVIS2 on C1; **operationally KltRansac in cycle 1** while AZ-332 / AZ-333 are BLOCKED awaiting Tier-2 prerequisites — see Components C1 above and FINAL_report § "Cycle 1 Implementation Status") plus the engine-rule-mandatory simple-baseline (KltRansac on C1); the IT-12 comparative-study binary links all C1 implementations side-by-side. The mechanism is per-component CMake `BUILD_*` flags (`BUILD_VINS_MONO`, `BUILD_SALAD`, …) plus the per-binary composition root choosing among the linked implementations at startup. **Justification is technical** — binary size on the 8 GB shared Jetson, boot/load time inside the AC-NEW-1 30 s budget, deployed dependency / attack surface, and accidental-selection risk reduction (a binary with only OKVIS2 + KltRansac linked cannot be misconfigured into running VINS-Mono). **Component licenses do not drive this decision** — see ADR-002. CI emits both the deployment binary and the research binary on every PR.
|
||||
4. **In-air network I/O against `satellite-provider` is forbidden — in BOTH directions.** Enforced primarily by **process-level isolation** — the Tile Manager (C11), which carries both the `TileDownloader` and the `TileUploader` interfaces, is not loaded in the airborne companion image. The defense-in-depth software guard is a C12-side `flight_footer.clean_shutdown == True` check (read by `PostLandingUploadOrchestrator` from the post-flight FDR via `FdrFooterReader`); C11 itself no longer gates (Batch 44 SRP refactor). The companion is read-only against C6 in flight; both pre-flight tile fetching and post-landing tile upload happen on the operator workstation.
|
||||
5. **All persistent imagery is in `satellite-provider`'s on-disk tile format** (`./tiles/{zoomLevel}/{x}/{y}.jpg` + matching metadata) so post-landing upload is byte-identical. No raw frames on disk except the AC-8.5 forensic ≤0.1 Hz failed-tile thumbnail log inside FDR.
|
||||
6. **Honest 6×6 posterior covariance via GTSAM `Marginals`** is the safety floor for AC-NEW-4 and AC-NEW-7. Under-reported `horiz_accuracy` is a defect, not a tuning knob.
|
||||
@@ -99,13 +99,13 @@ The system is a **Jetson Orin Nano Super-hosted onboard companion** that deliver
|
||||
| VPR (primary) | UltraVPR | RAL 2025 / ICRA 2026 (cbbhuxx/UltraVPR) | Documentary Lead PRIMARY; rotation-invariant, unsupervised aerial pretrain (multi-heading aerial flight + closes D-C2-1 retrain cost) |
|
||||
| VPR (secondary) | MegaLoc, MixVPR, SelaVPR, EigenPlaces, NetVLAD | upstream HEAD pinned per Plan-phase | Mode B Fact #110/#113 + mandatory simple-baseline (NetVLAD/MixVPR) |
|
||||
| State estimator | GTSAM + `gtsam_unstable.IncrementalFixedLagSmoother` | per Plan-phase pin (no published CVE at audit time) | Native 6×6 covariance; D-C5-5 = (c) `PriorFactorPose3` only |
|
||||
| Image / pose math | OpenCV (Python+C++) | **≥ 4.12.0** | CVE-2025-53644 mitigation (Mode B Fact #112); IPPE flags for D-C4-1 = (b) |
|
||||
| Image / pose math | OpenCV (Python+C++) | **≥ 4.11.0.86, < 4.12** (cycle-1 relaxation; original target ≥ 4.12.0) | CVE-2025-53644 mitigation target was ≥ 4.12.0 (Mode B Fact #112); cycle 1 relaxed the floor because `gtsam==4.2.1` only ships numpy<2 wheels and `opencv-python>=4.12` requires numpy>=2 — see `_docs/_process_leftovers/2026-05-11_d_cross_cve_1_opencv_pin_deferred.md`. 4.11.0.86 is in the supported 4.x line and receives security patches; the ≥ 4.12.0 pin replays once gtsam ships numpy-2 wheels or an alternative SE(3) backend lands. IPPE flags for D-C4-1 = (b) unaffected. |
|
||||
| VPR descriptor index | FAISS HNSW | upstream HEAD pinned per Plan-phase | `faiss.write_index` + atomicwrites + SHA-256 content-hash gate (D-C10-3) |
|
||||
| FC adapter (ArduPilot) | `pymavlink` + MAVLink 2.0 signing | bundled unmodified per D-C8-3 | Verified Source #4; ArduPilot canonical signing per Source #128 |
|
||||
| FC adapter (iNav) | YAMSPy + INAV-Toolkit MSP2 | MIT throughout | iNav has no inbound MAVLink ext-positioning handler (SQ6) |
|
||||
| VIO (production) | OKVIS2 (BSD-3-Clause) | upstream HEAD pinned per Plan-phase | D-C1-1-SUB-A = (a) production-default |
|
||||
| VIO (research / IT-12) | VINS-Mono | upstream HEAD pinned per Plan-phase | Research binary only (`BUILD_VINS_MONO=ON`) for IT-12 comparative study; build-time exclusion from deployment binary per ADR-002 |
|
||||
| VIO (mandatory baseline) | KLT+RANSAC over OpenCV | OpenCV ≥ 4.12.0 | Engine-rule-required mandatory simple-baseline |
|
||||
| VIO (production) | OKVIS2 (BSD-3-Clause) | upstream HEAD pinned per Plan-phase | D-C1-1-SUB-A = (a) architecturally-nominated production-default. **Cycle-1**: AZ-332 BLOCKED — facade + pybind11 skeleton ship; first `add_frame` raises until Tier-2 prerequisites (CI build env + Jetson hardware + DBoW2 vocab) and AZ-592 follow-up land. |
|
||||
| VIO (research / IT-12) | VINS-Mono | upstream HEAD pinned per Plan-phase | Research binary only (`BUILD_VINS_MONO=ON`) for IT-12 comparative study; build-time exclusion from deployment binary per ADR-002. **Cycle-1**: AZ-333 BLOCKED — same skeleton-only state as AZ-332, plus pending upstream-vendoring decision (HKUST + ROS-strip vs. community fork); AZ-593 follow-up. |
|
||||
| VIO (mandatory baseline) | KLT+RANSAC over OpenCV | OpenCV ≥ 4.11.0.86 (cycle-1 relaxation; see OpenCV row) | Engine-rule-required mandatory simple-baseline. **Cycle-1**: serves as the operational airborne `VioStrategy` default while AZ-332 / AZ-333 remain BLOCKED. |
|
||||
| Tile cache backend | PostgreSQL + filesystem | PostgreSQL 16 (mirror of `satellite-provider`) | C6 mirrors `satellite-provider`'s on-disk and table layout so C11 `TileUploader`'s post-landing payload is byte-identical to what the parent suite already serves |
|
||||
| Container runtime | Docker (Tier-1) + bare JetPack (Tier-2) | Docker 27.x; JetPack 6.2 | Tier-1 workstation Docker; Tier-2 Jetson native (no Docker — direct JetPack to keep INT8 calibration cache trustworthy per D-C10-6) |
|
||||
| Build system | CMake + Python `pyproject.toml` | CMake ≥ 3.27 | CMake `option(BUILD_VINS_MONO ...)` D-C1-1-SUB-A; Python wheels built per Jetson via cibuildwheel-equivalent recipe |
|
||||
@@ -297,7 +297,7 @@ The onboard side of D-PROJ-2 is fully specified in `_docs/_process_leftovers/202
|
||||
| Visual blackout failsafe (AC-NEW-8) | Mode transition ≤ 400 ms; covariance grows monotonically; spoofed GPS never re-promoted without 10 s + visual consistency gate | FT-N-04 + NFT-RES-04 | High | `tests/resilience-tests.md` + `tests/blackbox-tests.md` |
|
||||
| Cross-FC covariance honesty (AC-NEW-4 cross-FC) | `horiz_accuracy` (m, AP) and `hPosAccuracy` (mm, iNav) carry mathematically equivalent values from the same 2×2 sub-matrix | IT-10 cross-FC | High | `tests/blackbox-tests.md` |
|
||||
| MAVLink message-signing posture (AC-4.3 + D-C8-9) | Signing enabled on AP wired channel; per-flight key rotation logged to FDR; iNav documented residual risk | NFT-8 + NFT-SEC-03 | High | `tests/security-tests.md` |
|
||||
| Dependency CVE pinning (D-CROSS-CVE-1) | OpenCV ≥ 4.12.0; SBOM clean of unpatched CVEs at audit time; monthly re-scan | NFT-10 SBOM CVE audit | High | `tests/security-tests.md` |
|
||||
| Dependency CVE pinning (D-CROSS-CVE-1) | Target: OpenCV ≥ 4.12.0; SBOM clean of unpatched CVEs at audit time; monthly re-scan. **Cycle-1**: relaxed to `>=4.11.0.86,<4.12` per `_docs/_process_leftovers/2026-05-11_d_cross_cve_1_opencv_pin_deferred.md` (gtsam-4.2.1/numpy-1.x ABI block); CVE-2025-53644 to be re-validated against 4.11.0.86 before close. | NFT-10 SBOM CVE audit | High | `tests/security-tests.md` |
|
||||
| GCS bandwidth budget (AC-6.1) | 1–2 Hz downsampled summary | FT-P-12 | Medium | `tests/blackbox-tests.md` |
|
||||
| Frame-by-frame streaming (AC-4.4) | No batching/delay; estimates emitted per frame | NFT-PERF-02 | High | `tests/performance-tests.md` |
|
||||
| Smoothing-loop look-back (AC-4.5, Mode B Fact #107) | FDR contains smoothed past-frame estimates; smoothing horizon converges within X m of ground truth at K = 10–20 keyframes | IT-11 | Medium | `tests/blackbox-tests.md` |
|
||||
@@ -375,6 +375,8 @@ The onboard side of D-PROJ-2 is fully specified in `_docs/_process_leftovers/202
|
||||
|
||||
**Consequences**: A flight is locked to one VIO; failure of the active strategy = AC-5.2 fallback (FC IMU-only). The comparative study is a per-replay artifact, not a runtime decision.
|
||||
|
||||
**Cycle-1 operational note (2026-05-19, post-Implement)**: AZ-332 (OKVIS2) and AZ-333 (VINS-Mono) shipped as facade-only with `BLOCKED` terminal classification per the implement skill's PASS-with-BLOCKED policy (Tier-2 prerequisites: CI build env + Jetson hardware + DBoW2 vocab artifact for AZ-332; same plus upstream-vendoring decision for AZ-333). The `_STRATEGY_REGISTRY` (see ADR-009 cycle-1 note below) registers all three slots so the seam stays correct, but selecting `okvis2` or `vins_mono` raises `StrategyNotAvailableError` from `vio_factory.py` until the gating `BUILD_*` flag turns on. The cycle-1 production-default selection is **`klt_ransac`** (AZ-334). Follow-ups: **AZ-592** (Tier-2 OKVIS2 wiring) and **AZ-593** (VINS-Mono vendoring + wiring) — both parked in `_docs/02_tasks/backlog/`. Closed Won't-Fix during cycle 1: AZ-589 + AZ-590 (original remediation — they targeted upstream APIs that don't exist in the actually-checked-in OKVIS2 submodule). Full post-mortem in `_docs/03_implementation/implementation_completeness_cycle1_report.md` § "Verdict — Revised 2026-05-16".
|
||||
|
||||
### ADR-002 — Build-time exclusion of unused `Strategy` implementations (D-C1-1-SUB-A = (a))
|
||||
|
||||
**Context**: The architecture deliberately requires multiple interchangeable implementations per component (three `VioStrategy` for C1; multiple `VprStrategy` for C2; two FC adapters for C8). At runtime each binary uses exactly one of them per component. Linking *all* implementations into every binary would inflate binary size on the 8 GB shared Jetson, increase boot/load time inside the AC-NEW-1 ≤ 30 s p95 budget, expand the deployed dependency / attack surface, and create accidental-selection risk (a misconfigured runtime accidentally booting a non-deployment-default strategy). A single binary with all strategies present is also harder to reason about for the IT-12 comparative study, which deliberately wants the *opposite* — every strategy present and replayed against the same footage.
|
||||
@@ -620,6 +622,28 @@ This decision is made on **technical grounds only**. Component licenses (BSD/Apa
|
||||
|
||||
The ADR-009 "interface, not concrete" rule has an architectural sibling: cross-component imports go through `_types/*.py` (DTOs + typed-error envelopes such as `_types.inference_errors`), never through `components.X (Public API)`. The only exception is `runtime_root/*` (the composition root), which is allowed to import concrete strategies across components precisely because it is the single place that resolves Protocol parameters to concrete classes. Every other module under `components/**/*.py` consumes cross-component contracts via (a) shared DTOs in `_types/*`, and (b) consumer-side structural `Protocol` cuts defined locally inside the consuming component (e.g. `c10_provisioning.engine_compiler.CompileEngineCallable` for the narrow `compile_engine` surface of the C7 InferenceRuntime). This is the same architectural property as constructor-injection-against-interface, applied to the import graph rather than the call graph. The AZ-270 `test_az270_compose_root.test_ac6_only_compose_root_imports_concrete_strategies` lint enforces this on every `components/**/*.py`; AZ-507 reconciles `module-layout.md` with the lint so the documentation and the build gate agree.
|
||||
|
||||
#### Cycle-1 implementation: `_STRATEGY_REGISTRY` + `pre_constructed` (AZ-591, AZ-618)
|
||||
|
||||
Two cross-cutting Tier-1 mechanisms shipped inside `runtime_root/` during cycle 1 that the Plan-era ADR-009 sketch did not anticipate. Both are operational prerequisites for `compose_root()` reaching takeoff and are extensions of — not deviations from — the constructor-injection-against-interface rule above.
|
||||
|
||||
1. **`_STRATEGY_REGISTRY` + `register_strategy(...)` API (AZ-591).** A module-level `dict[(component_slug, strategy_name)] → _Registration]` populated per-binary. The airborne entrypoint calls `runtime_root.airborne_bootstrap.register_airborne_strategies()` once at process start, which fills 7 strategy-selecting airborne component slots (`c1_vio`, `c2_vpr`, `c2_5_rerank`, `c3_matcher`, `c3_5_adhop`, `c4_pose`, `c5_state`) with `tier="airborne"`. Without this, `compose_root()` raises `StrategyNotLinkedError` on the first config-driven strategy lookup. The registry is the **runtime-side complement to ADR-002 build-time exclusion**: the build chooses which strategies are even available to register; the registry chooses which one this binary serves; the config chooses which registered slot to wire. A misconfigured runtime asking for an unlinked strategy still fails fast (`StrategyNotLinkedError` carries the offending strategy name + component slug + actually-linked alternatives — operator gets a clear next step). The `register_strategy` call site is restricted by lint (AZ-270): only the composition root or a binary-specific bootstrap module may call it; calls from component modules are an architecture violation.
|
||||
|
||||
2. **`pre_constructed` kwarg + `build_pre_constructed(config)` (AZ-618 umbrella → subtasks AZ-619..AZ-624).** `compose_root(config, *, pre_constructed=...)` now accepts a dict of pre-built infrastructure objects keyed by documented strategy slug, consumed by the airborne wrapper factories registered in step 1. The airborne entrypoint builds these via `airborne_bootstrap.build_pre_constructed(config)` in 6 dependency-ordered phases:
|
||||
|
||||
| Phase | Slugs seeded | Notes |
|
||||
|-------|--------------|-------|
|
||||
| A (AZ-619) | `c13_fdr`, `clock` | `c13_fdr` is per-producer-cached; `clock` is fresh `WallClock` |
|
||||
| B (AZ-620) | `c6_descriptor_index`, `c6_tile_store` | gated on `BUILD_FAISS_INDEX` per consumer |
|
||||
| C (AZ-621) | `c7_inference` | gated on `BUILD_TENSORRT_RUNTIME` / `BUILD_PYTORCH_FP16_RUNTIME` |
|
||||
| D (AZ-622) | `c3_lightglue_runtime`, `c3_feature_extractor` | LightGlue runtime reuses Phase C `c7_inference` engine (no double build); gated on `C3_MATCHER_BUILD_FLAGS[strategy]` |
|
||||
| E (AZ-623) | `c282_ransac_filter`, `c5_imu_preintegrator`, `c5_se3_utils`, `c5_wgs_converter` | IMU preintegrator cached at module level keyed by camera-calibration path |
|
||||
| E.5 (AZ-625) | `c5_isam2_graph_handle` (+ internal `_c5_prebuilt_estimator`) | eager `(StateEstimator, ISam2GraphHandle)` build so C4 receives the handle (C4 runs before C5 in topo order) and the C5 wrapper short-circuits without re-invoking the factory; gated on `C5_STATE_BUILD_FLAGS[strategy]` |
|
||||
| F (AZ-624) | (no slot keys; wires `runtime_root.main()` and verifies AC-1..AC-5 end-to-end) | terminal phase |
|
||||
|
||||
The expected per-component dependency keys are documented in `airborne_bootstrap.AIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYS`. Missing keys raise `AirborneBootstrapError` with the missing-key name + the consuming component slug + the relevant gating `BUILD_*` flag, so the operator-facing error names exactly which build flag or which input is wrong. Tests stub by passing the same `pre_constructed=...` kwarg with mock objects; the bootstrap's caching makes two calls within a process return the same `c13_fdr` object (AC-619.2) without changing the contract. In replay mode (ADR-011), `compose_root` merges replay-built `frame_source` / `fc_adapter` / `clock` / `mavlink_transport` / `replay_sink` over `pre_constructed` so the replay branch's `TlogDerivedClock` correctly overrides the bootstrap's `WallClock`. AZ-687 added a guard for the minimal replay `Config` that omits strategy-component blocks — the bootstrap skips the `_build_c6_*` / `_build_c7_*` / `_build_c5_*` seeds when their component block is absent, since the corresponding wrappers do not run.
|
||||
|
||||
Both additions sit inside `runtime_root/`; no component crosses the AZ-507 import boundary. They preserve every ADR-009 invariant — interface-first components, constructor-injected dependencies, single composition root, build-time-exclusion-as-architectural-property — and add the runtime mechanics needed to make a 12+ infrastructure-dependency graph wirable without losing fail-fast behaviour. `module-layout.md` § shared/runtime_root carries the file-level ownership; this section is the architectural rationale.
|
||||
|
||||
### ADR-010 — Operator-planned mission is the cold-start trust anchor; FC GPS is secondary
|
||||
|
||||
**Context**: The original cold-start design (AZ-419 / FT-P-11) assumed the FC EKF's last valid GPS fix is available at takeoff to seed C5. Field reality contradicts this: a UAV operating in a contested-EW environment may have GPS jammed **before** takeoff (the jamming radius reaches the launch site, the unit launches under a jammer's umbrella, etc.). In that case the FC EKF has no GPS fix to give, and the companion has nothing to anchor the initial pose to — the entire downstream pipeline (VIO bootstrap, VPR retrieval scope, satellite anchoring) collapses or runs blind. At the same time, the parent suite already requires the operator to author a route in the **Mission Planner UI** (`suite/ui`) and persist it to the **`flights` REST service** (`suite/flights`) before any flight runs. The waypoint ordering is operationally meaningful: waypoint[0] is the planned takeoff point. The operator therefore already declares the takeoff position with operationally relevant accuracy (typically a few tens of metres) hours before launch, in a context that has no dependency on GPS at all. This information is the natural cold-start trust anchor.
|
||||
|
||||
@@ -397,10 +397,15 @@ Bootstrap reference: `_docs/02_tasks/todo/AZ-263_initial_structure.md`. Architec
|
||||
|
||||
### shared/runtime_root
|
||||
|
||||
- **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; serves both `config.mode == "live"` and `config.mode == "replay"` per ADR-011) and `compose_operator(config)` (operator-orchestrator). No separate `compose_replay` function — replay is a configuration of `compose_root`, not a sibling composition root.
|
||||
- **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 replay-mode branch of `compose_root` is owned by AZ-401.
|
||||
- **Consumed by**: the airborne binary entrypoint (live + replay modes), the operator-orchestrator binary entrypoint, and the research/comparative binary entrypoint.
|
||||
- **Package**: `src/gps_denied_onboard/runtime_root/` (Python package; a single-file layout was the Plan-era sketch — cycle 1 grew it into a package because the airborne bootstrap, the registry seam, and the per-component factories each have non-trivial concerns and own their own tests).
|
||||
- **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.
|
||||
- **Public surface (cycle-1)**:
|
||||
- `__init__.py` — hosts `compose_root(config, *, pre_constructed=...)` (airborne; serves both `config.mode == "live"` and `config.mode == "replay"` per ADR-011) and `compose_operator(config)` (operator-orchestrator). Also owns the module-level `_STRATEGY_REGISTRY` dict, the `register_strategy(...)` API (AZ-591), and the `StrategyNotLinkedError` envelope. No separate `compose_replay` function — replay is a configuration of `compose_root`, not a sibling composition root.
|
||||
- `airborne_bootstrap.py` — `register_airborne_strategies()` populates the 7 airborne strategy slots in `_STRATEGY_REGISTRY`; `build_pre_constructed(config)` builds the airborne 12-key infrastructure dict in 6 dependency-ordered phases (A→F); `AIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYS` is the documented per-component dependency map; `AirborneBootstrapError` envelope. See architecture.md § ADR-009 cycle-1 implementation note for the rationale.
|
||||
- `_replay_branch.py` — replay-only frame source / FC adapter / clock / mavlink transport / replay sink wiring; merged over `pre_constructed` by `compose_root` (replay entries take precedence — they own the replay-only seam per ADR-011).
|
||||
- Per-component factory modules (`c10_factory.py`, `c11_factory.py`, `c12_factory.py`, `clock_factory.py`, `fc_factory.py`, `frame_source_factory.py`, `inference_factory.py`, `matcher_factory.py`, `pose_factory.py`, `refiner_factory.py`, `rerank_factory.py`, `state_factory.py`, `storage_factory.py`, `vio_factory.py`, `vpr_factory.py`, `warm_start_wiring.py`, `spoof_recovery_sink.py`, `errors.py`) — each builds one component's strategies behind that component's `BUILD_*` flag gates.
|
||||
- **Owned by**: AZ-263 (Bootstrap stub) for the package skeleton; AZ-591 owns `_STRATEGY_REGISTRY` + `register_strategy`; AZ-618 (umbrella → AZ-619..AZ-624) owns `airborne_bootstrap.py` + `build_pre_constructed` + per-phase seeds; AZ-625 owns the eager `(StateEstimator, ISam2GraphHandle)` build (Phase E.5); AZ-687 owns the replay-mode component-block guard. Per-component additions that wire a new strategy are owned jointly by the bootstrap epic and the consuming component task (touching the package is allowed only via the explicit "wire-in" task in each component's epic). The replay-mode branch of `compose_root` is owned by AZ-401.
|
||||
- **Consumed by**: the airborne binary entrypoint (live + replay modes), the operator-orchestrator binary entrypoint, and the research/comparative binary entrypoint. Tests stub the registry via `clear_strategy_registry()` and the infrastructure dict via the same `pre_constructed=...` kwarg the production caller uses.
|
||||
|
||||
### shared/cli/replay
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ step: 13
|
||||
name: Update Docs
|
||||
status: in_progress
|
||||
sub_step:
|
||||
phase: 5
|
||||
name: system-level-updates
|
||||
detail: "FINAL_report.md + glossary.md + ripple_log_cycle1.md done; architecture.md + module-layout.md + 14 components + 8 helpers + tests/ DEFERRED to next session"
|
||||
phase: 6
|
||||
name: component-doc-updates
|
||||
detail: "item-1 done (architecture.md + module-layout.md; system-flows.md no-op); items 2-4 deferred (C1 description, 13 components, 8 helpers, tests/)"
|
||||
retry_count: 0
|
||||
cycle: 1
|
||||
tracker: jira
|
||||
|
||||
Reference in New Issue
Block a user