Hive can advertise a few of its open issues to new contributors — in
particular contributors who bring their own coding agent (Claude Code, Codex,
Copilot CLI, Bob, …). A periodic sweep (on by default; good_first_issue.enabled: false opts out) scores
the open, unclaimed issues in each watched repository, applies GitHub's
canonical good first issue and help wanted labels to the few that
qualify, and leaves one welcome comment that explains how to land the fix
through this hive's contributor relay without waiting
on a human.
The label is advertising, not a hold. The issue stays in the hive's own queue. If a hive agent starts on it first, the sweep's label comes off and the welcome comment is edited to say so. If a contributor claims it through the relay first, hive leaves it to them — and counts the conversion.
Default on: the operator asked the hive to decide what qualifies without
per-spoke YAML (#12185). The sweep is safe to leave on because
it is capped (max_per_sweep, max_per_repo) and self-silencing — it does
nothing until the hive has a public dashboard URL to link. Set
good_first_issue.enabled: false to opt out.
Because the scanner usually claims a fresh issue within minutes, the sweep runs every 15 minutes and advertises issues as soon as they are an hour old. In a hive that drains its own queue quickly, few issues will ever qualify — that is expected; the label is for the ones the hive has not got to yet.
The point of the label is reach. good first issue (exact spelling, colour
7057ff) plus help wanted are what GitHub's per-repository Contribute
page (github.com/<owner>/<repo>/contribute) and the good-first-issue
aggregators key on, so a hive-labelled issue shows up where people — and the
people steering agents — look for a first task. The welcome comment then does
the pitch, end to end:
- Claim through the relay. The comment deep-links this hive's relay page
for this issue:
<public_url>/contribute?issue=<owner>/<repo>%23<n>. The landing page recognises the parameter and greets the visitor with the issue they came from. Signing in with GitHub and claiming stamps the issue withhive:claim(see Contributor relay), which tells hive's own agents to leave it alone. - Bring your own agent. The comment says explicitly that the repository
is maintained with hive and welcomes agent-made contributions, and includes
a one-line "paste this to your agent" prompt carrying everything the
agent needs: repository, issue URL, relay claim URL, the DCO rule
(
git commit -s), theFixes #<n>rule, and the repository'sAGENTS.mdwhen it has one. - Open a PR that says
Fixes #<n>. The closing keyword is how the contributor lane links the PR to the claim; without it the PR is an ordinary human PR and waits for a maintainer. - Hive merges it. CI runs, the hive review runs, and a green PR from a
claimed contributor whose tier is sufficient (
require_tiersorregistry_tiers_sufficient) merges on its own.
The comment also says that hive may pick the issue up itself if nobody claims
it, and that claiming first prevents that. Note the interplay with the
default actionable priority labels: good first issue already ranks a
human-filed issue into tier 0 of kick lists
(labels-and-control-signals.md), so an
advertised issue is also one hive's own agents are likely to reach soon. The
minimum age, the per-repo cap and the release-on-start rule keep that honest:
hive never advertises something it is about to start, and it withdraws the
advertisement the moment it does start.
The scorer (src/pkg/gfi) runs over the hive's last enumeration — the
actionable issue list, which already excludes hard-suppressed, claimed and
PR-covered items. For potentially eligible candidates carrying size or
help wanted labels, the sweep reads GitHub's label timeline and checks
permissions or organization membership to verify who applied those labels.
Gates, in order; the first failure is the gfi skip reason=… logged:
| Gate | Skip reason |
|---|---|
| Pull request wearing the issue shape | pull-request |
Live claimant (hive:claim, assignee) |
claimed, assigned |
| An open PR already references the issue | linked-pr |
Hard-suppress label (needs-human, stage/045-needs-decision, a pre-045 stage/085-needs-decision, needs-spec, or the retired needs-direction / needs-decision) — always excluded, whatever exclude_labels says; needs-human next to approved-direction still excludes (#12680) |
hard-suppress:<label> |
Any hive/claimed-by-* label (always excluded) |
excluded-label:<label> |
Excluded label (kind/epic, epic, meta, meta-tracker, tracker, roadmap, security, blocked, hold, wontfix, duplicate, hive/in-progress, hive/claimed-by-*, the hive's own hive/advisory / hive/selfreport / hive/sentinel / hive/fleet reports, …) |
excluded-label:<label> |
Operations tracking issue — the body carries <!-- hive:ops-tracking --> (the promote-stable workflow stamps its emergency follow-up issue with it), or the title/body uses soak-checklist phrasing ("24h after promotion", "post-hoc soak", "promote-stable") — a maintainer's checklist, not a code change (#13267) |
ops-tracking:marker, ops-tracking:soak-checklist |
Time-gated — the body carries <!-- hive:recheck-after <RFC3339> -->, so nothing on it can be completed before the deadline |
time-gated |
Title starts with Epic, Tracking, RFC, Proposal, Umbrella, Hive Advisory Report, … after leading emoji, [tags] and punctuation are stripped, or contains the word epic, rfc, umbrella or meta |
title:<word> |
Title mentions security work (security, vulnerability, CVE-…, exploit, XSS, CSRF, RCE, injection) even without a security label |
title:security |
Younger than min_age (default 1h) |
too-fresh |
Body shorter than min_body_chars (80) or longer than max_body_chars (4000) |
body-too-short, body-too-long |
Mentions more than max_packages (2) distinct source directories |
touches-N-packages |
Fewer than min_score (2) positive signals |
score-N-below-M |
Positive signals, each worth one point and each quoted in the comment as a reason ("hive picked this issue because: …"):
- already sized small by a maintainer (
size/XS,size/S,good-first-issue,beginner,easy, …) — the label's latest application must be by a human collaborator with admin, maintain, write or triage permissions, or a member of the owning organization (unless the repo's label-driven approval policy turns org-member trust off; its trusted bots also count) - a concrete, reproducible bug report (
bug,kind/bug) - maintainers asked for help on it (
help wanted) — the same label-provenance rule as the size signal - has clear steps or acceptance criteria (two or more headings/bullets/checkboxes, or phrases like "acceptance criteria", "steps to reproduce")
- scoped to one or two packages (paths mentioned in the body)
- short, focused description (body at most half of
max_body_chars)
Size and help wanted labels last applied by bots (including hive accounts
and github-actions[bot]) earn no point. Missing provenance or a failed
timeline, permission or membership lookup also earns no point
(#14835).
Candidates come from the last enumeration, which can be many minutes old,
so immediately before labelling the sweep re-reads the issue's labels from
GitHub, re-verifies label provenance and scores again. The welcome comment's
reasons are recomputed from that fresh result. An issue that picked up
blocked, a claim or a park label in between is skipped as stale:<reason> (a failed read skips
as stale:label-read). #13267 was labelled from a snapshot taken before a
contributor's agent had returned "blocked" on it.
Per pass, each repository gets at most max_per_sweep (2) new selections, and
never more than max_per_repo (5) issues wearing the label at once — counting
issues a maintainer labelled by hand. Within a repository the highest score
wins, oldest first on ties. Issues with the good first issue label the hive
did not apply are still given the welcome comment (once) so that their
visitors get the relay pitch too.
One comment per issue, found by its first-line marker <!-- hive:gfi -->. A
later pass edits it in place when the rendered body changes; it never posts a
second one. The default template (gfi.DefaultTemplate, a Go text/template
over gfi.Vars):
<!-- hive:gfi -->
### 🌱 Good first issue — bring your own coding agent
Hi! This repository is maintained with [hive](<docs>/README.md) and welcomes contributions made **with your own AI coding agent** (Claude Code, Codex, Copilot CLI, Bob, …). <hive> picked this issue as a good place to start because:
- <reason 1>
- <reason 2>
**How to land it (no waiting on a human):**
1. **Claim it through the relay:** open <public_url>/contribute?issue=<owner>%2F<repo>%23<n> and sign in with GitHub. Claiming stamps the issue so hive leaves it to you.
2. **Fork or branch**, make the change with your agent, and sign each commit with DCO (`git commit -s`).
3. **Open a PR whose description says `Fixes #<n>`** — that closing keyword is how hive's contributor lane links the PR to your claim.
4. Hive runs CI and **merges green PRs from claimed contributors automatically**.
<details>
<summary>Paste this to your agent</summary>
```text
Fix #<n> in github.com/<owner>/<repo> (<issue url>). First open <claim url> and claim the issue through the hive relay (sign in with GitHub). Work on a fork/branch; keep the change scoped to the issue; sign every commit with DCO (git commit -s); open a PR whose description contains the line 'Fixes #<n>' so the hive's contributor lane can auto-merge it once CI is green. Read and follow <AGENTS.md url> before changing code.
```
</details>
If nobody claims it, hive may pick it up itself — claiming first prevents that. Docs: [contributor relay](<docs>/contributor-relay.md) · [contributor lane auto-merge](<docs>/hive-merge.md#contributor-lane-auto-merge) · [trust tiers](<docs>/contributor-trust-and-roles.md) · [AGENTS.md](<AGENTS.md url>).Template variables: .Repo, .Number, .Title, .IssueURL, .ClaimURL,
.RelayURL, .Docs, .Hive, .Reasons / .TopReasons (first two),
.AgentsMDURL (empty when the repository has no AGENTS.md), .AgentPrompt
and .Marker. An override set in good_first_issue.comment_template must
contain {{ .Marker }} (or the literal marker); otherwise the config is
rejected, because without the marker the sweep could not find its own
comment.
Whenever a hive agent's own request shows it working an advertised issue — a
claim, comment, label or PR request through the relay, or an agent claim on
the claims ledger — the good first issue label is removed (and help wanted
too, when this process added it), and the comment is edited to:
<!-- hive:gfi superseded=true -->
~~Good first issue~~ — **superseded**: <hive> started working on this issue itself (claimed-by-hive, <RFC3339>), so the `good first issue` label has been removed. Thanks for looking! Other issues open to new contributors are listed on the relay page: <public_url>/contributeA superseded marker is also how the sweep recognises, after a restart, an
issue it must not re-advertise; reselect_cooldown (7d) covers the same
within a process.
A labelled issue the scorer now rejects for a waiting reason — a
hard-suppress label, blocked, hold, an ops-tracking checklist or a
recheck-after deadline — has its advertisement withdrawn on the next
sweep whoever applied the labels: both good first issue and help wanted
come off, and the welcome comment is edited in place (or, when the labels
arrived without one, a single correction is posted):
<!-- hive:gfi superseded=true -->
~~Good first issue~~ — **withdrawn** by <hive>: this issue is not open to new contributors — it carries the `blocked` label, so it cannot be worked right now. The `good first issue` and `help wanted` labels have been removed (<RFC3339>). Sorry for the noise! Issues open to new contributors are listed on the relay page: <public_url>/contributeSofter rejections (too fresh, low score, an epic a maintainer labelled by
hand) leave a hand-applied label alone. Issues the enumeration filtered out
(blocked, held, parked) that still wear the label are included in the pass
for this purpose only. The event logs as gfi withdraw issue=… reason=…
and audits as gfi-withdraw.
Structured logs: gfi select issue=… score=… reasons=… claim_url=…,
gfi skip issue=… reason=… (debug), gfi release issue=… reason=claimed-by-hive,
gfi converted issue=… contributor=… kind=contributor|human (a claim through
the relay on a labelled issue), and a per-pass gfi sweep scanned=… selected=….
The same events land on the audit log as gfi-select, gfi-release,
gfi-withdraw and gfi-convert. Since-start counters (selected, released,
converted, withdrawn) appear on
Settings → Features → Good first issue curation and in the Features GET as
goodFirstIssueStats. The dashboard marks labelled issues with a 🌱 pill in
the project card listing.
good_first_issue: in hive.yaml. Every scalar key below is also on
Settings → Features → Good first issue curation, and a saved change applies on
the next pass; exclude_labels and repos are YAML-only.
| Key | Default | Meaning |
|---|---|---|
enabled |
true |
Set false to opt out. Requires dashboard.public_url or a hub-assigned dashboard URL; otherwise the sweep logs gfi skip reason=no-public-url and does nothing. |
interval |
15m |
Sweep cadence (over the last enumeration; costs GitHub calls for label-provenance checks on potentially eligible candidates and for the issues it labels). The labelled set used for release-on-claim is refreshed every cycle regardless. |
max_per_repo |
5 |
Issues wearing the label per repository at once. |
max_per_sweep |
2 |
New selections per repository per pass. |
min_age |
1h |
Minimum issue age (long enough that a reporter has finished editing). |
min_body_chars / max_body_chars |
80 / 4000 |
Body length bounds. |
max_packages |
2 |
Distinct source directories an issue may mention. |
min_score |
2 |
Positive signals required. |
reselect_cooldown |
168h |
A released issue stays out this long. |
exclude_labels |
built-in list | Replaces the built-in exclusions; hard-suppress labels (needs-human, stage/045-needs-decision, stage/085-needs-decision, needs-spec, retired spellings) and hive/claimed-by-* are always excluded. |
repos |
all watched | Restrict to these owner/repo slugs. |
docs_url |
hive's src/docs on v5 |
Base URL the comment links docs under. |
comment_template |
gfi.DefaultTemplate |
Override; must contain {{ .Marker }}. |
The same invitation reaches people who skip the issue and open a PR directly. When a pull request is opened by a human whose GitHub author_association is FIRST_TIME_CONTRIBUTOR or FIRST_TIMER, the hive leaves one comment (marker <!-- hive:first-timer-welcome -->) on it that thanks them and explains they can run their own hive — we call them clankers — and let it do the contribution loop (claim, PR, review fixes, rebase) for them. The comment lists the concrete advantages: a contributor profile (/contribute/dossier/<login>) and leaderboard place (/contribute/leaderboard) on this hive's dashboard, trust-tier progression (newcomer → contributor → trusted) that unlocks contributor-lane auto-merge, the hive handling failing checks, reviewer asks, rebases and PR adoption while they are offline, and faster turnaround. It links the /contribute landing page, contributor-relay.md and contributor-trust-and-roles.md.
Rules, mirroring the good-first-issue comment:
- Once per author per repository. The sweeper remembers who it welcomed, and after a restart it looks for the marker on the author's earlier PRs in the repo before posting again.
- Humans only. Bots, PRs carrying
author/clankerorauthor/hive, PRs the hive attributes to itself, drafts and logins already known as relay contributors (or with a trust tier) are skipped. - Silent without a public dashboard URL — the links need
dashboard.public_urlor a hub-assigned URL. - Every post is audited as
first-timer-welcome.
Key (governor.first_timer_welcome.*) |
Default | Meaning |
|---|---|---|
enabled |
true |
Set false to opt out. |
template_path |
firsttimer.DefaultTemplate |
Path to a text/template file over firsttimer.Vars; must contain {{ .Marker }}. |
- Contributor relay — what a contributor sets up and how claiming works.
- Hive merge — contributor lane auto-merge — the
Fixes #n, tier and DCO requirements for the merge. - Contributor trust tiers and roles.
- Labels and control signals — where
good first issuesits among hive's labels.