Phase 5 implementation allows the Inspector to spawn and kill continuum-run processes, enabling dynamic world loading without manual restarts.
- Process Spawning - Inspector spawns
continuum-runas child process - Process Killing - Clean shutdown with socket cleanup
- REST API Endpoints -
/api/sim/load,/api/sim/stop,/api/sim/restart,/api/sim/status - Graceful Shutdown - SIGTERM/SIGINT handler kills child process
- Auto-launch - If
--worldprovided at startup, automatically spawns simulation
Load a new world, killing any existing simulation.
Request:
{
"world_path": "examples/terra",
"scenario": "default" // optional
}Response:
{
"success": true,
"message": "Loaded world: examples/terra"
}Stop the current simulation.
Response:
{
"success": true,
"message": "Simulation stopped"
}Restart the current world (must have previously loaded one).
Response:
{
"success": true,
"message": "Simulation restarted"
}Check if simulation is running and which world is loaded.
Response:
{
"running": true,
"world_path": "examples/terra"
}cargo run --bin continuum_inspector -- examples/terra --bind 127.0.0.1:8080 --socket /tmp/test.sockExpected:
- Inspector starts on http://127.0.0.1:8080
- Terra world auto-spawns
- Socket appears at
/tmp/test.sock - WebSocket connects successfully
# Terminal 1: Start inspector without world
cargo run --bin continuum_inspector -- --bind 127.0.0.1:8080 --socket /tmp/test.sock
# Terminal 2: Load world via API
curl -X POST http://localhost:8080/api/sim/load \
-H "Content-Type: application/json" \
-d '{"world_path": "examples/terra"}'Expected:
- API returns
{"success": true, ...} - Socket file
/tmp/test.sockappears - WebSocket connects
- Simulation starts ticking
- Start inspector:
cargo run --bin continuum_inspector - Open http://localhost:8080
- Click "Sim Controls" button
- Enter world path:
examples/terra - Click "Load World"
Expected:
- Success message appears
- Simulation starts
- Tick count increases
curl -X POST http://localhost:8080/api/sim/stopExpected:
- Simulation process terminates
- Socket file removed
- WebSocket disconnects
- API returns success
# After loading a world
curl -X POST http://localhost:8080/api/sim/restartExpected:
- Old process killed
- New process spawned
- Socket recreated
- WebSocket reconnects
- Tick count resets to 0
# Load terra
curl -X POST http://localhost:8080/api/sim/load \
-H "Content-Type: application/json" \
-d '{"world_path": "examples/terra"}'
# Switch to poc
curl -X POST http://localhost:8080/api/sim/load \
-H "Content-Type: application/json" \
-d '{"world_path": "examples/poc"}'Expected:
- Terra process killed
- POC process spawned
- No socket leaks
- WebSocket reconnects
# Terminal 1: Start with world
cargo run --bin continuum_inspector -- examples/terra --socket /tmp/test.sock
# Terminal 2: Send SIGTERM
pkill -SIGTERM continuum_inspector
# Or use Ctrl+C in Terminal 1Expected:
- Inspector receives signal
- Child
continuum-runprocess killed - Socket file removed
- Clean exit
# Manually create a bad continuum-run that doesn't create socket
cat > /tmp/fake-continuum-run << 'EOF'
#!/bin/bash
sleep 100
EOF
chmod +x /tmp/fake-continuum-run
# Temporarily replace continuum-run in PATH
export PATH="/tmp:$PATH"
# Try to load - should timeout after 5 seconds
curl -X POST http://localhost:8080/api/sim/load \
-H "Content-Type: application/json" \
-d '{"world_path": "examples/terra"}'Expected:
- Request times out after ~5 seconds
- Error message: "Timeout waiting for socket to be created"
- Process is killed
- No orphaned processes
Symptom: "Failed to bind socket: Address already in use"
Fix:
rm /tmp/continuum-inspector.sock
# Or use different socket path
cargo run --bin continuum_inspector -- --socket /tmp/my-socket.sockSymptom: "Failed to spawn continuum-run: No such file"
Fix: Ensure continuum-run is built and in PATH:
cargo build --bin continuum-run
export PATH="$PWD/target/debug:$PATH"Symptom: Multiple continuum-run processes running
Fix:
pkill continuum-run
rm /tmp/*.sock- Inspector starts successfully
- World auto-launches if provided at startup
- Load world via API works
- Load world via UI works
- Stop simulation cleans up process and socket
- Restart simulation works
- Loading different world kills previous one
- Graceful shutdown (Ctrl+C) kills child process
- Socket timeout prevents hanging
- No orphaned processes after shutdown
- Multiple load/stop/restart cycles work without issues
Frontend updates needed:
- Update
TickEventtype to includeexecution_state,tick_rate,last_error - Wire up run/pause/resume handlers in Header
- Add tick rate slider control
- Show error state banner with resume button
- Handle execution state changes (running/paused/error)