Skip to main content

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​

Every route here wants a credential and X-Workspace-Id. Without the workspace header a route answers 400 and names it.

curl https://<your-backend-host>/api/scenarios \
-H "Authorization: Bearer $TOKEN" -H "X-Workspace-Id: $WORKSPACE"

curl -X POST https://<your-backend-host>/api/scenarios \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" -H "X-Workspace-Id: $WORKSPACE" \
-d '{ "name": "Harbour, two waves", "spec": { "…": "…" } }'

A scenario row is a name and a spec: the seed, the region, the environment, the forces, the time and the video. Each force has an id, a side (defender or adversary), a controller (c2 for a force DomeCommand flies, scenario for one the simulator flies), an optional objective, its drones as a swarm or a specific list, and its assets: sensors and effectors, each with an id and roles. A worked document is on Scenario model, and the whole run in curl on Running a simulation.

The spec is stored in its canonical form. A document written in the shorthand, with a friendlies fleet and an attack fleet, comes back as forces, the defending force carries the default sensor layout, and keys nothing reads are dropped. Read the answer rather than assuming it matches what you sent. A spec that does not deserialise is refused with 400 and the field that broke it.

PUT /api/scenarios/{id} replaces the spec, canonicalised the same way. DELETE removes it.

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.

A build without the simulator feature has no embedded simulator to drive, and POST /api/sim/start answers 501 on one.

Recorded runs​

Every run is recorded: which scenario, when, and every event the pipeline produced while it ran.

curl "https://<your-backend-host>/api/sim/runs?limit=20"
curl https://<your-backend-host>/api/sim/runs/<run-id>
curl "https://<your-backend-host>/api/sim/runs/<run-id>/events?kind=track&limit=1000"
curl -X DELETE https://<your-backend-host>/api/sim/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.