Skip to content

chore(contributing): make issue claims visible and expire them - #859

Open
s-annam wants to merge 1 commit into
mainfrom
chore/claim-visibility-and-expiry
Open

chore(contributing): make issue claims visible and expire them#859
s-annam wants to merge 1 commit into
mainfrom
chore/claim-visibility-and-expiry

Conversation

@s-annam

@s-annam s-annam commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Claim state for an issue lived only in the assignee field, which is invisible in every channel a contributor browses. This puts it in a label, documents the protocol, and expires claims that go quiet.

No product code is touched — CONTRIBUTING.md and one new workflow.

Why

On 2026-08-16, four PRs arrived for two issues:

Issue PRs Assigned at the time?
#681 #853, #854 Yes — for 17 days
#832 #840, #855 No

The #681 case is the interesting one. The assignment wasn't missing; @rohithgollapalli self-assigned on 2026-07-30. Two contributors still built it independently, because:

  • gh issue list prints labels, not assignees. The default table is number / state / title / labels / updated. A contributor scanning the backlog from the CLI sees no claim signal at all.
  • On the web list the assignee is a small right-margin avatar, easy to miss and absent from some search views.
  • Both collisions were on good first issue. That label selects for newcomers and for tooling that scans the backlog — precisely the population least likely to open an issue and read its sidebar before starting. One of the four PRs arrived on manus/* branches, which points at agent-driven contribution; that reads labels and issue text, not avatars.
  • CONTRIBUTING.md had no claim protocol. 193 lines on setup, branches, commits, PRs, tests, style, filing and the board — nothing on how to pick up work. The only assign match in the file is an env-var assignment.

Storing the claim where nobody looks is the whole defect. Three contributors lost an evening to it in one day.

What changes

1. status:claimed label — already created on the repo and applied to #681 and #832. It rides alongside the assignee and appears inline in every list view:

832  OPEN  [parser] skills — single-letter language tokens…  bug, good first issue, ux:parsing, status:claimed

That line is what both contributors saw before; it now carries the claim.

2. CONTRIBUTING.md → "Claiming an issue" — check the label before starting, comment to claim, a maintainer assigns and labels, what happens when a claim lapses. Also states that a maintainer-initiated assignment is a request, not an obligation.

3. .github/workflows/stale-claims.yml — daily job releasing a claim after 7 days with no linked PR and no activity.

A claim that never expires is worse than no claim: it reads as abandoned, so people route around it and the label stops meaning anything. A 17-day-old claim is exactly what this incident ran into.

The job is deliberately narrow:

  • never closes an issue, never edits a body, never changes a milestone
  • never touches a claim with an open linked PR — the PR is the work, however quiet the issue went
  • any activity resets the clock, so a one-line "still on it" holds a claim indefinitely
  • comments whenever it releases one, saying what happened and inviting re-claim
  • everything it does is undone by re-assigning and re-adding the label
  • cleans up the inconsistent status:claimed-with-no-assignee state too

workflow_dispatch takes a dry_run input so its selection can be inspected before the cron is trusted.

Verification

  • npm run verify green (pre-push gate): typecheck, lint, gates, tests, build, fallow.
  • fallow clean on both changed files.
  • Workflow YAML parses; the embedded github-script body passes node --check.
  • Label behaviour confirmed live against gh issue list --label "good first issue" — see the table above.

The scheduled job has not run yet. Recommend one workflow_dispatch with dry_run: true after merge to confirm its selection before the first real cron; it writes nothing in that mode.

Deliberately not included

  • Removing good first issue while claimed. It attacks the magnet more directly but churns labels and loses the newcomer-friendly signal on an issue that may be released a week later. Worth revisiting if collisions continue.
  • Auto-assign on a "I'll take this" comment. Wanted eventually, but it needs intent parsing, and a wrong auto-assign is more annoying than a missing one.

Follow-up

@rohithgollapalli's claim on #681 has been released and they've been notified on the issue; #681 and #832 are now assigned to @shubhransh-gupta, who has approved work on both.

Two contributors independently implemented #681 while it was assigned to a
third, and two more collided on #832 the same day. The assignment was not
missing — it had been in place for 17 days. It was invisible.

`gh issue list` prints labels and not assignees, and the web list renders the
assignee as a small right-margin avatar. Both collisions landed on issues
labelled `good first issue`, which is the filter used by exactly the people
least likely to open an issue and read its sidebar first. Claim state was
being stored in a field nobody browsing the backlog can see.

So put the claim in the channel people actually read:

- `status:claimed` (created on the repo) rides alongside the assignee and
  shows up inline in every list view, including `gh issue list`.
- CONTRIBUTING.md gains a "Claiming an issue" section — check the label before
  starting, comment to claim, and what happens when a claim lapses. The repo
  had no claim protocol documented at all.
- `stale-claims.yml` releases a claim after 7 days with no linked PR and no
  activity, because a claim that never expires reads as abandoned and people
  route around it, which is the failure this is meant to prevent.

The job is deliberately narrow: it never closes an issue, never edits a body,
and never touches a claim with an open linked PR. Any activity resets the
clock, so a one-line "still on it" holds a claim indefinitely. It comments
whenever it releases one, and everything it does is undone by re-assigning.
`workflow_dispatch` takes a `dry_run` input for checking its selection before
trusting the cron.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying offlinecv with  Cloudflare Pages  Cloudflare Pages

Latest commit: 56a683f
Status: ✅  Deploy successful!
Preview URL: https://77ff5f4a.offlinecv.pages.dev
Branch Preview URL: https://chore-claim-visibility-and-e.offlinecv.pages.dev

View logs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant