# Mission Executor State Machine (Both Variants)

**Task**: AZ-648_mission_executor_state_machine
**Name**: Variant-aware mission state machine
**Description**: Typed state machine for both multirotor and fixed-wing variants. Transitions are explicit and fully enumerated; bounded retry per transition with explicit max-retry. No infinite retry. State is in-process only; restart re-runs from `DISCONNECTED`.
**Complexity**: 5 points
**Dependencies**: AZ-640_initial_structure, AZ-641_mavlink_transport_and_heartbeat, AZ-642_mavlink_codec, AZ-643_mavlink_ack_demux_and_signing
**Component**: mission_executor
**Tracker**: AZ-648
**Epic**: AZ-636

## Problem

`mission_executor` drives the airframe through a typed state machine. The flow differs per variant (multirotor vs fixed-wing); both variants share the same transition discipline and observability surface. Every transition has a bounded retry budget — on cap exhaustion health flips to red and the failure surfaces via `operator_bridge`. **No infinite retry** is permitted (per `architecture.md §5`).

## Outcome

- A typed `MissionState` enum encodes:
  - Multirotor: `DISCONNECTED → CONNECTED → HEALTH_OK → BIT_OK → ARMED → TAKE_OFF → MISSION_UPLOADED → FLY_MISSION → LAND → POST_FLIGHT_SYNC → DONE`.
  - Fixed-wing: `DISCONNECTED → CONNECTED → HEALTH_OK → BIT_OK → MISSION_UPLOADED → WAIT_AUTO → FLY_MISSION → LAND → POST_FLIGHT_SYNC → DONE`.
- `MissionExecutor::tick(now, telemetry)` advances the state machine; each transition is gated by an explicit guard.
- Per-transition retry counter + last-failure reason; on cap exhaustion the machine pauses and health → red.
- Health surface: current state, `state_duration_ms`, `transition_failures_by_state`, retry counts.

## Scope

### Included
- Both variant state graphs.
- Bounded retry per transition (configurable; default 3 attempts).
- `Variant` enum (`Multirotor`, `FixedWing`) wired from startup config.
- State-transition events published on an output channel for `scan_controller` and `telemetry_stream`.
- Mission re-upload sequence (`MISSION_CLEAR_ALL` → upload waypoints → `MISSION_SET_CURRENT`) — invoked from `MISSION_UPLOADED` entry guards.

### Excluded
- BIT (F9) — separate task 11.
- Lost-link failsafe ladder (F10) — separate task 12.
- Geofence + battery enforcement — separate task 13.
- Middle-waypoint re-upload — separate task 13 (logic) but exercised here for the base mission upload.
- Post-flight push trigger — separate task 13.

## Acceptance Criteria

**AC-1: Happy-path multirotor flow against SITL**
Given a multirotor SITL + `mavlink_layer` healthy + a valid in-memory mission
When `mission_executor::run()` is started
Then it reaches `DONE` traversing the multirotor state graph; transitions are observable as events; mission progress reaches all waypoints.

**AC-2: Happy-path fixed-wing flow against SITL**
Given a fixed-wing SITL + the operator's GCS sets AUTO mode externally
When `mission_executor::run()` is started
Then it traverses the fixed-wing graph (no `ARMED`/`TAKE_OFF`; `WAIT_AUTO` waits for the AUTO transition) and reaches `DONE`.

**AC-3: Bounded retry on mission-upload rejection**
Given SITL is configured to reject `MISSION_ACK` for the first attempt and accept the second
When the executor reaches `MISSION_UPLOADED`
Then the retry counter increments to 1, the second attempt succeeds, and the machine proceeds.

**AC-4: Cap exhaustion flips health to red**
Given SITL is configured to reject `MISSION_ACK` for all 3 default attempts
When the executor reaches `MISSION_UPLOADED`
Then the machine pauses, health → red, and the failure is observable on the output channel; no transition past `MISSION_UPLOADED`.

## Non-Functional Requirements

**Performance**
- Mission-upload retry budget: configurable; default 3 attempts.
- State-machine tick: ≤10 ms p99.

**Reliability**
- No infinite retry anywhere.

## Constraints

- `mavlink_layer::send_command` is the only path to the airframe.
- Variant is fixed at startup; no runtime swap.

## Runtime Completeness

- **Named capability**: variant-aware state machine + mission upload via MAVLink.
- **Production code that must exist**: explicit transition guards; real retry counters; real mission-upload sequence.
- **Allowed external stubs**: ArduPilot SITL is the conformance target (both `arducopter` and `arduplane`).
- **Unacceptable substitutes**: a generic "if-else cascade" instead of typed state transitions is not acceptable.
