-
Notifications
You must be signed in to change notification settings - Fork 75
docs: correct issue/PR lifecycle table, fix reminder dedupe #1921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a51e79b
b3cbc7f
8594ed6
343db27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,11 +62,14 @@ jobs: | |
| // Target 14-29 day window (before stale bot at 30 days) | ||
| if (daysInactive < 14 || daysInactive >= 30) continue; | ||
|
|
||
| // Check if we already left a reminder | ||
| const { data: comments } = await github.rest.issues.listComments({ | ||
| // Check if we already left a reminder. Paginate: an unpaginated | ||
| // call returns only the 30 oldest comments, so on a busy PR the | ||
| // reminder falls off page one and a duplicate goes out. | ||
| const comments = await github.paginate(github.rest.issues.listComments, { | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: pr.number, | ||
| per_page: 100, | ||
| }); | ||
| const alreadyReminded = comments.some(c => | ||
| c.user.type === 'Bot' && c.body.includes('inactive for') | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor — Dedupe marker is a bare literal, now load-bearing for a documented guarantee The key Separately on this line: Blast radius: Latent. Requires a future edit to the message text to trigger, but the trigger is an innocuous-looking copy edit and the failure is silent and recurring. Fix: Hoist a hidden marker — |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -197,17 +197,32 @@ We welcome the use of AI tools (e.g., GitHub Copilot, ChatGPT, Claude) to help y | |
|
|
||
| Automated bots manage the lifecycle of issues and pull requests: | ||
|
|
||
| | Day | Action | | ||
| |-----|--------| | ||
| | 0 | Issue/PR opened, `needs-triage` label added to issues | | ||
| | 14 | Inactive PRs receive a reminder comment | | ||
| | 30 | Inactive PRs marked `lifecycle/stale` | | ||
| | 44 | Stale PRs auto-closed | | ||
| | 60 | Inactive issues marked `lifecycle/stale` | | ||
| | 74 | Stale issues auto-closed | | ||
| | 90+ | Closed issues/PRs locked | | ||
|
|
||
| **To prevent auto-close:** Add the `lifecycle/frozen` label. PRs with `do-not-merge` are also exempt. | ||
| | When | Action | | ||
| |------|--------| | ||
| | On open | `needs-triage` label added to issues | | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor — needs-triage row omits that the label is removed automatically
Blast radius: Doc-only. The row is accurate as far as it goes; it just names an automation step whose immediate automated reversal is absent. Fix: "| On open | |
||
| | 14 days of PR inactivity | PR author receives a reminder comment (once per PR) | | ||
| | 30 days of PR inactivity | PR marked `lifecycle/stale` | | ||
| | 30 days after being marked stale | Stale PR auto-closed | | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 Nitpick — Two rows share identical "When" cell text :205 and :207 both read "30 days after being marked stale", disambiguated only by row adjacency. Blast radius: Cosmetic. Fix: "30 days after the PR is marked stale" / "30 days after the issue is marked stale". |
||
| | 90 days of issue inactivity | Issue marked `lifecycle/stale` | | ||
| | 30 days after being marked stale | Stale issue auto-closed | | ||
| | 90 days of inactivity while closed | Issue/PR thread locked | | ||
|
|
||
| These are **inactivity windows, not days since opening**: any comment or update | ||
| restarts the applicable counter — including the day-14 reminder itself, which is | ||
| a comment and so pushes the stale mark out. | ||
|
|
||
| The day-14 reminder is the exception: it is posted **at most once per pull | ||
| request**. The workflow skips any PR that already carries a reminder, so | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "At most once per pull request" is very slightly stronger than the workflow guarantees. The
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed and fixed in
"At most once per pull request" was too strong. It now reads "normally posted only once per pull request", with a clause naming the first-page limitation as the reason a second can occur. I softened the prose rather than adding
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update — folded the workflow fix in rather than documenting the defect, so this reply supersedes my previous one.
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner, repo: context.repo.repo,
issue_number: pr.number, per_page: 100,
});One correction to the suggested fix:
Thanks for catching this — the original wording was mine, written this morning while fixing the opposite error (the table implied the reminder recurred), and I overcorrected into an absolute the code did not support. |
||
| replying and later going quiet again does not produce a second nudge — the next | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor — "the day-30 stale mark" reintroduces the absolute-day framing line 210 just warned against Substantively correct in its own scenario — after reply-then-quiet the reminder genuinely will not re-fire, so the stale mark is next. But "day-30" reads as a date three lines after the paragraph telling readers these are not days since opening. If the contributor does not reply, the day-14 reminder itself bumps Blast radius: Doc-only; a reader gets two different implied dates from adjacent paragraphs. Fix: "— the next automated action is the stale mark, 30 days after that reply." |
||
| automated action on that PR is the day-30 stale mark. | ||
|
|
||
| Each bot runs on a daily schedule, so an action lands on its next scheduled run | ||
| rather than the moment a threshold is crossed — expect up to ~24 hours of lag. | ||
|
|
||
| **To stay out of the stale process entirely:** Add the `lifecycle/frozen` label. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor — "stay out of the stale process entirely" overclaims — no label exempts locking
Also omitted here: both Blast radius: Doc-only, but it is the one place in the new section where a reader can be led to expect protection that does not exist. Fix: Narrow the heading to "To stay out of stale-marking and auto-close:", note that exempt items are also skipped by the day-14 reminder, and add that no label exempts a closed thread from the 90-day lock. |
||
| Exempt items are never marked `lifecycle/stale` in the first place, not merely | ||
| spared from closing. `good first issue` also exempts issues, and `do-not-merge` | ||
| exempts pull requests. | ||
|
coderabbitai[bot] marked this conversation as resolved.
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| ### Claiming an Issue | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Minor — Inline comment asserts an unreachable failure as observed behavior
"so on a busy PR the reminder falls off page one and a duplicate goes out" reads as a described incident. Measured across all 1363 PRs in this repo, the maximum issue-comment count is 20 (#1915) — no PR has ever crossed 30.
issues.listCommentsreturns issue comments only; review comments live atpulls/N/comments, which is why GitHub'scomments:>30search qualifier (91 PRs) overcounts for this call. Unreachability is doubled: a duplicate needs >30 issue comments accumulated after the reminder — which itself resetsupdated_at— plus 14 more days of silence. Production history is 2 reminders ever posted (#485, #676), zero duplicates.Blast radius: None at runtime. The fix is correct hardening and is cost-neutral (with max 20 comments,
paginateissues exactly one request — identical to the pre-change call count). The concern is the durable comment describing a failure mode that has never been reachable here.Fix: Reframe defensively rather than as an incident report, e.g. "an unpaginated call returns only the 30 oldest comments; paginating removes the bound so the guarantee holds regardless of comment volume."