Simulation
A scenario says where it runs and owns both sides. Start one and the pipeline sees simulated observations through the same door a sensor uses; stop it and the run is on the record.
Scenarios
curl https://<your-backend-host>/api/scenarios
curl -X POST https://<your-backend-host>/api/scenarios \
-H "Content-Type: application/json" \
-d '{ "name": "3v2 intercept", "spec": { "…": "…" } }'
A scenario row is a name and a spec, the declarative document the console's
scenario editor writes: the region it runs over, both force sides, and what each is
trying to do. PUT /api/scenarios/{id} updates, DELETE removes.
The simulation lifecycle
curl https://<your-backend-host>/api/sim/simulators # what this build can run
curl https://<your-backend-host>/api/sim/state # what is running now
curl -X POST https://<your-backend-host>/api/sim/start \
-H "Content-Type: application/json" -d '{ "scenario_id": "<uuid>" }'
curl -X POST https://<your-backend-host>/api/sim/pause \
-H "Content-Type: application/json" -d '{ "paused": true }'
curl -X POST https://<your-backend-host>/api/sim/stop
PUT /api/sim/state selects the workspace's simulation mode and simulator; it
answers 409 while a run is live and the change would swap the environment out
from under it. Progress during a run rides the stream:
simulated tracks arrive as track_update events flagged simulated, and the
picture's sim block carries the run's clock.
The older /api/simulation/start|stop|pause|resume|status routes drive the
embedded kinematic simulator directly and answer 501 on a build without the
simulator feature.
Recorded runs
Every run is recorded: which scenario, when, and every event the pipeline produced while it ran.
curl "https://<your-backend-host>/api/simulation/runs?limit=20"
curl https://<your-backend-host>/api/simulation/runs/<run-id>
curl "https://<your-backend-host>/api/simulation/runs/<run-id>/events?kind=track&limit=1000"
curl -X DELETE https://<your-backend-host>/api/simulation/runs/<run-id>
The events route takes the same kind, since, until and limit filters as
the event log, scoped to one run. Replaying a run is reading
its events back in order; reproducing one is starting its scenario again from the
same seed.