Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions .github/workflows/pr-monitor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,21 @@
# - 自己トリガー防止: 本 workflow の投稿は github-actions[bot] 名義の issue_comment に
# なるが、(a) issue_comment 条件が coderabbitai[bot] 限定、かつ (b) allowed_bots が
# coderabbitai[bot] のみ許可のため github-actions[bot] トリガーは弾かれ、二重に防止。
# - Max 枠の暴走ガード: concurrency で PR 単位に集約 (最新イベントのみ処理) +
# プロンプト内の重複ガード。
# - 重複投稿ガード (順位 319 — 決定論層を主とする): 旧構成は CR の投稿 (ack / rate-limit
# 通知含む) ごとに分析コメントを再投稿していた (PR #287 で 5 件、#304 で 3 件、#307 で 5 件
# 実観測)。原因はガードが LLM prompt 内 (助言層) にしかなく、トリガー事象 (新規コメントの
# 存在) 自身が prompt ガードの「新情報あり」を成立させるトートロジーだったこと。対策として
# jobs.analyze.if: に決定論的な起動選別を置く:
# (a) issue_comment は CR の walkthrough/summary コメント (summarize marker を含み、かつ
# rate-limit placeholder marker を含まないもの) のみ起動。ack (auto-generated reply) /
# rate-limit 通知 / コマンド応答は summarize marker を持たないため起動しない。walkthrough は
# in-place 更新される (types: [created] のみ購読) ため初回作成で高々 1 回起動し、実レビューの
# 追加は pull_request_review (submitted) 経路が拾う。
# (b) CLOSED / MERGED の PR では起動しない (issue.state / pull_request.state == 'open')。
# prompt 手順 2 の重複ガードはこの決定論層の二層目 (fallback) に降格。ADR-042 (ルール vs
# 仕組み化) の観点でガードを助言層から決定論層へ移した形。
# - Max 枠の暴走ガード: 上記の起動選別 + concurrency で PR 単位に集約 (最新イベントのみ処理)
# することで 1 PR あたりの claude-code-action run 数を抑える。

name: pr-monitor

Expand Down Expand Up @@ -94,14 +107,18 @@ jobs:
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request_review' &&
github.event.pull_request.state == 'open' &&
github.event.pull_request.head.repo.full_name == github.repository &&
github.event.review.user.login != 'github-actions[bot]' &&
github.event.review.user.login != 'claude[bot]' &&
!startsWith(github.event.review.user.login, 'dependabot') &&
!startsWith(github.event.review.user.login, 'renovate')) ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request != null &&
github.event.comment.user.login == 'coderabbitai[bot]')
github.event.issue.state == 'open' &&
github.event.comment.user.login == 'coderabbitai[bot]' &&
contains(github.event.comment.body, '<!-- This is an auto-generated comment: summarize by coderabbit.ai -->') &&
!contains(github.event.comment.body, '<!-- This is an auto-generated comment: rate limited by coderabbit.ai -->'))
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand Down Expand Up @@ -167,7 +184,10 @@ jobs:
- 会話コメント: gh api repos/${{ github.repository }}/issues/<番号>/comments
- 差分: gh pr diff <番号>

2. 重複ガード: 会話コメントに本 workflow の過去の分析コメント (見出し「🤖 PR Monitor 分析」) が既に存在し、その投稿時刻以降に新しいレビュー・指摘・コメント・CI 状態の変化が無い場合は、分析を行わず最終応答として厳密に次の1行のみを出力して終了する (前後に他の文字を付けない): `SKIP: no new information`
2. 重複ガード (二層目 — 主たるガードは workflow の jobs.analyze.if: の決定論層。この prompt ガードはその fallback): 会話コメントに本 workflow の過去の分析コメント (見出し「🤖 PR Monitor 分析」) が既に存在する場合、その最新の分析投稿時刻以降に **分析価値のある新情報** が生じたかで判断する。以下は新情報に**数えない** — 分析価値のある新情報がこれら以外に無ければ、分析を行わず最終応答として厳密に次の1行のみを出力して終了する (前後に他の文字を付けない): `SKIP: no new information`
- CodeRabbit の定型 acknowledgment / コマンド応答 (`✅ Action performed` / `For best results, initiate chat` 等)、rate-limit 通知 (`Review limit reached` 等)、レビュー未着 / skip の通知
- 本 workflow (github-actions[bot]) 自身が過去に投稿した分析コメント
分析価値のある新情報の例: 人間・レビュアーによる新規レビュー / 新規インライン指摘、CI 状態の変化、PR state の変化。

3. 分析:
- レビュー指摘 (CodeRabbit / 人間 / 他 bot を問わず全レビュアーの指摘) を 1 件ずつプロジェクト適合性でフィルタする。判定観点は .takt/facets/instructions/analyze-coderabbit.md の「Step 2: Project fitness filter」に従う (入力が gh コマンドの結果である点だけが異なる)。intentional design 判定は CLAUDE.md の ADR 一覧から該当 ADR を Read して行う。
Expand Down
14 changes: 8 additions & 6 deletions docs/todo17.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@

#### 作業計画

- [ ] **決定論ガードを `if:` に追加** (LLM prompt に依存しない層へ移す):
- [ ] CR の **ack / 定型応答コメントを除外**する。`github.event.comment.body` に `<!-- This is an auto-generated reply by CodeRabbit -->` (= ack) が含まれる場合は起動しない。分析価値があるのは walkthrough (`<!-- This is an auto-generated comment: summarize by coderabbit.ai -->`) のみ。**本件の再投稿 5 件中 2 件はこの 1 条件で消える**。
- [ ] PR が **CLOSED / MERGED なら起動しない** (`github.event.issue.state == 'open'`)。
- [ ] prompt 手順 2 のガード条件を「**新規コメントの有無**」から「**分析価値のある新情報の有無**」へ書き換える (ack / rate-limit 通知 / 自身の分析コメントは新情報に数えない旨を明示)。決定論ガードを主、prompt ガードを従 (二層目) とする。
- [ ] 起動条件を変えるため **workflow_dispatch でのスモークテスト**を行い、(a) ack で起動しないこと (b) walkthrough で起動すること (c) merged PR で起動しないこと を実測で確認する。
- [ ] 本エントリ削除 + todo-summary2.md 行削除。
- [x] **決定論ガードを `if:` に追加** (LLM prompt に依存しない層へ移す、2026-07-20 実装):
- [x] CR の **ack / rate-limit / コマンド応答を除外**する。当初案の denylist (`<!-- ...reply by CodeRabbit -->` を除外) ではなく **positive allowlist** を採用: issue_comment は walkthrough/summary マーカー `<!-- This is an auto-generated comment: summarize by coderabbit.ai -->` を含み、**かつ** rate-limit placeholder マーカー `<!-- This is an auto-generated comment: rate limited by coderabbit.ai -->` を含まない場合のみ起動。マーカーはライブ PR #304/#307 の生 body で実検証。ack (reply) / rate-limit 通知 / command invocation は summarize マーカーを持たないため一括除外される (denylist より確実 — #307 の 5 投稿中 4 件が消え、実レビュー 1 件のみ残る)。
- [x] PR が **CLOSED / MERGED なら起動しない**。issue_comment 経路に `github.event.issue.state == 'open'`、pull_request_review 経路に `github.event.pull_request.state == 'open'` を追加。
- [x] prompt 手順 2 のガード条件を「**新規コメントの有無**」から「**分析価値のある新情報の有無**」へ書き換え、ack / rate-limit / 自身の分析コメントは新情報に数えない旨を明示。決定論ガードを主、prompt ガードを従 (二層目) へ降格。
- [ ] 起動条件を変えるため **workflow_dispatch でのスモークテスト** (post-merge): (a) ack で起動しない (b) walkthrough で起動する (c) merged PR で起動しない を実測確認する。
- [ ] **dogfood 実 PR 確認**後に本エントリ削除 + todo-summary2.md 行削除。

> **現在地 (2026-07-20)**: `.github/workflows/pr-monitor.yml` の `jobs.analyze.if:` / prompt 手順 2 / 先頭設計メモを修正済 (YAML parse + paren balance を node で検証、CodeRabbit マーカーは live API で裏取り)。**残**: workflow は push/merge 後にしか実発火しないため、workflow_dispatch スモークと実 PR での「walkthrough 1 回 = 高々 1 投稿 / ack・merged では無投稿」確認は post-merge のバックストップ観測で行う。確認できたら本エントリ削除。

#### 完了基準

Expand Down