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
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
- [ADR-043: Security/Quality Gate での Fail-Closed 原則](docs/adr/adr-043-security-gates-fail-closed.md) *(試験運用)*
- [ADR-044: subprocess utility extraction の境界判定 — 共通化と分離の線引き](docs/adr/adr-044-subprocess-utility-extraction-boundary.md) *(試験運用)*
- [ADR-045: jj workspace による並列セッション運用 — メイン作業と細粒度改善の分離](docs/adr/adr-045-jj-workspace-parallel-sessions.md) *(試験運用)*
- [ADR-046: ローカル LLM pre-push レビュアー — 選定スパイクと不採用判断](docs/adr/adr-046-local-llm-review-spike.md) *(却下)*

## Build

Expand Down
98 changes: 98 additions & 0 deletions docs/adr/adr-046-local-llm-review-spike.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# ADR-046: ローカル LLM pre-push レビュアー — 選定スパイクと不採用判断

> 採番 046 は暫定 (land 時に空き番号で確定 — [ADR-039](adr-039-experimental-feature-standard-pattern.md) 配下 / 順位 135 placeholder policy)。

## ステータス

却下 (2026-07-04、選定スパイクの negative result により local_review stage の実装を見送り)

> 本 ADR は実装機構を持たず、[ADR-040](adr-040-local-llm-context-size.md) と同様に「実施したスパイクの empirical data + 判断根拠」を permanent record として固定する性格を持つ。CodeRabbit 往復削減を目的にローカル LLM の push 前レビューを挟む提案 (以下「local_review 案」) を、実測に基づき却下する。

## コンテキスト

### スパイクの目的

CodeRabbit 無料枠のレートリミット (3 件/時) が運用上の最大ボトルネックであり、push 前にローカル LLM で「CodeRabbit が出す指摘を先取りするレビュー」を挟めば往復を削減できる、という仮説を検証する。判断基準は **CodeRabbit findings に対する再現率**: ローカルモデルが同じ問題を push 前に surface できれば、著者が事前修正でき CodeRabbit 到達時に指摘が減る。

受け入れ基準 (事前定義): **再現率 50% 未満なら local_review 案 (実装フェーズ) を中止**する。

### 実測環境

- GPU: **NVIDIA RTX PRO 5000 Blackwell 48GB VRAM** ([ADR-038](adr-038-local-llm-finding-classification.md) / [ADR-040](adr-040-local-llm-context-size.md) が前提とする RTX 3070 8GB から更新済み。全候補モデルが 100% GPU で稼働し VRAM は制約にならない)。
- Ollama 0.30.10。
- 候補モデル (`ollama show` 実測、全 Q4_K_M):

| モデル | arch | params | context | 種別 |
|---|---|---|---|---|
| qwen3-coder:30b | qwen3moe | 30.5B | 262144 | MoE・コーディング特化 |
| gemma4:31b | gemma4 | 31.3B | 262144 | dense |
| gemma4:26b | gemma4 | 25.8B | 262144 | MoE (active 小) |
| mistral:7b | llama | 7.2B | 32768 | baseline (ADR-038 現行 classifier) |

### 評価データ (ground truth)

`check-ci-coderabbit --list-findings` を PR #90〜#242 に走査し、CodeRabbit の**未解決インライン findings** を **67 件 / 33 PR** 取得 (code=41, docs=24, config=2 / Major 35, Minor 30, Critical 2)。各 finding は file / line / severity / 要約を持つ。ツールは未解決スレッドルートのみ返す (`resolved:` 返信済みは除外) ため、これは歴史的 findings の下限。

パイロットは 5 PR / 23 findings (#233, #131, #113, #91, #97) を対象とし、diff は jj の squash commit から再構成 (全て num_ctx 32768 に収まるサイズを選定)。評価ハーネス (Node.js) は Ollama `/api/generate` をストリーミング呼び出し (`format:json`, temperature 0.1, num_ctx 32768, num_predict 4096)、「徹底的な senior reviewer」プロンプトで各モデルに diff をレビューさせ、findings を ground truth と照合した。

## 決定

**local_review 案を却下する** (push 前ローカル LLM レビュー stage を実装しない)。パイロットの再現率が受け入れ基準 50% を大きく下回り、かつ過剰検出が深刻なため。

### 実測結果

| モデル | 自動recall (行±25、上限甘) | 意味的recall (実力) | 過剰検出率 | latency 中央 | latency 最大 | VRAM |
|---|---|---|---|---|---|---|
| qwen3-coder:30b | 0.35 | 約 13% | 0.87 | 8.3s | 26.5s | 21.8GB |
| gemma4:31b | 0.26 | 約 9% | 0.77 | 23.4s | 26.5s | 20.9GB |
| gemma4:26b | 0.09 | 約 4% | 0.33 | 2.8s | 10.9s | 17.6GB |
| mistral:7b | 0.13 | 約 9% | 0.69 | 32.9s | 41.1s | 8.9GB |

- **どのモデルも意味的再現率 50% に遠く及ばない** (23 findings に対し union で約 6 件 ≈ 26%、厳密一致では約 3-4 件 ≈ 15%、単一最良モデルで約 13%)。
- 自動 recall 最良の qwen3-coder (0.35) は、大量に findings を出して GT 行の近くに偶然一致する **spray による水増し** (過剰検出率 0.87)。実力は約 13%。
- CodeRabbit findings の**約 4 割は docs / 合成 fixture** で、コードレビュープロンプトでは原理的に検出不能。
- コードファイル内でも、ローカルモデルは CodeRabbit とは**別の (多くは妥当だが異なる) 問題**を指摘する。意味的重複が低い。
- **過剰検出が深刻** (0.69〜0.87): push 前に挟むと CodeRabbit 指摘を先取りするどころか大量のノイズを足す。目的 (往復削減) に逆行する。

### 較正の過程で得た知見 (それ自体が再利用価値のある成果)

1. **再現率はプロンプトのフレーミングに強く依存する**。既存 lint-screen プロンプト由来の「flag しすぎるな・空が正解」抑制フレーミングでは qwen3-coder / gemma は findings 0 件になる。徹底フレーミングに変えて初めて出す。→ ローカル LLM レビューは prompt calibration に極めて敏感で、単一プロンプトの数字を過度に一般化できない。
2. **モデル別の固有失敗モード** (本リポの diff 規模で観測):
- qwen3-coder:30b — 大 diff で退行的反復ループ (同一指摘を数十行にコピー) → num_predict 上限で JSON truncation。
- gemma4:26b — 30KB 超の diff で沈黙 (diff は読むが `{"findings":[]}` を返す)。5 PR 中 4 PR で 0 件。
- gemma4:31b — 中央 23s と遅い割に recall 低。
- mistral:7b — 広範レビューで暴走生成 (非ストリーミングだと 300s タイムアウト)、最遅。
3. **行番号ベースの自動マッチは spray で水増しされる**ため、意味的判定が必須。モデルとレビュアーは同じ問題を別の行にアンカーする。

### 妥当性の脅威 (限界)

- N が小さい (5 PR / 23 findings)。ただし 4 モデル × 5 PR で一貫して 50% に届かず、シグナルは強い。
- プロンプトは未最適化。ただし失敗モードは「保守的すぎ」ではなく「CodeRabbit と別の問題を指摘」= 能力/整合の gap で、prompt tuning で 50% まで届く見込みは薄い。
- ground truth が未解決スレッドのみで母集団が偏る可能性。

## 帰結

### 却下による影響

- push 前 local_review stage は実装しない (`push-runner-config.toml` への `[local_review]` 追加、cli-push-runner への stage 追加は行わない)。
- CodeRabbit 往復削減は別アプローチ (レビュー対象の絞り込み = `.coderabbit.yaml` 設定、fix の push 束ね等) で追求する。

### 保持する価値

- **ground truth harvest の手法は再利用可能**: `check-ci-coderabbit --list-findings` を PR レンジに走査 → file/line/severity/要約付き findings を集約する評価データ生成法は、[ADR-038](adr-038-local-llm-finding-classification.md) 系の classifier eval や将来の LLM 機能評価に転用できる。
- **GPU 更新の事実**: [ADR-040](adr-040-local-llm-context-size.md) の実測値 (RTX 3070 8GB 前提) は陳腐化した。VRAM ではなく latency が実効制約になった。ADR-040 の再 calibration を follow-up とする (順位 255)。
- **独立レビュアーとしての別価値**: ローカル LLM は CodeRabbit と重複しない別の妥当な問題も出す。ただし過剰検出 (0.69〜0.87) に埋もれるため、「CodeRabbit 先取り」とは異なる premise であり、本 ADR の scope 外。必要なら別途評価する。

### classifier (ADR-038) との違い

本スパイクが却下したのは **review (open-ended な問題発見)** タスクであり、ADR-038 が採用している **classification (既知 findings の triage)** や lint-screen (狭い正規ルールの検出) は別タスク。分類は入力が構造化され判定空間が閉じているためローカル LLM が機能する。本結論は分類層の採用判断に影響しない。

## 関連 ADR

- ADR-038: ローカル LLM による CodeRabbit findings classification — 分類層 (本 ADR が却下した review 層とは別タスク、採用継続)
- ADR-039: Experimental feature 標準パターン — 本 ADR の判断形式 (bounded lifetime = スパイクで採否決定) の基盤
- ADR-040: Local LLM Context Size と Resource Trade-off — 本スパイクで GPU 更新により実測値が陳腐化、再 calibration の follow-up (順位 255)

## 由来

- 2026-07-04 のハーネス改善計画で定義されたローカル LLM レビュアー選定スパイクを実施。CodeRabbit 往復削減の仮説を、過去 PR の CodeRabbit findings を ground truth とした実測で検証し、再現率が受け入れ基準を満たさないため local_review 案を却下した。
8 changes: 6 additions & 2 deletions docs/harness-improvement-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Anthropic 公式のハーネスエンジニアリング指針(決定論的基

| WP | セクション | タスク | 工数 | 依存 | 状態 |
|---|---|---|---|---|---|
| WP-01 | 1-A | ローカル LLM レビュアー選定スパイク | S-M | なし | 未着手 |
| WP-02 | 1-A | `local_review` stage 実装 | M | WP-01 | 未着手 |
| WP-01 | 1-A | ローカル LLM レビュアー選定スパイク | S-M | なし | 見送り (ADR-046: 意味的再現率 ~13% ≪ 50%、GPU 再calibration → 順位 255) |
| WP-02 | 1-A | `local_review` stage 実装 | M | WP-01 | 見送り (WP-01 前提不成立、ADR-046 で却下) |
| WP-03 | 1-A | CodeRabbit クォータ設計(`.coderabbit.yaml` 新設) | S | なし | 実装済(ADR-019 amendment、dogfood 観測待ち: rate 解除待ち < 1 回/日) |
| WP-04 | 1-A | classifier モデル格上げ(7b → 27b 級) | XS-S | WP-01 | 未着手 |
| WP-05 | 1-A | Stop hook 高速化(nextest + 変更 crate 限定) | M | なし | 未着手 |
Expand Down Expand Up @@ -93,6 +93,8 @@ Anthropic 公式のハーネスエンジニアリング指針(決定論的基

### WP-01: ローカル LLM レビュアー選定スパイク

> **見送り (2026-07-04、[ADR-046](adr/adr-046-local-llm-review-spike.md) で却下)**: 実施済み。PR #90〜242 から CodeRabbit findings 67 件/33 PR を harvest し、5 PR/23 findings のパイロットで 4 モデル (qwen3-coder:30b / gemma4:31b / gemma4:26b / mistral:7b) を実測。意味的再現率は最良でも約 13%(union で約 26%)で受け入れ基準 50% を大きく下回り、かつ過剰検出が深刻 (0.69〜0.87)。結論・比較表・較正知見・モデル別失敗モードは ADR-046 に移管。副次 follow-up (GPU 更新による ADR-040 再 calibration) は順位 255。以下の当初ステップは記録用。

- **目的**: CodeRabbit 往復(最大ボトルネック)をローカル LLM の事前レビューで削減できるか、モデル選定と実測で判断する。
- **ステップ**:
1. **候補モデルは着手時に必ず ollama.com/library で最新状況を確認して差し替える**(以下は 2026-07-04 時点のスナップショット。LLM の世代交代は速く、本リストの鮮度は保証されない)。現時点の候補 3 つ: `qwen3-coder:30b`(MoE 30B-A3B、Q4 で 19GB。active 3B のため推論が数倍速い、コーディング特化)/ `gemma4:31b`(dense、20GB、256K context。品質枠)/ `gemma4:26b`(MoE active 4B、18GB。速度枠)。
Expand All @@ -105,6 +107,8 @@ Anthropic 公式のハーネスエンジニアリング指針(決定論的基

### WP-02: `local_review` stage 実装

> **見送り (2026-07-04、[ADR-046](adr/adr-046-local-llm-review-spike.md) で却下)**: 前提 (WP-01 スパイクで再現率 50% 以上) が不成立のため実装しない。push 前 local_review stage の追加 (`push-runner-config.toml` の `[local_review]` / cli-push-runner stage) は行わない。CodeRabbit 往復削減は WP-03(`.coderabbit.yaml` によるレビュー対象絞り込み)等の別経路で追求する。

- **目的**: push 前にローカル LLM レビューを挟み、CodeRabbit 到達時点で指摘が出尽くしている状態を作る。
- **ステップ**:
1. `push-runner-config.toml`(ルートと `templates/` の両方)に `[local_review]` セクション追加。`enabled = false` デフォルト(ADR-039 標準パターン: config opt-in + kill-switch + bounded lifetime)。
Expand Down
1 change: 1 addition & 0 deletions docs/todo-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
| 252 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): 部分効果 env var anti-pattern の文書化 (PR #239 post-merge-feedback T3-1 採用)** | todo13.md | S | なし (`GH_REPO` が gh pr 系に効き引数なし `gh repo view` に効かない partial coverage が PR #238 で「マージ成功 / feedback silent 消失」を招いた実例を原則化。gh-repo-env-guard preset = 機械層 (PR #239 実装済) に対する文書層の 2 層防御、同型ショートカット提案 (`GH_HOST` 等) への review guard、順位 135 placeholder policy 適用、CLAUDE.md はリンクのみ = ADR-022 方針) |
| 253 | 💎 Tier 3 | **ADR-030 に PR #239 の feedback silent skip 実装記録を追記 (PR #239 post-merge-feedback T3-2 採用)** | todo13.md | XS | なし (owner_repo 検出失敗 → marker 未書込 → L2 recovery 未発動の silent skip シナリオ (PR #238 実観測) と `AiStepContext::SkipWithMarker` による対処を ADR-030 に実装記録として残す。Severity Low = 既修正、次回 ADR-030 参照 PR への同乗で消化可) |
| 254 | 🔧 Tier 2 | **pr_size_check の base を remote tracking ref に変更 — 並列 workspace のローカル master 遅延による誤計測解消 (順位242 push で実観測)** | todo13.md | XS-S | なし (`[pr_size_check] default_branch = "master"` がローカル bookmark 基準の revset `master..@` を使うため、ADR-045 並列 workspace でローカル master が遅延すると merge 済み PR 分を合算して誤計測。順位 242 push で実 diff ~160 行が 1604 行と誤 block された実害、PR #239/#240 でも warning を静かに誤超過。ADR-013 の「remote tracking ref を使う」原則 (sync_local で test 固定済) を pr_size_check にも適用、`[file_length_gate] base` も同点検、順位 250 と相補) |
| 255 | 💎 Tier 3 | **ADR-040 の実測値を新 GPU (RTX PRO 5000 48GB) で再 calibration (ADR-046 WP-01 スパイクで陳腐化を観測)** | todo13.md | S | なし (ADR-038/040 が前提とする RTX 3070 8GB は RTX PRO 5000 Blackwell 48GB に更新済み。27-31B Q4 モデルが 100% GPU で動き VRAM が制約でなくなったため、ADR-040 の VRAM/latency trade-off 表と「VRAM scarcity → model swap 制約」framing が陳腐化。ADR-046 で mistral:7b / gemma4 / qwen3-coder の VRAM・latency を実測済 → ADR-040 amendment に反映、num_ctx 選定 flow の memory 軸を latency 軸へ再重み付け) |

**戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。

Expand Down
25 changes: 25 additions & 0 deletions docs/todo13.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,31 @@

---

### ADR-040 の実測値を新 GPU (RTX PRO 5000 48GB) で再 calibration (ADR-046 WP-01 スパイクで陳腐化を観測)

> **動機**: ADR-038 / ADR-040 は Local LLM の実行環境を **RTX 3070 8GB** として実測値を固定しているが、実機は **NVIDIA RTX PRO 5000 Blackwell 48GB** に更新済み (2026-07-04 に `nvidia-smi` で確認)。この結果、(1) ADR-040 の VRAM/latency trade-off 表 (例: mistral:7b ~2GB at 32K ctx) と (2)「VRAM scarcity → 同時起動不可 / model swap 制約 / KV cache budgeting」という framing が陳腐化した。27-31B Q4 モデルが 100% GPU で動き (qwen3-coder:30b ~21.8GB / gemma4:31b ~20.9GB / gemma4:26b ~17.6GB at num_ctx 32768)、VRAM ではなく latency が実効制約になった。
>
> **参照**: ADR-040 (Local LLM Context Size、実測値元)、ADR-046 (WP-01 スパイク、4 モデルの VRAM・latency 実測を保持)、ADR-038 (現行 classifier、RTX 3070 前提の記述)、memory `gpu-upgrade-rtx-pro-5000`。
>
> **実行優先度**: 💎 Tier 3 — Effort S。実装変更を伴わず ADR amendment 中心。分類層 (ADR-038) の運用に直接の不具合はないが、num_ctx 再選定や派生プロジェクト porting 時に誤った RTX 3070 前提を引き継ぐリスクを解消する。

#### 作業計画

- [ ] ADR-040 に amendment: RTX 3070 8GB の実測表は「旧環境 (historical)」と明示し、新 GPU での再測定値 (ADR-046 の VRAM 実測 + 代表 diff の latency) を追記
- [ ] 「Context 選定の判断 flow」の memory 軸 (同時起動可否 / swap) を latency 軸へ再重み付け
- [ ] ADR-038 の RTX 3070 前提記述 (§コンテキスト / §帰結の VRAM 8GB 制約) に更新環境への参照を付す
- [ ] 本 entry 削除 + todo-summary.md 行削除

#### 完了基準

- ADR-040 を読んだ実装者が、現行 GPU では VRAM が制約でなく latency が実効制約であることを把握でき、RTX 3070 8GB の数値を現行前提と誤認しないこと。

#### 詰まっている箇所

- なし (GPU 更新の事実・ADR-046 の実測値あり)。

---

## 既知課題 (記録のみ、本セッションで未対応)

(現時点で本ファイルへの既知課題は無し。docs/todo10.md / todo9.md 末尾を参照。)