Skip to content

feat(session-start): nudge の telemetry 統合 (ADR-055 / PR-N3) - #301

Merged
aloekun merged 3 commits into
masterfrom
feat/session-start-nudge-telemetry
Jul 19, 2026
Merged

feat(session-start): nudge の telemetry 統合 (ADR-055 / PR-N3)#301
aloekun merged 3 commits into
masterfrom
feat/session-start-nudge-telemetry

Conversation

@aloekun

@aloekun aloekun commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • SessionStart hook の 5 nudge (weekly_review_reminder / pr_monitor_catchup / reaper / staleness / workspace_stale) の発火を lib-telemetry に warn として記録し、ROI 棚卸し (ADR-055 WP-12) の観測基盤 firings-*.jsonl に載せる
  • record_nudge_firing ヘルパー追加 + 5 発火点への配線。配線で 50 行上限 (touch-trigger ratchet) を超えた emit_session_start_outputappend_pr_monitor_catchup_nudge / append_cwd_nudges に責務分割 (挙動不変)
  • ADR-055 の nudge 除外根拠 (「decision は block/warn の 2 値で nudge は乗らない」) を撤回。warn は「発火の重み」軸 (jj-op-verify の非 block warn と同性質) で nudge に整合、と整理する Amendment を追加
  • 記録失敗・opt-in OFF は lib-telemetry 内部で握りつぶす fail-open (hook 本来の出力を妨げない)

Context

weekly-review reminder (ADR-031) が約 4 週間ユーザーに気付かれず発火し続けた incident (ADR-059 / PR-N1) を受け、「どの nudge が実際に発火したか」を観測できる基盤が必要になった。本 PR は weekly-review 通知可視化改善計画 (PR-N1〜N3) の最終段 PR-N3 で、観測層のみを追加する。

ADR-059 の systemMessage 可視化は weekly reminder 限定で dogfood し、行動要求系 nudge への段階展開の採否を発火実績で判定する (期限 2026-08-16)。本計装がその観測データを供給する。表示ノイズがゼロのため、systemMessage と違い全 nudge 一括で記録する。

コミットはレビューしやすさ優先で 3 分割 (feat 配線 / ADR-055 追記 / 計画書作業記録)。stop-feedback-dispatch / user-prompt-feedback-recovery の計装は本 PR スコープ外 (各 hook を触る PR で個別に実施)。

Validation

  • cargo test -p hooks-session-start: 93 pass (観測層追加は挙動不変のため新規テストなし、telemetry 本体は lib-telemetry の 20+ テストが担保)
  • cargo clippy --workspace --all-targets --all-features -- -D warnings: クリーン
  • pnpm build:all: 成功 (全 crate release + exe 配布)
  • E2E: デプロイ済み exe を実 session_id で駆動 → firings-2026-07-19-*.jsonl に pr_monitor_catchup / weekly_review_reminder の発火行 (hook=hooks-session-start / kind=hook / decision=warn) が append されることを確認
  • pnpm push pre-push-review: verdict=APPROVE (security / simplicity 両者、2026-07-19)
  • /review-local (qwen3-coder:30b, 2 runs): 11 findings 全て誤検知/非該当と検証し rejected
  • 削除条件 4: land 後、新セッション起動で firings-*.jsonl に発火行が記録されることを目視確認

References

Summary by CodeRabbit

  • 新機能

    • セッション開始時に表示される5種類のナッジを、警告としてテレメトリーに記録するようになりました。
    • 記録にはセッション情報が連携され、既存のオプトイン設定・停止スイッチ・分割方針が適用されます。
    • テレメトリー記録に失敗しても、セッション開始処理は継続します。
  • ドキュメント

    • ナッジのテレメトリー統合方針、検証結果、削除条件を追記しました。

aloekun and others added 3 commits July 19, 2026 20:08
SessionStart hook の 5 nudge (weekly_review_reminder / pr_monitor_catchup /
reaper / staleness / workspace_stale) の発火を lib-telemetry に warn として記録し、
ROI 棚卸し (ADR-055 WP-12) の観測基盤 firings-*.jsonl に載せる。記録失敗・opt-in OFF は
lib-telemetry 内部で握りつぶす fail-open。

- Cargo.toml: lib-telemetry 依存を追加
- main.rs: record_nudge_firing ヘルパー + 5 発火点への配線。
  emit_session_start_output が 50 行上限 (touch-trigger ratchet) を超えたため
  append_pr_monitor_catchup_nudge / append_cwd_nudges に責務分割 (挙動不変)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
初版で除外していた session-start nudge を firing 計装対象に加える。除外根拠
「decision 語彙が block/warn の 2 値で nudge は乗らない」を撤回し、warn は「発火の重み」軸
(jj-op-verify の非 block warn と同性質) なので nudge に整合すると整理した。

- 除外リストから session-start reminder を外し amendment へのポインタに更新
- Amendment (2026-07-19) セクション追加: 撤回根拠 / 計装 id 5 種 / ADR-059 動機 / 残る除外
- 関連 ADR に ADR-059 を追記

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
session-start nudge の telemetry 統合 (PR-N3) の作業記録を追記。3 分割コミット / ADR-055
除外根拠の撤回判断 / cargo test 93 passed / clippy クリーン / pnpm build:all 成功 /
デプロイ exe 駆動での firings-*.jsonl E2E 確認 (pr_monitor_catchup + weekly_review_reminder
の 2 発火行) と残タスク (削除条件 4 の land 後目視確認) を記録。

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

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

session-start nudge 5種を lib-telemetry の warn firing として記録する方針を ADR に追加し、hook の発火点に session_id 付き記録処理を接続した。出力生成処理もヘルパーへ分割し、記録失敗時は処理を継続する。

Changes

Session-start nudge telemetry

Layer / File(s) Summary
計装対象と記録契約の更新
docs/adr/adr-055-firing-telemetry-collection.md
session-start nudge 5種を warn として記録する Amendment、記録方式、session_id 連携、既存の opt-in・kill-switch・partition・fail-open 原則を追加した。関連 ADR に ADR-059 を追加した。
発火経路への telemetry 接続と出力分割
src/hooks-session-start/Cargo.toml, src/hooks-session-start/src/main.rs, docs/weekly-review-notification-plan.md
lib-telemetry を依存に追加し、各 nudge 発火で record_nudge_firing を呼び出すようにした。SessionStart 出力生成をヘルパーへ分割し、weekly review reminder の systemMessage を上位処理で扱う構成に変更した。作業記録と検証結果を追記した。

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SessionStartHook
  participant lib_telemetry
  participant firings_jsonl
  SessionStartHook->>lib_telemetry: record_nudge_firing(nudge_id, session_id)
  lib_telemetry->>firings_jsonl: write warn firing
  lib_telemetry-->>SessionStartHook: return without blocking hook output
Loading

Possibly related PRs

🚥 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 session-start の nudge 5種に telemetry を統合する変更を的確に表しており、PR の主目的と一致しています。
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/session-start-nudge-telemetry

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.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Monitor 分析 (GitHub Actions バックストップ)

  • トリガー: issue_comment (created) / 実行 run
  • CI: CodeRabbit チェックが pending (Review in progress)。他に定義された CI チェックは検出されず。mergeStateStatus は UNSTABLE(CodeRabbit pending に起因)、mergeable は MERGEABLE
  • レビュー状況: CodeRabbit はレビュー未着手(自動生成の "processing" プレースホルダーコメントのみ、findings なし)。人間レビューも 0 件(reviewDecision 空、reviews API も空配列)
  • Verdict: approved(findings 0 件のため暫定。CodeRabbit 未完了につき今後の追記で更新され得る)

レビュー指摘が現時点で 1 件も無いため、CI 状態と diff 概要のみの軽量サマリーとする。

Diff 概要

PR-N3: session-start nudge 群 (5 種) を ADR-055 telemetry 計装に追加する変更。

File 変更の性質
Cargo.lock lib-telemetry 依存追加に伴う機械的更新(CodeRabbit のパスフィルタで除外対象)
docs/adr/adr-055-firing-telemetry-collection.md Amendment (2026-07-19) 追加。初版で「nudge は decision 語彙 (block/warn) に乗らない」として計装対象外としていた session-start nudge の除外根拠を撤回し、計装対象に追加。ADR-059 (weekly reminder 気付かれず4週間発火し続けた incident) を契機とした設計変更が明記されている
docs/weekly-review-notification-plan.md 実装完了の作業記録セクション追加(コミット分割方針、cargo test 93 passed、clippy クリーン、pnpm build:all 成功、実 exe を session_id で駆動した E2E 確認結果を記載)
src/hooks-session-start/Cargo.toml lib-telemetry パス依存追加
src/hooks-session-start/src/main.rs emit_session_start_outputappend_pr_monitor_catchup_nudge / append_cwd_nudges に分割(関数長 50 行 ratchet 超過が理由と PR 内で明記)。5 nudge 発火点に record_nudge_firing (kind=Hook, decision=Warn) を配線

Applicable Findings (Critical / High / Major)

(該当なし)

Applicable Findings (Medium 以下)

(該当なし)

Filtered (not applicable)

(該当なし — レビュー指摘自体がまだ存在しない)

次のアクション

  • CodeRabbit のレビュー完了を待ち、実際の findings が投稿された時点で再監視・再分析を行う。
  • ADR-055 Amendment は decision 軸の定義(「発火の重み」)を根拠に既存の warn 記録方針との整合を取っており、意図的設計変更として妥当性は本 PR 内で自己説明されている。CodeRabbit のレビューでこの設計判断(除外根拠の撤回)自体への疑義が出た場合は、ADR-055/ADR-059 の記述と突き合わせて fitness filter を適用すること。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/hooks-session-start/src/main.rs (1)

150-170: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

将来の拡張に備えた防衛的なリファクタリングの提案

現在の実装では機能的に問題ありませんが、独立した副作用(各 nudge の評価と context への追記)を直列に並べる関数において、? 演算子による早期リターン(151行目や164行目など)を使用すると、将来的に別の nudge をこの関数の末尾に追加した際、手前の設定(session_startweekly_config)が None だと後続の処理全体が意図せずスキップされる罠になります。

将来の拡張に備え、? 演算子を使わずに if let で明示的なブロックスコープに閉じる記述をお勧めします。

🛠️ 提案するリファクタリング
-    let hooks_config = read_hooks_config(cwd);
-    let session_start = hooks_config.session_start.as_ref()?;
-    if let Some(staleness_config) = session_start.staleness.as_ref() {
-        if let Some(staleness_nudge) = compute_staleness_nudge(cwd, staleness_config) {
-            context.push_str("\n\n");
-            context.push_str(&staleness_nudge);
-            record_nudge_firing("staleness", session_id);
-        }
-        if let Some(stale_nudge) = compute_workspace_stale_nudge(staleness_config) {
-            context.push_str("\n\n");
-            context.push_str(&stale_nudge);
-            record_nudge_firing("workspace_stale", session_id);
-        }
-    }
-    let weekly_config = session_start.weekly_review_reminder.as_ref()?;
-    let weekly_nudge = compute_weekly_review_reminder_nudge(cwd, weekly_config, now_unix)?;
-    context.push_str("\n\n");
-    context.push_str(&weekly_nudge.additional_context);
-    record_nudge_firing("weekly_review_reminder", session_id);
-    weekly_nudge.system_message
+    let hooks_config = read_hooks_config(cwd);
+    if let Some(session_start) = hooks_config.session_start.as_ref() {
+        if let Some(staleness_config) = session_start.staleness.as_ref() {
+            if let Some(staleness_nudge) = compute_staleness_nudge(cwd, staleness_config) {
+                context.push_str("\n\n");
+                context.push_str(&staleness_nudge);
+                record_nudge_firing("staleness", session_id);
+            }
+            if let Some(stale_nudge) = compute_workspace_stale_nudge(staleness_config) {
+                context.push_str("\n\n");
+                context.push_str(&stale_nudge);
+                record_nudge_firing("workspace_stale", session_id);
+            }
+        }
+        if let Some(weekly_config) = session_start.weekly_review_reminder.as_ref() {
+            if let Some(weekly_nudge) = compute_weekly_review_reminder_nudge(cwd, weekly_config, now_unix) {
+                context.push_str("\n\n");
+                context.push_str(&weekly_nudge.additional_context);
+                record_nudge_firing("weekly_review_reminder", session_id);
+                return weekly_nudge.system_message;
+            }
+        }
+    }
+    None
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks-session-start/src/main.rs` around lines 150 - 170, Refactor the
session-start nudge flow to avoid `?`-based early returns for `session_start`
and `weekly_review_reminder`. Use explicit `if let` blocks around the staleness
processing and weekly reminder processing so missing configuration skips only
that nudge while allowing later independent nudges to run; preserve the existing
context updates and firing records.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/hooks-session-start/src/main.rs`:
- Around line 150-170: Refactor the session-start nudge flow to avoid `?`-based
early returns for `session_start` and `weekly_review_reminder`. Use explicit `if
let` blocks around the staleness processing and weekly reminder processing so
missing configuration skips only that nudge while allowing later independent
nudges to run; preserve the existing context updates and firing records.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 31a651f4-998d-4922-91ed-46c40830b004

📥 Commits

Reviewing files that changed from the base of the PR and between 4e9c957 and fad0a93.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • docs/adr/adr-055-firing-telemetry-collection.md
  • docs/weekly-review-notification-plan.md
  • src/hooks-session-start/Cargo.toml
  • src/hooks-session-start/src/main.rs

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Monitor 分析 (GitHub Actions バックストップ)

  • トリガー: pull_request_review (submitted) / 実行 run
  • CI: CodeRabbit チェックは pass(Review completed)。analyze チェックは実行中(本 workflow 自身、pending)。他に定義された CI チェックは検出されず。mergeStateStatusUNSTABLE(analyze pending に起因と推定)、mergeableMERGEABLE
  • レビュー状況: CodeRabbit が新規レビューを submit(COMMENTED, 2026-07-19T12:38:31Z)— nitpick 1件(Trivial / Low value 自己申告)。人間レビューは0件(reviewDecision 空、reviews API 上も human review 無し)
  • Verdict: user_decision(Trivial 相当の指摘のみで Critical/High/Major 該当なしのため)

Applicable Findings (Critical / High / Major)

(該当なし)

Applicable Findings (Medium 以下)

# File (Line) Reviewer Issue Recommended Action
1 src/hooks-session-start/src/main.rs (150-170) CodeRabbit (Trivial/Low value) append_cwd_nudges 内で session_start.as_ref()? / weekly_review_reminder...?? 早期リターンを使っており、将来この関数末尾に別 nudge を追加した際 session_startNone だとその新 nudge も意図せずスキップされる懸念(現状の5 nudge の挙動自体は改修前と同一で正しく、今すぐの不具合ではない) 必須修正ではない。将来 nudge 追加時に if let ブロックへの書き換えを検討する程度でよく、本 PR での対応要否はユーザー判断に委ねる

Filtered (not applicable)

(該当なし — fitness filter の定義済みカテゴリ(platform scope / intentional design / docs-only mismatch / sensitive-file / scope mismatch / false positive)のいずれにも該当せず、severity はレビュアー申告どおり維持)

次のアクション

  • 上記1件は Trivial 相当のため即時修正は不要。ユーザー判断でスキップ、または軽微な追記コミットのどちらでも問題ない。
  • analyze チェック(本 workflow)の完了を待って最終 CI green を確認する。
  • 現時点で Critical/High/Major の指摘は無いため、マージ判断(user_decision)はユーザーに委ねる。

@aloekun
aloekun merged commit 1bb8341 into master Jul 19, 2026
2 checks passed
@aloekun
aloekun deleted the feat/session-start-nudge-telemetry branch July 19, 2026 12:42
aloekun added a commit that referenced this pull request Jul 19, 2026
* docs(todo): PR-N1〜N3 post-merge feedback の採用候補を todo 登録 (#288 昇格 + 329-332 新設)

PR #299/#300/#301 の post-merge feedback から採用候補 5 件を系統別に登録:
- #288 昇格 (系統 A): pre-push review の diff スコープ漏れが 3 連続再発 (Severity High)。
  post-merge 全 run 集約に加え push-runner [diff] stage の tip-only 範囲修正を統合し Tier2→Tier1
- 329 (系統 B): 新規 ADR 起案時の「判断根拠 × 既存 ADR 定義」矛盾チェックリスト
- 330 (系統 B): 行動要求 nudge の 2 チャネル返却 + 多義的戻り値 struct 化 convention
- 331 (系統 C): systemMessage 含む JSON 出力の exe-spawn E2E テスト
- 332 (系統 D): pnpm build:all の Windows cp.exe PATH 自動化

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

* docs(todo): PR #302 CodeRabbit 指摘を反映 (#288 fail-closed 祖先検証 / schema 移行 / Windows 検出 / ADR 意図変更)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
aloekun added a commit that referenced this pull request Jul 21, 2026
## 問題

`[diff] command` に `jj diff -r @` が直書きされており、AI レビュアーには **tip
コミットの diff しか渡っていなかった**。祖先コミットは pre-push のセルフレビューを
一度も経ずに merge される。

同じパイプライン内で `pr_size_check` と `docs_only_routing` は `<base>..@` (PR 範囲)
を見ており、`[diff]` だけが非対称だった。実際 PR #311 では 695 行の PR に対して
37 行だけがレビュー対象になり、レビュアーは渡された 37 行を見て正しく「docs-only」と
判定していた。**レビュアー側からは「渡された diff が PR 全体か」を検証できない**ため、
この誤りは誰にも検知されない。

docs/todo-summary2.md 順位 288 として既知で、Severity High で PR #268/#300/#301 に
続き #311 が 4 回目の再発。

## 変更

- **範囲の真実源を 1 箇所に**: top-level `default_branch` を新設し、`diff` /
  `docs_only_routing` / `pr_size_check` の 3 stage が `Config::resolve_base_branch`
  経由で同じ値を使う。従来は section ごとに独立した `default_branch` を持ち、
  「値を同期する義務」を config コメントで課していた (docs_only_routing.rs の doc に
  明記されていた) が、義務はコード上の不変条件ではないため非対称を許していた。
  section 側は後方互換の override として残す (派生プロジェクトの既存 config 対策)。
- **config から revset を排除**: `[diff] command` は `{{PR_RANGE}}` プレースホルダを
  使う。push-runner が `<base>..@` に展開するため、狭い範囲を書く余地が無くなる。
- **範囲カバレッジ検査 (fail-closed)**: 生成した diff が PR 範囲の全変更ファイルを
  含むか `jj diff --summary` と突き合わせ、不足があれば exit 5 で中断する。config の
  書き方に依存せず「レビュー範囲 < PR 範囲」を検知できるため、未更新の派生プロジェクト
  config も捕まえる。summary 取得失敗・`diff --git` ヘッダ不在 (= 収録ファイルを特定
  できない) も「網羅している」に倒さずエラーにする (ADR-043)。
- **`--git` 形式へ切替 (順位 264)**: 範囲検査がヘッダを読む要件に加え、jj 既定形式は
  色を落とすと `+`/`-` が消えて LLM レビュアーが削除を追加と誤読する (PR #256 で
  simplicity-review が todo 25 行の削除を追加と誤読し false positive REJECT、約 19 分
  浪費)。
- `templates/push-runner-config.toml` も同時修正 (deploy:hooks で派生配布されるため)。

## 実測で見つけた副次バグ

範囲 summary の取得を当初 shell 経由 (`[diff] command` と同じ経路) で実装したが、
実シェルで叩いたところ **cmd.exe はクォートを除去せず jj に渡す**ため
`Revision '"<base>..@"' doesn't exist` で必ず失敗した。sh は除去するので Linux だけ
通る = Windows の全 push が fail-closed で止まる形。ユニットテストは summary 取得を
注入していたため検出できなかった。direct args 呼び出し (docs_only_routing の既存
`run_jj_diff_summary`) を共有する形に修正し、doc に理由を残した。両 stage は
「PR 範囲の変更ファイル一覧」という同一の問いを扱うため、別実装にすると本 PR が
排除した非対称を再導入することになる。

## 検証

cargo test --workspace 全 pass / clippy clean。範囲検査は incident 形状 (PR 2 ファイル
変更に対し diff は tip の 1 ファイルのみ) の再現テストで固定し、fail-closed 経路
(summary 取得失敗 / ヘッダ不在) と過剰検知しない経路 (空 PR 範囲 / Windows パス
区切りの正規化) も併せて固定した。base branch 解決は 3 stage が同一範囲に解決される
ことと override の優先順位を machine-enforce している。
aloekun added a commit that referenced this pull request Jul 21, 2026
)

* fix(push-runner): AI レビュー対象 diff を PR 全体に修正し範囲を機械検査する (順位 288/264)

## 問題

`[diff] command` に `jj diff -r @` が直書きされており、AI レビュアーには **tip
コミットの diff しか渡っていなかった**。祖先コミットは pre-push のセルフレビューを
一度も経ずに merge される。

同じパイプライン内で `pr_size_check` と `docs_only_routing` は `<base>..@` (PR 範囲)
を見ており、`[diff]` だけが非対称だった。実際 PR #311 では 695 行の PR に対して
37 行だけがレビュー対象になり、レビュアーは渡された 37 行を見て正しく「docs-only」と
判定していた。**レビュアー側からは「渡された diff が PR 全体か」を検証できない**ため、
この誤りは誰にも検知されない。

docs/todo-summary2.md 順位 288 として既知で、Severity High で PR #268/#300/#301 に
続き #311 が 4 回目の再発。

## 変更

- **範囲の真実源を 1 箇所に**: top-level `default_branch` を新設し、`diff` /
  `docs_only_routing` / `pr_size_check` の 3 stage が `Config::resolve_base_branch`
  経由で同じ値を使う。従来は section ごとに独立した `default_branch` を持ち、
  「値を同期する義務」を config コメントで課していた (docs_only_routing.rs の doc に
  明記されていた) が、義務はコード上の不変条件ではないため非対称を許していた。
  section 側は後方互換の override として残す (派生プロジェクトの既存 config 対策)。
- **config から revset を排除**: `[diff] command` は `{{PR_RANGE}}` プレースホルダを
  使う。push-runner が `<base>..@` に展開するため、狭い範囲を書く余地が無くなる。
- **範囲カバレッジ検査 (fail-closed)**: 生成した diff が PR 範囲の全変更ファイルを
  含むか `jj diff --summary` と突き合わせ、不足があれば exit 5 で中断する。config の
  書き方に依存せず「レビュー範囲 < PR 範囲」を検知できるため、未更新の派生プロジェクト
  config も捕まえる。summary 取得失敗・`diff --git` ヘッダ不在 (= 収録ファイルを特定
  できない) も「網羅している」に倒さずエラーにする (ADR-043)。
- **`--git` 形式へ切替 (順位 264)**: 範囲検査がヘッダを読む要件に加え、jj 既定形式は
  色を落とすと `+`/`-` が消えて LLM レビュアーが削除を追加と誤読する (PR #256 で
  simplicity-review が todo 25 行の削除を追加と誤読し false positive REJECT、約 19 分
  浪費)。
- `templates/push-runner-config.toml` も同時修正 (deploy:hooks で派生配布されるため)。

## 実測で見つけた副次バグ

範囲 summary の取得を当初 shell 経由 (`[diff] command` と同じ経路) で実装したが、
実シェルで叩いたところ **cmd.exe はクォートを除去せず jj に渡す**ため
`Revision '"<base>..@"' doesn't exist` で必ず失敗した。sh は除去するので Linux だけ
通る = Windows の全 push が fail-closed で止まる形。ユニットテストは summary 取得を
注入していたため検出できなかった。direct args 呼び出し (docs_only_routing の既存
`run_jj_diff_summary`) を共有する形に修正し、doc に理由を残した。両 stage は
「PR 範囲の変更ファイル一覧」という同一の問いを扱うため、別実装にすると本 PR が
排除した非対称を再導入することになる。

## 検証

cargo test --workspace 全 pass / clippy clean。範囲検査は incident 形状 (PR 2 ファイル
変更に対し diff は tip の 1 ファイルのみ) の再現テストで固定し、fail-closed 経路
(summary 取得失敗 / ヘッダ不在) と過剰検知しない経路 (空 PR 範囲 / Windows パス
区切りの正規化) も併せて固定した。base branch 解決は 3 stage が同一範囲に解決される
ことと override の優先順位を machine-enforce している。

* docs: ADR-027 に「diff 局所 = 観点の限定であって範囲の限定ではない」を明記 (順位 288/264)

## ADR-027 amendment

ADR-027 が狭めたのは reviewer が使う criteria (cross-file 探索を要求しない)
であり、レビュー対象に含めるコミットの範囲ではなかった。この 2 つが混同され、
`[diff] command` が tip コミット限定のまま運用されて 4 回の再発を招いたため、
射程を明文化した。

「レビュー対象は PR 範囲全体」と決定した根拠も併記:

- 速度は理由にならない。同一 PR でレビュー対象を 37 行 → 1011 行 (27 倍) に
  広げても 4m32s → 4m43s の +11 秒。ADR-027 の速度改善は arch-review facet の
  除去 (219-270s/iter) によるもので、範囲縮小は寄与していなかった。
- 範囲が狭いことによる見落としはレビュアー側から検知できない (渡された diff が
  PR 全体かを検証する手段が無い)。
- CodeRabbit backstop はセルフレビューを省く理由にならない。独立した層として併用する。

## todo 更新

- 順位 264 (`--git` 切替): 完了につきエントリと table 行を削除。
- 順位 288: `[diff]` 範囲修正の部分のみ完了として記録。**残タスク** (post-merge
  feedback の全 run 集約、bookmark_check.rs の祖先未レビュー穴の検証) は明示して
  残す。エントリ全体を消すと未着手部分が失われるため削除しない。

* fix(push-runner): pre-push 範囲検査の欠陥修正 + CodeRabbit 指摘5件対応 (#313)
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