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
| Idea | agent-board | Why |
|---|---|---|
| Deterministic filtering and gating before any model | Has | reconcile(snapshot, policy, now) is pure and the model decides only judgment questions (design L110, L128). |
| Hold, blocked and needs-human exclusions | Has, stricter | Execution 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 admission | Adopt | See below. |
| Deterministic "clarify" for an unfilled issue | Adopt | See below. |
| Keyword tiers choosing the model | Has the idea, as cost routing only | toilFixPool 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 modes | Do not adopt | Work 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 healthy | Do not adopt | Events 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 reads | Adopt | See below. |
| Skip a failed repository, treat an unreadable blocker list as unblocked | Do not adopt | agent-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 relay | Has | The poll merges only the approved green head it read, with expectedHeadOid (L240–245). |
| Writes through a trusted relay, not the agent | Has, stricter | Hive 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 token | Do not adopt | The job/token separation already gives the sandbox at most a read-only token, so there is no write to tier. |
| Repository-restricted executor tokens | Adopt | See below. |
| Bounded fix attempts | Has | Two fix rounds a pull request in the poll (L466); Hive's breaker escalates after three (config.go L8104–8115, L8934). |
| Rolling token budget | Has, stricter | agent-board reserves the allowance before launch and holds admission on missing usage (L126); Hive checks spend between kicks. |
Recommended for adoption
- 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).
- 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
Triagedoes. 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. - 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.
- 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
ScopedTokenForReposdoes. 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).