# Component Fit Matrix — Cross-component process gates

> Mode A Phase 2 — engine Step 7.5 (Component Applicability Gate). Plan-phase Choose blocks raised by C1, C2, C3, C4, C5, C6, C7, C8, and C10 closures. Each gate names its owner and the resolution path. Backing fact cards live in [`../02_fact_cards/`](../02_fact_cards/) by component.
>
> Index: [`00_summary.md`](00_summary.md). Per-component rows: [C1](C1_vio.md), [C2](C2_vpr.md), [C3](C3_matchers.md), [C4](C4_pose_estimation.md), [C5](C5_state_estimator.md), [C6](C6_tile_cache_spatial_index.md), [C7](C7_inference_runtime.md), [C8](C8_fc_adapter.md), [C10](C10_preflight_provisioning.md). C9 dropped per 2026-05-08 restructure — see `../00_question_decomposition.md`.

---

## Cross-component process gates open (raised this session and prior)

| Gate | Owner | Resolution path |
|---|---|---|
| **D-C1-1 GPL-3.0 license posture** | User | Plan-phase Choose block (A/B/C) before any C1 candidate is locked Selected |
| **D-C1-2 Jetson Orin Nano Super hardware MVE phase** | Project bring-up team | Dedicated bring-up phase between research and Plan; produces single Jetson-MVE artifact that promotes Documentary leads to Selected (covers C1 AND C2 candidates per D-C2-4) |
| **Fact #40: single-rate vs dual-rate nav-camera pipeline** | Plan-phase architect | Plan-time decision; affects C1 candidate ranking; affects C2/C3 candidate scoring |
| **D-C2-1 VPR canonical-weights vs aerial-retrain vs aerial-community-checkpoint** (raised by MixVPR closure 2026-05-08; reaffirmed by SALAD + SelaVPR closures) | User + Plan-phase architect | Plan-phase Choose block (A/B/C) before any C2 candidate is locked Selected; applies to **every** ground-level-pretrained C2 candidate (MixVPR + SALAD + SelaVPR all street-view-trained); SelaVPR README recommends MSLS-finetuned variant for "diverse scenes" cross-domain transfer as default |
| **D-C2-2 descriptor-cache carve-out vs raw-tile-cache budget** (raised by MixVPR closure 2026-05-08; harshened by SALAD; **materially-changed-shape by SelaVPR**) | Plan-phase architect | Plan-time decision; AC-8.3 explicitly requires this. **Per-candidate global-descriptor cache**: SelaVPR 1024-D ~3.2% (smallest); MixVPR 2048-D ~6.5%; SALAD-slim 544-D ~1.7%; SALAD-full 8448-D ~27%. **NEW SelaVPR local-feature-cache pressure**: ~150 GB if naive cache → forces D-C2-7 mitigation choice. Conditional candidates (AnyLoc/BoQ/DINOv2-VLAD) at higher dimensionality push descriptor cache to ~10 GB alone, forcing carve-out |
| **D-C2-3 input-resolution shape (224×224 vs 320×320 vs 322×322 vs higher)** (raised by MixVPR closure 2026-05-08; harshened by SelaVPR's 224×224) | Plan-phase architect | Plan-phase decision after all C2 candidates have per-Mode entries; trade-off span: SelaVPR's 224×224 (most aggressive downscale) → MixVPR's 320×320 / SALAD's 322×322 (medium) → AnyLoc/BoQ at 322+ ViT (highest, next sessions) |
| **D-C2-4 deferred Jetson Orin Nano Super hardware MVE phase coverage for C2** (raised by MixVPR closure 2026-05-08; scope-broadened by SALAD; **broadened further by SelaVPR**) | Project bring-up team | Same artifact as D-C1-2 must produce per-C2-candidate latency + memory + AerialExtreMatch Recall@K numbers + DINOv2 ViT-B AND ViT-L → TensorRT fp16/INT8 export quality + SelaVPR two-stage re-ranking latency profile + on-demand local-feature extraction performance |
| **D-C2-5 DINOv2 ViT-export to TensorRT fp16/INT8 path on Jetson Orin Nano Super** (raised by SALAD closure 2026-05-08; **harshened by SelaVPR closure**) | Project bring-up team + C7 inference-runtime owner | Jetson MVE phase must validate DINOv2-B AND DINOv2-L export paths before any ViT-based C2 candidate (SALAD, SelaVPR, AnyLoc, BoQ, DINOv2-VLAD) advances from Documentary lead to Selected. SelaVPR's ViT-L is 3.5× larger than SALAD's ViT-B; counter-mitigation by SelaVPR's frozen-backbone canonical export pathway (FB AI Public Files distribution) |
| **D-C2-6 SALAD descriptor-size choice (8448-D / 2112-D / 544-D)** (raised by SALAD closure 2026-05-08; SALAD-only, does not apply to SelaVPR) | Plan-phase architect | Plan-time decision; full variant best R@1 but consumes ~27% of AC-8.3 cache budget; slim 544-D fits within 1.7% but loses ~5 R@1 points on MSLS Challenge. Interacts with D-C2-2 carve-out decision |
| **D-C2-7 SelaVPR re-ranking strategy choice (full re-rank with on-demand local-feature extraction / cache top-K local features per likely query path / disable re-ranking entirely and use SelaVPR-global-only mode)** (NEW from SelaVPR closure 2026-05-08; SelaVPR-only, first two-stage C2 candidate) | Plan-phase architect | Plan-time decision conditional on SelaVPR being elevated to Selected. Full re-rank at rerank_num=100 fails AC-4.1 latency budget on Jetson extrapolation; rerank_num=20 fits but tight; on-demand local-feature extraction + global-only-cache (~320 MB) is most cache-efficient; precompute-top-K-local-features (~3 GB at K=20 with selective coverage) is moderate; disable-rerank gives single-stage parity (MSLS-challenge R@1=69.6 vs full's 73.5, still ahead of MixVPR's 64.0). **Three-way interaction with D-C2-2 + AC-8.3 + AC-4.1** |
| **D-C2-8 NetVLAD PyTorch-port-strategy choice (Nanne/pytorch-NetVlad with license-uncertainty / re-port from canonical Relja/netvlad with MIT preservation / OpenVPRLab-NetVLAD-on-ResNet50 as separately-cataloged sibling mode)** (NEW from NetVLAD closure 2026-05-08; NetVLAD-only, first canonical-MATLAB-stack C2 candidate) | Plan-phase architect + license-posture decision-maker | Plan-time decision; canonical implementation is MATLAB + MatConvNet (not deployable on JetPack 6) — PyTorch port required. Nanne port is fastest path but README does NOT cite a LICENSE file → Plan-phase verification gate is a hard prerequisite before adoption; re-port from canonical Relja/netvlad MATLAB to PyTorch directly preserves MIT licensing alignment with MixVPR + SelaVPR on the BSD/permissive track but requires ~1 week of engineering + cluster-init prerequisite + retraining or weight-transfer; OpenVPRLab-NetVLAD-on-ResNet50 is apples-to-apples vs MixVPR but is a *different mode* per Per-Mode API rule (different backbone, different pretrained checkpoint provenance) and would be cataloged as a separate sibling candidate. **Recommendation: re-port from canonical** to preserve MIT licensing alignment |
| **D-C2-9 NetVLAD descriptor-dimension choice (canonical 4096-D PCA-whitened / 512-D `cropToDim` for tighter cache / 256-D `cropToDim` for tightest cache)** (NEW from NetVLAD closure 2026-05-08; NetVLAD-only; analogous to D-C2-6 SALAD descriptor-size choice but for NetVLAD's PCA-whitened output) | Plan-phase architect | Plan-time decision; canonical 4096-D consumes ~1.3 GB / 13% of 10 GB AC-8.3 cache budget — **largest single-stage descriptor cache** of any C2 candidate evaluated so far; 512-D `cropToDim` reduces to ~160 MB / 1.6% at additional Recall@K loss; 256-D `cropToDim` reduces to ~80 MB / 0.8% at further loss. Only valid for `+whitening` networks. Interacts with D-C2-2 carve-out decision. Given NetVLAD's mandatory-baseline role (NOT a competitive lead), the 256-D / 512-D `cropToDim` variants may be more appropriate to free cache budget for the modern lead's larger descriptor — but Plan must decide explicitly |
| **D-C2-10 EigenPlaces descriptor-dimension choice (canonical 2048-D / 512-D / 256-D / 128-D — eleven backbone+dim sibling modes PyTorch-Hub-distributed)** (NEW from EigenPlaces closure 2026-05-08; EigenPlaces-only; analogous to D-C2-6 SALAD and D-C2-9 NetVLAD descriptor-dimension choices) | Plan-phase architect | Plan-time decision; canonical ResNet-50 + 2048-D consumes ~650 MB / 6.5% of AC-8.3 cache budget (identical to MixVPR-2048 for direct apples-to-apples comparison); 512-D variant reduces to ~160 MB / 1.6% at modest Recall@1 loss (paper Tab 3: Pitts30k 91.9 at 512 vs 92.5 at 2048 = -0.6, Tokyo24/7 89.8 at 512 vs 93.0 at 2048 = -3.2 — extreme cross-domain hurts most); 256-D reduces to ~80 MB / 0.8% at moderate Recall@K loss; 128-D reduces to ~40 MB / 0.4% at substantial Recall@K loss on cross-domain (paper §4.3 explicit observation). Eleven canonical pretrained checkpoints PyTorch-Hub-distributed give the project the widest range of cache-footprint sibling modes of any C2 candidate evaluated. Interacts with D-C2-2 carve-out decision |
| **D-C2-11 (CONDITIONAL) MegaLoc successor evaluation as separately-cataloged sibling candidate** (NEW from EigenPlaces closure 2026-05-08; raised by canonical EigenPlaces README explicit pointer "EigenPlaces is quite old. Looking for SOTA Visual Place Recognition (VPR)? Check out MegaLoc") | User + Plan-phase architect | Plan-phase decision: (a) treat MegaLoc as a separately-cataloged sibling candidate at Plan time (would require its own per-mode API capability verification + sub-matrix), (b) defer MegaLoc evaluation to a post-research session if EigenPlaces fails Jetson MVE, (c) skip MegaLoc and rely on the closed mandatory pre-screen (5/5: MixVPR + SALAD + SelaVPR + NetVLAD + EigenPlaces). **Recommendation**: defer to post-research session — EigenPlaces closes the mandatory pre-screen at the documentary-required floor, and MegaLoc's Plan-phase relevance depends on which D-C1-1 license-track is chosen and how Jetson MVE results land |
| **D-C1-1 license-posture interaction with C2** (already raised by C1; sharpened by SALAD-GPL-3.0; materially-positive update from SelaVPR-MIT 2026-05-08; further-positive update from NetVLAD-MIT canonical 2026-05-08 with Nanne-port license-uncertainty Plan-phase verification gate; **fully-positive update from EigenPlaces-MIT 2026-05-08 closing the BSD/permissive C2 axis**) | User + Plan-phase architect | **BSD/permissive C2 axis (mandatory pre-screen COMPLETE 2026-05-08)** (under D-C1-1 = (b) or default (c)): MixVPR (CNN-ResNet50 + MLP-Mixer, MIT) + **SelaVPR (DINOv2 ViT-L/14 two-stage, MIT)** + **NetVLAD (CNN-VGG16 + soft-assignment-VLAD, MIT canonical / license-uncertain Nanne PyTorch port — D-C2-8 verification gate, mandatory simple-baseline)** + **EigenPlaces (CNN-ResNet50 + GeM + FC viewpoint-robust training paradigm, MIT)**. **GPL-3.0 C2 axis** (under D-C1-1 = (a) or default (c)): SALAD (DINOv2 ViT-B + optimal-transport, GPL-3.0) + (conditional next-sessions: AnyLoc/BoQ/DINOv2-VLAD pending license verification + INT8 quantization survey prerequisite). EigenPlaces's MIT-canonical placement materially completes the BSD/permissive C2 axis with **four materially-different design points** spanning 2016 (NetVLAD baseline VLAD) → 2023 (MixVPR ResNet50+MLP-Mixer) → 2023 (EigenPlaces ResNet50+GeM+viewpoint-robust-training) → 2024 (SelaVPR DINOv2-L+two-stage). The BSD/permissive C2 axis now has the **most diverse design-point coverage of any license track in any component row in the project** |
| **D-C3-1 (NEW from SP+LightGlue closure 2026-05-08) — SuperPoint-replacement-strategy choice (DISK+LightGlue with Apache-2.0 + paper Table 6 superiority [RECOMMENDED] / ALIKED+LightGlue with BSD-3-Clause+Apache-2.0 / SuperPoint-reproduction-with-permissive-license / accept-Magic-Leap-noncommercial-with-swap-commitment / SIFT+LightGlue classical-baseline-fallback)** | User + Plan-phase architect + license-posture decision-maker | Mandatory Plan-phase decision; canonical SuperPoint pretrained weights LICENSE (Source #72 Magic Leap noncommercial-research-only Software License Agreement) is a **HARD DISQUALIFIER** on the canonical SP+LightGlue mode in the project's dual-use deployment context (eastern/southern Ukraine fixed-wing UAV with AC-NEW-2 spoofing-promotion path is dual-use military by every reasonable interpretation, and the project's question_decomposition.md hard disqualifier list includes "anything whose license blocks military / dual-use deployment"). **Recommendation: D-C3-1 = (a) DISK+LightGlue** — Apache-2.0 throughout AND paper Appendix A Table 6 documentary technical superiority over canonical SP+LightGlue (+7.99 absolute AUC@5° on IMC 2020 stereo). Interacts with D-C1-1 (license-posture overall) + D-C2-1 (aerial-domain training, since DISK+LightGlue retrain is the cleanest license-compliant + retrain-friendly pathway) |
| **D-C3-2 (NEW from SP+LightGlue closure 2026-05-08) — LightGlue-inference-runtime choice (PyTorch-fp16 / Torch-TensorRT / ONNX Runtime + TensorRT EP via Source #73 / pure TensorRT via trtexec + Polygraphy via Source #73 / FP8 ModelOpt-on-Jetson if Ampere FP8 emulation works)** | Project bring-up team + C7 inference-runtime owner | Plan-phase decision conditional on D-C3-1 lock + Jetson MVE results; Source #73 (`fabio-sim/LightGlue-ONNX`) is the canonical reference for ONNX / TensorRT / OpenVINO / FP16 / FP8 export pathway with January 2026 active maintenance. **CRITICAL Jetson Orin Nano Super FP8 emulation gate**: Source #73 documents FP8 ModelOpt workflow on Hopper/Ada/Blackwell — Jetson Orin Nano Super is Ampere architecture (NOT FP8-native); FP8 ModelOpt path applies only with INT8 emulation fallback (verification at Jetson MVE phase). Likely rolls into the C7 cross-cutting integration row |
| **D-C3-3 (NEW from SP+LightGlue closure 2026-05-08) — K-pairs-per-frame budget choice (reduce K from 10 to 3-5 / reduce keypoints from 1024 to 512 / accept TIGHT 300-600 ms standard ÷ 150-300 ms adaptive margin and validate at Jetson MVE / parallelize matcher across multiple Jetson GPU streams / elevate ONNX Runtime + TensorRT EP + adaptive depth)** | Plan-phase architect | Plan-phase decision; canonical RTX-3080 throughput 150 FPS @ 1024 keypoints with adaptivity → Jetson Orin Nano Super extrapolation ~30-60 ms per pair → at K=10 top-K retrieval pairs per UAV frame = 300-600 ms standard / 150-300 ms adaptive against AC-4.1 400 ms budget — TIGHT before C1+C2+C5+C8 costs added. **Three-way interaction with AC-4.1 latency budget + AC-3.3 re-localization recall + AC-1.1/1.2 frame-center pose accuracy**. Adaptive-depth path (paper §5.4 1.86× speedup on easy pairs) is the most-favorable structural trade-off if many of the K pairs are high-overlap UAV-vs-cached-tile pairs. **MORE-TIGHT D-C3-3 gate for ALIKED+LightGlue** vs DISK+LightGlue or SP+LightGlue due to PyTorch-fp16-only restriction (ALIKED-export-absence in LightGlue-ONNX) — likely requires K reduction from 10 to 3-5 OR ALIKED-T(16) 64-D sibling mode for AC-4.1 satisfaction |
| **D-C3-4 (NEW from ALIKED+LightGlue closure 2026-05-08) — ALIKED-sibling-mode choice (ALIKED-T(16) 64-D Jetson-friendliest @ 1.37 GFLOPs / ALIKED-N(16) 128-D canonical baseline @ 4.05 GFLOPs / ALIKED-N(16rot) 128-D rotation-augmented @ same arch as N(16) / ALIKED-N(32) 128-D higher-SDDH-sample-count Aachen-best @ 4.62 GFLOPs)** | Plan-phase architect | Plan-phase decision conditional on D-C3-1 = (b) ALIKED+LightGlue secondary mitigation being selected; for project's UAV multi-heading 1 km AGL flights + Jetson PyTorch-fp16-only deployment (forced by ALIKED-export-absence in LightGlue-ONNX), **recommendation is ALIKED-N(16rot)** (rotation-augmentation aligns with multi-heading aerial flights; 4.05 GFLOPs leaves K=10 pairs/frame headroom; same 128-D descriptor as canonical N(16)). ALIKED-T(16) is the latency-fallback if AC-4.1 budget pressure forces 64-D descriptor reduction; ALIKED-N(32) is the accuracy-prioritization choice if Aachen-Day-Night documentary lift is the primary axis (paper Table VII at 2048 keypoints / 0.25m,2° tier = 77.6 best-in-paper). Interacts with D-C3-3 K-pairs-per-frame budget choice (T(16)'s 1.37 GFLOPs allows higher K than N(16)/N(32)'s 4.05/4.62 GFLOPs) |
| **D-C3-5 (NEW from DISK+LightGlue closure 2026-05-08) — DISK-pretrained-weights-choice (`save-depth.pth` canonical default RECOMMENDED / `save-epipolar.pth` supplementary-material alternate -0.5 to -1 absolute AUC trade-off / project-domain retrain on aerial nadir corpus via canonical `colmap/colmap2dataset.py` workflow at ~2 weeks on 32 GB V100 cost)** | Plan-phase architect | Plan-phase decision conditional on D-C3-1 = (a) DISK+LightGlue RECOMMENDED-PRIMARY-MITIGATION being selected; for project's pinned UAV-vs-satellite-tile registration use case **`save-depth.pth` is the recommended canonical default** (strongest documentary IMW2020 stereo + multiview AUC numbers per canonical paper Table 1 + cross-paper Aachen Day-Night transitive lift via ALIKED paper Table VII). `save-epipolar.pth` is the fallback if depth-map ground-truth is unavailable for aerial-domain retrain (paper §4 epipolar reward variant trades 0.5-1 absolute AUC for not requiring depth maps). Interacts with D-C2-1 retrain decision (DISK retrain via `colmap/colmap2dataset.py` is well-documented but materially expensive ~2 weeks on 32 GB V100 / ~2 weeks at smaller batch on 12 GB low-memory variant — vs ALIKED's ~24 hours on RTX 3090) |
| **D-C3-6 (NEW from XFeat closure 2026-05-08) — XFeat-mode-choice (XFeat sparse with MNN matching for SIMPLEST deployment / XFeat\* semi-dense with MNN+MLP-offset-refinement for HIGHEST inlier count per pair / XFeat+LighterGlue paired-matcher for MODERN learned-matcher accuracy)** | Plan-phase architect | Plan-phase decision conditional on XFeat being selected (D-C3-1 ALTERNATE-MODERN-COMPETITIVE-LEAD role alongside DISK+LightGlue's RECOMMENDED-PRIMARY-MITIGATION); for project's pinned UAV-vs-satellite-tile registration use case + AC-NEW-7 cache-poisoning safety budget + AC-3.3 re-localization stability, **(b) XFeat\* semi-dense is the strongest documentary structural choice** (4× more inliers per pair via lightweight MLP refinement provides best RANSAC stability at lowest engineering complexity — no LightGlue dependency, no productized-export dependency). (a) XFeat sparse is SIMPLEST deployment (D-C3-2 fully sidesteps cvg/LightGlue dependency; documentary AUC@5° materially below LightGlue-siblings); (c) XFeat+LighterGlue narrows MegaDepth-1500 gap to -2.5 to -2.8 absolute below SP+LightGlue at the cost of D-C3-2 reuse (community-contribution-needed for productized LighterGlue export pathway). Interacts with D-C2-1 retrain decision (XFeat is the cheapest retrain candidate among all C3 candidates evaluated at 36 hours single RTX 4090 + 6.5 GB VRAM total per Source #81 §3.3) and D-C3-2 (only XFeat+LighterGlue mode reuses D-C3-2 cvg/LightGlue runtime path; sparse + semi-dense modes sidestep entirely) |
| **D-C4-1 (CARRIED FORWARD from Fact #20 C2 closure; REINFORCED by OpenCV `cv::solvePnPRansac` closure 2026-05-08 Fact #52) — 2D-3D-lift architectural decision (3-DoF acceptance with attitude-from-IMU/VIO prior + 2D ortho-only cache / 4-DoF acceptance with flat-earth + altitude-from-IMU+barometer prior + planar-scene homography → 4-DoF pose extraction / 6-DoF via aerial-photogrammetry-DSM-acquisition + paired DSM at 0.94 m/px / 6-DoF via ALOS 30m DSM with 4× accuracy collapse per Source #41)** | User + Plan-phase architect | Plan-phase decision; **for the project's pinned 2D-ortho-only cache + IMU-attitude-prior context, recommendation is (b) 4-DoF flat-earth + IMU+barometer altitude + VIO/IMU attitude → planar-scene homography → 4-DoF pose extraction** — pairs naturally with `flags=SOLVEPNP_IPPE` (Source #83 explicit "Object points must be coplanar" minimal-solver designed for D-C4-1 = 4-DoF flat-earth case); ALOS-30m-DSM secondary mitigation if 4-DoF accuracy proves insufficient at AC-1.1/1.2 50m/20m bars at the tighter tail. **CRITICAL REINFORCEMENT from Fact #52**: solvePnPRansac requires 3D-2D correspondences (Source #83 explicit `objectPoints` Nx3 + `imagePoints` Nx2 signature) — D-C4-1 lift is a HARD prerequisite for ANY C4 candidate (OpenCV / OpenGV / GTSAM-PnP / Theia / Ceres-only), not unique to OpenCV |
| **D-C4-2 (NEW from OpenCV `cv::solvePnPRansac` closure 2026-05-08 Fact #52; UPDATED by GTSAM closure 2026-05-08 Fact #54) — covariance-recovery-strategy choice (post-hoc Jacobian-based via `cv::projectPoints` Jacobian + Schur complement / wrap solvePnPRansac result in GTSAM `Marginals` posterior / project-defined heuristic covariance scaling — likely AC-NEW-4 REJECT / migrate to OpenGV `absolute_pose::optimize_nonlinear` with custom Jacobian propagation through bearing-vector residuals)** | Plan-phase architect | Plan-phase decision; `cv::solvePnPRansac` returns `retval, rvec, tvec, inliers` only (Source #83 function signature); OpenGV's `optimize_nonlinear` has no covariance output API (Source #85) — **NO direct 6×6 covariance output from either OpenCV or OpenGV**. **GTSAM IS THE EXCEPTION**: `Marginals(graph, result).marginalCovariance(pose_key)` emits 6×6 posterior covariance NATIVELY (Source #87 multiple snippets). AC-NEW-4 covariance-honesty contract requires explicit recovery strategy. **Recommendation by primary path**: D-C4-2 = (b) **wrap solvePnPRansac result in GTSAM `Marginals` posterior** via `BetweenFactor<Pose3>` prior + per-inlier `GenericProjectionFactorCal3_S2` factors → `LevenbergMarquardtOptimizer.optimize()` → `Marginals.marginalCovariance` (canonical Plan-phase pathway documented in Fact #54; **STRONGLY RECOMMENDED for the OpenCV-as-RANSAC + GTSAM-as-covariance-recovery hybrid path** — couples Fact #52 mandatory-simple-baseline + Fact #54 modern-competitive-lead-covariance-honest); D-C4-2 = (a) post-hoc Jacobian-based via `cv::projectPoints` Jacobian + Schur complement on inlier residuals (~1 day engineering; pure OpenCV API) for the OpenCV-only-no-GTSAM path if Plan-phase Jetson MVE shows GTSAM's ~30-90 ms latency + ~50-200 MB memory footprint exceeds AC-4.1 / AC-4.2 budgets; D-C4-2 = (c) is likely AC-NEW-4 REJECT; D-C4-2 = (d) couples with D-C4-1 + D-C4-3 + D-C4-4 selection of OpenGV-as-primary at ~3-5 days engineering for OpenGV-internal Jacobian propagation through bearing-vector residuals (harder than OpenCV's pixel Jacobian per Fact #53 closure). **Three-way interaction with AC-NEW-4 covariance-honesty + D-C4-1 lift architectural decision + C5 fusion contract** (Fact #20 + #21 closures) |
| **D-C4-3 (NEW from OpenGV closure 2026-05-08 Fact #53) — license-clearance verification choice (counsel-review of License.txt to confirm BSD-3-Clause-equivalent / request author + ShanghaiTech Mobile Perception Lab to relicense to OSI canonical / treat NOASSERTION as effective disqualifier and pivot to OpenCV-as-primary / elevate D-C4-3 to D-C1-1 and treat OpenGV as eligible only on GPL-3.0 or keep-both-tracks-open)** | License-posture decision-maker + Plan-phase architect | Plan-phase decision conditional on OpenGV being elevated to Selected; Source #84 GitHub API license metadata reports `license.spdx_id: "NOASSERTION"` for canonical `laurentkneip/opengv` repo; Source #84 direct WebFetch of License.txt confirms BSD-3-Clause-equivalent boilerplate (3 numbered redistribution conditions + non-endorsement clause + "Copyright 2013 Laurent Kneip, ANU. All rights reserved." attribution) but the file does NOT use OSI canonical BSD-3-Clause template text. **Recommendation**: D-C4-3 = (a) counsel-review (~1-2 hours legal review) for the OpenGV-as-secondary path; D-C4-3 = (c) pivot to OpenCV-as-primary if Plan-phase Jetson MVE shows OpenCV's mandatory-simple-baseline coverage is sufficient without OpenGV's richer-minimal-solver-coverage. Interacts with D-C4-4 maintenance-staleness mitigation (if D-C4-3 fails, D-C4-4 also pivots to OpenCV-as-primary or Ceres-only fallback) |
| **D-C4-4 (NEW from OpenGV closure 2026-05-08 Fact #53) — maintenance-staleness-mitigation strategy choice (accept-as-is + freeze upstream / fork into project-controlled branch + apply Eigen-3.4+ + JetPack-6 + ARM Cortex-A78AE patches in-house / migrate to Ceres-only manual implementation as fallback / downgrade OpenGV to experimental status and pivot to OpenCV-as-primary)** | Plan-phase architect + project bring-up team | Plan-phase decision conditional on OpenGV being elevated to Selected; Source #84 last pushed 2023-06-07T18:14:14Z = ~2 years 11 months stale at access time 2026-05-08; Doxygen portal generated 2018-01-08 = 8.3 years old documentation; ShanghaiTech Mobile Perception Lab's claimed maintenance contradicted by commit history. **Recommendation**: D-C4-4 = (b) fork-and-patch (~1-2 weeks engineering) for the OpenGV-as-secondary path; D-C4-4 = (d) pivot to OpenCV-as-primary if Plan-phase Jetson MVE shows OpenCV's coverage is sufficient; D-C4-4 = (c) Ceres-only fallback (~2-4 weeks) only if (b) patches not feasible. Interacts with D-C4-3 license-clearance verification |
| **D-C5-1 (NEW from Manual ESKF Solà 2017 closure 2026-05-08 Fact #88) — reference-implementation-license-verification choice (counsel-review of repo for LICENSE file in subdirectory ~1 hour engineering RECOMMENDED first step / treat as GPL-equivalent and write project implementation from Solà 2017 paper directly without code reuse ~1-2 weeks engineering vs ~3-5 days with reference template / contact author for LICENSE clarification ~1-3 weeks turnaround if author responsive)** | License-posture decision-maker + Plan-phase architect | Plan-phase decision conditional on project electing to reuse `ludvigls/ESKF` (Python ESKF for fixed-wing UAVs DIRECTLY MATCHING project hardware family) OR `cggos/imu_x_fusion` (C++/ROS multi-source loosely-coupled fusion) OR `koledickarlo/ESKF-ESP32` (microcontroller-class with explicit Solà 2017 citation) at the source-code level; Source #89 README front-pages do NOT declare LICENSE for these three repos. `EliaTarasov/ESKF` is PX4-derived (PX4 is dual BSD/Apache-2.0, ecl is BSD-3-Clause) so license-clearance is easier. `joansola/slamtb` is MATLAB-only and not deployable on JetPack 6 (algorithmic reference only). **Recommendation**: D-C5-1 = (b) write directly from canonical Solà 2017 paper for cleanest license-compliance story; reference implementations serve as documentary templates (read for understanding, not copy-paste). Final lock at Plan phase after counsel-review per D-C5-1 = (a). Interacts with D-C1-1 license-posture overall |
| **D-C5-2 (NEW from Manual ESKF Solà 2017 closure 2026-05-08 Fact #88) — long-cruise-observability-strategy choice (accept observability degradation in long-cruise segments + monitor via covariance growth + alert operator if covariance > threshold RECOMMENDED / require operator to perform synthetic S-turns periodically every ~30 min to maintain bias observability / tighten bias-stationarity prior — lower IMU bias random-walk noise — at the cost of accepting more bias drift between updates)** | Plan-phase architect | Plan-phase decision; standard EKF/ESKF fusion of IMU + visual measurements requires sufficient excitation (non-pure-rotation, non-zero acceleration) for IMU bias observability per Solà §5.1 reference + classical observability literature. For a fixed-wing UAV in cruise (level flight at ~60 km/h with minimal acceleration), bias drift is the dominant error source; periodic accelerations (turns, climbs, level-to-bank transitions) re-excite observability. **Recommendation**: D-C5-2 = (a) accept + monitor. Mitigation = project's pinned mission profile per restrictions.md provides natural re-excitation via sharp turns up to ±20° bank per AC-3.1 + sharp-turn frames may share <5% overlap per AC-3.2. Covariance growth alert is consistent with AC-NEW-8 blackout failsafe escalation thresholds. **GTSAM iSAM2 Fact #89 partially mitigates** via incremental smoothing's look-back refinement of bias estimates over the entire sliding window (vs Manual ESKF's recursive forward-time-only bias estimation). Applies primarily to Manual ESKF Fact #88; partially-mitigated for GTSAM iSAM2 Fact #89 |
| **D-C5-3 (NEW from GTSAM iSAM2 closure 2026-05-08 Fact #89) — sliding-window-primitive-choice (`gtsam_unstable.IncrementalFixedLagSmoother` with K=10-20 keyframes covering ~3-7 s of recent history RECOMMENDED ~30 minutes engineering / custom marginalization via `ISAM2.marginalizeLeaves(keys_to_marginalize)` ~2-3 days engineering / accept unbounded ISAM2 graph growth simplest ~0 minutes engineering but tested at Jetson MVE phase — likely fails AC-4.2 budget at K_total = 86400 keyframes × ~1 KB per keyframe state = ~86 MB raw + factor-graph overhead)** | Plan-phase architect | Plan-phase decision conditional on D-C5-row final lock including GTSAM iSAM2; `IncrementalFixedLagSmoother` is in `gtsam_unstable` namespace per Source #91 (canonical fixed-lag smoother class but requires opt-in to gtsam_unstable APIs; not in stable `gtsam` namespace). **Recommendation**: D-C5-3 = (a) IncrementalFixedLagSmoother with K=10-20 keyframes covering ~3-7 s of recent history. Interacts with D-C5-5 factor-density-choice (lower K reduces per-update factor count proportionally) |
| **D-C5-4 (NEW from GTSAM iSAM2 closure 2026-05-08 Fact #89) — IMU-gap-handling-strategy choice (accept canonical pattern + monitor + adaptive integration covariance inflation RECOMMENDED ~1 day engineering / restart PIM on detected gaps with conservative initial covariance more aggressive ~3-5 days engineering / buffer IMU samples in a queue with explicit gap-fill via interpolation most aggressive ~1 week engineering)** | Plan-phase architect | Plan-phase decision conditional on D-C5-row final lock including GTSAM iSAM2; `CombinedImuFactor` requires CONTIGUOUS IMU samples between keyframes per Source #90 canonical pattern; if IMU samples are dropped mid-flight (network jitter, MAVLink frame loss), `pim.preintMeasCov()` 9×9 covariance becomes optimistic vs reality. **Recommendation**: D-C5-4 = (a) accept + monitor + adaptive inflation (track `last_imu_timestamp` and inflate `params.setIntegrationCovariance` adaptively if gap > expected). Project's pinned MAVLink IMU pipeline at ~100-200 Hz Pixhawk-class is delivered over UART or USB serial — dropped samples are rare. Interacts with C8 MAVLink/MSP2 FC adapter row (when opened) for IMU-pipeline-jitter characterization |
| **D-C5-5 (NEW from GTSAM iSAM2 closure 2026-05-08 Fact #89) — factor-density-choice (per-correspondence `GenericProjectionFactorCal3DS2` highest fidelity 1000+ factors per keyframe at K=10 image pairs × 100 inliers per pair ~50-150 ms per update on Jetson Orin Nano Super CPU tight AC-4.1 satisfaction / smart-projection-pose-factor canonical landmark-marginalization-at-construction-time 1 factor per landmark per keyframe ~10× speedup at minimal accuracy loss ~5-15 ms per update on Jetson Orin Nano Super CPU / `PriorFactorPose3` only with C4 GTSAM Marginals satellite-anchor 6×6 covariance — couples C4 Fact #54 D-C4-2 = (b) with C5 Fact #89 architectural integration via shared GTSAM substrate ~1 factor per keyframe ~2-5 ms per update on Jetson Orin Nano Super CPU CLEANEST cross-component coupling RECOMMENDED for the GTSAM-as-shared-C4+C5-substrate hybrid path)** | Plan-phase architect | Plan-phase decision conditional on D-C5-row final lock including GTSAM iSAM2; iSAM2 per-update latency depends critically on factor density per keyframe. **Recommendation**: D-C5-5 = (c) for the GTSAM-as-shared-C4+C5-substrate hybrid path (project's recommended C5 architecture per Fact #89 closure); D-C5-5 = (b) for the C5-as-secondary-with-smoothing path if Plan-phase Jetson MVE shows (c) accuracy is insufficient at AC-1.1/1.2 tail. **Three-way interaction with D-C4-2 covariance-recovery-strategy + AC-4.1 latency budget + AC-1.1/1.2 frame-center pose accuracy**. Strongest cross-component lever in the C4+C5 design space — D-C5-5 = (c) operationalizes the GTSAM-shared-substrate architectural advantage identified in C4 Fact #54 + C5 Fact #89 |
| **D-C6-1 (NEW from Cand 1 closure 2026-05-08 Fact #92; mirrored by Cand 2 D-C6-6) — descriptor-storage-format choice (full-precision float32 in `bytea` column ~8 KB/tile-at-2048-D / **halfvec via app-side conversion + storage as 2-byte half-floats ~4 KB/tile-at-2048-D ~50% cache savings ~0-2% Recall@K loss RECOMMENDED** / INT8 quantized + per-vector scale parameter ~1 KB/tile-at-2048-D ~87.5% cache savings + ~1 day engineering for quantization-aware loader)** | Plan-phase architect | Plan-phase decision; trade-off between AC-8.3 cache footprint vs Recall@K accuracy loss vs engineering complexity. **Recommendation**: D-C6-1 = (b) halfvec for descriptor storage at ~2× cache-footprint-saving with ~0-2% Recall@K loss. Interacts with D-C2-9 NetVLAD descriptor-dimension choice + D-C2-10 EigenPlaces descriptor-dimension choice + D-C2-6 SALAD descriptor-size choice + AC-8.3 10 GB cache budget |
| **D-C6-2 (NEW from Cand 1 closure 2026-05-08 Fact #92, Cand-1-only) — FAISS index variant choice for app-side descriptor ANN (`IndexFlatL2` brute-force exact-distance for small caches <10K tiles ~1-3 ms per query / **`IndexHNSWFlat(d, M=32)` graph-based approximate for primary path 100K-1M tiles ~1-3 ms per query w/ efSearch=64 RECOMMENDED** / `IndexIVFFlat` inverted-file approximate w/ training requirement / `IndexIVFPQ` for additional product-quantizer compression at ~10% Recall@K loss)** | Plan-phase architect | Plan-phase decision conditional on Cand 1 (mirror-suite-pattern) being selected as primary; trade-off between memory footprint vs query accuracy vs query latency. **Recommendation**: D-C6-2 = (b) IndexHNSWFlat M=32 for primary path; IndexFlatL2 fallback for small caches per Source #96 contextual guidance |
| **D-C6-3 (NEW from Cand 1 closure 2026-05-08 Fact #92, Cand-1-only, CROSS-COMPONENT with C10) — descriptor-cache-rebuild-trigger strategy (rebuild on every cache modification ~simplest but slow ~5-30 sec per rebuild blocks readiness / incremental add via `index.add()` ~faster but HNSW does not support delete cleanly per Source #96 / **periodic rebuild during pre-flight provisioning ~most robust requires C10 coordination + serialize via `faiss.write_index` + reload at takeoff in <5 sec RECOMMENDED**)** | Plan-phase architect + C10 owner | Plan-phase decision conditional on Cand 1 being selected; jointly owned with C10 pre-flight cache provisioning row (when opened). **Recommendation**: D-C6-3 = (c) periodic rebuild during C10 pre-flight provisioning. Strongest C6+C10 cross-component coupling |
| **D-C6-4 (NEW from Cand 1 closure 2026-05-08 Fact #92, Cand-1-only) — geographic-spatial-grid radius `k` choice (fixed-1 = 3x3 grid simplest / fixed-2 = 5x5 grid covers AC-3.x sharp turns more robustly / fixed-4 = 9x9 grid for very high-bank or low-zoom / **dynamic derived from zoom + ground-speed projected over next 5 sec RECOMMENDED**)** | Plan-phase architect | Plan-phase decision conditional on Cand 1 being selected; trade-off between per-query candidate count vs spatial coverage vs latency. **Recommendation**: D-C6-4 = dynamic |
| **D-C6-5 (NEW from Cand 2 closure 2026-05-08 Fact #93, Cand-2-only contingent) — Jetson PostGIS + pgvector co-installation Plan-phase verification choice (**verify on Jetson MVE phase as part of D-C1-2 dedicated bring-up phase RECOMMENDED — already-required Jetson hardware bring-up cycle absorbs this work cheaply** / fork PostGIS+pgvector ARM64 builds in-house if upstream packages incomplete ~1-3 days engineering / pivot to Cand 1 if PostGIS+pgvector co-installation reveals blocking incompatibility)** | Project bring-up team + C7 inference-runtime owner | Plan-phase decision conditional on Cand 2 being elevated to primary; Source #94 search results explicit limitation: "do not provide specific information about PostGIS 3.4's compatibility with ARM64 architecture on Jetson devices, nor do they document the installation footprint"; Source #97 March 2026 article confirms Postgres+pgvector but not explicitly+PostGIS. **Recommendation**: D-C6-5 = (a) verify on Jetson MVE. Interacts with D-C1-2 Jetson MVE phase + D-C7 (when opened) |
| **D-C6-6 (NEW from Cand 2 closure 2026-05-08 Fact #93, Cand-2-only contingent; mirrors D-C6-1 for the pgvector-side) — pgvector descriptor-storage-type choice (`vector` full-precision float32 with 2,000-dim max for HNSW per Source #95 — JUST EXCEEDED by MixVPR 2048-D / **`halfvec` half-precision 2-byte with 16,000-dim max + 50% cache savings + ~0-2% Recall@K loss RECOMMENDED — covers all C2 VPR descriptor candidates consistently** / `sparsevec` for sparse descriptors / `bit` for binary descriptors via Hamming distance)** | Plan-phase architect | Plan-phase decision conditional on Cand 2 being elevated to primary; trade-off between cache footprint vs accuracy vs descriptor compatibility with C2 VPR candidate output format. **Recommendation**: D-C6-6 = (b) halfvec. Interacts with D-C2-9 + D-C2-10 + D-C2-6 descriptor-dimension choices |
| **D-C6-7 (NEW from C6 batch 1 closure 2026-05-08 Fact #92 + Fact #93, CROSS-COMPONENT — affects both Cand 1 and Cand 2; forced by Cand 2 selection) — IF Cand 2 selected → cascade-changes-back-to-suite-satellite-provider strategy choice (cascade PostGIS+pgvector adoption back to satellite-provider for cross-suite consistency ~1-3 days engineering at suite + onboard / keep satellite-provider on btree-only and gps-denied-onboard on PostGIS+pgvector ~accept divergence + maintenance burden / migrate satellite-provider to PostGIS+pgvector in a separate ticket post-MVP / **leave satellite-provider unchanged + maintain Cand 1 throughout — no cascade needed RECOMMENDED if Cand 1 selected as primary which is the closure verdict**)** | User + Plan-phase architect + suite satellite-provider owner | Plan-phase decision conditional on Cand 2 being elevated to primary at C6; per user's session-start clarification "if improvement is small, then there is no sense to change anything at all" — IF Cand 2's MATERIAL improvement justifies adoption (currently NO per closure verdict in Fact #92 + Fact #93 comparative analysis), cascade via separate ticket; OTHERWISE stay with Cand 1 throughout the suite. **Cross-component cascade decision affecting parent-suite `satellite-provider` component** |
| **D-C7-1 (CLOSED IN C7 batch 1 2026-05-08, per C9 / SQ7 restructure user choice A) — calibration-dataset-strategy** | Plan-phase architect (CLOSED at research time — no Plan-phase decision remains) | **Closed at C7 batch 1**: strategy = **real UAV nadir flight footage at ~1 km AGL over season-matched satellite tiles** as the calibration corpus distribution (matches the Project Constraint Matrix's "Inputs available" pinning + provides realistic noise/illumination/season distribution that the deployed system will see). Specific fixture-file pin (AerialVL S03 vs project's Mavic + Derkachi flight clips vs other corpora) is fixture-class and **DELEGATED to Test Spec (greenfield Step 5)**. Synthetic-tile augmentation via random homography is the documented low-data fallback, only invoked if real flight footage is insufficient for Recall@K-target calibration. ~500–1,500 representative samples per the C7 batch 1 closure constraint. **No Plan-phase Choose block remains** — the architectural decision is locked at C7 batch 1 closure. **Cross-component coupling with C9 dropped** per restructure; coupling moves to C7 ↔ Test Spec for fixture-file pinning. |
| **D-C7-2 (NEW from Cand 1 TensorRT-native closure 2026-05-08 Fact #94, Cand-1-only) — TensorRT mixed-precision flag matrix per model family (single FP16-only flag for entire pipeline / **INT8+FP16 for VPR backbones + FP16-only for matchers + FP16-only for VIO frontends [hybrid per-family per D-C7-6] RECOMMENDED** / per-layer precision overrides via `setPrecision`)** | Plan-phase architect | Plan-phase decision conditional on Cand 1 (TensorRT-native) being selected as primary. **Recommendation**: D-C7-2 = (b) ladder per D-C7-6 per-model-family precision policy. Interacts with D-C7-6 cross-component model-family precision policy (AC-NEW-3 covariance honesty + AC-1.1/1.2 frame-center accuracy preserved at FP16 for matchers per Source #103 evidence) |
| **D-C7-3 (NEW from Cand 2 ONNX Runtime+TRT EP closure 2026-05-08 Fact #95, Cand-2-only) — ORT-Jetson-wheel-index-pin choice (`pypi.jetson-ai-lab.io/jp6/cu126` for JetPack 6.2 / `pypi.jetson-ai-lab.io/jp6/cu129` for JetPack 6.x with newer CUDA / **mirror the wheel index to a project-controlled artifact registry for offline-deployment robustness RECOMMENDED ~50 MB per wheel set; pre-flight provisioning step + cu126 variant for JetPack 6.2 alignment**)** | Plan-phase architect + C10 owner | Plan-phase decision conditional on Cand 2 (ONNX Runtime + TRT EP) being elevated to primary; standard `pip install onnxruntime-gpu` does NOT work on Jetson Tegra per Source #100 Issue #20503 — Microsoft does not publish prebuilt aarch64 wheels with CUDA/TensorRT EPs. **Recommendation**: D-C7-3 = (c) mirror to project artifact registry + cu126 variant. Interacts with R-NEW-2 no-cloud-at-flight (offline-deployment requires wheel mirror) + C10 pre-flight cache provisioning |
| **D-C7-4 (NEW from Cand 2 ONNX Runtime+TRT EP closure 2026-05-08 Fact #95, Cand-2-only) — numpy-version-pin choice (**`numpy<2.0.0` per Source #100 Issue #27562 RECOMMENDED until upstream rebuild** / wait for upstream onnxruntime-gpu rebuild against numpy>=2 / pin to a specific onnxruntime-gpu version known to work with numpy<2)** | Plan-phase architect | Plan-phase decision conditional on Cand 2 being elevated to primary; onnxruntime-gpu v1.23.0 wheels for JetPack 6 were built against `numpy<2.0.0`; importing under `numpy>=2.0.0` raises a compatibility error per Source #100 Issue #27562. **Recommendation**: D-C7-4 = (a) `numpy<2.0.0` until upstream rebuild; track Issue #27562 status at Plan phase |
| **D-C7-5 (NEW from Cand 3 pure-PyTorch-FP16 closure 2026-05-08 Fact #96, Cand-3-only) — PyTorch-Jetson-wheel-pin choice (**PyTorch 2.5 + torchvision 0.20 stable RECOMMENDED ~most-stable combination per NVIDIA Developer Forum** / PyTorch 2.9 + torchvision latest / track Jetson AI Lab cadence)** | Plan-phase architect | Plan-phase decision conditional on Cand 3 (pure PyTorch FP16) being selected as mandatory simple-baseline. Standard `pip install torch` does NOT include CUDA support on Jetson per Source #101 NVIDIA Developer Forum threads; must use Jetson AI Lab community wheels. Known dependency issues with `libcudss.so.0` and `libnvdla_runtime.so` on PyTorch 2.9 cu129 wheel under JetPack 6.2 (CUDA 12.6) — version-mismatch sensitive. **Recommendation**: D-C7-5 = (a) PyTorch 2.5 + torchvision 0.20 for the project's first deployment; revisit at Plan phase based on Jetson MVE results |
| **D-C7-6 (NEW from C7 batch 1 closure 2026-05-08 Fact #94 + Fact #95 + Fact #96, CROSS-COMPONENT — affects C2 + C3 + C1 + C7) — INT8-vs-FP16-per-model-family-precision-policy (single INT8 across all model families with sensitivity-fallback / **per-family precision policy: VPR INT8+FP16 fallback, matchers FP16-only, VIO frontends FP16-only RECOMMENDED — operationalizes Source #103 matcher-INT8-quantization-sensitivity finding + Source #102 VPR-CNN-INT8-tolerability finding** / FP16 across all model families until calibration data validates per-family INT8)** | User + Plan-phase architect | **Strongest cross-component lever in the C2+C3+C7 design space.** Plan-phase decision; Source #103 evidence shows LightGlue FP8 caused "match counts dropped sometimes hard" (FP8 is structurally similar to INT8 in dynamic-range reduction) — feature-matching networks are quantization-sensitive in a way that detection / VPR networks are not. Source #102 confirms YOLO26n CNN at INT8 has -6.5% mAP50-95 vs FP16 — acceptable for VPR Recall@K granularity. **Recommendation**: D-C7-6 = (b) per-family policy: VPR backbones (CNN-class MixVPR/EigenPlaces/NetVLAD) → INT8+FP16 mixed; ViT-class VPR backbones (SelaVPR DINOv2-L, conditional AnyLoc/BoQ/DINOv2-VLAD) → FP16-only initially with INT8 deferred to Jetson MVE per D-C2-5; matchers (LightGlue with SP/DISK/ALIKED, XFeat, XFeat+LighterGlue) → **FP16-only — NO INT8**; learned VIO frontends (if any selected at C1) → FP16-only initially, INT8 deferred to Jetson MVE per D-C7-2. **Three-way interaction with AC-1.1/1.2 frame-center accuracy + AC-4.1 latency budget + AC-NEW-3 (FDR for INT8 calibration cache provenance)** |
| **D-C7-7 (NEW from Cand 1 TensorRT-native closure 2026-05-08 Fact #94, Cand-1-only CROSS-COMPONENT with C10) — engine-build-on-Jetson-vs-prebuilt-engine-shipping strategy (build engines at pre-flight on the deployed Jetson / build engines on a known-good "reference Jetson" then ship the same `.engine` files to all production Jetsons / **both — primary path build-on-target with reference-Jetson-built engines as a fallback if pre-flight build fails RECOMMENDED ~handles SM-version drift + future TensorRT minor version updates**)** | Plan-phase architect + C10 owner | Plan-phase decision conditional on Cand 1 (TensorRT-native) being selected as primary; per Source #105 constraints #2 + #3, TensorRT engines are hardware-specific (SM 87 for Orin Nano Super) and CANNOT be transferred between devices. **Recommendation**: D-C7-7 = (c) primary build-on-deployed-Jetson during pre-flight; fallback prebuilt engines for emergency provisioning. **Strongest C7+C10 cross-component coupling — C10 owns the engine-build pipeline + calibration-dataset assembly per D-C7-1** |
| **D-C7-8 (NEW from Cand 1 TensorRT-native closure 2026-05-08 Fact #94, Cand-1-only) — `config.max_workspace_size` cap to avoid tactic-profile segfault during build (**1 GB safe default RECOMMENDED** / 2 GB for richer kernel-fusion search / 3 GB for fastest-possible engine but high segfault risk on 8 GB shared budget)** | Plan-phase architect | Plan-phase decision conditional on Cand 1 being selected as primary; per Source #105 constraint #4, TensorRT engine builds on Jetson under memory pressure can segfault during tactic profiling (8 GB shared CPU+GPU is tight; rich layer-fusion search consumes peak RAM during `tactic.profile` phase). **Recommendation**: D-C7-8 = (a) 1 GB safe default; raise to 2 GB only if Plan-phase Jetson MVE shows engine quality is materially worse at 1 GB |
| **D-C7-9 (NEW from Cand 1 TensorRT-native closure 2026-05-08 Fact #94, Cand-1-only) — TensorRT version pin within JetPack lifecycle (**lock to JetPack 6.2 + TensorRT 10.3 for the project's first deployment RECOMMENDED** / track JetPack 6.x minor releases / lock the exact JetPack point release for cross-deployment reproducibility)** | Plan-phase architect | Plan-phase decision conditional on Cand 1 being selected as primary; JetPack 6.2 ships TensorRT 10.3 + CUDA 12.6 + cuDNN 9.3 (Source #104). Upgrading TensorRT independently of JetPack is not officially supported per Source #105. **Recommendation**: D-C7-9 = (a) lock to JetPack 6.2 + TensorRT 10.3 for the project's first deployment; revisit at Plan phase per JetPack release cadence |
| **D-C8-1 (NEW from Cand 1 pymavlink-GPS_INPUT closure 2026-05-08 Fact #97, Cand-1-only) — pymavlink connection-string transport choice (`udpout:127.0.0.1:14550` for in-process companion+autopilot UDP / `serial:/dev/ttyTHS1:921600` for direct UART to AP TELEM port / `tcp:127.0.0.1:5760` for SITL replay / **all three configurable via env var, default UART for production deployment, UDP for SITL replay, TCP for unit tests RECOMMENDED**)** | Plan-phase architect | Plan-phase decision conditional on Cand 1 (pymavlink → GPS_INPUT) being selected as primary AP path; pymavlink supports all three transports identically. **Recommendation**: D-C8-1 = (d) all three configurable + default UART production. Reduces moving parts in production while preserving testability paths |
| **D-C8-2 (NEW from Cand 1 pymavlink-GPS_INPUT closure 2026-05-08 Fact #97, Cand-1-only CROSS-COMPONENT with AC-NEW-2) — `MAV_CMD_SET_EKF_SOURCE_SET` companion-driven switch ownership pattern (companion always claims source-set 1 + FC keeps real-GPS at source-set 2 + companion is reactive only / **companion publishes to source-set 2 + auto-switches FC to set 2 on first valid fix + switches back to set 1 when companion is unavailable RECOMMENDED ~mirrors NGPS/Auterion pattern** / operator manually flips source-set via RC aux switch option 90)** | Plan-phase architect + AC-NEW-2 owner | Plan-phase decision conditional on Cand 1 being selected as primary AP path; per SQ6 Fact #3 "no GCSs are currently known to implement" companion-driven `MAV_CMD_SET_EKF_SOURCE_SET` — but it works at firmware level. **Recommendation**: D-C8-2 = (b) companion publishes to source-set 2 + auto-switches FC; project gets to define the canonical pattern; mirrors NGPS/Auterion deployment pattern from SQ1 lookup |
| **D-C8-3 (NEW from Cand 1 pymavlink-GPS_INPUT closure 2026-05-08 Fact #97, Cand-1-only) — pymavlink LGPL-3.0 license-posture verification (**bundle pymavlink unmodified + publish requirements.txt with version pin RECOMMENDED ~standard LGPL §6 compliance** / statically link via Cython compilation [LGPL §6 obligation: provide relinkable form] / wrap pymavlink behind a thin C++/Rust process boundary to keep companion-app fully Apache-2.0 [over-engineered])** | Plan-phase architect + license owner | Plan-phase decision conditional on Cand 1 being selected as primary; LGPL §6 allows linking from Apache-2.0 app without "infecting" application license. **Recommendation**: D-C8-3 = (a) bundle unmodified + requirements.txt; aligns with D-C1-1 license-posture-track decision; pymavlink LGPL-3.0 vs project Apache-2.0 dual-use track is straightforward |
| **D-C8-4 (NEW from Cand 2 MSP2_SENSOR_GPS closure 2026-05-08 Fact #99, Cand-2-only) — Python MSP V2 implementation choice (**YAMSPy [community-blessed for iNav external-device comms per Issue #4465; MIT; widest community usage] RECOMMENDED PRIMARY** / INAV-Toolkit `msp_v2_encode` primitive lifted into the project [951-line MIT module, direct primary-source reference] SECONDARY / thin custom encoder using `struct.pack` + CRC-8 DVB-S2 helper [50-line bespoke fallback] FALLBACK / project-side fork of one of the above)** | Plan-phase architect | Plan-phase decision conditional on Cand 2 (MSP2_SENSOR_GPS) being selected as primary iNav path; all options are MIT and produce identical wire bytes. **Recommendation**: D-C8-4 = (a) YAMSPy primary + (c) thin custom encoder fallback if YAMSPy lacks MSP2_SENSOR_GPS support. Choice depends on maintainability vs minimum-dependency-surface preference |
| **D-C8-5 (NEW from Cand 2 MSP2_SENSOR_GPS closure 2026-05-08 Fact #99, Cand-2-only) — MSP2_SENSOR_GPS injection rate (**5 Hz periodic RECOMMENDED ~matches GPS_INPUT 5 Hz cadence on AP side, single-rate cross-FC consistency** / 10 Hz to match iNav nav-cycle frequency / variable rate matching estimator publication rate [3 Hz nominal, up to 10 Hz when matcher confidence is high])** | Plan-phase architect | Plan-phase decision conditional on Cand 2 being selected as primary; estimator publishes at 3 Hz nominal (per pinned dual-rate camera pipeline Fact #40). **Recommendation**: D-C8-5 = (a) 5 Hz periodic; spare headroom for IMU-propagation between estimator updates; cross-FC consistency with AP path |
| **D-C8-6 (NEW from Cand 3 UBX-impersonation closure 2026-05-08 Fact #98, Cand-3-only contingent) — IF Cand 3 selected → UBX-version-advertisement strategy (**advertise hwVersion ≥ M9 + swVersion ≥ 15.00 via NAV-VER (CLASS=0x0A, ID=0x04) at startup + every reset; force iNav into NAV-PVT-only protocol surface RECOMMENDED ~simplest** / advertise hwVersion = M8 + swVersion = 14.x to drive iNav into legacy NAV-POSLLH+NAV-SOL+NAV-VELNED+NAV-TIMEUTC quad mode [more messages but historical iNav-friendly path] / implement adaptive advertisement based on iNav firmware-version probe)** | Plan-phase architect | Plan-phase decision conditional on Cand 3 (UBX impersonation) being elevated to primary at iNav side; per Source #110 lines 1024-1060, iNav configures the simpler NAV-PVT-only path for u-blox version ≥ 15.0. **Recommendation**: D-C8-6 = (a) advertise version ≥ 15.0 to minimize protocol surface |
| **D-C8-7 (NEW from Cand 3 UBX-impersonation closure 2026-05-08 Fact #98, Cand-3-only contingent CROSS-COMPONENT with AC-NEW-7) — IF Cand 3 selected → AC-NEW-7 audit-trail posture (**explicit FDR audit entry on every UBX impersonation session start, naming companion as the UBX source + providing operator-consent provenance check at boot RECOMMENDED** / silent operation with user-manual disclosure only / require runtime parameter `gps-denied-onboard.enable_ubx_impersonation = true` to be set explicitly by the user via QGC [active opt-in])** | Plan-phase architect + AC-NEW-7 owner | Plan-phase decision conditional on Cand 3 being elevated to primary at iNav side; UBX impersonation is unambiguously a forgery posture (companion impersonates u-blox receiver). **Recommendation**: D-C8-7 = (a) explicit FDR audit entry on every impersonation session start; AC-NEW-7 (no covert GPS spoofing without consent) requires an audit trail |
| **D-C8-8 (NEW from Cand 1 + Cand 2 closure 2026-05-08 Fact #97 + Fact #99, CROSS-COMPONENT — affects both Cand 1 and Cand 2; CROSS-COMPONENT with C5 covariance contract) — covariance-honesty cross-FC enforcement strategy (project always publishes the SAME covariance value to both FCs [single shared contract, simpler test surface] / **per-FC covariance unit conversion: AP `GPS_INPUT.horiz_accuracy` (m) vs iNav `MSP2_SENSOR_GPS.hPosAccuracy` (mm) — companion publishes the same source covariance, formatted per-FC RECOMMENDED** / per-FC covariance smoothing [different filter parameters per FC; over-engineered + monotonicity-violation risk under C5 D-C5-2])** | Plan-phase architect + AC-NEW-4 owner | Plan-phase decision; AC-NEW-4 covariance-honesty obligation is the same for both FCs; only the unit + field-name change. **Recommendation**: D-C8-8 = (b) per-FC covariance unit conversion; same source covariance, formatted per-FC. **Strongest C5+C8 cross-component coupling** — extracts 2×2 horizontal sub-matrix from C5 GTSAM `Marginals.marginalCovariance` 6×6 matrix, computes 95% confidence ellipse semi-major axis `sqrt(2.0 * 5.991 * λ_max)`, emits as `horiz_accuracy` (m) for AP / `hPosAccuracy` (mm) for iNav |
| **D-C10-1 (NEW from Sub-area 1 closure 2026-05-08 Fact #100, C10-only) — descriptor-cache rebuild trigger choice (rebuild on every pre-flight invocation simplest but slow / **manifest-hash-driven (rebuild iff `SHA-256(descriptor_blobs[*] + IndexHNSWFlat params)` differs from last-recorded manifest hash) RECOMMENDED + `--force-rebuild` operator override** / time-based (rebuild every N days irrespective of content drift, AC-8.2-aligned))** | Plan-phase architect + C10 owner | Plan-phase decision; trade-off between rebuild latency (5-30 sec at 100K tiles) blocking pre-flight readiness vs unnecessary work when descriptor blobs haven't changed. **Recommendation**: D-C10-1 = (b) manifest-hash-driven + `--force-rebuild` override. Operationalizes the "incremental add unsafe with HNSW deletes" Source #96 finding by treating any descriptor-blob churn as a full rebuild trigger. Operator override allows AC-NEW-3 FDR-required rebuild for cache-poisoning recovery without operator hash-debugging |
| **D-C10-2 (NEW from Sub-area 1 closure 2026-05-08 Fact #100, C10-only) — descriptor-cache atomic-write strategy (write directly to target path simplest but unsafe — partial-write leaves a corrupt FAISS file that `read_index` will load successfully per Source #114 "no internal integrity check" warning / **`python-atomicwrites` package — write-to-temp + `fsync` + atomic rename + parent-dir fsync per Source #116 RECOMMENDED ~3-line addition** / hand-rolled `os.rename` via `tempfile.NamedTemporaryFile(dir=parent_dir)` + manual `fsync` ~10-line equivalent)** | Plan-phase architect + AC-NEW-7 owner | Plan-phase decision; without atomic-write, a power loss or process kill mid-`faiss.write_index` leaves a truncated/partial file that loads successfully and produces silently-wrong descriptor matches at takeoff — **direct violation of AC-NEW-7 cache-poisoning safety + AC-3.3 re-localization stability**. **Recommendation**: D-C10-2 = (b) `python-atomicwrites`. Cross-platform; pure-Python; auditable; established pattern per Source #116. Interacts with D-C10-3 content-hash verification (atomic-write prevents the truncated-file class of corruption; content-hash gate catches malicious tampering separately) |
| **D-C10-3 (NEW from Sub-area 1 closure 2026-05-08 Fact #100, C10-only CROSS-COMPONENT with AC-NEW-7) — content-hash verification gate at takeoff load (skip verification — accept FAISS file as-is per "trusted local filesystem" assumption / **compute `SHA-256(faiss_index_file)` at takeoff load + compare against manifest-recorded hash + reject load + emit STATUSTEXT to FC + refuse takeoff if mismatch RECOMMENDED — directly satisfies AC-NEW-7 cache-poisoning safety obligation** / verify only on first takeoff after rebuild + cache the verification result)** | Plan-phase architect + AC-NEW-7 owner | Plan-phase decision; FAISS Source #114 explicit security warning: "No attempt is made to check the correctness of loaded data. A faulty or malicious file could lead to out-of-memory errors or code execution. Users are responsible for verifying that files loaded with `read_index` have not been altered since being written by `write_index`." **Recommendation**: D-C10-3 = (b) reject-and-refuse-takeoff. The hash check is ~50 ms one-time cost vs the unbounded cost of silent descriptor-cache poisoning leading to incorrect VPR retrieval feeding the rest of the pipeline. **Strongest C10 ↔ AC-NEW-7 coupling**. Couples with D-C10-2 (atomic-write prevents truncation; content-hash catches tampering). Final lock at Plan phase after AC-NEW-7 owner reviews STATUSTEXT format + FC FDR audit-entry shape |
| **D-C10-4 (NEW from Sub-area 1 closure 2026-05-08 Fact #100, C10-only) — descriptor-cache load path (full read into RAM via `faiss.read_index(path)` simplest + warmest cache after first query / **mmap via `faiss.read_index(path, faiss.IO_FLAG_MMAP_IFC)` + `madvise(MADV_WILLNEED)` pre-fault to smooth p99 latency RECOMMENDED — eliminates ~430 MB read at takeoff, supports large indices that exceed shared 8 GB RAM budget per AC-4.2** / both — Plan-phase Jetson MVE benchmark to pick the lower-p99-latency path)** | Plan-phase architect + Jetson MVE bring-up team | Plan-phase decision conditional on Jetson MVE bench results; mmap eliminates the takeoff load read entirely (FAISS supports mmap on `IndexHNSWFlat` per Source #114 `IO_FLAG_MMAP_IFC` flag); but post-load search performance is "slightly slower initially due to memory layout and cache effects" per Source #115 Issue #622, requiring a warmup-search-pass at takeoff. **Recommendation**: D-C10-4 = (b) mmap with `madvise(MADV_WILLNEED)` pre-fault — fastest path for the project's <5 s takeoff load budget; or (c) bench both at Jetson MVE and pick the lower-p99-latency path empirically. Interacts with AC-4.2 8 GB shared CPU+GPU memory budget (mmap reduces peak RAM during load) |
| **D-C10-5 (NEW from Sub-area 2 closure 2026-05-08 Fact #101, C10-only CROSS-COMPONENT with C7) — TensorRT engine-build orchestration tool choice (`trtexec` only — single binary, simplest deployment, but `--int8` without `--calib` falls back to random calibration data per Source #119 — collapses INT8 accuracy / Polygraphy CLI only — handles INT8 calibration via `--data-loader-script` per Source #117 + canonical NVIDIA-blessed wrapper / direct `IBuilderConfig` Python API only — most flexible but most engineering cost per Source #121 + duplicates Polygraphy's calibration-cache management / **hybrid: Polygraphy CLI primary for INT8-calibrating builds + `trtexec` for cache-reuse fast rebuilds + direct `IBuilderConfig` Python API as escape hatch for unusual models like LightGlue dynamic-shape inputs RECOMMENDED ~best of all three for the project's mixed model family**)** | Plan-phase architect + C7 inference-runtime owner + C10 owner | Plan-phase decision conditional on Cand 1 (TensorRT-native) per D-C7-7 = (c) being selected as primary; trade-off between operational simplicity vs feature coverage vs maintenance footprint. **Recommendation**: D-C10-5 = (d) hybrid; pin canonical recipes per model family (VPR backbone INT8+FP16 via Polygraphy; matchers FP16-only via Polygraphy; LightGlue dynamic-shapes via direct API; cache-reuse rebuilds via trtexec). **Strongest C7+C10 cross-component coupling** — operationalizes D-C7-7 closure |
| **D-C10-6 (NEW from Sub-area 2 closure 2026-05-08 Fact #101, C10-only CROSS-COMPONENT with D-C7-1) — TensorRT calibration-cache reuse strategy (rebuild calibration on every engine build slowest but always uses freshest corpus / **rebuild calibration only when `SHA-256(calibration_corpus)` changes from last-recorded manifest hash + reuse cached scales otherwise per Source #117 cache-reuse pattern RECOMMENDED + `--force-trt-rebuild` operator override** / never recalibrate after first successful build — risks per-model accuracy drift if the underlying model graph changes via fine-tune)** | Plan-phase architect + C7 owner | Plan-phase decision conditional on Cand 1 being selected as primary; calibration cache binary-blob is keyed by `SHA-256(calib_corpus)` + onnx-graph hash + TRT version per Source #117 + Source #118 design. Without reuse, every engine build re-runs the ~10-30 minute calibration on the 500-1500-image corpus per D-C7-1 closure. **Recommendation**: D-C10-6 = (b) rebuild on `SHA-256(calib_corpus)` change + `--force-trt-rebuild` override. Subsequent rebuilds <30 sec via cache reuse per Source #117. **Strongest D-C7-1 ↔ C10 coupling** — operationalizes the calibration-corpus closure into the build pipeline |
| **D-C10-7 (NEW from Sub-area 2 closure 2026-05-08 Fact #101, C10-only) — TensorRT engine on-disk filename schema (single `<model>.engine` per model — simplest but breaks under TRT/JetPack version drift / **self-describing `<model>_sm<SM>_jp<JP>_trt<TRT>_<precision>.engine` filename + sidecar `manifest.json` per Source #105 hardware-tied-engine constraint RECOMMENDED ~enables side-by-side multi-version coexistence + reference-Jetson-built fallback engines per D-C7-7 = (c)** / single-bucket directory with manifest-only routing)** | Plan-phase architect + C10 owner | Plan-phase decision conditional on Cand 1 being selected as primary; per Source #105, TRT engines are tied to (SM version, JetPack version, TRT version, precision mode) — moving an engine across any of these dimensions silently fails or quietly degrades. **Recommendation**: D-C10-7 = (b) self-describing filename. Filename schema example: `mixvpr_sm87_jp62_trt103_int8fp16.engine`, `lightglue_disk_sm87_jp62_trt103_fp16.engine`. Sidecar manifest.json captures full provenance for AC-NEW-3 FDR. Couples with D-C7-9 JetPack version pin |
| **D-C10-8 (NEW from Sub-area 2 closure 2026-05-08 Fact #101, C10-only) — TensorRT prebuilt-fallback engine generation venue (build only on the deployed Jetson — minimal infra but blocks deployment until first build succeeds / build only on a reference Jetson at HQ — fastest deployment but loses per-target reproducibility per D-C7-7 = (c) primary path / **reference Jetson at HQ as canonical fallback corpus + deployed-Jetson-copy-to-archive on first successful local build RECOMMENDED — opportunistic redundancy + per-target validation + canonical fallback in case of pre-flight build failure**)** | Plan-phase architect + project bring-up team + C10 owner | Plan-phase decision conditional on Cand 1 being selected as primary; per D-C7-7 = (c), primary path is build-on-deployed-Jetson; fallback is reference-Jetson-built engines. **Recommendation**: D-C10-8 = (c) reference Jetson at HQ + deployed-Jetson-copy-to-archive on first successful local build. Reference Jetson must match deployed Jetson on (SM 87, JetPack 6.2, TensorRT 10.3, CUDA 12.6, cuDNN 9.3) per Source #105 + D-C7-9 lock. Provides AC-NEW-1 (8 h endurance, no infield infra) tolerance for the case where a freshly-deployed Jetson cannot complete a per-mission rebuild before takeoff |
