# FT-N-04 — Visual blackout + spoofed GPS combined failsafe

**Task**: AZ-426_ft_n_04_blackout_spoof
**Name**: AC-3.5 + AC-NEW-8 combined failsafe — switch label, reject spoof, propagate, monotonic covariance, STATUSTEXT (AC-3.5, AC-NEW-8)
**Description**: Implement FT-N-04 — three sub-cases at 5 s / 15 s / 35 s blackout windows paired with FC GPS spoof; assert mode transition ≤400 ms or ≤1 frame; spoofed GPS rejected; covariance monotonic; honest `horiz_accuracy`; `VISUAL_BLACKOUT_IMU_ONLY` STATUSTEXT at 1-2 Hz; 35 s window adds covariance-threshold escalations.
**Complexity**: 5 points
**Dependencies**: AZ-406, AZ-407, AZ-408
**Component**: Blackbox Tests / Negative / Security (epic AZ-262)
**Tracker**: AZ-426
**Epic**: AZ-262 (E-BBT)

## Problem

The combined "visual-blackout + spoofed-GPS" failsafe is the project's most security-critical degradation mode. AC-3.5 + AC-NEW-8 prescribe a multi-step ladder (label switch, spoof rejection, monotonic covariance, honest reporting, escalation thresholds) that is genuinely hard to validate end-to-end. This must be exercised with synthetic spoof injection.

## Outcome

- pytest scenario at `e2e/tests/negative/test_ft_n_04_blackout_spoof.py` with three sub-tests (5 s, 15 s, 35 s windows) using `blackout_spoof.py`.
- For every sub-case asserts:
  - Within ≤1 frame OR ≤400 ms of blackout-onset: `source_label = dead_reckoned`; spoofed GPS rejected; covariance grows monotonically.
  - `horiz_accuracy ≥ 0.95 × cov_semi_major_m` (no under-reporting).
  - GCS receives `VISUAL_BLACKOUT_IMU_ONLY` STATUSTEXT at 1-2 Hz throughout the blackout.
- For the 35 s window only:
  - When 95 % covariance crosses 100 m → fix-quality degraded ("2D fix or worse" in MAVLink fix_type).
  - When 95 % covariance crosses 500 m OR blackout exceeds 30 s → `horiz_accuracy=999.0` AND `VISUAL_BLACKOUT_FAILSAFE` STATUSTEXT.
- After blackout end: recovery only after FC GPS-health stable + non-spoofed for ≥10 s AND a visual/satellite consistency check succeeds.

## Scope

### Included
- All three sub-cases (5 s, 15 s, 35 s).
- Multi-step ladder assertions per sub-case.
- 35 s window covariance-threshold escalations.
- Recovery-gate assertion (≥10 s of stable non-spoofed FC GPS before re-promotion).

### Excluded
- Pure-blackout (no spoof) — owned by NFT-RES-01 / FT-N-03.
- Cache-poisoning safety — owned by NFT-SEC-01.

## Acceptance Criteria

**AC-1: switch latency**
Given any blackout-onset event
Then within ≤1 frame OR ≤400 ms (whichever is shorter for the run's frame rate), `source_label = dead_reckoned`.

**AC-2: spoof rejection**
Given the FC inbound proxy injects spoofed GPS during the window
Then the SUT does NOT consume the spoofed GPS into the estimator (verifiable via FDR `spoof-rejected` events).

**AC-3: monotonic covariance**
Given the per-frame `cov_semi_major_m` stream within the blackout
Then `cov_semi_major_m` is non-decreasing across consecutive emissions.

**AC-4: honest horiz_accuracy**
Given the outbound `GPS_INPUT.horiz_accuracy` (AP) field
Then `horiz_accuracy ≥ 0.95 × cov_semi_major_m` for every emission within the blackout.

**AC-5: STATUSTEXT 1-2 Hz**
Given the GCS-side mavproxy capture
Then `VISUAL_BLACKOUT_IMU_ONLY` STATUSTEXT messages are emitted at a rate in `[1, 2]` Hz throughout the blackout.

**AC-6 (35 s only): 100 m covariance escalation**
Given the 35 s window
When 95 % covariance crosses 100 m
Then outbound MAVLink reports fix-quality degraded (2D fix or worse).

**AC-7 (35 s only): 500 m / 30 s escalation**
When 95 % covariance crosses 500 m OR blackout exceeds 30 s
Then `horiz_accuracy=999.0` AND `VISUAL_BLACKOUT_FAILSAFE` STATUSTEXT emitted within ≤500 ms of the threshold crossing.

**AC-8: recovery gate**
Given blackout ends and FC GPS-health is restored
Then recovery to `satellite_anchored` only after: (a) FC GPS-health stable + non-spoofed for ≥10 s AND (b) a visual/satellite consistency check succeeds.

**AC-9: parameterization**
Given conftest parameterization
Then all sub-cases run per `(fc_adapter, vio_strategy)` for AP (where signing is in play), `fc_adapter=inav` exercises the same ladder minus the AP-specific signing context.

## System Under Test Boundary

End-to-end through public boundaries.

- **Allowed**: blackout_spoof injector (a public-input fault), FDR `spoof-rejected` events, mavproxy STATUSTEXT capture, outbound `horiz_accuracy` field.
- **Forbidden**: stubbing the spoof detector, monkeypatching the source-label state machine.

## Constraints

- All AC numerical thresholds match the AC-3.5 / AC-NEW-8 text exactly; deviation is a real defect signal.
- The recovery-gate ≥10 s is wall-clock measured by the runner.

## Document Dependencies

- `_docs/02_document/tests/blackbox-tests.md` § FT-N-04
- `_docs/02_document/tests/test-data.md` § Resilience (FT-N-04 row)
