Synced from Hive. This page is pulled from hivecommons/hive@v5 during the docs build. Edit the canonical source in the Hive repository.

Hive Labels and Control Signals

This is the operator view of Hive labels: if you add or remove a label, this is what the v5 code does. It also calls out non-label controls that look like labels from the dashboard.

How labels reach agents

Most hard gates run before an agent sees work. GitHub issue enumeration reads labels in this order: standing meta issues are excluded first, then hold labels move the item to the Hold list, then exempt labels and the issue-level hard-suppress labels (needs-human, needs-direction, needs-decision, needs-spec; hardSuppressIssueLabels in src/pkg/github/labels.go) filter it out, so no agent kick names, and no kick claims, a parked issue, then project.issue_filter.require_labels admits or rejects the issue, and only then is it actionable (src/pkg/github/client.go:955-1045). Pull requests use the same hold-first enumeration for the PR Hold list (src/pkg/github/client.go:1110-1165). That means kick prompts, dashboard actionable counts, planning-from-label, and contributor offers normally inherit the same gate.

Some sweeps bypass that enumeration and list items themselves, but every one of them gates on the same hold predicate as enumeration (Client.IsHeldLabels / Client.isHeld, src/pkg/github/client.go:1964-1972, src/pkg/github/client.go:2674-2676), so the generic hold substrings and the exact dashboard hive-pause/<hive-id> label hold everywhere:

  • Auto-merge sweeps reach it through the Transport.IsHeldLabels seam; the queued (lgtm) sweep skips a held PR before fetching it, and the self-authored sweep skips held PRs plus needs-human before merging (src/pkg/github/automerge/automerge_sweep.go:23-38, src/pkg/github/automerge/automerge_sweep.go:959-964, src/pkg/github/automerge/automerge_sweep.go:966-1004, src/pkg/github/automerge/automerge_sweep.go:1029-1046).
  • The task-list sweep skips a held issue before its exempt / issue needs-human gate, so a held issue is never commented on, relabelled, or closed by it (src/pkg/github/task_list_sweep.go:848-854).
  • The SHA-hold sweep lists primary-repo kind/bug issues itself, adds literal hold plus a marker notice when no SHA is present (for reporters in issue_filter.reporter_trust trusted associations it adds the soft issues.sha_hold_trusted_label, default needs-sha, instead, #12002), and removes hold only when the current hold is its own: the newest hold label event is a labeled by the App bot and an App-authored SHA-hold notice was posted at or after it (EnforceSHAHold / shaHoldIsOwn in src/pkg/github/client.go).
  • PR-request watching applies server-side PR holds after a PR is opened; the agent’s --label hold flag is deliberately discarded by the wrapper (src/pkg/github/pr_request_watcher.go:452-524, bin/hive-open-pr.sh:142-150).

The “respect hold labels” text in policy templates names the enforced set (hold, on-hold, hold/review, hive-pause/<hive-id>, any label containing hold, plus do-not-merge as exempt) but is a prompt-level backstop. The hard gate is the enumerator or sweep named in the table.

Label axes

Hive-authored labels answer different questions. Read them as independent axes, not as one taxonomy: an issue can carry one label from each axis at the same time, and swapping a label on one axis never changes what the others mean.

AxisShapeQuestion it answersSignal?Notes
Stagestage/<step>Where is this item in the pipeline?Control (read by claims/auto-merge)Being added by a parallel change together with author/*; see that PR and the reference table once it lands.
Agentagent/<lane>Which agent works it (filed/owning lane)?Routing + ownershipThe suffix is always the lane name from HIVE_AGENT. The classifier routes on it and PR ownership compares against it, so agent/reviewer would hand the item to a reviewer lane — never use it to say “a review produced this”.
Originorigin/<source>Where did this item come from?Provenance only, never a gateOne neutral colour (#8250df) for the whole family. origin/review is a review-swarm backlog finding (src/pkg/github/origin_labels.go, src/pkg/config/review_severity.go). It replaces the retired from-review; the startup reconciler (Client.MigrateOriginLabels) swaps the old name for the new one on open items once, and review.backlog.labels still accepts from-review and maps it to origin/review without double-labelling.
Authorauthor/<tier>What trust tier did the author have?Control (auto-merge)Parallel change, alongside stage/*.
Modifiersblocked, hold, needs-*, hive-pause/<hive-id>What is stopping it right now?Hold / suppressSee the reference table; these are the hard gates.

Some hive-authored labels look like provenance but are read as signals, so they stay outside origin/* on purpose: hive/selfreport is the dedupe key the self-report joiner searches (label:hive/selfreport in src/pkg/github/fleet_report.go) and the hub relay re-applies it; hive/advisory makes an issue a standing meta issue that enumeration excludes (src/pkg/github/standing_issues.go); hive/<hive-id> is the legacy hold/provenance label the hold migration still consults. hive/sentinel, hive/fleet and fleet are only consulted by the good-first-issue exclusion list (src/pkg/gfi/gfi.go) and are no longer written by this code base.

Categories

  • Informational / display-only changes how Hive explains an item, not whether agents can act.
  • Workflow / status marks a process state such as reviewer outcome or rebase need.
  • Gate / permit admits, blocks, or releases a specific workflow.
  • Hold / suppress removes work from agent/contributor/merge lanes until cleared.
  • Contributor eligibility / routing affects /contribute offers or agent lane choice.
  • Human approval / acknowledgement records that a human accepted a direction or design.

Reference table

Label or signalApplies toConsumerEffectGate or signalWho appliesWhen checkedCleared / overriddenConfig knobs
hold, on-hold, hold/reviewIssues, PRsGitHub enumeration, auto-merge sweeps, task-list sweepAny label containing a configured hold substring is held; held issues/PRs leave agent kicks, PR merge lanes, and the task-list sweep. Held red PRs still route back to their owning agent for CI repair, with instructions not to remove the hold.Hard holdHuman, Hive level gate, #5117 gate, holdguard, SHA-holdEnumeration and sweepsRemove the matching label; Hive releases only literal hold it applied itself (level gate, #5117, SHA-hold)Built-in HoldLabels; dashboard exact hold via Client.SetHoldLabels (src/pkg/github/client.go:750-755, src/pkg/github/client.go:1894-1972, src/pkg/scheduler/policy_overlays.go:210-220)
hive-pause/<hive-id>Issues, PRsGitHub enumeration, dashboard hold toggle, auto-merge sweeps, task-list sweepExact, hive-scoped dashboard hold. It is not provenance and intentionally avoids the substring hold.Hard holdDashboard operatorEnumeration and sweepsDashboard Release removes labels causing the hold, including this oneCanonicalized from hive id (src/pkg/github/client.go:1898-1932, src/pkg/github/client.go:1936-1945, src/docs/dashboard.md:80-96)
GitHub “blocked by” dependencyIssuesGitHub enumeration, kick-list assemblyAn open issue whose GitHub dependency list names an open blocker is enumerated with DependsOn edges and kept out of the ACTIONABLE ISSUES an agent picks from; the kick names it once in a Blocked by open dependencies footer with its blockers. A blocker that is closed resolves the edge; a mutual pair (A↔B) is dropped with a warning so neither hides the other. The blocker list failing to load fails open (issue offered).Soft holdHuman (GitHub UI) or agent via hive-open-issue --blocked-by when splitting ordered childrenEnumerationClose the blocker, or remove the dependency on GitHubNone (src/pkg/github/issue_dependencies.go, src/pkg/scheduler/kickmessage.go partitionBlockedIssues/formatBlockedIssuesNote)
hive/<hive-id>IssuesProvenance/migration fallback onlyMarks hive provenance. It is no longer a hold label except a temporary failed-migration fallback during upgrade.InformationalHiveDisplay/migrationRemove if unwanted; do not use as a holdHive id (src/pkg/github/client.go:1947-1953)
hold from ACMM level gatePRsPR-request watcher, self-authored auto-merge releaseAgent PRs at L3-L5 get literal hold; outreach PRs whose target repo is not one the hive manages (cross-repo outreach) are held at every level, while same-repo outreach PRs follow the level. The watcher, not the policy prompt, applies it from the PR’s target repo (config.AgentOwnsRepo).Hard merge gateHive AppPR creation, later self-authored auto-merge releaseAuto-release only when current policy no longer requires the level hold, latest hold event was by the App, and the release path runs; otherwise a human removes itHive-wide ACMM and agent (src/pkg/github/pr_request_watcher.go:452-524, src/pkg/github/pr_level_hold.go:16-124)
hold from #5117 self-authorizationPRsPR-request watcher and self-authorization releaseA PR whose only rationale is unacknowledged hive-filed issues gets literal hold. Acknowledging the issue later does not remove an existing PR hold by itself. At ACMM L6 Fully Autonomous, the unset default is off; lower levels default on.Hard merge gateHive AppPR creation; evaluated only when no level hold appliesAcknowledge the issue and remove the PR hold; disabled policy release can remove Hive’s own hold. At L6, that release path also clears existing Hive-applied #5117 holds when no explicit config keeps the policy on.github.self_authorization_hold, per-repo project.repo_policies[].self_authorization_hold, HIVE_SELF_AUTHORIZATION_HOLD (src/pkg/github/pr_self_authorization.go:14-226, src/pkg/github/pr_request_watcher.go:452-524)
triage/accepted (or project.issue_filter.reporter_trust.untrusted_require_labels); needs-triage while waitingHuman-filed issues from untrusted reportersGitHub enumerationWith reporter_trust.enabled: true, an issue whose reporter’s GitHub author_association is outside the trusted set (default OWNER, MEMBER, COLLABORATOR) and whose login is not in trusted_logins is not actionable until it carries one of these labels. On the first excluded scan, core github.Client.fetchIssues posts one marked explanation comment and applies needs-triage (or awaiting_label); later scans do not repeat the comment. This is a poller-side write, not an agent prompt, and is capped at 10 new notices per poll. When the triage label appears, the same poll loop removes needs-triage only if the marker records that Hive added it, then the issue enters the backlog. Trusted reporters’ issues pass untouched. Runs after holds/exempts and before require_labels, so the ordinary allow-list still applies afterwards. Hive- and bot-filed issues are not judged here (#5117 owns them). Counted as “needs triage” on the repo card, not as a generic filter refusal.Hard admission gate (off by default)Human; Hive App for the visibility comment/labelEnumerationAdd the label, trust the login or association under Settings → Labels → Reporter trust, or disable the gateproject.issue_filter.reporter_trust.{enabled,trusted_associations,trusted_logins,untrusted_require_labels,awaiting_label,comment} (src/pkg/config/reporter_trust.go, src/pkg/github/client.go fetchIssues)
hold from #9665 reporter trustPRsPR-request watcher, level-hold releaseA PR whose rationale (closing or referencing links, or the request’s declared issues) traces to an issue filed by an untrusted reporter gets literal hold at every ACMM level, including L6, plus needs-human (so it surfaces as waiting on a person, #10773) and a marked notice naming the untrusted reporter and stating the PR itself was authored by the hive. Any one untrusted citation holds. Evaluated even at hold-gated levels, because the notice is what stops promotion to L6 from releasing the label.Hard merge gateHive AppPR creation; re-checked by the level-hold release pathA human removes hold. Hive never auto-releases it: the release sweep sees the notice (or re-evaluates and re-posts it) and leaves the label. Holdguard re-holds on a new head SHA.github.reporter_trust_hold (nil follows reporter_trust.enabled), per-repo project.repo_policies[].reporter_trust_hold, HIVE_REPORTER_TRUST_HOLD (src/pkg/github/pr_reporter_trust.go, src/pkg/github/pr_level_hold.go)
project.repo_policies[].auto_merge: falsePRshive-merge relay, App self-authored auto-merge sweep, proxyBelow L6 this resolves off for every repo; at L6, PRs can still be opened, reviewed and held when the per-repo switch is off, but Hive refuses every merge path for that repo. Existing hold / hive-pause/<hive-id> labels stay put because the disabled repo is skipped before hold release or merge.Hard merge gateOperator/dashboardMerge relay request, self-merge sweep tick, proxy direct merge attemptDashboard repo-card switch or config edit sets auto_merge: true/removes the override at L6; enabling is rejected below L6project.repo_policies[].auto_merge (src/pkg/config/repo_policy.go, src/pkg/agent/manager_modes.go, src/pkg/github/automerge/automerge_sweep.go, src/pkg/proxy/rules.go)
hold from holdguardPRsHoldguard ledgerIf the head SHA changes while held, lifting the hold causes Hive to comment and re-apply literal hold; the next human removal is the fresh approval.Hard merge gateHiveGovernor holdguard passHuman removes the re-applied holdBuilt-in holdguard.ReHoldLabel (src/pkg/holdguard/holdguard.go:1-43)
hold from SHA-holdIssuesSHA-hold sweepHuman-filed primary-repo kind/bug without a 7-40 hex SHA gets hold and a notice carrying “; once a SHA appears in body/comments, Hive removes hold only if the current hold is its own (newest hold event labeled by the App bot, paired with an App-authored notice at or after it). A human’s hold, a re-hold, or another subsystem’s hold stays. Reporters whose author association is trusted (issue_filter.reporter_trust.trusted_associations, default OWNER/MEMBER/COLLABORATOR) get the soft needs-sha row below instead, and a SHA-hold hold already on such an issue is swapped for it (#12002). The hard-suppress reconcile also lifts this hold once a PR referencing the issue merges after it was applied.Hard issue holdHiveEval tick SHA sweep; hard-suppress reconcileAdd SHA evidence or merge the fix; sweep removes its own hold, a human removes any otherPrimary repo and SHA-hold config (src/pkg/github/client.go EnforceSHAHold, src/pkg/github/hard_suppress_reconcile.go)
needs-sha from SHA-holdIssuesSHA-hold sweepTrusted-reporter kind/bug without a SHA gets this soft label plus the same “ notice instead of hold; the issue stays actionable. The sweep removes it once a SHA appears.Soft (informational)HiveEval tick SHA sweepAdd SHA evidence, or remove the labelissues.sha_hold_trusted_label (default needs-sha; hold restores the hard hold for everyone)
do-not-merge and do-not-merge*Issues, PRsExempt filter, merge sweeps, task-list sweepPermanently exempt; exact match is case-insensitive but prefix matching follows Go strings.HasPrefix on the original label.Hard suppressHumanEnumeration/sweepsHuman removesBuilt-in PermanentExemptLabels (src/pkg/github/client.go:750-755, src/pkg/github/client.go:2030-2048)
governor.labels.exempt entriesIssues, PRsExempt filterSame exempt behavior as do-not-merge; wins over required-label admission. Defaults include nightly-tests, LFX, meta-tracker, auto-qa-tuning-report, adopters, changes-requested, waiting-on-author.Hard suppressOperator/dashboardEnumeration/sweepsRemove label or config entrygovernor.labels.exempt (src/pkg/config/config.go:3388-3396, src/pkg/config/config.go:5800-5808)
needs-humanIssuesEnumeration, task-list sweep, claim escalation gate and un-park sweepIssue is filtered, not held: no agent kick or contributor offer; task-list sweep adds it only when a merged PR carries the explicit Refs #N (needs-human: <reason>) marker (never on a held issue; remainder prose yields hive/handoff instead, #12002), and the claim escalation gate adds it instead of a third no-progress claim by the same agent (governor.claims.escalate_after_claims, #10527). The un-park sweep keeps a “What to reply” comment on every parked issue listing the commands. See Maintainer commands.Hard suppressHive or humanEnumeration/task-list sweep/kick buildingHuman removes, or a maintainer with write/maintain/admin access replies /hive approve or /hive decision <text> on the issue, which also adds approved-direction and never touches hold (src/pkg/github/issue_unpark_command.go)Fixed label (src/pkg/github/client.go:1008-1024, src/pkg/github/task_list_sweep.go:611-641, src/pkg/github/task_list_sweep.go:874-880, src/cmd/hive/claimescalation.go)
hive/handoffIssuesTask-list sweepSoft hand-off marker. When a merged PR’s Refs #N remainder section says in prose that the rest needs a person or another lane (“needs a human”, “fix lane”, “quality lane”, “production change”, …) without the explicit needs-human: marker, the sweep adds this label and notes “handed off to the next lane” in its remainder comment instead of parking the issue. It is not a hold, suppress, or enumeration filter: the issue stays actionable, so the next lane can still claim it (#12002). Not added when the same sweep is applying needs-human.InformationalHive (task-list sweep)Task-list sweepHuman or the claiming lane removes it; Hive never removes itFixed label (src/pkg/github/task_list_sweep.go:85, src/pkg/github/task_list_sweep.go:576-596, src/pkg/github/task_list_sweep.go:635-665)
needs-humanPRsEscalation ledger, reviewer lane, self-authored auto-merge sweep, queued auto-merge sweepApplied when red-CI fix budget is exhausted or a workflow needs a person; stops automated fix dispatch, sends the PR to the human/reviewer lane, and blocks auto-merge sweeps while present. It is not a PR enumeration filter.Hard fix-dispatch and merge gateHiveEscalation pass/kick building/auto-merge sweepsHuman removes after root cause or reviewer un-escalates; budget resets after grace; auto-merge reconsiders on the next tick because no persisted hold state is keptFixed label (src/pkg/escalation/escalation.go:400-470, src/pkg/escalation/escalation.go:1185-1205)
hive/advisoryIssuesStanding meta classifierHive advisory report is never actionable and never appears on the Hold list.Hard exclusionHiveBefore holds/exemptsRemove label, but exact advisory title still excludesFixed label/name (src/pkg/github/standing_issues.go:1-57, src/pkg/github/client.go:983-1001)
triage/advisoryIssuesStanding meta classifierAdvisory-only dedupe checklist (Decision required: no, #11864) is never actionable and never appears on the Hold list; action-required checklists are parked with needs-decision instead. The close-on-merge backfill closes it once every #N it references is closed or merged, or after 7 days, and swaps it for needs-decision plus the “What to reply” notice if line two turns to Decision required: yes (#11871).Hard exclusionDedupe agentBefore holds/exemptsRemove labelFixed label/name (src/pkg/github/standing_issues.go)
approved-directionAgent-filed issues#5117 gate, ranking, kick tagA PR opened after the label is present avoids #5117 hold; the issue ranks ahead of unacknowledged hive-filed backlog.Gate input + soft rankingHumanPR creation and issue rankingRemove label; human assignee/comment can still acknowledge for #5117Fixed HumanAckLabel (src/pkg/github/pr_self_authorization.go:14-226, src/pkg/github/client.go:2740-2832)
Human assigneeIssues#5117 gate and rankingHuman assignee acknowledges hive-filed direction and moves issue into rank tier 2.Non-label approvalHumanPR creation/rankingUnassignN/A (src/pkg/github/pr_self_authorization.go:180-226, src/pkg/github/client.go:2784-2832)
Relay-linked parentHive-filed issues the relay split out of a parent#5117 gate, ranking, kick tagA child the issue-request relay itself linked as a GitHub sub-issue inherits acknowledgement from an open, unheld parent that is human-filed or carries approved-direction/a human assignee; one level only, and only for links the relay made (recorded in /data/split-parents.json), never for sub-issue links added later in the UI. The kick line shows [hive-filed+parent-ack #N].Non-label approvalHive (from the parent’s human signal)Enumeration and PR creationhold the child, or close/hold the parentFixed ledger (src/pkg/github/split_parents.go)
Human commentIssues#5117 gateAny human comment in the first 100 issue comments acknowledges for #5117, but does not change ranking tier by itself.Non-label approvalHumanPR creationN/AselfAuthCommentPageSize (src/pkg/github/pr_self_authorization.go:14-18, src/pkg/github/pr_self_authorization.go:180-226)
needs-reporter-confirmationIssuesIssue-close gate, dashboardMarks an issue whose opted-in fix appears to have landed but still needs the reporter or a maintainer to reply /fixed. The CloseIssue reporter-confirmation gate applies it only when hive: needs-confirmation or issues.reporter_confirmation requested the gate; if the reporter has write/maintain/admin access Hive also adds needs-human so the dashboard’s human queue catches it.Hard suppress / human signalHive AppEnumeration/dashboard/fixed, deliberate close, or /reopen removes this label. Hive does not remove needs-human here because it may have been set by another workflow.Fixed label (src/pkg/github/issue_close.go, src/scripts/issue-confirm-fixed.sh)
hive: needs-confirmation label/body textIssuesIssue-close gateOpts one human-filed bug-family issue into reporter verification before closing. PR bodies keep Closes/Fixes; the close path leaves the issue open pending confirmation until /fixed, hive: reporter-confirmed, an override, or marker removal.Gate inputHuman/filer/operatorCloseIssueRemove label/text or confirm fixedFixed phrase (src/pkg/github/pr_request_claims.go, src/pkg/github/issue_close.go)
hive: reporter-confirmed label/body textIssuesIssue-close gateLegacy marker showing the reporter/maintainer verified the fix. Close-on-merge is now the default, so this is usually redundant; it still bypasses an active hive: needs-confirmation or issues.reporter_confirmation gate.PermitHuman/reporterCloseIssue, /fixed workflowRemove label/textFixed phrase (src/pkg/github/pr_request_claims.go, src/pkg/github/issue_close.go)
hive: close-on-merge label/body textIssuesIssue-close gateLegacy filing-time marker for bugs whose merged fix is the verification. Close-on-merge is now the default, so this is usually redundant; it still bypasses an active reporter-confirmation config gate. hive-open-issue --close-on-merge still adds it for compatibility.PermitHuman/filerCloseIssueRemove label/textFixed phrase (src/pkg/github/pr_request_claims.go, src/pkg/github/issue_close.go)
design-approvedIssuesPlanning design gateApproves a requested architect design; counts after a design exists.Planning gateHumanPlanning label sweepRemove/re-apply design labels as neededplanning.design_approved_label (src/pkg/planning/design.go:68-125, src/pkg/planning/design.go:320-345)
Lane-name label or agent/<role> segmentIssuesClassifier/schedulerRoutes issue to a lane after title prefix and before keyword routing. Scanner sees every issue; other agents see their lane.Soft routingHive/humanClassification before kicksChange/remove labelagents.*.lane_keywords (src/pkg/classify/classifier.go:249-276, src/pkg/scheduler/templates.go:298-303)
agent/<role>Issues, PRsProvenance, ownership, dashboard bandsMarks the filing/owning agent. The wrapper always derives the suffix from the lane name (HIVE_AGENT), never the display name, so PR ownership and label routing see the same token the scheduler compares against.Informational + routingHiveIssue/PR creation and displayRemove if wrongAgent identity settings (bin/gh-wrapper.sh:1068-1113, src/pkg/scheduler/pr_annotations.go:146-158)
Priority labels (triage/accepted, ai-fix-requested, approved-direction, kind/bug, bug, priority/critical-urgent, priority/important-soon, help wanted, good first issue)Human-filed issuesRankingHuman-filed issues with these labels go to tier 0 in kick lists.Soft orderingHuman/HiveRankingRemove labelHIVE_ACTIONABLE_PRIORITY_LABELS (src/pkg/github/client.go:2740-2832)
auto-qa, auto-qa-finding, kind/security, kind/regressionIssuesClassifierauto-qa/auto-qa-finding make Simple; kind/security/kind/regression make Complex.Soft classificationHive/humanClassificationRemove labelClassifier tables (src/pkg/classify/classifier.go:279-303)
run/spec, run/fixIssuesRuns triageForces spec or direct-fix triage when runs triage is enabled.Gate when enabledHuman/HiveTriageRemove labelruns.triage.enabled (src/pkg/classify/triage.go:1-55)
runs.triage.spec_labels / fix_labels (v6/edge Spek)IssuesSpek/runs triageConfigured exact labels route to spec or fix; mark this v6/edge when documenting Spek behavior.Gate when enabledOperator/humanTriageRemove label/configruns.triage.spec_labels, runs.triage.fix_labels (src/pkg/classify/triage.go:35-55)
tracker, meta-tracker, tracking, epic (last segment)IssuesTracker detector, PR claim rewrite, contributor queueMarks coordination-only/tracker issues; agents see tracker tags, contributors do not get them.Soft for agents; hard for contributorsHuman/HiveEnumeration/contributor admissionRemove label or close trackerTracker detector (src/pkg/github/client.go:2090-2156)
hive-plan, hive-designIssuesPlanning label sweephive-plan mints/decomposes an epic; hive-design asks architect for design first. Only works when planning-from-label is enabled and ACMM >= 5.Gate when enabledHumanPlanning sweepRemove label or process plan/designplanning.plan_from_label, planning.plan_labels, planning.design_labels (src/pkg/config/config.go:400-460, src/pkg/planning/issue.go:483-510)
lgtmPRsQueued auto-merge sweepQueue label for human/owner merge action; the sweep also requires its normal authorization and skips held/exempt PRs. Adding by hand is not enough if the App approval/authorization is absent.PermitDashboard/mergerAuto-merge sweepRemove label; head changes can de-queuegovernor.labels.automerge, default lgtm (src/pkg/config/config.go:3388-3396, src/pkg/config/config.go:4952-4957, src/pkg/github/automerge/automerge_sweep.go:966-1036)
reviewer-passedPRsReviewer lane/escalation reconciliationMarks one reviewer pass/de-escalation; with no needs-human, un-escalates.WorkflowReviewer lane/HiveReviewer/escalation passRemove only if intentionally re-reviewingFixed label (src/pkg/escalation/escalation.go:1185-1205)
reviewer-recommend-closePRsReviewer laneReviewer recommends closing rather than continuing automated repair.WorkflowReviewer laneReviewer passHuman decides/clearsFixed label (src/pkg/scheduler/reviewer_lane.go:296-305)
review.human_decision_labelPRsHuman-decision mirrorMirrors review requires_human verdict to an existing repo label. It gates nothing and Hive does not create/remove it.InformationalHive if label existsReview verdictHuman removesreview.human_decision_label (src/pkg/github/human_decision_label.go:1-36, src/pkg/config/config.go:7186-7203)
needs-rebasePRsScanner/kick annotationFills mergeability annotation in kick data.InformationalScanner/HivePR status processingRemove after rebaseFixed label (src/pkg/scheduler/pr_annotations.go:117-144)
🐝 covered by PR (formerly hive/covered-by-pr; retired in favour of stage/040-covered-by-pr, see Stage labels; the stage reconciler removes it from open items)IssuesPR-claim label sync and dashboardOpen PR is verified as related; issue remains actionable. For a closing or branch-name claim Hive also links the PR to the issue via GitHub’s addCloseIssueReferences, so GitHub’s own issue list shows the PR icon (#11888, #12091). A reference claim (Refs #N, Part of #N — including a branch named after the issue when the body says Refs #N) is never linked, because a closing link makes GitHub close the issue when the partial PR merges; if the hive App itself linked such a pair earlier, the next sweep retracts the link with removeCloseIssueReferences, while links made by a person are left in place and logged (#12144). The dashboard’s own 🔗 pill does not depend on the GitHub link. Labels are synced only for actionable issues, so stale labels can remain on held/exempt/filtered issues.Display-onlyHiveClaim sync after enumerationHive removes when actionable issue no longer has open PR evidenceFixed label (src/pkg/github/prclaims.go:1380-1435)
hive/likely-doneIssuesPR-claim label sync and dashboardMerged PR is verified as related while issue remains open; issue remains actionable until GitHub/operator closes or confirms. Requires a closing keyword or branch-name claim: a merged Refs #N / Part of #N applies hive/partially-addressed instead (#12383).Display-onlyHiveClaim sync after enumerationHive removes when actionable evidence no longer says likely doneFixed label (src/pkg/github/prclaims.go)
hive/partially-addressedIssuesClose-on-merge sweep, PR-claim label sync and task-list sweepA merged PR covered only part of the issue (#11931): applied instead of hive/likely-done when the PR has no closing keyword (Fixes/Closes/Resolves #N) for the issue, its body carries a remainder/out-of-scope paragraph, or none of the backtick-quoted paths cited in the issue body is among its changed files. No /fixed prompt is posted, hive/likely-done is suppressed, and the issue stays in the actionable pool; the “ comment lists the cited paths no merged PR changed as Not yet touched: ....Display; suppresses likely-doneHiveClose-on-merge sweep for issues behind a confirmation gateHive removes it when a later merged PR fully covers the issue and hive/likely-done is applied; humans may remove itFixed label (src/pkg/github/close_on_merge.go, src/pkg/github/task_list_sweep.go)
hive/already-doneIssuesContributor queue, already-done verdict close path, and dashboardContributor already-done verdict/confirmation; default contributor skip label and done band. When the verdict cites a PR that the API verifies as merged on the default branch, Hive labels the issue and runs the normal completed close path; human-filed bugs close too unless hive: needs-confirmation or issues.reporter_confirmation opted into the reporter gate.Contributor hard skip; dashboard display; conditional closeHive/contributor flowContributor admission, verified verdict settlement, issue close gateHuman removes/reopens or confirms reporter-gated bugshub.contribute_already_done_label, fixed label (src/pkg/config/config.go:4701-4924, src/pkg/dashboard/contribute_verdict_settle.go, src/pkg/github/issue_close.go)
blockedIssuesContributor queue and dashboard issue bandsAlways included in contributor skip patterns and default waiting band. Does not by itself stop spoke-agent enumeration unless also exempt/held/filtered.Contributor hard skip; displayHuman, or Hive App on a contributor blocked verdictContributor admission/dashboard renderRemove label. Hive’s hard-suppress reconcile (#12002) lifts a blocked whose newest label event is a labeled by the App bot once a PR referencing the issue merges after it, posting one note carrying “; a human-applied (or re-applied) blocked is never lifted.hub.contribute_skip_labels, dashboard bands (src/pkg/config/config.go:4585-4685, src/docs/dashboard.md:105-140)
needs-directionIssuesEnumeration, escalation labels, dashboard issue bands and un-park sweepADR-0019 escalation marker for work that needs a maintainer direction decision before continuing. Filtered from enumeration like needs-human: no agent kick, kick claim or contributor offer. The un-park sweep keeps the same “What to reply” notice as needs-human/needs-decision and accepts the same /hive approve or /hive decision <text> commands. See Maintainer commands.Hard suppress until directedHive/humanDashboard render and un-park sweepHuman removes, or a maintainer replies /hive approve / /hive decision <text>, which also adds approved-direction and never touches hold (src/pkg/github/issue_unpark_command.go)Fixed escalation label (src/pkg/github/labels.go, src/docs/adr/0019-escalation-over-stalling.md)
needs-decisionIssuesEnumeration, contributor relay, dashboard issue bands and un-park sweepRelay can apply it when a maintainer decision is needed; the issue relay also applies the configured label (project.issue_filter.hard_suppress_labels.needs_decision) when an agent files an issue with hive-open-issue --needs-decision (#11215), so an agent-filed question for the maintainer is parked on creation; filtered from enumeration like needs-human, so no agent kick, kick claim or contributor offer. The un-park sweep keeps the “What to reply” notice and command handling documented in Maintainer commands.Contributor hard skip; displayRelay/Hive/humanContributor admission/dashboard renderHuman removes, or a maintainer replies /hive approve / /hive decision <text>, which also adds approved-direction and never touches hold (src/pkg/github/issue_unpark_command.go); empty config disables relay applicationhub.contribute_needs_decision_label (src/pkg/config/config.go:4397-4408, src/pkg/config/config.go:4645-4685)
needs-triage, discussion, question, tracking, epicIssuesContributor queueDefault contributor skip labels/patterns.Contributor hard skipHuman/HiveContributor admissionRemove label or confighub.contribute_skip_labels, HIVE_CONTRIBUTE_SKIP_LABELS (src/pkg/config/config.go:4585-4685)
Contributor allow/deny label filtersIssuesContributor queueHive-wide label filters can run in deny mode (skip if any label matches) or allow mode (offer only if at least one label matches); per-repo filters layer on top and can only narrow offers. Patterns use Hive wildcard/substring matching, not GitHub hold matching.Contributor hard gateOperatorContributor admissionEdit filter mode/list or per-repo filterhub.contribute_labels_mode, contribute_deny_labels, contribute_allow_labels, contribute_repo_filters (src/pkg/config/config.go:4388-4420, src/pkg/config/config.go:6940-6994, src/pkg/config/config.go:7008-7055)
1-triage, 2-discussing, stage labelsIssuesDashboard repo-card bands/legendStage vocabulary is display-only unless another consumer names the same label. 2-discussing ships in the default waiting band; 1-triage is just a visible repo taxonomy label unless configured elsewhere.Display-onlyHuman/repo automationDashboard renderRemove label or change band configdashboard.issue_bands (src/docs/dashboard.md:105-140)
claimed (retired → stage/020-claimed), preempted:<login>, hive/claimed-by-<agent>IssuesClaims/dashboardA claim is a comment; the claimed label is a mirror Hive keeps in sync. Go claim gates use comments/assignees/ledger, not these labels.Display-onlyHive/claim flowsDashboard renderCleared by claim flow or humangovernor.claims.* (src/docs/dashboard.md:105-140)
hive/in-progress (retired → stage/020-claimed / stage/030-pr-in-progress; the claim marker comment below remains the detection signal)IssuesAgent claim relay, ledger mirror, enumeration sweep and dashboard in-progress bandStates that a hive agent (normally the scanner) has started work on a PR for this issue (#11841). Applied by hive-open-issue claim next to hive/claimed-by-<agent> in one label call, together with a bot comment carrying “ (the ledger’s 🔒 comment carries the same at= when governor.claims is on). While the marker is live (until in the future) every hive scanning the repo withholds the issue from kicks, so two spokes never start the same issue; the at= instant is the start timestamp for per-repo SLA spans (kicked → started → pr_opened).Kick withhold while marker live; displayHiveClaim relay, ledger OnClaimed, enumeration sweepHive removes when the agent’s PR opens (hive-open-pr --issues), when the ledger releases the agent claim, or at enumeration once PR evidence exists (hive/covered-by-pr, hive/likely-done, linked PRs) or the marker lapsed (default 2h agent_ttl_s); governor.claims.label: false disables itFixed label (src/pkg/github/issue_inprogress.go, src/cmd/hive/claimswire.go)
origin/review (was from-review)IssuesReview backlog filing, origin-label reconcilerMarks issues filed from review findings (origin/* provenance axis). No code path uses it as a gate; agent/<lane> on the same issue still says who works it. Open items carrying the retired from-review are swapped to origin/review once at startup.InformationalHiveIssue creation/display; one-time migration at startup (/data/origin-label-migration.done)Remove labelreview.backlog.labels (default [origin/review]; from-review accepted and mapped) (src/pkg/github/origin_labels.go, src/pkg/github/review_backlog.go)
hive: churn-triagedIssuesContributor churn guardMarks churn triage acknowledgement for contributor flow.Workflow signalHuman/HiveContributor/churn checksRemove label to re-triageFixed phrase in contributor flow docs/config (src/pkg/dashboard/contribute_admission.go:302-338)
good first issue, help wanted, bug, enhancementIssuesContributor opportunistic orderingSmall ordering boost/visibility in contributor panels; good first issue, help wanted, and bug also appear in default actionable priority labels for human-filed issues.Soft orderingHuman/HiveContributor queue/rankingRemove labelContributor/ranking config (src/pkg/github/client.go:2740-2832)
good first issue + help wanted (hive-curated, “ comment)IssuesContributor advertisingOn by default (good_first_issue.enabled: false opts out), hive applies both labels to a few qualifying open, unclaimed issues and leaves one welcome comment linking its relay. Not a hold — the issue stays in the hive’s queue; a hive agent starting it removes the label and marks the comment superseded. Never in the hard-suppress set. See good-first-issue.md.Soft (advertising)HiveSweep (src/pkg/gfi)Hive agent start, or remove labelgood_first_issue.*

Stage labels (stage/NNN-*): the pipeline state machine

Operator request (#12429): “the labeling of issues and prs has to give hints as to what stage the work is in … the labels must be clear and reflect the state machine … this needs to be dead simple.” The hive therefore owns ONE ordered, mutually exclusive stage/NNN-slug family shared by issues and PRs, an orthogonal author/* family that answers “would the hive auto-merge this?”, and two red health markers (stage/stalled, stage/regressed) that say the progression was disrupted. Exactly one stage/* stage label per open item; closed, merged or superseded items carry none (terminal = no stage).

The engine lives in src/pkg/stagelabels (the table, the reconciler plan, the persisted stage timing) and src/pkg/github/automerge/automerge_stage_labels.go (the mapping from each automerge lane’s per-PR reason to a stage, applied once per sweep cycle under the hive:stage_labels REST caller). Labels come from the PR list payload the sweep already fetched — no per-item GETs — and are written only when the planned set differs from the current one.

Numbering rules

  • Sparse, zero-padded, 3 digits. GitHub sorts labels lexically, so the padding is what keeps stage/100-… after stage/090-….
  • 100 is always the merge queue. New stages are inserted between existing numbers (e.g. 035), never above 100.
  • Renaming or inserting a stage = edit ONE table, stagelabels.Table. Stages are keyed in code by Go identifiers (ReviewPending, MergeQueue, …); the label string (number + slug), description, dwell and colour are all derived from that row. The reconciler treats any stage/* label not in the current table as stale and removes it, so a renumber ripples to every open item on the next cycle; the old labels can then be deleted from the repo.
  • Colours: every stage/NNN-* label is the same hive amber #f5a623 (the colour the retired 🐝 covered by PR used) so the eye tracks the family across lists; stage/stalled #d73a4a and stage/regressed #b60205 are red; author/* is neutral grey #6e7781 except author/trusted #0e8a16. The ensure-label step creates missing labels and PATCHes the colour of an existing one only when it differs from the table, once per repo per process.

The table

LabelApplies toMeaningExpected dwell (then stage/stalled)
stage/010-actionableissuetriaged; eligible for the hive to pick up24h
stage/020-claimedissueclaimed by the scanner or a relay contributor (replaces claimed, hive/in-progress)2h
stage/030-pr-in-progressissuean agent kick / contributor session is actively working; no PR yet90m
stage/040-covered-by-prissuean open PR covers it (replaces 🐝 covered by PR); from here the issue mirrors the PR’s stagen/a (mirrors)
stage/050-review-pendingPRreview swarm requested/dispatched; awaiting a verdict for the current head (or CI still pending with no verdict)1h
stage/060-reviewedPRswarm verdict approve but a gate is still pending (CI running, soak not started)30m
stage/070-fixingPRhive-authored (App/taken-over) PR: CI red, changes requested or needs-rebase; a hive agent is reworking it2h
stage/072-returned-to-contributorPRcontributor PR (relay or external): CI red / changes requested / conflicting; the hive posted its diagnosis, the ball is in the author’s court24h
stage/074-adopted-by-hivePRthe author was unavailable past the grace (see below); the hive pushed hive/adopt-<n> at the contributor’s head, opened a superseding App PR that keeps the author’s commits, and the scanner’s red-PR fix kick is finishing it. The original closes automatically when the superseder merges3h
stage/080-awaiting-merge-admissionPRnothing left for the author: CI green, verdict approve, no modifiers — and the automerge lane has not admitted it yet (prefilter not evaluated for this head, labels not synced, lane tripped). A stall here means a lane problem, so the hive also posts one “ comment with the lane’s last skip reason30m
stage/090-needs-humanPRcannot auto-merge; a person must act. Always read with the author/* label and any hold/needs-human/needs-decision modifiernone
stage/100-merge-queuePRlane admitted: soaking, merge-eligible or waiting for tide / the merge window3h

Dwell thresholds are overridable per slug under governor.labels.stage.dwell (review-pending: 1h, 0 = never). The whole family is switched by governor.labels.stage.enabled (default true); both are on the Settings → Labels tab.

How an issue’s stage is decided

The enumeration cycle already sorts every open issue into a work bucket (actionable, live claim, in-progress start mark, covered by an open PR, filtered …) before the scanner kicks anything. src/pkg/github/issue_stage_labels.go (SyncIssueStageLabels, REST caller hive:issue_stage_labels) runs once per cycle after the claim guards and the in-progress sweep, so the buckets are final, and maps each row (#12436):

Enumeration bucketStage
carries hive/likely-done (a PR merged, awaiting confirmation)no stage — every hive-owned label removed, timing forgotten
actionable (no claim, no PR)010-actionable
live claim (“ marker / ledger) by a human or relay contributor020-claimed
live claim by one of the hive’s own agents, or an in-progress start mark (kind=agent marker from hive-open-issue claim)030-pr-in-progress
covered by an open PR, PR not yet staged by the automerge sweep040-covered-by-pr
covered by an open PR the sweep has staged (≥ 050)mirrors the PR’s stage (050-review-pending … 100-merge-queue) so the issue list reads the same as the PR list
exempt / filtered / reporter triage / advisory / dependency dashboardno stage

Labels come from the issue list payload the cycle already fetched — no per-issue GETs — and are written only when the planned set differs from the current one. When the stage is mirrored from a PR, stage/stalled and stage/regressed belong to the PR and are not written on the issue; when the issue falls back between its own stages (a claim or kick lapsed with no PR: 030 → 010) it gets stage/regressed and one explanatory comment. The claim relay (hive-open-issue claim) writes stage/020-claimed / stage/030-pr-in-progress directly alongside hive/claimed-by-<who> so the label is right as soon as the claim lands; hive-open-pr --issues swaps 030 for 040 when the PR opens; close-on-merge strips every hive-owned label from an issue it closes. Timing and mirroring share the PR engine’s state file (/data/stage-labels.json, issues and PRs share a number space per repo).

How a PR’s stage is decided

The automerge sweep already computes one reason per PR per lane each cycle (self-authored, trusted-author, contributor lane — see hive-merge.md). automerge_stage_labels.go maps that reason, the review-swarm verdict for the head, and the author tier the lane actually used to admit the PR:

Lane reason (examples)Stage
merged / closed / goneterminal: every hive-owned label removed, timing forgotten
draftno stage (stale stage removed)
contributor-lane:no-verdict, CI pending with no verdict050-review-pending
CI pending, verdict approve060-reviewed
CI green, verdict approve, no modifier, yet the lane stopped on a reason no stage claims or tripped on a transient error (review-state-check, …)080-awaiting-merge-admission (weak opinion: any lane’s definite stage wins)
CI red (check-failing:*, required-check-failing:*, status-*), conflicting, not-mergeable, changes-requested, verdict changes_requested/reject, needs-rebase present070-fixing (self-authored lane) / 072-returned-to-contributor (trusted-author or contributor lane)
contributor-lane:soaking(...), head-changed-since-eval, merge-failed, required-checks-expected, behind, updated-branch, release-hold*100-merge-queue
label:hold, held, label:needs-human, exempt-label, excluded-label:*, sentinel, human-merge-path*, intent-*, contributor-lane:no-claim / claim-* / author-association / no-linked-issue / workflow-path / tests-removed / no-reviewer, untrusted-author-role, author-permission-missing090-needs-human
hand-offs (not-app-authored, trusted-bot-lane, contributor-lane:app-authored), transient fetch errorsno opinion — the owning lane decides; nothing is written

When several lanes see the same PR the self-authored lane outranks the trusted-author lane, which outranks the contributor lane; the trusted-author lane’s bare untrusted-author-role is a weak opinion the contributor lane refines.

author/* — would the hive auto-merge this?

One per PR, derived from what the lane used for admission (registry tier, claim-marker tier=, trusted-author list, App-authored), recomputed with the stage but written only on change:

LabelSource
author/trustedApp-authored or self-authored lane; trusted-author lane allowed the author; registry/claim tier in the contributor lane’s require_tiers (default trusted, merger) → auto-merge eligible
author/contributorregistry/claim tier contributor → needs human lgtm/approve
author/newcomerregistry/claim tier newcomer
author/untrustedno claim and no registry profile (external PR), revoked, or not a trusted author

stage/stalled and stage/regressed

  • stage/stalled — the item sat in its current stage longer than the table’s dwell. “Entered stage at” is tracked in the hive’s persisted state (/data/stage-labels.json), not GitHub’s timeline, so no extra API calls. Cleared automatically when the stage changes. Only a stall in 080-awaiting-merge-admission is explained in a comment (the lane’s last skip reason), because that stall is the hive’s fault, not the author’s.
  • stage/regressed — the stage number went DOWN (e.g. 100 → 070 because a new head went red). On every backward transition the hive posts one short idempotent comment carrying “: stage 100-merge-queue → 070-fixing: check-failing:unit. The label stays until the stage reaches the point it regressed from (or the item closes). Leaving a repair stage (070/072/074) for 050/060 is the repair route itself and is not counted as a second regression.
  • At most one health label at a time; regressed wins over stalled.
  • Filter label:stage/stalled or label:stage/regressed across repos = everything off the happy path.

Off the happy path: 072 → nudge → 074 → takeover

When a contributor PR goes red the hive does not just relabel it (full flow in hive-merge.md):

  1. stage/072-returned-to-contributor and ONE “ comment @-mentioning the author with the failing checks / review asks and “reply here or push a new head”. Re-posted only for a new head; re-nudged once more after governor.labels.stage.contributor_nudge.renudge_interval (default = the stage’s 24h dwell, i.e. at stage/stalled), then no more — cap: 2 nudges per head. mode= records how the relay side was handled so the comment itself answers “did their agent get interrupted?”. governor.labels.stage.contributor_nudge.enabled: false turns the comment and the relay task off; the stage label still moves.
  2. Relay contributors (the author has a contributor profile and a live relay connection) also receive the diagnosis in their relay session as a fix-pr task with priority: interrupt. Presence = a relay heartbeat within governor.labels.stage.presence_window (default 15m); an offline or external author gets the GitHub comment only (mode=comment). The hub picks the delivery mode from what the relay advertised at DECLARE:
    • mode=spawn — the relay declared parallel_sessions and max_parallel_fixes (its HIVE_MAX_PARALLEL_FIXES, default 1, only when the backend has a headless entry point): a bounded parallel sub-session fixes the red PR while the primary session keeps its task.
    • mode=preempt — no parallel capability: the primary agent is told to park its current issue (WIP committed/stashed; the claim and lease stay alive), fix the PR on its existing branch with the same sign-off, print HIVE_FIX_PR_DONE <task_id> (or HIVE_FIX_PR_FAILED <task_id> <reason>), then resume. A headless primary cannot be interrupted, so the relay defers the fix and runs it before its next ready.
    • mode=queued — the contributor is over their fix budget (below); the task waits server-side and the PR carries stage 072 + the comment only. Protocol fields and client behaviour: contributor-relay.md § fix-pr tasks.
  3. If the author stays unavailable past the grace — counted from the FIRST nudge for the head: governor.labels.stage.contributor_grace_online (default 2h) when the nudge reached a relay (mode=spawn|preempt|queued), governor.labels.stage.contributor_grace_offline (default 1h) after a comment-only nudge (offline relay or external author) — the hive adopts the PR (governor.labels.stage.adoption.enabled, default true):
    • pushes hive/adopt-<n> in the base repo at the contributor’s head SHA (the fork’s commits, authorship and Signed-off-by preserved byte for byte — “sign-off survives the squash”);
    • opens an App PR from it against the same base, titled like the original, whose body starts Supersedes #N (adopted after CI went red and the contributor was unavailable; original commits by @author preserved), carries the original’s Closes/Fixes/Resolves lines and instructs the fix agent to rebase on the base and fix CI on that branch without opening another PR;
    • posts ONE comment on the original and moves it to `stage/074-adopted-by-hive` (its linked issue mirrors the stage). The hub drops the PR from the contributor's fix queue. The superseding PR is App-authored and red with the same failures, so the existing machinery takes over: it lands in `ci-failing.json` and the scanner's FIX-BEFORE-NEW kick (the route every red hive-authored PR takes, [hive-merge.md](https://github.com/hivecommons/hive/blob/v5/src/docs/hive-merge.md#stage-labels)) rebases and fixes it on `hive/adopt-<n>`; it then runs the normal `050 → 100` path. No second takeover mechanism exists. One adoption attempt per contributor head, whatever the outcome. While in 074 the hive polls the superseder at most every 10 minutes: merged → one note and the original is closed; closed unmerged (a maintainer declined) → the adoption is forgotten and the original returns to 072 (not a regression).
  4. A new head from the author at any point before adoption re-arms the nudge (grace restarts) or, if green, returns the PR to the normal 050 → 100 path; no adoption. After adoption the author can still push a new head on the original and say so on the superseder.
  5. Backpressure — the per-contributor fix budget. Capacity = the relay’s advertised max_parallel_fixes (fix sub-sessions beside the primary), clamped by contribute.max_parallel_fixes (default 2); an unadvertised relay has capacity 1 (preempt mode). At most that many fix-pr tasks are in flight per contributor; the rest wait in a per-contributor FIFO (oldest PR first, a human changes-requested before CI-red) carrying stage 072 and the GitHub comment only. Preempt mode allows ONE preemption at a time and never preempts again until the parked task has resumed and run for contribute.min_focus_window (default 30m). Failures with the same cause (same failing check + error signature) are coalesced into one task listing every affected PR. A queued PR whose adoption grace expires goes to 074 instead of interrupting — the hive absorbs the overflow, not the human. Queue depth / in-flight is exposed as fix_queue on the contributor profile API and on the contribute page; the hub logs one line per enqueue/dequeue (fixqueue: … event=…).
  6. Governing rule of the contributor fix scheduler, verbatim from the operator: “contributors should clean up their mess before taking on new stuff.” Every ordering decision — task boundary, dequeue, a new-issue claim via the relay or the contribute page — checks the contributor’s red-PR queue first: queued fix-pr tasks are handed out oldest first (even to a relay that advertises no fix-pr support, as an ordinary task) and a fresh issue is served only when that queue is empty. The contribute page shows “You have N PRs to fix first” and offers those PRs before new issues. Preemption of in-progress work still obeys the single-preempt + focus-window rule; this ordering applies at task-boundary time.
  7. Capacity ≥ 2: fixes are dispatched immediately as parallel sub-sessions, up to the advertised count so the primary session keeps going and is never preempted; further failures queue, and each finished fix session (task_complete/task_failed for the fix’s task_id) frees a slot that is refilled automatically with the next queued fix-pr.

All seven steps ship with the stage engine and the contribute hub (hivecommons/hive#12436).

Modifiers, not stages

These existing labels qualify a stage and may coexist with any stage label; the reconciler never touches them: hold / hold/*, needs-human, needs-decision, needs-direction, blocked, needs-rebase, hive/likely-done, hive/partially-addressed, hive/claimed-by-<who> (the grey “who” modifier a stage cannot carry), lgtm, author/*, and the agent provenance labels.

Migration from retired labels

🐝 covered by PR (and its pre-#11888 spelling hive/covered-by-pr), the bare claimed label and hive/in-progress are retired: their meaning is carried by stage/040-covered-by-pr, stage/020-claimed and stage/020-claimed / stage/030-pr-in-progress. Claim detection never read those labels — it uses the “ marker comment (claim_source=marker), assignees and the ledger — so removing them changes no gate. On the first cycle after upgrade the reconciler removes them from every open item it writes a stage for, so open items lose claimed / hive/in-progress / 🐝 covered by PR and gain their stage label; the repo-level labels can be deleted afterwards. The legacy writers are gone: the claim relay and ledger mirror write stage/020-claimed / stage/030-pr-in-progress, the PR-claim sync writes stage/040-covered-by-pr, and the in-progress sweep still recognises hive/in-progress as a trigger for one migration cycle so a lapsed mark from an older spoke is cleared rather than orphaned. hive/claimed-by-<who> is kept as the grey “who” modifier.

Matching rules

  • GitHub generic holds are case-insensitive substring matches against hold, on-hold, hold/review, plus configured non-hive-pause/ extra holds. A label such as threshold contains hold and therefore holds (src/pkg/github/client.go:1894-1932).
  • hive-pause/<hive-id> is case-insensitive exact match, not substring, so it does not collide with hive/<hive-id> provenance (src/pkg/github/client.go:1898-1932).
  • Exempt labels use case-insensitive equality or prefix for permanent/configured labels, but the prefix check uses the original label string (src/pkg/github/client.go:2030-2048).
  • Contributor skip labels are lowercased and matched with path.Match glob syntax; invalid globs fall back to exact case-insensitive matching (src/pkg/config/config.go:4658-4708).
  • Lane routing lowercases labels and matches lane/routing tokens by segment, so agent/scanner can route to scanner; PR agent/ ownership paths are stricter and should be treated as case-sensitive operationally. The wrapper writes agent/<lane> from HIVE_AGENT, so the label always carries a routable token (src/pkg/classify/classifier.go:249-276, bin/gh-wrapper.sh:1068-1113).
  • Planning and triage labels are exact label names after normalization; defaults are prefixed (hive-plan, hive-design) so ordinary plan or capitalized Epic taxonomy does not trigger planning (src/pkg/config/config.go:400-460, src/pkg/classify/triage.go:66-84).
  • Linear holds use GitHub-like case-insensitive substring matching with defaults plus work_source.linear.hold_labels (src/pkg/worksource/linear.go:344-355).
  • Jira holds use exact, case-sensitive equality against configured work_source.jira.hold_labels; there is no built-in Jira default (src/pkg/worksource/jira.go:50-68, src/pkg/worksource/jira.go:302-330).
  • GitHub Projects work source carries labels through but does not implement a hold-label gate (src/pkg/worksource/github_projects.go:370-405).

Config that changes label behavior

  • github.self_authorization_hold, project.repo_policies[].self_authorization_hold, and HIVE_SELF_AUTHORIZATION_HOLD change #5117 holds. When all are unset, the default follows the live ACMM level: on through L5, off at L6 Fully Autonomous.
  • Hive-wide ACMM level controls level holds; per-repo ACMM overrides do not make PRs skip the level hold.
  • governor.labels.exempt, governor.labels.automerge, and project.issue_filter.require_labels decide exempt/admit/queue behavior.
  • project.issue_filter.reporter_trust.* (admission by reporter), github.reporter_trust_hold, project.repo_policies[].reporter_trust_hold, and HIVE_REPORTER_TRUST_HOLD (the matching merge hold) are the #9665 reporter-trust gate. Off unless reporter_trust.enabled: true; the hold follows that switch unless set on its own. Both are edited under Settings → Labels (who is trusted, which triage label) and Settings → Repos (the hold).
  • planning.plan_from_label, planning.plan_labels, planning.design_labels, and planning.design_approved_label control planning labels, with the L5+ planning floor.
  • runs.triage.enabled, runs.triage.spec_labels, and runs.triage.fix_labels control run triage labels.
  • governor.question_autoclose.* (HIVE_QUESTION_AUTOCLOSE, HIVE_QUESTION_AUTOCLOSE_HOURS) closes answered question issues; see Question auto-close.
  • governor.claims.*, review.human_decision_label, hub.contribute_*, dashboard.issue_bands.*, and HIVE_ACTIONABLE_PRIORITY_LABELS control the display/contributor/ranking labels above, including contributor label allow/deny filters and per-repo narrowing.
  • work_source.linear.hold_labels and work_source.jira.hold_labels are non-GitHub label-equivalent gates with the different matching rules described above.
  • Not labels: project.paused_repos pauses an entire repo; contributor queue holds can park owner/repo#N without changing GitHub labels.

Question auto-close

Off by default (#9584). When on, a question issue the hive has answered is closed after a short window unless the person who asked objects, so answered questions stop inflating the open-issue count and being rescanned every sweep.

governor:
  question_autoclose:
    enabled: true          # or HIVE_QUESTION_AUTOCLOSE=true
    hours: 4               # or HIVE_QUESTION_AUTOCLOSE_HOURS; default 4
    labels: [question, kind/question]   # default; what marks a question
    human_label: needs-human            # default; added when the author objects

How it works:

  1. The scanner kick gains a short answer contract: an issue that only asks a question gets the question label and ONE answer comment, which ends with a hidden “ marker and the line “If this doesn’t answer your question, react 👎 to this comment and the issue will stay open.” The footer text is built by Hive and passed through the mention sanitizer.
  2. Hive watches question-labelled issues from the normal issue pass. When the last comment on one is a marked answer posted by the hive’s own identity (the GitHub App bot login <app-slug>[bot] or project.ai_author), it schedules a close at answer time + hours. The schedule lives in /data/question-autoclose.json, so a restart keeps the original deadline. The marker is plain text, so a marked comment from any other account (a person or another bot pasting it) is ignored and never starts the clock; with no hive identity known, nothing is auto-closed.
  3. At the deadline Hive re-reads the issue. A 👎 from the issue author on the answer keeps it open and adds human_label. Otherwise the issue is closed with state_reason: completed and no extra comment, so the answer stays the last thing Hive said.

A schedule is cancelled (never acted on) when anyone comments after the answer, the issue is closed by someone else, the question label is removed, or a bug, enhancement, hold or human_label label appears. Bugs (bug, kind/bug, human-filed bug reports), enhancements/features and held issues are never auto-closed. A cancelled or finished answer is remembered for 30 days so the same answer is never scheduled twice; a new answer after a follow-up starts a new window.

Dashboard

The Governor dialog’s Features tab has a “Question Auto-Close” section: a switch for enabled and a field for hours (GET/PUT /api/config/governor/question-autoclose, owner-only, same pointer/only-what-you-send contract as the other governor-config sections). Turning it on there shows a read-only live-schedule table underneath — one row per answered issue currently waiting out its objection window (repo/issue, answered-at, closes-at), backed by GET /api/config/governor/question-autoclose/schedule. The table is read-only: labels/human_label still need hive.yaml.

Lifecycle examples

Strategist-filed direction to a PR

  1. Strategist files an issue with [strategist]/agent/strategist. It is actionable but lower-ranked as hive-filed.
  2. A maintainer adds approved-direction, assigns a human, or comments. Label or assignee also improves ranking; a comment only satisfies #5117.
  3. An agent opens a PR citing the issue. If the acknowledgement existed before PR creation, no #5117 hold is applied. At L3-L5, the separate level hold can still apply.
  4. If acknowledgement is added after a PR already has hold, remove the PR hold too.

Holding an issue

  1. Add hold/on-hold/hold/review, or use dashboard ⏸ Hold to add hive-pause/<hive-id>.
  2. Enumeration moves it to the Hold list. It leaves agent kicks and the contributor queue.
  3. Caveat: the task-list and SHA sweeps do their own listing but honour the same hold predicate; SHA-hold lifts only the literal hold it applied itself.
  4. Hard-suppress reconcile (#12002): every issues.hard_suppress_reconcile_interval (default 30m, unstick step of the eval loop), Hive lists open hold/blocked issues in its repos and lifts a label only when the newest event for it is a labeled by the App bot (for hold, also paired with the notice) **and** a cross-referencing PR merged after that event. It posts one note carrying. Disable with issues.lift_hive_hard_suppress: false.
  5. Remove the hold label or click ▶ Release; it is reconsidered on the next enumeration.

Holding a PR

  1. The PR receives hold from a human, the level gate, #5117, holdguard, or SHA-related policy, or receives needs-human from a human/escalation workflow.
  2. It is not merge-eligible or auto-merged; self-authored and queued auto-merge sweeps treat needs-human like a live hold label. If CI is red and it is not a held outreach PR or escalated, its owning agent may still be asked to fix CI without removing the hold.
  3. If the branch moves while held and then the hold is lifted, holdguard re-adds hold; removing it again is the fresh approval.

Escalation

  1. Red CI across the distinct-SHA budget applies PR needs-human; automated fix dispatch stops.
  2. Reviewer lane may add reviewer-passed and remove/un-escalate needs-human, or add reviewer-recommend-close.
  3. A human can remove needs-human after addressing the root cause; the ledger resets after the grace period.

Non-label equivalents

  • Human comments and assignees can acknowledge hive-filed directions for #5117; assignees also affect ranking.
  • Hidden comment markers carry state that no label does. records an issue claim, dedupes a published finding, marks an overlap notice, starts the question auto-close clock, and is stamped on the single comment a fix lane leaves on a PR it defers to shared incident `#<n>` (`DEFER_TO_INCIDENT` from `bin/hive-baseline-check.sh`), so "every PR incident `#<n>` broke" stays greppable after the fix lands ([#10441](https://github.com/hivecommons/hive/issues/10441)). One marker per PR per incident; it is never edited or removed while the incident is open. While incident `#<n>` is open, the governor records it as `deferred_incident` on the PR's `ci-failing.json` row and the kick builders keep that PR out of every CI-FAILING / FIX-BEFORE-NEW repair list, naming it only as deferred; once the incident closes the PR is listed for repair again ([#10528](https://github.com/hivecommons/hive/issues/10528)). When the incident closes (not as "not planned"), the shared-CI rerun sweep re-runs the failed jobs of each still-open PR carrying that marker — the newest failed or timed-out run per workflow on the PR head — using the hive's own credential, then stamps on the PR so it is re-run at most once per incident; disable with shared_ci_rerun.enabled: false (#12253).
  • Paused repos (project.paused_repos) stop whole-repo write/merge/enumeration paths without labels.
  • Contributor queue holds such as active leases, cooldowns, dependencies, and quota guard holds suppress contributor offers without touching GitHub labels.
  • Jira/Linear labels map only where the work-source adapter supports them: Linear skips held work using substring hold labels; Jira skips exact configured hold labels; GitHub Projects currently imports labels but does not use a hold gate.

Repo-card legend vocabulary

The repository-card legend is a UI vocabulary, not a second scheduler. Unclaimed, claimed, needs-triage, needs-human, and confirm-and-close issue bands are computed client-side from labels/assignees, the snapshot’s human_acknowledged flag (the cheap half of the #5117 acknowledgment: approved-direction or a human assignee, no comment scan), and dashboard.issue_bands; PR bands are computed client-side from held/needs-human labels, merge verdicts, CI, review links, draft state, and the same waiting/stale display config. Non-winning states stay as badges. State glyphs such as ⛔, ❓, 👤, ✓, role badges, stale 🕒, PR ✓/◐/⚠, held ⏸, failing CI ✗ CI, conflicts ⑂, reviewed 💬, auto-merge 🔀, and review-class badges explain the same data the table above names. A PR carrying the configured sentinel alert label (sentinel.label, default sentinel-alert, case-insensitive) is drawn as a red sentinel pill that wins over the held, needs-human and merge colours; the legend explains that Hive will not merge it until a maintainer removes the label and that trusted-author PRs, which normally get only a sentinel comment, are usually not red. Changing a band label changes the repo card description only; it does not make an item held, exempt, mergeable, or actionable.

Documented inconsistencies and follow-ups

Issue #8924 recorded the sharp edges of this page’s first version; #8927 aligned the code: auto-merge sweeps, the task-list sweep, and the SHA-hold sweep now gate on the enumeration hold predicate (so hive-pause/<hive-id> holds everywhere), SHA-hold lifts only its own hold, policy templates name the enforced hold set, and agent/<role> is always the lane name. Two behaviours remain deliberate rather than fixed:

  • Level-hold and #5117 disabled-policy auto-release are different. The self-authored auto-merge sweep may still release its own #5117 self-authorization holds, but ACMM level-applied holds are never auto-released by a sweep or level change. They are released by a human removing hold, or by a deliberate one-off PUT /api/packs/level with release_level_holds: true, which touches only Hive App level-hold notices whose latest hold event was by the App.
  • hive-open-pr discards every --label value, including hold, because the PR-request watcher applies holds server-side (bin/hive-open-pr.sh:142-150, src/docs/hive-open-pr.md).