docs(simulation): accept S1C live worker

This commit is contained in:
DCCONSTRUCTIONS 2026-07-24 20:47:08 +03:00
parent b7ccca3481
commit 1995dfdf68
5 changed files with 217 additions and 16 deletions

View File

@ -172,11 +172,36 @@ metadata and the virtual-only authority boundary. Live pause/resume/step/reset,
canonical telemetry, PX4 command mapping, watchdog/failsafe evidence and the canonical telemetry, PX4 command mapping, watchdog/failsafe evidence and the
top-level Polygon control surface remain gated. top-level Polygon control surface remain gated.
Configure a Mission Core backend that can read the accepted D repository and S1C commit `b7ccca3` adds the first registered live-worker vertical without
open the direct route: collapsing that boundary. An unprivileged worker agent owns the existing
application service and providers inside a fresh loopback-only network
namespace. Mission Core reaches it through a mode-`0600` Unix socket; React
reaches only same-origin Polygon API routes. The live browser panel can
start/stop the stock rover, show worker/run/provider status and render a bounded
top-down ENU trajectory from Gazebo dynamic-pose ground truth. That pose is
explicitly `diagnostic`, not accepted PX4/ROS 2 telemetry.
The exact D-only generation passed 21 target tests and a real UI-driven run
`s1c-b7ccca3-20260724t174030z-8e46b3`: both providers reached readiness, the
browser received live `VehicleState`, the run reached `completed` after
52.836 seconds of Gazebo time, and shutdown left no PX4/Gazebo/XRCE process
residue. The run contained zero commands, so this result does not yet prove
rover motion, PX4 command delivery, watchdog/failsafe behavior, navigation or
safety acceptance.
Start the worker from the exact immutable D source generation:
```bash
sudo simulation/s1/worker-agent.sh <exact-40-character-mission-core-commit>
```
Then configure the Mission Core backend and open the direct route:
```bash ```bash
export MISSIONCORE_POLYGON_RUNS_ROOT=/mnt/d/NDC_MISSIONCORE/simulation/artifacts/s1/runs export MISSIONCORE_POLYGON_RUNS_ROOT=/mnt/d/NDC_MISSIONCORE/simulation/artifacts/s1/runs
export MISSIONCORE_POLYGON_WORKER_SOCKET=/run/missioncore-sim/worker.sock
export MISSIONCORE_POLYGON_WORKER_CONTROL=internal-virtual-only
export MISSIONCORE_COMMIT=<exact-40-character-mission-core-commit>
uv run uvicorn k1link.web.app:app --host 127.0.0.1 --port 8765 uv run uvicorn k1link.web.app:app --host 127.0.0.1 --port 8765
``` ```
@ -184,15 +209,18 @@ uv run uvicorn k1link.web.app:app --host 127.0.0.1 --port 8765
http://127.0.0.1:8765/?workspace=polygon-run&run=<qualification-run-id> http://127.0.0.1:8765/?workspace=polygon-run&run=<qualification-run-id>
``` ```
The API provides `GET /api/v1/polygon/runs` and The archive API remains GET-only. The worker API adds status/live GETs and
`GET /api/v1/polygon/runs/{run-id}` only. Missing configuration returns `503`; explicit start/stop POSTs; POSTs remain `403` unless the backend has the
invalid/corrupt evidence fails closed. The browser receives no D root, artifact `internal-virtual-only` gate and an exact commit. Missing configuration,
bytes, command payloads or PX4/process-lifecycle operation. transport drift and corrupt evidence fail closed. The browser receives no Unix
socket, D root, artifact bytes, PX4 endpoint or direct provider command.
See the [Polygon product/SRS](docs/12_SIMULATION_POLYGON_PRODUCT_AND_SRS.md), See the [Polygon product/SRS](docs/12_SIMULATION_POLYGON_PRODUCT_AND_SRS.md),
[ADR 0015](docs/adr/0015-simulation-polygon-qualification-boundary.md), [ADR 0015](docs/adr/0015-simulation-polygon-qualification-boundary.md),
[ADR 0016](docs/adr/0016-distributed-product-edge-and-worker-topology.md) and the [ADR 0016](docs/adr/0016-distributed-product-edge-and-worker-topology.md) and the
[SIM S0 worker runbook](docs/runbooks/SIM_S0_AI_WORKER.md). [SIM S0 worker runbook](docs/runbooks/SIM_S0_AI_WORKER.md). The live-worker
launch and acceptance procedure is in
[SIM S1C live-worker runbook](docs/runbooks/SIM_S1C_LIVE_WORKER.md).
Mission Core remains a distributed browser product rather than a Mission Core remains a distributed browser product rather than a
platform-specific desktop executable. React runs in the operator browser; platform-specific desktop executable. React runs in the operator browser;

View File

@ -24,7 +24,7 @@ Each gate produces evidence and an explicit GO, PAUSE or BLOCKED result.
| Plugin isolation | GO (laboratory control plane) — vendor backend/frontend and optional scene controls are plugin-owned; manifest/runtime descriptor parity, versioned handshake, lifecycle health and transport correlation fail closed while execution remains in-process | | Plugin isolation | GO (laboratory control plane) — vendor backend/frontend and optional scene controls are plugin-owned; manifest/runtime descriptor parity, versioned handshake, lifecycle health and transport correlation fail closed while execution remains in-process |
| K1 application control | GO (physical staged cycle) — after fixing the PCAP-proven `sint64` time field, one explicit UI launch completed all 14 canonical operations on one control session, reached live `SCANNING + project + init_ready`, displayed real points, then one explicit STOP returned K1 to unbound `READY`. No retry or fallback command was sent. Native-project reuse through LixelGO/USB remains an independent verification | | K1 application control | GO (physical staged cycle) — after fixing the PCAP-proven `sint64` time field, one explicit UI launch completed all 14 canonical operations on one control session, reached live `SCANNING + project + init_ready`, displayed real points, then one explicit STOP returned K1 to unbound `READY`. No retry or fallback command was sent. Native-project reuse through LixelGO/USB remains an independent verification |
| Stage 8 product storage | PAUSE — retention, replication, encryption, capacity monitoring and long-run browser/WASM stress remain deployment gates | | Stage 8 product storage | PAUSE — retention, replication, encryption, capacity monitoring and long-run browser/WASM stress remain deployment gates |
| Simulation Polygon | SIM S0 GO; S1A complete; S1B real-provider lifecycle PASS; UI-0 internal read-only run view PASS — exact commit `6cb1495` passed 25 target tests and one D-only loopback stock-Ackermann run. Mission Core admitted world/startup/DDS health, persisted eight events, sent zero commands and stopped both PGIDs with zero residue. The Control Station now reads that canonical journal through GET-only Polygon API routes and a direct hidden workspace; visual QA opened the real accepted run. Pause/resume/step/reset, PX4 command delivery, canonical telemetry/frames, watchdog/failsafe, navigation/safety acceptance and real actuator authority remain absent; top-level Polygon remains gated | | Simulation Polygon | SIM S0 GO; S1A complete; S1B lifecycle PASS; S1C registered live worker/UI PASS — exact commit `b7ccca3` passed 21 focused target tests and a UI-driven D-only PX4/Gazebo run. Mission Core registered the loopback-only unprivileged worker through a private Unix socket, rendered diagnostic ENU `VehicleState`, persisted eight events and stopped both provider groups with zero residue. The run sent zero commands; PX4 command delivery/motion, canonical PX4/ROS 2 telemetry, pause/step/reset, watchdog/failsafe, navigation/safety acceptance, auth/RBAC and real actuator authority remain absent; top-level Polygon remains gated |
USB project copying remains optional ground truth rather than a blocker for the USB project copying remains optional ground truth rather than a blocker for the
now-verified network path. Owner-operated LixelGO traffic verifies the MQTT now-verified network path. Owner-operated LixelGO traffic verifies the MQTT
@ -160,9 +160,15 @@ exact-profile/D-only worker guard, health-gated real provider specs and
deterministic POSIX PGID supervision. Exact generation `6cb1495` passed on deterministic POSIX PGID supervision. Exact generation `6cb1495` passed on
`MissionCore-Sim`: Micro XRCE-DDS Agent and PX4/Gazebo stock rover ran inside a `MissionCore-Sim`: Micro XRCE-DDS Agent and PX4/Gazebo stock rover ran inside a
fresh loopback-only namespace, the run reached `completed`, and both provider fresh loopback-only namespace, the run reached `completed`, and both provider
groups stopped without residue. Live world control, PX4 command delivery, groups stopped without residue. S1C commit `b7ccca3` adds a persistent
heartbeat/watchdog execution and captured failsafe outcomes remain the next S1 unprivileged worker agent in the same isolation boundary, a bounded Unix-socket
increments. gateway, an explicit `internal-virtual-only` backend gate and a browser-native
live panel. The exact D-only generation passed 21 target tests and one
UI-driven provider run with diagnostic Gazebo `VehicleState`, eight persisted
lifecycle events, terminal `completed` and zero process residue. Its
zero-command stationary rover does not close PX4 command delivery, canonical
PX4/ROS 2 telemetry, pause/step/reset, heartbeat/watchdog or failsafe checkers;
these remain the next S1 increments.
UI-0 now consumes the same append-only run repository through UI-0 now consumes the same append-only run repository through
`GET /api/v1/polygon/runs` and `GET /api/v1/polygon/runs` and
@ -172,10 +178,12 @@ write transition. The Control Station opens the internal
`polygon-run-internal` workspace only for the direct `polygon-run-internal` workspace only for the direct
`?workspace=polygon-run[&run=<id>]` route; it is filtered out of System `?workspace=polygon-run[&run=<id>]` route; it is filtered out of System
navigation and adds no seventh top-level section. Browser QA loaded the accepted navigation and adds no seventh top-level section. Browser QA loaded the accepted
real run with eight events, four provider pins, zero commands and the unchanged archive and the S1C live worker. The hidden UI-1 panel shows
virtual-only authority boundary. A shared operator-facing deployment still worker/run/provider status, sim time, ENU/FLU pose and a bounded 2D trajectory.
requires a reviewed read-only D mount/source configuration; UI-0 does not use Start/stop stays behind the backend gate and reaches the worker through a local
SSH as a product data plane. Unix socket; SSH remains qualification bootstrap, never the product data plane.
A shared operator-facing deployment still requires authentication/RBAC,
service supervision and an accepted routed worker transport.
Mission Core remains a distributed web product. React is served by a long-lived Mission Core remains a distributed web product. React is served by a long-lived
Gateway/API and renders canonical state through browser-native components. Gateway/API and renders canonical state through browser-native components.

View File

@ -73,6 +73,18 @@ Polygon is now a parallel product branch. As of this document:
over GET-only Polygon API routes. Browser QA loaded the real accepted S1B over GET-only Polygon API routes. Browser QA loaded the real accepted S1B
journal and displayed its four provider pins, eight events, zero commands and journal and displayed its four provider pins, eight events, zero commands and
unchanged virtual-only authority boundary; 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;
- the hidden UI-1 live panel starts/stops the stock rover through Mission Core,
polls canonical worker state and renders a bounded ENU trajectory from
Gazebo dynamic-pose ground truth. The signal is marked `diagnostic`;
- the UI-driven target run
`s1c-b7ccca3-20260724t174030z-8e46b3` reached `completed` with eight
persisted events, 52.836 seconds of Gazebo time and zero provider residue;
it contained zero commands and therefore does not prove rover motion or PX4
command delivery;
- `actuator_authority=false`; - `actuator_authority=false`;
- `navigation_or_safety_accepted=false`. - `navigation_or_safety_accepted=false`.
@ -672,6 +684,20 @@ restart-safe PID/start-token reconciliation, live
pause/resume/step/reset, canonical VehicleState, frame conversion, rover command pause/resume/step/reset, canonical VehicleState, frame conversion, rover command
mapping, watchdog/failsafe cases, repeatability or S1 as a whole. 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.
### S2 ### S2
- Gazebo LiDAR/odometry feed the ROS 2/Nav2 baseline. - Gazebo LiDAR/odometry feed the ROS 2/Nav2 baseline.

View File

@ -126,6 +126,16 @@ The current `MissionCore-Sim` WSL2 distribution on the D drive is this
topology's first qualified worker. Its native Gazebo window is local diagnostics; topology's first qualified worker. Its native Gazebo window is local diagnostics;
the product view remains browser-native. the product view remains browser-native.
The first implemented registration slice is S1C commit `b7ccca3`. Mission Core
and the worker share only a private mode-`0600` Unix socket in the WSL mount
namespace. PX4, Gazebo and Micro XRCE-DDS stay inside the worker's
loopback-only network namespace and run as the unprivileged `missioncore`
identity. Run artifacts and provider logs remain under the admitted D-only
roots. The React client calls same-origin Mission Core endpoints and never
receives the socket path or a provider endpoint. Remote/routed worker
registration is intentionally not inferred from this local laboratory
transport; it requires an authenticated contract of its own.
### Connected field vehicle ### Connected field vehicle
```text ```text
@ -169,4 +179,3 @@ application. It is the review side of the same distributed system.
- Field hardware, storage budgets, network-loss policy, physical e-stop, - Field hardware, storage budgets, network-loss policy, physical e-stop,
operator takeover and real actuator authority still require separate operator takeover and real actuator authority still require separate
acceptance. acceptance.

View File

@ -0,0 +1,130 @@
# SIM S1C live-worker runbook
## Scope
This runbook starts the first browser-visible stock Ackermann rover through the
Mission Core control plane. It accepts only a virtual PX4/Gazebo run. It does
not admit a physical vehicle, direct actuator setpoints, navigation or safety.
Runtime placement:
```text
React Control Station
-> same-origin Mission Core Polygon API
-> mode-0600 Unix socket
-> unprivileged Simulation Worker agent
-> loopback-only network namespace
-> Micro XRCE-DDS Agent + PX4 SITL + Gazebo Harmonic
```
The Unix socket is ephemeral runtime coordination. Source, run journals,
provider logs and qualification artifacts remain under
`/mnt/d/NDC_MISSIONCORE/simulation`.
## Preconditions
- use the dedicated `MissionCore-Sim` WSL distribution;
- stage an immutable Git archive below the reviewed D root;
- verify its SHA-256 against the source artifact;
- use an exact 40-character Mission Core commit;
- confirm no PX4, Gazebo or Micro XRCE-DDS provider residue exists;
- keep `actuator_authority=false`;
- do not add a routed NIC to the worker namespace.
## Start worker agent
From the exact staged source generation:
```bash
sudo simulation/s1/worker-agent.sh <exact-40-character-commit>
```
The wrapper creates `/run/missioncore-sim` as a private runtime directory,
enters a fresh network namespace, raises only loopback and drops to the
`missioncore` user before importing product code.
Expected status through the backend gateway:
```json
{
"schema_version": "missioncore.simulation-worker-status/v1",
"worker_id": "mission-gpu-s1",
"transport": "unix",
"mode": "simulation",
"available": true,
"control_available": true,
"active_run_id": null,
"run_state": null
}
```
## Start Mission Core
```bash
export MISSIONCORE_POLYGON_RUNS_ROOT=/mnt/d/NDC_MISSIONCORE/simulation/artifacts/s1/runs
export MISSIONCORE_POLYGON_WORKER_SOCKET=/run/missioncore-sim/worker.sock
export MISSIONCORE_POLYGON_WORKER_CONTROL=internal-virtual-only
export MISSIONCORE_COMMIT=<exact-40-character-commit>
uv run uvicorn k1link.web.app:app --host 127.0.0.1 --port 8765
```
Open:
```text
http://127.0.0.1:8765/?workspace=polygon-run
```
The live panel must show `Worker готов`. Start/stop calls require an
`Idempotency-Key`; the React client generates one per operator intent. Removing
the `internal-virtual-only` environment gate must leave status visible while
disabling lifecycle actions.
## Live-state contract
The first S1C live sample comes from:
```text
/world/rover/dynamic_pose/info
```
It is published to the browser as `missioncore.vehicle-state/v1` with:
- `frame_id=map_enu`;
- `child_frame_id=base_link_flu`;
- integer Gazebo simulation time;
- bounded position and quaternion;
- `signal=ground-truth`;
- `quality=diagnostic`;
- `scope=virtual-only`;
- no navigation or safety acceptance.
This signal proves live presentation and frame naming only. It is not the
accepted PX4/ROS 2 telemetry path.
## Acceptance checklist
- [ ] exact source commit and source/build SHA-256 recorded;
- [ ] focused target tests pass from the same staged generation;
- [ ] worker status reports loopback-only, unprivileged and D-only boundaries;
- [ ] browser start creates one new immutable qualification run;
- [ ] status traverses `starting -> running`;
- [ ] both provider IDs appear only after readiness;
- [ ] live samples advance in Gazebo time;
- [ ] React shows run ID, sim time, ENU pose and provider list;
- [ ] archive remains path-free and command content is not exposed;
- [ ] browser stop reaches terminal `completed`;
- [ ] stop records `operator-stop-clean`;
- [ ] PX4, Gazebo and Micro XRCE-DDS leave no process residue;
- [ ] command count remains zero until the command-delivery checker is accepted.
## Failure handling
- A missing socket returns unavailable status; it does not fall back to PX4.
- Start/stop is `403` without the explicit backend control gate.
- Commit drift is rejected before provider start.
- A malformed or oversized worker message fails the gateway contract.
- Provider readiness failure seals the run as failed and triggers supervised
cleanup.
- Agent termination aborts an active run and stops owned provider groups.
- Agent restart reconciles an interrupted journal as failed; restart-safe
cross-process PID ownership remains a separate open checker.