# ADR 0015: Simulation Polygon as a qualification boundary

## Status

Accepted for architecture and SIM S0 implementation on 2026-07-24.
Navigation behavior, safety behavior and real actuator authority are not
accepted.

## Context

Mission Core has proven a K1 observation/archive/perception vertical, but the
perception outputs do not yet have a closed-loop consumer. Adding Gazebo, PX4,
ROS 2 and Nav2 directly to the web process or modeling every experiment as an
observation session would blur product ownership, lifecycle, evidence and
authority.

Replay, physics simulation, a digital twin, HIL and real shadow also have
different causal meaning. A recorded stream cannot react to a hypothetical
command, while a closed-loop world can. Calling both `SimulationRun` would make
reports easy to misuse.

## Decision

1. Polygon is a first-class Mission Core bounded context for autonomy
   qualification and assurance.
2. Mission Core owns scenarios, qualification-run lifecycle, authority policy,
   canonical contracts, provenance, evidence admission, evaluation and reports.
3. Gazebo, PX4 SITL, ROS 2, Nav2, Rerun and datasets are replaceable providers.
4. `QualificationRun` is the umbrella aggregate. Its kinds explicitly separate
   `simulation_closed_loop`, `replay_shadow`,
   `digital_twin_closed_loop`, `controller_in_loop`, `hil` and
   `physical_shadow`.
5. Simulation Orchestrator is the sole process-lifecycle owner. Gazebo and PX4
   do not run inside the Mission Core web process, and the browser has no direct
   PX4 channel.
6. Gazebo `/clock` is authoritative in closed-loop simulation. ROS 2 uses
   simulated time and PX4 uXRCE-DDS time synchronization is disabled for this
   profile.
7. Mission Core uses ENU/FLU. PX4 uses NED/FRD. Exactly one adapter boundary
   converts frames and requires golden tests.
8. The first command boundary permits only rover speed+steering and
   speed+yaw-rate profiles with sequence, TTL, heartbeat, watchdog and
   stop-on-loss behavior. Direct actuator setpoints are rejected.
9. Source-of-record, derived artifacts and presentation state remain separate.
   Reset creates a new immutable run/episode.
10. Ground truth is evaluator-only and is not visible to perception or planning.
11. SIM S0 targets the reviewed Windows 11 worker through a dedicated
    `MissionCore-Sim` WSL2 Ubuntu 24.04 distribution physically under
    `D:\NDC_MISSIONCORE`.
12. SIM S0 does not depend on the existing Docker Desktop runtime. Its WSL
    backend is C-backed and currently serves unrelated co-tenants.
13. S1 uses exact `px4_msgs` directly. The experimental
    `px4-ros2-interface-lib` is not a mandatory S1 dependency.
14. A top-level Polygon UI is gated on accepted contracts and a proven S1
    backend lifecycle with persisted run history.
15. Real actuator authority requires a new decision and physical safety gate.
16. S0 processes run inside an ephemeral loopback-only Linux network namespace.
    Micro XRCE-DDS Agent's UDP wildcard bind is acceptable only inside that
    boundary; no S0 listener may be reachable from the worker LAN or Windows
    host network.

## Consequences

- Perception can be measured by downstream decisions without granting it hidden
  behavior authority.
- Standard planners and future Mission Core planners can be compared on the
  same scenario and metric profiles.
- Replay cannot be presented as closed-loop safety evidence.
- Provider upgrades require explicit compatibility and evidence refresh.
- More up-front domain and artifact work is required before a visual demo.
- The AI worker must satisfy D-only, resource and coexistence constraints before
  installation is accepted.
- Simulation and HIL reduce risk but do not certify the real trike.

## First implementation

The qualification doctor is deliberately read-only:

- `simulation/s0/qualification-profile.yaml` is the candidate stack,
  storage, clock, authority, port and process contract.
- `k1link.simulation.s0` strictly validates that contract and optional
  digest-bound worker evidence.
- `missioncore-sim s0 doctor` inspects the current host without installing,
  starting or modifying anything.
- MISSIONCOR-40 tracks factual worker qualification.

The first target bootstrap also includes `simulation/s0/worker-smoke.sh`. It
creates the reviewed loopback-only namespace, starts only the pinned stock-rover
providers, observes ROS 2 vehicle status and Gazebo clock, requests PX4 shutdown,
checks for owned-process residue and writes D-only factual artifacts. It never
arms the vehicle or sends an actuator command.

`simulation/s0/gazebo_time_control.py` owns the S0 pause/single-step/1×/2× RTF
and resource acceptance probe. `simulation/s0/build_evidence_manifest.py`
admits only exact-profile, D-confined, passing 1×/2× runs into the digest-bound
evidence generation. These scripts are qualification tooling; the S1
Simulation Orchestrator remains the future product lifecycle owner.

The doctor reports `INCOMPLETE` until it is running on the reviewed target with
resolved/accepted pins and all required evidence. It cannot infer `GO` from the
repository state.
