# Test Specification — C4 Pose Estimator Component-scoped. Suite-level coverage in `_docs/02_document/tests/*.md`. ## Acceptance Criteria Traceability | AC ID | Acceptance Criterion (one-line) | Test IDs | Coverage | |-------|---------------------------------|----------|----------| | AC-1.1 | Frame-center GPS within 50 m for ≥80% of normal-flight photos | FT-P-01, **C4-IT-01** | Covered | | AC-1.2 | Frame-center GPS within 20 m for ≥50% | FT-P-01, **C4-IT-01** | Covered | | AC-1.4 | Estimate reports 95% covariance + source label | FT-P-03, **C4-IT-02** | Covered | | AC-4.1 | E2E latency <400 ms p95 (incl. Marginals) | NFT-PERF-01, **C4-PT-01** | Covered | | AC-NEW-5 | Operating envelope; thermal-throttle-driven covariance degradation hybrid | NFT-LIM-04, **C4-IT-03** | Covered (workstation portion) | --- ## Component-Internal Tests ### C4-IT-01: PnP convergence + WGS84 accuracy on Derkachi **Summary**: for the Derkachi normal segment, p80 of frame-center positions land within 50 m of ground truth, p50 within 20 m. **Traces to**: AC-1.1, AC-1.2 **Description**: feed `MatchResult` from C3 (Derkachi normal-segment fixture) into `estimate`; convert `position_wgs84` to local frame; compute distance to recorded GPS ground truth; assert p80 ≤ 50 m and p50 ≤ 20 m. **Input data**: `flight_derkachi/normal_segment_60_stills/` (with recorded GPS ground truth) + corresponding C3 `MatchResult` outputs (replayed from a recorded fixture so the test is C4-isolated). **Expected result**: p80 ≤ 50 m, p50 ≤ 20 m. **Max execution time**: 60 s. --- ### C4-IT-02: 6×6 covariance is SPD and honest under match degradation **Summary**: every emitted `PoseEstimate` carries an SPD `covariance_6x6`; under inlier degradation (synthetically reduced inlier count), the covariance norm rises monotonically. **Traces to**: AC-1.4 **Description**: replay 100 frames; for each, assert (a) covariance is symmetric and positive-definite, (b) when a fixture-injected inlier-degradation event occurs at frame 50, the cov norm rises and stays elevated for ≥10 frames. Also assert `source_label` reflects the gate state — `satellite_anchored` only when C5's gate confirms; `visual_propagated` otherwise. **Input data**: `synthetic_matcher/inlier_degradation_at_f50/`. **Expected result**: 100/100 frames pass SPD invariant; cov norm rises ≥1.5× steady-state for the degradation interval. **Max execution time**: 60 s. --- ### C4-IT-03: D-CROSS-LATENCY-1 hybrid auto-degrade switch **Summary**: when `ThermalState.throttle == true`, `current_covariance_mode()` returns `JACOBIAN`; when false, returns `MARGINALS`. The switch is per-frame. **Traces to**: AC-NEW-5 (workstation-baseline portion; hot-soak chamber deferred) **Description**: drive a 60 s replay alternating thermal flag every 5 s; assert `covariance_mode` in each emitted `PoseEstimate` matches the input thermal flag for that frame; assert no jitter or hysteresis (the spec calls for per-frame decision). **Input data**: synthetic frames + a `ThermalState` injection harness. **Expected result**: 100% match between thermal input and `covariance_mode` output. **Max execution time**: 90 s. --- ### C4-IT-04: shared-graph integration with C5 **Summary**: factors added by C4 to C5's iSAM2 graph survive an `update`/`marginalCovariance` cycle without corrupting prior keyframes. **Traces to**: AC-1.4 (defensive — backstops the C4↔C5 shared-substrate co-dependency per ADR-003) **Description**: in a single test process, instantiate C5 with a 10-keyframe synthetic prior; have C4 add a `GenericProjectionFactorCal3DS2` for keyframe 11; trigger iSAM2 update; assert (a) the previously-known keyframe poses change by less than configurable tolerance (10 cm position, 0.5° rotation), (b) marginals on every keyframe remain SPD. **Input data**: synthetic 10-keyframe iSAM2 prior + a known correspondence set. **Expected result**: prior-keyframe perturbations within tolerance; SPD invariant holds. **Max execution time**: 60 s. --- ## Performance Tests ### C4-PT-01: Marginals vs Jacobian path latency on Tier-2 **Traces to**: AC-4.1 **Load scenario**: 3 Hz, 10 min replay; thermal flag toggled every 30 s to exercise both modes. **Expected results**: | Metric | Target | Failure Threshold | |--------|--------|-------------------| | `estimate` p95 (MARGINALS, K=15) | ≤ 90 ms | 130 ms | | `estimate` p95 (JACOBIAN) | ≤ 15 ms | 25 ms | | Mode-switch latency | < 1 frame (i.e., next-frame switch) | > 1 frame | --- ## Security Tests C4 has no externally-reachable surface. --- ## Acceptance Tests Covered transitively via FT-P-01 / FT-P-03 / FT-P-09-AP / FT-P-09-iNav. --- ## Test Data Management | Data Set | Source | Size | |----------|--------|------| | Replayed C3 `MatchResult` for Derkachi | recorded once via fixture-build script | ~30 MB | | `synthetic_matcher/inlier_degradation_at_f50/` | generated | ~10 MB | | Synthetic 10-keyframe iSAM2 prior | scripted | <1 MB | **Setup**: replay fixture must be re-recorded if C3's output schema changes (versioned in `tests/fixtures/c4_inputs//`). **Teardown**: read-only. **Data isolation**: per-test temp dirs.