Communitygithub.com

hmisaki/voicebox

リリース前のオープンPRキューをトリアージ(優先順位付け)するスキルです。すべてのオープンPRを「マージ必須」「候補」「置換」「延期」に分類し、トリアージドキュメントを作成し、マージループを最初から最後まで実行します。一人のメンテナーがインバウンドのバックログを一気にクリアする、リリース前の「PRスピードラン」用に設計されています。

voicebox とは?

このスキルは、リリース前に蓄積したオープンPRのバックログを体系的に処理するためのものです。`gh` CLIを使用してPRのメタデータ(サイズ、マージ可能性、変更ファイルなど)を収集し、各PRを「Tier 1(マージ)」「Tier 2(候補)」「Supersede(置換)」「Defer(延期)」の4段階に分類します。トリアージの結果は `<VERSION>_PR_TRIAGE.md` という追跡・再開可能なドキュメントとして記録され、実際のマージ作業(リベース、スカッシュマージ、フォローアップの作成、置換PRのクローズなど)を効率的に進めます。特に、古いブランチを `git diff main..HEAD` でレビューする落とし穴や、リベースせずにスカッシュマージすると中間のコミットが逆適用される危険性など、実践的な注意点が豊富に含まれています。このスキルは `draft-release-notes` や `release-bump` と組み合わせて使用し、トリアージ後にリリースノートの下書き、リリースバンプへと進むことを想定しています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/hmisaki/voicebox/tree/HEAD/.agents/skills/triage-prs

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

PR のトリアージ

目標

オープンPRのバックログを、一回の集中セッションで出荷可能なマージセットに変える。追跡可能で再開可能な計画(<VERSION>_PR_TRIAGE.md)を作成し、それに沿って作業を進める。つまり、必要な場合はリベースし、分離安全なバッチでマージし、マージ後のフォローアップを適用し、置き換えられた、または部分的にしか適用できないPRを、その作者にクレジットを与えてクローズする。

このスキルは draft-release-notes および release-bump と対になります。まずトリアージを行い、次に新しい main に対してリリースノートの下書きを作成し、最後にリリースをカットします。

使用するタイミング

  • マイナーまたはメジャーリリースの前に、10件以上のオープンPRが蓄積されている場合
  • 何がランディングされるのかというストーリーを見失わずに、マージのブロックを解除したい場合
  • すべてのPRを深くレビューする時間はないが、クリティカルなサブセットを迅速にランディングさせる必要がある場合

前提条件

  • リポジトリに対して認証済みの gh CLI
  • PRレビューのための専用ワークツリー(main をコントリビューターブランチのチェックアウトで汚染しないため)
  • ターゲットバージョンの明確さ — トリアージドキュメントはそれにちなんで命名されます(例: 0.4.0_PR_TRIAGE.md)

ワークフロー

1. 隔離されたPRレビュー用ワークツリーをセットアップする

git worktree list  # まず古いものがないか確認
git worktree prune
git worktree add ../voicebox-pr-review -b pr-review-<VERSION> main

メインのワークツリーはリリース準備作業(チェンジログの下書き、main への直接フォローアップ)に使用します。レビューワークツリーは gh pr checkout に使用します。各チェックアウトで HEAD がコントリビューターブランチに移動するため、メインのワークツリーでこれを行うのは避けるべきです。

2. すべてのオープンPRのメタデータを収集する

gh pr list --state open --limit 50 --json \
  number,title,author,isDraft,mergeable,mergeStateStatus,files,additions,deletions,reviewDecision,statusCheckRollup,maintainerCanModify \
  --jq '.[] | {num: .number, title, author: .author.login, mergeable, state: .mergeStateStatus, canModify: .maintainerCanModify, changes: "+\(.additions)/-\(.deletions)", files: [.files[].path]}'

各PRについて、以下を確認します:

  • サイズ(+追加行数/-削除行数)
  • マージ可能性の状態(CLEAN、UNSTABLE、DIRTY = 競合、UNKNOWN = GitHub がまだ計算中)
  • メンテナーによるブランチ編集が許可されているか(後で作者の代わりにリベースする場合に必要)
  • 変更されたファイルパス(PR間の重複を特定するのに役立つ)

UNKNOWN は main へのプッシュ直後によく見られます。その場合は実際にマージを試してみてください。

3. ティアに分類する

各PRを、以下のいずれかのバケットに正確に分類します:

Tier 1 — マージ: 小さく、マージ可能で、実際のバグを修正し、CIがクリーンで、レビューコストが低い。1行の修正、依存関係の緩和、対象を絞った安全性の強化。これらは簡単な成果です。

Tier 2 — 候補、レビュー: 中規模(50〜200行)、より広い範囲に影響し、妥当に見えるが詳細な確認が必要。プロダクトの方向性に合った新しいユーザー向け機能。

置き換え(Supersede): 修正または機能が、マージ済みの別のPRですでにカバーされている。コメントを付けて、置き換えるPRを指摘しながらクローズします。注意深く確認してください — 「似たタイトル」は証拠になりません。実際の差分を比較してください。

次のリリースに延期: 大規模な機能、競合の多い状態、ドラフトPR、リリースパイプラインにリスクをもたらすような変更。スピードランではこれらをマージしないでください。専用の集中が必要です。

4. トリアージドキュメントを作成する

PRレビューワークツリーのルートに <VERSION>_PR_TRIAGE.md を作成します。構造:

# <リポジトリ> <VERSION> — PR トリアージ

どのオープンPRが <VERSION> にランディングされるかを追跡するための作業ドキュメント。リリースカット後に削除。

最終更新日: <日付>

## 進捗

**Tier 1: 0 / N マージ済み**
**Tier 2: 0 / M 処理済み**
**置き換えトリアージ: 未処理**

---

## <VERSION> にマージ — クリティカルなバグ修正

| PR | ステータス | サイズ | 修正内容 | 必須の理由 |
|---|---|---|---|---|
| [#123](url) | [ ] | +5/-0 | ... | ... |

## 有力な候補 — 簡単なレビューが必要

| PR | ステータス | サイズ | 概要 |
|---|---|---|---|

## 置き換えとしてクローズ

| PR | ステータス | 理由 |
|---|---|---|

## <NEXT_VERSION> に延期

- [#xxx](url) ... — 理由

---

## 攻撃順序

1. 置き換えPRをクローズする(1行コメント)
2. Tier 1を依存関係のないバッチでマージする — ファイルパスが重複していないことを確認
3. Tier 2を個別にレビューする
4. `draft-release-notes` を再実行してすべてを取り込む
5. `release-bump` を実行する

進捗 ヘッダーが最も重要です。これはスコアボードであり、セッションが中断された場合にクリーンに再開できるようにします。

5. ループを実行する — PRごとに

Tier 1 / Tier 2リストの各PRに対して:

a. レビューワークツリーでチェックアウト:

cd ../voicebox-pr-review
git checkout pr-review-<VERSION>  # ニュートラルなベースにリセット
git checkout pr-review-<VERSION> 
git checkout pr-review-<VERSION>  # ニュートラルなベースにリセット
gh pr checkout <N>

b. 実際のコミットを確認する。main..HEAD ではない:

git show HEAD                    # PRの実際の変更
git show --stat HEAD             # 変更されたファイル + 行数

PRブランチが main よりも古い場合、git diff main..HEAD でレビューしてはいけません。 その差分には、PRがフォークされた後に main にランディングされたすべてのコミットが -(削除)行として含まれます。たった3行のPRが、700行のリバートのように見える可能性があります。これはPRを誤判断する最も簡単な方法です。

c. 懸念事項を評価する: 正しさ、範囲、すでにマージされた作業との相互作用、バージョン互換性(例: まだ固定していない依存関係のバージョンを必要とするAPIは使用できない)。

d. ブランチが main より遅れている場合はリベースする:

git fetch origin main
git rebase origin/main

これはスカッシュマージの前に必須です。 GitHubのスカッシュは diff(PR-head, merge-base) を計算します。古いブランチでは、その差分には中間のすべてのコミットをリバートすることが含まれます。リベースはマージベースを前方に移動させるため、スカッシュがクリーンになります。

e. メンテナーによる編集が許可されている場合、リベースをコントリビューターのフォークにプッシュする:

git remote add <author> https://github.com/<author>/<repo>.git
git fetch <author> <branch>              # まず彼らのrefを取得
git push <author> HEAD:<branch> --force-with-lease

これにより、GitHubのPR UIがリベースされた状態と同期し、GitHub側からマージがクリーンになります。

f. マージする:

gh pr merge <N> --squash

g. トリアージドキュメントを更新する — チェックボックスを ✅ merged <sha> に切り替えます(gh pr view <N> --json mergeCommit --jq '.mergeCommit.oid[0:7]' からの短いSHAを使用)。進捗ヘッダーを更新します。

6. 小さな修正をバッチ処理する

変更行数が5行以下、CIがクリーン、ファイルパスが重複しておらず、意図が明らかに正しい(例: 1行の依存関係緩和、環境変数の追加、インポートパスの修正)PRは、PRごとのレビュー儀式なしで、単一のループでマージできます:

for pr in 425 384 416 429; do
  echo "=== Merging PR $pr ==="
  gh pr merge $pr --squash
done

その後、各PRがクリーンにランディングされたことを確認します:

for pr in 425 384 416 429; do
  gh pr view $pr --json state,mergeCommit --jq "{pr: $pr, state, sha: .mergeCommit.oid[0:7]}"
done

7. マージ後のフォローアップ

既知の軽微な問題(例: 不完全なdtypeマップ、古いセンチネルクリーンアップ)があっても、マージする価値のあるPRがあります。マージをブロックしないでください。フォローアップは、通常のブランチ+PRとしてすぐ後に適用します:

cd <main-worktree>
git pull --ff-only origin main
git checkout -b fix/<short-name>
# 編集...
git commit -m "fix(<area>): <one-liner>"
git push -u origin fix/<short-name>
gh pr create --title "..." --body "Follow-up to #<N>. ..."

両方のSHAをトリアージドキュメントに記録します(✅ merged <pr-sha> + follow-up <pr>)。

mainへの直接マージの例外: 明示的で範囲が限定されたポリシー(例: 「リリーススピードラン」)がある場合のみ。デフォルトにしないでください。

8. 置き換え: クレジットを明示するコメントを付けてクローズする

gh pr close <N> --comment "クローズします — マージ済み #<M> によって置き換えられました(<簡単な説明>)。ありがとうございます!"

まず差分を確認してください — 「似たタイトル」では十分ではありません。PRが部分的に置き換えられている場合(診断は正しいが、変更の半分だけがまだ必要)、代わりに部分適用を行います。

9. 部分適用パターン

価値のある変更と疑わしい変更が混在しているPRの場合:

cd <main-worktree>
git pull --ff-only origin main

# PRブランチから特定のファイルをチェリーピック
git checkout <pr-commit-sha> -- <file1> <file2>

# ステージされた変更を確認し、必要に応じて調整
git diff --cached

# 一括置換したくないファイルに外科的な編集を適用
# (例: PRのファイルが、保持する必要がある最近のmainコミットより前のものである場合)

# 元の作者にクレジットを与えるトレーラー付きでコミット
git commit -m "$(cat <<'EOF'
<件名>

<保持した内容と破棄した内容を説明する本文>

Co-Authored-By: <author> <[email protected]>
EOF
)"
git push ...  # ブランチ + PR(mainへの直接マージの例外がない限り)

次に、何が適用され、何が破棄されたかを説明し、コミットSHAを参照するコメントを付けてPRをクローズします。

10. ドキュメントを最新に保つ

マージ、クローズ、フォローアップのたびに → <VERSION>_PR_TRIAGE.md を更新します。ドキュメントはセッションログです。中断されて明日再開する場合、ドキュメントだけが「今どこにいるのか」の唯一の情報源です。

11. トリアージが完了したら

  • ドキュメント内のすべてのPRに最終ステータスがある(✅ merged / ✅ closed / deferred)
  • 進捗ヘッダーに各ティアの N/N が表示されている
  • 次に実行するスキルは draft-release-notes(新しい main に対して [Unreleased] を再生成するため)、次に release-bump

リリースが出荷された後、トリアージドキュメントは削除するか、バージョン履歴に記録として残すことができます。

落とし穴

  • 古いブランチでの main..HEAD は嘘をつく。 ブランチが分岐してから main が獲得したすべてのものが削除行として表示されます。PRの実際のコミットは常に git show HEAD でレビューしてください。
  • リベースされていないブランチをスカッシュマージすると、中間の作業が逆適用される。 スカッシュは diff(PR-head, merge-base) を計算します。リベースはマージベースを前方に移動させます。
  • mergeable=UNKNOWN は一時的なものです — プッシュ後にGitHubが再計算しています。マージを試してみてください。
  • ルートの順序が重要(FastAPIなど): DELETE /history/failed は DELETE /history/{id} より前に 登録する必要があります。そうしないと、パラメータ化されたパスが "failed" をIDとして消費します。
  • Appleの -weak_framework は、同じフレームワークに対して -framework をオーバーライドします(順序に関係なく)。依存関係がオプションのものをハードリンクする場合は、cargo:rustc-link-arg=-Wl,-weak_framework,Name を介して使用します。
  • 依存関係のバージョンフロアは、適用できる内容を制限する。 torch_dtype= → dtype= のようなキーワード引数の名前変更を受け入れる前に、最小バージョンピンがそれをサポートしているか確認してください。PRの半分をチェリーピックするのが正しい場合があります。
  • cpal::Stream および類似の !Send オーディオタイプ は、await ポイントや spawn_blocking を越えられません。「理想的ではないが正しい」同期待機が利用可能な最善の修正である場合があります。フラグは立てますが、ブロックはしません。
  • PyTorch nightly ビルドはリリースに出荷できません — 非決定的で、実行間で回帰する可能性があります。GPUの問題を修正するためにnightlyへの切り替えを提案するPRがある場合は、TORCH_CUDA_ARCH_LIST=...+PTX を優先するか、代わりに安定版のサポートを待ってください。

正規コマンドリファレンス

# 一括PRメタデータ
gh pr list --state open --limit 50 --json number,title,author,mergeable,mergeStateStatus,additions,deletions,maintainerCanModify,files

# 詳細な単一PRビュー
gh pr view <N> --json body,author,headRefName,baseRefName,mergeable,maintainerCanModify,files,statusCheckRollup

# 実際のコミット(ブランチとmainの差分ではない)
git show HEAD
git show --stat HEAD
gh pr diff <N>

# コントリビューターブランチを現在のmainにリベース
git fetch origin main && git rebase origin/main

# リベースをコントリビューターのフォークにプッシュ(maintainerCanModify=true が必要)
git remote add <author> https://github.com/<author>/<repo>.git
git fetch <author> <branch>
git push <author> HEAD:<branch> --force-with-lease

# マージ
gh pr merge <N> --squash

# トリアージドキュメント用のマージSHAを確認
gh pr view <N> --json state,mergeCommit --jq '{state, sha: .mergeCommit.oid[0:7]}'

# 置き換えをクローズ
gh pr close <N> --comment "クローズします — マージ済み #<M> によって置き換えられました。ありがとうございます!"

注意事項

  • 古いブランチを main..HEAD で決してレビューしないでください。 これがこのスキルにおいて最も重要な1行です。
  • トリアージドキュメントはセッション状態です。 ドキュメントを失うと、セッションを失います。すべてのアクションの後に更新してください。
  • 部分適用でもコントリビューターにクレジットを与えてください。 Co-Authored-By: トレーラーと、適用されたコミットにリンクするクローズコメントを使用してください。
  • 完璧を目指して出荷を遅らせないでください。 「壊れている」状態から「軽微な既知の問題はあるが動作する」状態への修正は、厳密には改善です。問題にフラグを立て、フォローアップを登録し、修正をマージしてください。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル