feat(cli-pr-monitor): rate-limit 自動検出 + 再トリガー (Phase 4 / 順位 13)#97
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughGitHubのCodeRabbitボットコメントから「Rate limit exceeded」を検出・解析して待機期限を算出し、その情報をcheck-ci-coderabbitのJSON出力へ追加。cli-pr-monitorはConfigと状態を拡張してrate-limitの永続化・重複排除・自動リトライ(投稿+再試行管理)を行うようポーリングループを更新。関連ドキュメント(todo*.md)とユニットテストが追加・更新された。 Changes
Sequence Diagram(s)sequenceDiagram
participant GH as GitHub API (PR & comments)
participant CCI as check-ci-coderabbit
participant PM as cli-pr-monitor (poll loop)
participant PS as PrMonitorState
participant GHC as gh CLI (quiet comment)
GH->>CCI: PR とコメント一覧を提供
CCI->>CCI: "Rate limit exceeded" を検出・regexで分秒抽出・created_at→Unix変換
CCI->>PM: CheckResult(rate_limit)
PM->>PS: 状態復元 (rate_limit, retries, last_retriggered_at)
alt rate_limit present
PM->>PM: 重複排除 (コメント時刻比較)
alt auto_retry_enabled かつ retries < max_retries
PM->>PM: 必要時間を計算して待機(sleep)
PM->>GHC: 静かな再トリガーコメントを投稿
GHC-->>PM: 投稿結果
PM->>PS: retries++ と last_retriggered_at 更新(永続化)
else
PM->>PM: max_retries到達または永続化失敗 → action_requiredで退出
end
else
PM->>PM: 通常ポーリング継続
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/cli-pr-monitor/src/config.rs (1)
282-282: 💤 Low valueテストカバレッジ:
RateLimitConfigのパーステスト追加を推奨既存の
config_fix_defaults/config_fix_customと同様に、rate_limitセクションのパーステストを追加すると、設定ファイルからの読み込みが期待通りに動作することを保証できます。💡 テスト追加案
#[test] fn config_rate_limit_defaults() { let toml_str = "[monitor]\n"; let config: Config = toml::from_str(toml_str).unwrap(); assert!(config.rate_limit.auto_retry_enabled); assert_eq!(config.rate_limit.max_retries, 3); } #[test] fn config_rate_limit_custom() { let toml_str = r#" [monitor] [rate_limit] auto_retry_enabled = false max_retries = 5 "#; let config: Config = toml::from_str(toml_str).unwrap(); assert!(!config.rate_limit.auto_retry_enabled); assert_eq!(config.rate_limit.max_retries, 5); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cli-pr-monitor/src/config.rs` at line 282, Add parsing tests for RateLimitConfig similar to existing config_fix_defaults/config_fix_custom: create two unit tests named config_rate_limit_defaults and config_rate_limit_custom that deserialize a Config via toml::from_str and assert the RateLimitConfig fields (auto_retry_enabled and max_retries) have the expected default and custom values; reference the Config struct and its rate_limit field (RateLimitConfig) and use assertions on auto_retry_enabled and max_retries to verify proper parsing and defaulting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/cli-pr-monitor/src/stages/poll.rs`:
- Around line 238-246: The log format in poll.rs prints "retry={}/{}` but passes
rl.until_unix_secs as the second placeholder; update the logging so the second
value is the configured max retries instead: either add a max_retries parameter
to handle_rate_limit_retry (or otherwise obtain rate_limit_config.max_retries)
and use that in the format args, or simplify the format to a single "retry={}"
using state.rate_limit_retries + 1; adjust the log_info call that references
sleep_secs, rl.wait_minutes, rl.wait_seconds, state.rate_limit_retries, and
rl.until_unix_secs accordingly to replace rl.until_unix_secs with
rate_limit_config.max_retries (or remove the second placeholder).
---
Nitpick comments:
In `@src/cli-pr-monitor/src/config.rs`:
- Line 282: Add parsing tests for RateLimitConfig similar to existing
config_fix_defaults/config_fix_custom: create two unit tests named
config_rate_limit_defaults and config_rate_limit_custom that deserialize a
Config via toml::from_str and assert the RateLimitConfig fields
(auto_retry_enabled and max_retries) have the expected default and custom
values; reference the Config struct and its rate_limit field (RateLimitConfig)
and use assertions on auto_retry_enabled and max_retries to verify proper
parsing and defaulting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 079e8c4f-d36c-49ba-a8d5-0abf12108255
📒 Files selected for processing (8)
docs/todo.mddocs/todo3.mddocs/todo4.mdsrc/check-ci-coderabbit/src/main.rssrc/cli-pr-monitor/src/config.rssrc/cli-pr-monitor/src/stages/monitor.rssrc/cli-pr-monitor/src/stages/poll.rssrc/cli-pr-monitor/src/state.rs
PR #89 T2-1 の自動化。CodeRabbit が `Rate limit exceeded` コメントを投稿した 場合、reset 時刻 + 60s buffer まで sleep し `@coderabbitai review` を再投稿する。 ## 実装 - check-ci-coderabbit: rate-limit comment を検出し reset 時刻を計算する `parse_rate_limit` を追加。`Please wait N minutes M seconds` の正規表現抽出 + ISO 8601 → unix epoch 秒の手動パース (chrono 依存追加なし)。 - cli-pr-monitor: poll loop に rate-limit retry ブランチを追加 - `RateLimitConfig`: auto_retry_enabled (default true) + max_retries (default 3) - `state.rate_limit_retries`: 累積 retry 回数を state.json で persist - `state.rate_limit_last_retriggered_at`: dedup key (advisor 指摘対応) - `handle_rate_limit_retry`: sleep → gh pr comment 投稿 → counter++ ## dedup の必要性 (advisor finding) `comment_created_at` で dedup しないと、同一 rate-limit comment が iteration を 跨いで PR コメント一覧に残り、`(until_unix_secs - now).max(0) = 0` となって 即時 retrigger を繰り返す。結果 max_retries=3 が数秒で消費され誤って `action_required` で抜ける。`rate_limit_last_retriggered_at` で同じ created_at を skip し、CR が新しい rate-limit comment を投稿した時点で再度対象にする。 ## テスト - check-ci-coderabbit: rate-limit detection / parsing 11 tests 追加 (56 passed) - cli-pr-monitor: poll dedup + state persistence 4 tests 追加 (116 passed) ## 完了タスク - 順位 13 を docs/todo.md table から削除、todo3.md detail 削除 - 順位 19 (REJECT-ESCALATE) が rate-limit critical 系の最後の Tier 2 残
- handle_rate_limit_retry の log format 修正: retry={}/{} の 2 番目に
rl.until_unix_secs (unix 秒) が渡されていたバグ。max_retries に修正。
以前は "retry=1/1735689600" のような意味不明な出力になっていた。
- RateLimitConfig の parse test 追加 (defaults + custom)。既存
config_fix_defaults / config_fix_custom と同パターンで網羅。
6451dfb to
0c7c67b
Compare
- handle_rate_limit_retry の log format 修正: retry={}/{} の 2 番目に
rl.until_unix_secs (unix 秒) が渡されていたバグ。max_retries に修正。
以前は "retry=1/1735689600" のような意味不明な出力になっていた。
- RateLimitConfig の parse test 追加 (defaults + custom)。既存
config_fix_defaults / config_fix_custom と同パターンで網羅。
- 前 commit で誤って snapshot された .claude/pr-monitor.lock を削除
(.gitignore 追加は後続 commit で実施)。
0c7c67b to
e7b8d49
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
docs/todo.md (1)
69-70: ⚡ Quick winADR-033: 「順位◯」の絶対参照をテーブル外で使わないように調整してほしいです。
Bundle W の説明文中で
(順位 34)/(順位 35)のように絶対順位をテーブル外に持ち出しています。ADR-033 の「絶対番号はテーブル内に限定」に合わせると、将来の並び替え時に文章とテーブルの不整合リスクが下がります。🛠️ Proposed fix
-**仕様を proptest properties で明文化 (順位 34) + `PastTime` 等の型で invalid state を unrepresentable に (順位 35)** することで、ルール (ask-based) では塞げない bug class を構造的に排除する。 +**仕様を proptest properties で明文化 + `PastTime` 等の型で invalid state を unrepresentable に** することで、ルール (ask-based) では塞げない bug class を構造的に排除する。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/todo.md` around lines 69 - 70, Remove the hard-coded absolute rank references like "(順位 34)" and "(順位 35)" from the Bundle W and Bundle X paragraphs and replace them with neutral references (e.g., "see ADR-033 table", "refer to the ADR-033 rank table", or use relative language such as "the rank in the ADR-033 table") so the prose references the ADR-033 table rather than embedding absolute numbers; update occurrences around the symbols "Bundle W", "Bundle X", "Finding D", "Finding E", and the parenthetical rank mentions to use the table pointer or relative wording.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/check-ci-coderabbit/src/main.rs`:
- Around line 355-396: parse_rate_limit is selecting any coderabbit rate-limit
comment (including older sessions) because it doesn't restrict by the current
session start; update it to accept the current session start (e.g. push_time
unix seconds or ISO string) and filter out comments whose created_at is before
that push_time (do this before selecting latest). Concretely: change
parse_rate_limit signature to take a push_time parameter, parse each
candidate.created_at to unix (using parse_iso8601_to_unix) and only keep those
with comment_unix >= push_time, then continue with the existing sorting,
extract_wait_time, and until_unix_secs computation; reference parse_rate_limit,
extract_wait_time, parse_iso8601_to_unix and start_monitoring /
parse_new_comments / parse_findings for consistent session-based filtering.
- Around line 932-937: The parsed comments JSON currently yields both
new_comments and rate_limit but parse_new_comments treats "Rate limit exceeded"
as a normal comment, causing decide() to return action_required and abort
recovery; fix by filtering out rate-limit comments: either update
parse_new_comments to exclude comments that match the rate-limit signature (the
same pattern parse_rate_limit detects) or, after calling parse_new_comments and
parse_rate_limit, remove any comments that match rate_limit from new_comments;
additionally ensure the actionable/decision path in decide() (and the retry
branch in src/cli-pr-monitor/src/stages/poll.rs) short-circuits when
rate_limit.is_some() so rate-limit presence does not trigger action_required.
In `@src/cli-pr-monitor/src/stages/poll.rs`:
- Around line 182-185: The code currently ignores write_state errors after
setting state.rate_limit_last_retriggered_at and continues; instead check the
Result from write_state(&state) and if it returns Err, stop the automatic retry
flow by marking the state for human action (e.g., set state.action_required =
Some("failed_persist_rate_limit_retriggered") or similar), attempt to persist
that updated state (call write_state again or log and escalate), and then exit
the retry path (do not continue the loop—return or break) so
handle_rate_limit_retry and rate_limit_retries/dedup are not left inconsistent
(refer to write_state, state.rate_limit_last_retriggered_at,
handle_rate_limit_retry, rate_limit_config.max_retries, and
state.action_required).
---
Nitpick comments:
In `@docs/todo.md`:
- Around line 69-70: Remove the hard-coded absolute rank references like "(順位
34)" and "(順位 35)" from the Bundle W and Bundle X paragraphs and replace them
with neutral references (e.g., "see ADR-033 table", "refer to the ADR-033 rank
table", or use relative language such as "the rank in the ADR-033 table") so the
prose references the ADR-033 table rather than embedding absolute numbers;
update occurrences around the symbols "Bundle W", "Bundle X", "Finding D",
"Finding E", and the parenthetical rank mentions to use the table pointer or
relative wording.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: de0d83f2-2c35-410e-96de-2bbdf9f48a28
📒 Files selected for processing (9)
.gitignoredocs/todo.mddocs/todo3.mddocs/todo4.mdsrc/check-ci-coderabbit/src/main.rssrc/cli-pr-monitor/src/config.rssrc/cli-pr-monitor/src/stages/monitor.rssrc/cli-pr-monitor/src/stages/poll.rssrc/cli-pr-monitor/src/state.rs
✅ Files skipped from review due to trivial changes (2)
- .gitignore
- docs/todo4.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/todo3.md
CR review @ commit e7b8d49 で検出された 3 Major + 1 Nitpick を修正。 ## 修正内容 ### Finding 1 (Major): parse_rate_limit に push_time フィルタ追加 過去セッションの rate-limit comment を新セッション開始時に誤って拾うバグを修正。 `comment.created_at >= push_time` フィルタを追加し、parse_new_comments / parse_findings と同じ規則に揃える。これにより本 PR 検証中に観測された 22 分遅延の根因の一つが解消される。 ### Finding 2 (Major): parse_new_comments で rate-limit comment 除外 rate-limit comment が new_comments にカウントされると `decide()` が action_required を早期 return し、poll.rs の rate-limit retry 経路に入らずに監視終了するバグ。 "Rate limit exceeded" を含む comment を新規コメント集計から除外する。22 分遅延のもう 一つの根因。 ### Finding 3 (Major): write_state 失敗時の自動 retry 停止 retrigger 後の state 永続化に失敗すると、次 iteration で `rate_limit_retries` と `rate_limit_last_retriggered_at` の復元に失敗し、dedup と max_retries が壊れて `@coderabbitai review` 重複投稿の可能性がある。失敗時は action_required で抜ける。 ### Finding 4 (Nitpick): docs/todo.md 順位 絶対参照削除 ADR-033 の「絶対番号は table のみに保持」原則に従い、Bundle W/X 説明文から `(順位 34)` `(順位 35)` 等の絶対参照を削除しタスク名参照に置換。 ### .gitignore: pr-monitor.lock 除外 cli-pr-monitor の重複起動防止 lock file (PR #88 / #96 で導入) が .gitignore 漏れで PR snapshot に混入する事故を防ぐ。 ## テスト - check-ci-coderabbit: 59 tests pass (rate_limit_filters_out_past_session_comments, rate_limit_includes_comment_at_exact_push_time, comments_excludes_rate_limit を追加) - cli-pr-monitor: 118 tests pass - clippy + fmt clean (変更パッケージ)
e7b8d49 to
79b7c3d
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/todo.md`:
- Around line 60-61: The second-layer description currently references only "PR
`#88` T2-4" but should include PR `#96` for accurate history; edit the text in
docs/todo.md (the line describing 第2層 / cli-pr-monitor ポーリング延長 + 重複起動ロック) to
change the parenthetical from "(PR `#88` T2-4、完了済)" to "(PR `#88` T2-4 / `#96`、完了済)"
so the record shows both PRs.
In `@src/check-ci-coderabbit/src/main.rs`:
- Around line 359-415: In parse_rate_limit, switch the timestamp basis from
created_at to updated_at when computing until_unix_secs: fetch latest.updated_at
(falling back to created_at only if updated_at is missing), pass that to
parse_iso8601_to_unix, and use it in the comment_unix + wait + 60s calculation;
also update the returned RateLimitInfo.comment_created_at (or add a
comment_updated_at field) to record the actual timestamp used. Locate symbols:
parse_rate_limit, GhComment.updated_at / created_at, extract_wait_time,
parse_iso8601_to_unix, and RateLimitInfo, and add a unit test where created_at
!= updated_at to ensure the updated_at path is exercised.
In `@src/cli-pr-monitor/src/stages/poll.rs`:
- Around line 179-203: The code marks a rate-limit event as handled even when
the retrigger (comment posting) fails by immediately incrementing
state.rate_limit_retries and setting state.rate_limit_last_retriggered_at;
change the flow so that retries/last_retriggered_at and state persistence are
only updated after a confirmed successful retrigger. Concretely, modify
handle_rate_limit_retry (or its caller) to return a success indicator (e.g.,
Result<(), Error> or bool) from the actual comment/post action, then in the
block that currently calls handle_rate_limit_retry(&rl, &mut state, ...) only
advance state.rate_limit_retries and set state.rate_limit_last_retriggered_at
and call write_state() when that indicator shows success; if the retrigger
fails, do not mutate those fields and instead return a
PollResult::action_required (or propagate the error) so the event stays eligible
for future retries. Ensure the same change is applied to the analogous logic
around lines 274-295.
- Around line 163-183: The rate-limit retry branch runs before timeout checks
and can block longer than the remaining monitoring budget; modify the logic in
the rate-limit handling (where state.rate_limit is used and
handle_rate_limit_retry(...) is called) to first compute remaining_monitor_secs
= max_duration - elapsed_since_start and if remaining_monitor_secs <= 0 set the
overall state to timed_out/action_required and skip retry, otherwise limit the
sleep duration passed to handle_rate_limit_retry to min(rl.sleep_secs,
remaining_monitor_secs); also apply the same remaining-time guard to the other
rate-limit retry sites that call handle_rate_limit_retry (the similar blocks
around the other occurrences) and set state.rate_limit_last_retriggered_at only
when a retry actually proceeds.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 76a11112-2a68-4f51-884d-adb13f59990c
📒 Files selected for processing (4)
.gitignoredocs/todo.mdsrc/check-ci-coderabbit/src/main.rssrc/cli-pr-monitor/src/stages/poll.rs
✅ Files skipped from review due to trivial changes (1)
- .gitignore
CR review @ commit 79b7c3d で検出された 3 Major + 1 Minor のうち Finding 1 (updated_at) を除く 3 件を修正。 ## 修正内容 ### Finding 2 (Major): rate-limit sleep を max_duration で cap `handle_rate_limit_retry` に `remaining_monitor_secs` 引数を追加し、 sleep が監視残り予算を超える場合は Err を返して retry を停止する。 これまでは max_duration を素通りして 30 分超ブロックする可能性があった。 ### Finding 3 (Major): handle_rate_limit_retry を Result 化 gh pr comment 投稿失敗 / PR 番号未確定の場合に retries++ や last_retriggered_at 更新を実施しないよう、関数を Result<(), String> に 変更。caller は Ok 時のみ dedup key を更新し、Err 時は action_required で抜ける。これにより失敗 retrigger が dedup で perma-skip 化する silent failure を防ぐ。 ### Finding 4 (Minor): docs/todo.md 第2層 PR 参照に #96 追記 "(PR #88 T2-4、完了済)" → "(PR #88 T2-4 / #96、完了済)" に履歴整合。 ## テスト追加 (2 件) - rate_limit_retry_returns_err_when_sleep_exceeds_budget: remaining=60s だが sleep=600s 必要なケースで Err を返し state 不変を確認 - rate_limit_retry_returns_err_when_pr_number_missing: PR 番号未確定で Err を返し state 不変を確認 ## 未対応 (任意) Finding 1 (updated_at): CR が rate-limit comment を編集する挙動は実観測なし。 将来的な堅牢性向上のため todo 化候補。
…nd 3 Finding 1 実観測対応) CR が rate-limit comment を編集して wait 時間を更新するケースが本 PR の dogfood で 実観測された (created_at=2026-04-30T11:11:51Z, updated_at=2026-04-30T14:38:32Z で "wait 21 minutes" に編集)。created_at 基準だと reset 時刻を 3 時間以上前として誤算定し、 premature retrigger → CR 再 rate-limit → comment edit のループに陥る危険があった。 ## 修正内容 - GhComment に updated_at フィールドを追加 - rate_limit_event_time(): updated_at fallback created_at を返すヘルパー追加 - parse_rate_limit: 計算基準を event_time に変更 (フィルタ / sort / until 計算) - RateLimitInfo.comment_created_at: 値の意味を「event_time」に拡張 (フィールド名は維持) - state.rs RateLimitState.comment_created_at の doc 更新 ## テスト追加 (3 件) - rate_limit_uses_updated_at_when_present: 実観測ケース (created_at != updated_at) で updated_at 基準計算を確認 - rate_limit_falls_back_to_created_at_when_updated_at_missing: 既存挙動の後方互換性を確認 - rate_limit_edited_comment_yields_new_dedup_key: 編集前後で dedup key が変化することを確認 (新 wait 時間で再 trigger 可能)
* feat(takt): Bundle Y2 - analyze facets を haiku 化 post-merge-feedback の 3 facets (analyze-pr / analyze-session / analyze-prepush-reports) と post-pr-review の analyze step を sonnet → haiku に変更。aggregate / fix / supervise は sonnet 維持で 品質担保。 analyze 系は「情報源から finding を抽出する分類タスク」で deep reasoning 不要。期待効果: PR #97 ベースラインから session あたり 15-20 分削減 + 該当 step の token cost 1/3。 token 効率改善計画書 (docs/pipeline-token-efficiency.md) も同コミットで 初出公開。進捗管理表で #A-1 / #C-1 を「採用済 (Bundle Y2)」マーキング。 Bundle Z (#B-*) / Bundle Z2 (#D-*) は別 PR で実装予定。 検証: AgentModelSchema (node_modules/takt/dist/core/models/schema-base.js) は ['opus', 'sonnet', 'haiku'] enum で haiku alias を accept。 npx takt prompt で両 workflow が parse 通ることを確認済み。 * docs(pipeline-token-efficiency): 進捗表の placeholder を PR #98 に更新 Bundle Y2 (#A-1 / #C-1) の進捗表エントリを「採用済 (Bundle Y2) | 2026-05-01 | (本 PR)」から実 PR 番号 #98 に書き換え。advisor 指摘の埋め忘れ防止のため、 親 commit (Bundle Y2 実装) と同 PR 内で完結させる。 PR #98 の post-pr-review takt 初回 run は 1 iteration / 1m 13s で APPROVED。 旧 baseline (1.5-2.5 min/iter) から早速 Bundle Y2 効果が反映された観測値。
* docs(pipeline-token-efficiency): 完了済 Bundle 整理 + 残作業を 3 PR 計画に再編 * feat(cli-pr-monitor): rate-limit 検出時に post-pr-review takt invoke を skip (#C-3) CR rate-limit が active な状態で polling を抜けた場合、stale な findings に対する takt 分析は空打ちになるため (1-2 分の浪費)、PR #97 で追加した検出機構を流用して takt invoke を skip する。 - PollResult に rate_limit: Option<RateLimitState> field を追加 - 8 つの PollResult 終了点すべてで state.rate_limit を伝播 - monitor.rs で has_coderabbit_findings + collect_findings 成功後、 rate_limit.is_some() を check して takt branch を skip + log 参照: docs/pipeline-token-efficiency.md PR 1 * feat(cli-merge-pipeline): trivial PR で post-merge-feedback を skip (#A-2) doc-only PR や 1-commit fix PR では post-merge-feedback の ROI が低いため、 gh pr view で取得した diff summary を判定して skip する。 判定条件 (3 つすべて満たす場合のみ skip): - changed files が全て .md - かつ commit 数 = 1 - かつ +/- 合計 < TRIVIAL_PR_LINE_LIMIT (50) 実装: - feedback.rs に PrDiffSummary / fetch_pr_diff_summary / parse_pr_diff_summary を追加 - main.rs run_ai_step で feedback::run 前に skip 判定 - 判定失敗時は WARN log を残して通常 flow に fallback (誤 skip による学習機会損失を最小化) unit test 9 件追加: - 境界 (TRIVIAL_PR_LINE_LIMIT 直前 / 上限と一致) - multi-commit / non-md 混在 / 空 files の non-trivial 判定 - 大文字 .MD 拡張子の認識 - 必須 field 欠損時の Err 返却 参照: docs/pipeline-token-efficiency.md PR 1
… 59/60 + ADR-035/036/037) (#108) * docs(todo): 順位 59 (ADR-035 docs 評価ポリシー / PR #107 T3-1) を追加 PR #107 post-merge-feedback の Tier 3 #1 採用に伴い、docs/todo.md 表と todo5.md 詳細を追加。 - 順位 59 (Tier 3, M): ADR-035 docs 評価ポリシー - docs-only 変更への code review criteria 誤適用を排除する global policy - review-security.md の既存 trust boundary criterion を ADR で集約 - review-simplicity.md / analyze-coderabbit.md にも一貫展開 - false REJECT 削減 + 開発体験劣化抑制 判定根拠 (順位 58 で導入した rubric ベース): - Severity Medium / Frequency Medium / Effort M / Adoption Risk None / ✅ 採用 * docs(efficiency): docs-pr-iteration-efficiency.md を新規作成 docs-only PR の iteration 改善に関する task 分類・bundle 案を集約する index を docs/ に新規追加。各 task の作業詳細は docs/todo*.md 系列に置き、本ファイル は概要 + リンクに留める設計。 掲載内容: - 現状の課題 / ボトルネック分析 (5 観点) - 改善 task 分類 (HIGH / MEDIUM / LOW IMPACT、合計 12 順位) - 推奨 bundle 案 (Bundle 'docs PR streamline' = 順位 59+31+32 を最優先) - 関連ドキュメント (todo.md / pipeline-token-efficiency.md / ADR-019/027/035) 役割: 試験運用 (bundle が消化されたら役割を終える計画書)。pipeline-token- efficiency.md と並列の領域特化計画書として機能する。 動機: 本セッションで 「docs-only PR の iteration 改善に当たる task をピック アップしてほしい」「毎回この情報を調べるのは手間」 とのユーザー要望に対応。 分析結果を再調査せず参照可能にする。 * docs(efficiency): coderabbit-monitoring-efficiency.md を新規作成 CodeRabbit 監視機能改善 (rate-limit 自動回復) に関する task 分類・bundle 案 を集約する index を docs/ に新規追加。各 task の作業詳細は docs/todo*.md 系列に置き、本ファイルは概要 + リンクに留める設計。 掲載内容: - 現状の課題 (CodeRabbit 無課金 = 1 時間 3 reviews 上限、47 分 rate-limit で auto-retry がバウンスする致命点) - ボトルネック分析 (6 観点: 長時間 rate-limit / polling 負荷 / silent loss / structured findings / 自動 trigger 信頼性 / ポリシー暗黙化) - 改善 task 分類 (HIGH / MEDIUM / LOW IMPACT、合計 9 順位) - 推奨 bundle 案 (Bundle 'CR auto-monitoring core' = 順位 53/54/55、 Bundle 'CR rate-limit auto-retry robustness' = 順位 42/43/46/49) - 推奨実行順序: 53 → 42-43-46-49 → 54 → 55 (1 と 2 は並行可) - 関連ドキュメント (ADR-009/018/019/034、todo.md、pipeline-token- efficiency.md、docs-pr-iteration-efficiency.md) 役割: 試験運用 (bundle 消化後に役割終了)。pipeline-token-efficiency.md / docs-pr-iteration-efficiency.md と並列の領域特化計画書として機能。 動機: 本セッションで 'CodeRabbit の監視機能改善に関する task をピックアップ してほしい'、'毎回この情報を調べるのは手間' とのユーザー要望に対応。 * docs(retire): pipeline-token-efficiency.md retire — ADR-036/037 化 + 順位 60 移管 + 削除 PR #97 セッション起源の計画書 docs/pipeline-token-efficiency.md (481 行) を 役割完了として retire。重要な設計決定は ADR に永続保存し、残作業 1 件のみを todo に移管した上で計画書ファイル本体を削除する。 新規 ADR (2 件): - ADR-036: Bundle Z 3 層アーキテクチャ - 決定論層 (#B-α PR #99/#105) → 制約付き修正 (#B-β PR #103) → 異常検知レビュアー (#B-γ PR #106) の 3 層スタック設計 - 'upper layer skips what lower layer catches' 原則 - 二重 miss 対策 (Calibration: avoid over-narrowing) を残置 - ADR-037: takt fix-trust shortcut (convergence_verdict 機構) - post-pr-review / pre-push-review の fix step が 'convergence_verdict: fully_resolved' で COMPLETE 直行する設計 - 'LLM が出した結果を後段で再検証しない' 原則 - Honesty constraint で安全網 bypass リスク管理 ADR-034 更新: - #D-4 (Claude 応答スタイル簡素化) を ❌ 不採用 に確定 (2026-05-04 ユーザー判断) Bundle Z Phase 2/3 完了後の再評価で副作用観測手段確立が見えないため 永続的に見送り。潜在 2.5-4M tokens 削減は採用しない - '将来の検討事項' から #D-4 再評価条件セクションを削除 - pipeline-token-efficiency.md への参照を '(削除済)' に annotate 順位 60 新規登録 (旧 #A-3、唯一の残作業): - analyze-session の transcript filter 絞り込み (Tier 3 / M) - input range を PR 作成 commit〜merge に限定し input token 30-50% 削減 ファイル削除: - docs/pipeline-token-efficiency.md (481 行) を削除 内容は git log で復元可能、主要設計は ADR-036/037 に集約 参照更新 (5 ファイル): - docs/coderabbit-monitoring-efficiency.md: 関連リンクから dead link 削除、ADR-036/037 を追加 - docs/docs-pr-iteration-efficiency.md: 同上 - docs/todo4.md: 順位 41 (Bundle Y2 効果定量計測) は動機失効を明記 (Bundle Z 完成 + Z2 不採用)、本格着手前にユーザー判断要。 順位 44/45 の参照を '(削除済)' に annotate - docs/todo5.md: 順位 51 の参照を ADR-036 に置換 - CLAUDE.md: ADR-036 / ADR-037 を index に追加 動機: ユーザー方針 '本当に必要な決定事項はADRに残し、不要になったTodoファイルや 作業計画のファイルは定期的に削除' に従い、計画書 retire の標準パターンを 本セッションで確立。今後類似の '計画書' (試験運用フラグ付き docs/) は 役割完了時に同パターンで retire する。 * fix(todo): 順位 41 entry の retire 済前提と旧フロー文言の不整合を解消 (#108 CR Minor) CodeRabbit が PR #108 review で 'outside diff range comment' として指摘した docs/todo4.md 順位 41 (Bundle Y2 効果定量計測) の line 371/378 残存問題を修正。 - 削除: 'Line 371: 想定削減量達成判定に基づき計画書 retire / 追加 Bundle 提案' (計画書はすでに retire 済のため、retire 判定ステップが矛盾) - 削除: 'Line 378: Bundle Z / Z2 の ROI 判断材料として活用可能なデータが揃う' (Bundle Z は完成、Bundle Z2 = #D-4 は不採用で本目的の役割消滅) - 修正: '結果を本 todo entry 内 (もしくは新規 ADR) に記録 — 旧計画は ...' → '結果を本 entry または新規 ADR に記録 (= 完了)' に簡素化 判定対象を「本 entry/ADR への記録完了」に統一し、retire 済前提との整合を確保。 備考 (別観察): 本指摘は CodeRabbit が 'outside diff range comment' として review body 内に含めて投稿したため、inline comment 前提の takt analyze-coderabbit step では 0 findings 判定 (= 検出漏れ) となった。 takt analyzer の coverage gap として将来の post-merge-feedback で扱う。
Summary
Rate limit exceededコメントを投稿した場合、cli-pr-monitorの polling loop が reset 時刻 + 60s buffer まで sleep し@coderabbitai reviewを再投稿する自動化を追加updated_at+ 残り時間 + 1 分バッファ」計算 → 再 trigger を機械化実装
check-ci-coderabbit
parse_rate_limit: CR コメント本文からRate limit exceeded+Please wait N minutes M secondsを検出し、updated_at+ 残時間 + 60s buffer でuntil_unix_secsを計算するparse_iso8601_to_unix: ISO 8601 → unix epoch 秒の手動パース (chrono 依存追加なし、leap year 対応)RateLimitInfoを JSON 出力に追加 (until_unix_secs,comment_created_at,wait_minutes,wait_seconds)cli-pr-monitor
RateLimitConfig:auto_retry_enabled(default true) +max_retries(default 3)state.rate_limit_retries: 累積 retry 回数 (state.json で persist)state.rate_limit_last_retriggered_at: dedup key (advisor 指摘対応)handle_rate_limit_retry: sleep →gh pr comment投稿 → counter++重要: dedup の必要性 (advisor finding)
comment_created_atで dedup しないと、同一 rate-limit comment が iteration を跨いで PR コメント一覧に残り、(until_unix_secs - now).max(0) = 0となって即時 retrigger を繰り返してしまう。結果 max_retries=3 が数秒で消費され誤ってaction_requiredで抜ける。シナリオ (バグなし版):
テスト
check-ci-coderabbit (56 passed)
rate_limit_detected_from_coderabbit_commentrate_limit_picks_latest_when_multiplerate_limit_no_match_when_unrelated_commentrate_limit_no_match_when_no_wait_timerate_limit_ignores_non_coderabbitrate_limit_empty_json_returns_nonewait_time_full_format/wait_time_minutes_only/wait_time_singular_units/wait_time_no_match_returns_noneiso8601_*(4 tests, including leap year)cli-pr-monitor (116 passed)
rate_limit_state_persists_retries_across_pollsrate_limit_default_config_allows_retry_within_limitrate_limit_dedup_skips_repeated_comment(advisor finding カバー)rate_limit_last_retriggered_at_persists_across_pollsupdate_state_populates_rate_limit/update_state_clears_rate_limit_when_absent完了タスク
Test plan
Summary by CodeRabbit