diff --git a/docs/local-llm-offload-analysis.md b/docs/local-llm-offload-analysis.md index 928a51f..2db13f4 100644 --- a/docs/local-llm-offload-analysis.md +++ b/docs/local-llm-offload-analysis.md @@ -229,20 +229,20 @@ Phase A 実装後、PR #141 (P-3 = 187 行 mixed diff) を replay → **`prompt_ `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 D: Clean dogfood validation (real pipeline 経由、進行中) +##### ✅ Phase D: Clean dogfood validation (real pipeline 経由、計画完遂 2026-05-12) -Phase C fix + Phase D 前提整備 (順位 109) 完了で **real pipeline 経由 dogfood の必要十分条件が揃った**。D-1 着手時に session-only opt-in workflow が jj auto-snapshot と本質的に衝突する gap が判明したが、**順位 115 (`LINT_SCREEN_ENABLED` env var override) land で解消**。env var 経路 (`$env:LINT_SCREEN_ENABLED = "true"`) で `push-runner-config.toml` を編集せずに lint_screen を有効化できるため、D-3 で初の実 dogfood が成立する。`.takt/lint-screen-report.md` の `## Summary` + `## Diagnostic` で metrics を実観測、fallback rate < 50% / num_ctx 起因 0% を real pipeline で再確認できれば Phase E に進む。 +Phase C fix + Phase D 前提整備 (順位 109) 完了で **real pipeline 経由 dogfood の必要十分条件が揃った**。D-1 着手時に session-only opt-in workflow が jj auto-snapshot と本質的に衝突する gap が判明したが、**順位 115 (`LINT_SCREEN_ENABLED` env var override) land で解消**。env var 経路 (`$env:LINT_SCREEN_ENABLED = "true"`) で `push-runner-config.toml` を編集せずに lint_screen を有効化できるため、D-3 で初の実 dogfood が成立し、計画 3 PR + prereq 1 PR がすべて land 完了。 -**Phase D 対象 PR 構成 (2026-05-12 確定 / D-2 land + 順位 115 land 後更新)**: +**Phase D 対象 PR 構成 (2026-05-12 完遂)**: -| Order | 構成 (todo-summary.md priority list より) | Effort | 推定 / 実 diff 行 | Diff Profile | 状態 | +| Order | 構成 (todo-summary.md priority list より) | Effort | 実 diff 行 | Diff Profile | 状態 | |---|---|---|---|---|---| | **D-1** ✅ | 順位 112 + 113 + 114 = ADR amendments bundle (ADR-038 eprintln scope / ADR-027 metrics override / 新規 ADR Local LLM context size) + 順位 115 backlog 化 | S+ | 298 (insert 228 / delete 70) | docs + 1 Rust comment | **PR #145 land 済 (2026-05-12)**、lint_screen dogfood は skip (workflow gap) | | **D-2** ✅ | 順位 101 + 106 + 103 = lint rule code touch (rule⑧ edge case test / self-exclusion assertion / lint runner field comment) | S+S+S | 172 (insert 84 / delete 88) | Rust test/comment mix | **PR #146 land 済 (2026-05-12)**、lint_screen dogfood は skip (順位 115 未 land 時点) | -| **115** ✅ | `LINT_SCREEN_ENABLED` env var override (D-1 で発見した workflow gap 解消) | S | 想定通り (Rust impl + test 10 件) | Rust impl + Phase D guide rewrite | **PR #147 想定で land 中**、D-3 着手 unblock | -| **D-3** ⏳ | 順位 102 = `paths` filter を lint runner に実装 (impl + test、既存 rule⑧ migration は 順位 118 で trade-off 検討に保留) | M | 実 ~270 (insert) | Rust impl + 7 unit tests + glob filter helper | **PR #148 想定で land 中、初の real lint_screen dogfood (`$env:LINT_SCREEN_ENABLED=true` 経路) + num_ctx 32768 上限テスト** | +| **115** ✅ | `LINT_SCREEN_ENABLED` env var override (D-1 で発見した workflow gap 解消) | S | 325 (insert 268 / delete 57) | Rust impl + 10 tests + Phase D guide rewrite | **PR #147 land 済 (2026-05-12)**、D-3 着手 unblock | +| **D-3** ✅ | 順位 102 = `paths` filter を lint runner に実装 (impl + test、既存 rule⑧ migration は 順位 118 で trade-off 検討に保留) | M | 496 (insert 375 / delete 121) | Rust impl + 7 unit tests + globset 依存追加 + glob filter helper | **PR #148 land 済 (2026-05-12)、初の real lint_screen dogfood 観測** | -**size ramp-up 設計**: small → mid → mid-large の漸増で、small PR 単体での fallback 観測と large PR で num_ctx 限界に近づく挙動を両方カバー。**D-1 / D-2 は workflow gap により lint_screen dogfood をスキップ、実質 metrics 観測は D-3 のみ**。3 PR 観測予定だったが kill-switch 基準 (3/5 で停止) を踏まえて D-3 単独でも判定可能 (採用昇格 / 継続観測 / 却下) と位置付ける。 +**size ramp-up 設計**: small → mid → mid-large の漸増で、small PR 単体での fallback 観測と large PR で num_ctx 限界に近づく挙動を両方カバー。**D-1 / D-2 は workflow gap により lint_screen dogfood をスキップ、実質 metrics 観測は D-3 のみ**。3 PR 観測予定だったが kill-switch 基準 (3/5 で停止) を踏まえて D-3 単独で 1 dogfood data point を取得済。Phase E 採否判定は次回以降の通常 PR 累積で確定する設計に変更。 **D-1 / D-2 dogfood outcome (skip 理由 + 副産物)**: @@ -252,6 +252,37 @@ Phase C fix + Phase D 前提整備 (順位 109) 完了で **real pipeline 経由 - 副産物 (D-1): lib.rs L128-139 → ADR-040 移管 edit order を post-merge-feedback Tier 3 #3 で codify 採用 (順位 117) - 副産物 (D-2): clean merge (post-merge-feedback 0 件採用)、feedback loop 正常動作を再確認 +**D-3 dogfood outcome (Phase D 初の real lint_screen 観測、PR #148)**: + +| Metric | 観測値 | +|---|---| +| screen_decision | `auto_fix` | +| findings 件数 | 1 (minor severity) | +| finding 内容 | `unused-import` rule、`src/hooks-post-tool-linter/Cargo.toml:12` で `globset` を誤検出 | +| finding accuracy | **false positive** (takt reviewer が main.rs での import 使用済を diff verify で dismiss) | +| fallback_reason | なし (clean run、JSON parse error 無し) | +| `## Diagnostic` section | 不在 = num_ctx 32768 で overflow 発生せず (Phase A 診断 log emit せず) | +| lint_screen latency | 推定 ~80-120s (pipeline 総 628s − takt 248s − その他) | +| kill-switch (fallback > 50%) | fallback 0/1 = 0% → 基準内 | + +**D-3 観測の意義**: + +1. **env override 経路の実証**: PR #147 で実装した `LINT_SCREEN_ENABLED` env var で `[lint_screen] enabled = false` (TOML default) を override し、commit-free な session opt-in が成立 +2. **num_ctx 32768 の容量実証**: ~270 line Rust diff (Cargo.toml + main.rs + Cargo.lock + docs) を overflow せず完走、Phase A 診断 log も emit せず +3. **lint_screen が takt reviewer の context として活用**: reviewer 出力に「Lint-screen finding: false positive」と明示的に評価あり = advisory consumption が成立 +4. **1 false positive は Phase b' agreement 75% (= 25% disagreement) と整合**: 想定範囲内、複数 PR 累積評価が前提 +5. **副産物 (D-3 post-merge-feedback)**: `MAX_CUSTOM_VIOLATIONS` outer/inner loop break scope の explicit test 必要性を発見 (Tier 2-1 採用、順位 119)、rule⑧ への paths filter 適用範囲検討を順位 118 として backlog 化 + +**Phase D 計画完遂後の Phase E 判定材料**: + +- ✅ pipeline integration works end-to-end (D-1 #144 smoke test + D-3 real diff 完走) +- ✅ num_ctx 32768 で 270 行 Rust diff overflow なし (Phase C reference values と整合) +- ✅ fallback rate < 50% (D-3 で 0/1) +- ⚠️ agreement: 1 false positive 観測 (Phase b' 75% 想定範囲内、単発観測) +- ⏳ **複数 PR 累積必要** (Phase E 採否判定は次回以降の通常 PR で dogfood data を蓄積) + +Phase E 着手の前提条件は **3-5 PR 累積 dogfood**。D-3 で 1 PR データを取得済 = あと 2-4 PR 観測すれば判定可能。当面は通常 PR の push 時に `$env:LINT_SCREEN_ENABLED=true` を opt-in で set し、`.takt/lint-screen-report.md` を post-push で記録する運用に移行する (本 § Phase D row への追記は dogfood data 蓄積継続中の暫定方針、判定時に Phase E section へ統合)。 + **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 を実施する。 diff --git a/docs/todo-summary.md b/docs/todo-summary.md index 62c7977..4480c2f 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -75,7 +75,8 @@ | 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 と同根) | | 116 | 💎 Tier 3 | **ADR-040 `step_timeout` 説明に sublinear / KV cache locality clarification 追記 (PR #145 T3-#1 採用)** | todo8.md | XS | なし (L42-48 で「sublinear (3.33x)」と「per-invoke latency が概ね線形」が並存し reference table 600s と formula 720s が乖離。実測値 600s 採択 + 保守上限 720s + sublinear 性の KV cache locality 根拠を 2-3 行追記して整合化、永続 ADR の数値正確性確保) | | 117 | 💎 Tier 3 | **`coding-style.md § Cross-File Reference Lifecycle` に ephemeral → permanent 知識移管 edit order 追記 (PR #145 T3-#3 採用)** | todo8.md | S | なし (PR #145 で lib.rs L128-139 → ADR-040 移管 + Phase C/D empirical data 移管の 2 観測。既存ルール (参照方向制約) と complementary な「① permanent target 先行作成・validate → ② 参照追加 → ③ 参照元削除」3 ステップ原則を `~/.claude/rules/common/coding-style.md` に codify、次回 ephemeral 計画書 retire 時の checklist として再利用) | -| 118 | 💎 Tier 3 | **rule⑧ への paths filter 適用範囲検討 (順位 102 land 時の意図的保留、follow-up)** | todo8.md | XS | 順位 102 (PR #148 想定で land 中、Phase D D-3) で paths filter は実装済だが、rule⑧ への `paths = ["docs/**/*.md"]` migration は D-2 (PR #146、順位 101) で追加した root-level MD fire intent を壊すため保留。4 案 (保留継続 / broader glob / explicit list / rule split) の trade-off 評価を ADR-007 amendment (順位 104) と整合させて結論を出す | +| 118 | 💎 Tier 3 | **rule⑧ への paths filter 適用範囲検討 (順位 102 land 時の意図的保留、follow-up)** | todo8.md | XS | 順位 102 (PR #148 land 済、Phase D D-3) で paths filter は実装済だが、rule⑧ への `paths = ["docs/**/*.md"]` migration は D-2 (PR #146、順位 101) で追加した root-level MD fire intent を壊すため保留。4 案 (保留継続 / broader glob / explicit list / rule split) の trade-off 評価を ADR-007 amendment (順位 104) と整合させて結論を出す | +| 119 | 🔧 Tier 2 | **`MAX_CUSTOM_VIOLATIONS` outer/inner loop break scope を explicit test で seal (PR #148 T2-1 採用)** | todo8.md | S | なし (PR #148 で `run_custom_rules` refactor 中に発見した bug fix = inner break が outer に伝播しない問題、takt reviewer が "Behavioral change: improvement" と評価。複数 rule 実行時に violation cap が正確に機能することを explicit test で seal、将来 refactor 時の regression 防止) | **戦略**: 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/todo8.md b/docs/todo8.md index 8fbf8cd..b3cd28c 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -33,6 +33,34 @@ --- +### `MAX_CUSTOM_VIOLATIONS` outer/inner loop break scope を explicit test で seal (PR #148 T2-1 採用) + +> **動機**: PR #148 (Phase D D-3、順位 102) の `run_custom_rules` refactor で発見した bug fix = inner `for m` loop の break のみで outer `for compiled in rules` loop に break が伝播しない問題。新コードでは `collect_violations_for_rule` 呼出後に `violations.len() >= MAX_CUSTOM_VIOLATIONS` を outer loop でチェックして break する設計に修正された (takt reviewer が "Behavioral change in `MAX_CUSTOM_VIOLATIONS`: improvement" として明示的に評価)。本タスクでは **複数ルール実行時に violation cap が正確に機能する** ことを explicit test で seal し、loop 構造を再 refactor する将来時の regression を防止する。 +> +> **本タスクの位置づけ**: PR #148 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort S / Adoption Risk None)。Phase D D-3 で発見済 bug fix の test net 補強。 +> +> **参照**: `.claude/feedback-reports/148.md` Tier 2-1、`src/hooks-post-tool-linter/src/main.rs` の `run_custom_rules` + `collect_violations_for_rule` (PR #148 で extract) + +#### 設計決定の余地 + +- **test fixture 設計**: violation cap (`MAX_CUSTOM_VIOLATIONS = 20`) を超える数の違反を 1 fixture で生成、複数 rule を同時に実行 +- **scope 検証**: (a) inner loop break (1 rule で 20 件で打ち切り)、(b) outer loop break (rule A で 20 件達成後、rule B が呼ばれない)、(c) 上限未達時に複数 rule 全実行 +- **既存テスト整合**: `run_custom_rules_respects_max_violations` test が単一 rule の cap 動作を test 済。本 task はそれを multi-rule scenario に拡張 + +#### 作業計画 + +- [ ] test fixture 設計: 20+ 違反を含む test file + 2 rules (例: `rule_a` + `rule_b` の異なる pattern) +- [ ] test ケース追加: (a) `rule_a` 単独で 20 件 → outer break、`rule_b` が実行されないこと assert (b) `rule_a` で 19 件、`rule_b` で 1 件 → 両方実行されて合計 20 件 +- [ ] cargo test 全 pass を確認 (既存 102 tests + 新規 2 tests 程度 = 104 tests) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `MAX_CUSTOM_VIOLATIONS` の outer/inner loop break scope が test で明示化される +- 将来 `run_custom_rules` を再 refactor した際、cap 動作の regression が即 fail で検出される + +--- + ### rule⑧ への paths filter 適用範囲検討 (順位 102 land 時に意図的保留、follow-up) > **動機**: 順位 102 (PR #148 想定で land 中、Phase D D-3) で paths filter が lint runner に実装されたが、当初計画した rule⑧ への `paths = ["docs/**/*.md"]` migration は **意図的に保留**。理由: D-2 (PR #146、順位 101) で追加した「root-level MD (CLAUDE.md / README.md) からの `../docs/` 参照を fire = true positive で扱う」design intent が、`paths = ["docs/**/*.md"]` 適用で scope narrow されて壊れる (root-level MD の実 path が docs/ 配下ではないため rule 対象外になり、broken link 検出を失う)。本タスクで以下のいずれを採用するか検討する: