pr-gardening について
Paperclip インスタンスが最近作成したプルリクエストを見つけ、最新コミットの準備状況を確認するスキルです。GitHub を読み取り専用で利用し、準備作業の調整やレポート作成を行いますが、マージ、承認、クローズは行いません。
主な機能
- 01対象プルリクエストの検出
- 02最新コミットの準備状況確認
- 03準備タスクの作成と重複排除
- 04元の issue へのコメント
- 05準備状況レポートの作成と公開
- 06条件を満たす受信箱 issue の任意アーカイブ
活用シーン
- 01最近作成されたインスタンス由来の PR の確認
- 02チェック失敗や更新の止まった PR の特定
- 03後続の準備作業の調整
- 04マージや承認を行わず準備状況を報告
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ paperclipai/ paperclip --skill pr-gardeningインストール後、Claude Code で/pr-gardeningを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
scripts/check-readiness.mjsfind-candidates.mjslib.mjspr-gardening.test.mjsrender-report.mjs詳細
PR のガーデニング
最近の期間(デフォルトは14日間)にアクティブだった Paperclip の課題で参照されている、この Paperclip インスタンスが作成したプルリクエストを積極的にガーデニングします。候補の検出と準備状況の確認はスクリプトで行い、LLM による分析は行いません。このワークフローでは、GitHub へのアクセスは常に読み取り専用です。
対象範囲 — 自分たちの PR のみ
デフォルトでは、このワークフローはこのインスタンスの GitHub アイデンティティ(gh の認証済みログイン名。例:cryppadotta)が作成したプルリクエストのみをガーデニングします。コミュニティからのコントリビューションと dependabot の PR は、Stage A で作成者のログイン名によって機械的に除外され、droppedCommunityPullRequests に記録されます。手動で再追加してはいけません。呼び出し元が --authors または --include-community を明示的に指定した場合に限り、対象範囲を広げます。
厳守すべきガードレール
- プルリクエストをマージ、承認、またはクローズしてはいけません。
- 他の人やエージェントに、プルリクエストのマージ、承認、またはクローズを指示してはいけません。
- コミュニティの PR をガーデニングしたり、コメントしたり、
/prepare-paperclip-prを実行したりしてはいけません。 対応可能なのは Stage A の作成者許可リストに含まれる PR のみです。 - 変更を伴う
ghコマンドや、変更を伴う GitHub API リクエストを使用してはいけません。スクリプトが使用するのはgh pr viewと、読み取り専用のgh apiGET リクエストのみです。 - ドラフトのプルリクエストは報告のみを行います。ドラフトにガーデニングコメントを投稿してはいけません。
- コメントは既存の起点となる課題にのみ投稿します。プルリクエストごとにガーデニング用の課題を作成してはいけません。
--dry-runは、ガーデニングコメント、準備タスク、受信トレイのアーカイブを含む、Paperclip に対するすべての変更を抑制します。どのモードでも、候補の検出と GitHub の調査は読み取り専用です。
入力
--days <N>:アクティビティの対象期間。デフォルトは14です。言及している課題のアクティビティと PR 自体のupdatedAtの両方に適用されます。期間内にアクティビティがないオープン PR は、古いものとして除外されます。--authors <logins>:対象とする PR の GitHub ログイン名をカンマ区切りで指定します。デフォルトはghの認証済みユーザーです。--include-community:作成者による絞り込みを完全に無効にします。呼び出し元が明示的にリクエストした場合に限ります。--repo <owner/repo>:GitHub リポジトリ。デフォルトではgh repo viewで検出されます。--dry-run:コメントを投稿したり、準備タスクを作成したり、受信トレイのエントリをアーカイブしたりせずに、検出、確認、報告を行います。--archive-inbox:候補 PR が現在のヘッドでマージ済みであることを GitHub が確認した後、Stage D で担当ユーザーの受信トレイから起点となる課題をアーカイブします。--cooldown-hours <N>:ガーデニングを繰り返すまでのクールダウン時間。デフォルトは48です。--max-rounds <N>:PR ごとのガーデニングラウンドの最大数。デフォルトは3です。
生成ファイルには、$PAPERCLIP_RUN_SCRATCH_DIR/pr-gardening など、実行専用のディレクトリを使用します。
Stage A — 候補の検出
抽出検索の処理を実行します。すべての結果ページをスキャンし、PR URL を正規化して PR 番号を重複排除し、言及しているすべての課題を記録し、課題の成果物を確認して起点を特定します。GitHub でマージ済みまたはクローズ済みとされている PR、作成者が許可リストに含まれない PR(コミュニティからのコントリビューション)、および PR 自体の updatedAt が期間より古いオープン PR はそれぞれ除外され、コミュニティからのコントリビューションは droppedCommunityPullRequests に、古い PR は droppedStalePullRequests に記録されます。課題ごとの抽出一致上限を超えた課題(通常、数百件の PR URL を列挙するダイジェストまたは QA の課題)は source.truncatedIssues に記録され、実行を中断する代わりにレポートに記載されます。
node .agents/skills/pr-gardening/scripts/find-candidates.mjs \
--days 14 \
--dry-run \
--output "$RUN_DIR/candidates.json"
このスクリプトは kind=url、scope=all、updatedWithin=<N>d を指定して GET /api/companies/:companyId/search/extract を呼び出し、その後、--authors または --include-community で上書きされていない場合は gh api user から作成者の許可リストを取得します。これを、課題一覧の全件取得や LLM によるスキャンに置き換えてはいけません。
ステージ B — 現在のヘッドの準備状況を確認する
node .agents/skills/pr-gardening/scripts/check-readiness.mjs \
--input "$RUN_DIR/candidates.json" \
--output "$RUN_DIR/readiness.json" \
--dry-run
各候補について、スクリプトは現在のヘッド SHA を再取得し、以下を記録します。
- オープン/ドラフト状態とマージ可能性/競合;
statusCheckRollupのチェック実行と従来のステータス一覧;- 正確なヘッド上で完了した Greptile のチェック実行。
successまたはneutralの場合のみクリーンと判定します; reviewDecision;- ベースブランチからの遅れたコミット数。
判定結果は ready、needs_gardening、またはドラフトの場合は report_only です。PR を起こした後、または修正済みとの申告があった後は、必ずこのステージを再実行してください。準備完了の証拠として、イシューのコメントを決して信用しないでください。
フォローアップの PR 作成タスクの重複排除
ブランチに対して単一のプルリクエストを作成するフォローアップタスクが必要だとガーデニングで判断した場合は、タスクを作成する前に重複を排除してください。
各ブランチについて、一度に 1 つずつ、以下の手順を順番に実行します。
- ステータスが
backlog、todo、in_progress、in_review、blockedのオープン状態にある Paperclip イシューを、ブランチ名と完全一致する条件で検索します。 - 該当するイシューのタイトル、説明、最近のコメントを調べ、同じブランチから PR を作成するための、内容が同等のオープンタスクがないか確認します。
- 内容が同等のオープンタスクがある場合は、それを再利用します。現在の PR/ヘッド/理由に関する簡潔なコメントを追加し、ガーデニングのイシューまたはブロッカー一覧からそのタスクにリンクします。別のタスクは作成しないでください。
- 内容が同等のオープンタスクがない場合に限り、そのブランチのフォローアップタスクを 1 つだけ作成します。
フォローアップタスクの作成を並列で行わないでください。PR 作成タスクまたは PR 準備タスクについて、POST /api/companies/:companyId/issues を同時に呼び出さないでください。P1 のイシュー作成の冪等性サポートが利用可能になった後は、PR 作成のフォローアップタスクを作成するたびに idempotencyKey: "pr-gardening:create-pr:{branch}" を指定し、PR 準備タスクを作成するたびに idempotencyKey: "pr-gardening:prepare-pr:{owner/repo}#{number}" を指定してください。
ステージ C — /prepare-paperclip-pr で自分たちの PR を準備完了にする
--dry-run モードの場合、および ready または report_only のエントリについては、このステージをスキップします。
ここにある needs_gardening の PR はすべて、このインスタンスが開いたものです(ステージ A で保証されています)。そのため、報告するだけでなく、対象に /prepare-paperclip-pr スキルを実行して、マージ可能な状態にしてください。PR は 1 つずつ処理します。
-
クールダウンとラウンド。
candidates.jsonからoriginatingIssueを特定します(選択の優先順位:pull_request作業成果物として PR の URL と完全一致するものを持つイシュー、次にコメントで PR に言及しているイシュー、次に PR に言及している最も最近アクティブなイシュー)。そのコメントを取得し、以下のマーカーを検索します。最新の該当マーカーがクールダウン期間内にある場合は、その PR をスキップします。該当マーカーからラウンド数を記録し、3 ラウンドに達したら停止して、
収束していません。クローズまたは人による判断を推奨しますと報告します。これは人に対応を委ねるための推奨であり、PR をクローズする指示ではありません。 -
重複排除。 PR 番号/ブランチを指定して、オープン状態の Paperclip イシューを検索します。内容が同等のオープン中の PR 準備タスクがすでにある場合は、別のタスクを作成する代わりに、簡潔なステータスコメントを付けてそのタスクを再利用します(上記の重複排除のセクションを参照)。
-
準備スキルを実行する。 PR ごとに、コーディングエージェント(CodexCoder を優先)に割り当てた、対象を絞った子タスクを 1 つ作成します。その PR に対して
/prepare-paperclip-prを実行するよう指示し、PR URL、ブランチ、現在のヘッド SHA、readiness.jsonから取得した機械検出のreasons[]を正確に含めてください。ガーデナー自身が対象 PR のブランチをワークツリーでチェックアウト済みの場合は、委任せずに/prepare-paperclip-prを直接実行してもかまいません。どちらの場合も、準備作業で PR をマージ、承認、またはクローズしてはいけません。 -
マーカーコメントを残す。 上記のマーカー、現在のヘッド SHA、コピーした
reasons[]、ラウンドカウンター、準備タスクへのリンクを添えて、起点イシューにコメントします。X-Paperclip-Run-Idを使用してPOST /api/issues/:issueId/commentsを呼び出してください。イシューが終了状態の場合はresume: trueを含め、コメントによってアクティブな継続が作成されるようにします。
推奨する本文:
Gardening: dispatched `/prepare-paperclip-pr` for https://github.com/paperclipai/paperclip/pull/1234 via PAP-XXXX.
Current-head verification at `abc123` found:
- failing check: test
- Greptile missing at current head
Gardening round 1/3. Re-verification is required after changes; do not merge based on this comment.
ステージ D — 受信トレイの整理(任意)
呼び出し元が明示的に --archive-inbox を指定した場合にのみ、このステージを実行します。--dry-run が指定されている場合は、--archive-inbox も指定されていても、受信トレイへの変更は常に抑止されます。このフラグがない場合は、何もアーカイブしないでください。
ステージ D の対象は、以前に監視していた候補のうち、マージ済みに移行したものです。このステージの直前にステージ B を再実行し、その検証で記録された同じ現在のヘッド SHA について、GitHub が state: merged と報告することを必須とします。ステージ A で新たに検出する際は、すでにマージ済みまたはクローズ済みの PR は意図的に除外されます。
条件を満たす候補ごとに、担当ユーザーの受信トレイから、その originatingIssue を POST /api/issues/:issueId/inbox-archive と空の JSON 本文でアーカイブします。userId は渡さないでください。Paperclip API は、ガーデナーの実行コンテキストから担当ユーザーを解決し、そのユーザーの受信トレイに関するエージェントポリシーを適用します。GitHub へのアクセスは引き続き読み取り専用です。
単に ready の PR、マージせずにクローズされた PR、ドラフト、保留中の PR、または未検証もしくは古いヘッドのままマージされた PR はアーカイブしないでください。ユーザーが引き続きレビュー、判断、承認、またはその他の対応を待っている間は、元の Issue を決してアーカイブしないでください。担当ユーザーが特定できない、受信トレイ管理が無効になっている、ガーデナーが許可リストに登録されていない、または信頼境界が適用されるために Paperclip が変更を拒否した場合は、その拒否を報告し、ポリシーを回避するために再試行せずに続行します。
アーカイブが成功したら、元の Issue に標準のガーデニングマーカーコメントを残し、アーカイブした Issue とマージ済みの PR を明記します:
Inbox tidy-up: archived [PAP-310](/PAP/issues/PAP-310) from the responsible user's inbox after confirming https://github.com/paperclipai/paperclip/pull/1234 merged at current head `abc123`.
This archive is audited and reversible; later issue activity may resurface the item.
POST /api/issues/:issueId/comments を使用し、アーカイブとコメントの両方のリクエストに X-Paperclip-Run-Id を含めてください。--dry-run では、実際に書き込まれるはずだったアーカイブとマーカーコメントを報告しますが、どちらの変更も実行しません。
ステージ E — 終了まで監視
ガーデニング実行 Issue の blockedByIssueIds に、ステージ C で関与した未終了の準備タスクと元の Issue を設定し、ブロッカーが解決したときにガーデナーが再開されるようにします。代替手段として、スケジュール実行または手動での再実行を使用します。
再開するたびに、まずステージ B を再実行します。次のいずれかが機械的に確認された場合にのみ、PR はアクティブなガーデニングの対象から外れます:
- 現在のヘッドで検証済みの
ready。 - 外部でマージまたはクローズされた。
- 最大ラウンド数に達し、収束していないと報告された。
終了済みの Issue をガーデニング Issue のブロッカーとして残さないでください。エージェントや長時間実行セッションをポーリングしないでください。
ステージ F — レポートの作成と公開
node .agents/skills/pr-gardening/scripts/render-report.mjs \
--input "$RUN_DIR/readiness.json" \
--output "$RUN_DIR/gardening-report.md"
レポートには対象範囲(作成者と期間)を記載し、オープン中の各 PR について、作成者、PR の説明から取得した目的の要約(1 行)、および準備状況の信頼度区分を記載します:
- 高: 現在のヘッドのチェックがすべて成功し、競合がなく、Greptile の問題がなく、ベースが最新で、元の Issue が終了済み。
- 中: それ以外は問題ないが、ベースが古い、レビューが完了していない、または元の Issue が対応中。
- 低: チェックの失敗または保留中、Greptile がない、ドラフト/修正済みだが未検証の状態、または特定可能な元の Issue がない。
PR の目的を示す生成文が空、または役に立たない場合は、レポートの公開時に PR タイトルと差分の要約から 1 文の説明を作成してください。
candidates.json、readiness.json、gardening-report.md をガーデニング Issue にアップロードし、Markdown の本文で gardening-report Issue ドキュメントを作成または更新して、成果物へのリンクを含む要約コメントを残します。レポートが成果物です。マージを許可するものでは決してありません。
検証
対象を絞ったスクリプトテストを実行します:
node --test .agents/skills/pr-gardening/scripts/pr-gardening.test.mjs
ライブのドライランでは、--dry-run を指定してステージ A、B、F を実行し、名前が指定された PR がまだオープン中の場合に限り、妥当性を確認します。マージ済みまたはクローズ済みの例は、準備状況の結果ではなく droppedClosedPullRequests に表示される必要があります。また、コミュニティ作成の PR は droppedCommunityPullRequests のみに表示される必要があります。許可リストにない作成者の候補やレポート項目は、対象範囲の違反です。--archive-inbox も検証する場合は、抑止されたステージ D のアクションがレポートに記載され、Paperclip のアーカイブやマーカーコメントの変更が一切行われていないことを確認してください。