Skip to content

feat(cli-pr-monitor): 順位 141 land — fix_push_time 固定 + RATE_LIMIT_BUT_MERGEABLE signal (順位 140 entry 追加)#170

Merged
aloekun merged 3 commits into
masterfrom
rank-140-141-cr-rate-limit-detection-fix
May 23, 2026
Merged

feat(cli-pr-monitor): 順位 141 land — fix_push_time 固定 + RATE_LIMIT_BUT_MERGEABLE signal (順位 140 entry 追加)#170
aloekun merged 3 commits into
masterfrom
rank-140-141-cr-rate-limit-detection-fix

Conversation

@aloekun
Copy link
Copy Markdown
Owner

@aloekun aloekun commented May 23, 2026

Summary

  • 順位 141 land (Tier 1、PR docs(adr): ADR-041 Test Isolation Patterns + 順位 78 placeholder 化 (順位 139 land) #169 観測由来の CR rate-limit detection bug 修正):
    • 主軸 C: state.jsonfix_push_time field を追加し、wakeup ごとに更新されない固定値を保持。CR walkthrough overlay の updated_atevent_time >= push_time filter で「過去扱い」で除外される構造バグを解消。
    • 早期 merge 判断 signal: rate-limit 検出時に同 process 内で gh pr view --json mergeable,mergeStateStatus を取得、MERGEABLE + CLEAN + 未解決 thread 0 件なら [RATE_LIMIT_BUT_MERGEABLE] signal を stdout 出力。Claude は AskUserQuestion 経由でユーザー判断 (5-10 分で merge / wait を選択) → wall clock を 38 分以上の reset 待ちから短縮。
    • 既存 auto-retry path は維持 (ユーザーが「待つ」を選んだ場合は通常 flow に合流)。
  • 順位 140 entry 追加 (Tier 3、PR docs(adr): ADR-041 Test Isolation Patterns + 順位 78 placeholder 化 (順位 139 land) #169 T3-fix(hooks): stop-quality のパイプデッドロックを修正 #2 採用): 順位 135 codified placeholder policy を正式 ADR に昇格する task entry を queue 追加。本 PR では実装せず、後続 PR で着手予定。
  • 3 commits 構成:
    • Commit 1 (順位 140 docs): entry 追加
    • Commit 2 (順位 141 docs): entry 追加 (shortcut 追加案)
    • Commit 3 (順位 141 実装): Rust 実装 + test 補強 (takt-fix loop で自動追加 3 件含む)

Background

PR #169 セッションで cli-pr-monitor の CR rate-limit 検出機構が、再 push 後の wakeup recheck 経路で構造的に動作不能な状態が systemic 観測された。check-ci-coderabbitparse_rate_limitevent_time >= push_time filter で「過去 session の古い rate-limit comment」を除外する safety guard を持つが、push_timestate.started_at (wakeup ごとに現在時刻に更新される値) を再利用するため、CR の walkthrough overlay の updated_at が push_time より過去になると検出対象から外れる。今回 CR が overlay (06:08:02Z) を投稿したが、wakeup 4 回目の started_at = 06:27:14Z で filter 除外 → rate_limit: null → auto-retry path に乗らず手動介入で merge へ進んだ。

memory feedback_pipeline_over_rules (本セッションで codify) を適用 = 「動作の不確実さはパイプラインで吸収、ルール codify では対処しない」原則の最初の実装事例。当初案 (defense-in-depth + 4 test) はユーザーから「処理時間が増える可能性」の指摘を受け、shortcut 追加案 = 主軸 C + 早期 merge 判断 signal の 2 機能に絞った最小実装に縮小。

Design

主軸 C: fix_push_time 固定

  • PrMonitorStatefix_push_time: Option<String> (legacy 互換)
  • fresh push 経路で fix_push_time = utc_now_iso8601() 設定、wakeup 経路で state から再利用
  • check-ci-coderabbit への --push-time 引数に fix_push_time を優先 (fallback to push_time で legacy 互換)

早期 merge 判断 signal (本 PR の核)

  • finalize_parked 末尾で emit_shortcut_signal_if_eligible(state, rl, pr_info) 呼び
  • evaluate_rate_limit_shortcut pure 関数で 3 条件 (mergeable + clean + threads 0) 評価
  • 条件一致時に [RATE_LIMIT_BUT_MERGEABLE] signal 出力 (PARK signal は引き続き出力、両方を Claude が読む)
  • gh 呼び失敗時は signal 出さず既存 PARK flow に倒す (safety)

CR 仕様変更時の挙動 (graceful degradation)

  • CR の walkthrough overlay format が変わったら主軸 C は壊れるが、誤検出はせず pipeline 静止
  • 「壊れたら再考」方針 (ユーザー判断)、defense-in-depth (補助 B = overlay marker bypass) は当初案から削除して scope 縮小

Files changed

File Nature
src/cli-pr-monitor/src/state.rs PrMonitorState::fix_push_time field 追加 + new() / legacy test / roundtrip test 更新
src/cli-pr-monitor/src/util.rs PrInfo::fix_push_time field 追加 + get_pr_info 初期化
src/cli-pr-monitor/src/stages/create_pr.rs build_pr_info_from_gh_output で fresh push 時に fix_push_time 設定
src/cli-pr-monitor/src/stages/monitor.rs run_monitor_only の fresh/resume 経路で fix_push_time 設定 + resume_fix_push_time_or_started_at helper + init_or_resume_state で state 維持 + 新規 test
src/cli-pr-monitor/src/stages/poll.rs PollContext::fix_push_time 追加 + build_state_for_iteration / finalize_*_park で fix_push_time 維持 + run_one_iteration で effective_push_time 算出 + 早期 merge 判断 signal 一式 (4 関数 + 5 test)
docs/todo-summary.md 順位 140 + 141 行追加
docs/todo8.md 順位 140 + 141 詳細 entry 追加

Test plan

  • cargo test -p cli-pr-monitor: 188 passed / 0 failed (新規 8 件 + 既存 180 件、takt-fix で自動補強 3 件含む)
  • cargo test -p check-ci-coderabbit: 79 passed / 0 failed (regression なし、本 PR は check-ci-coderabbit 側 logic は不変、呼び出し側で push_time に fix_push_time を優先するだけ)
  • pnpm build:all: 全 5 exe ビルド + .claude/ deploy 成功
  • markdownlint: docs ファイル全 0 error
  • pre-push-review: APPROVE (2 iterations, 18m 33s、convergence_verdict: fully_resolved)
  • 自動追加 test (takt-fix loop):
    • resume_returns_fix_push_time_from_state_when_set (monitor.rs): helper の Case A 検証
    • finalize_initial_review_park_preserves_existing_fix_push_time (poll.rs): non-None preservation
    • finalize_review_recheck_park_preserves_existing_fix_push_time (poll.rs): sibling parity

Notes

  • 順位 141 entry (todo8.md) は本 PR land 後の post-merge-feedback サイクルで削除予定 (memory: feedback_todo_no_history)。
  • 順位 140 entry は 本 PR では実装せず、後続 PR で着手 (順位 135 ADR 昇格は別タスク)。
  • 本セッション中に memory feedback_pipeline_over_rules.md を codify、本 PR がその最初の実装事例。
  • signal 出力後の Claude 側 AskUserQuestion 処理は本 PR scope 外 (signal を読んで判断する Claude 側の流れは memory + AskUserQuestion tool で対応)。

Summary by CodeRabbit

  • Documentation

    • ADR(アーキテクチャ決定記録)の採番戦略を正式化し、プロセスを明確化しました。
  • Bug Fixes

    • PR監視機能のレート制限検出精度を向上させ、マージ可能状態の判定を改善しました。

Review Change Stack

aloekun added 3 commits May 22, 2026 17:32
…er policy を ADR 昇格)

PR #169 post-merge-feedback の Tier 3 #2 採用結果として、順位 135
「ADR 番号 hardcode 撤廃 placeholder policy」を正式 ADR に昇格する task を
順位 140 として登録。PR #111/#132/#169 の 3 PR で適用実証済 (特に PR #169 で
順位 78 が ADR-038 → 041 → NNN の 3 段振り直し dogfood を完了) で、現在は
ephemeral todo entry 内の codify 限り = 派生プロジェクトへの transferability
不足を解消する目的。ADR 番号は順位 135 policy 自身に従い ADR-NNN placeholder
で登録 (= self-dogfood)、land 時 PR で確定する。
…案: fix_push_time 固定 + 早期 merge 判断 signal)

PR #169 セッションで systemic 観測された CR rate-limit detection bug を順位 141
として登録。当初案 (defense-in-depth + 4 test) はユーザーから「処理時間が増える可能性」
の指摘を受け、shortcut 追加案 = 主軸 C (fix_push_time 固定) + 早期 merge 判断 signal
(mergeable CLEAN なら 5-10 分で人間判断) の 2 機能に絞った最小実装に書き換え。

feedback_pipeline_over_rules.md 適用 = ルール codify ではなくパイプライン側の機械的
修正で Claude 判断介入を排除する原則の最初の実装事例。既存 auto-retry path は維持し、
ユーザーが「待つ」を選んだ場合は通常 flow に合流する設計で、wall clock (rate-limit
reset 38 分 + retry 最大 2.5 時間) と手間軽減のバランスを取る。
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e0e6ca93-e286-4cfe-b060-6bc61cc74646

📥 Commits

Reviewing files that changed from the base of the PR and between 1fba8b6 and 8eb1021.

📒 Files selected for processing (7)
  • docs/todo-summary.md
  • docs/todo8.md
  • src/cli-pr-monitor/src/stages/create_pr.rs
  • src/cli-pr-monitor/src/stages/monitor.rs
  • src/cli-pr-monitor/src/stages/poll.rs
  • src/cli-pr-monitor/src/state.rs
  • src/cli-pr-monitor/src/util.rs

📝 Walkthrough

Walkthrough

cli-pr-monitor の rate-limit 検出ロジックに fix_push_time フィールドを導入し、push_time の正確性を確保。rate-limit 検出時に mergeable 状態を確認して [RATE_LIMIT_BUT_MERGEABLE] signal を出力し、ユーザーが即 merge または待機を選択可能に。永続化とテスト・ドキュメント整合化を完備。

Changes

rate-limit 検出の正確性向上と早期 merge 判定

Layer / File(s) Summary
データ構造と状態管理:fix_push_time フィールド追加
src/cli-pr-monitor/src/util.rs, src/cli-pr-monitor/src/state.rs, src/cli-pr-monitor/src/stages/poll.rs
PrInfo / PrMonitorState / PollContextfix_push_time: Option<String> を追加。serde の defaultskip_serializing_if で legacy JSON 互換を確保。
初期値設定フロー:create_pr から monitor への fix_push_time 伝播
src/cli-pr-monitor/src/stages/create_pr.rs, src/cli-pr-monitor/src/stages/monitor.rs
build_pr_info_from_gh_output で取得した push_time を PrInfo.fix_push_time にも設定。monitor の初期化・再開時に state へ反映し、resume 時の time filter を確実化。resume_fix_push_time_or_started_at ヘルパーで state 優先フォールバック制御。
ポーリング実行と rate-limit shortcut signal:mergeable 早期判定
src/cli-pr-monitor/src/stages/poll.rs
PollContext で effective_push_time を決定し state への write-once 保持を実装。rate-limit park 処理に emit_shortcut_signal_if_eligible / fetch_mergeable_status / evaluate_rate_limit_shortcut を追加し、mergeable=CLEAN かつ未解決 thread=0 の場合に [RATE_LIMIT_BUT_MERGEABLE] signal を stdout に出力。MergeableStatus DTO で mergeable 情報を構造化。
テスト・ドキュメント整合化
src/cli-pr-monitor/src/stages/monitor.rs, src/cli-pr-monitor/src/stages/poll.rs, docs/todo-summary.md, docs/todo8.md
各テストで新フィールド fix_push_time を None で初期化。write-once 不変性・state 優先・shortcut signal 条件評価・fidelity ケースのテスト追加。ヘルパー pr_info_for_initial_review_park_test / make_default_test_ctx で ctx/PrInfo 生成を集約。todo ドキュメント(順位 140/141)に ADR 採番運用と rate-limit 修正計画を記載。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • aloekun/claude-code-hook-test#97: 本 PR は cli-pr-monitor の rate-limit flow 内で push_time の正確性を確保する fix_push_time を追加する一方、当該 PR は push_time 比較に基づく rate-limit auto-detection/retrigger を実装しており、同一の rate-limit 判定ロジックに直接依存。
  • aloekun/claude-code-hook-test#113: 本 PR が stages/poll.rsfinalize_parked 周りに shortcut signal や fix_push_time 優先化を追加する一方、当該 PR は rate-limit を PARK モデルへ移行する stages/poll.rs / state.rs 変更を導入しており、同一の parked_rate_limit 領域で直結。
  • aloekun/claude-code-hook-test#158: 本 PR と同様に docs/todo-summary.md / docs/todo8.md の ADR 採番運用(rank 135 placeholder ADR-XXX vs 固定番号)に関するドキュメント変更が含まれており、方針の整合性に関連。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR のタイトルは、主な変更内容(fix_push_time 固定化と RATE_LIMIT_BUT_MERGEABLE シグナル追加、及び順位 140 エントリ追加)を明確かつ具体的に記述しており、チェンジセット全体の主要な目的を正確に反映している。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aloekun aloekun merged commit d713d7a into master May 23, 2026
1 check passed
@aloekun aloekun deleted the rank-140-141-cr-rate-limit-detection-fix branch May 23, 2026 05:04
aloekun added a commit that referenced this pull request May 24, 2026
…171)

* docs(todo): 順位 142 新規追加 — PR #170 T3-#1 採用 (ADR-041 補強: State Preservation Invariant pattern)

PR #170 post-merge-feedback の Tier 3 #1 採用結果として、ADR-041
(Test Isolation Patterns for Multi-Condition Guards) に新 section
"State Preservation Invariant" (once-set-never-overwritten) を
追記する task を 順位 142 として登録。

PR #168/169/170 で write-once 不変式 (state.fix_push_time.or_else(...)
形式) のテストカバレッジ漏れが連続観測されたことが trigger。ADR-041 既存
section は Multi-Condition Guards (early-return) のみで、write-once 不変式は
別 pattern class として未収録だったため補強する。順位 141 で takt-fix が
自動追加した 3 件の preservation test (poll.rs / monitor.rs) を参照実装と
して cite し、3 点セット test pattern (既存値あり / 新値提供 / preservation
確認) を明文化する。

* test(hooks-linter): UTF-8 multi-byte content での line 算出 defensive test 追加 (順位 125 採用)

PR #151 (T2-#1) で hooks-post-tool-comment-lint-rust の byte_offset_to_line を multi-byte
boundary test 拡充で production bug を発見した経験を横展開。hooks-post-tool-linter の
build_violation_json (L500) は content[..m.start()] による str slicing を行うが、
regex::Match::start() が char boundary を保証するため panic 安全。

本 test は line 算出 (.bytes().filter(|b| *b == b'\n').count() + 1) が multi-byte content
(日本語/emoji/結合文字) でも正しく動作することを empirical に seal する。将来 char_indices()
ベースへの書き換え等で line off-by-one regression が入った場合に検知する。

string-processing 系の hooks のうち他 (pre-tool-validate / session-start / stop-quality /
user-prompt-feedback-recovery / stop-feedback-dispatch) は as_bytes() を write 用途で
使用するのみで offset 操作を持たないため横展開 scope 外。

* test(hooks-comment-lint-rust): collect_all_violations の MAX_VIOLATIONS truncate contract test 追加 (順位 57 採用)

collect_all_violations (L551) は find_violations と find_function_length_violations の両 source を extend した後に truncate(MAX_VIOLATIONS) で合計を cap する設計。既存 cap test (max_violations_capped / function_length_violations_capped) は各 source 単体の cap のみ検証し、合算 truncate の contract が機械強制されていなかった gap を補填。

将来の lint 追加時に L562 の truncate(MAX_VIOLATIONS) を削除した regression (= 合計が MAX を超える) を catch する explicit 安全網。

fixture: 長 function (55 行 > MAX_FUNCTION_LINES=50) 1 件 + 非 doc コメント 25 行 → find_function_length_violations 1 件 + find_violations が cap で 20 件 → 合計 21 件 → truncate 後 20 件に cap される contract を assert。

* docs(todo): 順位 91 [lint_screen] config parse test を既実装発見で削除 (memory feedback_verify_task_not_already_done.md 適用)

PR #132 (Phase c MVP land = 2026-05-09) 直後の post-merge-feedback で entry 化された
順位 91 だが、本セッション着手前の jj log + 既存 test 確認で src/cli-push-runner/src/config.rs
の test module L325-481 に既に 5 件の lint_screen parse test が存在することを発見:

  - config_parses_with_lint_screen_section_full_fields (L326): 全 7 field deserialize
  - config_parses_with_lint_screen_section_minimal_only_enabled (L370): enabled=false でも Some 構築
  - config_lint_screen_section_absent_yields_none (L402): section 不在 → None
  - config_lint_screen_numeric_defaults_resolve_via_constants (L441): default 値 fallback
  - config_lint_screen_string_defaults_resolve_via_constants (L456): default 値 fallback

entry の作業計画 4 項目はすべてカバー済 (silent field rename 防止 / 全 field deserialize /
section 不在時 None / default 値検証)。post-merge-feedback で採用された後、別 PR で
先行 land 済だった可能性が高い。

memory rule feedback_verify_task_not_already_done.md (todo 着手前に既実装検証 → stale
entry を削除に再目的化) の正典的 dogfood 例として価値あり。Bundle i のペアタスク 順位 92
(scale-aware eval fixtures) は別タスクとして残し、bundle 表記は historical note 化。

- docs/todo6.md: 順位 91 entry (L13-39) 削除
- docs/todo-summary.md: 順位 91 行削除 + 順位 92 行を独立タスクとして修正
aloekun added a commit that referenced this pull request May 25, 2026
* docs(adr): ADR-042 ルール vs 仕組み化の境界基準 — 試験運用 ADR 新設 + CLAUDE.md ADR list 追加

* docs(todo): 仕組み化方針切替 — todo9.md 新設 + 順位 142/143/144/145 + 146-151 追加 + 順位 44/61 hook 化転換 + 122→136 統合 (Bundle 既存ルール仕組み化)

PR #172 (順位 144 = jj-message-required hook) の dogfood 成功を受けた仕組み化方針切替に関する一連の todo system 更新:

- 順位 142 entry 追加 (PR #170 T3-#1 採用 ADR-041 補強 State Preservation Invariant pattern)
- 順位 143/144 entry 追加 (PR #171 post-merge-feedback Bundle 171 = 複言語 fixture helper + jj-message-required hook)
- 順位 145 entry 追加 (PR #172 T2-#1 採用 preset matrix test)
- 順位 146-151 entry 新規追加 (既存ルール仕組み化バンドル: secret detection / file length lint / test coverage CI gate / subprocess pipe truncate hook 拡張 / magic number lint / PR diff lines check)
- 順位 44 (gh CLI 使用規則) を docs 追記から PreToolUse hook 化方針に転換
- 順位 61 (CR review.body 手動 scan) を docs 追記から check-ci-coderabbit CLI 拡張方針に転換
- 順位 122 (新 todo 着手前の既実装確認) を 順位 136 (working copy staleness hook) に統合
- todo9.md 新設 (todo8.md 50KB 接近のため、新規追加先を todo9.md に移行)
- todo-summary.md 更新方針 + table 更新 + Bundle 171 タグ整備

memory rule `feedback_pipeline_over_rules.md` 適用 = rule docs → mechanism shift の体系的記録。

* chore(todo): land 済 entry 削除 + bundle-history 分離 (size 50KB 超過解消)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant