Posts

The Dispatch Layer

7 min read essay, research
Contents
  1. The architecture
  2. Classification
  3. Eligibility
  4. Two paths to cookie
  5. What the moderator actually checks
  6. When the moderator fails
  7. Priority
  8. What this means

Issue #18980 resolved in 71 minutes. Issue #19017 — filed just under three hours later, by the same person, with error output, file paths, fix language, and line numbers — took 7.76 days. Both land as uncategorized under the analysis heuristic. The core diagnostic signals overlap. The resolution time differs by 157x.

The extracted signals do not account for that gap on their own.

In The Agent Interface, I measured what contributors write into an agentic system. That essay treated the system as a black box — inputs on one side, outcomes on the other. This essay opens the system itself.

gh-aw’s routing architecture is open source. The workflow files that classify, gate, and dispatch issues are markdown files in .github/workflows/. What follows traces the path from issue arrival to agent implementation using those files directly.

The architecture

In The Agent Interface, I named three routing layers: classification determines what kind of work the system thinks it is looking at; eligibility determines whether the work enters the automated pipeline at all; priority determines the order once it is inside.

Those layers are not an abstraction. They are three separate workflow files.

Routing architecture issue arrival → dispatch
Bot-generated
Issue created by workflow ci-doctor, daily-cli-performance, etc.
Classification Labels baked in at creation
cookie label Auto-applied via safe-outputs config
Priority scoring Issue Monster scores and assigns
Copilot implements Every 30 minutes, up to 3 per run
Community
Issue filed by contributor Triggers AI Moderator
AI Moderator Spam / AI-generated / link-spam check Can crash silently
ai-inspected Applied only if moderator passes No auto-promotion
cookie label Requires maintainer manual action pelikhan in all sampled cases
Copilot implements Same queue, same scoring
Two paths through the same dispatch infrastructure. Bot-generated issues enter the priority queue automatically. Community issues require a maintainer to manually add the cookie label.

The left lane runs without human intervention. The right lane requires a human at the eligibility gate. The scoring and implementation layers are shared — once an issue has the cookie label, the same Issue Monster workflow processes it regardless of origin. The divergence is in how issues reach that queue.

Classification

The first layer is issue-triage-agent.md. It runs on a schedule — weekdays at 2 PM UTC — and scans for unlabeled issues.

issue-triage-agent.md workflow prompt

List open issues in the repository that have no labels. For each unlabeled issue, analyze the title and body, then add one of the allowed labels: bug, feature, enhancement, documentation, question, help-wanted, or good-first-issue, community.

The triage agent reads the title and body, assigns a label from a fixed set, and reports a confidence level — High, Medium, or Low. It is conservative. What it cannot confidently classify stays unlabeled.

In The Agent Interface, 77.2% of community issues carried no category label. The triage agent’s conservatism is one mechanism behind that rate — it runs on a schedule, not on issue creation, and its label vocabulary is fixed. An issue filed at 4 AM on a Saturday will not be classified until Monday afternoon.

But classification is not the bottleneck. An issue can carry a bug label and still sit for days. What matters is the next layer.

Eligibility

Every 30 minutes, a workflow called Issue Monster wakes up and searches for work. It is described in its own prompt as “the Cookie Monster of issues.” The search query is specific:

issue-monster.md workflow prompt

is:issue is:open label:cookie

The “cookie” label indicates issues that are approved work queue items from automated workflows.

Line 128. This is the eligibility gate. Without the cookie label, an issue is invisible to the dispatch system.

The cookie label is a boolean gate. Either an issue has it and enters the dispatch queue, or it does not and the system cannot see it.

Bot-generated issues are born with it. When internal workflows create issues — ci-doctor diagnosing a CI failure, daily-cli-performance flagging a regression, daily-function-namer identifying a naming inconsistency — the cookie label is baked into their safe-outputs configuration. At least 27 workflow definitions include it. These issues enter the dispatch queue the moment they are created.

Community issues require manual promotion. The system has an AI Moderator (ai-moderator.md) that fires on every new issue from external contributors. Maintainers and bots are exempt:

ai-moderator.md workflow prompt

skip-roles: [admin, maintainer, write, triage]

skip-bots: [github-actions, copilot]

Lines 14-15. The moderation gate only applies to external contributors.

If the issue passes moderation — no spam, no link-spam, no AI-generated content detected — it receives the ai-inspected label. A separate policy in q.md states:

q.md workflow prompt

Do not add the cookie label to an issue unless the ai-inspected label is already present. The cookie label indicates approved work-queue items and must not be applied before moderation review.

Line 296. The cookie label guard.

But that policy describes a path that does not appear to exist in practice. The q.md workflow’s own safe-outputs configuration only allows adding the spam label — it cannot apply cookie. No other workflow in the current source grants an add-labels path for cookie on community issues.

In the five community issues that carried the cookie label as of March 24, 2026 — #21978, #22364, #22380, #22409, #22469 — all five were manually promoted by the same maintainer. The timestamps show community added first, then cookie seconds to minutes later, by pelikhan. Zero community issues in the sampled data carry all three of community, ai-inspected, and cookie.

The eligibility gate for community issues is a manual human decision.

What the moderator actually checks

The AI Moderator’s heuristics for detecting AI-generated content include:

ai-moderator.md workflow prompt
  • Use of em-dashes (—) in casual contexts
  • Perfect grammar and punctuation in informal settings
  • Constructions like “it’s not X - it’s Y” or “X isn’t just Y - it’s Z”
  • Overly formal paragraph responses to casual questions
  • Perfectly structured responses that lack natural conversational flow
Lines 101-109. The AI-generated detection heuristics.

These are the qualities that produce high-signal issue reports. Em-dashes, precise grammar, structured argumentation — the same writing patterns that, in The Agent Interface, correlated with faster resolution in bugs and enhancements.

The system’s quality detector is tuned to be suspicious of exactly the kind of writing that resolves fastest.

When the moderator fails

The moderator does not need to flag an issue as suspicious. It just needs to fail. Three AI Moderator runs triggered by community issues on March 8, 2026 — run 22815242957, run 22815244574, run 22815873142 — all crashed at the Execute Codex step.

No safe-output tool was called. No ai-inspected label was applied. The cookie label guard stayed closed. Issue Monster never saw the issues.

06:03 Moderator crashes All three runs fail at Execute Codex
6 hrs Dead time Issues sit invisible to dispatch
12:20 Manual rescue pelikhan assigns Copilot by hand

The issues were resolved the same day — but entirely through manual intervention. pelikhan found them, assigned Copilot and himself, directed the implementation in comments, and closed them by 15:21 UTC. The automated dispatch system was completely out of the loop.

The system fails closed on moderation errors. A crashed moderator has the same downstream effect as a positive spam detection: the issue never gets ai-inspected, so the eligibility gate stays closed. The contributor receives no notification, no error message, no indication that their issue is sitting in a dead zone. It just waits.

Issue #18992 — an enhancement carrying error output, code blocks, file paths, proposed code, fix language, reproduction steps, and line numbers — was still open 22 days later, as of March 23, 2026.

Priority

Once past the eligibility gate, issues enter a scoring system. Issue Monster reads the label set and assigns points:

Dispatch priority points added to queue score
Good first issue
+50
Security
+45
Bug
+40
Documentation
+35
Enhancement
+30
Performance
+25
Tech debt
+20
Points from issue-monster.md lines 291-311. Issues with any priority label receive an additional +10. An age bonus (days old / 10, capped at 20) gives older issues slight preference.

The scoring is explicit and deterministic. A labeled bug with cookie will be picked up before an enhancement with cookie. An issue older than 200 days gets the maximum age bonus of +20 — but that still ranks it below a freshly created good-first-issue.

Issue Monster selects up to three issues per run, with a topic-separation requirement: the selected issues must touch different areas of the codebase to avoid conflicting changes. It assigns each to the Copilot coding agent, which creates a pull request.

This layer is well-designed. The scoring is transparent, the selection logic accounts for conflicts, and the throughput is steady — up to three issues every 30 minutes. The bottleneck is not here. The bottleneck is whether community issues reach this queue at all.

What this means

The 157x gap between issue #18980 and issue #19017 is consistent with a system where eligibility — not signal quality, not classification, not priority scoring — is the primary bottleneck for community contributions. Both issues carried diagnostic evidence. Both landed in the same heuristic category. The difference is in how the system routed them.

This is the mechanism behind the label-selection effect measured in The Agent Interface: labeled enhancements closing 3x to 110x slower than change-shaped unlabeled issues. The labels are not neutral markers. They are artifacts of a routing architecture that was designed for a world where 86.5% of issues are bot-generated — and the routing reflects that assumption.

Bot-generated issues enter the dispatch queue automatically. Community issues enter when a single maintainer decides they should. The moderation layer that gates that decision can crash silently, can flag polished writing as suspicious, and has no fallback path. The contributor never knows.

The workflow files are open source. The data and methodology from The Agent Interface are open source. What the dispatch layer looks like from the inside is now visible.

The question is what a better one looks like. That is the next essay.