Skip to content

Issue Dispatcher

Overview

The Issue Dispatcher determines which issues are eligible for work and organizes them into dispatch queues by agent type. It implements a priority-driven system that routes issues to workers (implementation), judges (review), planners (decomposition), and researchers (discovery), with intelligent filters to enforce business rules like dependency resolution and execution phases.

Two Dispatch Modes

The dispatcher operates in two modes that run independently each orchestrator tick:

Standard dispatch (execution pipeline) — handles issues moving through the backlog → todo → in_progress → review → done status flow.

Phase dispatch (readiness pipeline) — handles tickets in phase:research, phase:architecture, and phase:grooming, routing them to the appropriate phase agent.

Standard Dispatch Priority Order

Each candidate is tagged with a dispatch reason (review, implement, plan, research) and sorted by priority then timestamp.

Phase Dispatch Flow

Eligibility Rules by Agent Type

Workers

  • Status: todo
  • Phase: phase:ready or no phase label
  • All dependencies resolved (each dependency must have status done)
  • No agent currently running on the issue
  • Not flagged for planning (when planner is enabled)

Judges

  • Status: review
  • No agent currently running on the issue
  • Judge retry count below maximum
  • Last judge attempt more than 5 minutes ago (per-issue cooldown)

Planners

  • Status: todo
  • Labels: needs-planning OR size = large
  • No phase labels present
  • No agent currently running on the issue

Researchers (background scanner)

  • Idle conditions met: backlog has fewer than 10 items, no todo items are waiting, and the scan interval has passed
  • Only one research dispatch per cycle
  • Scoped per-project

Phase Agents

  • Exactly one phase label present matching the agent type
  • Status not in: done, cancelled, in_progress, blocked, review
  • No agent currently running on the ticket
  • No pending completion claim or verdict being processed

Cross-Project Fair Dispatch

When multiple projects are configured, the dispatcher uses a global priority queue to prevent project starvation. Instead of processing projects sequentially (which would let the first project consume all available slots), all dispatchable candidates from all projects are collected into a single list and sorted by:

  1. Dispatch type: Judges → Phase agents → Workers → Research
  2. Issue priority: Lower priority value = higher importance (Priority 1 before Priority 3)
  3. Cross-project interleaving: Within the same dispatch type and priority level, candidates from different projects are interleaved in round-robin fashion

This ensures:

  • High-priority issues from any project dispatch before low-priority issues from any other project
  • No single project can starve others when priorities are equal — slots are distributed fairly
  • Per-project concurrency limits are still enforced per-candidate during iteration
  • Worker slot reservation still prevents phase agent starvation of workers

Example

ProjectIssuesPriority
A20 todo2
B2 todo2

With max_concurrent_agents: 10, the dispatch order interleaves: A, B, A, B, A, A, A, A, A, A — both projects get slots proportional to their backlog while respecting the global limit.

Key Behaviors

Phase Labels Gate Worker Dispatch

Workers only see phase:ready or unlabeled issues. Issues with phase:research, phase:architecture, or phase:grooming labels are exclusively handled by phase agents and are invisible to worker dispatch. This ensures design and planning work completes before implementation begins.

Judge Cooldown

Judge attempts on the same issue are separated by a 5-minute cooldown. This prevents retry storms when a judge repeatedly fails on the same ticket and gives time for human intervention if needed. Cooldown is per-issue — other issues can be reviewed immediately.

Dependency Blocking

An issue cannot be dispatched to a worker until all its declared dependencies have status done. If a dependency is stuck (e.g., blocked indefinitely), the dependent issue will remain undispatched until a human resolves the dependency.

Planning Items Excluded from Worker Queue

When the planner is enabled, issues with needs-planning or large size are excluded from worker dispatch. They are only picked up once the planner has decomposed them. If the planner is disabled, workers handle these items directly.

Pending Verdict Blocks Phase Re-dispatch

Phase tickets are skipped if there is an unprocessed completion claim or verdict pending. This prevents a race condition where an agent is re-dispatched before the orchestrator has finished recording the previous verdict.

Research Only Runs When Idle

Background research (codebase scanning) dispatches only when the project is in an idle state: fewer than 10 backlog items, no todo items waiting, and the scan interval has passed. Research never competes with active work for concurrency slots.

Query Efficiency

All eligibility checks use batched queries to avoid N+1 database reads:

  1. One query for all issues matching base criteria (status, labels)
  2. One query for all dependencies of the candidate set
  3. One query for all dependency issue statuses
  4. Filtering and sorting in memory

getDispatchableIssues() makes 3 queries total regardless of candidate count.