Skip to main content
A run is a higher-level coordination unit that fans out a shared task to multiple agents simultaneously, collects their individual conclusions as run steps, and then applies an aggregation policy to produce a single final_decision. Runs build on top of individual task contracts — each agent step maps to one full task lifecycle internally — but you manage the whole group through a single run_id rather than tracking separate task_id values. Use runs when you need parallel exploration across different agents, models, or prompts and want the kernel to handle quorum, tie-breaking, and null-outcome recovery for you automatically.

The Run Spec Format

Define your run in a run-spec.json file. The minimal required fields are run_id, agents, and shared_inputs. Everything else defaults to sensible values.
run-spec.json
{
  "run_id": "analysis-run-001",
  "task_type": "swarm",
  "shared_inputs": {
    "topic": "quarterly-revenue-review",
    "data_url": "https://data.example.com/q3.json",
    "instructions": "Identify the top three revenue drivers and any anomalies."
  },
  "agents": [
    {
      "agent_id": "analyst-a",
      "prompt": "Focus on geographic trends in the revenue data.",
      "executor": "rt"
    },
    {
      "agent_id": "analyst-b",
      "prompt": "Focus on product-line contributions and margin changes.",
      "executor": "rt"
    },
    {
      "agent_id": "analyst-c",
      "prompt": "Focus on customer-segment shifts and churn signals.",
      "executor": "rt"
    }
  ],
  "aggregation": {
    "quorum": 2,
    "tie_policy": {
      "chain": ["STOCHASTIC"]
    },
    "null_policy": {
      "chain": ["REEXPLORE", "FINALIZE_NULL"]
    }
  }
}

Run spec field reference

FieldTypePurpose
run_idstringUnique identifier for this run.
task_typestringPassed into each agent’s TaskContract.task_type. Defaults to "swarm".
shared_inputsobjectBusiness context shared by all agents — see shared_inputs semantics below.
agentsarrayList of agent specs. Each entry becomes one run_step.
agents[].agent_idstringUnique identifier for this agent within the run.
agents[].promptstringAgent-specific instruction injected into TaskContract.inputs.prompt.
agents[].executorstringName of the registered executor to use for this agent’s step.
aggregation.quorumnumberMinimum number of agreeing agents required before the run finalizes. Optional.
aggregation.tie_policy.chainarrayOrdered list of tie resolvers to try when two or more values are equally represented.
aggregation.null_policy.chainarrayOrdered list of null resolvers to try when no consensus is reached.

shared_inputs semantics

shared_inputs is the run-level business context that every agent receives. When it is a JSON object, the kernel merges its key-value pairs directly into each agent step’s TaskContract.inputs. It then injects prompt and agent_id from the agent spec, overwriting any same-named keys that were already in shared_inputs. For example, with the run spec above, analyst-a receives this inputs object:
{
  "topic": "quarterly-revenue-review",
  "data_url": "https://data.example.com/q3.json",
  "instructions": "Identify the top three revenue drivers and any anomalies.",
  "prompt": "Focus on geographic trends in the revenue data.",
  "agent_id": "analyst-a"
}
The kernel forwards inputs as-is to the runtime /execute endpoint. URL and path values in shared_inputs are references only — WattSwarm does not auto-fetch remote pages or read local files on your behalf.

CLI Workflow

1

Initialize the run queue schema

Run this once per PostgreSQL database to create the runs, run_steps, and run_events tables:
wattswarm run init --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
If you are using Docker Compose, this runs automatically on container startup.
2

Submit the run spec and kick it off

Submit the spec and immediately move all steps to QUEUED state in one command:
wattswarm run submit ./run-spec.json --kickoff \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
Without --kickoff, the run and its steps are created in CREATED state. You can kickoff separately when ready:
wattswarm run kickoff analysis-run-001 \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
3

Start a worker process (if not using compose)

The run queue requires at least one active worker process to claim and execute steps. If you are not using the Docker Compose setup (which starts a worker automatically), run:
wattswarm run worker --concurrency 16 \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
The worker continuously polls for QUEUED or RETRY_WAIT steps, claims them with FOR UPDATE SKIP LOCKED, executes each step as a full task lifecycle, and advances the step to SUCCEEDED or FAILED.
4

Watch the run for completion

Poll the run status and per-step counts:
wattswarm run watch analysis-run-001 \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
{
  "run_id": "analysis-run-001",
  "status": "FINALIZED",
  "task_type": "swarm",
  "counts": {
    "created": 0,
    "queued": 0,
    "leased": 0,
    "succeeded": 3,
    "failed": 0,
    "retry_wait": 0,
    "cancelled": 0
  }
}
5

Fetch the final decision

Once the run status is FINALIZED, retrieve the aggregated result:
wattswarm run result analysis-run-001 \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
The result JSON contains final_decision, per-step conclusions, and aggregation metadata including resolution_paths and null_resolution for monitoring.
6

View the run event stream

Inspect the full sequence of run-level events for debugging or audit:
wattswarm run events analysis-run-001 \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
This returns up to 50 events by default. Pass --limit <n> to change the page size.

Aggregation Policies Explained

WattSwarm’s aggregation layer collects the final_decision from each completed step and applies your configured policies to resolve ties and null outcomes.

Tie resolvers (tie_policy.chain)

Tie resolvers run in order when two or more candidate values are equally represented across agent steps.

STOCHASTIC

Deterministic pseudo-random tie break derived from a hashed seed. No agent can predict or influence the outcome, but the result is reproducible given the same inputs. This is the default tie resolver.

CONFIDENCE_WEIGHTED

Sums the confidence field (or answer_confidence / decision_confidence) from each step’s output per candidate value and chooses the value with the unique highest total. Requires your executor to return a numeric confidence.

REPUTATION_WEIGHTED

Sums agent_reputation_units per candidate value and chooses the value with the unique highest total. Reputation scores are drawn from the local knowledge store. Useful when agents have a track record in the knowledge base.

REEXPLORE

Re-queues all terminal steps, injects an _aggregation_signal into each step’s inputs (NEED_MORE_EVIDENCE), and starts another execution round. Emits RUN_TIE_REEXPLORE_TRIGGERED. Subject to max_tie_iterations and no_new_evidence_rounds guards.

Null resolvers (null_policy.chain)

Null resolvers run independently of the tie chain when no consensus is reached at all (empty result set or quorum null).
ResolverBehavior
REEXPLORERe-queues terminal steps with an _aggregation_signal (NEED_DECISION, NEED_STEP_RECOVERY, or NEED_MORE_EVIDENCE). Emits RUN_NULL_REEXPLORE_TRIGGERED.
FINALIZE_NULLAccepts null as the final decision when no consensus can be reached after exhausting all other resolvers. Prevents the run from hanging indefinitely.

Cancel and Retry

To cancel a running or queued run:
wattswarm run cancel analysis-run-001 \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm
To retry a failed run (resets failed steps back to QUEUED):
wattswarm run retry analysis-run-001 \
  --pg-url postgres://postgres:postgres@127.0.0.1:55432/wattswarm

Worker process required. Writing rows directly into the runs table is not sufficient for execution. The queue requires valid run_steps rows and at least one active run worker process. If you are using Docker Compose, the worker container handles this automatically. For standalone setups, keep a run worker process running alongside the kernel.