# Integration Test: Failure Recovery Coordinator (F11)

## Summary
Validate the Failure Recovery Coordinator that detects processing failures and coordinates recovery strategies. F11 is a pure logic component that returns status objects - it does NOT directly emit events or communicate with clients.

## Component Under Test
**Component**: Failure Recovery Coordinator (F11)
**Interface**: `IFailureRecoveryCoordinator`
**Dependencies**:
- F04 Satellite Data Manager (search grids)
- F06 Image Rotation Manager (rotation sweeps)
- F08 Global Place Recognition (candidate retrieval)
- F09 Metric Refinement (alignment)
- F10 Factor Graph Optimizer (anchor application)
- F12 Route Chunk Manager (chunk operations)

## Architecture Pattern
**Pure Logic Component**: F11 coordinates recovery strategies but delegates execution and communication.
- **NO Events**: Returns status objects or booleans
- **Caller Responsibility**: F02.2 decides state transitions based on F11 returns
- **Chunk Orchestration**: Coordinates F12 and F10 operations during recovery

## Detailed Description
Per AC-6: "In case of being absolutely incapable of determining the system to determine next, second next, and third next images GPS, by any means (these 20% of the route), then it should ask the user for input for the next image."

Tests that the coordinator can:
1. Assess tracking confidence from VO and LiteSAM results
2. Detect tracking loss conditions
3. Coordinate progressive tile search (1→4→9→16→25)
4. Create user input request objects (NOT send them)
5. Apply user-provided GPS anchors
6. Proactively create chunks on tracking loss
7. Coordinate chunk semantic matching
8. Coordinate chunk LiteSAM matching with rotation sweeps
9. Merge chunks to main trajectory

## Input Data

### Test Case 1: Check Confidence (Good)
- **Input**: VO result with 80 inliers, LiteSAM confidence 0.85
- **Expected**: 
  - Returns ConfidenceAssessment
  - tracking_status = "good"
  - overall_confidence > 0.7

### Test Case 2: Check Confidence (Degraded)
- **Input**: VO result with 35 inliers, LiteSAM confidence 0.5
- **Expected**: 
  - Returns ConfidenceAssessment
  - tracking_status = "degraded"
  - overall_confidence 0.3-0.7

### Test Case 3: Check Confidence (Lost)
- **Input**: VO result with 10 inliers, no LiteSAM result
- **Expected**: 
  - Returns ConfidenceAssessment
  - tracking_status = "lost"
  - overall_confidence < 0.3

### Test Case 4: Detect Tracking Loss
- **Input**: ConfidenceAssessment with tracking_status = "lost"
- **Expected**: Returns True (tracking lost)

### Test Case 5: Start Search
- **Input**: flight_id, frame_id, estimated_gps
- **Expected**: 
  - Returns SearchSession
  - session.current_grid_size = 1
  - session.found = False
  - session.exhausted = False

### Test Case 6: Expand Search Radius
- **Input**: SearchSession with grid_size = 1
- **Action**: Call expand_search_radius()
- **Expected**: 
  - Returns List[TileCoords] (3 new tiles for 2x2 grid)
  - session.current_grid_size = 4

### Test Case 7: Try Current Grid (Match Found)
- **Input**: SearchSession, tiles dict with matching tile
- **Expected**: 
  - Returns AlignmentResult
  - result.matched = True
  - result.gps populated

### Test Case 8: Try Current Grid (No Match)
- **Input**: SearchSession, tiles dict with no matching tile
- **Expected**: 
  - Returns None
  - Caller should call expand_search_radius()

### Test Case 9: Mark Found
- **Input**: SearchSession, AlignmentResult
- **Expected**: 
  - Returns True
  - session.found = True

### Test Case 10: Get Search Status
- **Input**: SearchSession
- **Expected**: 
  - Returns SearchStatus
  - Contains current_grid_size, found, exhausted

### Test Case 11: Create User Input Request
- **Input**: flight_id, frame_id, candidate_tiles
- **Expected**: 
  - Returns UserInputRequest object (NOT sent)
  - Contains request_id, flight_id, frame_id
  - Contains uav_image, candidate_tiles, message
  - **NOTE**: Caller (F02.2) sends to F15

### Test Case 12: Apply User Anchor
- **Input**: flight_id, frame_id, UserAnchor with GPS
- **Expected**: 
  - Calls F10.add_absolute_factor() with high confidence
  - Returns True if successful
  - **NOTE**: Caller (F02.2) updates state and publishes result

### Test Case 13: Create Chunk on Tracking Loss
- **Input**: flight_id, frame_id
- **Expected**: 
  - Calls F12.create_chunk()
  - Returns ChunkHandle
  - chunk.is_active = True
  - chunk.has_anchor = False
  - chunk.matching_status = "unanchored"

### Test Case 14: Try Chunk Semantic Matching
- **Input**: chunk_id (chunk with 10 frames)
- **Expected**: 
  - Gets chunk images via F12
  - Calls F08.retrieve_candidate_tiles_for_chunk()
  - Returns List[TileCandidate] or None

### Test Case 15: Try Chunk LiteSAM Matching
- **Input**: chunk_id, candidate_tiles
- **Expected**: 
  - Gets chunk images via F12
  - Calls F06.try_chunk_rotation_steps() (12 rotations)
  - Returns ChunkAlignmentResult or None
  - Result contains rotation_angle, chunk_center_gps, transform

### Test Case 16: Merge Chunk to Trajectory
- **Input**: flight_id, chunk_id, ChunkAlignmentResult
- **Expected**: 
  - Calls F12.mark_chunk_anchored()
  - Calls F12.merge_chunks()
  - Returns True if successful
  - **NOTE**: Caller (F02.2) coordinates result updates

### Test Case 17: Process Unanchored Chunks (Logic)
- **Input**: flight_id with 2 unanchored chunks
- **Expected**: 
  - Calls F12.get_chunks_for_matching()
  - For each ready chunk:
    - try_chunk_semantic_matching()
    - try_chunk_litesam_matching()
    - merge_chunk_to_trajectory() if match found

### Test Case 18: Progressive Search Full Flow
- **Scenario**: 
  - start_search() → grid_size=1
  - try_current_grid() → None
  - expand_search_radius() → grid_size=4
  - try_current_grid() → None
  - expand_search_radius() → grid_size=9
  - try_current_grid() → AlignmentResult
  - mark_found() → success
- **Expected**: Search succeeds at 3x3 grid

### Test Case 19: Search Exhaustion Flow
- **Scenario**: 
  - start_search()
  - try all grids: 1→4→9→16→25, all fail
  - create_user_input_request()
- **Expected**: 
  - Returns UserInputRequest
  - session.exhausted = True
  - **NOTE**: Caller sends request, waits for user fix

### Test Case 20: Chunk Recovery Full Flow
- **Scenario**: 
  - create_chunk_on_tracking_loss() → chunk created
  - Processing continues in chunk
  - try_chunk_semantic_matching() → candidates found
  - try_chunk_litesam_matching() → match at 90° rotation
  - merge_chunk_to_trajectory() → success
- **Expected**: Chunk anchored and merged without user input

## Expected Output

### ConfidenceAssessment
```json
{
  "overall_confidence": 0.85,
  "vo_confidence": 0.9,
  "litesam_confidence": 0.8,
  "inlier_count": 80,
  "tracking_status": "good|degraded|lost"
}
```

### SearchSession
```json
{
  "session_id": "string",
  "flight_id": "string",
  "frame_id": 42,
  "center_gps": {"latitude": 48.275, "longitude": 37.385},
  "current_grid_size": 4,
  "max_grid_size": 25,
  "found": false,
  "exhausted": false
}
```

### UserInputRequest
```json
{
  "request_id": "string",
  "flight_id": "string",
  "frame_id": 42,
  "candidate_tiles": [...],
  "message": "Please provide GPS location for this frame"
}
```

### ChunkAlignmentResult
```json
{
  "matched": true,
  "chunk_id": "string",
  "chunk_center_gps": {"latitude": 48.275, "longitude": 37.385},
  "rotation_angle": 90.0,
  "confidence": 0.85,
  "inlier_count": 150,
  "transform": {...}
}
```

## Success Criteria

**Test Cases 1-4 (Confidence)**:
- Confidence assessment accurate
- Thresholds correctly applied
- Tracking loss detected correctly

**Test Cases 5-10 (Progressive Search)**:
- Search session management works
- Grid expansion correct (1→4→9→16→25)
- Match detection works

**Test Cases 11-12 (User Input)**:
- UserInputRequest object created correctly (not sent)
- User anchor applied correctly

**Test Cases 13-17 (Chunk Recovery)**:
- Proactive chunk creation works
- Chunk semantic matching works
- Chunk LiteSAM matching with rotation works
- Chunk merging works

**Test Cases 18-20 (Full Flows)**:
- Progressive search flow completes
- Search exhaustion flow completes
- Chunk recovery flow completes

## Maximum Expected Time
- check_confidence: < 10ms
- detect_tracking_loss: < 5ms
- Progressive search (25 tiles): < 1.5s total
- create_user_input_request: < 100ms
- apply_user_anchor: < 500ms
- Chunk semantic matching: < 2s
- Chunk LiteSAM matching (12 rotations): < 10s
- Total test suite: < 120 seconds

## Pass/Fail Criteria

**Overall Test Passes If**:
- All 20 test cases pass
- Confidence assessment accurate
- Progressive search works
- User input request created correctly (not sent)
- Chunk recovery works
- No direct event emission (pure logic)

**Test Fails If**:
- Tracking loss not detected when should be
- Progressive search fails to expand correctly
- User input request not created when needed
- F11 directly emits events (violates architecture)
- Chunk recovery fails
- Performance exceeds targets

## Architecture Validation

**F11 Must NOT**:
- Call F15 directly (SSE events)
- Emit events to clients
- Manage processing state
- Control processing flow

**F11 Must**:
- Return status objects for all operations
- Let caller (F02.2) decide next actions
- Coordinate with F10, F12 for chunk operations
- Be testable in isolation (no I/O dependencies)
