# NFT-RES-01 — IMU-only fallback drift bound

**Task**: AZ-432_nft_res_01_imu_only_fallback
**Name**: 30 s vision blackout drift bound: 100 m without good IMU, 50 m with CombinedImuFactor (AC-3.5, AC-NEW-7)
**Description**: Implement NFT-RES-01 — Derkachi replay; inject 30 s pure-black-frame window (no spoof); measure drift between estimate at blackout onset and estimate at blackout end against GT.
**Complexity**: 3 points
**Dependencies**: AZ-406, AZ-407, AZ-408 (blackout_spoof with `--no-spoof` flag)
**Component**: Blackbox Tests / Resilience (epic AZ-262)
**Tracker**: AZ-432
**Epic**: AZ-262 (E-BBT)

## Problem

The 30 s pure-vision-blackout drift bound is the project's IMU-fusion-quality cornerstone. AC-3.5 / AC-NEW-7 prescribe two budgets — 100 m without IMU, 50 m with CombinedImuFactor — and only by exercising both paths can the project verify the IMU fusion's value.

## Outcome

- pytest scenario at `e2e/tests/resilience/test_nft_res_01_imu_only_fallback.py`. Tier-1 OR Tier-2.
- Two sub-cases:
  - (a) "No good IMU" = SUT runs without IMU input or with IMU disabled in C5.
  - (b) "Good IMU + CombinedImuFactor" = SUT's default config.
- Each sub-case: 30 s blackout (no spoof); measure drift at blackout end vs GT.
- Assert `drift ≤ 100 m` (no IMU) AND `drift ≤ 50 m` (CombinedImuFactor).

## Scope

### Included
- Both sub-cases.
- Per-sub-case drift measurement.

### Excluded
- Spoof-paired blackout — owned by FT-N-04.
- Cumulative-drift over multiple blackouts — owned by FT-P-08.

## Acceptance Criteria

**AC-1: 30 s window injected**
Given the no-spoof blackout injector
Then a 30 s pure-black-frame window is active during the measurement.

**AC-2: drift bound (no IMU)**
Given sub-case (a)
Then `drift_at_t_end ≤ 100 m`.

**AC-3: drift bound (CombinedImuFactor)**
Given sub-case (b)
Then `drift_at_t_end ≤ 50 m`.

**AC-4: parameterization**
Given conftest parameterization
Then both sub-cases run per `(fc_adapter, vio_strategy)`.

## System Under Test Boundary

End-to-end through public boundaries.

- **Allowed**: no-spoof blackout injector, outbound estimate stream, GT from `data_imu.csv`.
- **Forbidden**: stubbing C5 IMU-fusion path; sub-case (a) uses the SUT's documented "disable IMU" config flag if one exists, OR an empty IMU stream from the FC inbound proxy.

## Constraints

- Drift is `vincenty(estimate_at_t_end, GT_at_t_end)`.
- Sub-case (a) MUST exercise a real "no IMU" config path; if the SUT cannot be configured this way, the test fails AC-2.

## Document Dependencies

- `_docs/02_document/tests/resilience-tests.md` § NFT-RES-01
- `_docs/02_document/tests/test-data.md` § Resilience (NFT-RES-01 row)
