A claim on a curated issue waits until a maintainer seat happens to run:
#19143, 2026-09-23 15:40Z: a first-time contributor claimed it. The first reply, the assignment, came 27.5 h later and said "your comment reached nobody for a day".
#19143 again, 2026-09-25 07:59Z: a second first-timer claimed it, 13 h after the assignment. The reply came 2 h later, after the assignee's PR had opened.
#19140, 2026-09-24 18:20Z: a claim, then a withdrawal 16 minutes later ("I can't self-assign it"), with no reply in between.
Hacktoberfest opens on 2026-10-01 (#18985). In October 2025, 20 people opened 60 external PRs.
The Problem
The claim rule is CONTRIBUTING §3 item 3 (#19195): the first claimant is assigned, the first approve-worthy PR wins, and assignment protects your time. It only protects the claimant if they hear back in time.
A seat runs when the operator starts one. Heartbeats are off on purpose (daytime noise), and @tobiu ruled on 2026-09-24 that a 20–30 min heartbeat would be too slow anyway. neo-agent-brain#468 took the heartbeat path and was closed on that ruling.
@tobiu's rule from 2025 for a late claimant is to offer a different ticket, because someone else has started.
Maintainers are not online around the clock (@tobiu, 2026-09-25). The operator sleeps about 8 h, and rate limits keep AI seats from running 24/7. So every step that needs a maintainer, confirming an assignment included, waits for the next session, and that can be many hours away. A workflow is the one participant that is always there, and on a public repository it costs no seat time.
The Architectural Reality
No workflow in .github/workflows/ triggers on issue_comment today.
Siblings: prevent-reopen.yml answers an issue event with inline actions/github-script@v9. CI logic that carries a spec lives in buildScripts/util/check-*.mjs, with specs in test/playwright/unit/buildScripts/.
An issue_comment run uses the workflow file from the default branch (dev), holds a write token, and reads untrusted text.
Curated means good first issue or help wanted. Only neomjs/neo has open good first issues (6 on 2026-09-25).
The Fix
.github/workflows/claim-responder.yml, on issue_comment[created], for issues (not PRs) that carry either label. It replies at most once per (issue, user), and only to a comment with claim intent:
State when the claim arrives
The reply
free: no assignee, no open linked PR, no earlier claim
"you're first in line and can start now; a maintainer confirms the assignment when one is online, which can take a while"
an earlier claimant, still unassigned
who asked first, plus alternatives
assigned
the assignee, plus alternatives
an open PR resolves it
the PR, plus alternatives
Through a maintainer gap, the first-in-line reply is the claimant's protection. Later claimants are pointed elsewhere, so the first one starts at once instead of waiting hours for an assignment. The assignment confirms it afterwards.
Alternatives come from the live no:assignee -linked:pr set for the same label, excluding this issue. They must not give everyone the same short list; that funnel is what produced #19143.
The workflow never assigns. Assignment stays with a seat, which is what screens out spray accounts. An account that sprays claim templates across repositories gets skipped, and the next human is confirmed. The known cost: during a gap, a spray account that claims first holds the ticket until a seat screens it. That hold ends at the next session, and the workflow offers everyone else alternatives in the meantime.
Requirements from @neo-opus-ada, the #18985 steward, 2026-09-24:
Claim intent, once. Patterns such as "work on", "claim", "assign", "take this", /assign, matched on the comment without its quoted lines. No reply to questions, thanks, maintainers, bots or the assignee.
Injection-safe.actions/github-script, reading the body from context.payload, never ${{ github.event.comment.body }} in a run: step. Check out only the default branch. permissions: issues: write, plus pull-requests: read only if the linked-PR read measurably needs it.
No promise the workflow can't keep. "A maintainer confirms" names no time, and the reply says a confirmation can take a while, so the claimant starts instead of waiting.
The intent classifier and the reply choice go into one pure module beside the check-*.mjs siblings, with a spec. The fixtures come from real threads: the three claims above, plus non-claims that must not trigger. The most important non-claim is the assignee's thank-you on #19143, which contains "work on the fix" and quotes "it's yours".
one clause in CONTRIBUTING §3 item 3: a claim gets an automatic reply that says where you stand, and first in line may start before a maintainer confirms (wording agreed with @neo-opus-ada, whose sentence it extends)
the spec, plus the first reply after merge
Acceptance Criteria
A claim by a non-member on a curated issue gets one reply, matching the table, within a minute.
The first-in-line reply says the claimant can start now and that the confirmation can take a while, and it names no time.
Questions, thanks, quoted text, the assignee's own comments, and maintainer and bot comments get no reply. The spec covers each case, using the fixtures above.
At most one reply per (issue, user), across edits and re-runs.
The workflow never assigns, never interpolates the comment into a shell step, and checks out only dev. Its permissions are only what it needs, and the PR says why each one is there.
Alternatives come from the live query, exclude the current issue, and don't send every redirect to the same ticket.
CONTRIBUTING §3 item 3 has the clause from the ledger.
Post-merge, flagged: the first real claim after merge gets its reply, linked here.
Out of Scope
Assigning.
The PR-side case, a non-assignee's PR against an assigned issue (the operator's "day 5" gap). It gets a leaf of its own if it recurs.
Other repositories. When a second repository curates good first issues, lift the module into neo-agent-skills' reusable workflows.
Avoided Traps
A /claim auto-assign bot. It hands first-timer issues to whoever sprays claims fastest.
The heartbeat path (neo-agent-brain#468). Heartbeats are disabled on purpose, and too slow even when they run.
Replying to every comment. A reply to a question or a spam comment amplifies the noise that turning heartbeats off removed.
A spray screen inside the workflow (account age, fork count). A real first-timer's account is often new too, so the screen stays with a seat.
"We'll assign you soon." No seat is always online, so the only honest time is none.
Related
#18985 (parent) · #19195 (the claim rule) · neo-agent-brain#468 (closed predecessor) · #19201 (closed as not planned: contributors find good first issues through GitHub's own issue lists, which show the assignee, not through CONTRIBUTING's link)
Live latest-open sweep: the latest 20 open neomjs/neo issues at 2026-09-25T10:14:56Z, plus a live org-wide claim search. No equivalent.
A2A in-flight sweep: the last 30 messages, all read-states, at 10:15Z. No claim on this scope.
MC sweep: query_raw_memories("contributor comment reached nobody for a day, claimant waited hours for a reply on a good first issue, claimed an issue already assigned"), 6 results. They are the 2026-09-24 design turns this ticket carries forward: the heartbeat ruling and the steward's three requirements. No decision against it.
Own-assignment sweep: 9 open, none on this surface.
Decision Record impact: none
Origin Session ID: d2d30528-b6fe-423b-86ce-ab945396a201
Retrieval Hint: "claim responder issue_comment good first issue reply within seconds no heartbeat"
Authored by 🖖 Grace · @neo-opus-grace · Claude Opus 5.5 · Claude Code
tobiu referenced in commit 988f3e7 - "feat(ci): a claim on a curated issue gets an automatic reply saying where the claimant stands (#19202) (#19211) on Sep 25, 2026, 2:04 PM
Context
A claim on a curated issue waits until a maintainer seat happens to run:
#19143, 2026-09-23 15:40Z: a first-time contributor claimed it. The first reply, the assignment, came 27.5 h later and said "your comment reached nobody for a day".#19143again, 2026-09-25 07:59Z: a second first-timer claimed it, 13 h after the assignment. The reply came 2 h later, after the assignee's PR had opened.#19140, 2026-09-24 18:20Z: a claim, then a withdrawal 16 minutes later ("I can't self-assign it"), with no reply in between.Hacktoberfest opens on 2026-10-01 (#18985). In October 2025, 20 people opened 60 external PRs.
The Problem
The Architectural Reality
.github/workflows/triggers onissue_commenttoday.prevent-reopen.ymlanswers an issue event with inlineactions/github-script@v9. CI logic that carries a spec lives inbuildScripts/util/check-*.mjs, with specs intest/playwright/unit/buildScripts/.issue_commentrun uses the workflow file from the default branch (dev), holds a write token, and reads untrusted text.good first issueorhelp wanted. Onlyneomjs/neohas open good first issues (6 on 2026-09-25).The Fix
.github/workflows/claim-responder.yml, onissue_comment[created], for issues (not PRs) that carry either label. It replies at most once per (issue, user), and only to a comment with claim intent:Through a maintainer gap, the first-in-line reply is the claimant's protection. Later claimants are pointed elsewhere, so the first one starts at once instead of waiting hours for an assignment. The assignment confirms it afterwards.
Alternatives come from the live
no:assignee -linked:prset for the same label, excluding this issue. They must not give everyone the same short list; that funnel is what produced#19143.The workflow never assigns. Assignment stays with a seat, which is what screens out spray accounts. An account that sprays claim templates across repositories gets skipped, and the next human is confirmed. The known cost: during a gap, a spray account that claims first holds the ticket until a seat screens it. That hold ends at the next session, and the workflow offers everyone else alternatives in the meantime.
Requirements from @neo-opus-ada, the #18985 steward, 2026-09-24:
/assign, matched on the comment without its quoted lines. No reply to questions, thanks, maintainers, bots or the assignee.actions/github-script, reading the body fromcontext.payload, never${{ github.event.comment.body }}in arun:step. Check out only the default branch.permissions: issues: write, pluspull-requests: readonly if the linked-PR read measurably needs it.The intent classifier and the reply choice go into one pure module beside the
check-*.mjssiblings, with a spec. The fixtures come from real threads: the three claims above, plus non-claims that must not trigger. The most important non-claim is the assignee's thank-you on#19143, which contains "work on the fix" and quotes "it's yours".Contract Ledger
Acceptance Criteria
dev. Its permissions are only what it needs, and the PR says why each one is there.Out of Scope
neo-agent-skills' reusable workflows.Avoided Traps
/claimauto-assign bot. It hands first-timer issues to whoever sprays claims fastest.Related
#18985 (parent) · #19195 (the claim rule) · neo-agent-brain#468 (closed predecessor) ·
#19201(closed as not planned: contributors find good first issues through GitHub's own issue lists, which show the assignee, not through CONTRIBUTING's link)Live latest-open sweep: the latest 20 open
neomjs/neoissues at 2026-09-25T10:14:56Z, plus a live org-wideclaimsearch. No equivalent. A2A in-flight sweep: the last 30 messages, all read-states, at 10:15Z. No claim on this scope. MC sweep:query_raw_memories("contributor comment reached nobody for a day, claimant waited hours for a reply on a good first issue, claimed an issue already assigned"), 6 results. They are the 2026-09-24 design turns this ticket carries forward: the heartbeat ruling and the steward's three requirements. No decision against it. Own-assignment sweep: 9 open, none on this surface.Decision Record impact: none
Origin Session ID: d2d30528-b6fe-423b-86ce-ab945396a201 Retrieval Hint: "claim responder issue_comment good first issue reply within seconds no heartbeat"
Authored by 🖖 Grace ·
@neo-opus-grace· Claude Opus 5.5 · Claude Code