Skip to content

docs: PR-W5 (#234) land 反映 + post-merge-feedback 採用 3 件を todo 登録 (順位 248-250) - #237

Merged
aloekun merged 1 commit into
masterfrom
pr-w5-followup-docs
Jul 2, 2026
Merged

docs: PR-W5 (#234) land 反映 + post-merge-feedback 採用 3 件を todo 登録 (順位 248-250)#237
aloekun merged 1 commit into
masterfrom
pr-w5-followup-docs

Conversation

@aloekun

@aloekun aloekun commented Jul 2, 2026

Copy link
Copy Markdown
Owner

概要

PR-W5 (#234, file-length Stop gate) の land 反映と、その post-merge-feedback で承認された再発防止策 3 件の todo 登録を行うドキュメント PR。docs-only (ADR-035)。

変更内容

1. docs/file-length-enforcement-plan.md

  • PR-W5 status を [x] land 済 (#234, merged 2026-07-02T12:06:37Z) に更新
  • 進捗追跡ブロックの PR-W5 を [x] #234 に更新
  • 削除条件の進捗を追記: ① 全 W0〜W5 land 済 ✅ / ② 800 行超 0 件 (weekly audit で確認) ⏳ / ③ override 未使用で 1-2 セッション dogfood 通過 ⏳

2. post-merge-feedback (#234) 採用 3 件を todo 登録 (順位 248-250)

docs/todo-summary.md (採番テーブル) + docs/todo13.md (詳細エントリ):

順位 Tier 内容 Effort
248 💎 Tier 3 Gate Function Design Checklist (fail-closed パターン集) 新規 guide S
249 💎 Tier 3 ADR-043 に fail-open vs fail-closed の具体コード例を追記 S
250 💎 Tier 3 ADR-021 に「jj revset の base branch は config/arg 化 (hardcode 禁止)」明文化 XS

いずれも #234 で遭遇した論点(.ok()? fail-open bug、jj revset base branch の hardcode)の一般化。却下推奨だった linter 化 2 件 (T1-1/T1-2、FP 多発) の代替として T3-1 のドキュメント化を採用。

除外: feedback T2-2 (test_addition) は実体が doc comment 追加のみで T3 相当のため、独立 test 項目としては未登録 (analyzer の分類誤りをユーザー判断で除外)。

補足

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@aloekun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 84838e44-0c82-4dbe-879b-a40f898dc5ef

📥 Commits

Reviewing files that changed from the base of the PR and between 514d137 and f3bdff9.

📒 Files selected for processing (3)
  • docs/file-length-enforcement-plan.md
  • docs/todo-summary.md
  • docs/todo13.md

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.

@aloekun
aloekun merged commit f60146b into master Jul 2, 2026
1 check passed
@aloekun
aloekun deleted the pr-w5-followup-docs branch July 2, 2026 15:45
aloekun added a commit that referenced this pull request Aug 3, 2026
cli-pr-monitor を「1 回 check して必ず terminal 報告で終了する」モデルへ移行する。
旧 Bb-1/Bb-2 の park モデル (未確定なら state に wakeup 時刻を書き、[PR_MONITOR_PARK]
envelope で Claude に CronCreate 予約を依頼し、発火時の再 invoke で継続する) を撤去した。

## なぜ廃止するか (ADR-018 amendment)

- wakeup はローカルセッションの寿命に依存する。PR #237 でセッション終了による
  CronCreate 失効 = 監視の取りこぼしを実観測した。
- WP-17 で GitHub Actions 経路 (pr-monitor workflow の Phase A/B) が常設になった。
  CodeRabbit のレビュー到着・後続コメントがそのままトリガーになるため、ローカルの
  時限 wakeup は冗長になった。

## 挙動の変化

- 未確定 (review 未完) → 旧: park + wakeup 予約 / 新: terminal `pending_review` 報告
  (「後続は GitHub Actions 経路が処理」を明示。ADR-064 の陽性証拠原則どおり
  pending を silent success に見せない)
- rate-limit reset 待ち → 旧: park / 新: terminal `rate_limited` 報告 (ADR-064 (b) の
  保留判定文を維持)。reset 経過後の即時 retrigger 投稿と comment dedup は残す
- fresh push → 旧: checker を呼ばず initial park / 新: 即 1 回 check して報告

## 残したもの (park の付随物ではないため)

- **時刻窓アンカーの継続** (`should_continue_state`): 同一 PR + 同一 head なら
  state.started_at / fix_push_time を維持する。これを落とすと再実行のたびに
  `--push-time` が「今」になり、push 後に届いた CR コメントが新着判定から漏れる。
  旧 `should_resume_wakeup` から wakeup 時刻経過の条件だけを外した形
- rate_limit_retries / rate_limit_last_retriggered_at (dedup と retry 上限は
  invocation 跨ぎで引き続き意味を持つ)
- **順位 141 の mergeable shortcut** (`[RATE_LIMIT_BUT_MERGEABLE]` signal):
  「rate-limit 中でも既に mergeable なら即 merge を選べる」独立機能で、park の
  付随物ではない。初版 diff は rate_limit_signal.rs の削除に巻き込んで silent に
  消しており、pre-push simplicity review が REJECT
  (SIM-NEW-src-cli-pr-monitor-rate_limit-L138: 他の撤去物は全て ADR/計画書に
  列挙されているのに shortcut だけ無言で消えている = 意図の疑い) → fix step が
  rate_limit.rs へテストごと復元した (実測検証済み)。terminal 化した
  `finalize_waiting_reset` から引き続き発火する。signal 文面の選択肢 B は
  single-shot 後の実態 (Actions 経路 / --monitor-only 再実行) に合わせて更新

## 撤去したもの

- state: next_wakeup_at_unix / wakeup_reason / review_recheck_count (旧 state file に
  残っていても unknown field として無視される — 前方互換テストを追加)
- poll: review_recheck.rs / review_recheck_signal.rs (park scheduling と PARK envelope
  整形の全量)。rate_limit_signal.rs はファイルとしては削除したが、上記のとおり
  shortcut 部分は rate_limit.rs へ移設して維持
- config: [review_recheck] セクションと sanitize / overflow 検査 (wakeup 時刻の加算
  演算ごと消滅)、monitor.max_duration_secs (ループ上限)。旧 config は unknown
  field/section として無視される — 前方互換テストを追加

検証: cargo test -p cli-pr-monitor 224 件 pass、workspace 全緑、
clippy --workspace -D warnings 緑。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aloekun added a commit that referenced this pull request Aug 3, 2026
cli-pr-monitor を「1 回 check して必ず terminal 報告で終了する」モデルへ移行する。
旧 Bb-1/Bb-2 の park モデル (未確定なら state に wakeup 時刻を書き、[PR_MONITOR_PARK]
envelope で Claude に CronCreate 予約を依頼し、発火時の再 invoke で継続する) を撤去した。

## なぜ廃止するか (ADR-018 amendment)

- wakeup はローカルセッションの寿命に依存する。PR #237 でセッション終了による
  CronCreate 失効 = 監視の取りこぼしを実観測した。
- WP-17 で GitHub Actions 経路 (pr-monitor workflow の Phase A/B) が常設になった。
  CodeRabbit のレビュー到着・後続コメントがそのままトリガーになるため、ローカルの
  時限 wakeup は冗長になった。

## 挙動の変化

- 未確定 (review 未完) → 旧: park + wakeup 予約 / 新: terminal `pending_review` 報告
  (「後続は GitHub Actions 経路が処理」を明示。ADR-064 の陽性証拠原則どおり
  pending を silent success に見せない)
- rate-limit reset 待ち → 旧: park / 新: terminal `rate_limited` 報告 (ADR-064 (b) の
  保留判定文を維持)。reset 経過後の即時 retrigger 投稿と comment dedup は残す
- fresh push → 旧: checker を呼ばず initial park / 新: 即 1 回 check して報告

## 残したもの (park の付随物ではないため)

- **時刻窓アンカーの継続** (`should_continue_state`): 同一 PR + 同一 head なら
  state.started_at / fix_push_time を維持する。これを落とすと再実行のたびに
  `--push-time` が「今」になり、push 後に届いた CR コメントが新着判定から漏れる。
  旧 `should_resume_wakeup` から wakeup 時刻経過の条件だけを外した形
- rate_limit_retries / rate_limit_last_retriggered_at (dedup と retry 上限は
  invocation 跨ぎで引き続き意味を持つ)
- **順位 141 の mergeable shortcut** (`[RATE_LIMIT_BUT_MERGEABLE]` signal):
  「rate-limit 中でも既に mergeable なら即 merge を選べる」独立機能で、park の
  付随物ではない。初版 diff は rate_limit_signal.rs の削除に巻き込んで silent に
  消しており、pre-push simplicity review が REJECT
  (SIM-NEW-src-cli-pr-monitor-rate_limit-L138: 他の撤去物は全て ADR/計画書に
  列挙されているのに shortcut だけ無言で消えている = 意図の疑い) → fix step が
  rate_limit.rs へテストごと復元した (実測検証済み)。terminal 化した
  `finalize_waiting_reset` から引き続き発火する。signal 文面の選択肢 B は
  single-shot 後の実態 (Actions 経路 / --monitor-only 再実行) に合わせて更新
- **rate-limit 系 terminal での head_commit 保存**: 2 回目の pre-push review が、
  `finalize_waiting_reset` / `finalize_posted_retrigger` で head_commit 保存が
  落ちている回帰を REJECT で検出 (SIM-NEW-rate_limit-L154: 保存が無いと次回
  `--monitor-only` の継続判定が fresh 初期化に倒れ、時刻窓リセットで CR コメントを
  取りこぼす — 本 PR 自身が動機に挙げた incident class の再導入)。fix step が
  両関数への保存 + 回帰テスト 2 件を追加した (実測検証済み)

## 撤去したもの

- state: next_wakeup_at_unix / wakeup_reason / review_recheck_count (旧 state file に
  残っていても unknown field として無視される — 前方互換テストを追加)
- poll: review_recheck.rs / review_recheck_signal.rs (park scheduling と PARK envelope
  整形の全量)。rate_limit_signal.rs はファイルとしては削除したが、上記のとおり
  shortcut 部分は rate_limit.rs へ移設して維持
- config: [review_recheck] セクションと sanitize / overflow 検査 (wakeup 時刻の加算
  演算ごと消滅)、monitor.max_duration_secs (ループ上限)。旧 config は unknown
  field/section として無視される — 前方互換テストを追加

検証: cargo test -p cli-pr-monitor 226 件 pass、workspace 全緑、
clippy --workspace -D warnings 緑。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
aloekun added a commit that referenced this pull request Aug 3, 2026
…bit #353)

PR #353 の CodeRabbit 指摘 3 件への対応。うち 2 件は本 PR が持ち込んだ実バグだった。

## 指摘 2 (Minor): terminal 化 3 経路が head_commit を None で上書きする

`finalize_pending_review` / `finalize_waiting_reset` / `finalize_posted_retrigger` が
`state.head_commit = pr_info.head_commit.clone()` と**無条件代入**していた。
`util::get_pr_head_commit` は gh 失敗を None に潰すため、API 障害のたびに保存済み OID が
消える。その状態で次回 `--monitor-only` を実行すると `should_continue_state` が None を
見て継続を拒否し、時刻窓アンカーが「今」へリセットされて間に届いた CR コメントを
取りこぼす — 本 PR が動機に挙げた incident class (#237/#307/#309) と同型。

CodeRabbit が「共通の根本原因」と指摘したとおり 3 経路に同じ欠陥があったため、
`PrMonitorState::record_head_commit(Option<&str>)` を state.rs に置き、Some のときだけ
上書きする単一実装へ集約した。取得失敗は「head が変わった」の証拠ではないので既存値の
保持が正しい (fail-safe)。回帰テスト 2 件 (None で消えない / Some で上書きする) を追加。

## 指摘 3 (Minor): テストが実 gh CLI を呼ぶ

`finalize_waiting_reset` は内部で `fetch_mergeable_status` → `run_gh_quiet` を呼ぶため、
前コミットで追加した回帰テストが実 gh プロセスを起動していた (ネットワーク依存・低速)。

`finalize_waiting_reset_with(..., fetch_mergeable: impl FnOnce(&PrInfo) -> Option<..>)`
へ本体を切り出し、production は `fetch_mergeable_status` を、テストは closure を渡す形に
した (cli-push-runner の `verify_diff_covers_pr_range` と同じ注入の流儀)。

あわせて「注入したものが実際に使われている」ことを確認するテストを追加した — `|_| None`
を渡すだけのテストでは、fetcher を無視する実装でも通ってしまい注入の正しさを判別できない。
Cell フラグで呼び出し自体を観測する。

## 指摘 1 (Minor): 計画書の stale な park 検証残

「WP-15 追補残: レート制限 park の実観測」は park 廃止で (a) が moot になっていた。
見出しを「レート制限時の保留保証 (GitHub Actions 経路)」へ改め、(a) の終了と (b) の
引き継ぎ先を明記した (ADR-018 amendment / ADR-064 ステータス欄と同じ内容を計画書側にも
反映し、3 箇所の記述を揃える)。

検証: cargo test --workspace 1905 件 pass (新規 4 件)、clippy --workspace -D warnings 緑、
pnpm lint:docs / lint:md 0 error。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aloekun added a commit that referenced this pull request Aug 3, 2026
…d 回帰復元 (CodeRabbit #353)

PR #353 のレビュー指摘への対応。CodeRabbit 3 件 + pre-push simplicity 1 件で、
**4 件中 3 件は本 PR が持ち込んだ実バグ / カバレッジ欠落**だった。

## CodeRabbit 指摘 2 (Minor): terminal 化 3 経路が head_commit を None で上書きする

`finalize_pending_review` / `finalize_waiting_reset` / `finalize_posted_retrigger` が
`state.head_commit = pr_info.head_commit.clone()` と**無条件代入**していた。
`util::get_pr_head_commit` は gh 失敗を None に潰すため、API 障害のたびに保存済み OID が
消える。その状態で次回 `--monitor-only` を実行すると `should_continue_state` が None を
見て継続を拒否し、時刻窓アンカーが「今」へリセットされて間に届いた CR コメントを
取りこぼす — 本 PR が動機に挙げた incident class (#237/#307/#309) と同型。

CodeRabbit が「共通の根本原因」と指摘したとおり 3 経路に同じ欠陥があったため、
`PrMonitorState::record_head_commit(Option<&str>)` を state.rs に置き、Some のときだけ
上書きする単一実装へ集約した。取得失敗は「head が変わった」の証拠ではないので既存値の
保持が正しい (fail-safe)。回帰テスト 2 件 (None で消えない / Some で上書きする) を追加。

## CodeRabbit 指摘 3 (Minor): テストが実 gh CLI を呼ぶ

`finalize_waiting_reset` は内部で `fetch_mergeable_status` → `run_gh_quiet` を呼ぶため、
前コミットで追加した回帰テストが実 gh プロセスを起動していた (ネットワーク依存・低速)。

`finalize_waiting_reset_with(..., fetch_mergeable: impl FnOnce(&PrInfo) -> Option<..>)`
へ本体を切り出し、production は `fetch_mergeable_status` を、テストは closure を渡す形に
した (cli-push-runner の `verify_diff_covers_pr_range` と同じ注入の流儀)。

あわせて「注入したものが実際に使われている」ことを確認するテストを追加した — `|_| None`
を渡すだけのテストでは、fetcher を無視する実装でも通ってしまい注入の正しさを判別できない。
Cell フラグで呼び出し自体を観測する。

## pre-push simplicity 指摘 (SIM-NEW-rate_limit-L122, Medium): fail-closed 回帰の消失

tests.rs のファイル分割時に `finalize_posted_retrigger_action_required_when_write_state_fails`
だけが欠落していた。この関数は 2 つの sibling (`finalize_waiting_reset` /
`finalize_pending_review`) と**逆に fail-closed** で、理由は `@coderabbitai review` 投稿と
いう副作用を伴うため state 永続化の成否で重複投稿を防ぐ必要があるから。fail-open 側 2 件の
回帰テストは移行されていたのに、意図的に非対称な唯一の経路のテストが落ちていた。復元し、
非対称の理由を doc comment に明記した。

## CodeRabbit 指摘 1 (Minor): 計画書の stale な park 検証残

「WP-15 追補残: レート制限 park の実観測」は park 廃止で (a) が moot になっていた。
見出しを「レート制限時の保留保証 (GitHub Actions 経路)」へ改め、(a) の終了と (b) の
引き継ぎ先を明記した (ADR-018 amendment / ADR-064 ステータス欄と同じ内容を計画書側にも
反映し、3 箇所の記述を揃える)。

検証: cargo test --workspace 1906 件 pass (新規 5 件)、clippy --workspace -D warnings 緑、
pnpm lint:docs / lint:md 0 error。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aloekun added a commit that referenced this pull request Aug 3, 2026
… 3) (#353)

* refactor(pr-monitor): CronCreate park モデルを撤去し single-shot 化 (WP-17 PR 3)

cli-pr-monitor を「1 回 check して必ず terminal 報告で終了する」モデルへ移行する。
旧 Bb-1/Bb-2 の park モデル (未確定なら state に wakeup 時刻を書き、[PR_MONITOR_PARK]
envelope で Claude に CronCreate 予約を依頼し、発火時の再 invoke で継続する) を撤去した。

## なぜ廃止するか (ADR-018 amendment)

- wakeup はローカルセッションの寿命に依存する。PR #237 でセッション終了による
  CronCreate 失効 = 監視の取りこぼしを実観測した。
- WP-17 で GitHub Actions 経路 (pr-monitor workflow の Phase A/B) が常設になった。
  CodeRabbit のレビュー到着・後続コメントがそのままトリガーになるため、ローカルの
  時限 wakeup は冗長になった。

## 挙動の変化

- 未確定 (review 未完) → 旧: park + wakeup 予約 / 新: terminal `pending_review` 報告
  (「後続は GitHub Actions 経路が処理」を明示。ADR-064 の陽性証拠原則どおり
  pending を silent success に見せない)
- rate-limit reset 待ち → 旧: park / 新: terminal `rate_limited` 報告 (ADR-064 (b) の
  保留判定文を維持)。reset 経過後の即時 retrigger 投稿と comment dedup は残す
- fresh push → 旧: checker を呼ばず initial park / 新: 即 1 回 check して報告

## 残したもの (park の付随物ではないため)

- **時刻窓アンカーの継続** (`should_continue_state`): 同一 PR + 同一 head なら
  state.started_at / fix_push_time を維持する。これを落とすと再実行のたびに
  `--push-time` が「今」になり、push 後に届いた CR コメントが新着判定から漏れる。
  旧 `should_resume_wakeup` から wakeup 時刻経過の条件だけを外した形
- rate_limit_retries / rate_limit_last_retriggered_at (dedup と retry 上限は
  invocation 跨ぎで引き続き意味を持つ)
- **順位 141 の mergeable shortcut** (`[RATE_LIMIT_BUT_MERGEABLE]` signal):
  「rate-limit 中でも既に mergeable なら即 merge を選べる」独立機能で、park の
  付随物ではない。初版 diff は rate_limit_signal.rs の削除に巻き込んで silent に
  消しており、pre-push simplicity review が REJECT
  (SIM-NEW-src-cli-pr-monitor-rate_limit-L138: 他の撤去物は全て ADR/計画書に
  列挙されているのに shortcut だけ無言で消えている = 意図の疑い) → fix step が
  rate_limit.rs へテストごと復元した (実測検証済み)。terminal 化した
  `finalize_waiting_reset` から引き続き発火する。signal 文面の選択肢 B は
  single-shot 後の実態 (Actions 経路 / --monitor-only 再実行) に合わせて更新
- **rate-limit 系 terminal での head_commit 保存**: 2 回目の pre-push review が、
  `finalize_waiting_reset` / `finalize_posted_retrigger` で head_commit 保存が
  落ちている回帰を REJECT で検出 (SIM-NEW-rate_limit-L154: 保存が無いと次回
  `--monitor-only` の継続判定が fresh 初期化に倒れ、時刻窓リセットで CR コメントを
  取りこぼす — 本 PR 自身が動機に挙げた incident class の再導入)。fix step が
  両関数への保存 + 回帰テスト 2 件を追加した (実測検証済み)

## 撤去したもの

- state: next_wakeup_at_unix / wakeup_reason / review_recheck_count (旧 state file に
  残っていても unknown field として無視される — 前方互換テストを追加)
- poll: review_recheck.rs / review_recheck_signal.rs (park scheduling と PARK envelope
  整形の全量)。rate_limit_signal.rs はファイルとしては削除したが、上記のとおり
  shortcut 部分は rate_limit.rs へ移設して維持
- config: [review_recheck] セクションと sanitize / overflow 検査 (wakeup 時刻の加算
  演算ごと消滅)、monitor.max_duration_secs (ループ上限)。旧 config は unknown
  field/section として無視される — 前方互換テストを追加

検証: cargo test -p cli-pr-monitor 226 件 pass、workspace 全緑、
clippy --workspace -D warnings 緑。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(hooks-session-start): pr_monitor catch-up nudge を撤去 (WP-17 PR 3)

pr_monitor catch-up nudge (Bb-3) は「park 中にセッションが終了して CronCreate が失効
した場合の救済」だった。park/wakeup モデルの廃止 (同 PR の cli-pr-monitor 変更) に伴い
救済対象の状態が存在しなくなるため、機構ごと撤去する。

- hooks-session-start: pr_monitor.rs module 削除 + main.rs の配線解除
- .claude/hooks-config.toml: telemetry registry から `pr_monitor_catchup` id を除去
  (過去の firings jsonl には残るが現役 id ではない)。あわせて、どのコードも読んで
  いなかった daemon 時代 (ADR-009) の死に設定 [post_pr_monitor] セクションを撤去
  (現行の監視設定はリポジトリルートの pr-monitor-config.toml が正)
- cli-telemetry-report: doc comment の例示 id を現役のものへ差し替え

検証: cargo test --workspace 1893 件 pass、clippy --workspace -D warnings 緑。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(adr): ADR-018 amendment (park モデル廃止) + ADR-064/034 整合 + 計画書 (WP-17 PR 3)

- ADR-018 追記 (2026-08-03): park モデル廃止の決定・根拠・維持したもの (時刻窓アンカー
  の state 継続 / rate-limit dedup) を記録。ADR-064 検証残の移し替え ((a) park 実観測は
  moot / (b) 判定文の保留保証は Actions 経路の検証残へ) を明記
- ADR-064 ステータス欄: 同じ移し替えを検証残の側からも記載 (両方に記録して検証の穴を
  残さない — 計画書の着手前決定 2)
- ADR-034: Bundle b の CronCreate park モデル記述に「廃止済み、歴史記録として読む」
  注記を追加
- 計画書: PR 3 を実施中に更新し、実装で確定した設計判断 (should_continue_state を残す
  理由) と「本 PR の PR がスモーク段 1 の観測対象を兼ねる」ことを記載

検証: pnpm lint:docs / lint:md 0 error。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(pr-monitor): head_commit の None 上書き防止 + テストの gh 依存除去 + fail-closed 回帰復元 (CodeRabbit #353)

PR #353 のレビュー指摘への対応。CodeRabbit 3 件 + pre-push simplicity 1 件で、
**4 件中 3 件は本 PR が持ち込んだ実バグ / カバレッジ欠落**だった。

## CodeRabbit 指摘 2 (Minor): terminal 化 3 経路が head_commit を None で上書きする

`finalize_pending_review` / `finalize_waiting_reset` / `finalize_posted_retrigger` が
`state.head_commit = pr_info.head_commit.clone()` と**無条件代入**していた。
`util::get_pr_head_commit` は gh 失敗を None に潰すため、API 障害のたびに保存済み OID が
消える。その状態で次回 `--monitor-only` を実行すると `should_continue_state` が None を
見て継続を拒否し、時刻窓アンカーが「今」へリセットされて間に届いた CR コメントを
取りこぼす — 本 PR が動機に挙げた incident class (#237/#307/#309) と同型。

CodeRabbit が「共通の根本原因」と指摘したとおり 3 経路に同じ欠陥があったため、
`PrMonitorState::record_head_commit(Option<&str>)` を state.rs に置き、Some のときだけ
上書きする単一実装へ集約した。取得失敗は「head が変わった」の証拠ではないので既存値の
保持が正しい (fail-safe)。回帰テスト 2 件 (None で消えない / Some で上書きする) を追加。

## CodeRabbit 指摘 3 (Minor): テストが実 gh CLI を呼ぶ

`finalize_waiting_reset` は内部で `fetch_mergeable_status` → `run_gh_quiet` を呼ぶため、
前コミットで追加した回帰テストが実 gh プロセスを起動していた (ネットワーク依存・低速)。

`finalize_waiting_reset_with(..., fetch_mergeable: impl FnOnce(&PrInfo) -> Option<..>)`
へ本体を切り出し、production は `fetch_mergeable_status` を、テストは closure を渡す形に
した (cli-push-runner の `verify_diff_covers_pr_range` と同じ注入の流儀)。

あわせて「注入したものが実際に使われている」ことを確認するテストを追加した — `|_| None`
を渡すだけのテストでは、fetcher を無視する実装でも通ってしまい注入の正しさを判別できない。
Cell フラグで呼び出し自体を観測する。

## pre-push simplicity 指摘 (SIM-NEW-rate_limit-L122, Medium): fail-closed 回帰の消失

tests.rs のファイル分割時に `finalize_posted_retrigger_action_required_when_write_state_fails`
だけが欠落していた。この関数は 2 つの sibling (`finalize_waiting_reset` /
`finalize_pending_review`) と**逆に fail-closed** で、理由は `@coderabbitai review` 投稿と
いう副作用を伴うため state 永続化の成否で重複投稿を防ぐ必要があるから。fail-open 側 2 件の
回帰テストは移行されていたのに、意図的に非対称な唯一の経路のテストが落ちていた。復元し、
非対称の理由を doc comment に明記した。

## CodeRabbit 指摘 1 (Minor): 計画書の stale な park 検証残

「WP-15 追補残: レート制限 park の実観測」は park 廃止で (a) が moot になっていた。
見出しを「レート制限時の保留保証 (GitHub Actions 経路)」へ改め、(a) の終了と (b) の
引き継ぎ先を明記した (ADR-018 amendment / ADR-064 ステータス欄と同じ内容を計画書側にも
反映し、3 箇所の記述を揃える)。

検証: cargo test --workspace 1906 件 pass (新規 5 件)、clippy --workspace -D warnings 緑、
pnpm lint:docs / lint:md 0 error。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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