# Mission Core Polygon: product definition and system requirements

Status: canonical working SRS, 2026-07-24.

Ops source of truth:

- [MISSIONCOR-38](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-38) is the
  product epic and original simulation-branch scope.
- [MISSIONCOR-39](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-39) is the
  canonical, changeable architecture plan.
- [MISSIONCOR-40](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-40) is the
  completed SIM S0 implementation and qualification gate.
- [MISSIONCOR-41](https://ops.nodedc.ru/nodedc/browse/MISSIONCOR-41) is the
  active S1 lifecycle/authority implementation and qualification gate.

This document, ADR 0015, ADR 0016 and ADR 0017 are the repository truth. A material change
to run kinds, authority, clocks, frames, source-of-record, provider boundaries,
component placement or phase gates must update the ADR/SRS and MISSIONCOR-39
together.

## 1. Product thesis

Polygon is Mission Core's autonomy qualification and assurance layer. It is not
a simulator embedded for visual effect and it is not a second observation
viewer.

Polygon makes one product promise:

> Given a versioned scenario and qualification profile, Mission Core can run or
> replay the autonomy stack, preserve exact provenance and evidence, explain
> each control/safety decision and compare outcomes without granting undeclared
> authority.

The product value appears in increments:

| Gate | Value |
| --- | --- |
| P0/S0 | Makes the stack installable, inspectable and reproducible rather than an ad hoc lab |
| S1 | Proves Mission Core can own a complete virtual rover run lifecycle |
| S2 | Produces the first useful navigation baseline and comparable safety/latency evidence |
| S3 | Connects Mission Core perception to a closed-loop consumer and exposes product differentiation |
| S4 | Makes recorded real data useful for regression and shadow-policy analysis |
| S5/S6 | Reduces risk before a real vehicle, without claiming real-world safety certification |

The first product-useful baseline is P0 through S2. The current estimate is
27–46 engineer-days, excluding waits for hardware, external accounts or a
resolved worker-access blocker.

## 2. Current truth

The repository's proven vertical remains K1 observation, durable archive,
recorded perception and diagnostic motion evidence through LAB E26. It has not
accepted navigation behavior, safety behavior or real actuator control.

Polygon is now a parallel product branch. As of this document:

- P0 architecture and SRS are committed on the Polygon branch;
- SIM S0 has a strict accepted qualification profile and read-only doctor;
- the dedicated D-only worker distribution has been created and the accepted
  PX4/Gazebo/ROS 2/Nav2 stack has been installed without using Docker;
- PX4 v1.17.0 and the stock Ackermann rover have completed repeated factual
  smoke runs with ROS 2 vehicle status, Gazebo clock and clean shutdown;
- the exact accepted-profile generation has passed pause freeze, one 2 ms
  single-step, 1×/2× speed and structured resource cases;
- all nine digest-bound S0 evidence claims validate and the target doctor
  returns `GO` for profile SHA-256
  `aeecf5005301db230e1340b85215cbbd862b72974a22b8c43767c28be8453e2f`;
- S1B exact generation `6cb1495` has passed a product-owned real-provider
  lifecycle in a fresh loopback-only namespace: two provider PGIDs, explicit
  world/startup/DDS-writer readiness, eight persisted events, zero commands,
  terminal `completed` and zero process residue;
- the UI-0 archive contract remains available over GET-only Polygon API routes
  and as a compatibility deep-link. Browser QA loaded the real accepted S1B
  journal and displayed its four provider pins, eight events, zero commands and
  unchanged virtual-only authority boundary;
- S1C exact code generation `b7ccca3` adds a persistent, unprivileged
  Simulation Worker agent in a fresh loopback-only namespace, a bounded
  Unix-socket Mission Core gateway and an explicit `internal-virtual-only`
  lifecycle gate;
- UI-2 exact generation `60e7916` established `Полигон` as a dedicated header
  root only while Mission Core confirms an available Simulation Worker. The
  current product surface keeps that direct entry. The operator navigation has
  one implemented item, `Датасеты`; immutable run evidence remains an internal
  backend contract rather than a second page;
- the browser-native Three.js scene renders a recognisable procedural Ackermann
  Rover, ground grid and ENU trajectory. Orbit supports 360° azimuth, bounded
  vertical inspection from overhead to horizon, zoom, pan, follow and camera
  reset. The Gazebo dynamic-pose signal remains marked `diagnostic`;
- the UI-driven target run
  `s1c-60e7916-20260724t182006z-2f164e` reached `completed` with eight
  persisted events, 27.74 seconds of Gazebo time and zero provider residue;
  it contained zero commands and therefore does not prove rover motion or PX4
  command delivery;
- S1D exact code generation `49b0f47` adds the admitted Ackermann
  speed/steering command route from React through Mission Core and the private
  worker gateway. The worker journals before delivery and translates the
  bounded intent to PX4 rover-level Offboard `RoverThrottleSetpoint` plus
  `RoverSteeringSetpoint`; the stock-model conversion uses
  `RO_MAX_THR_SPEED=3.1`, while direct actuator topics remain prohibited;
- the exact D-only generation passed 40 focused target tests. Its first cold
  start completed in one request after 32.08 seconds. Run
  `s1c-49b0f47-20260724t195259z-62edd2` proved 3.74 m straight motion, a curved
  turn, reverse motion, 44.6 ms sampled command admission, 250 ms TTL expiry,
  stable stopped pose and clean shutdown with no provider residue;
- this is not a calibrated closed-loop speed controller acceptance and does
  not close Differential Rover, canonical PX4/ROS 2 telemetry,
  heartbeat/offboard/link-loss, failsafe, navigation or safety checkers;
- the next repository slice introduces
  `missioncore.simulation-provider-profile/v1`, worker status v2 and command
  acceptance v2. Runtime roles/capabilities, authoritative simulation clock,
  canonical frames and control profiles are no longer inferred from hardcoded
  Gazebo/PX4 names;
- the stock Gazebo/PX4 profile remains the accepted regression baseline.
  Unreal is a candidate high-fidelity provider family; native Unreal, CARLA and
  Project AirSim require the bounded U0 comparison from ADR 0017 before one is
  selected;
- `actuator_authority=false`;
- `navigation_or_safety_accepted=false`.

The doctor reports `GO` only on the matching target with the exact confined
worker evidence. A repository manifest alone remains insufficient.

## 3. Goals

### 3.1 Product goals

- Turn perception and planning work into measurable sense-plan-act experiments.
- Compare standard and Mission Core planners against the same versioned inputs.
- Preserve failures, limitations and uncertainty as first-class evidence.
- Reuse the same scenario/run/report concepts across simulation, replay, digital
  twin, controller-in-loop, HIL and physical shadow.
- Keep physics, autopilot, middleware, planner and viewer replaceable.
- Create a controlled path toward a future trike without silently widening
  authority.

### 3.2 Engineering goals

- Deterministic lifecycle ownership with no orphan simulator processes.
- Exact version, environment, input and artifact provenance.
- Explicit clock-domain and coordinate-frame conversions.
- Fail-closed setpoint validity, TTL, heartbeat, watchdog and loss behavior.
- Append-only run history and digest-bound source/derived artifacts.
- Side-effect-free infrastructure diagnosis before installation.

## 4. Non-goals

The first delivery does not:

- grant real actuator authority;
- expose PX4 directly to the browser;
- use direct actuator setpoints;
- certify Nav2, PX4 or Mission Core as a real-time safety system;
- treat replay as closed-loop evidence;
- import all 300 BARN worlds before a stock-world baseline;
- download complete CODa, JRDB or NCLT collections;
- build a custom physics engine;
- make `px4-ros2-interface-lib` mandatory for S1;
- overload the observation-session model for qualification runs;
- treat the capability-gated top-level UI as proof of the backend S1 command or
  safety gate.

## 5. Product and system boundaries

### 5.1 Mission Core ownership

Mission Core owns:

- scenario definitions and profile selection;
- qualification-run identity and lifecycle;
- command authority and safety policy;
- canonical state, setpoint, decision and event contracts;
- orchestration of replaceable providers;
- evidence admission, provenance and immutable history;
- evaluation, comparison and qualification reports.

### 5.2 Provider ownership

Providers remain replaceable:

- a world/physics/state provider owns simulated world state, sensors, contacts,
  truth and the declared simulation clock; the accepted regression provider is
  Gazebo, while Unreal candidates remain unaccepted;
- a controller provider owns rover control loops, constraints, command
  lifecycle and controller failsafe; the accepted stock controller is PX4 SITL;
- a transport provider carries typed telemetry and commands; the stock profile
  uses ROS 2 and Micro XRCE-DDS;
- Nav2 supplies the first mature planning/costmap/collision-checking baseline.
- Rerun or another viewer presents derived evidence and never becomes a queue,
  orchestrator or source-of-record.
- Dataset adapters expose recorded streams but never pretend alternative
  commands changed future recorded observations.

### 5.3 Neighboring Mission Core contexts

- Observation owns real and recorded sensor streams plus perception layers.
- Polygon owns scenarios, qualification runs, decisions, simulated state and
  comparisons.
- Missions owns goals and routes that may later target a virtual or real
  vehicle.
- Data owns source-of-record, derived artifacts, retention and report access.

Observation `SessionStatus` and its modality model are not extended to describe
simulation. Shared UI components require an explicit data-source contract.

## 6. Target architecture

```text
Mission Core UI
       |
Simulation API
       |
Simulation Orchestrator
       +---- scenario/profile registry
       +---- run state machine and authority gate
       +---- clock, namespace, port and process ownership
       +---- artifact/provenance store and evaluator
       |
       +---- provider profile -- roles/capabilities/clock/frames
       +---- world adapter ----- Gazebo baseline or admitted Unreal profile
       +---- control adapter --- PX4 SITL or another admitted controller
       +---- transport adapter - ROS 2/XRCE or another admitted transport
       +---- planner adapter --- Nav2 or Mission Core planner
       +---- viewer adapter ---- canonical state/derived report
```

Native simulation and controller providers never run inside the web process. The browser never owns process
lifecycle or command authority. Losing the browser cannot terminate the only
copy of run state and cannot bypass the server-side authority gate.

### 6.1 Product form and component placement

Mission Core is a distributed web product, not a monolithic desktop
application:

| Component | Product placement | Packaging and responsibility |
| --- | --- | --- |
| Control Station | Any operator browser on macOS, Windows, Linux or tablet | React static assets; interactive planning, live state, history, comparison and reports |
| Gateway/API and Control Plane | Control-centre server, laboratory host or offline field kit | Long-lived service; identity, policy, mission/scenario/run state, orchestration and catalogues |
| Simulation Worker | Registered Linux GPU worker; currently dedicated WSL2 on the reviewed Windows host | Headless worker service plus Gazebo, PX4 SITL, ROS 2 and Nav2 |
| Native Gazebo GUI | Worker desktop only | Optional diagnostic attachment; never product state, authority or source-of-record |
| Vehicle Edge Agent | Future onboard or vehicle-adjacent Linux computer | Headless device/runtime adapters, local authority gate, bounded mission state, durable evidence and store-and-forward sync |
| PX4 controller | SITL process in simulation or separate controller hardware in the field | Vehicle control loops, constraints and failsafe behind an allowlisted adapter |
| Observation/perception worker | Onboard, nearby edge or control-centre worker according to latency/bandwidth profile | Canonical perception outputs; placement does not change contracts |
| Archive/evidence storage | Worker/vehicle local-first, then optional central synchronization | Immutable source evidence, derived artifacts and reports |

The primary deliverable remains the browser application. A PWA, kiosk package
or thin Tauri/Electron wrapper may distribute the same assets for an offline
field kit, but it is not a second product and never owns provider processes or
command authority.

The Polygon browser view consumes bounded canonical state and derived evidence:
rover pose, route, planned/factual trajectory, footprint, contacts, safety
state, metrics and optional media. The accepted live rover scene uses
browser-native Three.js; Rerun remains available for recorded spatial evidence.
Both presentation paths consume server-owned contracts rather than worker
processes. Full Gazebo pixels are optional diagnostics through the worker
desktop or a separately gated remote-display capability; they are not required
for the product view.

### 6.2 Deployment topologies

Laboratory simulation:

```text
Operator browser
  -> Mission Core Gateway/API
  -> Simulation Orchestrator
  -> registered Linux/WSL2 worker
  -> Gazebo + PX4 SITL + ROS 2 + Nav2
  -> canonical live stream + local source/derived artifacts
```

Connected field vehicle:

```text
Operator browser/control centre
  -> Mission Core Gateway/API
  <-> Vehicle Edge Agent on onboard Linux
  -> PX4 hardware boundary
  -> sensors and actuators
```

Disconnected field vehicle and later review:

```text
Locally admitted mission + Edge Agent + PX4
  -> accepted local watchdog/failsafe behavior
  -> append-only onboard evidence
  -> later idempotent digest-bound synchronization
  -> browser history/replay/report
```

Field execution and safety never depend on a browser tab or continuous WAN.
The Edge Agent writes source evidence locally before upload, retains
high-volume data according to storage policy and sends bounded telemetry,
events, decisions and previews when connected. Reconnection synchronizes the
same immutable run identity; a partial upload is never presented as complete.

The authority path remains:

```text
Browser intent
  -> Mission Core API/policy
  -> Simulation Orchestrator or Vehicle Edge Agent
  -> allowlisted provider/device adapter
  -> PX4 boundary
```

The placement decision is specified by
[ADR 0016](adr/0016-distributed-product-edge-and-worker-topology.md).

## 7. Canonical domain model

### 7.1 Versioned inputs

`ScenarioDefinition` contains identifiers and references for:

- world and deterministic actor placement;
- vehicle profile;
- sensor profile;
- route/goal;
- planner profile;
- fault profile;
- metric profile;
- seed and reproducibility tier.

`VehicleProfile`, `SensorProfile`, `PlannerProfile`, `FaultProfile` and
`MetricProfile` are independently versioned. A run stores the exact resolved
generation and hashes, not only mutable names.

### 7.2 QualificationRun

`QualificationRun` is the umbrella aggregate. `SimulationRun` is not used as
the common type because replay, HIL and physical shadow are not simulations.

Required identity:

- immutable run ID and episode ID;
- run kind;
- scenario/profile generations and hashes;
- Mission Core commit;
- provider versions, commits or image digests;
- host and resource profile;
- seed and reproducibility tier;
- authority profile;
- start/end UTC provenance;
- authoritative clock domain.

Reset creates a new episode/run identity. It never reuses a completed identity
or overwrites artifacts.

### 7.3 Run kinds

| Kind | Commands affect future inputs | Actuator authority |
| --- | --- | --- |
| `simulation_closed_loop` | Yes, through virtual physics | Virtual only |
| `replay_shadow` | No | None |
| `digital_twin_closed_loop` | Yes, through an attested twin | Virtual only |
| `controller_in_loop` | Yes, through a bounded controller interface | Lab-specific |
| `hil` | Yes, with hardware in the loop | Separate gate |
| `physical_shadow` | No | None |

No result may be promoted from one kind to another by changing report wording.

### 7.4 Canonical streams

- `VehicleState`: pose, twist, acceleration, steering/wheel state, estimator
  state and source frames.
- `PerceptionWorldState`: occupancy, objects, motion, confidence, unknown and
  uncertainty.
- `ControlSetpoint`: profile, sequence, issued time, validity deadline,
  speed/steering or speed/yaw-rate and authority scope.
- `SafetyDecision`: allow/slow/stop, reason, active constraint, TTC/clearance
  evidence and input generation.
- `QualificationEvent`: lifecycle, collision/contact, reset, deadline miss,
  data loss, watchdog, failsafe and evaluator events.
- `QualificationReport`: verdict, metrics, violations, limitations and evidence
  links.

## 8. Lifecycle requirements

The minimum lifecycle is:

```text
admitted -> starting -> running <-> paused -> stopping -> completed
                       |                    |
                       +--------------------+-> failed
```

Cancellation is a requested transition, not evidence that processes stopped.
A run reaches a terminal state only after:

- child-process ownership is reconciled;
- stop/failsafe outcome is captured;
- source artifacts are sealed;
- derived indexes are generated or explicitly marked absent;
- the report records the final limitations.

Process shutdown order is explicit and deterministic. Orchestrator shutdown is
last. An orphan process is an S0/S1 failure.

## 9. Clock contract

For `simulation_closed_loop`:

- the admitted provider profile declares exactly one authoritative simulation
  clock and a provider with `clock.simulation`;
- the stock regression profile uses Gazebo `/clock`; an Unreal adapter must
  publish a distinct fixed-step clock domain;
- ROS 2 consumers use `use_sim_time=true`.
- PX4 uXRCE-DDS time synchronization is disabled when Gazebo time is used.
- Canonical timestamps are integer nanoseconds and include their clock domain.
- UTC is provenance only.
- TTL, deadline and watchdog calculations declare whether they use simulation
  or monotonic host time.
- Pause, resume, single-step and real-time-factor changes are qualification
  cases, not UI-only behavior.

Wall clock must not appear implicitly in planner or safety calculations.

## 10. Coordinate-frame contract

Mission Core navigation uses:

- `map` and `odom`: ENU;
- `base_link`: FLU.

PX4 uses:

- world/local: NED;
- body: FRD.

All PX4 conversion happens at one adapter boundary. Pose, vector, yaw, yaw-rate
and covariance transformations require golden tests. Every canonical message
identifies source and target frame. A frame mismatch fails closed and cannot be
reclassified as planner noise.

## 11. Authority and safety requirements

Until a new physical-control card and formal safety gate:

- `simulation_or_shadow_only=true`;
- `actuator_authority=false`;
- `navigation_or_safety_accepted=false`;
- direct actuator setpoints are rejected;
- supported S1 command profiles are `rover-speed-steering/v1` and
  `rover-speed-yaw-rate/v1`;
- each command carries a monotonic sequence and explicit expiry;
- heartbeat loss, TTL expiry, invalid state, planner timeout or link loss causes
  a stop/failsafe transition;
- unknown occupancy never becomes free space by omission;
- ground truth is unavailable to the planner and perception runtime;
- ground truth is separately available to the evaluator.

Nav2 Collision Monitor is an additional software safety layer. It is not a
hard-real-time certified safety controller.

## 12. Evidence and data requirements

### 12.1 Source-of-record

The minimum source set is:

- exact scenario and qualification profiles;
- stack/version lock;
- run manifest and authority profile;
- PX4 ULog;
- Gazebo log or equivalent world-state/contact evidence;
- rosbag2/MCAP for admitted canonical streams;
- factual host/resource and process-lifecycle evidence.

### 12.2 Derived artifacts

Derived data includes:

- normalized metrics;
- evaluator outputs;
- comparison tables;
- Rerun recording;
- qualification report.

Presentation state is not source evidence. Derived artifacts are rebuildable and
must retain input hashes. Source and derived generations are append-only.

### 12.3 Required metrics

Each applicable run reports:

- completion and terminal reason;
- collision/contact count and minimum clearance;
- path length, elapsed simulation time and efficiency;
- route/pose error;
- speed/steering tracking;
- stop time and distance;
- TTC and constraint activation;
- replans and oscillation;
- dropped/late messages and deadline misses;
- stage latency p50/p95/max and queue depth;
- real-time factor;
- CPU, GPU, RAM, VRAM and disk usage.

Inapplicable metrics are explicit, not silently zero.

## 13. Reproducibility

- R0: exact inputs and versions are retained; outcome may vary.
- R1: the same inputs/seed/version lock reproduce the same verdict within
  declared tolerances.
- R2: defined metrics remain within accepted tolerance bands.

Bitwise-identical physics is not promised. Comparison is rejected when scenario
schema, metric profile, provider generation or reproducibility tier are
incompatible.

## 14. Upstream baseline

The S0 accepted regression line is:

- Windows 11 AI worker;
- dedicated `MissionCore-Sim` WSL2 Ubuntu 24.04 distribution physically on D;
- no Docker dependency in S0, so active shared Docker co-tenants remain untouched;
- ROS 2 Jazzy;
- Gazebo Harmonic;
- PX4 Autopilot v1.17.0;
- matching `px4_msgs` v1.17.0 generation;
- Micro XRCE-DDS Agent v2.4.3;
- Nav2 Jazzy;
- PX4 Gazebo stock rover models.

The exact source commits and package versions are resolved in the profile.
Target installation, PX4 build, DDS telemetry, Nav2/ROS package discovery and
repeated 1×/2× stock-rover evidence have moved every component pin to
`accepted`. A future pin change creates a new profile generation and invalidates
evidence tied to the prior SHA-256.

S1 uses direct exact `px4_msgs` integration. The experimental
`px4-ros2-interface-lib` is evaluated later and is not on the S1 critical path.

## 15. Storage and runtime placement

All mutable worker bytes must be physically placed under
`D:\NDC_MISSIONCORE`, including:

- the dedicated `MissionCore-Sim` WSL distribution/VHD;
- Docker data and images if a later profile elects to use containers; the S0
  profile explicitly does not;
- sources and build products;
- package/model caches;
- runtime and logs;
- bags, ULog and Gazebo evidence;
- datasets and reports.

The WSL view is `/mnt/d/NDC_MISSIONCORE`. C-drive placement is a blocking
failure. S0 requires at least 300 GiB free before installation and a stop-below
threshold of 200 GiB. Full external datasets are out of S0 scope.

S0 runtime processes execute in a new loopback-only Linux network namespace.
Micro XRCE-DDS Agent v2.4.3 has no address-selection flag and therefore binds
UDP wildcard inside that namespace; the namespace contains only `lo`, so the
effective exposure remains loopback-only. ROS domain 0 is isolated by the same
boundary. This distinction is part of the port evidence and must not be
misreported as a host-wide `127.0.0.1` bind.

The stock rover world declares a 2 ms physics step. S0 pause acceptance permits
zero simulation-time advance; single-step requires exactly +2,000,000 ns and
+1 iteration. Speed factors 1× and 2× are measured over four seconds with a
±20% RTF tolerance. Resource sampling runs every 500 ms with an owned-process
budget of 2 GiB RSS and 800% CPU, at least 8 GiB available WSL memory and the
existing 200 GiB D stop floor. GPU values are recorded as global co-tenant
context and are not misattributed to headless S0.

## 16. Delivery plan

| Phase | Estimate | Exit condition |
| --- | ---: | --- |
| P0 | 2–4 days | Product thesis, SRS, ADR and canonical contracts accepted |
| S0 | 3–5 days | Target compatibility, D-only runtime, exact pins, clock/process/resource evidence |
| S1 | 7–12 days | Stock Ackermann and Differential lifecycle/control/failsafe evidence |
| U0 | 2–4 days | Native Unreal/CARLA/Project AirSim selection matrix with measured worker fit |
| U1 | 5–10 days | Selected Unreal candidate proves canonical clock/state/command lifecycle |
| S2 | 15–25 days | LiDAR/odometry/Nav2 baseline, evaluator and obstacle scenarios |
| S2B | 5–8 days | Representative 30-world BARN pilot |
| S3 | 20–35 days | K1-like virtual sensors and Mission Core perception closed loop |
| S4 | 10–20 days | Canonical replay/shadow adapters and reports |
| S5 | 20–40 days | Attested RAVNOVES00 digital twin |
| S6 | 20–40+ days | Trike model, controller-in-loop/HIL and physical-shadow gate |

Implementation cards follow this order:

1. Product SRS and ADR.
2. D-only inventory and stack lock.
3. Clock, frame and authority contracts.
4. Orchestrator lifecycle and artifact store.
5. PX4 stock rover control and failsafe.
6. Provider-neutral profile/status/command boundary.
7. Complete the U0 Unreal candidate comparison; U1 may run in parallel.
8. Nav2 adapter and truth baseline on the frozen Gazebo profile.
9. Evaluator, report and BARN pilot.
10. Virtual K1 and perception; promote an Unreal provider only after U1.
11. Replay/shadow datasets.
12. RAVNOVES00 twin and Unreal physical/sensor world if U2 is accepted.
13. Trike, HIL and safety gate.

## 17. SIM S0 acceptance

SIM S0 requires all of the following factual evidence:

- worker inventory;
- physical D-only placement of the dedicated WSL VHD, sources, builds, caches
  and artifacts;
- confirmation that S0 uses the dedicated D-only WSL and does not use the
  existing C-backed Docker Desktop runtime;
- exact component/package pins and licenses;
- one stock PX4 rover launch;
- ROS 2 telemetry;
- authoritative simulation clock;
- pause, resume, single-step and speed-factor behavior;
- clean stop with no orphan processes;
- 1× resource baseline;
- 2× resource baseline;
- explicit `GO`, `INCOMPLETE` or `BLOCKED` report.

The repository profile and doctor implement preflight and evidence admission.
They do not install packages, start processes, open ports or write a target
report.

Run the local read-only preflight:

```bash
uv run missioncore-sim s0 doctor --json
```

An optional evidence manifest uses
`missioncore.simulation-s0-evidence/v1`. Each required claim points to a
confined regular artifact and supplies its SHA-256. The profile SHA-256 must
match the exact candidate generation.

## 18. S1 and S2 acceptance outline

### S1

- Ackermann primary and Differential reference launch from the orchestrator.
- Start, pause, resume, step, reset and stop are server-owned.
- Straight, turn, reverse, deceleration and emergency-stop cases pass.
- TTL, heartbeat, offboard loss and link loss produce a captured safe outcome.
- Pose, speed, steering/controller state and failsafe telemetry are retained.
- Reset creates a new run/episode.
- A repeated seed produces the declared R1 verdict tolerance.

K1, Nav2 and top-level UI do not block S1 backend acceptance.

#### S1A implementation status

The first S1 increment is implemented in `k1link.simulation.contracts` and
`k1link.simulation.run_store`:

- the immutable manifest owns run/episode identity, exact scenario/profile
  digests, Mission Core revision, provider pins, host profile, seed,
  reproducibility tier, clock domain and fail-closed authority;
- lifecycle and domain events are stored as exclusive, individually atomic,
  contiguous records; state is reconstructed by replay and the immutable
  manifest is never rewritten;
- only legal lifecycle edges are admitted; terminal history and its artifact
  index are sealed;
- Ackermann speed/steering and Differential speed/yaw-rate commands require a
  positive monotonic sequence, simulation-time expiry and the current authority
  generation; non-finite values, over-limit TTL, stale generations, direct
  actuator authority and commands outside `running` fail closed;
- replay/shadow cannot causally accept commands, while HIL and
  controller-in-loop admission remain blocked pending a separate safety gate;
- restart reconciliation marks an active run `failed` with
  `orchestrator-recovery-interrupted`; it never hides a resume;
- reset is accepted only after the prior run is terminal and creates a new
  linked run and episode identity;
- registered artifacts use confined relative POSIX paths, SHA-256 and
  append-only sequence records.

The repository root is caller-supplied so unit tests and development remain
portable. The target Simulation Orchestrator must bind that root under the
accepted `/mnt/d/NDC_MISSIONCORE` storage boundary; S1 provider orchestration
and target evidence are not implied by this increment.

#### S1B ownership foundation status

The next local increment implements the provider-neutral ownership boundary:

- `SimulationApplicationService` is the only caller allowed to drive persisted
  start, pause, resume, single-step, stop, reset and restart reconciliation;
- start and stop requests are journal-bound to idempotency keys, and a
  different request cannot rebind the same run operation;
- a second `starting|running|paused|stopping` run cannot acquire the same worker
  authority;
- the worker port exposes lifecycle operations without exposing a browser-to-PX4
  channel or choosing a remote transport;
- `S0WorkerGuard` requires the run's exact accepted S0 profile ID/SHA-256, the
  canonical `/mnt/d/NDC_MISSIONCORE/simulation/artifacts/s1/runs/<run-id>`
  artifact layout and the actual
  `/mnt/d/NDC_MISSIONCORE/simulation/runtime/s1/runs/<run-id>` supervisor
  working layout before provider start;
- `PosixProcessSupervisor` launches argv without a shell, creates one dedicated
  session/PGID per provider, writes run-scoped stdout/stderr and a process
  registry, rolls back partial starts, and stops in ascending S0 shutdown order;
- failure, profile drift or process residue becomes a persisted terminal
  failure rather than a successful stop.

The first target adapter now supplies concrete Micro XRCE-DDS Agent and combined
PX4/Gazebo stock-rover specs. Readiness is an executable contract: the Agent
must be listening, while PX4 must report the exact rover world/model, completed
startup and a `vehicle_status_v1` DDS writer. PX4 stdin remains open without
sending a command, so its shell cannot enter an EOF prompt loop. Provider logs
are read incrementally, all argv are shell-free, and every provider owns a
dedicated PGID.

The exact commit `6cb1495` passed `25` target tests and the real
`s1b-6cb1495-20260724t1535z` lifecycle inside `MissionCore-Sim`. Its immutable
Git archive SHA-256 is
`37da47744e855bb1031734893a6f2dd82bb4eb92b7e15edd70794c29b2dfb451`.
Mission Core persisted the admitted/starting/running/stopping/completed history,
started `micro-xrce-dds-agent` plus `px4-gazebo-stock-rover`, observed an XRCE
session and PX4 DDS writer, sent zero control commands, and stopped with no
registry or `/proc` residue. Evidence is D-only and digest indexed under
`/mnt/d/NDC_MISSIONCORE/simulation/artifacts/s1/lifecycle/`.

This accepts the S1B target start/health/stop boundary. UI-0 now consumes the
accepted persisted history without widening authority. It does not accept
restart-safe PID/start-token reconciliation, live
pause/resume/step/reset, canonical VehicleState, frame conversion, rover command
mapping, watchdog/failsafe cases, repeatability or S1 as a whole.

S1C commit `b7ccca3` accepts the next placement/presentation slice only. A
persistent worker agent runs unprivileged in a new loopback-only namespace and
is registered to Mission Core through a private Unix socket. The browser uses
same-origin APIs for worker status, explicit virtual-only start/stop and a
bounded `missioncore.vehicle-state/v1` view. Exact target source archive
SHA-256 is
`fc3195dbffef270f9669c194cf90e3fe4b62e113a5a7b74af89caa123b601ccd`;
the xattr-free Control Station build archive SHA-256 is
`76b687d12a7675275dfae8ebe3d806d3725240182136108c9bd01f0e8e364df6`.
The first UI-driven run completed cleanly with 52.836 seconds of Gazebo time
and no provider residue. Its `VehicleState` is Gazebo ground truth marked
`diagnostic`; PX4/ROS 2 canonical telemetry and command-induced rover motion
remain open.

UI-2 commit `60e7916` accepts the next browser-placement slice. Its exact
source archive SHA-256 is
`d0f343154981c6dc78deb8ac57de4d980388a0d3f80ff7405ff53e52166d2bd3`;
the xattr-free Control Station build archive SHA-256 is
`250898e82ae3c97c1328ea90b5a1fc0fed9aeedcd2c06002b9b5d1e5bfa50f36`.
The exact D-only generation passed 35 focused target tests. Browser QA entered
through the capability-gated header, found no secondary launcher, exercised
orbit and zoom, observed advancing Gazebo time and stopped
`s1c-60e7916-20260724t182006z-2f164e` cleanly at 27.74 seconds of simulation
time with eight events, zero commands and zero provider residue.

S1D code generation `49b0f47fea0ae29c977bbd60808696b85a9380cd`
accepts the first Ackermann command/motion slice. Its exact source archive
SHA-256 is
`30aad33664a536f2a6cb87bc172a5dae111ae479d5899723832a1abc17c4517b`;
the xattr-free Control Station build archive SHA-256 is
`014724896c8c2169a89b0ed6971b285b6e80da918d892509e9e93568efb99f25`.
The target imported product code from the immutable source generation before
the D-only dependency site and passed 40 focused tests.

The browser contract remains speed in metres per second plus normalized
steering. On this stock PX4 v1.17.0 model, the worker's S1 adapter converts speed
to `RoverThrottleSetpoint` using `RO_MAX_THR_SPEED=3.1` and publishes
`RoverSteeringSetpoint` under Offboard `thrust_and_torque`, which retains PX4
arming and control allocation. It never publishes `ActuatorMotors` or
`ActuatorServos`. This adapter is sufficient for causal motion qualification
but is not evidence of calibrated closed-loop speed tracking.

The first cold start completed in one request after 32.08 seconds. Run
`s1c-49b0f47-20260724t195259z-62edd2` moved from `(0.00, 0.00)` to
`(3.74, -0.00)` in the straight case, then to `(5.11, 2.13)` through a turn and
to `(5.58, 0.67)` in reverse. One sampled command completed in 44.6 ms. A
single non-zero command expired at the 250 ms boundary and incremented
`ttl_expired_count` from 4 to 5; two following one-second-separated live
samples had identical X/Y. Explicit stop disarmed the virtual rover, completed
the run and left no PX4, Gazebo or Micro XRCE-DDS process residue.

This evidence checks the primary Ackermann command item only. S1 stays open for
Differential Rover, deceleration/emergency-stop profiles, accepted PX4/ROS 2
telemetry, reset/repeatability, heartbeat/offboard/link-loss, full failsafe and
navigation/safety cases.

#### S1E provider-neutral boundary status

The next repository increment makes provider interchangeability executable
rather than aspirational:

- `SimulationProviderProfile` strictly declares logical provider roles,
  capabilities, authoritative simulation clock, canonical ENU/FLU frames and
  supported rover control profiles;
- worker status v2 separates the configured provider stack from currently
  active process IDs;
- `VehicleState` retains the v1 canonical frame/safety contract but accepts any
  safe named diagnostic ground-truth provider;
- command acceptance v2 reports a generic controller provider, canonical
  control profile, readiness and bounded boolean diagnostics;
- the stock Gazebo/PX4/XRCE profile satisfies the new contract;
- backend and browser tests admit an Unreal-shaped profile without adding
  Unreal-specific branches.

This is contract acceptance only. It does not claim that Unreal is installed,
selected, running or qualified. ADR 0017 U0 is the next decision gate.

### S2

- Gazebo LiDAR/odometry feed the ROS 2/Nav2 baseline.
- Ackermann uses MPPI plus Smac Hybrid/Lattice or an explicitly justified
  equivalent.
- Static wall, corridor, bypass, narrow passage, no-data, planner timeout and
  control-loss scenarios produce comparable reports.
- PX4 waypoint following without obstacle avoidance and Nav2 are measured on
  the same profiles.
- A 30-world BARN pilot follows stock-world acceptance; only geometry, maps,
  paths and difficulty are imported from the legacy runtime.

## 19. Replay and dataset policy

Recorded datasets support detector, segmentation, tracking, occupancy and
shadow-policy regression. They do not react to alternative commands and cannot
prove a closed-loop avoidance maneuver.

- CODa and JRDB non-commercial/share-alike restrictions prohibit treating them
  as unrestricted commercial runtime dependencies.
- NCLT is large and must be admitted by a size/license manifest.
- SCAND supplies social-navigation demonstrations but remains replay evidence.
- RAVNOVES00 first enters as canonical replay/shadow; only S5 may turn an
  attested reconstruction into a digital-twin world.

Unknown or unobserved space remains unknown/occupied according to the selected
safety policy.

## 20. UI gate

Polygon is implemented as a permanent seventh top-level bounded context:

```text
Center | Fleet | Observation | Missions | Data | Polygon | System
```

The product surface and execution capability are intentionally distinct.
`Полигон` and its dataset catalog remain visible without a worker. Worker
capability gates only live lifecycle and command actions, which fail closed and
show an explicit offline state.

The Polygon navigation is task-oriented and currently has one operator
surface:

- `Датасеты` owns admitted replay inputs, their real source structure,
  operator inspection of source scans and analysis scoped to the selected
  dataset fragment;
- immutable run identity, aggregate qualification, provenance and artifacts
  remain available to backend evidence consumers but do not create a separate
  operator page.

Dataset bytes and source artifacts remain in Data storage, but algorithm
evaluation does not live under `Данные`. Device-specific scanner diagnostics
remain under Fleet. The operator sees metrics in the context of the exact
fragment being inspected; global gates, provider pins and artifact identities
are not mixed into that workflow.

Live simulation is a different operator task. A rover scene, worker health and
start/control actions must not be mounted above an archived dataset replay.
They require a separate future live surface that appears only when the
Simulation Worker capability is available.

### UI-0 — read-only dataset evidence inspection

Target S1B proves persisted start/health/stop history. The first direct
developer-oriented view exposed lifecycle, events, provider pins and artifact
hashes on the main screen. Operator review rejected that composition, rejected
treating the GOOSE validation split as a single recording and rejected a
separate aggregate Runs page. The current UI-0 is one coherent dataset
workflow:

- `Датасеты → Открыть датасет` shows the admitted source. GOOSE validation is
  explicitly grouped into eight independent fragments; Play is bounded to one
  fragment and described as accelerated review of sparse annotated scans.
- The catalog is multi-source. RELLIS-3D v1.1 appears as an independent Ouster
  domain with its own license and admission state. Its current `smoke-ready`
  view shows official frame `000104`, semantic colors, FLU axes and the
  versioned `ground / non-ground / ignore` mapping; it does not show invented
  algorithm metrics.
- The dataset viewer exposes source frame number, nanosecond timestamp gaps,
  ground truth and Current/Patchwork++ overlays.
- The fixed sensor-centric coordinate frame and operator camera are preserved
  within a fragment. Missing scans, ego trajectory and cross-fragment motion
  are never synthesized.
- Below the viewer, metrics are calculated only across the selected fragment:
  mean Ground IoU, natural-ground recall, obstacle preservation, improved and
  regressed frame counts, weakest Patchwork++ frame, strongest regression and
  largest capture gap. Every risk item opens its exact source frame.
- Global acceptance gates, run IDs, event journals, provider pins and artifact
  lists are not part of the operator screen.

The accepted `3.3 GB` annotated validation ZIP is not a continuous recording.
Continuous ego-motion requires a separately admitted raw ROS bag and
localization source.

RELLIS S0 uses only a bounded derivative of the pinned official example for
browser inspection. The full `14 GB` Ouster SemanticKITTI scans, labels and
poses remain a separate D-only admission gate. Its `CC-BY-NC-SA-3.0` license
means cross-dataset research evidence cannot silently become an unrestricted
commercial runtime or training dependency.

The backend reads the configured repository from
`MISSIONCORE_POLYGON_RUNS_ROOT` using
`QualificationRunStore(read_only=True)`. It exposes only:

```text
GET /api/v1/polygon/runs
GET /api/v1/polygon/runs/{run-id}
GET /api/v1/polygon/runs/{run-id}/qualification
GET /api/v1/polygon/runs/{run-id}/qualification/review
GET /api/v1/polygon/runs/{run-id}/qualification/review/frames/{frame-id}
```

Missing/malformed configuration returns `503`; invalid or corrupt evidence
fails closed. The review index exposes no paths or digests. A selected frame is
verified against the content-bound review manifest before its bounded point
preview is decoded. Responses never contain the configured root, raw dataset
bytes or command payloads. `?workspace=polygon-run[&run=<run-id>]` remains a
compatibility redirect into `polygon-datasets`; it does not restore a separate
Runs page.

UI-0 itself has no PX4 transport or lifecycle/command operations. It remains a
read-only evidence contract backed by the server-owned run repository and is
composed into UI-2. A shared review deployment requires a reviewed read-only D
mount or a co-located backend; SSH is not a product data plane.

### UI-2 — permanent Polygon with worker-gated live actions

The full UI-2 control/scenario gate begins only after:

1. this SRS and the clock/frame/authority contracts are accepted;
2. S1 target backend lifecycle and command authority are proven;
3. run history is persisted independently of a browser session.

Commit `60e7916` accepted the presentation/lifecycle slice before all three
conditions were complete. The root is now permanent so datasets and persisted
evidence remain reachable while the worker is offline; live start/stop and
commands remain capability-gated. The slice includes the direct workspace,
virtual-only start/stop, 3D rover inspection, diagnostic ENU pose and read-only
history. It does not claim command authority. Scenarios, pause/step/reset,
canonical rover commands, Compare and Report remain planned. UI-2 cannot own
provider processes, bypass authority checks or write directly to PX4.

The browser scene remains a canonical-state product view, not the physics
engine. A future Unreal worker supplies the same state/evidence contracts; it
is not embedded into React and its native editor/window remains diagnostic.

## 21. Change control

A material change requires:

1. an ADR/SRS diff;
2. an update to MISSIONCOR-39;
3. migration and compatibility notes;
4. new or updated tests;
5. fresh evidence before a previously accepted gate remains accepted.

No checkbox is closed from intent alone. A commit plus factual validation or
admitted evidence is required.
