# FT-P-05 + FT-P-06 — Satellite-anchor cross-domain registration + MRE budgets

**Task**: AZ-413_ft_p_05_06_sat_anchor_mre
**Name**: Cross-domain matcher registration + Mean Reprojection Error budgets (AC-2.1b, AC-2.2)
**Description**: Implement FT-P-05 (satellite-anchor cross-domain registration with MRE < 2.5 px and accuracy budget) and FT-P-06 (frame-to-frame MRE < 1.0 px and cross-domain MRE < 2.5 px at 95th percentile). FT-P-06 piggybacks on FT-P-04 + FT-P-05 runs and only adds the MRE 95th-percentile assertion.
**Complexity**: 3 points
**Dependencies**: AZ-406, AZ-407, AZ-412 (FT-P-06 reuses FT-P-04 MRE collection)
**Component**: Blackbox Tests / Positive (epic AZ-262)
**Tracker**: AZ-413
**Epic**: AZ-262 (E-BBT)

## Problem

Two AC bind the cross-domain matcher (UAV → satellite tile) quality: AC-2.1b (registration succeeds with MRE in budget) and AC-2.2 (95th-percentile MRE < 1.0 px frame-to-frame, < 2.5 px cross-domain). Both are direct measurements of C3 / C3.5 quality and are required to validate the matcher choice.

## Outcome

- pytest scenarios at `e2e/tests/positive/test_ft_p_05_sat_anchor.py` (FT-P-05) and a small piggyback assertion in `e2e/tests/positive/test_ft_p_06_mre_budgets.py` (FT-P-06).
- FT-P-05: pushes each `still-image-set-60` image; reads per-frame MRE (via `NAMED_VALUE_FLOAT` or FDR); aggregates per-image accuracy AND MRE distribution; asserts MRE < 2.5 px for all images, ≥80 % within 50 m of GT, ≥50 % within 20 m of GT.
- FT-P-06: depends on the runs of FT-P-04 (frame-to-frame MRE) and FT-P-05 (cross-domain MRE); aggregates by domain; asserts 95th-percentile MRE < 1.0 px frame-to-frame, < 2.5 px cross-domain.
- CSV evidence: `e2e-results/run-${RUN_ID}/ft-p-05.csv` (one row per image: `image_id, est_lat, est_lon, error_m, mre_px, pass_50m, pass_20m, pass_mre`).

## Scope

### Included
- FT-P-05 test method.
- FT-P-06 piggyback method that reads FT-P-04 + FT-P-05 evidence and adds the 95th-percentile assertion.
- Per-image MRE retrieval via `NAMED_VALUE_FLOAT` or post-run FDR archive read.

### Excluded
- The 60-image accuracy-only assertion (AC-1.1, AC-1.2) — owned by FT-P-01 (AZ-409).
- The Derkachi frame-to-frame success ratio (AC-2.1a) — owned by FT-P-04.
- C3.5 conditional-refiner-specific assertions — out of scope; AC-2.1b is on the matcher pipeline as a whole.

## Acceptance Criteria

**AC-1: per-image MRE captured**
Given each `still-image-set-60` image
Then the test records the per-frame MRE in `ft-p-05.csv`.

**AC-2: cross-domain MRE budget (per image)**
Given each per-image MRE
Then `mre_px < 2.5` for all 60 images (per AC-2.1b "all images").

**AC-3: accuracy budget alongside MRE**
Given the same 60 images
Then ≥80 % satisfy `error_m ≤ 50` AND ≥50 % satisfy `error_m ≤ 20` (matches FT-P-01 thresholds; this assertion may be loosened to "implied by FT-P-01" if FT-P-01 already passes in the same run).

**AC-4: 95th-percentile MRE budget (FT-P-06)**
Given FT-P-04 + FT-P-05 evidence
Then `MRE_95th_percentile_frame_to_frame < 1.0 px` AND `MRE_95th_percentile_cross_domain < 2.5 px`.

**AC-5: parameterization**
Given the conftest's `(fc_adapter, vio_strategy)` parameterization
Then both test files run per parameterization.

## System Under Test Boundary

End-to-end through public boundaries.

- **Allowed**: `NAMED_VALUE_FLOAT` MRE exposure OR post-run FDR archive read.
- **Forbidden**: importing C3 / C3.5 matcher state, stubbing the matcher to force a specific MRE.

## Constraints

- The per-frame MRE must be exposed as a documented public artifact (NAMED_VALUE_FLOAT key or FDR field) — if absent, the test fails.
- The 95th-percentile is computed strictly (linear interpolation between the two adjacent ranks per numpy's default percentile algorithm).

## Document Dependencies

- `_docs/02_document/tests/blackbox-tests.md` § FT-P-05, § FT-P-06
- `_docs/02_document/tests/test-data.md` § Image processing quality
