dispatch is your engineering control tower. It watches a GitHub Issues queue,
picks up one ready job at a time, runs it through a workflow engine across a
spec → work → build cycle, opens a pull request, and either arms it for merge or
escalates back to you — all unattended, a few times a day. You write the issues
and approve the results; dispatch coordinates the work in between.
It does three things and nothing more:
- Intake — fetch and classify queued issues, claim one.
- Issue the job — the Architect phase composes a structured work order; the work phase implements it in an isolated worktree.
- Approve or escalate — on success, arm auto-merge (awaiting your approval); on failure, advance the fix ladder; on ambiguity, comment and escalate.
📖 Full guide: the dispatch wiki. Start with Getting started and Strengths and limitations.
Underneath the GitHub control tower, dispatch is a small, focused orchestration tool over a workflow engine. It gives you a declarative, programmable surface for the hard parts of putting LLM agents to work on real engineering: organizing user requests, marshalling resources, coordinating agents, handling communication, and recovering from failure. It sits one abstraction level above raw model/agent libraries (Transformers, OpenRouter): you express what the workflow is, and the engine runs it — deterministically validated, observable, and recoverable.
Its competencies are deliberately narrow:
- Task decomposition — break a request into independently shippable units.
- Slice-based work processing — fan work out across per-unit slices.
- Admin validation — verify process and outcome (CI, review, acceptance).
- Arbitrary inputs and outputs — GitHub issues are one input adapter, not the core. The engine consumes generic work items and emits generic deliverables; the GitHub queue above is the first such adapter.
The aim is to let everyday consumer programs benefit from AI through both classical and AI-engineering principles — engineering loops, process verification, agent communication, lifecycle management — so a complicated request can be solved by a swarm of small agents working in parallel without the end user ever needing to know they ran.
dispatch keeps a clear boundary between three layers; consumer code never reaches past its own:
- Foundation tooling (
foundation/) — primitives: agents, backends, models, shelves, process/filesystem facades. The vocabulary. - Workflow-engine subsystems (
foundation/workflow/,baseworkflow/subsystems) — the HFSM/statechart engine: controllers, actions, manifests, validation, the declarative composition surface. The grammar. - Consumer app code (
app/) — concrete workflows (app/workflows/*.yml), config, the./dispatchentry point, and the/dispatchskills. The programs.
For now, YAML + Python is expressive enough to convey function composition and implementation complexity; the abstraction boundary is what keeps the engine flexible enough to take on new workflow problems.
./debug-viewer draws every workflow as a live statechart and lights up each
state as a tick executes it (mock engine, no network). It makes the three-layer
model — and superseedable states — concrete.
Above is the shared seed phase (shown on websitewf, which inherits it from
baseworkflow). The workflow references the seed.intake controller (cyan);
the three dashed supersede targets — seed.handle.github / .interactive /
.job — are variations of the seed controller entered dynamically. On a run,
seed:route classifies the request and supersedes its own processing with the
matching variant. The live-session log captures the preemption as it happens:
0.61s → 2.seed:route
0.91s · supersede.accepted
0.91s → 4.seed.handle.job
1.22s → 0.seed:accept_job
1.52s → 1.seed:emit_work_item
1.82s · supersede.completed
The variant takes over (policy abandon), the generic seed:fallback is skipped,
and every intake source converges on one source-agnostic work_item before the
lifecycle continues into spec → work → build. Because a supersede target's states
carry the same ids the engine mints at run time, the dashed subgraph highlights
live the moment a run routes into it — no special-casing. See
docs/adr/003-controller-needs-supersede.md.
The guiding principle: 1.x is refinement and discipline; 2.0 is expansion. 1.x hardens the existing single-host pipeline — clean layering, decoupling, and serialization/tool/shelf hygiene — before 2.0 builds outward with new backends, multi-host scaling, and new surfaces.
- 1.x — refinement & discipline. Superseedable HFSM states (a more pressing state can preempt the active one) and per-workflow event responders (handlers for unexpected lifecycle conditions — e.g. no ready issues → exit; missing information → open a clarifying ticket), so dispatch behaves less like a straight-line program and more like an agent with reflexes. Plus the discipline work that keeps the layers clean: decoupling GitHub-issue intake from core, agent-runtime / tool-layer hardening, shelf observability and typing, a typed wire contract, TOON serialization for agent-bound data, proxy tools for context management, the live-parallelism fix, and containerized worker isolation on a single host.
- 2.0 — expansion. OpenRouter (tool-using) backends, declarative backend-bound agent profiles, and a CPU-pressure-aware fleet dispatcher that scales containerized workers across multiple hosts. Built outward on the refined 1.x layers.
- Exploratory (not committed) — a readable, debuggable scriptable workflow language expressing asynchronous communication, function composition, and parameterizable invocation. Direction, not scope.
dispatch is L3-class automation: it shines on small, clear, checkable units of
work and struggles with vague or sprawling ones. The standard, encouraged way to
drive it is the composable /dispatch Claude Code skill family, which
interviews you (AskUserQuestion) and shapes work toward what the pipeline does
well — before anything reaches the queue.
| Skill | What it does |
|---|---|
/dispatch |
Front door: takes any high-level ask, interviews until it is specified, then routes it. |
/dispatch:scope |
One rough idea → one well-formed issue (goal, acceptance criteria, scope, verification). |
/dispatch:decompose |
A large ask → small, shippable leaf issues filed as a Draft epic. |
/dispatch:tick |
Preview a tick in dry-run, then a deliberate go-live. |
/dispatch:review |
Vet a pipeline pull request against its acceptance criteria before you approve. |
/dispatch:oneshot |
Interview a task, then feed it straight into the engine — bypassing GitHub issue intake. |
The skills ship under .claude/skills/ and work automatically
when this repo is your Claude Code workspace. To use them in any project, run
the cross-platform installer (Windows · macOS · Linux):
python install_claude_skills.py # copy the skills into ~/.claude/skills/
python install_claude_skills.py --list # preview what would be installed
python install_claude_skills.py --force # overwrite an existing copyThen just say what you want — "have dispatch build a Vercel landing page" — and
/dispatch takes it from there. Full guide:
Interacting with dispatch.
git clone git@github.com:ReclaimByDesign/dispatch.git
cd dispatch
# 1. Secrets and config (gitignored). Set CLAUDE_CODE_OAUTH_TOKEN, PIPELINE_REPO, tokens.
cp .env.example .env
# 2. Verify the workflow engine.
python3 app/scripts/smoke.py
# 3. Dry-run a tick — prints what it would do, mutates nothing.
./dispatch -r owner/repo
# 4. When ready, provision labels and go live.
bash scripts/bootstrap-labels.sh # requires gh authed + a live run
./dispatch -r owner/repo --liveDry-run is the default; --live is the only switch that lets dispatch mutate
GitHub. Configure branch protection on main (CI + one human review) before going
live — auto-merge waits on it, and no token may merge directly. See
Configuration and
Unattended Linux server installation
(systemd) for the full setup.
dispatch earns its keep on work that is bounded and checkable:
- Backlog burndown — a queue of small, well-specified bugs and features, worked a few at a time on a schedule.
- Repetitive, well-patterned changes — a new route, a config key, a localized fix, scaffolding that resembles many prior examples.
- Decomposed projects — a larger build (a website, a service) broken via
/dispatch:decomposeinto leaf issues the pipeline takes one at a time. - Test-backed work — anything whose success a test or command can confirm, so mistakes are caught before they reach you.
dispatch is a capable but fallible L3 collaborator — treat it like one:
- Write small, clear, verifiable issues. Use the
issue templates (or
/dispatch:scope); every task needs a goal, acceptance criteria, scope, and a way to verify "done". - Decompose big asks. Hand the pipeline leaves, not epics — do the sprawling or novel thinking interactively with Claude first.
- Stay in the loop. Escalations arrive as GitHub comments and merges wait on your approval. It is scheduled, not fire-and-forget.
- Review before you merge. Every pull request is a draft to read — use
/dispatch:review. Merging is never delegated. - Label by priority. Carry one status rung —
Unscheduled▸Draft▸Candidate▸Release— plus theBlockeroverlay to jump the queue; dispatch works the highest-priority ready issue first.
The wiki is the complete reference:
- Getting started
- Interacting with dispatch (Claude skills)
- Configuration
- Strengths and limitations
- Development and contribution
- Architectural patterns · Understanding HFSMs and statecharts
- Creating your own workflow
- Unattended Linux server installation
In-repo references: CLAUDE.md (worker contract) ·
docs/adr/ (architecture decisions) ·
schemas/ (Job Request / Invoice).

