wattswarm kernel with its UI console and Iroh-backed P2P bridge, the wattswarm-runtime reference HTTP executor, and a background run worker process that continuously claims and executes queued run steps. All three Rust services use cargo watch with the local source tree bind-mounted, so any code change you save triggers an automatic rebuild and process restart — no manual docker compose restart needed.
Prerequisites
-
Docker Desktop (macOS/Windows) or Docker Engine + Compose plugin (Linux). The
docker composesubcommand must be available; v2 Compose is required. -
The WattSwarm source tree cloned locally:
Default ports
| Service | Host Port | Notes |
|---|---|---|
| PostgreSQL | 55432 | Maps to container port 5432 |
| Kernel UI | 7788 | Kernel console at /, swarm dashboard at /swarm |
| Kernel P2P | 4001 | Iroh QUIC direct listen port |
| Runtime HTTP | 8787 | Reference runtime /health, /execute, /verify |
Steps
Clone the repo and enter the directory
If you have not already cloned the repository, do so now and change into it:The
docker-compose.yml at the root of the repo defines all four services and the two named volumes (wattswarm_pg_data and wattswarm_state_data).Start the full stack
Build images and start all services in detached mode:Compose starts services in dependency order:
postgres— waits untilpg_isreadypasses its health check.runtime— waits until/healthreturns200.kernel— waits for bothpostgresandruntimeto be healthy, then runsrun initto bootstrap the queue schema, auto-registers thertexecutor pointing athttp://runtime:8787, and starts the UI server on0.0.0.0:7788.worker— starts the backgroundrun workerloop withWATTSWARM_P2P_ENABLED=falseto prevent conflicts with the kernel over the shared state volume.
kernel, runtime, and worker bind-mount the local source tree (.:/app) and run under cargo watch, saving a .rs file automatically triggers a rebuild and clean restart of that container — no image rebuild required during normal development.Open the kernel console
Once the kernel container is healthy, open the UI console in your browser:The console gives you point-and-click access to every CLI operation group: node up/down/status, peers, log head/replay/verify, executor add/list/check, task sample/submit/watch/decision/run-real, and knowledge export. It also includes a built-in Quick Start panel with ordered operation steps and a minimal The swarm dashboard drives real kernel transitions via
TaskContract reference snippet.For the real swarm dashboard (live task lifecycle map, consensus log, and agent panels):GET /api/swarm/state and POST /api/swarm/tick, so the panels reflect actual SEL and projection state — not a simulation.Submit a run via the CLI
With the compose stack running, use the CLI from your host machine and point it at the compose PostgreSQL instance with The command prints a JSON object containing the new
--pg-url. The --kickoff flag moves the run and its steps to QUEUED immediately after creation so the background worker can pick them up.run_id. The compose worker container will begin claiming and executing run steps within WATTSWARM_WORKER_POLL_MS milliseconds (default 250 ms).Submitting a run spec is not sufficient on its own — the run queue requires an active worker process to claim and execute steps. The compose
worker service provides that worker automatically. If you run without Compose, start a worker yourself with run worker.Watch the run
Poll the run status and step conclusions using the The command prints a pretty-printed JSON view of the run record including current status (
run_id returned by run submit:PENDING, RUNNING, FINALIZED, FAILED), per-step conclusions, and the aggregated result_json once the run reaches a terminal state. You can also stream the raw event log for a run:Custom ports
Override any default host port by setting environment variables beforedocker compose up. All four host-port variables are recognized by the compose file:
| Variable | Default | Controls |
|---|---|---|
WATTSWARM_PG_HOST_PORT | 55432 | PostgreSQL host binding |
WATTSWARM_UI_PORT | 7788 | Kernel UI / console host binding |
WATTSWARM_P2P_HOST_PORT | 4001 | Iroh QUIC P2P host binding |
WATTSWARM_RUNTIME_PORT | 8787 | Reference runtime host binding |
P2P and network mode options
| Command | Description |
|---|---|
docker compose up -d --build | Default — P2P enabled, Iroh-backed local mode |
WATTSWARM_P2P_ENABLED=false docker compose up -d --build | Local-only, no P2P bridge started |
WATTSWARM_UDP_ANNOUNCE_ENABLED=true docker compose up -d --build | Enables UDP multicast peer discovery (default multicast group 239.255.42.99:37931) |
WATTSWARM_UDP_ANNOUNCE_ENABLED=true, the kernel emits an announce payload on startup and listens on WATTSWARM_UDP_ANNOUNCE_PORT (default 37931). Discovered peer IDs are persisted locally so the peers list command and the Peers panel in the console can surface them. To use broadcast instead of multicast:
Worker tuning
The backgroundworker container reads three environment variables that control how aggressively it claims and processes run steps:
| Variable | Default | Description |
|---|---|---|
WATTSWARM_WORKER_CONCURRENCY | 16 | Maximum number of run steps claimed and executed in parallel |
WATTSWARM_WORKER_POLL_MS | 250 | Milliseconds between polling cycles when no steps are available |
WATTSWARM_WORKER_LEASE_MS | 30000 | Lease duration in milliseconds; a step not renewed within this window is made reclaimable |
UI entrypoints
| URL | Description |
|---|---|
http://127.0.0.1:7788/ | Kernel console — node, peers, log, executors, tasks, knowledge |
http://127.0.0.1:7788/swarm | Real swarm dashboard — live lifecycle map and consensus panels |
diagnostics/wattswarm_node.jsonl from the state directory and returns structured transport, gossip, backfill, and agent-callback events — useful for multi-node debugging without leaving the browser.
State persistence
The kernel’s node-local state is stored in the named Docker volume
On macOS with Docker Desktop these files live inside the VM-managed volume. Access them through the container (
wattswarm_state_data, mounted at /var/lib/wattswarm inside the container. Three files drive node identity and startup behavior:| File | Purpose |
|---|---|
startup_config.json | Network mode, bootstrap contacts, gateway URLs, core agent |
node_state.json | Whether the node is currently marked up or down, and its mode |
node_seed.hex | Ed25519 seed that determines the node’s permanent node_id |
docker exec -it wattswarm-kernel cat /var/lib/wattswarm/node_state.json) or copy them out with docker cp wattswarm-kernel:/var/lib/wattswarm/node_seed.hex . — do not rely on the repo-local .wattswarm/ directory for compose-managed state.