spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

Fix issues being auto-closed despite human activityBrowse files
The sweep script was closing issues based solely on when a lifecycle label
was applied, ignoring any human comments posted after the label. This caused
active issues (like #11792) to be closed even when users responded to the
stale warning.

Three changes:

1. Teach the triage bot about `stale` and `autoclose` labels so it removes
   them when a human comments on the issue.

2. Add a safety net in `closeExpired()` that checks for non-bot comments
   posted after the lifecycle label was applied — if any exist, skip closing.

3. Extend the 10-upvote protection (which previously only applied to
   enhancements) to all issue types, in both `markStale()` and
   `closeExpired()`.

Fixes #16497

## Test plan

Trace through scenarios manually:
- Issue with stale label + human comment after → triage removes label;
  sweep skips even if triage hasn't run yet (safety net)
- Issue with stale label + no human comment → closes as before
- Issue with 10+ upvotes of any type → never marked stale or closed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Chris Lloyd authored on Feb 17, 2026 parent 32c7ff2 · commit f0970ee09da6
2 changed files+25 -6compared with 32c7ff2
M.github/workflows/claude-issue-triage.yml
Mscripts/sweep.ts
@@ -45,7 +45,7 @@
4545 ALLOWED LABELS — you may ONLY use labels from this list. Never invent new labels.
4646
4747 Type: bug, enhancement, question, documentation, duplicate, invalid
48- Lifecycle: needs-repro, needs-info
48+ Lifecycle: needs-repro, needs-info, stale, autoclose
4949 Platform: platform:linux, platform:macos, platform:windows, platform:wsl, platform:ios, platform:android, platform:vscode, platform:intellij, platform:web, platform:aws-bedrock
5050 API: api:bedrock, api:vertex
5151
@@ -85,10 +85,12 @@
8585 **If EVENT is "issue_comment" (comment on existing issue):**
8686
8787 3. Evaluate lifecycle labels based on the full conversation:
88+ - If the issue has `stale` or `autoclose`, remove the label — a new human comment means the issue is still active:
89+ `gh issue edit ${{ github.event.issue.number }} --remove-label "stale" --remove-label "autoclose"`
8890 - If the issue has `needs-repro` or `needs-info` and the missing information has now been provided, remove the label:
8991 `gh issue edit ${{ github.event.issue.number }} --remove-label "needs-repro"`
9092 - If the issue doesn't have lifecycle labels but clearly needs them (e.g., a maintainer asked for repro steps or more details), add the appropriate label.
91- - Comments like "+1", "me too", "same here", or emoji reactions are NOT the missing information. Only remove labels when substantive details are actually provided.
93+ - Comments like "+1", "me too", "same here", or emoji reactions are NOT the missing information. Only remove `needs-repro` or `needs-info` when substantive details are actually provided.
9294 - Do NOT add or remove category labels (bug, enhancement, etc.) on comment events.
9395
9496 GUIDELINES:
@@ -70,11 +70,8 @@
7070 );
7171 if (alreadyStale) continue;
7272
73- const isEnhancement = issue.labels?.some(
74- (l: any) => l.name === "enhancement"
75- );
7673 const thumbsUp = issue.reactions?.["+1"] ?? 0;
77- if (isEnhancement && thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
74+ if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
7875
7976 const base = `/repos/${owner}/${repo}/issues/${issue.number}`;
8077
@@ -109,6 +106,10 @@
109106 for (const issue of issues) {
110107 if (issue.pull_request) continue;
111108 if (issue.locked) continue;
109+
110+ const thumbsUp = issue.reactions?.["+1"] ?? 0;
111+ if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
112+
112113 const base = `/repos/${owner}/${repo}/issues/${issue.number}`;
113114
114115 const events = await githubRequest<any[]>(`${base}/events?per_page=100`);
@@ -120,6 +121,22 @@
120121
121122 if (!labeledAt || labeledAt > cutoff) continue;
122123
124+ // Skip if a non-bot user commented after the label was applied.
125+ // The triage workflow should remove lifecycle labels on human
126+ // activity, but check here too as a safety net.
127+ const comments = await githubRequest<any[]>(
128+ `${base}/comments?since=${labeledAt.toISOString()}&per_page=100`
129+ );
130+ const hasHumanComment = comments.some(
131+ (c) => c.user && c.user.type !== "Bot"
132+ );
133+ if (hasHumanComment) {
134+ console.log(
135+ `#${issue.number}: skipping (human activity after ${label} label)`
136+ );
137+ continue;
138+ }
139+
123140 if (DRY_RUN) {
124141 const age = Math.floor((Date.now() - labeledAt.getTime()) / 86400000);
125142 console.log(`#${issue.number}: would close (${label}, ${age}d old) — ${issue.title}`);