Skip to content
This text was generated by an LLM (how cgwalters uses LLMs). cgwalters has not reviewed it yet. It was written from reading source and documentation; nothing in it was run.

Hive's deterministic pipeline and the coordinator

Hive filters, classifies and gates GitHub work in Go and shell before any model sees it (architecture.md L9–12). This page compares that pipeline with the coordinator in agent-board's design and says, for each idea, whether agent-board already has it, should adopt it, or should not (agentic-job#2). Hive is read at commit 0680bb5 and agent-board at 7311f92, both of 2026-10-16. Line numbers are of those commits.

What each stage decides

Enumerate and filter. Each governor pass lists the open issues and pull requests of the active (not paused) repositories (client.go L1188–1211). An issue is dropped, in this order, if it is a standing report or dependency dashboard, carries a hold label, an exempt label, a needs-reporter-confirmation label or a hard-suppress label such as needs-human (L1339–1392). With reporter trust on, a human author whose login or author_association is not trusted needs a maintainer's label before the issue counts (L1405–1419, issue_filter.go L139–151); then an optional require_labels allow-list applies (L1421–1425). Drafts and held pull requests are kept out the same way (L1552–1652). The inputs are labels, author login and association, title and repository; the body is kept for the next stage. If every repository fails to list, the pass errors so the queue is not read as empty (L1245–1250); one failing repository is skipped with only a logged warning and its work drops out of the count (L1216–1235), and an unreadable "blocked by" list is treated as unblocked (L1439–1451).

Classify. Classify gives each issue a lane, a tier and a model recommendation (classifier.go L144–171). The lane is the first match of a [lane] title prefix, a label naming a lane, then lane keywords in the title or labels (L249–277); an agent is offered only issues of its own lane or none (repofilter.go L192–200). The tier is Simple, Medium or Complex from title keywords such as "typo" or "race condition" and from kind/security or kind/regression labels, and it maps to haiku, sonnet or opus (L279–314). Triage then picks fix, spec or clarify: override labels first, clarify for a short body, an unchosen option list or an unfilled template placeholder, spec for Complex issues or spec labels, otherwise fix (triage.go L26–57). Most inputs here (title, body) are written by the issue's author.

Gate. classifyMergeEligibility puts each pull request in one of merge-eligible, CI-failing, conflict or skipped, with a reason (merge_eligibility.go L357–514): drafts, hold labels and an intent-verification refusal keep it out, conflicts are skipped, failing required checks send it to its author for repair, and, when configured, an aggregate review approval of the current head is required. The merge relay re-reads that list on every request, refuses a request without an expected head SHA or not on the list at that SHA, and fails closed if the list is unreadable (L231–300); direct merges and pull request creation by an agent are refused at the proxy and go through the relay instead (rules.go L195–227).

How it paces work

The governor runs every eval_interval_s, 300 seconds by default (config.go L6449). Queue depth (actionable issues plus open pull requests, held items excluded; governor.go L407–412) picks a mode, idle, quiet, busy or surge, by the first threshold exceeded (L510–528). The default thresholds (2, 10, 20) are per repository and, with the default linear scaling, multiplied by the number watched; a threshold set by hand is used as it is (governor-thresholds.md). Each mode sets each agent's kick interval, time-of-day schedule or pause (agent-configuration.md L595–625); an agent is due once that interval has passed since its last kick (governor.go L973–993). While webhooks are healthy the pass stretches to 900 seconds, and when the GitHub rate limit falls below a reserve (800) or critical level (250) it stretches two or four times, capped at 1800 seconds, and sheds enrichment steps before the steps that unstick items (api_budget_decision.go L22–118, apibudget.go L90–125). A seven-day rolling budget of model tokens, counted from the agents' session logs, suppresses kicks once spent (architecture.md L140–143, L373–376); it is checked between kicks, not reserved before one.

How it scopes forge tokens

Each agent gets a GitHub App installation token for its trust tier: advisor and reviewer read contents and pull requests; newcomer reads contents and writes issues; contributor writes issues, contents and pull requests; trusted also reads checks and writes workflows (app.go L282–386). ScopedTokenForRepos can restrict a token to named repositories (L388–394), but the agent's session token is minted without that, for the whole installation (L268–270, L528–529). It is written to a file only that agent's user can read, or, if that file was not created in advance, the agent falls back to a shared token (L581–588). An opt-in, off by default, gives the agent a placeholder and has the proxy inject the real token instead (proxy_inject_flag.go L28–30). A proxy on the agent's egress maps method and path on api.github.com to the minimum mode a write needs and applies a repository allow-list, but by default tunnels github.com, git pushes included, without inspecting it (architecture.md L225–266, github_proxy.go L399–419). So from the newcomer tier up a Hive agent holds a write-capable, installation-wide token in its own session, and with the defaults a push is limited by that token alone.

Idea by idea

Ideaagent-boardWhy
Deterministic filtering and gating before any modelHasreconcile(snapshot, policy, now) is pure and the model decides only judgment questions (design L110, L128).
Hold, blocked and needs-human exclusionsHas, stricterExecution needs an authenticated admission authorization or permitted classification, whatever Status says (L126); Blocked, Needs human and Turn record why an item waits (L20–22).
Reporter trust before automatic admissionAdoptSee below.
Deterministic "clarify" for an unfilled issueAdoptSee below.
Keyword tiers choosing the modelHas the idea, as cost routing onlytoilFixPool classifies review findings, not issue text, to pick a cheaper pool under the same bounds (L298–306). Hive's tiers read author-written titles, and its own #5856 comment on lane keywords shows how fragile keyword matching is, so a keyword tier must never admit work.
Queue-depth cadence modesDo not adoptWork is bounded by slots and the run allowance (L126), not by how often agents are kicked; kicking more often under load would only spend faster. The poll's backoff while idle already covers the quiet end (L235–237).
Longer polling while webhooks are healthyDo not adoptEvents are wake hints and the ten-minute pass is the backstop (L112); a fixed backstop is simpler, and a scheduled pass is cheap.
Rate-limit reserve that sheds optional readsAdoptSee below.
Skip a failed repository, treat an unreadable blocker list as unblockedDo not adoptagent-board blocks actions that depend on missing facts and treats 404 as unknown (L112), which is safer than a queue that silently shrinks.
Head-pinned merge list re-read by the merge relayHasThe poll merges only the approved green head it read, with expectedHeadOid (L240–245).
Writes through a trusted relay, not the agentHas, stricterHive relays merges and pull request creation but agents keep tier tokens; agent-board and agentic-job give the model no write credential (L60).
Tiered permissions in the agent's tokenDo not adoptThe job/token separation already gives the sandbox at most a read-only token, so there is no write to tier.
Repository-restricted executor tokensAdoptSee below.
Bounded fix attemptsHasTwo fix rounds a pull request in the poll (L466); Hive's breaker escalates after three (config.go L8104–8115, L8934).
Rolling token budgetHas, stricteragent-board reserves the allowance before launch and holds admission on missing usage (L126); Hive checks spend between kicks.
  1. Reporter trust before automatic admission. Decision D allows "policy-approved low-risk automatic admission" later (L454). That classification must not be satisfiable by text alone: require that the issue's author is trusted (role, as agentic-job's event admission reads it) or that a maintainer has labelled it, as Hive's reporter trust does. The threat: an outside author writes an issue that classifies as low risk and gets an inference-funded run and a pull request proposal without a maintainer reading it. Unlike Hive, which re-reads the labels each pass so a label survives later edits of the body, bind the admission to the revision the label or role applied to, as agentic-job refuses edits because "the text that was read is gone" (events.md).
  2. Deterministic "clarify" reason. A pure rule that holds an item out of automatic admission, with a reason code, when its body is short or still has a template placeholder or unchosen options, as Hive's Triage does. It saves a coordinator run on items no model can act on, and is a table test. It stops no attack; it is cost, not a control.
  3. Rate-limit reserve. When the remaining API quota is under a reserve, skip enrichment and census reads first and keep the reads that block irreversible actions, recording what was skipped on the control issue, as Hive tiers its steps. agent-board already says to honor rate limits and expose stale coverage (L112); this makes the order explicit so a long census cannot starve the pass that repairs drift. It is ordering for availability, not a security control.
  4. Repository-restricted executor tokens. When an executor mints a GitHub App installation token, request only its operation's permissions and only the target repository, as ScopedTokenForRepos does. The threat: a bug or a compromised handler in one executor writing to another repository of the same installation, as a Hive agent's own token could. This is the concrete form of "each executor has only its operation's credential" (L102).