# Component Fit Matrix — C10: Pre-flight cache provisioning (cross-coupling minimal scope)

> Mode A Phase 2 — engine Step 7.5 (Component Applicability Gate). C10 was promoted to its own row file on 2026-05-08 after user-locked scope narrowing (`c10_scope=C` cross-coupling minimal — see [`../00_question_decomposition.md` → "C10 Scope Restructure"](../00_question_decomposition.md)). Operator CLI/desktop tooling, sector classification heuristics, and tile age-stamping/freshness schema are **deferred to Plan-phase as `operator tooling design` out-of-research-scope**. C10 batch 1 covers only the two cross-coupling confirmation sub-areas: D-C6-3 (descriptor-cache rebuild trigger pipeline) and D-C7-7 (TensorRT engine-build pipeline).
>
> Index: [`00_summary.md`](00_summary.md). Sibling components: [C1 VIO](C1_vio.md), [C2 VPR](C2_vpr.md), [C3 Matchers](C3_matchers.md), [C4 Pose](C4_pose_estimation.md), [C5 State estimator](C5_state_estimator.md), [C6 Tile cache + spatial index](C6_tile_cache_spatial_index.md), [C7 On-Jetson inference runtime](C7_inference_runtime.md), [C8 MAVLink / MSP2 FC adapter](C8_fc_adapter.md). Cross-component gates: [`99_cross_component_gates.md`](99_cross_component_gates.md). C9 dropped per 2026-05-08 restructure.

---

## C10 — Pre-flight cache provisioning + sector classification (CROSS-COUPLING MINIMAL scope)

**Status**: IN PROGRESS at 0/2 (batch 1 = 2 sub-areas; opened 2026-05-08).

**Pinned input/output contract (per the locked C10 scope)**:
- inputs:
  - `descriptor_blobs[*]` per tile = the per-tile global VPR descriptor (per D-C2-9 / D-C2-10 / D-C2-6 final lock: dimension d ∈ {256, 512, 1024, 2048, 4096} float32 or halfvec) — produced offline at C10 pre-flight by running C2 VPR backbone over each cached tile image.
  - `onnx_models[*]` per inference target = the ONNX-exported model graphs for C2 VPR backbone + C3 matcher + (optional) C1 learned VIO frontend, exported on the dev machine via `torch.onnx.export`.
  - `calibration_corpus` = real UAV nadir flight footage at ~1 km AGL over season-matched satellite tiles (per D-C7-1 closure, fixture-file pin delegated to Test Spec) — ~500-1,500 representative samples; binary tensor format `[N, C, H, W]`.
  - `target_jetson_uri` = SSH/serial address of the deployed Jetson Orin Nano Super target (or `localhost` when build runs on the deployed Jetson directly).
- outputs:
  - **`/var/lib/onboard/cache/faiss/v_<descriptor_dim>_M<HNSW_M>.index`** = FAISS HNSW index file written via `faiss.write_index(index, path)`; loaded at takeoff via `faiss.read_index(path)`; sized at ~`(n_tiles × d × 2 B halfvec) + (n_tiles × M × 4 B graph links)`. Per-takeoff load latency target <5 s.
  - **`/var/lib/onboard/cache/trt/<model>_sm87_jp62_trt103_<precision>.engine`** = serialized TensorRT engine file produced by `trtexec` or `IBuilderSerializationConfig.serialize()`; loaded at takeoff via `IRuntime.deserializeCudaEngine`; tied to SM 87 (Jetson Orin Nano Super Ampere) per Source #105.
  - **Build/rebuild manifest** = single JSON file recording `(model_name, precision_mode, calib_data_sha256, build_start_iso8601, build_duration_sec, engine_sha256, target_sm, jetpack_version, trt_version)` per engine; `(descriptor_dim, n_tiles, faiss_M, ef_construction, build_duration_sec, faiss_sha256)` per FAISS index. Fed into AC-NEW-3 FDR.
- runtime context:
  - **Pre-flight only**, NOT runtime. Build/rebuild cost amortized across all takeoffs that use the same artifacts. Per-mission rebuild only if `calibration_corpus` or `descriptor_blobs[*]` changed (manifest-hash-driven).
  - Build runs ON the deployed Jetson Orin Nano Super (per D-C7-7 = primary build-on-target). Reference-Jetson-prebuilt engine fallback supported (per D-C7-7 = fallback path) when pre-flight build fails or is skipped.

---

## Candidate matrix (batch 1 CLOSED at 2/N on 2026-05-08)

| Sub-area | Candidate | Pinned Mode/Config | Option Family | Intended Role | API Capability Evidence | Mismatches / Disqualifiers | Status | Decision Rationale |
|---|---|---|---|---|---|---|---|---|
| **Sub-area 1: D-C6-3 confirmation** | Direct `faiss.write_index` / `faiss.read_index` Python API + `python-atomicwrites` + content-hash verification gate at takeoff + manifest-hash-driven rebuild trigger + `IO_FLAG_MMAP_IFC` mmap load | `faiss.IndexHNSWFlat(d=descriptor_dim, M=32)` build per pre-flight when `manifest_hash` changed; `faiss.write_index(index, temp_path)` + atomic-rename + content-hash; takeoff load via `faiss.read_index(target_path, faiss.IO_FLAG_MMAP_IFC)` after content-hash verification | Established production (FAISS MIT + python-atomicwrites MIT) + project-side orchestration wrapper | C6 ↔ C10 cross-component gate closure (D-C6-3 confirmation) | MVE: see [`../02_fact_cards/C10_preflight_provisioning.md` Fact #100](../02_fact_cards/C10_preflight_provisioning.md); docs: Source #114 (FAISS API), Source #115 (size formula), Source #116 (atomic write pattern) | None — content-hash gate mitigates the documented FAISS "no internal integrity check" warning per Source #114 | **Selected** | Closes D-C6-3 with idempotent + crash-safe + AC-NEW-7-compliant pipeline; license-clean; minimal abstraction surface; ~430 MB cache file at 2048-D halfvec × 100K tiles fits AC-8.3 + AC-4.2 + AC-NEW-1 budgets comfortably |
| **Sub-area 2: D-C7-7 confirmation** | Hybrid orchestration: Polygraphy CLI primary for INT8-calibrating builds + `trtexec` for cache-reuse fast rebuilds + direct `IBuilderConfig` Python API for unusual models (LightGlue dynamic shapes) | `polygraphy convert <model>.onnx --int8 --fp16 --data-loader-script ./calib_data_loader.py --calibration-cache <calib_cache> --workspace=1000000000 -o <engine>_sm87_jp62_trt103_<prec>.engine` (primary); `trtexec --onnx=... --saveEngine=... --fp16 --int8 --calib=... --shapes=...` (cache-reuse fallback); direct `IBuilderConfig` + `IInt8EntropyCalibrator2` Python API (escape hatch) | Established production NVIDIA-blessed orchestration (Polygraphy Apache-2.0; trtexec bundled with TensorRT 10.x Apache-2.0; direct API bundled with TensorRT 10.x) | C7 ↔ C10 cross-component gate closure (D-C7-7 confirmation) | MVE: see [`../02_fact_cards/C10_preflight_provisioning.md` Fact #101](../02_fact_cards/C10_preflight_provisioning.md); docs: Source #117 (Polygraphy CLI), Source #118 (Polygraphy Calibrator class), Source #119 (trtexec CLI), Source #120 (calib corpus size guidance), Source #121 (direct API cross-cite from C7 Source #105) | None — `trtexec --int8` without `--calib` random-data-fallback caveat is mitigated by project-side wrapper that enforces `--calib=<existing_cache>` non-empty as precondition | **Selected** | Closes D-C7-7 with hybrid tool matrix matching D-C10-5 = (d); operationalizes D-C7-1 closure (real UAV nadir flight footage corpus) via Polygraphy `--data-loader-script`; calibration-cache reuse keeps subsequent rebuilds <30 sec; license-clean Apache-2.0 throughout; engine cache files ~100-500 MB on disk separate from AC-8.3 tile cache budget |

---

## Working conclusions and decisions

**Selected primary**:
- **D-C6-3 confirmation** (Sub-area 1): direct `faiss.write_index` / `faiss.read_index` Python API + `python-atomicwrites` + content-hash verification gate + manifest-hash-driven rebuild trigger + optional `IO_FLAG_MMAP_IFC` mmap load. **Closes the C6 ↔ C10 cross-component gate.**
- **D-C7-7 confirmation** (Sub-area 2): hybrid Polygraphy + `trtexec` + direct `IBuilderConfig` Python API matrix per D-C10-5 = (d). Calibration corpus per D-C7-1 closure (real UAV nadir flight footage at ~1 km AGL over season-matched satellite tiles; specific fixture-file pin delegated to Test Spec). **Closes the C7 ↔ C10 cross-component gate.**

**Decisions raised (D-C10-N gates)** — see [`99_cross_component_gates.md`](99_cross_component_gates.md):

- **D-C10-1** (Fact #100) — descriptor-cache rebuild trigger choice — RECOMMENDED manifest-hash-driven + `--force-rebuild` override
- **D-C10-2** (Fact #100) — descriptor-cache atomic-write strategy — RECOMMENDED `python-atomicwrites`; fallback hand-rolled
- **D-C10-3** (Fact #100, CROSS-COMPONENT with AC-NEW-7) — content-hash verification gate at takeoff load — RECOMMENDED reject + STATUSTEXT + refuse takeoff
- **D-C10-4** (Fact #100) — descriptor-cache load path — RECOMMENDED mmap with `madvise(MADV_WILLNEED)` pre-fault (or both for Plan-phase Jetson MVE)
- **D-C10-5** (Fact #101, CROSS-COMPONENT with C7) — TensorRT engine-build orchestration tool choice — RECOMMENDED hybrid (Polygraphy + trtexec + direct API by use case)
- **D-C10-6** (Fact #101, CROSS-COMPONENT with D-C7-1) — TensorRT calibration-cache reuse strategy — RECOMMENDED rebuild-on-calib-corpus-SHA-256-change + `--force-trt-rebuild` override
- **D-C10-7** (Fact #101) — TensorRT engine on-disk filename schema — RECOMMENDED self-describing `<model>_sm<SM>_jp<JP>_trt<TRT>_<precision>.engine` filename + manifest.json side-cache
- **D-C10-8** (Fact #101) — TensorRT prebuilt-fallback engine generation venue — RECOMMENDED reference Jetson at HQ + deployed-Jetson-copy-to-archive on first successful local build (opportunistic redundancy)

**C10 batch 1 closed at 2/N on 2026-05-08.** **No further C10 batches required at the research layer** — D-C6-3 and D-C7-7 cross-component gates are now closed; remaining C10 questions (operator CLI/desktop tooling, sector classification heuristics, freshness pipeline workflow) are deferred to Plan-phase per the 2026-05-08 `c10_scope=C` user choice.

---

## Out-of-research-scope items (deferred to Plan-phase)

The following items were originally part of C10's "Required outputs" per `../00_question_decomposition.md` line 78 but were narrowed out of research scope by user choice C on 2026-05-08:

| Deferred item | Plan-phase owner | Why it doesn't need research |
|---|---|---|
| Operator-side CLI/desktop tool design | Plan-phase architect + UX | Tool shape is a UX/integration decision; doesn't bind any architectural contract |
| Sector classification (active-conflict vs stable rear) heuristics + interface | Plan-phase architect + operations team | AC-8.2 freshness threshold (6 mo vs 12 mo) is operational; heuristic source TBD (operator-marked geofence vs Suite Service metadata) |
| Tile age-stamping schema beyond restrictions.md mandate | Plan-phase architect | Restrictions.md already mandates per-tile capture date in manifest; additional sector-class tag is a Plan-phase decision |
| Freshness pipeline workflow | Plan-phase architect + operations team | When to re-pull from Suite Sat Service (every flight, weekly, on operator demand, on sector-class change) is operational |

These items will be revisited at Plan-phase. Their cross-coupling with the runtime architecture is mediated entirely by the descriptor-cache file (D-C6-3) and the TensorRT engine cache file (D-C7-7) — both pinned by C10 batch 1 confirmations.

---
