Issueの誤自動クローズを防ぐ、トリアージボットとスウィープの二重安全策

anthropics/claude-code

Issueに人間がコメントしても自動クローズされてしまうバグを修正するため、トリアージワークフローとスウィープスクリプトの両方に防護処理が追加されました。人間のアクティビティを確実に検出する二重の安全策により、アクティブなIssueの誤クローズを防ぎます。

背景

#16497 として報告された通り、「60日間の非アクティブ」を理由に大量のIssueが誤ってクローズされる問題が発生していました。ユーザーが stale 警告に「まだ関連性がある」とコメントしても、その後も自動クローズが実行されるという状況です。

問題の根本原因は3つあります。第一に、トリアージボット(claude-issue-triage.yml)が stale および autoclose ラベルの存在を認識しておらず、人間がコメントしてもこれらのラベルを除去する処理がありませんでした。第二に、sweep.tscloseExpired() 関数がライフサイクルラベルの付与日時と経過時間しか確認せず、ラベル付与後に人間がコメントしたかどうかを無視していました。第三に、10件以上のアップボートによる保護がenhancementラベルのIssueにのみ適用されており、人気の高いバグ報告でも自動クローズされる可能性がありました。

#11792 は、stale警告の後に3件の人間コメントがあったにもかかわらず自動クローズされた具体例として挙げられています。

技術的な変更

変更は claude-issue-triage.ymlscripts/sweep.ts の2ファイルにわたり、それぞれ独立した防護層を構成しています。

トリアージワークフローへの stale/autoclose ラベル認識の追加では、まず許可ラベルリストに staleautoclose を追加しました。

# 変更前
Lifecycle: needs-repro, needs-info

# 変更後
Lifecycle: needs-repro, needs-info, stale, autoclose

さらに、issue_comment イベント処理のプロンプト指示に、人間コメント時にこれらのラベルを除去する命令が追加されました。

# 追加された指示
- If the issue has `stale` or `autoclose`, remove the label — a new human comment means the issue is still active:
  `gh issue edit ${{ github.event.issue.number }} --remove-label "stale" --remove-label "autoclose"`

あわせて、needs-repro / needs-info ラベルの除去条件に関するコメントも「実質的な詳細が提供された場合のみ needs-repro または needs-info を除去する」と明確化され、stale/autoclose との混同を防いでいます。

sweep.ts への安全ネット処理は2点の変更で構成されます。closeExpired() に、ラベル付与後の人間コメント存在チェックが追加されました。

// 追加されたコード
const comments = await githubRequest<any[]>(
  `${base}/comments?since=${labeledAt.toISOString()}&per_page=100`
);
const hasHumanComment = comments.some(
  (c) => c.user && c.user.type !== "Bot"
);
if (hasHumanComment) {
  console.log(
    `#${issue.number}: skipping (human activity after ${label} label)`
  );
  continue;
}

また、アップボート保護については、markStale()closeExpired() の両方で isEnhancement による条件分岐が削除され、すべてのIssueタイプに一律に適用されるようになりました。

// 変更前(markStale内)
const isEnhancement = issue.labels?.some(
  (l: any) => l.name === "enhancement"
);
const thumbsUp = issue.reactions?.["+1"] ?? 0;
if (isEnhancement && thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;

// 変更後
const thumbsUp = issue.reactions?.["+1"] ?? 0;
if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;

設計判断

トリアージワークフローと closeExpired() の両方に保護処理を置く「二重防御」の設計が採用されました。

理想的にはトリアージワークフローがラベルを除去するため、closeExpired() が人間コメントを確認する必要はないはずです。しかし、スウィープが実行されるタイミングとトリアージボットがコメントを処理するタイミングの間に競合状態が発生し得ます。人間がコメントした直後にスウィープが走った場合、トリアージボットがまだラベルを除去していなければ誤クローズが起きます。PR本文でも「The triage workflow should remove lifecycle labels on human activity, but check here too as a safety net.」と明記されており、スウィープ側のチェックは意図的な安全ネットとして位置付けられています。

アップボート保護の全タイプ拡張は、バグ報告を含むすべての人気Issueを平等に保護するという方針の明確化です。enhancementに限定していた元の実装は、バグ報告への適用漏れという非対称性を生んでいました。

まとめ

トリアージボットへのラベル認識追加と closeExpired() の安全ネットにより、競合状態を含む様々なタイミングで人間のアクティビティを見逃さない設計が実現しました。人間コメントを「Botでないユーザーのコメント」として定義する単純な判定が、複雑なワークフロー間の同期問題をシンプルに解決しています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
e10b8dc8

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の構成が記事全体に適用されており、リード文、背景、技術詳細、設計判断、まとめの各要素が明確に配置されています。模範的な構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```言語:ファイルパス)およびGitHubのIssue/PRへのリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

GitHub ActionsワークフローやTypeScriptに関する技術的な内容が、専門知識を持つエンジニアを対象として適切に記述されています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論で構成され、各段落はトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が遵守されており、非常に高い可読性を実現しています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されているコードは、提供されたDiffの内容と完全に一致しており、ファイルパスも正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「トリアージボット」「スウィープスクリプト」「競合状態」など、PRで用いられている技術用語が正確かつ適切な文脈で使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

変更の背景、原因、解決策についての説明は、PR DescriptionとDiffの内容に完全に裏付けられており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(問題の原因、具体例、解決策の意図など)は、提供されたPR情報に基づいており、ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#26360)、Issue番号(#16497, #11792)などの数値・固有名詞はすべて正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRの主題「人間のアクティビティがあるにもかかわらず自動クローズされる問題の修正」を的確に反映し、「二重安全策」という解決策の核心を加えています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事はPR情報に記載されている事実のみに基づいており、バージョン情報やリリース日程といった外部知識の追記はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「問題が発生していました」といった過去形の表現がPRの時間軸と一致しており、時間表現の歪曲はありません。