Skip to content

Getting started · 0.4.11 · Experimental developer preview

Keep your agents’ Work valid.

How Dispatch judges Work against the code as it is now, then install, watch a project, attach the agent you already use, and accept or reject what it produced.

Suitability

When to use Dispatch.

Dispatch at rundispatch.sh, the local CLI for validating coding-agent changes. It is worth running wherever more than one thing changes a repository while agents work.

Use it when

  • The repository changes while an agent works: you commit, you pull a teammate’s merge, or another agent’s Work lands.
  • Several agents work in separate worktrees on one repository and land one at a time. After each landing, Dispatch judges the rest against the new code.
  • You are about to integrate a change an agent made from an older snapshot, and you want to know whether it still holds, with reasons, before it lands.

It adds little when

  • One agent works on a repository nothing else changes during the task. The code did not move, so the verdict is CONTINUE.
  • You need a security sandbox. Agents and checks run with your operating-system permissions.
  • You want stale Work fixed for you. Dispatch does not rebase, resolve conflicts or rerun an agent by itself; it tells you to redo the Work.
  • You need a hosted service or a server-side merge queue. Dispatch is a local CLI with no server.
  • You need symbol-level analysis outside Rust and Python. Other languages get file-level facts: any change to a file the Work edits or names is a REFRESH.
  • You are not on macOS arm64 or Linux x86_64. Those are the only prebuilt releases; other platforms are untested.

A rebase and your tests tell you whether the merge is clean and the tests pass. Dispatch also keeps the snapshot the Work started from, names the declaration it relied on that changed, and blocks dispatch accept until the Work is redone.

Dispatch judges the local checkout it watches. A teammate’s merge counts once you pull it into that checkout. The verdict gates dispatch accept, which applies Work only when it still holds. Interactions between pieces of Work are advisory and block nothing.

Operating Dispatch from a coding agent? The agent guide covers verdict handling, authorization and the JSON output.

Work coherence

Before setup: how Work stays valid.

Every piece of Work has an S0, the code it started from, and a Δ, the patch it produced. dispatch check evaluates Δ against the source as it is now; the verdict is always recomputed, never trusted from an earlier moment. dispatch accept evaluates again, runs your checks on the merged tree when the source moved, and applies only if that gate passes.

VerdictMeaningAt accept timeMid-run (native runs)
CONTINUEThe source did not move, or nothing the Work relied on changed, as far as the analysis sees.If the source moved, checks.verify runs on the merged tree first; then the patch applies and your acceptance is recorded.Nothing, unless it follows an earlier invalid verdict (coherence.checked).
REFRESHΔ no longer applies, a relied-on fact changed, or a check failed on the merged tree.Nothing is applied, the source is unchanged, and the review stays pending. Redo the Work, or override an analysis-only REFRESH.coherence.invalidated is recorded and the agent continues. Only with mid_run: stop and stop_on_refresh: true is it stopped.
STOPΔ is already present in the source.Nothing is applied; the message names the run that landed it and points to dispatch reject.coherence.invalidated is recorded. With mid_run: stop the native run is stopped.
dispatch.yml · optional coherence block (defaults shown)
coherence:
  accept: validate        # strict: refuse on any drift (0.1.x behavior)
  mid_run: observe        # stop: cancel a native run on STOP
  stop_on_refresh: false
  poll_secs: 10
  integration_checks: true

What it checks, and what it does not

  • Symbol facts exist for Rust and Python only. Other languages use file-level facts: any change to a file the patch edits, or mentions by path, is REFRESH.
  • A referenced symbol is bound by unique name in the baseline, not full name resolution. Ambiguous or very common names are skipped, so some breakage is missed.
  • A Python function that only gains optional parameters keeps its callers valid. Any other signature change to a function the Work calls is REFRESH; Rust signatures compare exactly.
  • Integration checks run your checks.verify on the merged tree in a scratch copy with no build cache. They are skipped when none are configured, and for a run not approved for local execution.
  • Two edits to the same symbol are REFRESH. Transitive behavior changes, such as a callee’s callee, are caught only if your checks cover them.
  • Nested repositories and submodules are not analysed.
  • On Dispatch’s own fixture matrix — 36 scenarios, each on a Git and a plain-directory source — the coherence layer produces zero false CONTINUE and zero false REFRESH. Real-world rates are not yet measured.

Read the coherence reference for the model, events, and fixture matrix, and coherence validation for what is measured and what would show it to be wrong.

Visible first-run path

  1. 01Install Dispatch
  2. 02Start watching the project
  3. 03Attach an agent
  4. 04Watch its Work
  5. 05Accept or reject
  6. 06Stop watching

None of this needs an agent profile. Set one up only if you want Dispatch to launch the agent itself (step 09).

Step 01

Install the 0.4.11 preview.

Prebuilt archives are the preferred path for macOS Apple Silicon and Linux x86_64. The download page includes checksum verification and PATH setup. Interactive testing for this release was on macOS arm64; Linux is built and smoke-tested by CI but was not exercised interactively.

Install with Cargo
cargo install --git https://github.com/rundispatch/dispatch --tag v0.4.11 --locked
dispatch version

Source installation requires the current stable Rust toolchain and Git. For deeper CLI details, read the Core README.

Step 02

Watch the project.

dispatch start watches the project in the background and gives your shell back. While it runs, Dispatch keeps the verdict of every Work item it knows about current as the code moves: results waiting for review, attached Work still in progress, and attached Work it may apply. No agent needs to be set up for this.

Watching
dispatch start                # watch in the background; your shell returns
dispatch watch                # the live view; leaving it keeps watching
dispatch stop                 # stop watching this project

# Or watch in the foreground until you stop it:
dispatch serve
  • dispatch watch shows the project’s Work live. On a terminal it is a table (WORK, AGENT, STATE, VERDICT, CHECKS, TOUCHES), with Work named by its worktree folder or task and Work that needs you listed first; the selected Work’s details say why its verdict is what it is and what to do next. Below 90 columns each Work is a two-line card. Keys act on the selected Work, not a row number: f finishes, a accepts through the same gate as dispatch accept, r rejects after asking, d or Enter reviews. Piped or with --json, it prints one line per Work and only reports.
  • Leaving watch does not stop watching. dispatch stop ends watching for this project.
  • dispatch serve does the same watching in the foreground, until you stop it. check and status answer on demand either way.
  • Watching covers Work Dispatch launched, Work you attached, and sessions whose runtime reports them. It does not scan for agent processes. After a reboot, run dispatch start again.
  • Where Work interacts. While it watches, Dispatch compares the Work not yet integrated and says where two pieces already touch: the same declaration or file, overlapping lines, a signature one changes and the other uses, or a file one changes and the other relies on. On a terminal the TOUCHES column names the other Work; piped, a line ends with interacts with <id>. The selected Work’s details, and dispatch status under Concurrent, say how. Exact to the declaration for Rust and Python, to the file elsewhere. It is advisory: Work can be CONTINUE and still interact, and nothing is blocked, reordered or refreshed.
  • When Work lands, Dispatch records how its interactions turned out. The documented queries in coherence validation read precision and misses from your own state directory; nothing leaves your machine.
  • Running several agents on one repository, the way Dispatch builds its own releases, is set out step by step in the self-hosting guide.

Step 03

Attach the agent you already use.

Run dispatch attach -- <agent command> from your checkout. Dispatch makes the agent its own isolated workspace, so any agent CLI works, with or without worktree support of its own; you do not create a worktree first. It stays silent while the agent runs, then freezes Δ, runs your checks if you allowed them, and judges the Work when the agent exits.

Attach
# From your checkout: Dispatch makes an isolated workspace
dispatch attach -- claude -p "add input validation"

# Or observe an agent already working in a separate worktree
dispatch attach --workspace ../feature-wt --agent codex
dispatch finish <run-id>      # you say when it is done
  • dispatch attach --workspace <path> observes an agent already working in a separate workspace; dispatch finish freezes the result when you say it is done. Attaching the integration checkout itself this way is refused.
  • How much Dispatch can vouch for S0. Full confidence when S0 is the workspace as the Work began (a workspace Dispatch made, or a session start the runtime reported) or a real Git merge base. Partial confidence when Dispatch had to snapshot a directory at attach time, or a session resumed in a worktree it had not seen, since earlier edits are then invisible to the patch.
  • A workspace Dispatch made is removed once its Work is applied, and kept otherwise until you run dispatch clean.
  • If the project configures checks.verify, attach needs --allow-unsafe-local, because finishing runs those checks on your machine. mid_run: stop does not apply to attached Work.

Every flag and refusal is in the attach reference.

Step 04

Let Claude Code sessions register themselves.

dispatch setup → Runtime integrations installs Claude Code’s hooks, after showing exactly what it adds (a backup of your settings is kept, and Remove takes out only what was added). Then a Claude Code session in its own worktree of a watched project becomes Work by itself.

Claude Code
dispatch setup                # → Runtime integrations… → Install Claude Code hooks
dispatch start
claude --worktree             # a session in its own worktree becomes Work
  • S0 is the worktree as the session found it, before its first edit. Later sessions in the same worktree join the same Work.
  • When Claude Code removes the worktree, Dispatch first keeps its exact changes, then waits for you to finish or reject them.
  • If you let this project’s checks run by themselves (step 05), Dispatch runs them on the kept changes instead, and the Work waits for your review.
  • Discovered Work is never applied by itself.
  • A session working directly in your checkout is told that Dispatch cannot tell its edits from yours, and nothing is tracked.
  • No session in its own worktree is lost silently, even on a busy machine. It ends tracked (its Work exists before the hook returns), pending (its starting state is saved and the watcher finishes creating the Work moments later), or not tracked, and the session is told which. Work is never left half-created.
  • Codex has no equivalent lifecycle integration in this version. Attach it: dispatch attach -- codex.

Step 05

Approve a project check.

Dispatch offers known choices from an existing verify.sh, Cargo.toml, or Makefile, or you set checks.verify in dispatch.yml. The same screen can let Work in this project run those checks by themselves.

Guided
dispatch setup --checks
dispatch.yml
checks:
  verify:
    - cargo test

Common equivalents

Python
pytest
Node
npm test
Rust
cargo test
Go
go test ./...

That consent names the exact commands. When checks.verify changes, it no longer holds until you approve the new ones. It never lets anything apply.

Verification is mechanical evidence, not a code-quality judgment. A passing check is never a review. Without checks, Dispatch reports Verification: Not configured.

Step 06

Inspect and check the Work.

Without a run ID, these commands resolve the latest single-result Work for the current source tree. Execution, verification, review, and application are reported as separate facts. dispatch check is read-only and stores nothing; it runs the file, patch and symbol layers, so its CONTINUE is preliminary until the integration checks run at accept.

Inspect
dispatch status          # state of the latest Work for this source
dispatch diff            # the patch
dispatch diff --stat
dispatch check           # the verdict against the code now; read-only

Step 07

Accept or reject.

Human acceptance is the quality signal. Accept applies the patch through the safe apply path and then records your acceptance. If the source moved, the verdict gates the apply: a REFRESH or STOP leaves the source untouched, shows the application as blocked, and records no acceptance, so the Work stays pending until you redo or reject it.

Review
dispatch accept          # applies, then records your acceptance
dispatch reject          # records your decision; the source is untouched

# A REFRESH from the analysis alone, when you checked the Work still holds:
dispatch accept --despite-refresh --explanation "<why it still holds>"

Overriding a REFRESH

--despite-refresh applies a REFRESH whose every reason comes from the file and symbol analysis, when you have checked the Work still holds. It needs an explanation, and your checks must still run and pass on the merged tree; with no checks configured it is refused. It never overrides STOP, a patch that no longer applies, or a failing check. The overridden verdict is recorded with your explanation, and auto-apply never uses it.

Both commands also take repeatable --reason labels and an --explanation, stored verbatim on your machine.

Step 08

Redo stale Work.

For a run Dispatch launched, dispatch refresh starts a new run of the same task on the current source, with a fixed note naming the earlier run and up to ten reasons it went stale. The old run is untouched and the same explicit flags are required again. For attached Work, Dispatch cannot relaunch your agent: run it again on current code and attach the new Work. Nothing is redone automatically.

Redo on the current source
# A run Dispatch launched:
dispatch refresh

# Attached Work: run your agent again on current code and attach it
dispatch reject <run-id>
dispatch attach -- claude

The coherence: block configures the gate: set accept: strict to refuse on any drift, or mid_run: stop so a STOP observed while a native run works cancels it.

Step 09

Or let Dispatch run the agent.

dispatch run launches Claude Code or Codex CLI from a frozen snapshot in an independent candidate workspace, never your tree. This needs a profile: guided setup writes one to ~/.dispatch/resources.yml naming the exact model, effort and included funding you confirmed. No paid fallback is ever automatic, and there is no Dispatch account.

Guided setup
dispatch setup claude    # or: dispatch setup codex
dispatch resources       # cached configuration status, no model call

Claude Code

Uses its own login. The subscription evidence must be current, and assertions expire within 24 hours; revalidate with dispatch setup.

Codex CLI

Uses its own ChatGPT login. Before each launch Dispatch checks the account setup recorded: ChatGPT authentication, no paid credits, the standard tier and your plan.

Run a task
cd my-project
dispatch run "Fix the retry race in the worker"

# Or name the agent for this run:
dispatch run "Fix the retry race in the worker" --agent claude

Local execution is not a security sandbox. Agents and project checks run with your operating-system permissions, so start with a repository you can restore.

How the agent is chosen

Each run uses exactly one agent: the first eligible profile in resources.yml, narrowed by --agent and --model. With no profiles, --agent claude|codex|cursor runs that agent with its own login and no funding contract. With neither, dispatch run refuses. There is no ranking, benchmark data or automatic fallback. dispatch explain shows which agent and resource a run used; see provider support for what is and is not claimed.

Step 10

Apply eligible Work automatically.

Auto-apply is a policy you turn on for a session, a run or an attach. It applies only Work whose evidence is complete for the exact code it lands on: an unmoved source with passed verification, or a moved source whose merged tree passed your own checks. It never overrides a verdict and never records a human review, so review stays pending until you give one. Work a Claude Code session registered is never auto-applied.

Opt in
dispatch attach --auto-apply -- claude -p "add input validation"
dispatch run "Fix the retry race in the worker" --auto-apply

# In the interactive session: Shift+Tab, or /auto-apply on

Step 11

Clean up workspaces.

dispatch clean removes the workspaces Dispatch made for Work that is over (rejected, closed, or applied and not yet released). It lists them and asks before removing anything; without a terminal it needs --yes. Nothing is removed on a timer.

Cleanup
dispatch clean --dry-run     # list what would be removed
dispatch clean               # asks before removing

Step 12

Scripts and exit codes.

Non-interactive use cannot answer the local-execution confirmation, so it passes the acknowledgement explicitly. --json prints one versioned result object; --jsonl streams committed events followed by the result. dispatch watch --json streams the project’s Work as JSON Lines.

Non-interactive run
# Non-interactive use. The flag acknowledges that the agent runs
# with your OS permissions; local execution is not a security sandbox.
dispatch run "Fix the retry race in the worker" \
  --allow-unsafe-local --json
0
A result is ready for review and verification passed or was not configured
3
A result is ready for review, but configured verification failed
4
The goal is waiting on a human (a durable clarification)
124
The goal-wide deadline expired
1
Execution or orchestration failed, including a mid-run coherence stop
2
Command-line usage error

Current 0.4.11 boundaries.

Safety and data
  • Experimental developer preview, not a stable 1.0.
  • The background watcher (dispatch start) is one local process per project. It keeps verdicts current and applies only attached Work you allowed to integrate; it never launches, refreshes or discovers agents. After a reboot, run dispatch start again.
  • Work appears by itself only for Claude Code sessions in their own worktree of a watched project, with the hooks installed. Codex has no equivalent integration in this version; attach it.
  • Interactions between Work exist only while a project is watched, and are advisory. Their precision is measured by Dispatch’s own later verdicts, not by confirmed conflicts.
  • One agent per run. No automatic retry, task decomposition, agent racing or fallback to another agent.
  • mid_run: stop applies to native runs only. No real run has been stopped by the mid-run watcher yet.
  • Coherence evidence comes from the fixture matrix and a small number of runs. No token, time or cost saving is claimed.
  • Docker execution is advanced and experimental, with a user-supplied image.