# Solution Draft > Mode A Phase 2 — engine Step 8 (Deliverable Formatting). Integrates all intermediate research artifacts into a single actionable architecture proposal. > > **Research Output Class**: Technical-component selection (per [`../00_research/00_question_decomposition.md`](../00_research/00_question_decomposition.md)). > > Backing artifacts (read these alongside this draft for full evidence): > - Question decomposition + scope: [`../00_research/00_question_decomposition.md`](../00_research/00_question_decomposition.md) > - Source registry: [`../00_research/01_source_registry/00_summary.md`](../00_research/01_source_registry/00_summary.md) (#1–#121) > - Fact cards: [`../00_research/02_fact_cards/00_summary.md`](../00_research/02_fact_cards/00_summary.md) (#1–#101) > - Comparison framework: [`../00_research/03_comparison_framework.md`](../00_research/03_comparison_framework.md) > - Reasoning chain: [`../00_research/04_reasoning_chain.md`](../00_research/04_reasoning_chain.md) > - Validation log: [`../00_research/05_validation_log.md`](../00_research/05_validation_log.md) > - Component fit matrix: [`../00_research/06_component_fit_matrix/00_summary.md`](../00_research/06_component_fit_matrix/00_summary.md) > - Cross-component gates: [`../00_research/06_component_fit_matrix/99_cross_component_gates.md`](../00_research/06_component_fit_matrix/99_cross_component_gates.md) > - Project Constraint Matrix: [`../00_problem/problem.md`](../00_problem/problem.md), [`../00_problem/restrictions.md`](../00_problem/restrictions.md), [`../00_problem/acceptance_criteria.md`](../00_problem/acceptance_criteria.md) > > **Note on AC assessment** — Mode A Phase 1 (`00_ac_assessment.md` BLOCKING gate per the research SKILL.md) was not executed as a standalone artifact in this run. Per-AC binding evidence is instead distributed across the per-component fact cards and the Restrictions × Candidate-Modes sub-matrix sections in `06_component_fit_matrix/Cx_*.md`. This is acknowledged as a process deviation and is recoverable by extracting an `00_ac_assessment.md` summary file from the existing per-AC binding evidence on demand. No AC has been silently dropped or unverified. --- ## Product Solution Description A Jetson-Orin-Nano-Super-hosted companion-PC system that produces a GPS-equivalent WGS84 position estimate (with honest 6×6 covariance) for a fixed-wing UAV operating in a GPS-denied or GPS-spoofed environment, by fusing pre-flight-cached satellite tile imagery (from the parent-suite Azaion Satellite Service) with live nav-camera frames and FC-supplied IMU + attitude. The system implements the canonical hierarchical GPS-denied pipeline `retrieval → matching → pose → fusion` (per SQ2 surveys converging on this pattern, Sources #38–#42), runs on the pinned Jetson Orin Nano Super hardware (Source #105 hardware-tied constraints honored), and delivers the final pose to the FC via per-FC external-positioning interfaces — MAVLink `GPS_INPUT` for ArduPilot Plane (verified Source #4 + #106 + #107), MSP2 `MSP2_SENSOR_GPS` for iNav (verified Source #111 + #112 + #113). PX4 is explicitly out of scope per `restrictions.md`. ### Component-interaction diagram (pre-flight + runtime) ``` PRE-FLIGHT (operator-managed, on-Jetson) ───────────────────────────────────────── parent-suite Satellite Service ─→ tile cache (PostgreSQL btree + filesystem) ─→ C2 VPR backbone (TensorRT engine, INT8+FP16) └─→ per-tile descriptors → FAISS HNSW index (.index file written via faiss.write_index + atomicwrites + SHA-256 content-hash gate) ONNX models (C2/C3/C1) ─→ Polygraphy / trtexec / IBuilderConfig hybrid orchestration → TensorRT engines (.engine files, SM 87 / JetPack 6.2 / TRT 10.3) TAKEOFF LOAD (≤5 s) ────────────────────────────────────────────────────────────── FAISS read_index(IO_FLAG_MMAP_IFC) + content-hash verify → ready IRuntime.deserializeCudaEngine per-engine → ready RUNTIME (3 Hz nav-camera, 100-200 Hz IMU; AC-4.1 <400 ms p95) ───────────────────── nav-camera frame ─→ C1 OKVIS2 VIO (relative pose, IMU bias) ─→ C2 MixVPR query → top-K=3 satellite tile retrieval (~25 ms) ─→ C3 DISK+LightGlue × K pairs (~90-180 ms FP16) ─→ C4 OpenCV solvePnPRansac (~5-15 ms) └─→ wrap in GTSAM Marginals (~30-90 ms; 6×6 covariance) FC IMU + attitude ─→ C5 GTSAM iSAM2 + CombinedImuFactor + PriorFactorPose3 (~2-5 ms per update at D-C5-5=(c) factor density) └─→ posterior 6×6 covariance via Marginals ─→ C8 per-FC unit conversion ├─→ pymavlink GPS_INPUT (AP) └─→ MSP2_SENSOR_GPS (iNav) (5 Hz periodic) total runtime: ~140-420 ms p95 at K=3 + adaptive LightGlue depth ``` --- ## Existing/Competitor Solutions Analysis | System | Class | Stack signature | Relation to this project | |---|---|---|---| | **Twist Robotics OSCAR** (Source #25) | Deployed peer (Ukraine theater) | Visual navigation companion; closed-source | Closest peer system; deployed in theater the project will operate in. Confirms operational viability of the canonical pipeline shape. | | **Auterion Artemis / Skynode N** (Sources #31+#32) | Commercial deployed (Ukraine-tested) | Skynode N + Visual Navigation; 1000-mile deep-strike demonstrated; closed-source proprietary stack | Demonstrates Jetson-class hardware can host GPS-denied companion at deployed-mission scale. Validates the pinned hardware target. | | **NGPS (snktshrma/ngps_flight)** (Source #33) | Open-source (ArduPilot GSoC 2024) | LightGlue + SuperPoint + UKF + VISION_POSITION_ESTIMATE | Closest open-source pipeline-match. Confirms ArduPilot Plane + visual-localization companion is operationally validated. **License gap**: relies on Magic Leap-noncommercial canonical SP weights — same hard disqualifier this project hits in D-C3-1, mitigated by D-C3-1 = (a) DISK+LightGlue swap. | | **Vantor Raptor** (Source #30) | Commercial deployed | GPS-denied UAV navigation + coordinate extraction | Validates dual-purpose pose + object-localization output. Aligns with project AC-7.x object-localization requirements. | | **DARPA FLA (T&E review)** (Source #35) | Defense program lineage | GPS-denied autonomy with onboard compute | Provides T&E reference for AC-NEW-4 false-position safety budget validation methodology. | | **DSMAC / TERCOM lineage** (Source #36) | Defense legacy | Digital Scene Matching Area Correlator + Terrain Contour Matching | Historical proof point that the project's "match against pre-cached imagery" core idea predates modern CV by decades; modern equivalents (this project) trade hand-engineered correlators for learned VPR + matchers. | **Key delta vs existing systems**: this project (a) supports both ArduPilot Plane AND iNav (no other open-source GPS-denied companion targets iNav per SQ6 saturation), (b) enforces an explicit AC-NEW-7 cache-poisoning safety budget across the descriptor cache + tile cache + Suite Sat Service pipeline, (c) ships an honest 6×6 posterior covariance per AC-NEW-4 via a GTSAM-shared-substrate hybrid (D-C4-2 + D-C5-5 + D-C8-8 cross-component coupling). --- ## Architecture The solution is decomposed into nine components (C1–C8 + C10; C9 was dropped in the SQ7/C9 restructure 2026-05-08 and deferred to Test Spec greenfield Step 5). Per-component candidate tables follow. **All "Selected" candidates have an MVE link in the Restrictions × Candidate-Modes sub-matrix sections** of [`../00_research/06_component_fit_matrix/Cx_*.md`](../00_research/06_component_fit_matrix/) per Step 7.5.3 decision rules. ### Component: C1 — Visual / Visual-Inertial Odometry | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **OKVIS2** (modern-competitive-lead) | C++ + ROS; smartroboticslab/okvis2 | Loosely-coupled VIO with stereo+IMU optionable; for this project mono+IMU mode; outputs per-frame relative pose + IMU bias estimates | Best modern accuracy on cross-domain tracking; permissive (BSD) | C++ + ROS dependency; ~30-50 ms per frame on Jetson Orin Nano Super extrapolation | C++17, ROS Noetic optional, IMU at 100-200 Hz | BSD-3-Clause clean | ~1-2 wk integration | MVE: see [`../00_research/02_fact_cards/C1_vio.md`](../00_research/02_fact_cards/C1_vio.md); docs: Sources #47+#48+#56 | **Selected (modern-competitive-lead)** — preferred runtime path | | **VINS-Mono** (mandatory simple-baseline) | C++ + ROS; HKUST-Aerial-Robotics/VINS-Mono | Mono+IMU loosely-coupled VIO | Stable since 2018; simplest baseline | Older accuracy; some Jetson port effort | C++17, ROS Noetic optional, IMU at 100-200 Hz | BSD permissive clean | ~3-5 days fallback | MVE: see fact card; docs: Sources #43+#55 | **Selected (mandatory simple-baseline)** — fallback if OKVIS2 fails Jetson MVE | | **KLT+RANSAC** (homemade fallback) | OpenCV pure-Python | KLT optical flow + 5-point/homography RANSAC essential-matrix → pose decomposition | Pure OpenCV; no C++ dependency; pure-VO baseline | No IMU fusion (delegated to C5); ~5-10 ms per frame on Jetson | OpenCV 4.x; IMU bypassed | Apache-2.0 | ~3-5 days fallback | MVE: see fact card; docs: Source #53 | **Selected (project-internal homemade fallback)** — used when OKVIS2/VINS-Mono unavailable | **Exact-fit evidence**: - Project constraints checked: AC-1.3 cumulative drift (visual-only / IMU-fused branches); AC-2.1a frame-to-frame registration; AC-3.1 outlier tolerance; AC-3.2 sharp-turn behavior; AC-4.1 + AC-4.2 latency + memory. - Evidence: `02_fact_cards/C1_vio.md`; Sources #43+#47+#48+#53+#55+#56. - Disqualifiers: VINS-Fusion + OpenVINS GPL-3.0 contingent on D-C1-1 = (a) track. - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C1_vio.md`](../00_research/06_component_fit_matrix/C1_vio.md) per-candidate sections. - API capability gates: ✅ MVE saved. ### Component: C2 — Visual Place Recognition | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **MixVPR** (mandatory simple-baseline, BSD/permissive track) | PyTorch; amaralibey/MixVPR | ResNet50 backbone + MLP-Mixer aggregator; output dimension 2048-D float32 (or 512-D / 256-D `cropToDim` per D-C2-9 / D-C2-10 / D-C6-1 = halfvec); input 320×320 | MIT throughout; modest descriptor budget (~6.5% of AC-8.3 cache); active maintenance | Street-view-pretrained — D-C2-1 retrain on aerial corpus required | PyTorch 2.x; ONNX export verified | MIT clean | ~3-5 days base + ~1-2 wk D-C2-1 retrain | MVE: see [`../00_research/02_fact_cards/C2_vpr.md`](../00_research/02_fact_cards/C2_vpr.md); docs: Sources #57+#58+#61 | **Selected (mandatory simple-baseline + recommended primary on BSD/permissive track)** | | **SALAD** (modern-competitive-lead, GPL-3.0 track) | PyTorch; serizba/salad | DINOv2 ViT-B + optimal-transport aggregator; output 8448-D / 2112-D / 544-D per D-C2-6; input 322×322 | +5-7 R@1 over MixVPR-2048 on MSLS Challenge | GPL-3.0; D-C2-5 ViT export risk; descriptor budget at full size 27% of AC-8.3 | PyTorch 2.x; DINOv2 ViT-B export | GPL-3.0 contingent | ~3-5 days base + ~1-2 wk D-C2-1 retrain | MVE: see fact card; docs: Sources #59+#60 | **Selected (modern-competitive-lead) on GPL-3.0 track** — eligible only if D-C1-1 = (a) or (c) | | **EigenPlaces** (BSD/permissive sibling) | PyTorch; gmberton/EigenPlaces | ResNet-50 + GeM + FC viewpoint-robust training; 2048-D / 512-D / 256-D / 128-D per D-C2-10 | MIT throughout; viewpoint-robust training paradigm; eleven sibling modes | Older approach (2023); modest accuracy lift over MixVPR | PyTorch 2.x | MIT clean | ~3-5 days | MVE: see fact card; docs: Sources #67+#68 | **Selected (BSD/permissive sibling)** — alternate primary on BSD/permissive track | | **SelaVPR** (BSD/permissive two-stage sibling) | PyTorch; Lu-Feng/SelaVPR | DINOv2 ViT-L two-stage (global + local); 1024-D global + on-demand local features | MIT; lift from two-stage; 1024-D smallest single-stage cache | DINOv2 ViT-L is 3.5× larger than ViT-B; D-C2-5 + D-C2-7 re-rank gates | PyTorch 2.x; DINOv2 ViT-L export | MIT clean | ~3-5 days base + ~1-2 wk D-C2-1 retrain | MVE: see fact card; docs: Sources #62+#63 | **Selected (modern-competitive-lead BSD/permissive two-stage)** — eligible if D-C2-7 re-rank strategy chosen | | **NetVLAD** (mandatory baseline, BSD/permissive track) | PyTorch port; Relja/netvlad canonical | VGG16 + soft-assignment-VLAD; 4096-D / 512-D / 256-D PCA-whitened per D-C2-9 | MIT canonical; classical-baseline; widely-cited | Largest single-stage descriptor cache at canonical 4096-D; D-C2-8 PyTorch-port-strategy gate | PyTorch port required from canonical MATLAB | MIT canonical (Nanne port has license-uncertainty per D-C2-8) | ~1 wk re-port from canonical OR ~3 days Nanne port + license-clearance | MVE: see fact card; docs: Sources #64+#65+#66 | **Selected (mandatory simple-baseline)** — classical reference; D-C2-8 = (b) re-port from canonical recommended | **Exact-fit evidence**: - Project constraints checked: AC-2.1b satellite-anchor registration; AC-2.2 cross-domain MRE; AC-8.3 cache budget; AC-8.6 retrieval robustness; AC-4.1 latency. - Evidence: `02_fact_cards/C2_vpr.md`; Sources #57–#68. - Disqualifiers: SALAD GPL-3.0 contingent on D-C1-1 = (a); conditional candidates (AnyLoc/BoQ/DINOv2-VLAD) pending D-C2-5 INT8 quantization survey prerequisite. - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C2_vpr.md`](../00_research/06_component_fit_matrix/C2_vpr.md). - API capability gates: ✅ MVE saved for all 5 mandatory pre-screen candidates. ### Component: C3 — Cross-domain matchers | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **DISK+LightGlue** (recommended-primary-mitigation) | PyTorch + LightGlue ONNX; cvlab-epfl/disk + cvg/LightGlue | DISK `save-depth.pth` canonical default + LightGlue+DISK paired matcher; FP16 only (D-C7-6 matchers→FP16-only per-family policy); K=3-5 retrieval pairs per UAV frame per D-C3-3 | +7.99 absolute AUC@5° over canonical SP+LightGlue (LightGlue paper Tab 6); Apache-2.0 throughout; clean license | ~30-60 ms per pair on Jetson FP16 — TIGHT at K=10; D-C3-3 mitigation via K=3-5 + adaptive depth | PyTorch 2.x; LightGlue ONNX export verified | Apache-2.0 throughout | ~1 wk ONNX export + ~1-2 wk D-C2-1 retrain | MVE: see [`../00_research/02_fact_cards/C3_matchers.md`](../00_research/02_fact_cards/C3_matchers.md); docs: Sources #69+#70+#71+#76+#77 | **Selected (recommended-primary-mitigation)** — replaces canonical SP+LightGlue (Magic Leap noncommercial HARD DISQUALIFIER per D-C3-1) | | **ALIKED+LightGlue** (modern-competitive-lead-secondary) | PyTorch (ALIKED export-absence in LightGlue-ONNX → PyTorch fp16-only); Shiaoming/ALIKED + cvg/LightGlue | ALIKED-N(16rot) 128-D rotation-augmented (D-C3-4) + LightGlue+ALIKED paired matcher; PyTorch fp16 | Rotation-augmented for multi-heading aerial flights; Apache-2.0 | PyTorch fp16-only forces D-C3-3 K reduction more than DISK | PyTorch 2.x | Apache-2.0 + BSD-3-Clause | ~1 wk swap from DISK | MVE: see fact card; docs: Sources #74+#75 | **Selected (modern-competitive-lead-secondary)** | | **XFeat / XFeat\* / XFeat+LighterGlue** (alternate-modern-competitive-lead) | PyTorch; verlab/accelerated_features | Recommended XFeat\* semi-dense with MNN+MLP-offset-refinement per D-C3-6 = (b); cheapest C3 retrain (~36h on RTX 4090) | 4× more inliers per pair via lightweight MLP refinement; cheapest retrain | Documentary AUC@5° below LightGlue siblings | PyTorch 2.x | Apache-2.0 throughout | ~3-5 days base + ~36h retrain | MVE: see fact card; docs: Sources #80+#81 | **Selected (alternate-modern-competitive-lead)** — lowest engineering complexity path | | **SuperGlue + SuperPoint canonical** (deprecated by LightGlue authors) | magicleap/SuperGluePretrainedNetwork | n/a — canonical SP weights | Reference baseline | **Magic Leap noncommercial license = HARD DISQUALIFIER** in dual-use deployment context | n/a | n/a | n/a | docs: Sources #78+#79 | **Rejected** (D-C3-1 hard disqualifier) | **Exact-fit evidence**: - Project constraints checked: AC-2.1b satellite-anchor registration; AC-2.2 cross-domain MRE <2.5 px; AC-3.3 disconnected-segment recovery; AC-4.1 latency budget. - Evidence: `02_fact_cards/C3_matchers.md`; Sources #69–#81. - Disqualifiers: Magic Leap noncommercial on canonical SP weights (HARD DISQUALIFIER); MASt3R CC-BY-NC; RoMa / DKM / LoFTR not selected at this batch. - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C3_matchers.md`](../00_research/06_component_fit_matrix/C3_matchers.md). - API capability gates: ✅ MVE saved for selected candidates; canonical SP rejected before API verification. ### Component: C4 — Pose estimation (PnP+RANSAC+LM) | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **OpenCV `cv::solvePnPRansac`** (mandatory simple-baseline) wrapped in **GTSAM `Marginals`** (D-C4-2 = (b) covariance recovery) | OpenCV 4.x calib3d + GTSAM Python | `solvePnPRansac(objectPoints, imagePoints, K, dist, ..., flags=SOLVEPNP_IPPE)` (planar-scene IPPE per D-C4-1 = (b) 4-DoF flat-earth); wrap result in GTSAM `BetweenFactor` prior + per-inlier `GenericProjectionFactorCal3_S2` factors → `LevenbergMarquardtOptimizer` → `Marginals.marginalCovariance(pose_key)` 6×6 | OpenCV simplest-baseline + 7 USAC RANSAC variants; GTSAM provides NATIVE 6×6 covariance recovery; couples C4 + C5 via shared GTSAM substrate per D-C5-5 = (c) | GTSAM `Marginals` ~30-90 ms per pose recovery (Plan-phase Jetson MVE confirms tail); OpenCV alone has no covariance API per Source #83 signature | OpenCV 4.x; GTSAM Python | Apache-2.0 + BSD-3-Clause | ~3-5 days OpenCV + ~3-5 days GTSAM wrapper | MVE: see [`../00_research/02_fact_cards/C4_pose_estimation.md`](../00_research/02_fact_cards/C4_pose_estimation.md); docs: Sources #82+#83+#86+#87 | **Selected (mandatory simple-baseline + recommended-primary covariance recovery via GTSAM)** | | **OpenGV** (modern-competitive-lead-richer-minimal-solver) | C++ + Python bindings; laurentkneip/opengv | `absolute_pose::optimize_nonlinear` per D-C4-2 = (d); algorithm-selectable RANSAC enums (KNEIP/GAO/EPNP/GP3P) | Richer minimal-solver coverage than OpenCV; 2 P3P variants; UPnP global-optimal; GP3P generalized-camera | NOASSERTION SPDX (D-C4-3 license-clearance gate); ~3 yr stale (D-C4-4 maintenance gate); no native planar-scene solver vs OpenCV's IPPE | C++17; Eigen-3.4+ | BSD-3-Clause-equivalent NOASSERTION pending counsel review | ~1-2 wk fork-and-patch (D-C4-4 = (b)) | MVE: see fact card; docs: Sources #84+#85 | **Selected with runtime gate** — secondary path conditional on D-C4-3 + D-C4-4 closures | **Exact-fit evidence**: - Project constraints checked: AC-1.1/1.2 frame-center accuracy; AC-2.2 reprojection error <2.5 px cross-domain; AC-NEW-4 covariance honesty (P(error >500 m) <0.1 %); AC-4.1 latency. - Evidence: `02_fact_cards/C4_pose_estimation.md`; Sources #82–#87. - Disqualifiers: none in selected candidates; OpenGV NOASSERTION gated as `Selected with runtime gate` per Step 7.5.3 carve-out for license-clearance. - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C4_pose_estimation.md`](../00_research/06_component_fit_matrix/C4_pose_estimation.md). - API capability gates: ✅ MVE saved. ### Component: C5 — State estimator / sensor fusion | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **Manual ESKF (Solà 2017)** (mandatory simple-baseline) | NumPy/SciPy project-side implementation | Quaternion-correct ESKF on SO(3); analytic Jacobian per Solà §6; ~5-15 ms per update on Jetson CPU | Trivial dependency footprint (~kilobytes of code); fastest C5 candidate; native 6×6 covariance via analytic Jacobian propagation | No look-back refinement (forward-time-only Kalman update); D-C5-2 long-cruise observability strategy required | NumPy 1.x + SciPy + Solà 2017 paper as canonical reference | Public-domain canonical equations + project Apache-2.0 implementation | ~1-2 wk D-C5-1 = (b) re-implement from paper directly | MVE: see [`../00_research/02_fact_cards/C5_state_estimator.md`](../00_research/02_fact_cards/C5_state_estimator.md); docs: Sources #88+#89 | **Selected (mandatory simple-baseline)** — always-running fallback | | **GTSAM iSAM2 + CombinedImuFactor + smart factors + Marginals + IncrementalFixedLagSmoother** (modern-competitive-lead-factor-graph) | GTSAM Python; borglab/gtsam | iSAM2 incremental smoothing + `CombinedImuFactor` 6-key per-keyframe-pair factor with bias evolution + `BetweenFactorPose3` + `GenericProjectionFactorCal3DS2` per D-C5-5 = (c) `PriorFactorPose3` only + `gtsam_unstable.IncrementalFixedLagSmoother` K=10-20 keyframes per D-C5-3 | NATIVE 6×6 posterior covariance via `Marginals`; NATIVE AC-4.5 look-back refinement; couples C4 + C5 via shared GTSAM substrate per D-C5-5 = (c) | GTSAM ~50-200 MB footprint; per-update latency ~5-100 ms depending on factor density (D-C5-5 = (c) gives ~2-5 ms) | GTSAM Python; daily-active maintenance | BSD-3-Clause clean | ~2-3 wk full factor-graph design | MVE: see fact card; docs: Sources #90+#91 | **Selected (modern-competitive-lead-factor-graph + recommended primary path)** — couples NATIVELY with C4 GTSAM Marginals via D-C5-5 = (c) | **Exact-fit evidence**: - Project constraints checked: AC-1.3 cumulative drift; AC-1.4 95% covariance ellipse + source label; AC-3.5 visual blackout + spoofed GPS dead-reckon; AC-4.1 + AC-4.5 latency + look-back refinement; AC-NEW-4 covariance honesty; AC-NEW-8 visual blackout failsafe. - Evidence: `02_fact_cards/C5_state_estimator.md`; Sources #88–#91. - Disqualifiers: D-C5-1 reference-implementation-license-verification gates `ludvigls/ESKF` and `cggos/imu_x_fusion` (mitigation = D-C5-1 = (b) re-implement from canonical Solà 2017 paper). - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C5_state_estimator.md`](../00_research/06_component_fit_matrix/C5_state_estimator.md). - API capability gates: ✅ MVE saved. ### Component: C6 — Tile cache + spatial index | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **Mirror-of-suite-`satellite-provider` pattern** (recommended primary) | PostgreSQL btree composite + bytea + FAISS HNSW + filesystem | btree composite index on `(tile_zoom, tile_x, tile_y, version)` for slippy-map spatial-grid range queries; `bytea` descriptor blobs (halfvec per D-C6-1); `IndexHNSWFlat(d, M=32)` per D-C6-2 loaded at takeoff via `faiss.read_index(path, IO_FLAG_MMAP_IFC)`; tile storage at `./tiles/{zoom}/{x}/{y}.{image_type}` slippy-map convention | Mirrors verified-existing parent-suite pattern (Source #92 filesystem read); ~6-54 ms per cache hit within AC-4.1; ~700 MB-1.5 GB total memory within AC-4.2; trivial dependency footprint (no Postgres extensions) | Halfvec descriptor storage requires app-side conversion; sector classification heuristic deferred to Plan-phase | PostgreSQL 16 + Dapper or psycopg2 + FAISS Python | PostgreSQL License + MIT clean | ~3-5 days mirror integration | MVE: see [`../00_research/02_fact_cards/C6_tile_cache_spatial_index.md`](../00_research/02_fact_cards/C6_tile_cache_spatial_index.md); docs: Sources #92+#96+#97+#98 | **Selected (recommended primary)** — leverages existing verified-suite pattern | | **PostGIS + pgvector** (deferred secondary) | PostgreSQL + PostGIS 3.4 + pgvector 0.7+ | GiST on `geography(POINT,4326)` with KNN distance ordering (`<->`); pgvector HNSW for descriptor ANN; same filesystem tile storage | Native KNN + radius queries; combined-SQL capabilities | 5-10× slower geographic lookup at 3 Hz query rate per Sources #93 + #97; PostGIS GPL-2.0-or-later (CONTINGENT REJECT under D-C1-1 = (b)); +50-100 MB Jetson memory + 50-200 MB disk install; D-C6-5 Jetson PostGIS+pgvector co-installation Plan-phase verification gate | PostgreSQL 16 + PostGIS 3.4 + pgvector 0.7+ | GPL-2.0-or-later via PostGIS contingent | ~1-2 wk + Plan-phase Jetson MVE | MVE: see fact card; docs: Sources #94+#95 | **Deferred secondary** — comparative-improvement verdict does NOT clear user's "significant-improvement-only" bar | **Exact-fit evidence**: - Project constraints checked: AC-3.3 disconnected-segment retrieval; AC-4.1 latency; AC-4.2 memory; AC-8.1 cache-interface resolution; AC-8.2 freshness; AC-8.3 cache budget; AC-8.6 satellite-anchor relocalization robustness. - Evidence: `02_fact_cards/C6_tile_cache_spatial_index.md`; Sources #92–#98. - Disqualifiers: PostGIS GPL-2.0-or-later contingent on D-C1-1 = (a) license track. - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C6_tile_cache_spatial_index.md`](../00_research/06_component_fit_matrix/C6_tile_cache_spatial_index.md). - API capability gates: ✅ MVE saved for selected primary; deferred secondary has API capability evidence saved but is not active. ### Component: C7 — On-Jetson inference runtime | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **TensorRT native** (recommended primary) | TensorRT 10.3 bundled with JetPack 6.2 | `IInt8EntropyCalibrator2` + `BuilderFlag.FP16+INT8` mixed-precision per D-C7-2 = (b) per-family ladder per D-C7-6; engines built directly on Jetson Orin Nano Super SM 87 per D-C7-7 = (c); `config.max_workspace_size = 1 << 30` (1 GB) per D-C7-8 | Apache-2.0 in TRT 10.x; ships with JetPack so zero-effort install; lowest-latency primary path; 2-3× speedup at INT8 vs FP16 per Source #102 | Engines hardware-tied to SM 87 (Source #105) — must be built per-target via D-C10-5..D-C10-8 orchestration | JetPack 6.2 + CUDA 12.6 + cuDNN 9.3 + TRT 10.3 | Apache-2.0 throughout | ~1 wk first-model + ~1 day each subsequent | MVE: see [`../00_research/02_fact_cards/C7_inference_runtime.md`](../00_research/02_fact_cards/C7_inference_runtime.md); docs: Sources #99+#104+#105 | **Selected (recommended primary)** — lowest-latency runtime path | | **ONNX Runtime + TensorRT EP** (modern-competitive-lead-cross-architecture-portability) | onnxruntime-gpu via Jetson AI Lab JP6/CU126 wheel index | `TensorrtExecutionProvider` config + automatic CUDA EP / CPU EP subgraph fallback | MIT throughout; cross-architecture portability for replay/SITL on x86 dev hosts | `pip install onnxruntime-gpu` does not work on Jetson (D-C7-3 mitigation = mirror Jetson AI Lab wheel index); `numpy<2.0.0` pin per D-C7-4 | Jetson AI Lab community wheels | MIT throughout | ~1 wk Jetson AI Lab wheel mgmt | MVE: see fact card; docs: Sources #100+#103 | **Selected (modern-competitive-lead-cross-architecture-portability)** — secondary for replay/SITL only | | **Pure PyTorch FP16** (mandatory simple-baseline + reference-correctness oracle) | torch.amp.autocast + model.half() + Jetson AI Lab PyTorch 2.5 ARM64 wheel | FP16 across all models; no quantization | BSD-3-Clause; zero-conversion regression baseline; reference-correctness oracle for accuracy validation of TRT-built engines | Standard `pip install torch` lacks CUDA on Jetson — needs Jetson AI Lab wheel via D-C7-5 = (a) PyTorch 2.5 + torchvision 0.20 | Jetson AI Lab PyTorch 2.5 wheel | BSD-3-Clause throughout | ~3-5 days base | MVE: see fact card; docs: Source #101 | **Selected (mandatory simple-baseline)** — accuracy-validation oracle only, not runtime path | **Exact-fit evidence**: - Project constraints checked: AC-4.1 latency; AC-4.2 memory; AC-NEW-3 INT8 calibration cache provenance for FDR; AC-NEW-5 thermal envelope (Jetson runs at 25 W TDP). - Evidence: `02_fact_cards/C7_inference_runtime.md`; Sources #99–#105. - Disqualifiers: Triton/DeepStream/CUDA-Python custom kernels considered-and-rejected (server/video-pipeline class, out-of-budget for embedded 8 h mission). - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C7_inference_runtime.md`](../00_research/06_component_fit_matrix/C7_inference_runtime.md). - API capability gates: ✅ MVE saved for all 3 candidates per per-family roles. ### Component: C8 — MAVLink / MSP2 FC adapter | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **pymavlink → MAVLink `GPS_INPUT`** (recommended-primary for ArduPilot Plane) | ardupilot/pymavlink | `master.mav.gps_input_send(time_usec, gps_id, ignore_flags, time_week_ms, time_week, fix_type, lat, lon, alt, hdop, vdop, vn, ve, vd, speed_accuracy, horiz_accuracy, vert_accuracy, satellites_visible, yaw)` 5 Hz periodic per D-C8-5 over UART/USB/UDP per D-C8-1; FC-side `GPS1_TYPE=14` MAVLink + `EK3_SRC1_POSXY=3` GPS source-set; per-FC unit conversion `horiz_accuracy` (m) per D-C8-8 = (b) | Cooperative-path; FC-side ingestion via `AP_GPS_MAV` (verified Source #4); LGPL-3.0 linkable from Apache-2.0 app per LGPL §6 (D-C8-3 mitigation) | LGPL-3.0 license-posture verification (D-C8-3 mitigation = bundle unmodified) | pymavlink + ArduPilot Plane firmware (any) | LGPL-3.0 linkable | ~3-5 days | MVE: see [`../00_research/02_fact_cards/C8_fc_adapter.md`](../00_research/02_fact_cards/C8_fc_adapter.md); docs: Sources #106+#107 | **Selected (recommended-primary)** for ArduPilot Plane | | **MSP2_SENSOR_GPS via Python MSP V2** (recommended-primary for iNav) | YAMSPy + INAV-Toolkit `msp_v2_encode` | `MSP2_SENSOR_GPS` (id 7939 / 0x1F03) 36-byte payload at 5 Hz periodic per D-C8-5; `mspGPSReceiveNewData()` direct passthrough on iNav side; per-FC unit conversion `hPosAccuracy` (mm) per D-C8-8 = (b) | YAMSPy + INAV-Toolkit MIT throughout; covariance fields aligned (`hPosAccuracy`/`vPosAccuracy`/`hVelAccuracy`); `USE_GPS_PROTO_MSP` enabled by default in iNav target/common.h | D-C8-4 implementation choice gate (YAMSPy primary + thin custom encoder fallback) | YAMSPy or INAV-Toolkit; iNav firmware 8.0+ | MIT throughout | ~3-5 days | MVE: see fact card; docs: Sources #111+#112+#113 | **Selected (recommended-primary)** for iNav | | **UBX impersonation via pyubx2 NAV-PVT** (deferred secondary for iNav) | semuconsulting/pyubx2 | NAV-PVT periodic + NAV-VER startup + CFG-MSG/CFG-RATE ACK; iNav-side `gpsMapFixType()` validation gate requires `flags & 0x01 = 1` AND `fixType ∈ {2,3}` per Source #110 | BSD-3-Clause clean; richer protocol surface | Forgery posture; D-C8-7 AC-NEW-7 audit-trail verification gate | pyubx2; iNav firmware (any) | BSD-3-Clause | ~1-2 wk + audit-trail design | MVE: see fact card; docs: Sources #108+#109+#110 | **Deferred secondary** — comparative-improvement verdict does NOT clear user's "significant-improvement-only" bar over MSP2 | **Exact-fit evidence**: - Project constraints checked: AC-4.3 per-FC external-positioning interface; AC-NEW-2 spoofing-promotion latency; AC-NEW-4 covariance honesty (per-FC unit conversion); AC-NEW-7 forgery posture for UBX path. - Evidence: `02_fact_cards/C8_fc_adapter.md`; Sources #106–#113. - Disqualifiers: PX4 explicitly out of scope per `restrictions.md`; pymavlink LGPL-3.0 mitigated via bundle-unmodified pattern (D-C8-3). - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C8_fc_adapter.md`](../00_research/06_component_fit_matrix/C8_fc_adapter.md). - API capability gates: ✅ MVE saved for all 3 candidates. ### Component: C10 — Pre-flight cache provisioning + sector classification + freshness pipeline | Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit | |----------|-------|--------------------|------------|-------------|--------------|----------|------|-------------------------|-----| | **D-C6-3 confirmation: descriptor-cache rebuild trigger pipeline** | FAISS Python API + python-atomicwrites + SHA-256 content-hash | Manifest-hash-driven rebuild trigger per D-C10-1 = (b); `python-atomicwrites` write-temp + `fsync` + atomic rename + parent-dir fsync per D-C10-2 = (b); SHA-256 content-hash gate at takeoff + reject + STATUSTEXT + refuse takeoff if mismatch per D-C10-3 = (b); mmap with `madvise(MADV_WILLNEED)` pre-fault per D-C10-4 = (b) | FAISS MIT + atomicwrites MIT throughout; idempotent + crash-safe + AC-NEW-7-compliant; minimal abstraction surface | FAISS warns "no internal integrity check, expects validated input" — MITIGATED by content-hash gate at takeoff | FAISS Python + python-atomicwrites + SHA-256 stdlib | MIT throughout | ~1 wk orchestration wrapper | MVE: see [`../00_research/02_fact_cards/C10_preflight_provisioning.md`](../00_research/02_fact_cards/C10_preflight_provisioning.md); docs: Sources #114+#115+#116 | **Selected** — closes D-C6-3 cross-component gate | | **D-C7-7 confirmation: TensorRT engine-build pipeline** | Polygraphy CLI + trtexec + direct `IBuilderConfig` Python API | Hybrid orchestration per D-C10-5 = (d): Polygraphy CLI primary for INT8-calibrating builds (`polygraphy convert --int8 --fp16 --data-loader-script ./calib_data_loader.py --calibration-cache -o `) + trtexec for cache-reuse fast rebuilds + direct `IBuilderConfig` Python API escape hatch for unusual models (LightGlue dynamic shapes); calibration cache reuse keyed by `SHA-256(calib_corpus)` per D-C10-6; self-describing filename `_sm87_jp62_trt103_.engine` per D-C10-7; reference Jetson at HQ + deployed-Jetson-copy-to-archive on first successful local build per D-C10-8 | Polygraphy + TRT 10.x Apache-2.0 throughout; calibration-cache reuse keeps subsequent rebuilds <30 sec; production-mature NVIDIA-blessed orchestration | `trtexec --int8` without `--calib` random-data-fallback caveat — MITIGATED by project-side wrapper enforcing `--calib=` non-empty as precondition | TensorRT 10.3 + Polygraphy + JetPack 6.2 | Apache-2.0 throughout | ~1 wk first-model + ~1 day each subsequent | MVE: see fact card; docs: Sources #117+#118+#119+#120+#121 | **Selected** — closes D-C7-7 cross-component gate | **Exact-fit evidence**: - Project constraints checked: AC-NEW-7 cache-poisoning safety budget (descriptor cache + TensorRT engine path); AC-8.3 cache budget; AC-NEW-1 cold-start TTFF (takeoff load <5 s); restrictions.md rebuild-while-not-flying constraint. - Evidence: `02_fact_cards/C10_preflight_provisioning.md`; Sources #114–#121. - Disqualifiers: none — both candidates Apache-2.0/MIT clean. - Restrictions × Candidate-Modes sub-matrix: see [`../00_research/06_component_fit_matrix/C10_preflight_provisioning.md`](../00_research/06_component_fit_matrix/C10_preflight_provisioning.md). - API capability gates: ✅ MVE saved for both sub-areas. ### Out-of-research-scope items (deferred to Plan-phase) Per the C10 scope restructure 2026-05-08 (`c10_scope=C` cross-coupling minimal), the following are deferred to Plan-phase as `operator tooling design`: - Operator-side CLI/desktop tool design (Plan-phase architect + UX) - Sector classification (active-conflict vs stable rear) heuristics + interface (Plan-phase architect + operations team) - Tile age-stamping schema beyond restrictions.md mandate (Plan-phase architect) - Freshness pipeline workflow (Plan-phase architect + operations team) Their cross-coupling with the runtime architecture is mediated entirely by the descriptor-cache file (D-C6-3 closure) and the TensorRT engine cache file (D-C7-7 closure) — both pinned by C10 batch 1 confirmations. --- ## Testing Strategy > **Note**: full test specifications are produced by the Test Spec skill (greenfield Step 5). What follows is the research-level test envelope, named so the Test Spec skill can elaborate against it. ### Integration / Functional Tests - **IT-1 — Pipeline smoke**: feed `_docs/00_problem/input_data/flight_derkachi/` (cropped nadir flight footage + synchronized `SCALED_IMU2` + `GLOBAL_POSITION_INT`) into the full C1+C2+C3+C4+C5+C8 pipeline; assert that the emitted `GPS_INPUT` (ArduPilot SITL) and `MSP2_SENSOR_GPS` (iNav SITL) frames stay within AC-1.1/1.2 frame-center-accuracy bounds vs the tlog GPS path. - **IT-2 — Cold-boot TTFF**: cold-boot the companion 50× with a simulated FC pose; measure boot → first valid emitted external-position MAVLink frame; pass = 95th percentile <30 s per AC-NEW-1. - **IT-3 — Spoofing-promotion latency**: SITL on each supported FC (ArduPilot Plane + iNav, production param sets); inject false GPS; measure spoof onset → companion estimate becoming primary FC source via D-C8-2 = (b) `MAV_CMD_SET_EKF_SOURCE_SET` companion-driven switch; pass = 95th percentile <3 s on both per AC-NEW-2. - **IT-4 — Sharp-turn recovery**: synthetic UAV trajectory with ±20° bank turns + <5% inter-frame overlap; assert C2/C3 satellite-anchor recovery within 1-2 frames per AC-3.2 + AC-3.3. - **IT-5 — Visual blackout + GPS spoofing degraded mode**: SITL/replay on each FC; inject 5 s / 15 s / 35 s blackouts while spoofing GPS; assert mode transition ≤400 ms, spoofed GPS ignored, covariance grows monotonically, MAVLink fields degrade at AC-NEW-8 thresholds (>100 m → "2D fix or worse"; >500 m or >30 s → "no fix" + `VISUAL_BLACKOUT_FAILSAFE` STATUSTEXT), recovery only via trusted anchor or 10-s GPS-health + visual-consistency gate. - **IT-6 — Stale tile rejection (AC-NEW-6)**: inject synthetic-age tiles into C6 cache; verify rejection or downgrade-to-non-`satellite_anchored` per AC-8.2 freshness threshold. - **IT-7 — Cache-poisoning verification (AC-NEW-7)**: tamper with `/var/lib/onboard/cache/faiss/v_2048_M32.index` post-write but pre-takeoff; verify D-C10-3 SHA-256 content-hash gate triggers reject + STATUSTEXT + refuse takeoff. - **IT-8 — Pre-flight cache rebuild idempotence**: invoke C10 pre-flight provisioning twice consecutively without input changes; verify D-C10-1 manifest-hash-driven trigger correctly skips rebuild on second invocation; verify atomic-write integrity holds across simulated power-loss mid-rebuild. - **IT-9 — TensorRT engine cache reuse**: invoke C10 pre-flight provisioning with same model + same calibration corpus twice; verify D-C10-6 calibration-cache reuse triggers <30 sec rebuild on second invocation; verify D-C10-7 self-describing filename schema correctly identifies SM/JP/TRT/precision tuple. - **IT-10 — AC-NEW-4 covariance-honesty cross-FC**: verify D-C8-8 = (b) per-FC unit conversion correctly extracts 2×2 horizontal sub-matrix from C5 GTSAM `Marginals.marginalCovariance`, computes 95% confidence ellipse semi-major axis `sqrt(2.0 * 5.991 * λ_max)`, emits as `horiz_accuracy` (m) for ArduPilot AND `hPosAccuracy` (mm) for iNav with mathematically equivalent values. ### Non-Functional Tests - **NFT-1 — End-to-end latency p95 (AC-4.1)**: 8 h synthetic load (3 Hz nav frames replayed); measure end-to-end latency distribution; pass = 95th percentile <400 ms; up to ~10% frames may drop under sustained load per AC-4.1. - **NFT-2 — Memory cap (AC-4.2)**: same 8 h load; assert peak shared CPU+GPU memory <8 GB per AC-4.2. - **NFT-3 — Thermal envelope (AC-NEW-5)**: hot-soak 25 W @ +50 °C for 8 h; assert no Jetson thermal throttling. Cold-soak −20 °C cold-start within AC-NEW-1 30 s p95 budget. - **NFT-4 — False-position safety budget (AC-NEW-4)**: Monte Carlo over public aerial-localization dataset (e.g., AerialVL S03) + own recorded flights; report error CDF; pass = `P(>500 m) <0.1 %` AND `P(>1 km) <0.01 %` across ≥100 flights. - **NFT-5 — Cache-poisoning safety budget (AC-NEW-7)**: multi-flight Monte Carlo replay over public datasets + own flights with synthetic over-confidence injection (deflate covariance ×1.5–3); assert `P(geo-misalign >30 m) <1 %` AND `P(>100 m) <0.1 %` across ≥100 flights. Independently exercise the Suite Sat Service-side voting contract (out of onboard scope but acknowledged as cross-component). - **NFT-6 — FDR storage cap (AC-NEW-3)**: 8 h synthetic load; assert FDR ≤64 GB; verify no payload class silently dropped without a logged rollover. - **NFT-7 — License posture verification**: SBOM dump of the deployed companion; verify D-C1-1 license-track is honored (no GPL-3.0 candidate loaded if D-C1-1 = (b); pymavlink LGPL-3.0 bundled-unmodified per D-C8-3); verify Magic Leap noncommercial canonical SP weights are NOT loaded; verify all selected candidates' LICENSE files are bundled in `LICENSE/`. --- ## References > Full per-source descriptions in `_docs/00_research/01_source_registry/` (organized by category file). ### SQ6 — ArduPilot Plane vs iNav external positioning Sources #1–#24. See [`SQ6_external_positioning.md`](../00_research/01_source_registry/SQ6_external_positioning.md). ### SQ1 — Existing GPS-denied UAV systems Sources #25–#37. See [`SQ1_existing_systems.md`](../00_research/01_source_registry/SQ1_existing_systems.md). ### SQ2 — Canonical pipeline decomposition Sources #38–#42. See [`SQ2_canonical_pipeline.md`](../00_research/01_source_registry/SQ2_canonical_pipeline.md). ### C1 — VIO candidates Sources #43–#56. See [`C1_vio.md`](../00_research/01_source_registry/C1_vio.md). ### C2 — VPR candidates Sources #57–#68. See [`C2_vpr.md`](../00_research/01_source_registry/C2_vpr.md). ### C3 — Matcher candidates Sources #69–#81. See [`C3_matchers.md`](../00_research/01_source_registry/C3_matchers.md). ### C4 — Pose estimation candidates Sources #82–#87. See [`C4_pose_estimation.md`](../00_research/01_source_registry/C4_pose_estimation.md). ### C5 — State estimator / sensor fusion candidates Sources #88–#91. See [`C5_state_estimator.md`](../00_research/01_source_registry/C5_state_estimator.md). ### C6 — Tile cache + spatial index candidates Sources #92–#98. See [`C6_tile_cache_spatial_index.md`](../00_research/01_source_registry/C6_tile_cache_spatial_index.md). ### C7 — On-Jetson inference runtime candidates Sources #99–#105. See [`C7_inference_runtime.md`](../00_research/01_source_registry/C7_inference_runtime.md). ### C8 — MAVLink / MSP2 FC adapter candidates Sources #106–#113. See [`C8_fc_adapter.md`](../00_research/01_source_registry/C8_fc_adapter.md). ### C10 — Pre-flight cache provisioning candidates Sources #114–#121. See [`C10_preflight_provisioning.md`](../00_research/01_source_registry/C10_preflight_provisioning.md). --- ## Open decisions for Plan-phase (D-Cx-y registry) The 27 Plan-phase-architect-owned decisions and 8 cross-component-owner decisions raised across all components are catalogued in [`../00_research/06_component_fit_matrix/99_cross_component_gates.md`](../00_research/06_component_fit_matrix/99_cross_component_gates.md). The most architecturally significant **user-decision** gates are: - **D-C1-1 license-track posture** (User + Plan-phase architect). Recommendation: D-C1-1 = (c) both tracks open; preserves modular swap pathway documented in Comparison Framework Dimension 8. - **D-C2-1 VPR canonical-weights vs aerial-retrain vs aerial-community-checkpoint** (User + Plan-phase architect). Recommendation: aerial-retrain on real UAV nadir flight footage corpus per D-C7-1 closure (cost ~1-2 weeks per retrained candidate). - **D-C3-1 SuperPoint-replacement-strategy** (User + Plan-phase architect + license-posture decision-maker). Recommendation: D-C3-1 = (a) DISK+LightGlue (Apache-2.0 throughout + +7.99 absolute AUC@5° lift over canonical SP+LightGlue per LightGlue paper Tab 6). - **D-C2-11 (CONDITIONAL) MegaLoc successor evaluation** (User + Plan-phase architect). Recommendation: defer to post-research session — EigenPlaces closes the mandatory pre-screen at the documentary-required floor; MegaLoc's Plan-phase relevance depends on D-C1-1 + Jetson MVE results. --- ## Related Artifacts - Tech stack evaluation (`tech_stack.md`): NOT PRODUCED in this Mode A run. Recommendation set is embedded in the per-component candidate tables above. Full extraction into `tech_stack.md` is a low-cost task if the user requests it before Plan-phase. - Security analysis (`security_analysis.md`): NOT PRODUCED in this Mode A run. AC-NEW-7 cache-poisoning safety + AC-NEW-2 spoofing-promotion + AC-NEW-8 visual blackout failsafe + AC-NEW-4 covariance honesty are addressed component-by-component above and cross-referenced in [`../00_research/05_validation_log.md`](../00_research/05_validation_log.md). Full extraction into `security_analysis.md` is a low-cost task if the user requests it before Plan-phase. - AC assessment (`_docs/00_research/00_ac_assessment.md`): NOT PRODUCED as standalone artifact in this Mode A run; per-AC binding evidence distributed across per-component fact cards + Restrictions × Candidate-Modes sub-matrix sections.