From 58f3cc9168aca1e6e431b236fdc51d67931fd167 Mon Sep 17 00:00:00 2001 From: aloekun Date: Tue, 12 May 2026 03:28:00 +0900 Subject: [PATCH] =?UTF-8?q?docs(adr):=20D-1=20ADR=20amendments=20bundle=20?= =?UTF-8?q?+=20Phase=20D=20=E8=A8=88=E7=94=BB=20land=20(=E9=A0=86=E4=BD=8D?= =?UTF-8?q?=20112/113/114)=20+=20workflow=20gap=20=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase D dogfood の 1 本目 (D-1)。3 件 ADR 採用 + Phase D 計画 land + workflow gap 反映を bundled。 順位 112 (PR #142 T3-#3): ADR-038 に 2 section 追記 - Diagnostic logging scope: eprintln (CLI 前提) と structured logging 移行条件 - 90% 閾値 rationale: 保守採用根拠 + Phase D 完了時の precision/recall 評価方針 順位 113 (PR #142 T3-#4): ADR-027 に metrics override 判断基準追記 - Incidental change vs Responsibility change の線引き - Override 記述様式 (Override / Reason / Rationale の 3 項目) 順位 114 (PR #143 T3-#1): ADR-040 新規作成 - mistral:7b context size 実測値 (8K 512MB 5-20s ↔ 32K 2GB 30-90s) - step_timeout 3.33x 比例係数の根拠 - num_ctx 選定 flow chart - CLAUDE.md ADR index 追加 - lib-ollama-client/src/lib.rs L128-139 dogfood evolution コメントを 4 行参照に短縮 Phase D 計画 land + workflow gap (新規): - analysis.md に D-1/D-2/D-3 PR 構成 + 計測手順 + 想定リスクを追加 - D-1 着手時に判明した workflow gap (jj auto-snapshot vs session-only opt-in) を計測手順に反映 - env var override (LINT_SCREEN_ENABLED) を todo8.md / todo-summary.md (順位 115) に backlog 登録 - D-1 自身は dogfood skip、env var override land 後に D-2 / D-3 で実 dogfood 実施 D-1 lint_screen 状態: skipped。Phase D guide §1 session-only opt-in workflow が jj auto-snapshot と 本質的に衝突するため、配列 env var override の cli-push-runner 実装 (順位 115) を D-2 前に land 必須。 --- CLAUDE.md | 1 + .../adr-027-push-review-simplicity-focus.md | 30 ++++++ ...dr-038-local-llm-finding-classification.md | 25 +++++ docs/adr/adr-040-local-llm-context-size.md | 93 +++++++++++++++++++ docs/local-llm-offload-analysis.md | 57 ++++++++++-- docs/todo-summary.md | 4 +- docs/todo6.md | 38 -------- docs/todo8.md | 32 ++++--- src/lib-ollama-client/src/lib.rs | 14 +-- 9 files changed, 223 insertions(+), 71 deletions(-) create mode 100644 docs/adr/adr-040-local-llm-context-size.md diff --git a/CLAUDE.md b/CLAUDE.md index bd820ef..bdfcef3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,6 +40,7 @@ - [ADR-037: takt fix-trust shortcut — convergence_verdict による Iter 3 短絡](docs/adr/adr-037-takt-fix-trust-shortcut.md) *(試験運用)* - [ADR-038: ローカル LLM による CodeRabbit findings classification](docs/adr/adr-038-local-llm-finding-classification.md) *(試験運用)* - [ADR-039: Experimental feature 標準パターン (config opt-in + kill-switch + bounded lifetime)](docs/adr/adr-039-experimental-feature-standard-pattern.md) *(試験運用)* +- [ADR-040: Local LLM Context Size と Resource Trade-off](docs/adr/adr-040-local-llm-context-size.md) *(試験運用)* ## Build diff --git a/docs/adr/adr-027-push-review-simplicity-focus.md b/docs/adr/adr-027-push-review-simplicity-focus.md index 2d6e9c2..fe15777 100644 --- a/docs/adr/adr-027-push-review-simplicity-focus.md +++ b/docs/adr/adr-027-push-review-simplicity-focus.md @@ -192,6 +192,36 @@ security-review (同じ workflow 内で並列実行) の execute median は 62s - security-review の slowdown は別トラックで調査 (model 指定以外に context サイズが効いている可能性)。 - 次回のこの種の性能 ADR では、baseline/target とも **median で記述する** (p75 値を typical として扱わない)。 +## Metrics override 判断基準 (PR #142 追記) + +simplicity-review が複雑度 metrics (関数長 / ネスト深さ / 重複等) で flag した行が、PR の本質的責務と独立した **incidental change** であった場合、reviewer は明示的に override 判定を下す。本 ADR では override の判断境界と記述様式を以下に codify する。 + +### Incidental change vs Responsibility change の線引き + +| 種類 | 例 | metrics 判定の扱い | +|---|---|---| +| **Incidental change** | `cargo fmt` による空白/改行整形、import 整理、無関係な未使用コード除去 (`cargo fix --allow-dirty`)、エディタ自動 trailing whitespace 除去 | override OK (本 PR の責務外) | +| **Responsibility change** | 本 PR の fix 本体、新 function 追加、API 変更、bug fix のための ネスト改修 | metrics 判定を尊重 (override 禁止、改善 or 受け入れ rationale 必須) | + +判断境界の essential rule: **「diff の hunk を消したら PR の主目的が達成不能になるか」** で判定。Yes → responsibility / No → incidental。 + +### Override 記述様式 + +reviewer report で incidental override を行う場合は、以下の 3 項目を明示: + +```markdown +- **Override**: +- **Reason**: incidental (e.g., cargo fmt による 2 行整形 / 既存 import の alphabetize) +- **Rationale**: 本 PR の主責務 () と独立しており、削除しても主目的を阻害しない +``` + +理由を残さない silent override は禁止 (将来の review で「なぜ flag が消えたか」を逆引きできなくなる)。 + +### 由来 + +- PR #142 (Phase A 診断 log 実装) の simplicity-review で `cargo fmt` 整形による 1-2 行 diff 増加が metrics override 判定対象になった事例があり、incidental / responsibility の線引きが不明瞭だった +- post-merge-feedback T3-#4 採用、Frequency Low / Severity Low / Effort XS + ## 次ステップ (スコープ外) - **call chain drift lint の導入**: ADR 内のコードシンボル参照と実コードの整合性を lint で検証する仕組み diff --git a/docs/adr/adr-038-local-llm-finding-classification.md b/docs/adr/adr-038-local-llm-finding-classification.md index 9fe8592..ceb7a19 100644 --- a/docs/adr/adr-038-local-llm-finding-classification.md +++ b/docs/adr/adr-038-local-llm-finding-classification.md @@ -64,6 +64,31 @@ Ollama 不在 / timeout / parse 失敗 / invalid action は **fallback として これは [docs/local-llm-offload-analysis.md](../local-llm-offload-analysis.md) §6 の方針 (「失敗してもリトライ可能 / Claude が後段で検証」) と整合する。 +### Diagnostic logging の scope と移行条件 (PR #142 / Phase A) + +JSON parse error 時の context overflow 診断 log は **`eprintln!` で stderr に出力する** 設計 (`src/lib-ollama-client/src/lib.rs` の `emit_overflow_diagnostic`)。これは現状の consumer (`cli-finding-classifier` / `cli-push-runner` lint_screen stage) がすべて CLI 起動で stderr を report に取り込む前提に基づく。 + +**structured logging (log / tracing crate) への移行条件**: + +- `lib-ollama-client` が CLI 以外 (例: 長期常駐 daemon / web service) から呼ばれるようになった場合 +- 複数 consumer が log level / target filter で diagnostic 出力を制御したいニーズが生じた場合 +- log aggregation (Loki / Datadog 等) への連携を求める要件が出た場合 + +これらが揃うまでは `eprintln!` で十分。早期の structured logging 導入は依存追加 (log + env_logger / tracing + subscriber) のコストに対して得られる柔軟性が見合わない。 + +### 90% 閾値の rationale + tuning 方針 (PR #142 / Phase A) + +`overflow_hint()` は `prompt_eval_count >= num_ctx * 0.90` で hint を emit する保守設計。**90% 採用根拠**: + +- mistral:7b の prompt_eval_count は num_ctx の cap で clamp される (Ollama の internal 仕様、Phase B で実測確認)。100% 到達 = 確定 overflow だが、90% 到達 = overflow 寸前で同一症状を予兆できる +- false positive の負担は warn log 1 件のみ (block しない)、false negative (= overflow を見逃す) の方が debug cost が高い + +**tuning 方針**: + +- **Phase C/D dogfood で得た data が蓄積するまで本閾値を変更しない**。根拠なき早期変更で false positive 増加 / false negative 増加のいずれかに振れるリスクが高い +- Phase D 完了時 (3-5 PR 観測) に hint emit 件数と実 overflow 件数を突合し、precision / recall を確認して再評価 +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) で diff 規模 / prompt 構造が異なる場合は、本リポジトリ baseline と別系統で再 calibration を検討 + ### プロンプト `src/cli-finding-classifier/prompts/classify.txt` に同梱 (`include_str!`)。`--prompt-file` で差し替え可能。テンプレート placeholders は `{severity}` `{file}` `{line}` `{issue}` `{suggestion}`。 diff --git a/docs/adr/adr-040-local-llm-context-size.md b/docs/adr/adr-040-local-llm-context-size.md new file mode 100644 index 0000000..a5e65c5 --- /dev/null +++ b/docs/adr/adr-040-local-llm-context-size.md @@ -0,0 +1,93 @@ +# ADR-040: Local LLM Context Size と Resource Trade-off + +## ステータス + +試験運用 (2026-05-12) + +> 本 ADR は [ADR-039 (試験運用標準パターン)](adr-039-experimental-feature-standard-pattern.md) 配下の knowledge record。本 ADR 自体は実装変更を持たず、ADR-038 (Local LLM finding classification) で進行中の Phase D/E で得た empirical data を permanent record として固定する性格を持つ。 + +## コンテキスト + +ADR-038 配下の lint_screen / finding-classifier では `lib-ollama-client` の `DEFAULT_NUM_CTX` を Phase A → Phase C で `2048 → 8192 → 16384 → 32768` と段階的に拡大した。各段階で観測した latency / VRAM 使用量 / `step_timeout` 整合性は、将来 num_ctx を再選定する局面 (派生プロジェクトへの porting / 別 model 採用 / diff 規模変化) で再利用価値の高い empirical data だが、現状は以下に分散していて参照が難しい: + +- `src/lib-ollama-client/src/lib.rs` L128-139 の dogfood evolution コメント +- `push-runner-config.toml` L8-10 の step_timeout 履歴コメント +- `docs/local-llm-offload-analysis.md` (ephemeral 計画書、retire 予定) + +ephemeral artifact (analysis.md) には permanent data を残さない原則 (`~/.claude/rules/common/docs-governance.md` § Ephemeral 大規模コンテンツの ADR 昇格基準) に従い、Phase D/E 進行中で再利用機会が高い本 data を ADR として固定する。 + +## 決定 + +`mistral:7b` を Ollama 経由で本リポジトリの lint_screen / finding-classifier 用途で利用する際の **context size 選定の trade-off** を以下に codify し、ephemeral 経路 (lib.rs コメント / analysis.md) を本 ADR への参照に置き換える。 + +### 実測値 (mistral:7b on RTX 3070 8GB) + +| num_ctx | VRAM 使用量 | per-invoke latency (lint-screen prompt + 200-500 行 diff) | overflow 発生 | +|---|---|---|---| +| 2048 (Ollama default) | ~400MB | 評価不可 (prompt 単体で overflow) | 確実 | +| 4096 | ~450MB | (実測スキップ、PR #135 で 8192 へ直接) | 確実 | +| **8192 (Phase b'/c MVP)** | ~512MB | **5-20s** (median ~7s、Bundle i evals 15 件 p50=4.6s / p95=8.4s) | 大規模 diff (200+ 行) で発生 (Bundle i eval13 / eval15) | +| 16384 (Phase A 試行) | ~1GB | ~15-40s | PR #141 (487 行 diff) で 100% overflow 再観測 | +| **32768 (Phase C 確定値、mistral:7b theoretical max)** | ~2GB | **30-90s** (mean ~50s、3 PR replay 平均) | 確認なし (487 行 diff まで) | + +### Trade-off 軸 (context 選定時の判断基準) + +| 軸 | 8K | 32K | +|---|---|---| +| **Latency** | 5-20s/invoke = UX 許容範囲 | 30-90s/invoke = pipeline 滞留が顕在化 | +| **Memory** | 512MB = 同時に他 model 起動可能 | 2GB = `mistral:7b` 単独占有、`llama2:13b` swap 不可 | +| **Accuracy** | 大規模 diff で truncation → fallback rate 高 (Bundle i 73.3% agreement) | overflow 解消 → fallback rate < 50% に低下 (Phase C smoke で 33% 達成) | +| **Timeout 整合性** | `step_timeout = 180s` で 12 件 mistral invoke ([cargo test -- --ignored]) を完走 | `step_timeout = 600s` (= 3.33x) が必要、`push-runner-config.toml` 側で整合化 | + +### `step_timeout` 比例係数の根拠 + +`push-runner-config.toml` の `step_timeout` は num_ctx に対して **sublinear** に拡大する (context 4x = 8K → 32K に対して timeout は 3.33x = 180s → 600s)。per-token budget で見ると `180s / 8192 = 22 ms/token` ↔ `600s / 32768 = 18.3 ms/token` で、大規模 context の方が per-token 推論コストがわずかに低い (KV cache の locality 効果と推定): + +- Phase b' (8K): 180s で 12 件 mistral invoke (`cargo test --ignored`) を完走 +- Phase C (32K): 269s 観測 (= 180s 超過、cargo test 全体) → 600s に拡大 +- per-invoke latency が num_ctx に対して概ね線形に拡大する経験則 (overflow 解消後の純粋な inference time) + +**reference 値** (派生プロジェクトでの derivation 用): + +| num_ctx | 採用 step_timeout | 根拠 | +|---|---|---| +| 8192 | 180s | Phase b' 実測 (12 件 mistral invoke、cargo test --ignored 完走) | +| 32768 | 600s | Phase C 実測 (269s 超過観測 → 2x margin で確定) | + +派生プロジェクトでは上記 reference 値を最初の見積もりに使い、実測 cargo test 経過時間の **2x margin** で補正する (例: 観測 250s → 500s に設定)。 + +### Context 選定の判断 flow + +新規 LLM 系 feature 導入時 / num_ctx 再選定時の判断順序: + +1. **prompt + 想定入力の token 量を実測** (`prompt_eval_count` を Phase A diagnostic log で取得可) +2. token 量の **1.5x を初期 num_ctx 候補** とする (margin で truncation 回避) +3. 候補値が `mistral:7b theoretical max (32768)` を超える場合は、prompt 圧縮 / diff truncation / 別 model (llama2:13b 等 8K context) への切替を検討 +4. 選定した num_ctx に対して上記 reference table から initial `step_timeout` を取り、実測 cargo test 経過時間の 2x margin で補正 +5. dogfood で fallback rate / latency p95 を実観測し、`overflow_hint` (ADR-038、90% 閾値) の emit 件数を監視 + +## 帰結 + +### Pros + +- num_ctx 再選定時の判断基準が ADR として permanent 化、ephemeral 計画書 retire 時の data loss を防ぐ +- `step_timeout` 比例係数の根拠が明示化、将来の derivation 時に再発見コストが消える +- `src/lib-ollama-client/src/lib.rs` の evolution コメントが本 ADR への 1-line reference で済み、code comment 肥大化が解消 + +### Cons / リスク + +- mistral:7b 固有の実測値のため、別 model (llama2:13b / qwen2.5:7b 等) では再 calibration が必要 +- RTX 3070 8GB の VRAM 制約に依存する値、より大容量 GPU では memory 軸の trade-off が変わる +- 実測 latency は warm context 前提、cold start (model load 直後) では 1.5-2x の variance がある + +### 試験運用 → 本採用への昇格条件 + +ADR-038 が「採用」に昇格 (Phase E 完了) するタイミングで、本 ADR も「採用」に昇格する。ADR-038 が「却下」の場合は、本 ADR の data は historical record として保持する (revert はせず、`lib-ollama-client` 利用機会が再来した時のための knowledge prior)。 + +## 関連 + +- [ADR-038](adr-038-local-llm-finding-classification.md) — Local LLM finding classification、本 ADR の data 元 +- [ADR-039](adr-039-experimental-feature-standard-pattern.md) — 試験運用標準パターン、本 ADR の運用基盤 +- `src/lib-ollama-client/src/lib.rs` — `DEFAULT_NUM_CTX = 32768`、Phase C 確定値 +- `push-runner-config.toml` L8-10 — `step_timeout = 600` の根拠 +- `docs/local-llm-offload-analysis.md` (ephemeral) — Phase A/B/C 進行ログ、retire 時に本 ADR へ data migrate 済 diff --git a/docs/local-llm-offload-analysis.md b/docs/local-llm-offload-analysis.md index 9d757c6..ef9e46b 100644 --- a/docs/local-llm-offload-analysis.md +++ b/docs/local-llm-offload-analysis.md @@ -201,7 +201,7 @@ cargo test -p cli-finding-classifier --test lint_screen_evals -- \ > > **進行方針 (2026-05-11、kill-switch 100% trend を踏まえた pivot)**: dogfood を一度止めて broken signal の repair (順位 98 = `num_ctx` overflow detection 診断) を最優先。診断 → root cause 特定 → fix → clean dogfood の順で進む。Bundle c-1 (旧 P-4) や Bundle c の他項目は **本 critical path 外** として通常 Tier 1 優先度で別途処理。 -##### 🚀 Phase A: Diagnostic ✅ **完了 (本 PR、2026-05-11)** +##### 🚀 Phase A: Diagnostic ✅ **完了 (PR #142、2026-05-11)** **順位 98 実装完了** = `lib-ollama-client` の `generate_json` に `OllamaMetadata` (`prompt_eval_count` / `eval_count` / `num_ctx`) を組み込み、serde parse error 時に stderr へ warn log を emit する診断層を追加。`OllamaApi` trait の `generate_with_metadata` (default fallback あり、StubOllama は変更不要)、`emit_overflow_diagnostic` 関数で 90% 以上時に「num_ctx を増やす hint」を含める。16 unit test pass、cli-finding-classifier 経由でも warn log が stderr に出ることを smoke 確認。 @@ -209,9 +209,9 @@ cargo test -p cli-finding-classifier --test lint_screen_evals -- \ Phase A 実装後、PR #141 (P-3 = 187 行 mixed diff) を replay → **`prompt_eval_count: 8192 (vs num_ctx: 8192)` = 100% 到達を実機確認**。**真因 = num_ctx truncation で確定**。mistral の prompt が完全に context cap で truncate されて JSON output が完成せず `screen_decision` field 欠落の症状を引き起こしていた。仮説 2 候補 (num_ctx truncation / mistral 出力崩壊) のうち前者が真因と decisive 判定。 -##### 🔧 Phase C: Root cause fix ✅ **完了 (本 PR、2026-05-11)** +##### 🔧 Phase C: Root cause fix ✅ **完了 (PR #143、2026-05-11)** -`DEFAULT_NUM_CTX = 8192 → 16384` (initial) → 16384 でも 100% overflow を再観測 → `DEFAULT_NUM_CTX = 16384 → 32768` (mistral:7b theoretical max) に再増加。`lib_ollama_client` の lint test 17 件 pass、`cli-finding-classifier` evals 20 件 pass。 +`DEFAULT_NUM_CTX = 8192 → 16384` (initial) → 16384 でも 100% overflow を再観測 → `DEFAULT_NUM_CTX = 16384 → 32768` (mistral:7b theoretical max) に再増加。`lib_ollama_client` の lint test 17 件 pass、`cli-finding-classifier` evals 20 件 pass。副次的に `push-runner-config.toml` の `step_timeout = 180 → 600` に拡大 (num_ctx 増加で `cargo test -- --ignored` の 12 件 mistral invoke が long-running 化)。 **Phase C smoke dogfood** (32768 で 3 PRs replay): @@ -222,18 +222,58 @@ Phase A 実装後、PR #141 (P-3 = 187 行 mixed diff) を replay → **`prompt_ | P-3 (#141) | 487 | 55s | fallback (truncation) | ✅ `auto_fix` (real classification) | - **num_ctx truncation 起因 fallback: 3/3 → 0/3 (100% 解消)** ← Phase C 主目的を達成 -- **総合 fallback rate: 3/3 (100%) → 1/3 (33%)** ← **Phase D 基準 (<50%) を達成** +- **総合 fallback rate: 3/3 (100%) → 1/3 (33%)** ← **Phase D 基準 (<50%) を classifier preview で達成** - 残り 1/3 は mistral 出力の contract violation (Phase b' agreement 75% で説明可能な semantic 精度問題、別 phase で対応 / Phase D scope 外) -##### ✅ Phase D: Clean dogfood validation (2-3 通常 PR、real pipeline 経由) +##### 🛠️ Phase D 前提整備 (順位 109) ✅ **完了 (PR #144、2026-05-11)** -Phase C fix 入りで real pipeline 経由 dogfood。fallback rate が許容範囲 (< 50%) に落ちることを確認。既存 P-1/P-2/P-3 の preview data は Phase C 前の構成なので **不要、新 PR data で代替**。本 phase の通常 PR は Phase d roster から再選定 (Bundle f-1/f-2 / Bundle j-2 / 順位 100-108 docs bundle 等の通常 Tier 1〜3 タスクで代替可能)。 +`src/cli-push-runner/src/stages/lint_screen.rs` 改修: graceful fallback (exit 0) 時にも classifier stderr を `.takt/lint-screen-report.md` の `## Diagnostic` section に取込。Phase A 診断 warn log が **real pipeline 経由で visible** になる状態を確保。新 struct `ClassifierOutput { stdout, stderr }`、新 helper `render_diagnostic`、新規 smoke test 4 件 (TP / FP / edge case / parse-error path) で contract を seal。lint_screen tests 14/14 pass + workspace 全 cargo test pass。 -##### 🎯 Phase E: 採否判定 + retirement (1 PR、analysis.md 削除を含む) +##### 🔄 Phase D: Clean dogfood validation (real pipeline 経由、未着手、計画 land 済) + +Phase C fix + Phase D 前提整備 (順位 109) 完了で **real pipeline 経由 dogfood の必要十分条件が揃った**。次の 3 通常 PR を **session-only opt-in (b) (`push-runner-config.toml` の `[lint_screen] enabled = true` を session 内で manual 切替、commit しない)** で dogfood、`.takt/lint-screen-report.md` の `## Summary` + `## Diagnostic` で metrics を実観測。fallback rate < 50% / num_ctx 起因 0% を real pipeline で再確認できれば Phase E に進む。 + +**Phase D 対象 PR 構成 (2026-05-12 確定)**: + +| Order | 構成 (todo-summary.md priority list より) | Effort | 推定 diff 行 | Diff Profile | Phase C 既存 PR との対比 | +|---|---|---|---|---|---| +| **D-1** | 順位 112 + 113 + 114 = ADR amendments bundle (ADR-038 eprintln scope / ADR-027 metrics override / 新規 ADR Local LLM context size) | S+ | ~180-200 | docs only | #139 (414 行 docs-only) と類似 | +| **D-2** | 順位 101 + 106 + 103 = lint rule code touch (rule⑧ edge case test / self-exclusion assertion / lint runner field comment) | S+S+S | ~150-200 | Rust test/comment mix | #141 (487 行 Rust test) と類似 | +| **D-3** | 順位 102 = `paths` filter を lint runner に実装 (impl + test + 既存 rule migration) | M | ~250-350 | Rust impl + test | #141 を超える規模、num_ctx 32768 上限テスト | + +**size ramp-up 設計**: small → mid → mid-large の漸増で、small PR 単体での fallback 観測と large PR で num_ctx 限界に近づく挙動を両方カバー。 + +**Phase D 計測手順** (各 PR 共通): + +> **D-1 着手時に判明した workflow gap (2026-05-12)**: Phase D guide §1 の「session-only opt-in」 (`[lint_screen] enabled = true` を commit せず runtime のみ反映) は jj の auto-snapshot 性質と本質的に衝突する。cli-push-runner は `push-runner-config.toml` を TOML 経由でのみ読み取り、env var / CLI flag による override path は未実装。よって config 変更を @ に持たせるとそのまま push commit に乗ってしまい、「local enable / remote disable」が成立しない。**暫定方針**: D-1 (docs-only、ADR markdown は lint_screen 分析価値が低い) は `enabled = false` のまま push して dogfood をスキップ。D-2 着手前に **env var override (`LINT_SCREEN_ENABLED`) を cli-push-runner に追加** (todo8.md に backlog 登録予定) してから D-2 / D-3 の dogfood を実施する。 + +1. **PR 着手前** (D-2 以降): env var `LINT_SCREEN_ENABLED=true` を session に export (`push-runner-config.toml` の `enabled = false` は維持) +2. **push 前**: env var の有効性を `echo $LINT_SCREEN_ENABLED` (Unix) or `echo $env:LINT_SCREEN_ENABLED` (PowerShell) で確認、config TOML 側の `enabled = false` は変更しない +3. **pnpm push 実行**: lint_screen stage → takt review iteration → jj git push の流れ +4. **report 確認**: `.takt/lint-screen-report.md` を読み、以下 metrics を記録 + - (a) screen_decision (auto_fix / human_review / informational) + - (b) findings 件数 + severity 分布 + - (c) fallback_reason (あれば) + - (d) `## Diagnostic` section の有無 (Phase A warn log の visible 化検証) + - (e) latency (`.takt/runs//logs/` から抽出) +5. **post-push cleanup**: env var を unset (session 終了で自動消滅、commit には影響なし)、PR 作成 → CR review → merge +6. **3 PR 完了後**: 累積 fallback rate を集計 (num_ctx truncation / contract violation / 別問題 / 成功 で分類)、Phase D 基準 (<50% fallback) 達成判定、本 § Phase D row に dogfood outcome table 追加、Phase E 移行判断 + +**想定リスク**: + +- **D-1 dogfood 不実施**: D-1 は ADR markdown のみで lint_screen が code lint findings を検出しない予測 (informational 0 件)。Phase D 前提整備 PR #144 で pipeline integration は smoke test 4 件で seal 済のため、D-1 skip による metrics ロスは限定的 +- **env var override 実装の D-2 への前出し**: D-2 (Rust test/comment mix) の scope に env var override (~30-50 行 Rust) が加わる。D-2 effort が S+S+S+S → S+S+S+M 程度に増加するが、PR sizing rule (250-800 行) 内に収まる予測 +- **D-3 (順位 102) のサイズ**: 250-350 行を超える可能性。L effort 化しても PR sizing rule (250-800 行) 内 +- **contract violation の再観測**: Phase C P-2 で `invalid severity: "error"` を観測した型崩壊系が Rust diff (D-2/D-3) で再発する可能性、Phase D scope 外として metrics 記録のみ +- **num_ctx 32768 再 overflow**: D-3 は P-3 (487 行) より小さいため発生しないはずだが、prompt の token 効率次第。Phase A diagnostic log (`## Diagnostic` section) で即検知 + +**別案 (棚上げ)**: D-1 を順位 110+111+104 (testing.md + docs-governance routing rule + ADR-007 amendment、mixed) に変更する案もあったが、ADR codify 優先で 112+113+114 を採用。 + +##### 🎯 Phase E: 採否判定 + retirement (1 PR、analysis.md 削除を含む、未着手) - **採用 case**: ADR-038 を「採用」に昇格 + [docs/local-llm-offload-phase-d-guide.md](local-llm-offload-phase-d-guide.md) を削除 (試験運用ガイド役目終了) + 本 analysis.md を削除 + history.md は permanent record として保持判断 - **却下 case**: cli-finding-classifier crate revert + ADR-038 を「却下」に更新 + Phase d guide 削除 + 本 analysis.md 削除 -- **継続 case**: Phase C が unresolved (Phase B で別問題判明等) なら判定延期 + 本 §「次に何をするか」を再 pivot +- **継続 case**: Phase D で別問題判明等 (例: real pipeline で classifier preview と異なる挙動) なら判定延期 + 本 §「次に何をするか」を再 pivot ##### Critical path 外 (並行 land 可、本 phase 完了を block しない) @@ -243,6 +283,7 @@ Phase C fix 入りで real pipeline 経由 dogfood。fallback rate が許容範 | Bundle c-1 (順位 63+64+67、c-1a/c-1b 分割推奨) | L (M+M+XS、split 推奨) | Phase d とは独立、通常 Tier 1 として後で対応 | | Bundle j-2 (順位 95+96、`.github/workflows/lint.yml` 新設) | M (S+M) | 独立 | | Bundle f-1/f-2 (PR #120 feedback) | S+M | 独立 | +| 順位 110-114 (PR #142/#143 post-merge-feedback 採用分) | XS-S 各 | Phase D の対象 PR 候補としても活用可能 | ##### Dogfood signal log (旧 PR roster の preview 結果、Phase B/D の比較対象として保持) diff --git a/docs/todo-summary.md b/docs/todo-summary.md index 864217d..a3332d2 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -77,9 +77,7 @@ | 108 | 💎 Tier 3 | **CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用)** | todo6.md | S | なし (`~/.claude/CLAUDE.md` に memory `feedback_no_unenforced_rules` の policy をユーザー可視 table として公開、Tier 2 と称した必須化ルール提案を新セッションでも一貫して却下できる構造、memory ファイル閉鎖を補完) | | 110 | 💎 Tier 3 | **pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用)** | todo6.md | S | なし (Phase A の `overflow_hint()` をモデル例とし「境界値 / None / 閾値未満」3 パターンの test テンプレを `~/.claude/rules/common/testing.md` に追記、副作用分離の促進、Rust lib 全般で再利用) | | 111 | 💎 Tier 3 | **`docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用)** | todo6.md | S | なし (Phase/bundle 関連 → todo6、global rules/lint → todo5 等の routing rule を `~/.claude/rules/common/docs-governance.md` に追記、PR #142 で実証された file pointer bifurcation の構造的予防、CR Minor #2 と同根) | -| 112 | 💎 Tier 3 | **ADR-038 に eprintln scope + 90% 閾値 rationale 追記 (PR #142 T3-#3 採用)** | todo6.md | XS | なし (a) eprintln は CLI 前提、lib 拡張時は structured logging 移行が必要 (b) 90% 閾値は保守的設定で Phase C/D dogfood データに基づきチューニング、根拠なき早期変更を防止 | -| 113 | 💎 Tier 3 | **ADR-027 に metrics override 判断基準追記 (PR #142 T3-#4 採用)** | todo6.md | XS | なし (incidental change = PR 副作用 / cargo fmt 整形 vs responsibility change = fix 本体 の線引きと override 記述様式を ADR-027 に codify、simplicity-review 運用の一貫性確保) | -| 114 | 💎 Tier 3 | **新規 ADR: Local LLM Context Size と Resource Trade-off (PR #143 T3-#1 採用)** | todo8.md | S | なし (Phase C で取得した empirical data = mistral:7b 8K/512MB/20s ↔ 32K/2GB/90s + step_timeout 比例係数 3.33x を permanent record 化、lib.rs の dogfood evolution comment を ADR に移管、将来 num_ctx 再選定時の判断 prior) | +| 115 | 🚀 Tier 1 | **`LINT_SCREEN_ENABLED` env var override を cli-push-runner に追加 (Phase D D-1 workflow gap)** | todo8.md | S | D-2 を block (D-2 着手前に land 必須)。Phase D guide §1 の session-only opt-in が jj auto-snapshot と本質的に衝突するため、env var で TOML override する path を追加し commit-free な dogfood を成立させる。Phase D D-1 (PR #145 想定) 着手時に systemic に発見 | **戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 diff --git a/docs/todo6.md b/docs/todo6.md index 75e5af4..d00876b 100644 --- a/docs/todo6.md +++ b/docs/todo6.md @@ -619,41 +619,3 @@ config.rs + push-runner-config.toml + review-simplicity.md + ADR で family_tag - 次回 todo*.md 50KB 超過時に routing 判断が明確になり、CR Minor #2 と同型の bifurcation が再発しない ---- - -### ADR-038 に eprintln scope + 90% 閾値 rationale 追記 (PR #142 T3-#3 採用) - -> **動機**: PR #142 で実装した diagnostic log は (a) `eprintln!` で stderr 出力する設計で CLI 前提、lib として他 process から呼ばれる場合に structured logging (log/tracing) への移行が必要。(b) 90% 閾値は保守的設定で、Phase C/D dogfood データに基づきチューニングするべき。両者を ADR-038 に追記しないと将来の根拠なき早期変更 / 設計迷走を招く。 -> -> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Low / Effort XS / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/142.md` Tier 3 #3、`docs/adr/adr-038-local-llm-finding-classification.md` - -#### 作業計画 - -- [ ] ADR-038 に 2 点追記 (a) eprintln scope / structured logging 移行条件、(b) 90% 閾値 rationale + Phase C/D dogfood 後の tuning 方針 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR-038 に 2 点が permanent record として記録、将来の lib 拡張時 / 閾値変更時の判断 prior になる - ---- - -### ADR-027 に metrics override 判断基準追記 (PR #142 T3-#4 採用) - -> **動機**: PR #142 の simplicity-review で `cargo fmt` 整形による 1-2 行 diff 増加が metrics override 判定対象になった事例があり、incidental change (PR 副作用 / cargo fmt 等) と responsibility change (fix 本体) の線引きが不明瞭。ADR-027 に判断基準と override 記述様式を codify することで一貫性確保。 -> -> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 3 #4 採用 (Severity Low / Frequency Low / Effort XS / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/142.md` Tier 3 #4、`docs/adr/adr-027-push-review-simplicity-focus.md` - -#### 作業計画 - -- [ ] ADR-027 に「metrics override 判断基準」section を追加: incidental vs responsibility の線引き + override 記述様式 example -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- simplicity-review 運用で override 判断の一貫性と transparency が確保される - diff --git a/docs/todo8.md b/docs/todo8.md index d134a42..bf95b12 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -10,28 +10,34 @@ ## 現在進行中 -### 新規 ADR: Local LLM Context Size と Resource Trade-off (PR #143 T3-#1 採用) +### `LINT_SCREEN_ENABLED` env var override を cli-push-runner に追加 (Phase D D-1 着手時の workflow gap、2026-05-12 発見) -> **動機**: PR #143 (Phase C = `DEFAULT_NUM_CTX 8192 → 32768`) で取得した empirical data — 8K で 512MB / latency 5-20s、32K で 2GB / latency 30-90s、`step_timeout` の比例係数 3.33x (180s → 600s) — は permanent record として ADR に codify する価値が高い。Phase D/E 進行中で num_ctx 再選定の機会は高い + 将来の lib-ollama-client 利用拡大時の判断 prior になる。`src/lib-ollama-client/src/lib.rs` L128-139 の dogfood evolution コメント (CR Low nitpick で言及あり) を ADR に移管することで code comment 肥大化も同時解消。 +> **動機**: Phase D guide §1 / analysis.md Phase D 計測手順 は「session-only opt-in」 (`[lint_screen] enabled = true` を commit せず runtime のみ反映) を前提に記述されていたが、jj の auto-snapshot 性質と本質的に衝突する。`push-runner-config.toml` を編集すると即座に @ にスナップショットされ、`pnpm push` がその commit を remote に push してしまうため、「local enable / remote disable」が成立しない。`cli-push-runner` の config 読み取り経路に env var override (`LINT_SCREEN_ENABLED=true` 等で TOML の `[lint_screen] enabled` を上書き) を追加することで、commit-free な session opt-in が成立する。 > -> **本タスクの位置づけ**: PR #143 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 +> **本タスクの位置づけ**: Phase D D-1 (PR #145 想定) 着手時に systemic に発見された **workflow blocker**。D-2 着手前に land しないと D-2 / D-3 の dogfood も同様にスキップせざるを得ない。Effort S (~30-50 行 Rust + test 2-3 件)。 > -> **参照**: `.claude/feedback-reports/143.md` Tier 3 #1、`src/lib-ollama-client/src/lib.rs` L128-139 (移管対象 comment)、`push-runner-config.toml` の step_timeout 履歴 comment +> **参照**: `docs/local-llm-offload-analysis.md` Phase D 計測手順 (D-1 時点で gap が明文化済)、`src/cli-push-runner/src/config.rs` (LintScreenConfig 読み取り箇所)、`docs/local-llm-offload-phase-d-guide.md` §1 (旧 workflow 記述) + +#### 設計決定の余地 + +- **env var 名**: `LINT_SCREEN_ENABLED` (TOML field 名と揃える) / `PUSH_RUNNER_LINT_SCREEN` (prefix で namespace) / 別案 +- **値 semantics**: `true` / `1` / `yes` で有効、空文字列 / 未設定 / `false` で TOML 値を尊重 +- **TOML override 方向**: env var を **TOML より優先** (現状 TOML default OFF を env で強制 ON にする運用) / TOML を優先で env は fallback (現実装では TOML 必須なのでこちらは意味なし) +- **将来拡張**: 他フィールド (model / endpoint / timeout_secs) も env var で override する一般化 → 当面は `enabled` のみ +- **type 安全**: bool parse 失敗時の fallback (FALSE 扱い vs 警告 emit) → 警告 emit + FALSE 扱い #### 作業計画 -- [ ] `docs/adr/adr-04X-local-llm-context-size.md` を次の連番 (現在 040 が次) で新規作成 -- [ ] content: - - mistral:7b × 8K (512MB, latency 5-20s) vs 32K (2GB, latency 30-90s) の実測値記録 - - step_timeout の比例係数設計 (180s → 600s = 3.33x) の根拠 - - context 選定時の判断基準 (latency / memory / accuracy / timeout trade-off) - - lib.rs L128-139 の evolution history コメントを本 ADR に移管 + 参照 link 化 -- [ ] CLAUDE.md の ADR index に追加 +- [ ] `src/cli-push-runner/src/config.rs` の `LintScreenConfig::enabled` を env var override 対応に変更 (TOML 読み取り後に env を merge) +- [ ] env var parse helper 関数を追加 (bool 解釈 + warning emit) +- [ ] unit test 3 件: env unset で TOML 尊重 / env=true で override / env=invalid で警告 + FALSE +- [ ] `docs/local-llm-offload-phase-d-guide.md` §1 Setup を env var ベースに rewrite (旧「config を編集」記述を削除) +- [ ] `docs/local-llm-offload-analysis.md` Phase D 計測手順は D-1 PR で既に env var ベースに更新済、整合性を確認 - [ ] 本エントリ削除 + todo-summary.md 行削除 #### 完了基準 -- 将来の num_ctx 再選定 (Phase D/E 進行中) で本 ADR が判断 prior として参照可能になる -- lib.rs の dogfood evolution コメントが ADR へ移管され、code comment 肥大化が解消される +- env var 経由で lint_screen を有効化でき、`push-runner-config.toml` を編集せずに dogfood 実施可能になる +- D-2 / D-3 で session-only opt-in workflow が成立する --- diff --git a/src/lib-ollama-client/src/lib.rs b/src/lib-ollama-client/src/lib.rs index a9c54d1..aa63b44 100644 --- a/src/lib-ollama-client/src/lib.rs +++ b/src/lib-ollama-client/src/lib.rs @@ -125,17 +125,13 @@ fn emit_overflow_diagnostic(parse_error: &serde_json::Error, raw: &str, metadata } } -/// Ollama 既定の `num_ctx` (2048) は本リポジトリの lint-screen prompt -/// (~7700 chars = ~3000 tokens) + diff (実 PR で 24KB+ = ~10K+ tokens) に対して不足し、 +/// Ollama 既定の `num_ctx` (2048) は本リポジトリの lint-screen prompt + 実 PR diff に対して不足し、 /// prompt が silently truncate される (Ollama は overflow 時に prompt_eval_count を num_ctx に clamp して報告)。 /// -/// dogfood の進化: -/// - 2048 (Ollama default) → 評価不可、PR #135 で 8192 へ -/// - 8192 → PR #141 (P-3) で `prompt_eval_count: 8192` = 100% 到達確認 -/// - **16384** → PR #142 (Phase A 診断 log 実装) + Phase B 真因確定で増加、しかし dogfood 再計測でも 100% 到達 -/// - **32768 (現値)** → mistral:7b の theoretical max、Phase C で増加 -/// -/// 32768 でも overflow する場合は、diff truncation を classifier 側で実装する次の Phase へ進む。 +/// dogfood の進化 (2048 → 8192 → 16384 → 32768) と各段階の latency / VRAM / overflow 観測値は +/// ADR-040 (docs/adr/adr-040-local-llm-context-size.md) に migrate 済。 +/// 32768 は mistral:7b の theoretical max。overflow が再発する場合は diff truncation を +/// classifier 側で実装する次の Phase へ進む。 pub const DEFAULT_NUM_CTX: u32 = 32768; /// Ollama client 設定