# Component Fit Matrix — C4: Pose estimation (PnP + RANSAC + LM)

> Mode A Phase 2 — engine Step 7.5 (Component Applicability Gate, structured per-component candidate-selection table). Status vocabulary in [`00_summary.md`](00_summary.md). Backing fact cards: [`../02_fact_cards/SQ2_canonical_pipeline.md`](../02_fact_cards/SQ2_canonical_pipeline.md) (canonical PnP+RANSAC+LM pipeline) and [`../02_fact_cards/C3_matchers.md`](../02_fact_cards/C3_matchers.md) (C3 → C4 input contract).
>
> Index: [`00_summary.md`](00_summary.md). Sibling components: [C1 VIO](C1_vio.md), [C2 VPR](C2_vpr.md), [C3 Matchers](C3_matchers.md), [C5–C10 pending](C5-C10_pending.md). Cross-component gates: [`99_cross_component_gates.md`](99_cross_component_gates.md).

---

## C4 — Pose estimation (PnP + RANSAC + LM)

**Status**: IN PROGRESS — **3 of N candidates** complete at documentary level (mandatory-simple-baseline role STRUCTURALLY COMPLETE — OpenCV `cv::solvePnPRansac` per Fact #52; modern-competitive-lead-richer-minimal-solver role — OpenGV per Fact #53; modern-competitive-lead-covariance-honest role — GTSAM per Fact #54). Subsequent candidates (Theia / Ceres-only) will be cataloged in subsequent sessions if needed.

**Definition correction (2026-05-08, locked by user)**: the original `00_question_decomposition.md` line 72 taxonomy table named C4 "Single-frame orthorectification" but the dominant convention through C1+C2+C3 closures (line 160 + 194 of `00_question_decomposition.md`, ALL C3-row pinned outputs `feeding C4 PnP+RANSAC pose estimator`, Fact #20 + #21 + #45 through #51 audience lines) treats C4 as "Pose estimation (PnP + RANSAC + LM)" — taking C3's 2D-2D correspondences and producing 6-DoF camera pose w.r.t. tile, feeding C5 estimator. **User-locked C4 definition is Pose estimation**. The orphaned "Single-frame orthorectification" responsibility (AC-8.4 mid-flight tile generation, write-side path) is reassigned-pending-final-row-decision to **C6 (tile cache + spatial index)** as a write-side cache concern (since AC-8.4 is fundamentally `pose-from-C5 + nav-frame-from-C1 → ortho-rectified-tile → C6 cache write`, and C6 already owns tile cache write per Fact #21 binding `AC-8.4 ... bound by ... C6 (tile cache write)`). Final placement of orthorectification will be confirmed when the C6 row is opened. **No new component slot is created**; the original C4–C10 numbering is preserved; only C4's responsibility is changed.

**Pinned mode** (per-frame pose-from-correspondences contract for the project's C4 row):

- inputs: `{up to 1024 2D-2D correspondences with confidence scores per (UAV-frame, satellite-tile) image pair from C3 (DISK+LightGlue D-C3-1 RECOMMENDED-PRIMARY / ALIKED+LightGlue D-C3-1 SECONDARY / XFeat D-C3-1 ALTERNATE / SP+LightGlue documentary-baseline / SuperGlue+SuperPoint mandatory-simple-baseline) + per-tile geo metadata (WGS84 corner coordinates + ortho resolution per AC-8.1) from C6 tile cache read + 3D lift via DSM (if available; AC + restrictions specify 2D ortho only — Fact #23 closure deferred 2D-3D-lift architectural decision means 2D-only operation is the project default)}` on `Jetson Orin Nano Super (8 GB shared, JetPack 6, ROS 2 Humble; final inference runtime selection deferred to C7 + D-C3-2 reuse)`; per-frame compute = K=10 image pairs × 1 PnP+RANSAC+LM call per Fact #25 + AC-3.3 re-localization
- outputs: `{6-DoF camera pose w.r.t. tile (R, t) + per-correspondence inlier mask + reprojection error + 6×6 covariance + inlier ratio + RANSAC iteration count + source label satellite_anchor for the fused C5 estimate}` per Fact #20 + #21 + AC-NEW-4 (covariance honesty)

**Locked-in research-time defaults** (carried forward from C1 + C2 + C3 — Fact #41):
- D-C1-1 = (c) **keep both license tracks open** through Plan; final license decision deferred to post-Jetson-MVE.
- D-C1-2 = (b) **defer Jetson Orin Nano Super hardware MVE to a dedicated bring-up phase** between research and Plan; research closes with documentary ranking + per-candidate `Verify` gates.

**Interactions with prior C-row closures**:
- C3 D-C3-1 extractor choice determines the C4 RANSAC inlier-count distribution (DISK 2424.8 multiview NL vs ALIKED-N(16) 1975.4 vs XFeat\* 1885 vs SP 1500 — varies the C4 PnP+RANSAC failure rate; high-inlier extractors give more-stable RANSAC).
- C3 outputs include per-correspondence confidence — C4 PnP+RANSAC must consume the τ=0.1 cosine-confidence-threshold-filtered subset, not the full match list, to avoid bias from low-confidence outliers (consistent with cvg/LightGlue paper Table 3 Aachen Day-Night pipeline shape via Source #71 cross-cite).
- C5 covariance-honesty contract (AC-NEW-4) requires C4 to produce a HONEST 6×6 covariance, not a placeholder identity-matrix stub. Fact #20 closure (DSM lift architectural decision) interacts: 2D-only pose-from-homography produces a 3-DoF homography that lifts to 6-DoF only with attitude-from-IMU/VIO prior — D-C4-1 NEW (3-DoF-acceptance / DSM-coarseness-acceptance / aerial-photogrammetry-DSM-acquisition-cost) was raised at Fact #20 closure and remains the canonical Plan-phase decision for C4.

| # | Candidate | License | Per-mode verification | Status | Lead reason / disqualifier | Sub-matrix cite |
|---|---|---|---|---|---|---|
| 1 | **OpenCV `cv::solvePnPRansac` + paired `cv::solvePnPRefineLM`** (canonical `opencv/opencv` calib3d module; mandatory simple-baseline) | Apache-2.0 (clean throughout) — Source #82 GitHub API metadata `license.spdx_id: "Apache-2.0"`; 87385 stars + last pushed 2026-05-08 = TODAY at access time | ✅ Mode enumeration via WebFetch fallback (context7 MCP-validation-error) — 9 `SolvePnPMethod` enum values + 2 function signatures (classical + USAC) + paired `solvePnPRefineLM`/`solvePnPRefineVVS`/`solvePnPGeneric` + 7 USAC RANSAC variants documented in Source #83; ✅ runnable example in canonical PnP tutorial; ✅ canonical defaults `iterationsCount=100, reprojectionError=8.0, confidence=0.99, flags=SOLVEPNP_ITERATIVE`; ⚠️ **3D-2D INPUT CONTRACT, NOT 2D-2D** — requires D-C4-1 lift (inherent to all PnP candidates); ⚠️ **NO DIRECT 6×6 COVARIANCE** — D-C4-2 NEW gate raised; ⚠️ **2 of 9 enum values BROKEN** (SOLVEPNP_DLS + SOLVEPNP_UPNP fall back to EPNP per explicit docstring); ⚠️ `solvePnPRefineLM` rotation update NOT on SO(3) (alternate `solvePnPRefineVVS` is SO(3)-correct) | **Mandatory-simple-baseline reference** (engine Component Option Breadth rule role — structurally analogous to NetVLAD's role in C2 row + SuperGlue+SuperPoint's role in C3 row); deployment-ready under every D-C1-1 license-posture choice; final ranking deferred to Jetson MVE phase per D-C1-2 | **TWO CONVERGING POSITIVE structural advantages**: (i) clean Apache-2.0 throughout (tied with cvg/LightGlue + DISK + XFeat for cleanest license-compliance story); (ii) dominant industry-standard reference (87385 stars + daily-active maintenance + JetPack 6 canonical distribution = zero-effort Jetson deployment). **TWO NEGATIVE-BUT-MITIGABLE structural findings** (inherent to PnP class, apply identically to all C4 candidates): (iii) 3D-2D input contract → D-C4-1 2D→3D lift required; (iv) no direct 6×6 covariance → D-C4-2 NEW covariance-recovery-strategy required. **TWO MINOR CAVEATS**: (v) 2 BROKEN enum values eliminated; valid set is `EPNP / AP3P / IPPE / SQPNP` plus 2 special-case (`P3P` for exactly-3, `IPPE_SQUARE` for 4-fixed-pattern markers); (vi) `solvePnPRefineLM` not on SO(3) — alternate `solvePnPRefineVVS` is preferred for high-accuracy. Recommended pairing for D-C4-1 = 4-DoF flat-earth lift: **`flags=SOLVEPNP_IPPE`** (planar-scene minimal-solver designed for coplanar object points) with **`SOLVEPNP_SQPNP`** as the modern globally-optimal fallback for the 6-DoF DSM-lift case | Fact #52 in [`../02_fact_cards/C4_pose_estimation.md`](../02_fact_cards/C4_pose_estimation.md) (per-mode entry + per-numbered-Restriction × per-numbered-AC sub-matrix block) |
| 2 | **OpenGV `absolute_pose::AbsolutePoseSacProblem(KNEIP)` + paired `absolute_pose::optimize_nonlinear`** (canonical `laurentkneip/opengv` library; modern-competitive-lead-richer-minimal-solver) | BSD-3-Clause-equivalent CONTINGENT on D-C4-3 NEW Plan-phase license-clearance verification — Source #84 License.txt direct WebFetch verified BSD-3-Clause boilerplate (3 numbered redistribution conditions + non-endorsement clause), but GitHub SPDX detector reports `license.spdx_id: "NOASSERTION"` due to non-canonical-OSI-template formatting; 1109 stars + 358 forks + last pushed **2023-06-07 = ~2y 11mo stale** at access time (D-C4-4 NEW maintenance-staleness mitigation gate) | ✅ Mode enumeration via WebFetch fallback (context7 NOT INDEXED — only OpenCV variants returned for OpenGV query) — 4 absolute-pose minimal solvers (`p2p / p3p_kneip / p3p_gao / upnp`) + 2 non-minimal solvers (`epnp / upnp`) + 2 generalized-camera solvers (`gp3p / gpnp`) + 1 LM optimizer (`optimize_nonlinear`) + 4 RANSAC algorithm enums (`KNEIP / GAO / EPNP / GP3P`) documented in Source #85; ✅ runnable example with `sac::Ransac` + `AbsolutePoseSacProblem` integration; ⚠️ **BEARING-VECTOR INPUT CONTRACT, NOT 2D PIXEL** — requires project-side adapter or pre-computed inverse-intrinsic projection from C3's pixel correspondences; ⚠️ **3D-ANGLE RANSAC THRESHOLD** — conversion required from project's pixel-reprojection-error budget; ⚠️ **NO DIRECT 6×6 COVARIANCE OUTPUT** from `optimize_nonlinear` (D-C4-2 applies identically; harder to mitigate than OpenCV since OpenGV's residuals are bearing-vector not pixel); ⚠️ **NO PLANAR-SCENE DEDICATED SOLVER** equivalent to OpenCV's `flags=SOLVEPNP_IPPE` — DOCUMENTARY NEGATIVE for D-C4-1 = 4-DoF flat-earth case | **Modern-competitive-lead-richer-minimal-solver-coverage** (engine Component Option Breadth rule role); deployment-ready CONTINGENT on D-C4-3 license-clearance + D-C4-4 maintenance-staleness mitigation; final ranking deferred to Jetson MVE phase per D-C1-2 | **TWO CONVERGING POSITIVE structural advantages**: (i) **richer minimal-solver coverage than OpenCV** (4 algorithm-selectable RANSAC enums + 2 P3P variants [Kneip 2011 + Gao 2003] + 1 UPnP global-optimal alternate + 1 generalized-camera GP3P; vs OpenCV's effectively-4-valid SolvePnPMethod after 2 BROKEN entries removed; OpenGV provides Kneip's original 2011 P3P that OpenCV does NOT distribute — only Ke & Roumeliotis 2017 AP3P); (ii) **generalized-camera + non-central absolute pose support** — `absolute_pose::gp3p` + `absolute_pose::gpnp` for multi-camera rigs; not directly applicable to project's pinned 1× ADTi 20MP nav frame but architecturally cleaner if project later adds side-looking camera. **FIVE NEGATIVE-BUT-MITIGABLE structural findings**: (iii) bearing-vector input contract → adapter engineering required; (iv) 3D-angle RANSAC threshold → conversion required; (v) no direct 6×6 covariance → D-C4-2 applies identically (recommendation = option (b) wrap in GTSAM Marginals since OpenGV-internal Jacobian recovery is ~3-5 days vs ~1 day for OpenCV); (vi) **~3 years maintenance staleness** → D-C4-4 NEW gate; (vii) **NOASSERTION SPDX-detector status** → D-C4-3 NEW Plan-phase license-clearance verification gate. **ONE MAJOR DOCUMENTARY NEGATIVE finding vs OpenCV**: (viii) NO planar-scene dedicated minimal solver vs OpenCV's `flags=SOLVEPNP_IPPE` — for project's locked-in D-C4-1 = 4-DoF flat-earth lift recommendation, OpenGV requires using Kneip's P3P or EPNP without the planar-scene specialization advantage. Net trade-off favors OpenCV-as-primary for the project's D-C4-1 = 4-DoF flat-earth case; OpenGV-as-secondary-evaluation if Plan-phase Jetson MVE shows the need for non-central or generalized-camera support | Fact #53 in [`../02_fact_cards/C4_pose_estimation.md`](../02_fact_cards/C4_pose_estimation.md) (per-mode entry; per-numbered-Restriction × per-numbered-AC sub-matrix deferred to next session per scope-discipline) |
| 3 | **GTSAM `LevenbergMarquardtOptimizer` + `GenericProjectionFactorCal3_S2` + `Marginals.marginalCovariance`** (canonical `borglab/gtsam` library by Frank Dellaert et al. + Georgia Tech Borg Lab; modern-competitive-lead-covariance-honest) | BSD-3-Clause (clean throughout) — Source #86 LICENSE.BSD direct WebFetch verified `Copyright (c) 2010, Georgia Tech Research Corporation` with 3 numbered redistribution conditions + non-endorsement clause; bundled deps clean (BSD-3 + Apache-2.0 + MPL2 file-level — all dual-use compatible); 3424 stars + 927 forks + last pushed **2026-05-08T13:00:22Z = TODAY** at access time (fresher than OpenCV by 6 hours = daily-active maintenance) | ✅ Mode enumeration via context7 INDEXED PASS at `/borglab/gtsam` version 4.3a1 with **1121 code snippets** (best context7 indexing of any C4 candidate evaluated) — `GenericProjectionFactorCal3_S2` + `LevenbergMarquardtOptimizer` + `Marginals.marginalCovariance` + `NonlinearFactorGraph` + `Cal3_S2` / `Cal3DS2` + `Pose3` + `noiseModel.Diagonal.Sigmas` / `noiseModel.Isotropic.Sigma` + `noiseModel.Robust.Create` + `mEstimator.Huber.Create` + `GncOptimizer` documented in Source #87; ✅ runnable example via `python/gtsam/examples/CameraResectioning.ipynb` canonical PnP pattern; ✅ **NATIVE 6×6 POSE COVARIANCE via `Marginals(graph, result).marginalCovariance(pose_key)`** — only C4 candidate to date that satisfies AC-NEW-4 covariance-honesty NATIVELY; ⚠️ **NO NATIVE RANSAC** (canonical pattern is external-RANSAC-via-OpenCV-for-inliers → GTSAM-factor-graph-from-inliers OR in-graph robust noise model OR `GncOptimizer`); ⚠️ **~50-200 MB library footprint** (heaviest C4 candidate to date but well within AC-4.2 budget); ⚠️ **TIGHT AC-4.1 latency margin** (~30-90 ms per call extrapolated to Jetson Orin Nano Super = 300-900 ms total at K=10 pairs/frame vs 400 ms budget); ⚠️ **NO JetPack 6 canonical distribution** (~1-2 days cross-compilation engineering) | **Modern-competitive-lead-covariance-honest** (engine Component Option Breadth rule role; **directly addresses AC-NEW-4-binding-constraint axis** that drives C4 row's primary architectural concern); deployment-ready under every D-C1-1 license-posture choice; final ranking deferred to Jetson MVE phase per D-C1-2 | **THREE CONVERGING POSITIVE structural advantages**: (i) **NATIVE 6×6 POSE COVARIANCE via `Marginals.marginalCovariance`** — the **only C4 candidate to date that satisfies AC-NEW-4 covariance-honesty NATIVELY without D-C4-2 mitigation work**; **directly addresses the AC-NEW-4-binding-constraint axis**; (ii) clean BSD-3-Clause throughout (tied with cvg/LightGlue + DISK + XFeat + OpenCV for cleanest license-compliance story); bundled deps clean (BSD-3 + Apache-2.0 + MPL2 file-level); (iii) daily-active maintenance + best context7 indexing of any C4 candidate (1121 code snippets at version 4.3a1). **ONE ADDITIONAL POSITIVE structural advantage**: (iv) **ARCHITECTURAL EXTENSION TO C5 VIA iSAM2** — factor-graph paradigm scales naturally from C4 single-frame PnP to C5 multi-frame state estimation via `iSAM2` + `BetweenFactor<Pose3>` + `PriorFactorPose3`; would simplify C5 implementation if both C4 and C5 are GTSAM-based, providing a forward-looking architectural integration advantage that no other C4 candidate provides. **ONE NEGATIVE-BUT-MITIGABLE structural finding**: (v) NO native RANSAC → canonical pattern is external-RANSAC-via-OpenCV (couples C4 = GTSAM-as-primary with OpenCV-RANSAC-as-inlier-detector); alternative is in-graph M-estimator robust noise model OR `GncOptimizer` (Yang et al. RAL 2020). **THREE CAVEATS**: (vi) ~50-200 MB library footprint; (vii) no JetPack 6 canonical distribution (~1-2 days cross-compilation engineering); (viii) tight AC-4.1 latency margin requiring Plan-phase Jetson MVE phase verification — mitigation strategies include reduce K from 10 to 3-5 (couples with D-C3-3) OR GTSAM-as-secondary-only for satellite-anchor frames OR batch GTSAM optimization across multiple frames via iSAM2 incremental update. **Recommended C4 architecture for the project**: **OpenCV solvePnPRansac as mandatory simple-baseline reference floor + per-frame inlier detection + initial pose estimate + GTSAM factor-graph posterior recovery for AC-NEW-4 covariance-honest output** (couples Fact #52 + Fact #54 closures via D-C4-2 = (b)) | Fact #54 in [`../02_fact_cards/C4_pose_estimation.md`](../02_fact_cards/C4_pose_estimation.md) (per-mode entry; per-numbered-Restriction × per-numbered-AC sub-matrix deferred to next session per scope-discipline) |

### C4 — Plan-phase deliverables raised by prior closures (will compound as candidates close)

1. **D-C4-1 (CARRIED FORWARD from Fact #20 closure 2026-05-XX) — 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 / 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) — **carried forward from C2 row deferred resolution** (Fact #20 surfaced this decision but the C2 row closure left it for the C4 row to consolidate). Plan-phase decision; **for the project's pinned 2D-ortho-only cache + IMU-attitude-prior context, recommendation is 4-DoF with flat-earth assumption (altitude from IMU+barometer + attitude from VIO/IMU + planar-scene homography → 4-DoF pose extraction)** — this is the "flat-steppe Donetsk/Kharkiv operational area" assumption made plausible by Source #38 Skoltech survey + restrictions on 2D-ortho-only cache. ALOS-30m-DSM fallback is the secondary mitigation if 4-DoF accuracy proves insufficient at AC-1.1/1.2 50m/20m bars at the tighter tail.

2. **D-C4-2 NEW (raised by OpenCV `cv::solvePnPRansac` closure 2026-05-08, Fact #52; UPDATED by GTSAM closure 2026-05-08 Fact #54) — covariance-recovery-strategy** — `cv::solvePnPRansac` returns `retval, rvec, tvec, inliers` only; OpenGV's `optimize_nonlinear` has no covariance output API; **NO direct 6×6 covariance output from either OpenCV or OpenGV** per Source #83 + Source #85 function signatures. **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 Plan-phase choice between: **(a)** post-hoc Jacobian-based covariance recovery via `cv::projectPoints` Jacobian + Schur complement on inlier residuals (~1 day engineering; pure OpenCV API; covariance approximation of equivalent quality to ROS `tf2`'s standard recipe; **recommended for OpenCV-as-primary mandatory-simple-baseline path**); **(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 GTSAM-as-covariance-recovery hybrid path** — couples Fact #52 OpenCV solvePnPRansac mandatory-simple-baseline + Fact #54 GTSAM modern-competitive-lead-covariance-honest); **(c)** project-defined heuristic covariance scaling from inlier residual statistics (lowest engineering, lowest correctness — **likely AC-NEW-4 REJECT** since it's effectively an identity-matrix-placeholder family); **(d)** migrate to OpenGV's `absolute_pose::optimize_nonlinear` with custom Jacobian propagation through bearing-vector residuals (~3-5 days engineering vs ~1 day for OpenCV; couples D-C4-2 with D-C4-1 selection of OpenGV-as-primary; STRONGER NEGATIVE than expected per Fact #53 closure — OpenGV's bearing-vector Jacobian is harder to recover than OpenCV's pixel Jacobian). **Recommendation**: D-C4-2 = (b) for the OpenCV-as-RANSAC + GTSAM-as-covariance-recovery hybrid path (project's recommended C4 architecture per Fact #54 closure) — provides AC-NEW-4 covariance honesty NATIVELY via GTSAM's `Marginals` posterior while keeping OpenCV's mandatory-simple-baseline RANSAC inlier detection at zero-effort Jetson deployment. D-C4-2 = (a) Jacobian-based recovery 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. Final lock at Plan phase after Jetson MVE.

3. **D-C4-3 NEW (raised by OpenGV closure 2026-05-08, Fact #53) — license-clearance verification** — 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, causing GitHub SPDX detector to fail to identify the license. Plan-phase decision-maker MUST choose between: **(a)** counsel-review of License.txt to confirm BSD-3-Clause-equivalent dual-use compatibility (~1-2 hours legal review; recommended for OpenGV adoption), **(b)** request author Laurent Kneip + ShanghaiTech Mobile Perception Lab to relicense canonical License.txt to OSI canonical BSD-3-Clause boilerplate (~1-3 weeks turnaround if responsive, may not be responsive given ~3-year staleness), **(c)** treat NOASSERTION as effective disqualifier and pivot to OpenCV-as-primary instead of OpenGV-as-primary (lowest risk, but loses OpenGV's richer-minimal-solver-coverage advantage), **(d)** elevate D-C4-3 to D-C1-1 license-posture decision and treat OpenGV as eligible only on D-C1-1 = (a) GPL-3.0 track or (c) keep-both-tracks-open (since BSD-3-Clause-equivalent without canonical template formatting is more ambiguous than GPL-3.0). **Recommendation**: D-C4-3 = (a) counsel-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. Applies only if D-C4-row final lock includes OpenGV.

4. **D-C4-4 NEW (raised by OpenGV closure 2026-05-08, Fact #53) — maintenance-staleness-mitigation strategy** — Source #84 GitHub API `pushed_at` field shows `laurentkneip/opengv` last commit at 2023-06-07T18:14:14Z = ~2 years 11 months stale at access time 2026-05-08; Doxygen documentation portal generation timestamp 2018-01-08 21:43:04 = 8.3 years old documentation. ShanghaiTech Mobile Perception Lab's claimed maintenance is contradicted by commit history. Plan-phase decision-maker MUST choose between: **(a)** accept-as-is + freeze upstream at git commit ea7c66f5e (lowest engineering; assumes Eigen 3.3.x continues to compile on JetPack 6 ARM Cortex-A78AE without patches; risk: future Eigen 3.4+ migration breaks build), **(b)** fork into project-controlled branch + apply Eigen-3.4+ + JetPack-6 + ARM Cortex-A78AE patches in-house (~1-2 weeks engineering; medium risk; allows future upstream-patch contribution), **(c)** migrate to Ceres-only manual implementation as fallback if OpenGV-specific patches not feasible at Jetson MVE phase (highest engineering at ~2-4 weeks; lowest dependency-lock risk), **(d)** downgrade OpenGV to "experimental" status and pivot to OpenCV-as-primary if D-C4-3 license-clearance fails OR Jetson MVE shows OpenCV's coverage is sufficient. **Recommendation**: D-C4-4 = (b) fork-and-patch 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. Applies only if D-C4-row final lock includes OpenGV.

5. (additional D-C4-N gates will be added as candidates close)

---
