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
3 changes: 3 additions & 0 deletions .github/workflows/pr-monitor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ jobs:
- レビュー指摘 (CodeRabbit / 人間 / 他 bot を問わず全レビュアーの指摘) を 1 件ずつプロジェクト適合性でフィルタする。判定観点は .takt/facets/instructions/analyze-coderabbit.md の「Step 2: Project fitness filter」に従う (入力が gh コマンドの結果である点だけが異なる)。intentional design 判定は CLAUDE.md の ADR 一覧から該当 ADR を Read して行う。
- severity はレビュアーの申告値を維持する (再分類しない)。
- レビュー指摘がまだ 1 件も無い場合は、CI 状態と diff 概要 (変更ファイル・行数・変更の性質) のみの軽量サマリーにする。CodeRabbit のレビュー未着はその旨を 1 行記すだけでよい (待たない)。
- **レビュー実施の陽性証拠を確かめてから Verdict を決める** (analyze-coderabbit.md の「Review evidence gate」と同じ趣旨、ADR-064)。**証拠は必ず現在の head に紐づける** — まず `gh pr view <番号> --json headRefOid` で head SHA を取り、次のいずれかが成立する場合だけ証拠として採用する: (a) `gh api .../pulls/<番号>/reviews` の要素で `commit_id` が head SHA と一致するものがある、(b) その head に対するインライン指摘がある、(c) CodeRabbit の walkthrough / summary コメントが最新 push 以降に投稿されている。**過去の head に対するレビューは証拠にしない** — 古いレビュー記録で「今の差分もレビュー済み」と誤認するのは、ADR-064 が `unresolved_threads` を証拠から外したのと同じ失敗の形。
- **CI check の緑や `mergeStateStatus` はレビュー実施の根拠にならない** — 「check は pass だが実レビュー 0 件」を approved と誤報したのが順位 320 の実観測。証拠がどれも無ければ Verdict を `approved` にせず `user_decision` とし、「レビュー状況」行に「未実施 (陽性証拠なし)」と明記する。
- **証拠の source が analyze-coderabbit.md と違うのは意図的**。本 backstop は `.takt/review-comments.json` を持たず gh CLI しか使えないため、facet 側の `findings` / `coderabbit.actionable_comments` をそのまま参照できない。また本 backstop の対象は「CodeRabbit / 人間 / 他 bot を問わず全レビュアー」(上記) なので、人間のレビューも証拠に数えてよい。**共通なのは「現在の head に対してレビューが走った陽性証拠を要求する」という原則のほう**で、その判定材料は各層で使えるものを使う。

4. 分析結果を日本語の markdown で、下記のコメントフォーマットに従って最終応答として出力する。**最終応答は前置き・後書き・思考過程を一切含めず、必ず見出し行 `## 🤖 PR Monitor 分析 (GitHub Actions バックストップ)` から書き始めること** (この最終応答テキストがそのままコメント本文として投稿されるため、前置きがあるとコメントに混入し重複ガードの見出し検出も乱す)。あなた自身はコメントを投稿しない — 投稿はこの workflow の後続 step (エージェント外) が、あなたの最終応答テキストをそのまま `--body-file` として渡して行う。

Expand Down
25 changes: 24 additions & 1 deletion .takt/facets/instructions/analyze-coderabbit.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ The severity is preserved on `user_decision_path` findings so the user can prior

### Summary
- CI: [status]
- レビュー実施: 実施 (根拠: findings N 件 / actionable_comments=N) or **未実施 (陽性証拠なし)**
- CodeRabbit: [N] findings total, [M] applicable after filter
- Verdict: approved / needs_fix / user_decision

Expand Down Expand Up @@ -76,8 +77,30 @@ The severity is preserved on `user_decision_path` findings so the user can prior
1. [Prioritized action items for critical/major findings]
```

## Review evidence gate (check this BEFORE the verdict rules)

`approved` は「レビューが走った結果、直すものが無かった」という意味であり、**「レビューが走らなかった」は含まない**。両者は findings が空という同じ見え方をするため、区別せずに `approved` を出すと未レビューの PR を「指摘なし」と誤報する ([ADR-064](../../../docs/adr/adr-064-monitor-success-positive-evidence.md) の陽性証拠原則を、決定論層と同じ趣旨で本 facet にも適用する)。

**レビュー実施の陽性証拠**として採用してよいのは次の 2 つだけ:

- `findings` が 1 件以上ある
- `coderabbit.actionable_comments` が `null` でない (`0` を含む — 「レビューして 0 件だった」は陽性証拠)

どちらも**今サイクルの CR 出力に限定されている** — 上流の `check-ci-coderabbit` が `parse_actionable_comments` / `parse_new_comments` で `push_time` 以降のものだけを数えるため、過去 push に対するレビュー記録は入り込まない。「現在の head に対してレビューが走った証拠を要求する」という原則は `pr-monitor.yml` の GHA backstop と共通で、判定材料 (あちらは `reviews[].commit_id` と head SHA の照合) が層ごとに違うだけである。

次は**証拠に採用しない**:

- `coderabbit.new_comments > 0` — rate-limit 通知やコマンド応答など、レビュー以外の CR コメントでも増える。本 facet が起動する条件そのものでもあるため、これを証拠に数えると gate が常に素通りになる
- **決定論層の `has_review_evidence()` (`src/check-ci-coderabbit/src/decide.rs`) は `new_comments > 0` を証拠に採用しており、本 facet は意図的にそれより厳しい。** 両者は判定の重みが違う — 決定論層が誤ると `continue_monitoring` に倒れる (監視を続けるだけで、外しても回復する) のに対し、本 facet の `approved` は**人間に示す終端 verdict** で、外すと未レビューの PR が「指摘なし」として読まれたまま残る。どちらかに寄せる場合は、この非対称を崩していないか確かめること
- `coderabbit.unresolved_threads > 0` — 過去サイクルの残骸を含み、今回レビューが走った証拠にならない (ADR-064 と同じ理由)
- `coderabbit.review_state` の値や CI の緑 — **check が pass でもレビュー実施の根拠にはならない**。これが順位 320 で実観測した誤報の形

**陽性証拠がどちらも無い場合、`approved` を出してはならない。** verdict は `user_decision` とし、レポートの Summary に「CodeRabbit のレビュー未実施 (指摘 0 件ではなく、レビューが走った証拠が無い)」と明記する。`needs_fix` の条件 (applicable な Critical/High/Major) を満たす場合はそちらが優先される — 指摘があるなら証拠は成立している。

## Verdict Rules (3-way)

> 下記は**上記 review evidence gate を通過した場合の**判定である。verdict は 3 値のまま増やさない (`post-pr-review.yaml` の `rules.condition` がリテラル照合するため)。

- **approved**: No applicable findings, OR all applicable findings are Info/Low severity
- Output: `approved` condition
- **needs_fix**: Any applicable Critical, High, or Major finding exists (excluding `user_decision_path`)
Expand All @@ -93,7 +116,7 @@ The severity is preserved on `user_decision_path` findings so the user can prior
- Do NOT modify any code. This is analysis only.
- Do NOT fabricate findings. Report only what is in the JSON.
- Do NOT skip the fitness filter. Every finding must be evaluated for project applicability.
- If the findings array is empty, report "No actionable findings" with verdict `approved`.
- If the findings array is empty, first apply the **review evidence gate** above. With evidence, report "No actionable findings" with verdict `approved`; without evidence, report the review as not performed with verdict `user_decision`.
- If the JSON file is missing or empty, report the error and exit.
- When this is a re-analysis after a fix iteration, compare with previous reports to check for regression or persistence.

Expand Down
20 changes: 17 additions & 3 deletions docs/bugfix-batch-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
| B-1 | fix(merge-pipeline): transcript の連結順序を時系列にする | 446 (再定義) | **完了** ([PR #419](https://github.com/aloekun/claude-code-hook-test/pull/419)) |
| B-2 | fix(merge-pipeline): 分析ソース選定を陽性照合ベースに統一 | 336 + 288(a) | **完了** ([PR #420](https://github.com/aloekun/claude-code-hook-test/pull/420))。実 run で照合成功を確認済み |
| B-3 | fix(merge-pipeline): transcript 抽出を workspace 横断にする | 469 (446 から分離) | **完了** ([PR #421](https://github.com/aloekun/claude-code-hook-test/pull/421)) |
| C | fix(hooks): smoke suite の ETXTBSY 解消 | 396 | 実装済み |
| D | fix(check-ci-coderabbit): rate-limit 第 3 format + 実レビュー有無分離 | 318 + 320 | 未着手 |
| C | fix(hooks): smoke suite の ETXTBSY 解消 | 396 | **完了** ([PR #423](https://github.com/aloekun/claude-code-hook-test/pull/423))。台帳の 3 案はいずれも副作用があり、copy/spawn の相互排除に切り替えた |
| D | fix(coderabbit-review): レビュー実施の陽性証拠を facet/prompt 層にも要求する | 318 + 320 | 実装済み。**318 は全項目・320 は決定論層が既に実装済みだった**ため、facet gap 修正 + 後始末に縮小 |
| E | fix(ci): 監視系 workflow の誤動作修正 | 319 + 431 | 未着手 |
| F | fix(pr-monitor): cli-pr-monitor 小修正束 | 246 + 292 + 385 | 未着手 |
| G | fix(jj-helpers): bookmark 探索の深さ非依存化 + 自動 fix 後始末 | 386 + 387 | 未着手 |
Expand Down Expand Up @@ -45,7 +45,7 @@

本計画の PR A〜B-3 (2026-08-18〜19) で実際に踏んだ穴。以降の PR C〜L でも同じ形で再発する。

**台帳の記述をそのまま信じない。** 本計画で着手した 6 件のうち **5 件で台帳と実態がずれていた**。
**台帳の記述をそのまま信じない。** 本計画で着手した 9 件のうち **7 件で台帳と実態がずれていた**。

| 順位 | 台帳の記述 | 実際 |
|---|---|---|
Expand All @@ -54,6 +54,8 @@
| 347 | `cli-merge-pipeline` の欠陥 | 実装先は `cli-pr-monitor` |
| 446 | 並列 workspace のセッションが不可視 | 真因は**連結順序が時系列でないこと** |
| 336 | 時刻範囲のみで照合しない | 時刻範囲すら使わず**辞書順で最新 1 件** |
| 318 | 第 3 format 未対応 + silent 化が残る | **4 項目すべて実装済み** (PR #309 ほか)。本丸の既定 30 分 park も入っていた |
| 320 | check pass の誤報が残る | 決定論層は [ADR-064](adr/adr-064-monitor-success-positive-evidence.md) で**実装済み**。残件は facet/prompt 層のみ |

台帳は起票時点のスナップショットで、実装が動くほどずれる。328 と 446 は、台帳どおりに実装すれば**存在しない不具合を直すか誤った箇所を直す**ところだった。**自分が前日に書いたエントリでも同じ** — 順位 469 の Frequency 評価は実測で覆った。

Expand Down Expand Up @@ -175,6 +177,18 @@

**⚠ 着手前の lane 調整**: [claude-code-web-tasks.md](claude-code-web-tasks.md) の順位 176 (`✅` auto lane) が同一ファイル `src/check-ci-coderabbit/src/rate_limit.rs` を触る。台帳の規律は「競合する割り当てをしない」— ユーザーに確認して 176 を `—` (human) へ移して本 PR に取り込むか、夜間 PR の land を待つ。

> **着手前の競合確認と実態調査の結果 (2026-08-19)**: **lane 調整は不要になり、実装対象もほぼ消えた。**
>
> **競合確認**: 開いている夜間 PR は 2 本 ([#422](https://github.com/aloekun/claude-code-hook-test/pull/422) 順位 228 / [#413](https://github.com/aloekun/claude-code-hook-test/pull/413) 順位 240) で、**どちらも `check-ci-coderabbit` を触らない**。順位 228 は名前が「rate-limit」で紛らわしいが `cli-pr-monitor` 側の別実装 (`src/cli-pr-monitor/src/stages/poll/rate_limit/tests.rs`)。順位 176 は auto lane 25 行中の **22 番目**で、夜間ループは 1 晩 1 件を**文書順**で選ぶ (open PR のある順位のみ skip、`lib_ledger::select`) ため当分回ってこない。実接触は `docs/todo-summary2.md` を両 PR が編集する点のみ (削除行が別なので軽微)。
>
> **順位 318 は 4 項目すべて実装済みだった** — ① `extract_next_review_format_wait_time` (rate_limit.rs:120、PR #309 / 2026-07-20)、② 本丸の silent 化解消 (`UNKNOWN_FORMAT_FALLBACK_WAIT_MINUTES = 30` + `warn_unknown_wait_time_format()` + `wait_time_parsed`)、③ 第 3 format fixture 3 本 + fallback 2 本、④ ADR-034 の format 一覧 table 行。**計画書が「案を検討」と書いた保守的既定 30 分の park がそのまま入っている。**
>
> **順位 320 も決定論層は実装済みだった** — [ADR-064](adr/adr-064-monitor-success-positive-evidence.md) の `has_review_evidence` が decide.rs の R1/R4 ゲートとして「check が pass でもレビュー実施の陽性証拠がなければ success に倒さない」を実現している (計画書の対処 (2))。
>
> **残っていたのは対処 (1) の facet 層だけで、影響は誤読リスクに限定**されていた。3 経路を追った結果: (a) 決定論層は倒れない、(b) ローカル takt は起動条件が `has_coderabbit_findings` なので「レビュー無し」では**そもそも到達せず**、verdict は re-push/fix 経路にしか流れない、(c) GHA Phase A は `Verdict: approved` を出しうるが**機械消費されない**コメント文字列 (`pr-monitor.yml` 全体で該当トークンの出現は 1 箇所のみ) で、監視役は approve/merge が禁止 (ADR-022)。
>
> **したがって本 PR は「facet gap 修正 + 台帳後始末」に縮小した** (ユーザー判断)。Rust コードは変更しない。

### 順位 318: rate-limit 第 3 format 未対応 + silent 化

- **不具合**: PR #287 で CR の wait-time 文言が第 3 format (`**Next review available in:** **32 minutes**`) に変わり、marker (`is_rate_limit_comment`) は一致するのに全 extract 関数が不一致 → `parse_rate_limit` が None で**静かに**「rate-limit 無し」扱い。監視が false-green を報告した。旧 → 新 → 第 3 と同一クラス 3 世代目。
Expand Down
2 changes: 0 additions & 2 deletions docs/todo-summary2.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@
| 315 | 💎 Tier 3 | **ADR-055 telemetry の bounded lifetime 期限を config コメントに明記 (275.md T3-1 採用)** | todo16.md | XS | なし (warm-up 期限 2026-08-12 頃 + ADR-062 リンクを `[telemetry]` section コメントに追記。step2/3 は ADR-062 で消化済み) |
| 316 | 💎 Tier 3 | **ADR-044「2nd consumer で共通化」原則の明確化・判定基準の例示 (275.md T3-2 採用)** | todo16.md | S | なし (is_truthy の非対称性を case study 化。順位 317 と対) |
| 317 | 💎 Tier 3 | **utility 関数追加前のチェックリスト(workspace grep)(275.md T3-3 採用)** | todo16.md | XS | 順位 316 (ADR-044 明確化と対) |
| 318 | 🚀 Tier 1 | **CR rate-limit 第3 format (`Next review available in: N minutes`) 未対応 + marker 一致/regex 不一致の silent 化 (PR #287 で実観測)** | todo16.md | S | なし (ADR-034 § 検出 logic 更新手順 の 4-6 をそのまま適用可。silent 化解消は追加設計) |
| 319 | 🚀 Tier 1 | **pr-monitor.yml バックストップの重複ガードが構造的に機能しない — CR 投稿ごとに分析コメントを再投稿 (PR #287 で 5 件実観測)** | todo17.md | S | なし (ガードが LLM prompt 内にあり、トリガー事象自身が skip 条件を無効化するトートロジー。Status update 2026-08-12: #310 の決定論ガードは dogfood 不合格 — #347〜#390 の 29 PR で 2 投稿以上が 69%。残原因は pull_request_review 経路の content フィルタ欠落、詳細と追加修正案は todo17.md エントリ) |
| 320 | 🔧 Tier 2 | **CodeRabbit status check は実レビュー有無に関わらず `pass` — 緑チェックを「レビュー済み」の根拠にしない (PR #287 で実観測)** | todo17.md | S | 順位 318 (決定論的な rate-limit 検知が前提) |
| 321 | 🔧 Tier 2 | **ADR-019/WP-03 クォータ設計の前提 stale (無料枠 → Pro + adaptive limit) + 初回レビュー処理中 push のレビュー欠落穴** | todo17.md | S | なし (dev-conventions 順位 262「外部 SaaS 無料枠/制限の調査チェックリスト」の適用対象) |
| 322 | 🚀 Tier 1 | **post-merge-feedback が repo root に scratch script を残し `scratch_file_warning` の pattern をすり抜ける (near-miss 実観測)** | todo17.md | S | なし (PR #85 と同一クラス。pattern 列挙 (deny-list) の構造的限界が露呈) |
| 323 | 🚀 Tier 1 | **`lib-subprocess` `run_cmd_shell_*` の timeout が wall-clock を縛れない — 孫プロセス残存で join がブロック (push-pipeline-fix-plan §6 backlog 10 移管)** | todo17.md | S | なし (quality_gate step_timeout / push timeout / cli-merge-pipeline のハング打ち切りが実質無効。#286 post-merge-feedback の orphan/stale marker と同根の実害 1 件観測済。回帰テストに経過時間 assert 必須 = T6 教訓) |
Expand Down
Loading
Loading