# Feature: Chunk Lifecycle Management

## Name
Chunk Lifecycle Management

## Description
Core operations for creating, growing, and managing the lifecycle of route chunks. Chunks are first-class entities in the Atlas multi-map architecture, created proactively on tracking loss to continue processing without failure. This feature handles the fundamental CRUD-like operations for chunk management and maintains internal state tracking.

## Component APIs Implemented

### `create_chunk(flight_id: str, start_frame_id: int) -> ChunkHandle`
Creates a new route chunk when tracking is lost or proactively by F11.
- Generates unique chunk_id
- Calls F10.create_new_chunk() to initialize subgraph
- Initializes chunk state (unanchored, active)
- Stores ChunkHandle in internal dictionary

### `add_frame_to_chunk(chunk_id: str, frame_id: int, vo_result: RelativePose) -> bool`
Adds a frame to an active chunk during frame processing.
- Verifies chunk exists and is active
- Appends frame_id to chunk's frames list
- Calls F10.add_relative_factor_to_chunk()
- Updates end_frame_id

### `get_active_chunk(flight_id: str) -> Optional[ChunkHandle]`
Retrieves the currently active chunk for a flight.
- Queries internal state dictionary
- Returns ChunkHandle with is_active=True or None

### `deactivate_chunk(chunk_id: str) -> bool`
Deactivates a chunk after merging or completion.
- Sets is_active=False on ChunkHandle
- Does not delete chunk data

## External Tools and Services
- **F10 Factor Graph Optimizer**: `create_new_chunk()`, `add_relative_factor_to_chunk()`

## Internal Methods

### `_generate_chunk_id() -> str`
Generates unique chunk identifier (UUID or sequential).

### `_validate_chunk_active(chunk_id: str) -> bool`
Checks if chunk exists and is_active=True.

### `_get_chunk_by_id(chunk_id: str) -> Optional[ChunkHandle]`
Internal lookup in _chunks dictionary.

### `_update_chunk_end_frame(chunk_id: str, frame_id: int)`
Updates end_frame_id after adding frame.

## Unit Tests

### Test: create_chunk_returns_active_handle
- Call create_chunk(flight_id, start_frame_id)
- Assert returned ChunkHandle has is_active=True
- Assert chunk_id is non-empty string
- Assert start_frame_id matches input

### Test: create_chunk_calls_f10
- Call create_chunk()
- Assert F10.create_new_chunk() was called with correct parameters

### Test: create_multiple_chunks_same_flight
- Create chunk_1 and chunk_2 for same flight
- Assert both chunks exist with different chunk_ids

### Test: add_frame_to_active_chunk
- Create chunk
- Call add_frame_to_chunk() with valid frame
- Assert returns True
- Assert frame_id in chunk.frames

### Test: add_frame_updates_end_frame_id
- Create chunk with start_frame_id=10
- Add frames 11, 12, 13
- Assert end_frame_id=13

### Test: add_frame_to_inactive_chunk_fails
- Create chunk, then deactivate_chunk()
- Call add_frame_to_chunk()
- Assert returns False

### Test: add_frame_to_nonexistent_chunk_fails
- Call add_frame_to_chunk("invalid_id", ...)
- Assert returns False

### Test: get_active_chunk_returns_correct_chunk
- Create chunk for flight_1
- Assert get_active_chunk(flight_1) returns chunk
- Assert get_active_chunk(flight_2) returns None

### Test: get_active_chunk_none_when_deactivated
- Create chunk, then deactivate
- Assert get_active_chunk() returns None

### Test: deactivate_chunk_success
- Create chunk
- Call deactivate_chunk()
- Assert returns True
- Assert chunk.is_active=False

### Test: deactivate_nonexistent_chunk_fails
- Call deactivate_chunk("invalid_id")
- Assert returns False

## Integration Tests

### Test: chunk_lifecycle_flow
1. create_chunk() → verify ChunkHandle
2. add_frame_to_chunk() × 10 → verify frames list grows
3. get_active_chunk() → returns the chunk
4. deactivate_chunk() → chunk deactivated
5. get_active_chunk() → returns None

### Test: multiple_chunks_isolation
1. Create chunk_1 (flight_A)
2. Create chunk_2 (flight_A)
3. Add frames to chunk_1
4. Add frames to chunk_2
5. Verify frames lists are independent
6. Verify only one can be active at a time per flight

