diff --git a/CLAUDE.md b/CLAUDE.md index 1c818088..97f6fb68 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,6 +42,7 @@ - [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) *(試験運用)* - [ADR-041: Test Isolation Patterns for Multi-Condition Guards](docs/adr/adr-041-test-isolation-patterns.md) *(試験運用)* +- [ADR-042: ルール vs 仕組み化の境界基準](docs/adr/adr-042-rule-vs-mechanism-boundary.md) *(試験運用)* ## Build diff --git a/docs/adr/adr-042-rule-vs-mechanism-boundary.md b/docs/adr/adr-042-rule-vs-mechanism-boundary.md new file mode 100644 index 00000000..ebf5270d --- /dev/null +++ b/docs/adr/adr-042-rule-vs-mechanism-boundary.md @@ -0,0 +1,183 @@ +# ADR-042: ルール vs 仕組み化の境界基準 + +## ステータス + +試験運用 (2026-05-25) + +> ADR-039 (Experimental feature 標準パターン) に準拠: config opt-in なし (本 ADR は decision criteria であり実装機構ではないため該当しない) / kill-switch = 本 ADR を supersede する後続 ADR で停止可能 / bounded lifetime = 採用判定 6 ヶ月 (2026-11-25) を目安に dogfood 結果から本採用 / 修正 / 却下を判定。 + +## コンテキスト + +### 問題 + +本プロジェクトでは知見の codify 先として **3 種類** の choice が存在する: + +1. **rule docs** (`~/.claude/rules/common/*.md` / `CLAUDE.md` / ADR) — 人間 / AI が session 起動時に読み込む +2. **mechanism** (custom lint rule / PreToolUse hook / CI step / cargo test 等) — runtime に機械強制 +3. **memory** (`memory/feedback_*.md`) — session 固有の補足 + +新規知見を codify する際、どの choice を選ぶかの判断が個別に行われており、systemic な判断基準が不在だった。具体的には PR #172 (順位 144 = `jj-message-required` preset) で「post-merge-feedback analyzer の docs 化原案を、ユーザー判断で hook 化に切り替え」というケースが発生し、後続 PR でも同型の判断 (6 件: 順位 44/61/146-151) が連続した。 + +### 既存事例 + +本 ADR 起案前にも、本 criteria に従う実装が散見される (= 暗黙裡の運用が systemic に存在していた): + +| 機械化済 | 元の rule docs section | +|---|---| +| `no-ephemeral-todo-reference` lint rule | `coding-style.md` § Cross-File Reference Lifecycle | +| `no-mutable-anchor` lint rule | `coding-style.md` § 日付入り見出しアンカー | +| `hooks-post-tool-comment-lint-rust` 関数長 50 行 ratchet | `coding-style.md` § Long Functions | +| `polling-anti-pattern` preset | `development-workflow.md` § 背景タスクの待機方針 | +| `exe-help-block` preset | `development-workflow.md` § 長時間 subprocess pipe truncate 禁止 | +| `find_powershell_rules_missing_case_insensitive_flag` cargo test | `code-review.md` § `(?i)` フラグ必須 | +| `rule_test_coverage_check` cargo test | `testing.md` § Custom Lint Rule Test Coverage | +| `jj-message-required` preset (PR #172) | (rule 化前に hook 化方針確定) | + +合計 **11 custom lint rule + 10 preset + cargo test contracts** が既に機械化済。残る rule docs 内に仕組み化候補が存在する。 + +### 既存 memory rules (本 ADR の哲学的基盤) + +3 件の memory rule が本 ADR の核心哲学を session-level で codify している: + +- **`feedback_no_unenforced_rules.md`**: 強制力のないルール追加は即却下、機械検知不可なら何もしない方がマシ。ルール乱立は重要ルール埋没の害悪。 +- **`feedback_pipeline_over_rules.md`**: 動作の不確実さはパイプラインで吸収。ルール codify ではなくパイプライン設計で機械的に解決、Claude 判断介入を新規導入する anti-pattern を避ける。 +- **`feedback_dogfood_evals_two_phase.md`**: 動作不確実な検証は evals + dogfood の 2 段階。妥当性 evals → 実運用 dogfood の順、PR-based 一気進行は阻害要因。 + +本 ADR ではこれら 3 件を ADR レベルに昇格し、派生プロジェクト transferability を確保する (memory は session-specific 補足として継続)。 + +## 検討した選択肢 + +### 選択肢 A: 既存 ADR-022 (自動化責務分離) に拡張 + +ADR-022 は automated actor の副作用範囲 (生成 vs 確定 / 既存 artifact 上書き禁止 等) を扱う。本 ADR の scope (rule vs mechanism の meta-decision) とは **直交**しており、拡張すると ADR-022 の主旨が霞む。**却下**。 + +### 選択肢 B: 新規 ADR で独立 codify (採用) + +本 ADR は具体的 architecture pattern ではなく **上位の meta-decision criteria** であり、後続 ADR (ADR-022 / ADR-036 / ADR-039 等) が「本 ADR criteria に従って...」と参照する構造になる。独立 ADR が ADR 階層上 clean。**採用**。 + +### 選択肢 C: 記述せず memory rules のみで運用継続 + +memory は session-specific 補足の位置付けで、派生プロジェクトに伝播しない。本 criteria は派生プロジェクト (techbook-ledger / auto-review-fix-vc) でも適用される meta-principle のため codify が必要。**却下**。 + +## 決定 + +新規知見の codify 先を選択する際、以下の **3 step 判定** と **decision matrix** を適用する。 + +### Decision framework (3 step 判定) + +#### Step 1: Mechanizable analysis (機械検知可能性) + +以下の問いに Yes/No で答える: + +- 検知方法が **regex / structural / AST / runtime check** で表現可能か? +- 検知失敗時の **graceful degradation** が可能か? (fail-soft で work 続行) + +両者 Yes なら mechanizable。一方でも No なら mechanism 化困難 = rule docs 維持。 + +#### Step 2: False positive 緩和分析 + +mechanizable な場合、以下を評価: + +- FP 率が許容範囲 (経験則 `< ~10%`) か? +- FP が出る場合、以下のいずれかで緩和可能か: + - **paths filter** (test / config / docs フォルダ除外) + - **opt-in design** (default fallback に含めない、明示有効化必要) + - **severity warning** (block ではなく judgment 補助に格下げ) + +緩和可能なら「限定 scope で仕組み化」、緩和不可能なら rule docs に倒す。 + +#### Step 3: Cost-benefit + Frequency 評価 + +- **実装工数**: S (~半日) / M (~1-2 日) / L (~3 日以上) +- **維持コスト**: rule = session 毎の read コスト × 期間、mechanism = FP 修正 / pattern 更新 コスト +- **観測頻度**: Frequency Low (1 観測) / Medium (2-3 観測) / High (4+ 観測) +- **Adoption Risk**: 既存 workflow 阻害 / breaking change の程度 + +Frequency Low の場合は **観測継続** (3 観測で再評価) を default とし、Medium+ で実装着手。 + +### Decision matrix + +| Mechanizable | FP 緩和可 | Frequency | 判定 | 代表例 | +|---|---|---|---|---| +| ✅ Yes | ✅ Yes | Medium+ | **仕組み化** (hook / lint / CI / cargo test contract) | 順位 144 (jj-message-required) / 順位 146 (secret detection) | +| ✅ Yes | ⚠️ scope 限定で可 | Medium+ | **限定 scope で仕組み化** (paths filter / opt-in / warning) | 順位 150 (magic number, source folder 限定) / 順位 151 (PR diff, 条件付き block 3 段階) | +| ✅ Yes | ❌ No (FP 過多) | * | **Rule docs** (機械化 FP 過多、judgment が必要) | 順位 100 (同一 file multi-edit anti-pattern) | +| ❌ No (semantic) | * | * | **Rule docs** (intent / NLP 必要、機械化不可) | 順位 117 (ephemeral → permanent edit order) / 順位 128 (retirement clause consistency) | +| ✅ Yes | * | Low (1 観測) | **観測継続** (3 観測で Frequency Medium 昇格 → 再評価) | 順位 81 (cli-pr-monitor CR 投稿エラー auto-retry、defer 中) | + +### 関連 design 原則 + +#### 伝播経路の違い + +- **機械化** (custom lint rule / hooks-config.toml / push-runner-config.toml): exe deploy で派生プロジェクトに伝播。各プロジェクトで明示的に有効化 / config 設定が必要 +- **Rule docs** (`~/.claude/rules/common/*.md`, `CLAUDE.md`): global location で派生プロジェクトに自動波及。`~/.claude/` の編集が直接的に派生プロジェクトの session 起動時 context に乗る + +#### Mechanism graveyard prevention + +機械化したものは継続的維持コストがかかる (FP 修正 / pattern 更新 / 廃止判定)。Frequency が下がっても放置されると tech debt 化する。本 ADR 採用後は以下を運用 default とする: + +- 機械化機構は ADR-039 (Experimental feature 標準パターン) に従い試験運用期間を設定 +- 採用判定で本採用 / 修正 / 却下を明示 +- 却下時は機械化機構を物理削除 (test を含む全 artifact) + +#### Rule docs 縮小効果 + +機械化された機構は対応する rule docs section を hook block message / CI gate output に集約することで rule docs を縮小可能。session 起動時 context 消費の削減 + AI 解釈ブレ排除の効果がある。 + +本セッション (2026-05-25) で 6 件 (順位 146-151) の仕組み化を採用した場合、`~/.claude/rules/common/*.md` の総量を **~30-50% 縮小** 見込み。 + +## 帰結 + +### 採用効果 + +- 新規知見の codify 先選択が systemic に判定可能になる (meta-decision の judgment 揺らぎ削減) +- 既存 rule の review 時にも適用 (本セッションで 6 件採用 + 3 件保留判定の実例) +- memory rules (`feedback_no_unenforced_rules` / `feedback_pipeline_over_rules` / `feedback_dogfood_evals_two_phase`) を ADR レベルに昇格、派生プロジェクト transferability 確保 +- rule docs 縮小 → session 起動時 context 消費削減 + +### 既存運用との整合 + +- ADR-022 (自動化責務分離): runtime 責務、本 ADR と直交。両者を併用 +- ADR-036 (Bundle Z 3 層): 本 ADR criteria に従い設計された pattern の一例 (= 仕組み化判定後の specific architecture) +- ADR-039 (Experimental feature 標準パターン): 仕組み化採用後の rollout phase で適用 (= 本 ADR criteria の下流) +- memory rules: ADR 昇格後も session-specific 補足として継続。新規判定時に memory を確認する運用は変更なし + +### 欠点 / 留意点 + +- **判定の揺らぎ**: 「FP 率 `< ~10%`」「Frequency Medium」等の閾値は経験則であり、厳密な定義ではない。具体ケースでの判定は AskUserQuestion 等でユーザー判断を仰ぐ運用継続が望ましい +- **既存 rule の retroactive review**: 本 ADR 採用後、既存の全 rule を review して仕組み化候補を洗い出すべきか? 本セッションで 6 件採用したが、全件 audit は scope creep。**実装着手時の opportunistic review** で十分とする +- **mechanism graveyard 防止コスト**: 機械化機構の維持・廃止判定が本 ADR 採用で増える。ADR-039 (Experimental feature 標準パターン) 適用で軽減するが、長期的な technical debt 監視は別途必要 +- **既存 ADR / docs への遡及参照**: 本 ADR を採用する時点で ADR-022 / ADR-036 / ADR-039 の冒頭に「本 ADR criteria に従う」blockquote を追加するか? **本 ADR 起案時は追加しない** (ADR-039 起案時と同方針、後続 PR で個別追補) + +### 採用判定基準 (2026-11-25 目安) + +以下のいずれかが満たされた時点で本採用に昇格: + +- 本 ADR criteria を適用した新規 rule / mechanism 判定が 5+ ケースで適切に機能 (dogfood 期間中の AskUserQuestion 介入が 30% 以下) +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) で本 ADR を reference として独自 rule / mechanism 判定が行われた事例 1+ + +不採用判定 (= 修正 or 却下) は以下で発火: + +- judgment 揺らぎが収まらず criteria が機能不全 (= AskUserQuestion 介入が 70%+) +- decision matrix の現実適合性が低いことが dogfood で明確 (例: Frequency Low でも仕組み化推奨ケースが頻発) + +## 派生プロジェクトへの展開 + +- `~/.claude/rules/common/` への直接的な追記は本 ADR では行わない。本 ADR は `docs/adr/` 内に閉じ、派生プロジェクトは本 ADR を reference として参照する +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) が独自 rule / mechanism 提案する際、本 ADR criteria を参照する想定 +- memory rules (`feedback_no_unenforced_rules.md` 等) は global location (`~/.claude/.../memory/`) で派生プロジェクトに自動波及するため、ADR と memory の両方が transferability 経路として機能 + +## 関連 ADR + +- [ADR-022 (自動化責務分離)](adr-022-automation-responsibility-separation.md) — runtime 自動化の責務境界、本 ADR と直交 scope +- [ADR-036 (Bundle Z 3 層 review)](adr-036-bundle-z-three-layer-review.md) — 本 ADR criteria に従い設計された pattern の一例 (= 仕組み化判定後の specific architecture) +- [ADR-039 (Experimental feature 標準パターン)](adr-039-experimental-feature-standard-pattern.md) — 仕組み化採用後の rollout phase pattern、本 ADR criteria の下流 +- [ADR-035 (docs-only PR 評価ポリシー)](adr-035-doc-evaluation-policy.md) — rule docs 系 PR の review 基準、本 ADR の「rule docs 維持」判定後の運用層 + +## References + +- memory: `feedback_no_unenforced_rules.md` (機械検知不可ルール却下) +- memory: `feedback_pipeline_over_rules.md` (パイプライン化優先原則) +- memory: `feedback_dogfood_evals_two_phase.md` (動作不確実な検証の 2 段階アプローチ) +- 本セッション (2026-05-25) 6 件採用 (順位 44 / 61 / 122→136 統合 / 146 / 147 / 148 / 149 / 150 / 151) + 3 件 rule 維持 (順位 100 / 117 / 128+133) +- PR #172 (順位 144 = `jj-message-required` preset) — 本 ADR 起案の直接 trigger となった hook 化 dogfood 成功事例 diff --git a/docs/bundle-history.md b/docs/bundle-history.md new file mode 100644 index 00000000..7328d83b --- /dev/null +++ b/docs/bundle-history.md @@ -0,0 +1,172 @@ +# Bundle 履歴 — post-merge-feedback 反映の累積記録 + +> **本ファイルの位置付け**: `docs/todo-summary.md` から「完了済 Bundle / post-merge-feedback 反映」の長文 paragraph を切り出した history 専用ファイル (2026-05-25 分離、todo-summary.md 50KB 超過解消)。サマリーは index 専用責務に集中、本ファイルは Bundle 単位の経緯 / 採用判定 / Sub-PR 構成等を時系列で蓄積する。 +> +> **更新方針**: 新規 Bundle の post-merge-feedback 反映時に **本ファイル末尾に追記**。Bundle 単位の paragraph は完了後も残し、reference value として保持する (削除しない)。新規 task entry は引き続き `docs/todoN.md` 系列に登録、本ファイルは「採用判定の経緯」のみ codify する。 +> +> **関連**: [docs/todo-summary.md](todo-summary.md) (現役 task の優先度 index) / [docs/todo*.md](todo.md) (現役 task 詳細) / `~/.claude/memory/feedback_*.md` (session-specific 補足) + +--- + +## Bundle 1 完了 + post-merge-feedback 反映 (2026-04-29) + +PR #91 (Bundle 1: PowerShell + Markdown anchor lint rules) merge 後の post-merge-feedback で **4 件の新規 task を追加** (PowerShell `(?i)` 自動検証 / `.claude/` filter + ADR-030 制約 / cli-pr-monitor 通知 Recovery 経路 / takt REJECT-ESCALATE)。**前 2 件は本 PR で実証された「fix iteration の根因」に対する決定論的防止策で最優先候補**。**日付ベース見出しアンカーのグローバル明文化 task は決定論的防止 (no-mutable-anchor rule) との二重防衛として継続有効**。 + +**reviewer facet 改善 (Bundle T で land 済)** + **post-pr-review fix loop の `.claude/` filter (Bundle T で land 済)** + **cli-pr-monitor ポーリング延長 + 重複起動ロック (Phase 3 で land 済)** + **rate-limit 自動検出 + 再トリガー (Phase 4 で land 済)** が完了し、reviewer 精度向上 + convergence cost 削減 + ポーリング頻度削減 + rate-limit 自動 recovery の四段構えが成立。残る Tier 2 では takt REJECT-ESCALATE が最優先候補。 + +**rate-limit 抑制の 3 層**: (1) Polling anti-pattern 検出 (PR #86 T1-1、完了済) = Claude 側の polling 禁止 (preventive)、(2) cli-pr-monitor ポーリング延長 + 重複起動ロック (PR #88 T2-4 / #96、完了済) = tool 側のポーリング頻度削減 (corrective)、(3) post-pr-review rate-limit 自動検出 + 再トリガー (Phase 4 / 完了済) = review 単位の自動 recovery。 + +**cli-pr-monitor 通知 Recovery 経路 (SessionStart hook 拡張) は PR #91 の直接観測知見**。SessionStart hook で再起動跨ぎの通知ロスト防止。post-pr-review fix loop の `.claude/` filter (path-based 解決) は Bundle T で land 済。 + +**Stop hook の `pnpm lint:md` 統合 task は Markdown linter hook 統合 (PR #88 で merged) の gap closure**。**AI 生成一時スクリプト pattern 検出は push 前 untracked `__*` hook (PR #85 T1-4) と関連** (実装前に擦り合わせ要)。 + +**`.failed` marker 自己文書化 task は ADR-030 soft-fail 機構の運用負荷削減** (PR #89 セッションで recovery が機能した実証から派生、Effort S)。 + +**takt REJECT-ESCALATE は post-pr-review fix loop の `.claude/` filter (Bundle T で land 済) の verdict-based 一般解**。path-based 解決が完了したので、本 task 着手で補完関係を完成させる。 + +**T3 グローバルルール 4 件 (日付ベース見出しアンカー / jj conflict リカバリ / `__` prefix scratch / post-pr-monitor polling 禁止) は `~/.claude/` 配下への XS 追記なので並列実施推奨**。 + +--- + +## Bundle U / V / e 完了 (2026-05-05) + +**Bundle U の 順位 29 = PR #110、順位 30 = Bundle e、Bundle V の 順位 31/32 = PR #109、順位 33 = Bundle e で全消化**。**Bundle e (convention 明文化 long-tail、2026-05-05)**: 順位 23/24/25/26 (PR #85/#86 由来) + 順位 30 (Bundle U 残) + 順位 33 (Bundle V 残) + 順位 70 (Bundle d 残) を 1 PR で集約 land、`~/.claude/rules/common/{coding-style,git-workflow,development-workflow,code-review}.md` + `~/.claude/CLAUDE.md` の global rules に convention 7 項目を codify。XS×7 で long-tail 一掃。 + +--- + +## Bundle W / X (PBT + 型強化 + cargo-mutants) + +**Bundle W (PBT + 型強化) は PR #96 で実証された flaky 実装防御の最上層**。Finding D (`saturating_sub` の silent semantic mismatch) と E (concurrency test の guard 即 drop) はどちらも「Rust 的に正しいコードがドメイン的に間違う」典型例で、advisor + takt-fix の 2 layer も貫通した。**仕様を proptest properties で明文化 + `PastTime` 等の型で invalid state を unrepresentable に** することで、ルール (ask-based) では塞げない bug class を構造的に排除する。**rate-limit 自動検出 (Phase 4 で land 済) / takt REJECT-ESCALATE を先行**し、その後 Bundle W に着手する流れがユーザー指示。 + +**Bundle X (cargo-mutants + stress runner) は Bundle W の後付け検証層**。L2 post-PR で変更 crate + 1-hop 依存に cargo-mutants を走らせ test の弱さを直接測定、L1 pre-push で concurrency stress N=100 を回し scheduling race を sampling。Bundle W で書いた spec / 型を後段で機械的に検証する補完関係。**L3 weekly cargo-mutants workspace 全体 + stress N=1000 は ADR-031 Phase B 週次レビューと bundle 化** することで long-tail flake と coverage 全体監査を week 単位で audit する layer に統合。 + +--- + +## PR #98 (Bundle Y2) post-merge-feedback 反映 (2026-05-01) + +3 件の follow-up task を追加。**takt workflow `model` フィールド必須化 lint rule** と **Bundle Y2 効果の定量計測** は Bundle Y2 完全性確保 + ROI 検証で同系列 (lint rule 着手時に post-pr-review.yaml supervise step への `model: sonnet` 明示追加を同 PR に含める想定)。**prepare-pr skill Step 1 bookmark 存在チェック強化** は本セッション運用痛 (bookmark 未作成 push 失敗) から派生した独立 task で skill repository 側の更新となる。 + +--- + +## Bundle a (PR #99 post-merge-feedback 反映、2026-05-02 拡張) + +4 component を **2 Sub-PR で分割** land 推奨 (設計根拠は ADR-034)。共通テーマは「PR #99 で複数回発生した手動 `@coderabbitai review` 投稿の自動化」 + 「CR review query の token bloat 削減」。Bundle Y2 効果でパイプラインが加速した結果として CR rate-limit 発生頻度が増えた逆説的副作用への対策。effort 合計 M+S+XS+M (= 2 Sub-PR で M、M+S 程度に分散)。 + +- **Sub-PR 1 (token 削減層、先行)**: **gh CLI 使用規則** (`git-workflow.md` 追記) + **`check-ci-coderabbit --list-findings`** (Rust モード、cli-pr-monitor 連携 API 提供)。旧 Bundle Z2 の `#D-1` + `#D-3` を本 Bundle に統合 (旧 `#D-2` は `#D-3` で代替のため取り下げ、旧 `#D-4` は思考連続性懸念で保留、ADR-034 参照) +- **Sub-PR 2 (rate-limit 自動化層、主軸)**: **cli-pr-monitor の rate-limit auto-retry** (Sub-PR 1 の `--list-findings` API を消費) + **ADR-018 / ADR-009 の rate-limit retry ポリシー明文化** + **integration test 追加** (rate-limit 検出 → backoff → retry サイクルの regression 防止、PR #100 post-merge-feedback T2-1 採用) + **`parse_findings` 系 error-path test infra** (順位 49、PR #101 T2-1、`unwrap_or_else(\|_\| empty)` silent fallback の test 検証)。session 超え recovery / walkthrough overlay 検出 / 解除 + 1 分マージン投稿の設計詳細は ADR-034 + +--- + +## PR #101 (Bundle a Sub-PR 1) post-merge-feedback 反映 (2026-05-03) + +9 件の finding を頻度評価 (過去 report 横断 + 同一 PR latent 件数) して **3 件を採用**。**順位 47 (`>` vs `>=` boundary lint)** は同一ファイル内 3 関数 (parse_listed_findings / parse_new_comments / parse_findings) で同 drift が実証済 = latent 高頻度。**順位 48 (関数長 oxlint)** は #96 / #101 で繰り返し言及 = explicit 高頻度。両者とも Bundle Z #B-α と同じ「決定論的防止層」哲学で、Bundle Z Phase 1 (Rust comment lint) の land 後に並列 deploy 可能。**順位 49 (error-path test infra)** は #99 / #101 で同型 silent fallback anti-pattern が再発、Bundle a Sub-PR 2 (順位 42 / 43 / 46) と **同一 PR で land** 推奨 (cli-pr-monitor の mock infrastructure を再利用、test 二重投資なし)。残り 6 件 (Tier 1 #1, #3, #5、Tier 2 #2、Tier 3 #1, #2) は session 1 回限りの low-frequency events として不採用。 + +--- + +## Bundle h (PR #123 post-merge-feedback、experimental feature 標準パターン + ephemeral lifecycle 強化、2026-05-07) ✅ 完了 + +順位 89 (Experimental feature 標準パターン = ADR-039 として codify) + 順位 90 (ephemeral 大規模 content の ADR 昇格基準 + config コメント lifecycle anti-pattern を `~/.claude/rules/common/{docs-governance,coding-style}.md` に追加) で land。 + +**却下** (4 件): T1 #3 (`enabled = true` 検出 lint、誤検出確実) / T1 #4 (見出し参照誤り検出 hook、NLP 必要) / T2 #2 (env var override、ROI 不成立) / T3 #4 (ADR-039 config hardcode policy、ADR-038 でカバー済)。**様子見** (4 件): T1 #1 (ephemeral 計画書参照 lint、命名規則 codify 先行) / T1 #2 (jq 括弧不均衡 lint、再発頻度低) / T2 #1 (classifier endpoint fallback integration test、takt test infra 調査依存) / T3 #3 (config コメント ADR 参照修正、XS opportunistic)。 + +--- + +## Bundle g (PR #121 post-merge-feedback、monitor verdict logic + session pattern codify、2026-05-07) ✅ 完了 + +4 件採用 (Tier 1 #85、Tier 2 #86、Tier 3 #87/#88) を 2 PR で land。**g-1 (順位 85 + 86、Rust 実装 + verdict transition matrix tests) は PR #125 で land 済** (`compute_verdict` の review_state == "not_found" / "pending" guard + 12 verdict transition tests in `src/cli-pr-monitor/src/stages/monitor.rs`)。**g-2 (順位 87 + 88、global rule 追記)** は Bundle h と同 PR (#139) で land 済。Bundle f との関係: Bundle f は retry logic (rate-limit + 投稿エラー)、Bundle g は verdict logic (review_state 評価) で別軸、両者 land で post-pr-monitor の robustness が retry/verdict/state 全方向で堅牢化された状態。 + +--- + +## Bundle f (PR #120 post-merge-feedback、cli-pr-monitor robustness、2026-05-07) + +PR #120 (ADR-038 Phase 5: cli-finding-classifier 統合) の dogfood で post-pr-monitor の wakeup state 遷移に複数の edge case を観測。**5 件採用** (Tier 1 #80/#81、Tier 3 #82、Tier 2 #83、Tier 3 #84) で **3 層対策**: (1) 実装層 = 順位 80 / 81 (rate-limit + CR 投稿エラーの auto-retry path 整理) + 順位 82 (ADR-018 設計明文化、同 PR 推奨)、(2) test 層 = 順位 83 (複合 guard の独立 variant test)、(3) ガイド層 = 順位 84 (code-review.md checklist 追記、独立並列可)。**Sub-PR 分割推奨**: f-1 (順位 80 + 81 + 82、cli-pr-monitor + ADR、Effort M+M+S、Bundle f コア) / **f-2 (順位 83、test 拡充) + f-3 (順位 84、global rule) は 2026-05-21 land 済 (Bundle B)**。Bundle f はローカル LLM dogfood (ADR-038 採用、2026-05-15) の副産物として cli-pr-monitor の堅牢化を進める位置づけ。 + +--- + +## Bundle c (PR #109 post-merge-feedback 堅牢化、2026-05-04) + +PR #109 で post-merge-feedback workflow が SIGPIPE で silent 中断され `.failed` marker 未生成という ADR-030 仕様違反が実証された。5 件採用 (Tier 1 #63/#64/#65 + Tier 3 #66/#67) で **3 層防御** を構築: (1) 事前防止 = 順位 65 (exe + `--help` を PreToolUse block) + 順位 66 (グローバルルールの subprocess pipe truncate 禁止)、(2) in-process recovery = 順位 63 (Drop guard / signal trap で abrupt 終了時の `.failed` marker 保証)、(3) out-of-process backstop = 順位 64 (`meta.json status=running` 5-15 分放置 reaper)。順位 67 (ADR-030 spec 拡張) は実装と同 PR で仕様/実装の整合性確保。**Sub-PR 分割推奨**: c-1 (順位 63 + 64 + 67、Rust 実装 + ADR、Effort M+M+XS、コア層) / c-2 (順位 65 + 66、hook + global rule、Effort S+XS、trigger 防止層)。c-1 と c-2 は独立に land 可能だが c-1 land 後の dogfood で recovery 機構を実証してから c-2 を入れると順位の合理性が見える順序になる。 + +--- + +## Bundle d (PR #110 post-merge-feedback、2026-05-04) + +PR #110 (Bundle "docs quality pre-write") merge 後の post-merge-feedback で 6 findings 中 3 件採用。共通テーマは「PR #110 で導入した `no-ephemeral-todo-reference` rule (順位 29 採用分) の robustness 強化 + 設計 doc / 実装の乖離 ガード」。**順位 68 (T2 self-exclusion test)** は **本 PR (Phase d P-3 繰上げ) で land 済** = `hooks-post-tool-linter` の 6 件 unit test (TP / FP / Edge / 大文字無視 / 拡張子限定 / deployed TOML self-exclusion invariant)。**順位 69 (T3 yaml/yml コメント)** は OBS-2 (spec-impl 乖離) 対策で別 PR で対応予定。順位 70 (code-review checklist) は Bundle e で land 済。 + +--- + +## Bundle f + retirement (PR #111 post-merge-feedback + 計画書 retire、2026-05-05) ✅ 完了 + +PR #111 (Bundle e) merge 後の post-merge-feedback で 10 findings 中 4 件採用 (順位 71/72/73/74 = Tier 3 XS×4) + 順位 62 (Document Governance) + `docs/docs-pr-iteration-efficiency.md` retirement を **1 PR で集約 land**。Sub-PR 分割推奨ルール (順位 73 自身が codify する内容) を本 PR で **dogfood**: 順位 73 が land する PR 自身が「分割 vs 統合」判断対象 → ファイル削除 + 順位 62 + Bundle f を統合した結果、scope は 5 ファイル touch (global rules 2 + ADR 2 + 削除 1) + cleanup で clean、Bundle 分割で得られる review 容易性より統合 PR の atomic な lifecycle 完結性が勝った。共通テーマ: 「PR #111 自己違反事例 → self-application 強化」 + 「Document Governance を global rule に codify」 + 「計画書 retirement を実例化」の 3 layer 同時 land。 + +--- + +## PR #113 (Bb-1 = Bundle b PR-1) post-merge-feedback (2026-05-05) + +9 findings に対して **1 件のみ採用** (順位 75 = T2-2 の `finalize_parked` write_state 失敗時 fail-safe 回帰テスト)。T1 #1/#2 (lint rule 案) は NLP 必要 / FP リスクで却下、T2-1 (Windows path test) / T2-3 (state cycle integration) / T2-4 (CronCreate format lint) は ROI 不見合いで不採用、**T3-1 / T3-2 (`~/.claude/rules/common/coding-style.md` への ルール追記)** は **ユーザー判断で却下** — 「強制力のないルール追加は却下: 機械検知できなければ何もしない方がマシ。ルール乱立は重要ルール埋没の害悪」(memory: feedback_no_unenforced_rules.md として codify 済)、T3-3 (PARK signal 設計 ADR) は premature で 🤔 様子見保留。**本 PR 含意**: Bb-1 の sibling parity invariant (`finalize_*` 群の error path 対称性) は Bb-2 / Bb-3 で同種関数を追加する際に再発確度が高いため、**test レベルで machine-enforceable に保護** することを Bb-2 着手前の前提条件とする。 + +--- + +## PR #114 (Bb-2 + 順位 75 = Bundle b PR-2 + T2-2) post-merge-feedback (2026-05-05) ✅ 完了 + +9 findings に対して **2 件採用 / 5 件様子見 / 3 件却下**。**Bb-3 (順位 55) で fold-in する採用提案**: T2-2 (Parity test coverage 拡張 = `finalize_park_siblings_have_symmetric_write_state_handling` テストに `finalize_initial_review_park` を追加、self-violation 解消、Effort S)。T2-1 (Legacy JSON deserialize test) は **PR #114 で既に実装済** (`state_legacy_json_without_new_fields_deserializes_with_defaults`、Bb-3 以降の新フィールド追加時に同 pattern を継続するための reference として保存)。 + +**様子見 (5 件)**: T1-1 (finalize_* parity lint、Effort M + NLP 必要、簡易プロキシで再評価) / T1-2 (polling block lint、FP リスクで dogfood 後判断) / T2-3 (env override コメント強化、XS Low) / T2-4 (CI parallel race 確認、preventive only) / T3-1 (Wakeup Resume Invariant ADR) / T3-2 (DI 戦略 ADR、Bb-3 着手時に再検討)。 + +**却下 (3 件)**: T1-3 (Serde schema lint、ROI 低、T2-1 で代替) / T3-3 (parity invariant の global rules 追加) / T3-4 (test-only env var prefix rule) — 後 2 件は **memory: feedback_no_unenforced_rules.md** を直接引用してアナライザが正しく即却下判定。Bb-2 land 時点で Bundle b の核 (CronCreate park モデル) 完成、残る Bb-3 は config 整理 + SessionStart catch-up + T2-2 follow-up を bundled。 + +--- + +## Bundle j (PR #133 post-merge-feedback、docs/ 整合性多層検証、2026-05-09) + +PR #133 (todo.md / todo5.md 50KB 分割) merge 後の post-merge-feedback で 9 findings 中 **3 件採用** (Tier 1 #1 / Tier 2 #3, #4) で **3 層対策**: (1) **規約層** = 順位 94 (`(?i)\]\(\.\./docs/` regex 1 行で `docs/` 配下からの逆戻り参照を block) は CodeRabbit が PR #133 で実検出した broken link を決定論的に防止、(2) **CI 検証層** = 順位 95 (preamble file count 自動照合) は todo*.md 分割が今後反復する pattern (todo3 → 4 → 5 → 6 → 7) のため Frequency Medium で採用、(3) **包括的 link 検証層** = 順位 96 (Markdown cross-reference validator、directory-aware resolution) は順位 10 (ADR-032 PR-broken-link) と方向性近接で fold-in 検討余地あり。 + +**Sub-PR 構成**: **j-1 (順位 94、`.claude/custom-lint-rules.toml` 規約追加) は land 済 (Phase d P-2)** / j-2 (順位 95 + 96、`.github/workflows/lint.yml` 新設 = workflows 未存在 repo の最初の workflow 整備、Effort S+M、まとめて land が効率的)。 + +**却下** (2 件): T1 #2 (prose 数詞 lint、NLP 必要 + FP 確実) / T3 #5/#6 (機械検知不可ルール追加、`feedback_no_unenforced_rules.md` 適用)。**様子見** (3 件): T3 #7 (ADR-035 not_applicable と GitHub thread state の乖離明文化、1 観測のみ) / T3 #8 (ADR-030 AFK wakeup 時 PR body intent ルール化、1 観測のみ) / T3 #9 (50KB 分割原則 CLAUDE.md 明文化、機械検知不可)。 + +**本 PR 含意**: 順位 94 = 「決定論的防止層」哲学 (Bundle Z #B-α 系譜)、順位 95-96 = 「規約だけでは塞げない構造的検証は CI で」(ADR-031 週次レビューと相補)。`.github/workflows/` 未存在 repo に最初の workflow を追加する転換点でもあり、scope 慎重判断が必要。 + +--- + +## Bundle k (PR #151 post-merge-feedback、Phase D dogfood 観測由来の lint-screen FP 対策、2026-05-13) + +PR #151 (Phase D D-5 = comment-lint test 拡充 + MAX cap test) merge 後の post-merge-feedback で 11 findings 中 **5 件採用** (Tier 1 #1, #2 / Tier 2 #1 / Tier 3 #1, #2) を 5 entries (順位 123-127) で登録。**コア発見**: D-3 (PR #148) / D-4 CR fix (PR #150) / D-5 ×2 (PR #151) の 3 PR・4 push events で「mistral:7b が docs-only diff や `.md` ファイルに対して Rust の `unused-import` を hallucinate する」FP pattern が一貫して観測 = Phase b' fixture では再現しない failure mode。**順位 123 (lint-screen MD 除外フィルター、Tier 1 / M / High freq)** が最重要 = 拡張子ベース mechanical filter で構造的に解消可能、Phase D dogfood 観測から導かれた最も価値ある決定論的防止策。 + +**Sub-PR 推奨**: k-1 (順位 123 + 126、実装 + ADR-038 codify、Effort M+XS、コア層) / k-2 (順位 124 + 127、TOML test + extensions code comment、Effort S+XS、test gap 補強層) / k-3 (順位 125、UTF-8 boundary 横展開、Effort M、独立) で 3 PR 分割推奨。 + +**却下** (4 件): UTF-8 lint rule (FP リスク、AST 必須) / `byte_offset_to_line` 強化 (PR #151 で既対応) / UTF-8 guideline + extensions checklist (`feedback_no_unenforced_rules.md` 適用)。**様子見** (3 件): T2 #2 (lint-screen dogfood CI step、L effort + takt test infra 調査依存) / T3 #3 (test 拡充→bug 発見 pattern を ADR-007 記録、1 PR 観測のみ) / T3 #4 (multi-rule scenario fixture pattern を test comment 明文化、Low × Low)。 + +**本 PR 含意**: Phase D dogfood 観測 (analysis.md L334-340) が直接 actionable な決定論的防止層 (順位 123) に結実、Phase E 採否判定前に systemic FP root cause が解消される構造的進展。 + +--- + +## Bundle k 補強 (PR #152 post-merge-feedback、D-6 docs-only PR、2026-05-13) + +PR #152 (Phase D D-6 = fix.md instruction-level review-diff refresh + Bundle k 順位 123-127 entry 登録) merge 後の post-merge-feedback で 8 findings 中 4 件採用 (Tier 1 #1 / Tier 2 #1 / Tier 3 #1, #2)。**全 4 件が Bundle k 既存エントリ (順位 123/124/126/127) と完全重複** = post-merge-feedback analyzer 自身が「Bundle k 優先度 X で既に roadmap 済」と明記。新規順位を追加せず、**既存 4 entries (順位 123/124/126/127) に PR #152 を追加観測として追記** (frequency 観測: 3 PR → **4 PR** に更新、Bundle k の優先度 / Sub-PR 分割推奨は不変)。 + +**注**: 順位 126 (ADR-038 hallucinate codify) は Phase E 採用昇格 PR で ADR-038 へフォルドイン land 済 (2026-05-15)、現 table には不在。 + +**含意**: PR #152 (docs-only) でも `.md` への `unused-import` FP が同根 root cause で再現したことが「lint_screen FP は diff 内容ではなく hook source 周辺 context を見て hallucinate している」仮説を 4th observation として裏付け = 順位 123 拡張子フィルター実装の confidence 向上。 + +**様子見** (2 件): PostToolUse hook 自動化 (案 D、Frequency Low) / fix.md 自己参照 ambiguity (1 PR 観測のみ、次回 fix.md 編集機会に opportunistic 適用)。**却下** (2 件): 機械検知不可な `~/.claude/rules/*` 追加 (memory `feedback_no_unenforced_rules.md` 適用)。 + +--- + +## Bundle k 補強 (PR #153 post-merge-feedback、analysis.md 軽量化 PR、2026-05-13) + +PR #153 (D-6 post-merge follow-up + analysis.md 49KB→26KB split) merge 後の post-merge-feedback で 6 findings 中 **2 件採用** (Tier 3 #1, #2)。**T3 #1 = 順位 126 (ADR-038 hallucinate codify、Phase E でフォルドイン land 済) と完全重複** → 順位 126 entry を「**5 PR 連続観測** (#148/#150/#151/#152/#153)」+ root cause / structural fix の明示記載要件追加で更新 → 最終的に Phase E 採用昇格 PR (2026-05-15) で ADR-038 § Known failure modes に migrate。**T3 #2 = 新規採用** → **順位 128 (CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist 追加)** として登録、PR #133 (todo.md 分割) + PR #153 (analysis.md 分割) の successful pattern を明文化。 + +**様子見** (2 件): CLAUDE.md → docs-governance.md cross-link / docs-only PR template の Retired sections list (どちらも Frequency Low)。**却下** (2 件): cross-reference lifecycle 自動 lint rule (NLP 必要) / file role scope exceptions guidance (1 観測のみ、過剰一般化リスク)。 + +**含意**: docs-only PR でも mistral:7b の FP が 5 観測目として再現、Bundle k 順位 126 の優先度を High freq として確定。多ファイル分割の retirement workflow を順位 128 で global rule 化することで、今後の docs/* 50KB 分割 (history.md 等) で同 pattern を mechanical に reproducible 化。 + +--- + +## PR #168 post-merge-feedback (Bundle B follow-up、2026-05-21) + +PR #168 (Bundle B = 順位 83 cli-pr-monitor 複合 AND guard test 単独検証 + 順位 84 code-review.md checklist 追記) merge 後の post-merge-feedback で 6 findings 中 **1 件採用** (Tier 3 #2) を 順位 139 として登録。**順位 139 = ADR-041: Test Isolation Patterns for Multi-Condition Guards** — PR #120 W-001 初発見 + PR #168 sentinel pattern 実装の **2 PR 横断で Frequency Medium** に達したため、code-review.md global checklist (順位 84 land 済) に加えて project-level ADR で rationale・実装例 (poll.rs `enrich_with_classifier_skips_when_disabled` / `_skips_when_findings_empty`)・PR #120 W-001 history を codify する方針が成立。番号は順位 135 codified placeholder policy に従い当初 `ADR-NNN` で entry 登録 → **本 PR (順位 139 land) で `ADR-041` 確定取得**、順位 78 (旧 ADR-041 予約) を再 placeholder 化。 + +**様子見** (1 件): T2 #1 (guard isolation test 用 precondition assert helper macro 抽出、複合 guard test 再登場時に再評価)。**却下** (4 件): T1 #1 (NLP 必要 + L effort lint rule) / T1 #2 (Bundle Z #B-α safe-list exception、Frequency Low + 代替策で十分) / T2 #2 (CI coverage section、Very Low freq + ROI 不見合い) / T3 #1 (`~/.claude/rules/rust.md` rule 追加、`feedback_no_unenforced_rules.md` 適用)。 + +**recovery 含意**: 本 PR の post-merge-feedback は cli-merge-pipeline 経由で起動した workflow が PC crash で abrupt 終了し、ADR-030 §L1 の pre-emptive `.failed` marker (`168.md.failed`) が UserPromptSubmit hook (`hooks-user-prompt-feedback-recovery`) によって次セッションで検出 → `pnpm exec takt -w post-merge-feedback` 直接再起動で aggregation 完了 → manual cleanup (report copy + marker 削除) で復旧。**gap 観測**: 復旧手順 (`168.md.failed` の文書) は takt 再起動コマンドのみ codify されており、`.takt/runs//reports/feedback-report.md` → `.claude/feedback-reports/.md` への copy + marker 削除という artifact relocation step が未文書化。次回類似復旧時の摩擦軽減 follow-up 候補。 diff --git a/docs/todo-summary.md b/docs/todo-summary.md index f99480d7..015337b6 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -2,7 +2,7 @@ > **本ファイルの位置付け**: `docs/todo.md` から「推奨実行順序サマリー」section を切り出した index 専用ファイル。各タスクの詳細は「ファイル」列に示された `docs/todoN.md` を参照する。`docs/todo.md` のサイズが 50KB を超え Claude Code 読み取り安定性に影響したため分離 (2026-05-09)。 > -> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo8.md`、2026-05-11 PR #143 T3-#1 採用時に todo6.md が 50KB 到達したため todo8.md に移行) に記録する。 +> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo9.md`、2026-05-25 PR #172 仕組み化方針切替セッション時に todo8.md が 60KB 到達したため todo9.md に移行) に記録する。 ## 推奨実行順序サマリー (2026-05-10 更新、ADR-033 採番管理簡素化 land 後) @@ -36,7 +36,7 @@ | 41 | 🔧 Tier 2 | **Bundle Y2 効果の定量計測 — post-merge-feedback / post-pr-review の avg time 比較 (PR #98 T2-2)** | todo4.md | M | なし (PR #97 sonnet baseline vs PR #98 以降 haiku の実測比較。Bundle Z / Z2 の ROI 判断材料、PR #98 merge 後 3-5 PR の観察ベース) | | 42 | 🔧 Tier 2 | **cli-pr-monitor の rate-limit auto-retry + `@coderabbitai review` auto-trigger 実装 (PR #99 T2-4) ★ Bundle a Sub-PR 2** | todo4.md | M | 順位 45 と同 PR (Sub-PR 2、Sub-PR 1 の `--list-findings` API を消費) | | 43 | 💎 Tier 3 | **ADR-018 / ADR-009 の rate-limit retry ポリシー明文化 (PR #99 T3-5) ★ Bundle a Sub-PR 2** | todo4.md | S | 順位 42 と同 PR (Sub-PR 2 内、実装と ADR の整合確保) | -| 44 | 💎 Tier 3 | **gh CLI 使用規則を `~/.claude/rules/common/git-workflow.md` に追記 (計画書 #D-1) ★ Bundle a Sub-PR 1** | todo4.md | XS | なし (Sub-PR 1、Sub-PR 2 でも `gh api` を使うため先行 land 推奨) | +| 44 | 💎 Tier 3 | **PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25)** | todo4.md | M | なし (順位 144 hook 化 dogfood 成功事例を踏襲、3 BlockedPattern = 応答破棄漏れ POST / `--jq` なし GET / CR walkthrough state 混入 を `exception` field 付きで実装、`feedback_pipeline_over_rules.md` 適用で rule → hook 切替、session 毎の rule load コスト不要) | | 45 | 🔧 Tier 2 | **`check-ci-coderabbit --list-findings` Rust モード追加 (計画書 #D-3) ★ Bundle a Sub-PR 1** | todo4.md | M | なし (Sub-PR 1、cli-pr-monitor が消費する構造化 findings API を提供) | | 46 | 🔧 Tier 2 | **CodeRabbit rate-limit auto-retry の integration test (PR #100 T2-1) ★ Bundle a Sub-PR 2** | todo4.md | M | 順位 42 と同 PR (Sub-PR 2、rate-limit auto-retry 実装と一体) | | 49 | 🔧 Tier 2 | **`parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2** | todo7.md | M | 順位 42 / 43 / 46 と同 PR (Sub-PR 2、`unwrap_or_else(\|_\| empty)` silent fail 抑止 + cli-pr-monitor mock infra 流用) | @@ -44,7 +44,7 @@ | 52 | 💎 Tier 3 | **comment-lint hook の MultiEdit 対応 (順位 50 follow-up)** | todo7.md | S | なし (順位 50 で v1 = Edit のみ実装、MultiEdit は whole-file fallback で no-regression、利用頻度低く優先度は低) | | 57 | 🔧 Tier 2 | **Aggregation cap integration test (PR #105 T2-1 採用)** | todo7.md | S | なし (`collect_all_violations` の MAX_VIOLATIONS contract を test 化、将来の lint 追加時に `truncate(MAX)` 削除 regression を防止する explicit 安全網) | | 60 | 💎 Tier 3 | **analyze-session の transcript filter 絞り込み (旧 #A-3)** | todo7.md | M | なし (旧 docs/pipeline-token-efficiency.md #A-3、ADR-036/037 化に伴い計画書削除、本 task のみ todo に移管。analyze-session の input range を PR 作成 commit〜merge に限定して input token 30-50% 削減見込み、dogfood で実測必要) | -| 61 | 🔧 Tier 2 | **post-PR 検証フローに CR review.body 手動スキャン step 追加 (PR #108 T2-1 採用)** | todo7.md | XS | なし (PR #108 で analyze-coderabbit が review body の outside diff range comment を検出漏れし line 371/378 の修正が後追い、blind spot の暫定緩和策として手動 checklist を整備) | +| 61 | 🔧 Tier 2 | **`check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25)** | todo7.md | M | 順位 45 (`--list-findings` Rust モード) land が前提、`source: "inline" \| "review_body"` field 追加で同型 finding 化、手動 checklist (= 当初 rule 案、人間が忘れる課題) を programmatic 検出で置換、`feedback_pipeline_over_rules.md` 適用、analyze-coderabbit 連携で merge 前検出を構造化 | | 78 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up** | todo5.md | S | なし (config が user-editable system boundary のとき `sanitize()` 値域検証を必須化し dependent arithmetic に `// SAFETY: により上限保証` コメントを要求するパターンを ADR + CLAUDE.md に codify、Rust 固有の checked_add + MAX_SAFE capping + time-dependent test の 3 層を明文化。2026-05-16 entry 登録時の旧予約 ADR-038 → ADR-041 振り直し → 順位 139 (PR #168 follow-up) ADR-041 取得に伴い 2026-05-22 再 placeholder 化、land 時 PR で空き番号確定 — 順位 135 codified placeholder policy の実例運用) | | 79 | 💎 Tier 3 | **`docs-governance.md` § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用)** | todo5.md | XS | なし (PR #117 で順位 15 を Bb-3 で吸収済として削除した際、現 Step 2「残タスクを priority table に登録」が priority table から除外するケース = 完了/deprioritize/defer を未定義だった実証。除外時の commit/PR で 3 値のいずれかを明示する要件を追加して将来の同型 ambiguity を構造的に防ぐ) | | 81 | 🚀 Tier 1 | **cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer)** | todo5.md | M | 1 観測のみで systemic 性未確認 (§A-2 P-5 PR で defer 判断、ADR-018 §追記 2026-05-08 で re-trigger 条件 = 2 件以上の同型観測を規定) | @@ -62,63 +62,22 @@ | 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) と整合させて結論を出す | -| 122 | 💎 Tier 3 | **`development-workflow.md` Step 0 に「新 todo 着手前の既実装確認」チェックステップ追加 (PR #150 T3-#1 採用)** | todo8.md | XS | なし (memory rule `feedback_verify_task_not_already_done.md` を canonical workflow へ昇格。`jj log --limit 20 ` は決定的コマンドのため `feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + 機械実行可能で採用、グローバル設定変更前に `~/.claude/` バックアップ取得必須) | -| 125 | 🔧 Tier 2 | **UTF-8 マルチバイト boundary test を他の string-processing hooks に横展開 (PR #151 T2-#1 採用)** | todo8.md | M | なし (PR #151 で `byte_offset_to_line` char-boundary panic bug を test 拡充で発見、同型関数を持つ他 hooks に systemic 防御を確保。test 拡充が production fault detection に直結する事例の横展開) | | 128 | 💎 Tier 3 | **CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用)** | todo8.md | XS | なし (PR #133 (todo.md 分割) + PR #153 (analysis.md 分割) の successful pattern を明文化、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | | 133 | 💎 Tier 3 | **docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = grep hit は実ファイル Read で確認」明記 (PR #156 T3 #1 採用)** | todo8.md | XS | なし (PR #156 で 5 件以上の false alarm 発生、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | | 134 | 💎 Tier 3 | **ADR-035 に docs-only PR 評価の適用外基準リスト追加 (mutation / error handling / DRY / YAGNI / function length / test coverage / magic-number 等) (PR #156 T3 #2 採用)** | todo8.md | S | なし (Severity Medium = reviewer の criteria 誤適用による unnecessary review overhead / 開発体験劣化、ADR-035 は分類基準のみ定義済で適用外基準が未明示、`feedback_no_unenforced_rules.md` 例外 = ADR への追加で機械強制ではなく reviewer / Claude の judgment 補助) | | 135 | 💎 Tier 3 | **todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来)** | todo8.md | XS | なし (順位 78 (旧 ADR-038 → ADR-041) で番号 conflict が顕在化、queue 滞留 entry の hardcode が後発 PR の採番と衝突する構造リスクを convention で予防、`~/.claude/rules/common/docs-governance.md` に 2-3 行追記。採番予約簿は管理コスト過剰のため見送り、land 時 PR で空き番号確定の軽量運用に統一) | -| 136 | 🚀 Tier 1 | **working copy staleness 検出 hook 2 段構え: SessionStart (jj git fetch + lineage 報告) + PreToolUse (stale 時 docs/todo*.md edit block) — 本セッション cleanup-stale-rank-39 由来** | todo8.md | M | なし (本セッションで実証された「stale parent で docs/todo*.md 読込 → 既削除 entry を再度削除提案」failure mode の structural enforcement。Claude Code Web 並列セッション運用前提下で再発確実。`feedback_no_unenforced_rules.md` 例外 = 2 つの hook で機械強制可能、案 A 予防層 + 案 B 最終 backstop の二段構え、ADR-039 experimental pattern 適用) | -| 139 | 💎 Tier 3 | **ADR-041: Test Isolation Patterns for Multi-Condition Guards (PR #168 T3-#2 採用) — 本 PR で land** | todo8.md | M | なし (PR #120 W-001 初発見 + PR #168 sentinel pattern 実装の 2 PR 横断で Frequency Medium、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + project-specific 実装例 (poll.rs) + PR #120 W-001 history codify、順位 84 = code-review.md global checklist の補完 layer、順位 135 codified placeholder 番号 policy 適用 — 当初 ADR-NNN placeholder で entry 登録 → land 時 PR で ADR-041 確定取得、順位 78 を ADR-NNN に再 placeholder 化) | +| 136 | 🚀 Tier 1 | **working copy staleness 検出 hook 2 段構え + stale todo entry 既実装 grep 提示 (PR cleanup-stale-rank-39 由来 + PR #150 T3-#1 統合 2026-05-25)** | todo8.md | M-L | なし (本セッション実証 failure mode の structural enforcement + 旧 順位 122 機能統合。案 A SessionStart で jj fetch + lineage 報告、案 B PreToolUse で docs/todo*.md edit 時の stale block + 既実装 grep 自動実行で関連 commit を warning 提示、rule 追加 (= 順位 122 当初案) を仕組み化に切替で session 跨ぎ品質一定化、ADR-039 experimental pattern 適用) | | 140 | 💎 Tier 3 | **順位 135「codified placeholder policy」を正式 ADR に昇格 (PR #169 T3-#2 採用)** | todo8.md | S | なし (順位 135 entry を retire し、ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy として永続化。PR #111/#132/#169 の 3+ PR で適用実証済 — PR #169 で「ADR-038 → 041 → NNN」3 段振り直し dogfood が land、ephemeral todo entry 限りでは派生プロジェクトへの transferability 不足、`feedback_no_unenforced_rules.md` 例外 = 既存実践 (3 PR で実証) の明文化 + 後続 entry が同 policy を参照する際の永続 reference 確保) | -| 141 | 🚀 Tier 1 | **CR rate-limit detection bug 修正 — fix_push_time 固定 + 早期 merge 判断 signal (PR #169 観測由来)** | todo8.md | S | なし (PR #169 セッションで systemic 観測 = wakeup ごとの push_time 更新で CR walkthrough overlay の updated_at が「過去扱い」になり parse_rate_limit の event_time >= push_time filter で除外される構造バグ、`feedback_pipeline_over_rules` 適用 = パイプライン側機械的修正で Claude 判断介入を排除、wall clock 短縮 = rate-limit 検出時に mergeable CLEAN なら 5-10 分で人間判断 (38 分 reset 待ちを bypass)、既存 auto-retry path は維持 (ユーザーが「待つ」選択時は通常 flow)、Bundle a Sub-PR 2 / Bundle f scope 外の独立 layer) | | 142 | 💎 Tier 3 | **ADR-041 補強 — "State Preservation Invariant" pattern section 追加 (PR #170 T3-#1 採用) ★ Bundle 171** | todo8.md | S | なし (PR #168/169/170 で連続観測の write-once 不変式 (once-set-never-overwritten) パターンを ADR-041 に追記、`state.fix_push_time.or_else(...)` 形式の 3 点セット test pattern (既存値あり / 新値提供 / preservation 確認) を明文化、参照実装 = poll.rs `finalize_*_preserves_existing_fix_push_time` + monitor.rs `resume_returns_fix_push_time_from_state_when_set`、ADR-041 既存 section (Multi-Condition Guards) とは別 pattern class、`feedback_no_unenforced_rules.md` 例外 = 既存実践 (3 PR で実証) の明文化 + 派生プロジェクト transferability 確保) | | 143 | 🔧 Tier 2 | **複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171** | todo8.md | S | なし (PR #151/#171 の 2 PR 横断で multi-byte fixture 手動組み立てコストが Frequency Medium で観測、Japanese / emoji / combining chars helper 3 関数を標準化して新規 string-processing 関数追加時の boundary test コスト削減 + silent regression early detection、順位 142 + 144 と同 PR で land 推奨) | +| 145 | 🔧 Tier 2 | **preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用)** | todo8.md | M | なし (PR #172 Phase 3 で `jj-message-required` が opt-in preset であることを前提とせず test を書き rewrite が必要になった経緯、preset architecture の implicit assumption (always-enabled vs config-selectable) を classification 表として test レベルで codify、新 preset 追加時に matrix 更新を強制する mechanical enforcement で design misalignment を構造的検出、target は main.rs (feedback report の lib.rs 記載は誤り)) | +| 146 | 🚀 Tier 1 | **Secret detection PreToolUse hook 追加 — AWS/OpenAI/GitHub token 等の hardcoded secret 検出 (PR #172 仕組み化方針切替由来、`security.md` § Secret Management 移管) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`~/.claude/rules/common/security.md` § Secret Management 記述のみで機械強制なし、AWS Access Key / OpenAI sk- / GitHub ghp_/gho_/ghs_ / Anthropic sk-ant- 等 6+ 種 pattern を `preset_secret_detection` で regex 検出 + 即 block、順位 144 hook 化 template 踏襲、security-critical かつ漏洩観測前の preventive 層として Tier 1、rule docs § Secret Management を hook block message に集約で縮小) | +| 147 | 🔧 Tier 2 | **File length lint (800 行 max) 追加 — `coding-style.md` § File Organization 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`~/.claude/rules/common/coding-style.md` § File Organization の 800 行 max を `hooks-post-tool-comment-lint-rust` に追加、順位 48 関数長と同 touch-trigger ratchet pattern で grandfather 適用、Rust 限定 MVP、順位 57 truncate contract 整合、rule docs から具体閾値削除で縮小) | +| 148 | 🔧 Tier 2 | **Test coverage 80% CI gate 追加 — `testing.md` § Minimum Test Coverage 80% 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S-M | なし (`~/.claude/rules/common/testing.md` § 80% coverage ガイドラインを実行時 gate に変換、`cargo llvm-cov --fail-under-lines 80` を push-runner-config.toml [quality_gate] に integration 推奨、現状未測定のため段階導入計画必要、rule docs § 80% coverage を実行時 gate 参照に縮小) | +| 149 | 🔧 Tier 2 | **Long-running subprocess pipe truncate hook 拡張 — `development-workflow.md` § subprocess pipe truncate 禁止 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (既存 `exe-help-block` preset を `cli-*.exe ... \| (head\|tail\|awk)` 等の副作用ある subprocess 出力 truncate にも拡張 or 新 `subprocess-pipe-truncate-block` preset 追加、PR #109 SIGPIPE 事故 root cause の構造化、順位 44 (gh-token-efficiency) との scope 境界整理必要、development-workflow.md § 該当 section 縮小) | +| 150 | 🔧 Tier 2 | **Magic number lint 追加 — `coding-style.md` § Magic Numbers 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = source folder 限定) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`.claude/custom-lint-rules.toml` に `no-magic-number` rule 追加、source folder paths filter で test/config 除外、時間定数 / リトライ回数 / threshold の 3 category MVP、severity warning で reviewer 判断補助、順位 102 paths filter + 順位 118 適用範囲検討と整合、coding-style.md § Magic Numbers 削除可否は dogfood 後判断) | +| 151 | 🔧 Tier 2 | **PR diff lines check 追加 — `git-workflow.md` § Multi-PR chaining 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = 条件付き block 3 段階) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`src/cli-push-runner/src/stages/pr_size_check.rs` 新 stage 追加、`push-runner-config.toml` `[pr_size_check]` section で threshold 設定可能化 (default: block 1500 / warning 800)、jj diff stat 計測、大型 refactoring 時の override は config 編集、git-workflow.md § Multi-PR chaining 縮小) | **戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 -**Bundle 1 完了 + post-merge-feedback 反映 (2026-04-29)**: PR #91 (Bundle 1: PowerShell + Markdown anchor lint rules) merge 後の post-merge-feedback で **4 件の新規 task を追加** (PowerShell `(?i)` 自動検証 / `.claude/` filter + ADR-030 制約 / cli-pr-monitor 通知 Recovery 経路 / takt REJECT-ESCALATE)。**前 2 件は本 PR で実証された「fix iteration の根因」に対する決定論的防止策で最優先候補**。**日付ベース見出しアンカーのグローバル明文化 task は決定論的防止 (no-mutable-anchor rule) との二重防衛として継続有効**。 - -**reviewer facet 改善 (Bundle T で land 済)** + **post-pr-review fix loop の `.claude/` filter (Bundle T で land 済)** + **cli-pr-monitor ポーリング延長 + 重複起動ロック (Phase 3 で land 済)** + **rate-limit 自動検出 + 再トリガー (Phase 4 で land 済)** が完了し、reviewer 精度向上 + convergence cost 削減 + ポーリング頻度削減 + rate-limit 自動 recovery の四段構えが成立。残る Tier 2 では takt REJECT-ESCALATE が最優先候補。 -**rate-limit 抑制の 3 層**: (1) Polling anti-pattern 検出 (PR #86 T1-1、完了済) = Claude 側の polling 禁止 (preventive)、(2) cli-pr-monitor ポーリング延長 + 重複起動ロック (PR #88 T2-4 / #96、完了済) = tool 側のポーリング頻度削減 (corrective)、(3) post-pr-review rate-limit 自動検出 + 再トリガー (Phase 4 / 完了済) = review 単位の自動 recovery。 -**cli-pr-monitor 通知 Recovery 経路 (SessionStart hook 拡張) は PR #91 の直接観測知見**。SessionStart hook で再起動跨ぎの通知ロスト防止。post-pr-review fix loop の `.claude/` filter (path-based 解決) は Bundle T で land 済。 -**Stop hook の `pnpm lint:md` 統合 task は Markdown linter hook 統合 (PR #88 で merged) の gap closure**。**AI 生成一時スクリプト pattern 検出は push 前 untracked `__*` hook (PR #85 T1-4) と関連** (実装前に擦り合わせ要)。 -**`.failed` marker 自己文書化 task は ADR-030 soft-fail 機構の運用負荷削減** (PR #89 セッションで recovery が機能した実証から派生、Effort S)。 -**takt REJECT-ESCALATE は post-pr-review fix loop の `.claude/` filter (Bundle T で land 済) の verdict-based 一般解**。path-based 解決が完了したので、本 task 着手で補完関係を完成させる。 -**T3 グローバルルール 4 件 (日付ベース見出しアンカー / jj conflict リカバリ / `__` prefix scratch / post-pr-monitor polling 禁止) は `~/.claude/` 配下への XS 追記なので並列実施推奨**。 -**Bundle U / V / e は完了** (Bundle U の 順位 29 = PR #110、順位 30 = Bundle e、Bundle V の 順位 31/32 = PR #109、順位 33 = Bundle e で全消化)。**Bundle e (convention 明文化 long-tail、2026-05-05)**: 順位 23/24/25/26 (PR #85/#86 由来) + 順位 30 (Bundle U 残) + 順位 33 (Bundle V 残) + 順位 70 (Bundle d 残) を 1 PR で集約 land、`~/.claude/rules/common/{coding-style,git-workflow,development-workflow,code-review}.md` + `~/.claude/CLAUDE.md` の global rules に convention 7 項目を codify。XS×7 で long-tail 一掃。 -**Bundle W (PBT + 型強化) は PR #96 で実証された flaky 実装防御の最上層**。Finding D (`saturating_sub` の silent semantic mismatch) と E (concurrency test の guard 即 drop) はどちらも「Rust 的に正しいコードがドメイン的に間違う」典型例で、advisor + takt-fix の 2 layer も貫通した。**仕様を proptest properties で明文化 + `PastTime` 等の型で invalid state を unrepresentable に** することで、ルール (ask-based) では塞げない bug class を構造的に排除する。**rate-limit 自動検出 (Phase 4 で land 済) / takt REJECT-ESCALATE を先行**し、その後 Bundle W に着手する流れがユーザー指示。 -**Bundle X (cargo-mutants + stress runner) は Bundle W の後付け検証層**。L2 post-PR で変更 crate + 1-hop 依存に cargo-mutants を走らせ test の弱さを直接測定、L1 pre-push で concurrency stress N=100 を回し scheduling race を sampling。Bundle W で書いた spec / 型を後段で機械的に検証する補完関係。**L3 weekly cargo-mutants workspace 全体 + stress N=1000 は ADR-031 Phase B 週次レビューと bundle 化** することで long-tail flake と coverage 全体監査を week 単位で audit する layer に統合。 -**PR #98 (Bundle Y2) post-merge-feedback 反映 (2026-05-01)**: 3 件の follow-up task を追加。**takt workflow `model` フィールド必須化 lint rule** と **Bundle Y2 効果の定量計測** は Bundle Y2 完全性確保 + ROI 検証で同系列 (lint rule 着手時に post-pr-review.yaml supervise step への `model: sonnet` 明示追加を同 PR に含める想定)。**prepare-pr skill Step 1 bookmark 存在チェック強化** は本セッション運用痛 (bookmark 未作成 push 失敗) から派生した独立 task で skill repository 側の更新となる。 -**Bundle a (PR #99 post-merge-feedback 反映、2026-05-02 拡張)**: 4 component を **2 Sub-PR で分割** land 推奨 (設計根拠は ADR-034)。共通テーマは「PR #99 で複数回発生した手動 `@coderabbitai review` 投稿の自動化」 + 「CR review query の token bloat 削減」。Bundle Y2 効果でパイプラインが加速した結果として CR rate-limit 発生頻度が増えた逆説的副作用への対策。effort 合計 M+S+XS+M (= 2 Sub-PR で M、M+S 程度に分散)。 - -- **Sub-PR 1 (token 削減層、先行)**: **gh CLI 使用規則** (`git-workflow.md` 追記) + **`check-ci-coderabbit --list-findings`** (Rust モード、cli-pr-monitor 連携 API 提供)。旧 Bundle Z2 の `#D-1` + `#D-3` を本 Bundle に統合 (旧 `#D-2` は `#D-3` で代替のため取り下げ、旧 `#D-4` は思考連続性懸念で保留、ADR-034 参照) -- **Sub-PR 2 (rate-limit 自動化層、主軸)**: **cli-pr-monitor の rate-limit auto-retry** (Sub-PR 1 の `--list-findings` API を消費) + **ADR-018 / ADR-009 の rate-limit retry ポリシー明文化** + **integration test 追加** (rate-limit 検出 → backoff → retry サイクルの regression 防止、PR #100 post-merge-feedback T2-1 採用) + **`parse_findings` 系 error-path test infra** (順位 49、PR #101 T2-1、`unwrap_or_else(\|_\| empty)` silent fallback の test 検証)。session 超え recovery / walkthrough overlay 検出 / 解除 + 1 分マージン投稿の設計詳細は ADR-034 - -**PR #101 (Bundle a Sub-PR 1) post-merge-feedback 反映 (2026-05-03)**: 9 件の finding を頻度評価 (過去 report 横断 + 同一 PR latent 件数) して **3 件を採用**。**順位 47 (`>` vs `>=` boundary lint)** は同一ファイル内 3 関数 (parse_listed_findings / parse_new_comments / parse_findings) で同 drift が実証済 = latent 高頻度。**順位 48 (関数長 oxlint)** は #96 / #101 で繰り返し言及 = explicit 高頻度。両者とも Bundle Z #B-α と同じ「決定論的防止層」哲学で、Bundle Z Phase 1 (Rust comment lint) の land 後に並列 deploy 可能。**順位 49 (error-path test infra)** は #99 / #101 で同型 silent fallback anti-pattern が再発、Bundle a Sub-PR 2 (順位 42 / 43 / 46) と **同一 PR で land** 推奨 (cli-pr-monitor の mock infrastructure を再利用、test 二重投資なし)。残り 6 件 (Tier 1 #1, #3, #5、Tier 2 #2、Tier 3 #1, #2) は session 1 回限りの low-frequency events として不採用。 - -**Bundle h (PR #123 post-merge-feedback、experimental feature 標準パターン + ephemeral lifecycle 強化、2026-05-07)** ✅ 完了: 順位 89 (Experimental feature 標準パターン = ADR-039 として codify) + 順位 90 (ephemeral 大規模 content の ADR 昇格基準 + config コメント lifecycle anti-pattern を `~/.claude/rules/common/{docs-governance,coding-style}.md` に追加) で land。**却下** (4 件): T1 #3 (`enabled = true` 検出 lint、誤検出確実) / T1 #4 (見出し参照誤り検出 hook、NLP 必要) / T2 #2 (env var override、ROI 不成立) / T3 #4 (ADR-039 config hardcode policy、ADR-038 でカバー済)。**様子見** (4 件): T1 #1 (ephemeral 計画書参照 lint、命名規則 codify 先行) / T1 #2 (jq 括弧不均衡 lint、再発頻度低) / T2 #1 (classifier endpoint fallback integration test、takt test infra 調査依存) / T3 #3 (config コメント ADR 参照修正、XS opportunistic)。 - -**Bundle g (PR #121 post-merge-feedback、monitor verdict logic + session pattern codify、2026-05-07)** ✅ 完了: 4 件採用 (Tier 1 #85、Tier 2 #86、Tier 3 #87/#88) を 2 PR で land。**g-1 (順位 85 + 86、Rust 実装 + verdict transition matrix tests) は PR #125 で land 済** (`compute_verdict` の review_state == "not_found" / "pending" guard + 12 verdict transition tests in `src/cli-pr-monitor/src/stages/monitor.rs`)。**g-2 (順位 87 + 88、global rule 追記)** は Bundle h と同 PR (#139) で land 済。Bundle f との関係: Bundle f は retry logic (rate-limit + 投稿エラー)、Bundle g は verdict logic (review_state 評価) で別軸、両者 land で post-pr-monitor の robustness が retry/verdict/state 全方向で堅牢化された状態。 - -**Bundle f (PR #120 post-merge-feedback、cli-pr-monitor robustness、2026-05-07)**: PR #120 (ADR-038 Phase 5: cli-finding-classifier 統合) の dogfood で post-pr-monitor の wakeup state 遷移に複数の edge case を観測。**5 件採用** (Tier 1 #80/#81、Tier 3 #82、Tier 2 #83、Tier 3 #84) で **3 層対策**: (1) 実装層 = 順位 80 / 81 (rate-limit + CR 投稿エラーの auto-retry path 整理) + 順位 82 (ADR-018 設計明文化、同 PR 推奨)、(2) test 層 = 順位 83 (複合 guard の独立 variant test)、(3) ガイド層 = 順位 84 (code-review.md checklist 追記、独立並列可)。**Sub-PR 分割推奨**: f-1 (順位 80 + 81 + 82、cli-pr-monitor + ADR、Effort M+M+S、Bundle f コア) / **f-2 (順位 83、test 拡充) + f-3 (順位 84、global rule) は 2026-05-21 land 済 (Bundle B)**。Bundle f はローカル LLM dogfood (ADR-038 採用、2026-05-15) の副産物として cli-pr-monitor の堅牢化を進める位置づけ。 - -**Bundle c (PR #109 post-merge-feedback 堅牢化、2026-05-04)**: PR #109 で post-merge-feedback workflow が SIGPIPE で silent 中断され `.failed` marker 未生成という ADR-030 仕様違反が実証された。5 件採用 (Tier 1 #63/#64/#65 + Tier 3 #66/#67) で **3 層防御** を構築: (1) 事前防止 = 順位 65 (exe + `--help` を PreToolUse block) + 順位 66 (グローバルルールの subprocess pipe truncate 禁止)、(2) in-process recovery = 順位 63 (Drop guard / signal trap で abrupt 終了時の `.failed` marker 保証)、(3) out-of-process backstop = 順位 64 (`meta.json status=running` 5-15 分放置 reaper)。順位 67 (ADR-030 spec 拡張) は実装と同 PR で仕様/実装の整合性確保。**Sub-PR 分割推奨**: c-1 (順位 63 + 64 + 67、Rust 実装 + ADR、Effort M+M+XS、コア層) / c-2 (順位 65 + 66、hook + global rule、Effort S+XS、trigger 防止層)。c-1 と c-2 は独立に land 可能だが c-1 land 後の dogfood で recovery 機構を実証してから c-2 を入れると順位の合理性が見える順序になる。 - -**Bundle d (PR #110 post-merge-feedback、2026-05-04)**: PR #110 (Bundle "docs quality pre-write") merge 後の post-merge-feedback で 6 findings 中 3 件採用。共通テーマは「PR #110 で導入した `no-ephemeral-todo-reference` rule (順位 29 採用分) の robustness 強化 + 設計 doc / 実装の乖離 ガード」。**順位 68 (T2 self-exclusion test)** は **本 PR (Phase d P-3 繰上げ) で land 済** = `hooks-post-tool-linter` の 6 件 unit test (TP / FP / Edge / 大文字無視 / 拡張子限定 / deployed TOML self-exclusion invariant)。**順位 69 (T3 yaml/yml コメント)** は OBS-2 (spec-impl 乖離) 対策で別 PR で対応予定。順位 70 (code-review checklist) は Bundle e で land 済。 - -**Bundle f + retirement (PR #111 post-merge-feedback + 計画書 retire、2026-05-05)** ✅ 完了: PR #111 (Bundle e) merge 後の post-merge-feedback で 10 findings 中 4 件採用 (順位 71/72/73/74 = Tier 3 XS×4) + 順位 62 (Document Governance) + `docs/docs-pr-iteration-efficiency.md` retirement を **1 PR で集約 land**。Sub-PR 分割推奨ルール (順位 73 自身が codify する内容) を本 PR で **dogfood**: 順位 73 が land する PR 自身が「分割 vs 統合」判断対象 → ファイル削除 + 順位 62 + Bundle f を統合した結果、scope は 5 ファイル touch (global rules 2 + ADR 2 + 削除 1) + cleanup で clean、Bundle 分割で得られる review 容易性より統合 PR の atomic な lifecycle 完結性が勝った。共通テーマ: 「PR #111 自己違反事例 → self-application 強化」 + 「Document Governance を global rule に codify」 + 「計画書 retirement を実例化」の 3 layer 同時 land。 - -**PR #113 (Bb-1 = Bundle b PR-1) post-merge-feedback (2026-05-05)**: 9 findings に対して **1 件のみ採用** (順位 75 = T2-2 の `finalize_parked` write_state 失敗時 fail-safe 回帰テスト)。T1 #1/#2 (lint rule 案) は NLP 必要 / FP リスクで却下、T2-1 (Windows path test) / T2-3 (state cycle integration) / T2-4 (CronCreate format lint) は ROI 不見合いで不採用、**T3-1 / T3-2 (`~/.claude/rules/common/coding-style.md` への ルール追記)** は **ユーザー判断で却下** — 「強制力のないルール追加は却下: 機械検知できなければ何もしない方がマシ。ルール乱立は重要ルール埋没の害悪」(memory: feedback_no_unenforced_rules.md として codify 済)、T3-3 (PARK signal 設計 ADR) は premature で 🤔 様子見保留。**本 PR 含意**: Bb-1 の sibling parity invariant (`finalize_*` 群の error path 対称性) は Bb-2 / Bb-3 で同種関数を追加する際に再発確度が高いため、**test レベルで machine-enforceable に保護** することを Bb-2 着手前の前提条件とする。 - -**PR #114 (Bb-2 + 順位 75 = Bundle b PR-2 + T2-2) post-merge-feedback (2026-05-05)** ✅ 完了: 9 findings に対して **2 件採用 / 5 件様子見 / 3 件却下**。**Bb-3 (順位 55) で fold-in する採用提案**: T2-2 (Parity test coverage 拡張 = `finalize_park_siblings_have_symmetric_write_state_handling` テストに `finalize_initial_review_park` を追加、self-violation 解消、Effort S)。T2-1 (Legacy JSON deserialize test) は **PR #114 で既に実装済** (`state_legacy_json_without_new_fields_deserializes_with_defaults`、Bb-3 以降の新フィールド追加時に同 pattern を継続するための reference として保存)。**様子見 (5 件)**: T1-1 (finalize_* parity lint、Effort M + NLP 必要、簡易プロキシで再評価) / T1-2 (polling block lint、FP リスクで dogfood 後判断) / T2-3 (env override コメント強化、XS Low) / T2-4 (CI parallel race 確認、preventive only) / T3-1 (Wakeup Resume Invariant ADR) / T3-2 (DI 戦略 ADR、Bb-3 着手時に再検討)。**却下 (3 件)**: T1-3 (Serde schema lint、ROI 低、T2-1 で代替) / T3-3 (parity invariant の global rules 追加) / T3-4 (test-only env var prefix rule) — 後 2 件は **memory: feedback_no_unenforced_rules.md** を直接引用してアナライザが正しく即却下判定。Bb-2 land 時点で Bundle b の核 (CronCreate park モデル) 完成、残る Bb-3 は config 整理 + SessionStart catch-up + T2-2 follow-up を bundled。 - -**Bundle j (PR #133 post-merge-feedback、docs/ 整合性多層検証、2026-05-09)**: PR #133 (todo.md / todo5.md 50KB 分割) merge 後の post-merge-feedback で 9 findings 中 **3 件採用** (Tier 1 #1 / Tier 2 #3, #4) で **3 層対策**: (1) **規約層** = 順位 94 (`(?i)\]\(\.\./docs/` regex 1 行で `docs/` 配下からの逆戻り参照を block) は CodeRabbit が PR #133 で実検出した broken link を決定論的に防止、(2) **CI 検証層** = 順位 95 (preamble file count 自動照合) は todo*.md 分割が今後反復する pattern (todo3 → 4 → 5 → 6 → 7) のため Frequency Medium で採用、(3) **包括的 link 検証層** = 順位 96 (Markdown cross-reference validator、directory-aware resolution) は順位 10 (ADR-032 PR-broken-link) と方向性近接で fold-in 検討余地あり。**Sub-PR 構成**: **j-1 (順位 94、`.claude/custom-lint-rules.toml` 規約追加) は land 済 (Phase d P-2)** / j-2 (順位 95 + 96、`.github/workflows/lint.yml` 新設 = workflows 未存在 repo の最初の workflow 整備、Effort S+M、まとめて land が効率的)。**却下** (2 件): T1 #2 (prose 数詞 lint、NLP 必要 + FP 確実) / T3 #5/#6 (機械検知不可ルール追加、`feedback_no_unenforced_rules.md` 適用)。**様子見** (3 件): T3 #7 (ADR-035 not_applicable と GitHub thread state の乖離明文化、1 観測のみ) / T3 #8 (ADR-030 AFK wakeup 時 PR body intent ルール化、1 観測のみ) / T3 #9 (50KB 分割原則 CLAUDE.md 明文化、機械検知不可)。**本 PR 含意**: 順位 94 = 「決定論的防止層」哲学 (Bundle Z #B-α 系譜)、順位 95-96 = 「規約だけでは塞げない構造的検証は CI で」(ADR-031 週次レビューと相補)。`.github/workflows/` 未存在 repo に最初の workflow を追加する転換点でもあり、scope 慎重判断が必要。 - -**Bundle k (PR #151 post-merge-feedback、Phase D dogfood 観測由来の lint-screen FP 対策、2026-05-13)**: PR #151 (Phase D D-5 = comment-lint test 拡充 + MAX cap test) merge 後の post-merge-feedback で 11 findings 中 **5 件採用** (Tier 1 #1, #2 / Tier 2 #1 / Tier 3 #1, #2) を 5 entries (順位 123-127) で登録。**コア発見**: D-3 (PR #148) / D-4 CR fix (PR #150) / D-5 ×2 (PR #151) の 3 PR・4 push events で「mistral:7b が docs-only diff や `.md` ファイルに対して Rust の `unused-import` を hallucinate する」FP pattern が一貫して観測 = Phase b' fixture では再現しない failure mode。**順位 123 (lint-screen MD 除外フィルター、Tier 1 / M / High freq)** が最重要 = 拡張子ベース mechanical filter で構造的に解消可能、Phase D dogfood 観測から導かれた最も価値ある決定論的防止策。**Sub-PR 推奨**: k-1 (順位 123 + 126、実装 + ADR-038 codify、Effort M+XS、コア層) / k-2 (順位 124 + 127、TOML test + extensions code comment、Effort S+XS、test gap 補強層) / k-3 (順位 125、UTF-8 boundary 横展開、Effort M、独立) で 3 PR 分割推奨。**却下** (4 件): UTF-8 lint rule (FP リスク、AST 必須) / `byte_offset_to_line` 強化 (PR #151 で既対応) / UTF-8 guideline + extensions checklist (`feedback_no_unenforced_rules.md` 適用)。**様子見** (3 件): T2 #2 (lint-screen dogfood CI step、L effort + takt test infra 調査依存) / T3 #3 (test 拡充→bug 発見 pattern を ADR-007 記録、1 PR 観測のみ) / T3 #4 (multi-rule scenario fixture pattern を test comment 明文化、Low × Low)。**本 PR 含意**: Phase D dogfood 観測 (analysis.md L334-340) が直接 actionable な決定論的防止層 (順位 123) に結実、Phase E 採否判定前に systemic FP root cause が解消される構造的進展。 - -**Bundle k 補強 (PR #152 post-merge-feedback、D-6 docs-only PR、2026-05-13)**: PR #152 (Phase D D-6 = fix.md instruction-level review-diff refresh + Bundle k 順位 123-127 entry 登録) merge 後の post-merge-feedback で 8 findings 中 4 件採用 (Tier 1 #1 / Tier 2 #1 / Tier 3 #1, #2)。**全 4 件が Bundle k 既存エントリ (順位 123/124/126/127) と完全重複** = post-merge-feedback analyzer 自身が「Bundle k 優先度 X で既に roadmap 済」と明記。新規順位を追加せず、**既存 4 entries (順位 123/124/126/127) に PR #152 を追加観測として追記** (frequency 観測: 3 PR → **4 PR** に更新、Bundle k の優先度 / Sub-PR 分割推奨は不変)。**注**: 順位 126 (ADR-038 hallucinate codify) は Phase E 採用昇格 PR で ADR-038 へフォルドイン land 済 (2026-05-15)、現 table には不在。**含意**: PR #152 (docs-only) でも `.md` への `unused-import` FP が同根 root cause で再現したことが「lint_screen FP は diff 内容ではなく hook source 周辺 context を見て hallucinate している」仮説を 4th observation として裏付け = 順位 123 拡張子フィルター実装の confidence 向上。**様子見** (2 件): PostToolUse hook 自動化 (案 D、Frequency Low) / fix.md 自己参照 ambiguity (1 PR 観測のみ、次回 fix.md 編集機会に opportunistic 適用)。**却下** (2 件): 機械検知不可な `~/.claude/rules/*` 追加 (memory `feedback_no_unenforced_rules.md` 適用)。 - -**Bundle k 補強 (PR #153 post-merge-feedback、analysis.md 軽量化 PR、2026-05-13)**: PR #153 (D-6 post-merge follow-up + analysis.md 49KB→26KB split) merge 後の post-merge-feedback で 6 findings 中 **2 件採用** (Tier 3 #1, #2)。**T3 #1 = 順位 126 (ADR-038 hallucinate codify、Phase E でフォルドイン land 済) と完全重複** → 順位 126 entry を「**5 PR 連続観測** (#148/#150/#151/#152/#153)」+ root cause / structural fix の明示記載要件追加で更新 → 最終的に Phase E 採用昇格 PR (2026-05-15) で ADR-038 § Known failure modes に migrate。**T3 #2 = 新規採用** → **順位 128 (CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist 追加)** として登録、PR #133 (todo.md 分割) + PR #153 (analysis.md 分割) の successful pattern を明文化。**様子見** (2 件): CLAUDE.md → docs-governance.md cross-link / docs-only PR template の Retired sections list (どちらも Frequency Low)。**却下** (2 件): cross-reference lifecycle 自動 lint rule (NLP 必要) / file role scope exceptions guidance (1 観測のみ、過剰一般化リスク)。**含意**: docs-only PR でも mistral:7b の FP が 5 観測目として再現、Bundle k 順位 126 の優先度を High freq として確定。多ファイル分割の retirement workflow を順位 128 で global rule 化することで、今後の docs/* 50KB 分割 (history.md 等) で同 pattern を mechanical に reproducible 化。 - -**PR #168 post-merge-feedback (Bundle B follow-up、2026-05-21)**: PR #168 (Bundle B = 順位 83 cli-pr-monitor 複合 AND guard test 単独検証 + 順位 84 code-review.md checklist 追記) merge 後の post-merge-feedback で 6 findings 中 **1 件採用** (Tier 3 #2) を 順位 139 として登録。**順位 139 = ADR-041: Test Isolation Patterns for Multi-Condition Guards** — PR #120 W-001 初発見 + PR #168 sentinel pattern 実装の **2 PR 横断で Frequency Medium** に達したため、code-review.md global checklist (順位 84 land 済) に加えて project-level ADR で rationale・実装例 (poll.rs `enrich_with_classifier_skips_when_disabled` / `_skips_when_findings_empty`)・PR #120 W-001 history を codify する方針が成立。番号は順位 135 codified placeholder policy に従い当初 `ADR-NNN` で entry 登録 → **本 PR (順位 139 land) で `ADR-041` 確定取得**、順位 78 (旧 ADR-041 予約) を再 placeholder 化。**様子見** (1 件): T2 #1 (guard isolation test 用 precondition assert helper macro 抽出、複合 guard test 再登場時に再評価)。**却下** (4 件): T1 #1 (NLP 必要 + L effort lint rule) / T1 #2 (Bundle Z #B-α safe-list exception、Frequency Low + 代替策で十分) / T2 #2 (CI coverage section、Very Low freq + ROI 不見合い) / T3 #1 (`~/.claude/rules/rust.md` rule 追加、`feedback_no_unenforced_rules.md` 適用)。**recovery 含意**: 本 PR の post-merge-feedback は cli-merge-pipeline 経由で起動した workflow が PC crash で abrupt 終了し、ADR-030 §L1 の pre-emptive `.failed` marker (`168.md.failed`) が UserPromptSubmit hook (`hooks-user-prompt-feedback-recovery`) によって次セッションで検出 → `pnpm exec takt -w post-merge-feedback` 直接再起動で aggregation 完了 → manual cleanup (report copy + marker 削除) で復旧。**gap 観測**: 復旧手順 (`168.md.failed` の文書) は takt 再起動コマンドのみ codify されており、`.takt/runs//reports/feedback-report.md` → `.claude/feedback-reports/.md` への copy + marker 削除という artifact relocation step が未文書化。次回類似復旧時の摩擦軽減 follow-up 候補。 +**Bundle 履歴**: 完了済 Bundle / post-merge-feedback 反映の経緯詳細は [docs/bundle-history.md](bundle-history.md) を参照 (2026-05-25 分離、本ファイルの index 責務集中のため)。 diff --git a/docs/todo4.md b/docs/todo4.md index fede2bf8..941f253b 100644 --- a/docs/todo4.md +++ b/docs/todo4.md @@ -437,42 +437,58 @@ --- -### gh CLI 使用規則を `~/.claude/rules/common/git-workflow.md` に追記 (計画書 #D-1) +### PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25) -> **動機**: PR #97 / #99 セッションで観測された gh tool_result の token bloat (POST 応答 24KB / GET 過剰 metadata 44KB) を rule で構造的に抑制する。具体的には (1) POST 操作の応答破棄漏れ (`gh api .../replies` で `> /dev/null 2>&1` 漏れによる 24KB context 汚染)、(2) GET 操作で `--jq` filter 不使用による生 JSON 全取得、(3) `gh pr view --json comments` の CR walkthrough base64 internal state 混入 — の 3 パターン。 +> **動機**: PR #97 / #99 セッションで観測された gh tool_result の token bloat (POST 応答 24KB / GET 過剰 metadata 44KB) を、当初 rule 追加 (`~/.claude/rules/common/git-workflow.md`) で抑制する計画だった。しかし PR #172 で 順位 144 (`jj-message-required` preset) の dogfood が成功し、「rule 化は session 毎に読み込みコストがかかり、別セッションでも結果が一定にならない」課題が顕在化。仕組み化 (PreToolUse hook) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。 > -> **本タスクの位置づけ**: Bundle a の **Sub-PR 1 token 削減層**。`check-ci-coderabbit --list-findings` Rust 実装 と同 PR で land 推奨。global rule (`~/.claude/rules/common/git-workflow.md`) への追記のため本リポジトリ scope 外だが、開発体験への影響は本リポジトリで主に発生。 +> 抑制対象 3 パターン (rule 設計時点で確定済): > -> **参照**: ADR-034 (CodeRabbit 監視・対話の自動化戦略)、(削除済) `docs/pipeline-token-efficiency.md` #D-1 セクション (経緯は ADR-034 で保存)、PR #99 セッションで実証された rate-limit overlay (memory `project_coderabbit_rate_limit_overlay.md`) +> 1. **POST 操作 (作成・更新)** の応答破棄漏れ: `gh api .../replies` 等で `> /dev/null 2>&1` がない → 24KB の reply body が context 汚染 +> 2. **GET 操作 (取得)** で `--jq` filter 不使用: `gh api .../comments` 等で生 JSON 全取得 → 44KB の不要 metadata 流入 +> 3. **CR walkthrough internal state 混入**: `gh pr view --json comments` で CR walkthrough の base64 encoded state が含まれる (1 PR で 30KB+) → 確認時は `--jq 'del(.comments[].body)'` 等で除外必須 > -> **実行優先度**: 💎 **Tier 3** — Effort XS。rule 追記のみ。Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) でも `gh api` を使うため Sub-PR 1 で先行 land 推奨。 +> **本タスクの位置づけ**: 順位 144 (jj-message-required hook) の同型実装パターン。`feedback_pipeline_over_rules.md` 適用 = パイプライン側機械的修正で Claude 判断介入を排除、session 毎の rule load コスト不要、別セッションでも結果が一定。Bundle a の **Sub-PR 1 token 削減層** だが docs 化 → hook 化への切替に伴い Bundle a との結合は緩む。 +> +> **参照**: ADR-034 (CodeRabbit 監視・対話の自動化戦略)、PR #99 / #97 session log (token bloat 実観測)、PR #172 (順位 144 = `jj-message-required` preset 実装事例)、`src/hooks-pre-tool-validate/src/main.rs` の `preset_jj_message_required` を template に追加 +> +> **実行優先度**: 💎 **Tier 3** — Effort M (順位 144 と同型実装で工数把握済、~90 分見込み)。Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) でも `gh api` を使うため Sub-PR 1 で先行 land 推奨。 -#### 設計決定 (案) +#### 設計決定 (案、順位 144 hook 実装を template に踏襲) -- **追記先**: `~/.claude/rules/common/git-workflow.md` の既存セクションに追加 (新規ファイル作成は避け、navigation 性確保) -- **記述する 3 規則**: - - **POST 操作 (作成・更新)**: 応答 body は破棄する (`gh api -X POST .../replies -f body='...' > /dev/null 2>&1`)。success/fail は exit code で判別 - - **GET 操作 (取得)**: `--jq` で必要 field のみ抽出する (`gh api .../comments --jq '.[] | {created_at, body_first: .body[:200]}'` 等) - - **CR walkthrough 除外**: `gh pr view --json reviews,comments` の `comments` field に CR walkthrough の base64 internal state が含まれる (1 PR で 30KB+) ため、確認時は `--jq 'del(.comments[].body)'` 等で除外 -- **記述スタイル**: BAD / GOOD のコード例ペアを併記 (既存 git-workflow.md の他セクションと整合) +- **配置**: `src/hooks-pre-tool-validate/src/main.rs` に新 preset `gh-token-efficiency` 追加 +- **`BlockedPattern.exception` を活用** (順位 144 で導入済、再利用) +- **block 対象 3 種類** (個別 BlockedPattern として実装): + - (1) **POST 応答破棄漏れ**: pattern = `gh\s+(api\s+-X\s+POST|api\s+(?!.*-X\s+GET)[^|]*-f\s+)`、exception = `>\s*/dev/null|>\s*NUL`、message = 「`> /dev/null 2>&1` で応答 body 破棄を推奨 (24KB context 汚染防止)」 + - (2) **`gh api` の `--jq` 不使用**: pattern = `gh\s+api\s+[^|]*`、exception = `--jq\b|\|\s*jq\b|>\s*/dev/null`、message = 「`--jq` で必要 field のみ抽出を推奨 (生 JSON 過剰流入防止)」 + - (3) **CR walkthrough state 混入**: pattern = `gh\s+pr\s+view\s+[^|]*--json\s+[^|]*comments`、exception = `del\(\.comments|--jq.*comments.*\|\s*map`、message = 「CR walkthrough base64 internal state を含むため `--jq 'del(.comments[].body)'` 等で除外を推奨」 +- **hooks-config.toml**: `blocked_patterns` に `"gh-token-efficiency"` を追加 (opt-in preset、派生プロジェクト breaking change リスク軽減) +- **opt-in 設計**: `default_preset_names()` の fallback には含めない (`gh-pr-create-guard` 等と同じ classification) -#### 作業計画 +#### 作業計画 (順位 144 と同 phase 構造) -- [ ] `~/.claude/rules/common/git-workflow.md` の既存構造を確認し追記位置を選定 -- [ ] 3 規則 (POST 応答破棄 / GET --jq / CR walkthrough 除外) を BAD/GOOD コード例つきで追記 -- [ ] 本リポジトリでの dogfood: 1〜2 PR で実際に新規則に従って `gh api` を使い、token 削減を実測 -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への global rule 反映確認 (rule は global なので自動的に適用、deploy 不要) -- [ ] 本 todo4.md エントリを削除 +- [ ] **Phase 1**: 既存 preset 構造を理解し、`preset_gh_token_efficiency()` 関数を実装 (3 BlockedPattern を vec で返す) +- [ ] **Phase 2**: `build_blocked_patterns` の `resolve_preset_or_custom` dispatch に登録 + `.claude/hooks-config.toml` の `blocked_patterns` に `"gh-token-efficiency"` 追加 + コメント section に説明追加 +- [ ] **Phase 3**: test 拡充 — block ケース (応答破棄漏れ POST / `--jq` なし GET / walkthrough exclusion なし) × 3 + allow ケース (3 規則すべて遵守) × 3 + non-regression (既存 preset との干渉なし) +- [ ] **Phase 4**: `pnpm build:hooks-pre-tool-validate` で exe deploy + dogfood (本 todo を読んだ後の `gh api` 呼び出しで block 動作確認) +- [ ] **Phase 5**: `pnpm push` (AI review) + `pnpm create-pr` +- [ ] **post-merge**: 本リポジトリ 1-2 PR の dogfood で false positive 観測 → 派生プロジェクト deploy 判断 +- [ ] 本 todo4.md エントリ削除 + todo-summary.md 行削除 #### 完了基準 -- `~/.claude/rules/common/git-workflow.md` に 3 規則が追記される -- dogfood 1〜2 PR で gh tool_result avg/max chars が削減されることを実測 (現状 max 47KB → 目標 10KB 以内) -- POST 応答 24KB の context 汚染が消失 +- `jj-message-required` と同型の `gh-token-efficiency` preset が稼働 (3 BlockedPattern が block + exception 機能で正規パターン allow) +- `gh api .../replies -f body='...'` (応答破棄なし) → block + 修正手順 feedback +- `gh api .../comments` (`--jq` なし) → block + 修正手順 feedback +- `gh pr view 171 --json comments` (walkthrough 除外なし) → block + 修正手順 feedback +- 規則遵守版 (`> /dev/null 2>&1` 付き POST / `--jq` 抽出 / `del(.comments[].body)` 除外) は通過 +- 既存 preset との non-regression (jj-main-guard / git push block 等は継続動作) +- `cargo test -p hooks-pre-tool-validate` pass #### 詰まっている箇所 -- なし (Effort XS、global rule への追記のみで完結)。Sub-PR 1 の `check-ci-coderabbit --list-findings` 実装と同 PR で land する想定。 +- 順位 144 実装パターンを踏襲することで設計判断は最小化される +- false positive リスク: `gh api ... | jq` のような piped jq は exception regex で吸収可能 (`\|\s*jq\b` を含める) +- 派生プロジェクト deploy timing: 本リポジトリ先行 dogfood (1-2 PR) → 観測後判断 (`feedback_dogfood_evals_two_phase.md` 適用) --- diff --git a/docs/todo7.md b/docs/todo7.md index ed1fc21f..7eb7d58e 100644 --- a/docs/todo7.md +++ b/docs/todo7.md @@ -218,48 +218,63 @@ --- -### post-PR 検証フローに CR review.body 手動スキャン step 追加 (PR #108 T2-1 採用) +### `check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25) > **動機**: PR #108 で CodeRabbit が `Outside diff range comment` として review body 内に投稿した Minor finding (`docs/todo4.md` line 371/378 の retire 済前提と旧フロー混在) を、takt の `analyze-coderabbit` step が検出漏れした。`analyze-coderabbit` は `pulls/N/comments` (= inline review comment) ベースで動作するため、review.body 内のコメントは parse 対象外。結果、PR #108 で line 371/378 の修正が merge 後 follow-up commit (`vokyspww`) になった。 > -> **本タスクの位置づけ**: PR #108 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None / ✅ 採用)。`analyze-coderabbit` の根本解決 (review.body 解析対応) は別 task として実装複雑度が高いため、暫定緩和策として **手動 checklist** で対応する。Tier 1 の analyzer 拡張 (= 将来の根本解決) の先行策として機能する。 +> 当初計画では暫定緩和策として **手動 checklist** (post-PR フローに目視確認 step) を追加する rule 化方針だったが、PR #172 で「rule 化は session 毎に読み込みコストがかかり、人間が忘れる」課題が顕在化。仕組み化 (`check-ci-coderabbit` 拡張で programmatic 検出) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。当初 Tier 1 として位置づけていた analyzer 拡張を本 task で先行実施する形。 > -> **参照**: `.claude/feedback-reports/108.md` Tier 2 #1、PR #108 review (`Outside diff range comments` セクション、reviewer comment id 4217897113)、`.takt/facets/instructions/analyze-coderabbit.md` +> **本タスクの位置づけ**: PR #108 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。手動 checklist の根本解決 = 検出漏れを programmatic に消滅させる。手動 step が持続性低い (= 人間が忘れる) ため、CLI 拡張で session 跨いだ品質一定化が確保される。 > -> **実行優先度**: 🔧 **Tier 2** — Effort XS。post-PR checklist documentation の更新のみ。 +> **参照**: `.claude/feedback-reports/108.md` Tier 2 #1、PR #108 review (`Outside diff range comments` セクション、reviewer comment id 4217897113)、`src/check-ci-coderabbit/src/main.rs` (`parse_findings` 系 + `--list-findings` mode = 順位 45)、`.takt/facets/instructions/analyze-coderabbit.md`、PR #172 (順位 144 hook 化の dogfood 成功事例) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。`check-ci-coderabbit` 既存 crate への parse 機能追加 + analyze-coderabbit 連携。 #### 設計決定 (案) -- **配置先候補**: - - `docs/workflow.md` (新規 or 既存): post-PR checklist として統一記述 - - `~/.claude/rules/common/git-workflow.md`: 既存 PR workflow ルールに追記 - - 着手時に既存 docs 配置を grep して整合する場所を選定 -- **追加する checklist 項目** (案): - - `pnpm create-pr` 完了後 / takt post-pr-review 完了後に、CodeRabbit の review (= `Outside diff range comments` 含む全 review body) を手動で目視確認する - - `gh api repos/{owner}/{repo}/pulls/{N}/reviews --jq '.[].body'` で review body を抽出して読む - - 確認対象: `Outside diff range comments` セクション、`Caution` / `Warning` セクション、行番号参照のある comment 全般 -- **検出時の対応**: 該当 finding を inline thread と同じく severity 評価 → 修正 commit を追加 → 手動で acknowledge reply -- **将来対応**: takt analyze-coderabbit に review body parse を追加 (= Tier 1 task として別 entry が必要、本 task の dogfood で頻度が高ければ昇格) +- **対象 source**: `gh api repos/{owner}/{repo}/pulls/{N}/reviews --jq '.[].body'` で取得する review.body markdown 文字列 +- **parse 対象セクション** (CR の出力フォーマットに準拠): + - `## Outside diff range comments` セクション内の bullet list (file:line 参照 + comment body) + - `## Caution` / `## Warning` セクション内の bullet (severity-marked findings) + - 行番号参照のある generic comment (regex: `\b(file|line)\s*[:=]\s*\d+|`L\d+`|`:`) +- **JSON schema 拡張**: 既存 `--list-findings` mode (順位 45) の出力に `source: "inline" | "review_body"` field を追加して同型 findings として扱う: + + ```json + { + "findings": [ + {"severity": "minor", "file": "docs/todo4.md", "line": 371, "summary": "...", "source": "review_body"} + ] + } + ``` + +- **analyze-coderabbit 連携**: 既存 `analyze-coderabbit` step が `--list-findings` 出力を取得する形になっていれば、source field を追加するだけで本 task の出力が自動的に下流に流れる +- **検出時の挙動**: inline findings と同じく severity 評価 → fix commit 追加 → resolve reply の通常 flow に乗る (本 task で flow 自体は変更しない) #### 作業計画 -- [ ] `docs/workflow.md` または `~/.claude/rules/common/git-workflow.md` の現状を確認、追記場所を選定 -- [ ] post-PR checklist 項目を追記 (gh api コマンド + 確認対象 + 検出時対応の 3 項目) -- [ ] dogfood: 次の数 PR で本 checklist を実行、blind spot 検出頻度を観測 -- [ ] 観測結果に応じて Tier 1 へ昇格判断 (= analyzer 拡張) -- [ ] 派生プロジェクト deploy 不要 (本リポジトリ workflow 固有) -- [ ] 本 todo7.md エントリを削除 +- [ ] `check-ci-coderabbit` 現状確認 (`--list-findings` mode が 順位 45 として実装済か、未実装なら本 task 着手前に 順位 45 を land) +- [ ] review.body 取得 API (`gh api .../pulls/{N}/reviews`) wrapper 実装 (既存の gh CLI wrapper が `src/check-ci-coderabbit/src/` にあれば再利用) +- [ ] markdown parser: `## Outside diff range comments` / `## Caution` / `## Warning` セクション抽出 + bullet 毎の file:line + body 抽出 +- [ ] JSON schema 拡張: `source` field 追加 (既存 schema は inline 想定なので default 値 `"inline"` で後方互換) +- [ ] test 拡充: 実 PR #108 の review.body を fixture 化 + parse 結果が期待 finding を返す test +- [ ] `analyze-coderabbit` 連携検証: source 別の handling が必要か (`outside-diff-range` の重み付けは inline と同等で進める想定) +- [ ] dogfood: 次 1-2 PR の post-pr-review で review.body finding が自動検出されることを観測 +- [ ] 派生プロジェクト deploy 検討 (`check-ci-coderabbit.exe` は本リポジトリ exe なので deploy で配布、scope 内) +- [ ] 本 todo7.md エントリ削除 + todo-summary.md 行削除 #### 完了基準 -- post-PR workflow に「CR review.body 手動スキャン」step が追記される -- 次 1-2 PR の dogfood で本 checklist の実行が観察される -- review body 内の actionable finding が後追い修正にならない (= merge 前に検出される) +- `check-ci-coderabbit --list-findings --pr 108` が PR #108 の outside-diff-range finding (line 371/378) を構造化 JSON で返す +- `source` field で inline vs review_body の区別が可能 +- `analyze-coderabbit` 連携で merge 前に outside-diff-range finding が actionable として扱われる +- 既存 inline finding 検出に regression なし +- `cargo test -p check-ci-coderabbit` pass #### 詰まっている箇所 -- 配置先選定 (本リポジトリ docs/workflow.md vs グローバル `~/.claude/rules/`)。本タスクは本リポジトリ固有の暫定緩和策のため、本リポジトリ docs/ への追記が妥当か -- 手動 checklist は持続性が低い (人間が忘れる) ため、Tier 1 への昇格 (= analyzer 拡張) の優先度判断が dogfood 結果に依存 +- 順位 45 (`check-ci-coderabbit --list-findings` Rust モード) の land 状況確認が前提。未 land なら本 task 着手前に 順位 45 を先に進める +- CR 側 review.body フォーマットの変更耐性: section header (`## Outside diff range comments`) が CR の出力変更で変わる可能性がある。fail-soft 設計 (parse 失敗時は空 findings で続行 + warn log) で運用継続性を確保 +- false positive リスク: 行番号らしき文字列 (`L42` 等) が誤検出される可能性。CR 公式フォーマット section に限定した parse でリスク軽減 --- diff --git a/docs/todo8.md b/docs/todo8.md index efd9a66f..55a8c43e 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -2,7 +2,7 @@ > **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #143 T3-#1 採用時 = 2026-05-11)。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md / todo7.md の既存エントリは引き続き有効、相互に独立。新セッションでは九つすべてを確認すること (todo.md / todo2-8.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #143 T3-#1 採用時 = 2026-05-11 から新規エントリは本ファイルに記録していた。**本ファイルも 60KB に到達したため、PR #172 仕組み化方針切替セッション = 2026-05-25 以降の新規エントリは [docs/todo9.md](todo9.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md / todo7.md / todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十つすべてを確認すること (todo.md / todo2-9.md / todo-summary.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 @@ -10,31 +10,6 @@ ## 現在進行中 -### `development-workflow.md` Step 0 に「新 todo 着手前の既実装確認」チェックステップ追加 (PR #150 T3-#1 採用、補足: ユーザー判断採用) - -> **動機**: PR #150 着手時に「順位 47 は PR #126 で既 land 済」という stale todo entry を memory rule `feedback_verify_task_not_already_done.md` 適用で発見・回避できた。memory にとどまる限り read 漏れリスクが残るため、canonical workflow doc (`~/.claude/rules/common/development-workflow.md`) Step 0 (Research & Reuse) に「新 todo 着手前に `jj log --limit 20 ` で既実装確認」step を正式追加すれば、AI エージェントの workflow 読込時の visibility が向上する。 -> -> **本タスクの位置づけ**: PR #150 post-merge-feedback Tier 3 #1 採用。rule 追加は本来 `feedback_no_unenforced_rules.md` 適用で却下 zone だが、本 case は「stale entry 発見の具体的 grep コマンドが workflow 内で機械的に実行可能 (`jj log` は決定的)」+「memory rule の昇格 path 実例」としてユーザー判断で採用。Severity Medium / Frequency Medium (memory 既存 + 本 PR で再発) / Effort XS / Adoption Risk None。 -> -> **参照**: `.claude/feedback-reports/150.md` Tier 3 #1、`~/.claude/rules/common/development-workflow.md` Step 0 (Research & Reuse)、memory `feedback_verify_task_not_already_done.md` - -#### 作業計画 - -- [ ] `~/.claude/rules/common/development-workflow.md` Step 0 (Research & Reuse) 末尾または直後に「Stale task verification」サブステップ追加: - - `jj log --limit 20 ` で既実装の有無を確認 - - 既 land を発見した場合は stale todo entry を docs/todo*.md / todo-summary.md から削除する形に re-purpose -- [ ] 既存 memory `feedback_verify_task_not_already_done.md` の content を canonical rule へ昇格させた旨を memory に追記 (or memory を削除して rule に統合) -- [ ] グローバル設定変更前に `~/.claude/` バックアップ取得 (memory `feedback_global_config_backup.md` 適用) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `development-workflow.md` Step 0 で「stale entry 確認」が canonical workflow として読まれる -- memory ファイルとの責任分離が明確 (rule = 公式手順、memory = session-specific 補足) または memory が rule に統合される -- 次回 todo 着手時に AI エージェントが自然に `jj log` 確認を行う - ---- - ### ADR-040 `step_timeout` 説明に sublinear / KV cache locality clarification 追記 (PR #145 T3-#1 採用) > **動機**: ADR-040 L42-48 の `step_timeout` 説明は「sublinear (3.33x)」と記述したが、本文中に「per-invoke latency が num_ctx に対して概ね線形に拡大する経験則」も併記しており、両者の関係が不明瞭。派生プロジェクトが reference table から 32K = 600s を読む際、なぜ formula `(num_ctx/8192)*180` で導出される 720s と乖離するかが直感的に分からない。clarification として「実測値 600s を正規値として採択、computed 720s は保守上限の目安、sublinear 性の根拠は KV cache locality 効果 (大規模 context で per-token efficiency 向上)」の 2-3 行追記が必要。 @@ -113,29 +88,6 @@ --- -### UTF-8 マルチバイト boundary test を他の string-processing hooks に横展開 (PR #151 T2-#1 採用) - -> **動機**: PR #151 で `byte_offset_to_line` の char-boundary panic bug を test 拡充 (UTF-8 漢字単独 needle) で発見した。同型関数 (byte offset から行番号変換 / needle 検索 + slice 操作) は他の string-processing hooks にも存在する可能性が高く、横展開 test で systemic 防御を確保すべき。 -> -> **本タスクの位置づけ**: PR #151 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None)。test 拡充は単なるカバレッジ追加ではなく fault detection に直結することが実証済 (本 PR で副産物として 1 production bug 修正)。 -> -> **参照**: `.claude/feedback-reports/151.md` Tier 2 #1、`src/hooks-post-tool-comment-lint-rust/src/main.rs:byte_offset_to_line` (PR #151 で修正済)、対象は `src/hooks-*` で string offset 操作を行う関数 - -#### 作業計画 - -- [ ] `grep -rn "as_bytes\|byte\|offset" src/hooks-*/src/` で類似処理を持つ hooks を列挙 -- [ ] 各 hook で multi-byte boundary に晒される operation を識別 (byte slice / needle search / offset → line 変換 等) -- [ ] 対象 hook 毎に test fixture 追加: 漢字単独 / emoji / 結合文字 / BMP 外文字 のうち最低 1 パターン -- [ ] 検出された production bug は 1 行 fix で resolve (PR #151 と同じ pattern) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 全 string-processing hook が multi-byte boundary の panic に対して test で防御されている -- 横展開 test 実施過程で発見された production bug が修正される - ---- - ### CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用) > **動機**: PR #153 で旧 `docs/local-llm-offload-analysis.md` を `phase-d-outcomes.md` に分割した際 (3 ファイルは Phase E 採用昇格 = 2026-05-15 に retire 済)、retirement clause を **3 ファイル (analysis.md / history.md / phase-d-outcomes.md) 同時削除** に統一する作業が developer/AI の手動 review でしか担保されていなかった。advisor 指摘で明示的に「3 ファイルすべてに同じ retirement clause を書く」ステップを踏んだが、これは structural pattern として再利用可能 (今後の docs/* 50KB 分割でも同じ checklist が必要)。同パターンが drift すると ephemeral artifact の lifecycle 整合が崩れ、stale pointer が増殖するリスクあり。 @@ -273,15 +225,17 @@ --- -### working copy staleness 検出 hook 2 段構え: SessionStart + PreToolUse (本セッション cleanup-stale-rank-39 由来) +### working copy staleness 検出 hook 2 段構え + stale todo entry 既実装 grep 提示 (PR cleanup-stale-rank-39 由来 + PR #150 T3-#1 統合 2026-05-25) > **動機**: 本セッション (PR cleanup-stale-rank-39 作業中) で「local working copy が stale parent (master と sibling) のまま docs/todo*.md を読み込み、master 上で既に削除済の entry 2 件 (順位 104 / 126) を『stale entry として削除する』と誤判定」failure mode を実証した (実 stale entry は 1 件のみだった)。memory rule `feedback_verify_task_not_already_done.md` (todo 着手前に既実装検証 → stale entry 削除に再目的化) は強制力ゼロで再発確実 = memory rule 全般の限界 (`feedback_no_unenforced_rules.md` 原則の自己事例)。Claude Code Web との並列セッション運用前提下では構造的に同 mode が発生する。 > -> **本タスクの位置づけ**: 本セッション post-merge-feedback 相当の structural defense。`feedback_no_unenforced_rules.md` 例外条件 = **2 つの hook で機械強制可能**。案 A (予防層 = session 起動時に状況認識) + 案 B (最終 backstop = stale 状態での編集を hard block) のセット二段構え。 +> **統合履歴 (2026-05-25)**: 旧 順位 122 (`development-workflow.md` Step 0 に「新 todo 着手前の既実装確認 `jj log --limit 20 `」step 追加 = PR #150 T3-#1 採用) を本 task に統合。rule 化 (= docs 追加) では session 毎に読み込みコストがかかり別セッションで結果が一定にならない課題が PR #172 (順位 144 hook 化成功事例) で明確化、仕組み化に方針切替。stale 検出 hook が `docs/todo*.md` edit 時に発火する際、合わせて既実装の有無を grep して結果を提示する形で 順位 122 の機能を吸収する (`feedback_pipeline_over_rules.md` 適用)。 > -> **参照**: 本セッション (2026-05-18) PR cleanup-stale-rank-39 root cause 分析 (ユーザー対話)、memory `feedback_verify_task_not_already_done.md`、ADR-039 (Experimental feature 標準パターン) +> **本タスクの位置づけ**: 本セッション post-merge-feedback 相当の structural defense + 旧 順位 122 機能統合。`feedback_no_unenforced_rules.md` 例外条件 = **2 つの hook で機械強制可能**。案 A (予防層 = session 起動時に状況認識) + 案 B (最終 backstop = stale 状態での編集を hard block + 既実装 grep 提示) のセット二段構え。 > -> **実行優先度**: 🚀 **Tier 1** — Effort Medium (案 A ~80 行 + 案 B ~30 行)。本セッションの実観測 failure mode に対する直接対策で、並列セッション運用が常態化している現状で再発確率が高い。 +> **参照**: 本セッション (2026-05-18) PR cleanup-stale-rank-39 root cause 分析 (ユーザー対話)、PR #150 post-merge-feedback Tier 3 #1 (旧 順位 122 由来)、memory `feedback_verify_task_not_already_done.md`、ADR-039 (Experimental feature 標準パターン)、PR #172 (順位 144 hook 化 dogfood 事例) +> +> **実行優先度**: 🚀 **Tier 1** — Effort Medium-Large (案 A ~80 行 + 案 B ~50 行 = 既実装 grep 拡張で +~20 行)。本セッションの実観測 failure mode に対する直接対策で、並列セッション運用が常態化している現状で再発確率が高い。 #### 設計決定 (案 A + B) @@ -302,18 +256,22 @@ - 最適化: `.git/FETCH_HEAD` mtime を確認して「5 分以内なら fetch skip」 (network cost 抑制) - fail-open: fetch timeout / 失敗時は warning なしで pass-through (block しない、AI 操作は継続可能) -**案 B: PreToolUse hook で stale 時の `docs/todo*.md` edit を block** +**案 B: PreToolUse hook で stale 時の `docs/todo*.md` edit を block + 既実装 grep 提示 (旧 順位 122 統合)** -- 配置: 既存 `src/hooks-pre-tool-validate/` に統合 (~30 行追加) -- 動作: Edit / Write の対象が `docs/todo*.md` 系列のとき、master と @- の lineage 確認 → master が ahead なら hard block -- block message: +- 配置: 既存 `src/hooks-pre-tool-validate/` に統合 (~50 行追加 = 30 行 stale 検知 + ~20 行既実装 grep 拡張) +- 動作 1 (stale 検知): Edit / Write の対象が `docs/todo*.md` 系列のとき、master と @- の lineage 確認 → master が ahead なら hard block +- 動作 2 (既実装 grep 提示、旧 順位 122 機能統合): stale でない場合も `docs/todo*.md` への Edit/Write 時に対象 entry の keyword (= 直近の `### ` 見出し title から抽出) を `jj log --limit 20` で grep し、既実装らしき commit があれば warning として additional context に表示 +- block / warning message: ```text - ❌ working copy parent (#X) is N commits behind master (#Y). - docs/todo*.md は state を反映する artifact のため、master と同期した状態で編集すること。 - 修正手順: `jj git fetch && jj new master` + [docs/todo edit context] + @: lmzvnwlu (parent: #159, master: #161 = 2 ahead) + stale parent detected → block + 関連既実装の可能性: " の上位 3 件> + 修正手順: `jj git fetch && jj new master -m "WIP: "` ``` -- scope 限定: `docs/todo*.md` のみ block (コード / config までは過剰、false positive リスク) +- scope 限定: `docs/todo*.md` のみ block / grep 対象 (コード / config までは過剰、false positive リスク) - 案 A と異なり、本 hook は fail-closed (lineage 判定不能なら block) で安全側に倒す +- 既実装 grep の keyword 抽出ロジック: `### ` で始まる見出しから「順位 N」prefix を除いた title を取得、句読点 / 括弧を除外して 2-3 語の noun phrase を抽出 (NLP 不要、簡易 regex で実装可能) #### 作業計画 @@ -322,15 +280,19 @@ - [ ] `master..@-` の lineage 計算ロジック実装 (`jj log -r "master..@-" --no-graph -T 'description'` 等) - [ ] additional context 出力フォーマット決定 (一行 vs 複数行、AI 読み飛ばし耐性検証) - [ ] `hooks-pre-tool-validate.exe` に `docs/todo*.md` edit block ロジック追加 +- [ ] **既実装 grep ロジック実装 (旧 順位 122 統合)**: Edit/Write の old_string or new_string から `### ` 見出し title を抽出 → keyword 抽出 (順位 prefix / 句読点除去) → `jj log --limit 20` 実行 → 上位 3 件を additional context に追記 +- [ ] `~/.claude/rules/common/development-workflow.md` Step 0 (Research & Reuse) の手動 grep step 追加は **不要** (hook が自動実行するため rule 化スキップ、`feedback_pipeline_over_rules.md` 適用) +- [ ] memory rule `feedback_verify_task_not_already_done.md` の closure 検討 (hook 化で機能吸収後、memory entry を削除して責任を hook に集約) - [ ] ADR 起案 (新 hook 設計 + ADR-039 experimental pattern 適用、land 時採番確定) - [ ] dogfood 期間設定 (試験運用 flag で N 週間運用後採否決定) - [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) deploy 検討 -- [ ] 本エントリ削除 + todo-summary.md 行削除 +- [ ] 本エントリ削除 + todo-summary.md 行削除 (順位 122 行は本 entry 統合時に削除済 2026-05-25) #### 完了基準 - session 開始時に working copy が master より遅れている場合、AI が context 出力で即座に状況を認識する -- stale parent 状態で `docs/todo*.md` を編集しようとすると hard block + 修正手順 (`jj git fetch && jj new master`) 表示 +- stale parent 状態で `docs/todo*.md` を編集しようとすると hard block + 修正手順 (`jj git fetch && jj new master -m "WIP: "`) 表示 +- **`docs/todo*.md` への Edit/Write 時に既実装 grep が自動実行され、関連 commit が warning として提示される (旧 順位 122 機能、hook 化で session 跨ぎ品質一定化)** - ADR-039 experimental pattern に従い kill-switch 装備 (network 異常 / feature branch 運用への退避経路) - 派生プロジェクトでの動作確認 @@ -341,44 +303,6 @@ --- -### ADR-041: Test Isolation Patterns for Multi-Condition Guards (PR #168 T3-#2 採用) — 本 PR で land - -> **動機**: PR #120 W-001 で `enrich_with_classifier_skips_when_disabled` テストが OR-guard `if !config.enabled || state.findings.is_empty() { return; }` の責務混在 (vacuous assertion: 空 `classified_findings` → 空 `classified_findings` で早期 return 由来か他経路由来か判別不能) で書かれていた問題、および PR #168 で sentinel pattern + 直交 precondition setup により構造的解決した実装を、project-level ADR として永続化する。`~/.claude/rules/common/code-review.md` (global rule、順位 84 で追加済) の checklist entry を補完する形で、project ADR には rationale・具体実装例 (poll.rs)・PR #120 W-001 history を codify し、将来の複合 guard テスト実装者が独立して参照できるようにする。 -> -> **本タスクの位置づけ**: PR #168 post-merge-feedback Tier 3 #2 採用。`feedback_no_unenforced_rules.md` の例外 = 既存実践 (PR #168 で実装済) の明文化 + project-specific context の補完。Severity Low / **Frequency Medium (PR #120 W-001 初発見 + PR #168 sentinel pattern 実装の 2 PR 横断)** / Effort M / Adoption Risk None。 -> -> **参照**: `.claude/feedback-reports/168.md` Tier 3 #2、`src/cli-pr-monitor/src/stages/poll.rs` (`enrich_with_classifier_skips_when_disabled` / `enrich_with_classifier_skips_when_findings_empty`)、`~/.claude/rules/common/code-review.md` (順位 84 land 済 checklist entry)、PR #120 W-001 / PR #168 history -> -> **実行優先度**: 💎 **Tier 3** — Effort M。新規 ADR 1 件作成 (記述のみ、コード変更なし)。 - -#### ADR 番号 (本 PR で確定) - -順位 135 codified policy (`~/.claude/rules/common/docs-governance.md`) に従い、本 entry は当初 `ADR-NNN (採番未確定)` placeholder で登録した。**本 PR で `ADR-041` を本件に確定取得**し、順位 78 (旧 ADR-041 予約 = Rust timestamp arithmetic safety) を `ADR-NNN` に再 placeholder 化した (順位 78 は今後 land 時 PR で空き番号を取得する運用)。本 entry は本 PR land 後に post-merge-feedback サイクルで削除される予定 (memory: feedback_todo_no_history)。 - -#### 作業計画 (本 PR で完了) - -- [x] `docs/adr/adr-041-test-isolation-patterns.md` を新規作成 -- [x] 内容構成: - - **問題**: PR #120 W-001 の vacuous assertion (検証対象 field が空のまま → 早期 return 由来か他経路由来か判別不能) で OR-guard test の責務混在が顕在化した経緯 - - **設計原則**: sentinel pattern (検証対象 field を pre-populate → survival assert で mutation 不発を明示) + OR-guard precondition assertion (短絡発火条件を test 内で明示し直交性を保証) - - **実装例**: `enrich_with_classifier_skips_when_disabled` (左 arm = `!enabled` 単独) / `enrich_with_classifier_skips_when_findings_empty` (右 arm = `findings.is_empty()` 単独) の 2 variant 抜粋コード - - **適用範囲**: 2+ 条件の OR/AND 早期 return を持つ pure function 系 test (副作用検証は別パターン、本 ADR の scope 外) - - **既存資料との関係**: `~/.claude/rules/common/code-review.md` checklist entry (順位 84 land 済) を project-level rationale + 具体実装例で補完する layer -- [x] `CLAUDE.md` の ADR リストに 1 行追加 -- [x] PR description で `docs/adr/adr-041-test-isolation-patterns.md` への link と「sentinel pattern + OR-guard test orthogonality を project codify」要約を明記 (PR #169 description に反映済 = "Summary" / "Background" / "Files changed" 3 箇所で言及) - -#### 完了基準 (本 PR で達成) - -- ADR-041 ファイルが新規作成され、PR #120 W-001 history + sentinel pattern + 2 variant 実装例が記述される ✅ -- CLAUDE.md の ADR リストに ADR-041 entry が追加される ✅ -- 次回複合 guard test を含む PR を書く際の reference として poll.rs の doc comment などから ADR-041 へリンク可能になる ✅ - -#### 詰まっている箇所 - -なし。記述のみで実装変更不要。 - ---- - ### ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment (PR #169 T3-#2 採用) > **動機**: 順位 135 で codify された「ADR 番号は entry 登録時に hardcode せず `ADR-NNN (採番未確定)` placeholder で記述し、land 時 PR で空き番号を確定する」運用が、PR #111 / PR #132 / PR #169 の **3+ PR で適用実証済**になった。特に PR #169 では同一 entry (順位 78) が `ADR-038 → 041 → NNN` の **3 段振り直し** を経た live dogfood が完了し、queue 滞留 entry と後発 PR の採番衝突を convention 層で完全予防できる状態が確立された。現在 policy は `~/.claude/rules/common/docs-governance.md` の 2-3 行追記として ephemeral todo (順位 135) 内で codify されているが、ephemeral artifact 限りでは派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への transferability に欠ける。正式 ADR に昇格して永続化する。 @@ -426,98 +350,6 @@ --- -### CR rate-limit detection bug 修正 — fix_push_time 固定 + 早期 merge 判断 signal (PR #169 観測由来) - -> **動機**: PR #169 セッション (2026-05-22) で `cli-pr-monitor` の CR rate-limit 検出機構が、再 push 後の wakeup recheck 経路で **構造的に動作不能** な状態が systemic 観測された。`check-ci-coderabbit` の `parse_rate_limit` は `event_time >= push_time` filter で「過去 session の古い rate-limit comment」を除外する safety guard を持つが、`push_time` が `state.started_at` (wakeup ごとに現在時刻に更新される値) を再利用するため、CR の walkthrough overlay の `updated_at` が push_time より過去になると検出対象から外れる。今回 PR #169 で CR が overlay (`2026-05-22T06:08:02Z`) を投稿したが、wakeup 4 回目の started_at = `06:27:14Z` で filter 除外 → `rate_limit: null` → auto-retry path に乗らず手動介入で merge へ進んだ。 -> -> **本タスクの位置づけ**: `feedback_pipeline_over_rules.md` 適用 = 「動作の不確実さはパイプラインで吸収、ルール codify では対処しない」原則の実装事例。「Claude が gh CLI で手動確認すればよい」式の運用ルール codify は次セッションで AI が守らない可能性が構造的に残るため不採用 (本 PR セッションでユーザー明示却下)。代わりにパイプライン側 (Rust 実装) で機械的に検出を堅牢化し、Claude 判断介入を排除する。CR 仕様変更時は graceful degradation (検出失敗 = pipeline が静かに止まるだけ、誤判定はしない) で受容、発生時に再考。 -> -> **wall clock 配慮 (shortcut 追加案、ユーザー要件で原案から縮小)**: rate-limit 検出後に「reset まで 38 分自然待ち + CR 2 回目 review 待ち」の通常 flow に直行すると、最悪 `max_retries=3` で 2.5 時間消費する可能性がある (1 日がかりではないが許容外)。本タスクでは **rate-limit 検出時に同 process 内で mergeable status を併せて確認し、即 merge 可能なら 5-10 分の人間判断で済む shortcut signal を出力** する。既存 auto-retry path は維持 = ユーザーが「reset を待つ」を選んだ場合は通常 flow に合流する。これにより手間軽減 + wall clock 短縮の両立を図る。 -> -> **参照**: PR #169 session log (本 entry 由来)、`src/check-ci-coderabbit/src/main.rs` L416 `parse_rate_limit` (push_time filter)、`src/cli-pr-monitor/src/stages/monitor.rs` L202-211 + L220-230 (`detect_wakeup_resume` / push_time 算出経路)、`src/cli-pr-monitor/src/state.rs` (`PrMonitorState` schema)、memory: `feedback_pipeline_over_rules.md` / `project_coderabbit_rate_limit_overlay.md` / `feedback_coderabbit_no_actionable_merge_signal.md`、Bundle a Sub-PR 2 (順位 42/43/46) / Bundle f (順位 80-82) は別 layer (retry path / 投稿エラー対応) で本タスク scope 外 -> -> **実行優先度**: 🚀 **Tier 1** — Effort S。PR #169 で systemic 観測 + ユーザー判断で priority elevated。原案 (defense-in-depth + 4 test) から縮小し、主軸 C + shortcut signal の 2 機能に絞った最小実装。 - -#### 設計方針 - -「**検出は機械化、判断は人間に短期で渡す**」 = pipeline で検出までは確実に動かし、reset 待ちの長時間 wall clock を許容するか即 merge 判断に進むかは **人間 (= ユーザー) が 5-10 分以内に決める**。Claude 判断介入は介在させない (signal を読んでユーザーに AskUserQuestion で問うのみ、AI 独断で merge / wait を決めない)。 - -CR 仕様変更時は graceful degradation: 検出が壊れたら shortcut signal も出ない → 従来通り手動 workflow に倒れるだけで誤判定はしない。 - -#### 設計決定 (案) - -**主軸 C: state.json に fix push 時刻を別 field で保存** - -- `PrMonitorState` schema に **`fix_push_time: Option`** field を追加 (Option = legacy state 互換、None なら fallback to started_at) -- `monitor.rs` の fresh 起動経路 (`detect_wakeup_resume` が None) で `fix_push_time = Some(utc_now_iso8601())` を設定 -- wakeup resume 経路では state の `fix_push_time` を **そのまま再利用** (wakeup ごとに上書きしない) -- `poll.rs` の state 書き込み箇所で `fix_push_time` を保持 -- `check-ci-coderabbit` への引数 `--push-time` には **`fix_push_time`** を渡す -- 効果: 「fix push 直後の overlay は `updated_at` >= `fix_push_time` で確実に検出」、「過去 session の古い rate-limit comment は依然 filter で除外」 の両立 - -**早期 merge 判断 signal (本タスクの核)** - -- `poll.rs` の `handle_rate_limit_branch` で `state.rate_limit = Some(_)` を検出した時点で、**同 process 内で 1 回だけ** mergeable status を `gh pr view --json mergeable,mergeStateStatus` 経由で取得 -- 以下の **全 condition** を満たす場合、`PARK signal` の代わりに **`[RATE_LIMIT_BUT_MERGEABLE]` signal** を stdout に出力: - - `mergeable == "MERGEABLE"` - - `mergeStateStatus == "CLEAN"` - - `state.coderabbit.unresolved_threads == Some(0)` または `None` (初回 review の actionable が resolve 済 or 検出なし) -- signal 例: - ```text - [RATE_LIMIT_BUT_MERGEABLE] - pr: 169 - repo: aloekun/claude-code-hook-test - rate_limit_reset_at_iso_utc: 2026-05-22T06:46:32Z - rate_limit_wait_seconds: 2310 - mergeable: MERGEABLE - merge_state: CLEAN - unresolved_threads: 0 - - ACTION REQUIRED: ユーザーに以下 2 択を AskUserQuestion で問うこと: - A: 今すぐ merge する (rate-limit reset を待たない、CR 2 回目 review なしで進める) - B: reset (38 分) を待って通常 auto-retry flow に乗る - [/RATE_LIMIT_BUT_MERGEABLE] - ``` -- 条件不一致 (mergeable: BLOCKED、unresolved 1+ 件 等) の場合は **従来通り通常 PARK signal を出す** (= 既存 auto-retry path がそのまま動く) -- Claude 側の対応: signal を検出したら **AskUserQuestion で A/B 選択を問う**、回答に応じて merge 実行 / wakeup 予約継続 - -#### 作業計画 - -- [ ] **PrMonitorState schema 拡張**: - - `src/cli-pr-monitor/src/state.rs` に `fix_push_time: Option` field を追加 (`#[serde(default)]` で legacy state 互換) -- [ ] **`monitor.rs` の push_time 算出経路修正**: - - L202-211 の fresh / resume 分岐で `pr_info.fix_push_time` を設定 - - fresh 経路: `state.fix_push_time = Some(utc_now_iso8601())` で state 書き込み - - resume 経路: `state.fix_push_time` を読んで `pr_info.push_time` に渡す (未設定なら fallback to `state.started_at` で legacy 互換) -- [ ] **`poll.rs` の state 書き込み箇所**: - - `build_state_for_iteration` / `finalize_*_park` 等で `fix_push_time` を新 state に保持 (上書きしない) -- [ ] **`poll.rs` に早期 merge 判断 signal 追加**: - - `handle_rate_limit_branch` で rate_limit 検出後、mergeable status 取得 + 条件評価 - - 全条件一致時に `[RATE_LIMIT_BUT_MERGEABLE]` signal を `println!` で出力、PARK signal は skip - - 条件不一致時は既存 PARK signal flow に合流 - - mergeable 取得失敗 (gh エラー / timeout) 時は安全側に倒して既存 flow に合流 -- [ ] **test 追加** (2 シナリオに絞る): - - シナリオ 1 (主軸 C): fresh push 経路で `fix_push_time` が設定され、wakeup 経路で同値が維持される (state round-trip test) - - シナリオ 2 (検出 + signal): mockable な gh 応答 (mergeable CLEAN 固定) を注入し、`[RATE_LIMIT_BUT_MERGEABLE]` signal が出力されることを assert -- [ ] **dogfood**: 派生 test PR で再 push → CR rate-limit 強制発火 → signal 出力 → AskUserQuestion 経由でユーザー判断 → merge / wait 分岐が機能することを観測 -- [ ] **削除した原案要素**: 補助 B (overlay marker bypass) は削除 = 主軸 C 単独で十分、CR 仕様変更時は graceful degradation で受容 -- [ ] **削除した原案要素**: ADR-018 注記追記は scope 外 (本修正は spec drift fix なので ADR-018 spec 自体は変更不要) - -#### 完了基準 - -- `cargo test -p cli-pr-monitor -p check-ci-coderabbit` で 2 シナリオ test が pass -- PR #169 で観測した overlay 除外現象が再現できなくなる (主軸 C による回帰防止) -- 次回 CR rate-limit 観測時に **5-10 分以内** にユーザーが merge / wait を判断できる (shortcut signal 経由) -- ユーザーが「待つ」を選んだ場合は既存 auto-retry path がそのまま動く (回帰なし) -- Claude 判断介入 (AI 独断で merge or wait) は介在しない (signal → AskUserQuestion → ユーザー判断 → action の構造) - -#### 詰まっている箇所 - -- **mergeable 取得の遅延 / 失敗時の挙動**: `gh pr view` が rate-limit に当たる (GitHub API 側の rate-limit、CR とは別軸) ケースは稀だが存在する。safety: 取得失敗時は signal を出さず既存 PARK flow に倒す = 「shortcut が出ない = 通常 flow」で誤動作なし -- **同 process 内 1 回限り の制約**: wakeup 経路で再度 rate-limit が観測された場合、毎回 mergeable status を取得しに行く設計。retry 回数が増えると gh 呼び出しも増えるが、`max_retries=3` で頭打ちなので影響軽微 -- **派生プロジェクトへの transferability**: 本修正は本リポジトリの cli-pr-monitor 固有実装に依存。techbook-ledger / auto-review-fix-vc 等の派生プロジェクトに展開する場合は同型 schema 拡張 + signal 追加が必要 (porting 時に検討) - ---- ### ADR-041 補強 — "State Preservation Invariant" pattern section 追加 (PR #170 T3-#1 採用) @@ -601,6 +433,53 @@ analyzer report の `[ADR-041 追加 section 案]` をベースに、`docs/adr/a --- +### preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用) + +> **動機**: PR #172 で `jj-message-required` preset 実装の Phase 3 において、当初 `is_blocked("jj new")` (default config 使用) で block を assert する test を書いたが、`jj-message-required` が `default_preset_names()` の fallback list に含まれない opt-in preset であることを前提とせず、test rewrite が必要になった。preset architecture の implicit assumption (always-enabled vs config-selectable) を test 設計レベルで codify することで、将来の新 preset 追加時の design misalignment を構造的に防止する。 +> +> **本タスクの位置づけ**: PR #172 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。matrix test で preset 分類を明示する mechanical enforcement 層を追加。 +> +> **参照**: `.claude/feedback-reports/172.md` Tier 2 #1、`src/hooks-pre-tool-validate/src/main.rs` の `default_preset_names()` + test module、PR #172 Phase 3 (test rewrite 経緯) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。Bundle 171 残タスク (順位 142 + 143) との並列実施可能。 + +#### 設計決定 (案) + +- **配置先**: `src/hooks-pre-tool-validate/src/main.rs` の test module (feedback report は lib.rs と記載するが本 crate は binary crate のため main.rs を採用) +- **matrix 構成** (2 軸): + - axis 1: `default fallback (always-enabled)` vs `config-selectable (opt-in)` + - axis 2: 各 preset 名 +- **classification 期待値** (本セッション時点): + - always-enabled (`default_preset_names()` 内): `default` / `git` / `jj-immutable` / `jj-main-guard` / `jj-push-guard` / `electron` + - config-selectable: `gh-pr-create-guard` / `gh-pr-merge-guard` / `polling-anti-pattern` / `exe-help-block` / `jj-message-required` +- **test 案**: + - `preset_default_fallback_classification`: 各 always-enabled preset 名が `default_preset_names()` の return に含まれることを assert + - `preset_config_selectable_opt_in_classification`: 各 config-selectable preset 名が `default_preset_names()` に含まれないことを assert + - `preset_matrix_full_coverage`: 既知 preset 名の全集合が classification 表 (always-enabled ∪ config-selectable) と一致することを assert (= 新 preset 追加時に matrix 更新を強制) + +#### 作業計画 + +- [ ] preset 分類表を const として定義 (`ALWAYS_ENABLED_PRESETS` + `CONFIG_SELECTABLE_PRESETS`) +- [ ] matrix test 関数 3 件追加 (default fallback / config-selectable / full coverage) +- [ ] 既存 test (`default_config_enables_all_presets` / `jj_message_required_not_in_default_fallback_is_opt_in` 等) との重複整理 (削除 or matrix への移行) +- [ ] `resolve_preset_or_custom` の dispatch arm 列挙との整合性確認 (matrix の preset 名 = dispatch arm 名) +- [ ] 派生プロジェクト transferability 考慮 (porting 時に preset 分類を即把握できる) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- preset の分類 (always-enabled vs config-selectable) が test レベルで codify される +- 将来の新 preset 追加時に classification 表を更新せざるを得ない構造になり、design misalignment が構造的に検出される +- 既存 test (158 件) との regression なし +- `resolve_preset_or_custom` の arm 列挙との不整合 (preset 追加忘れ等) が test で catch される + +#### 詰まっている箇所 + +- feedback report は target を `src/hooks-pre-tool-validate/src/lib.rs` と記載するが、本 crate は binary crate (main.rs のみ) で lib.rs は存在しない → main.rs を採用 (target 是正) +- 「config-selectable preset 名が default に含まれない」test は `jj_message_required_not_in_default_fallback_is_opt_in` で 1 件既存。matrix 化で全 5 preset に拡張する + +--- + ## 既知課題 (記録のみ、本セッションで未対応) ### post-merge-feedback workflow が長時間 stale marker を残す問題 (PR #119 marker observed 2026-05-15) diff --git a/docs/todo9.md b/docs/todo9.md new file mode 100644 index 00000000..9cba1ee9 --- /dev/null +++ b/docs/todo9.md @@ -0,0 +1,310 @@ +# TODO (Part 9) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo8.md がファイルサイズ 60KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #172 仕組み化方針切替セッション = 2026-05-25)。todo.md / todo2.md 〜 todo8.md の既存エントリは引き続き有効、相互に独立。新セッションでは十つすべてを確認すること (todo.md / todo2-9.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### 既存ルール仕組み化バンドル — 6 件 (PR #172 仕組み化方針切替由来、2026-05-25 ユーザー判断採用) + +本 section は PR #172 (順位 144 = `jj-message-required` preset) の hook 化 dogfood 成功事例を踏まえ、`~/.claude/rules/common/*.md` 内の既存ルールから機械強制可能な 6 件を仕組み化に切り替えるバンドルです。memory rule `feedback_pipeline_over_rules.md` の体系的適用で、session 毎の rule load コスト削減 + 別セッションでの結果一定化を実現します。 + +仕組み化後は対応する rule docs section を縮小または削除 (block message に集約) し、`~/.claude/rules/common/*.md` の総量を削減します。 + +--- + +### Secret detection PreToolUse hook 追加 — AWS/OpenAI/GitHub token 等の hardcoded secret 検出 (PR #172 仕組み化方針切替由来、`security.md` § Secret Management 移管) + +> **動機**: `~/.claude/rules/common/security.md` § Secret Management の「NEVER hardcode secrets in source code」は現在 rule docs 記載のみで機械強制なし。session 毎に security.md を読み込まないと AI が rule を解釈しない構造的脆弱性が残る。PreToolUse hook で Edit/Write 時に AWS key / OpenAI key / GitHub token 等の regex 検出を行い、即 block + feedback を返すことで漏洩を構造的に防止する (ユーザー判断 2026-05-25 = PreToolUse hook 方式採用)。 +> +> **本タスクの位置づけ**: 既存ルール仕組み化バンドルの第 1 件。順位 144 (`jj-message-required`) と同型実装パターン。`feedback_pipeline_over_rules.md` 適用 = パイプライン側機械的修正で Claude 判断介入を排除。 +> +> **参照**: `~/.claude/rules/common/security.md` § Secret Management、`src/hooks-pre-tool-validate/src/main.rs` (`preset_jj_message_required` を template に追加)、`.claude/hooks-config.toml`、PR #172 (順位 144 hook 化 dogfood) +> +> **実行優先度**: 🚀 **Tier 1** — Effort M。security-critical かつ漏洩観測前の preventive 層。 + +#### 設計決定 (案) + +- **配置**: `src/hooks-pre-tool-validate/src/main.rs` に新 preset `secret-detection` 追加 +- **検出対象 regex** (高頻度 secret pattern): + - AWS Access Key: `AKIA[0-9A-Z]{16}` + - AWS Secret Key: `aws_secret_access_key\s*=\s*[A-Za-z0-9/+=]{40}` + - OpenAI API Key: `sk-[A-Za-z0-9]{20,}` (現 sk-proj 系を含む形式) + - GitHub Personal Access Token: `ghp_[A-Za-z0-9]{36}` / `github_pat_[A-Za-z0-9_]{20,}` + - GitHub OAuth Token: `gho_[A-Za-z0-9]{36}` / `ghs_[A-Za-z0-9]{36}` + - Anthropic API Key: `sk-ant-[A-Za-z0-9_-]{20,}` + - 汎用高エントロピー string (要 false positive 評価): `[A-Za-z0-9+/]{40,}={0,2}` (base64-like) は対象外とする (汎用過ぎる) +- **exception field 不使用**: secret pattern に正当な使用例はない (test fixture は dummy で十分) +- **block message**: 「機密情報が検出されました。環境変数 / secret manager に移管してください」+ 検出 pattern type +- **hooks-config.toml**: `blocked_patterns` に `"secret-detection"` 追加 (opt-in 設計だが Tier 1 のため default 推奨) + +#### 作業計画 (順位 144 と同 phase 構造) + +- [ ] Phase 1: `preset_secret_detection()` 関数を実装 (6-8 種の BlockedPattern を vec で返す) +- [ ] Phase 2: `build_blocked_patterns` の `resolve_preset_or_custom` dispatch に登録 + `.claude/hooks-config.toml` の `blocked_patterns` に追加 + コメント section 説明追加 +- [ ] Phase 3: test 拡充 — block ケース (6+ 種類の secret pattern) × allow ケース (regular code) × non-regression +- [ ] Phase 4: `pnpm build:hooks-pre-tool-validate` で exe deploy + dogfood (dummy AWS key 等で block 動作確認) +- [ ] Phase 5: `pnpm push` + `pnpm create-pr` +- [ ] post-merge: 派生プロジェクト deploy + `~/.claude/rules/common/security.md` § Secret Management の hook 化記述追加 (rule docs 縮小は別 follow-up) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 6+ 種類の高頻度 secret pattern が Edit/Write 時に block される +- regular code (variable name "key" / "secret" の使用、test fixture の dummy "AKIATEST...") は通過 +- 既存 preset と non-regression +- `cargo test -p hooks-pre-tool-validate` pass +- security.md § Secret Management から具体 pattern 列挙を hook block message に移管 (docs 縮小) + +#### 詰まっている箇所 + +- false positive リスク: API key 形式の文字列が test fixture / 説明文に登場する可能性。test fixture は paths filter 除外で対応 (順位 150 magic number lint と同 pattern) +- pattern 漏れ: 検出対象 6-8 種類は主要のみ。Anthropic API key 形式変更 / 新 service token 追加時は手動更新が必要 (feedback loop) + +--- + +### File length lint (800 行 max) 追加 — `coding-style.md` § File Organization 移管 (PR #172 仕組み化方針切替由来) + +> **動機**: `~/.claude/rules/common/coding-style.md` § File Organization の「200-400 lines typical, 800 max per file」ガイドラインは現在 rule docs 記載のみで、機械強制されていない。順位 48 (関数長 50 行) は `hooks-post-tool-comment-lint-rust` で touch-trigger ratchet 方式により既に機械強制済の前例があり、ファイルサイズも同 pattern で実装可能。session 毎の rule load コスト削減 + 800 行突破時の編集時即 block を実現する。 +> +> **本タスクの位置づけ**: 既存ルール仕組み化バンドル 2 件目。順位 48 (関数長) と同 pattern で工数把握済。touch-trigger ratchet 適用で既存超過ファイルを編集時のみ flag (grandfather)、新規 800 行超え発生を block。 +> +> **参照**: `~/.claude/rules/common/coding-style.md` § File Organization、`src/hooks-post-tool-comment-lint-rust/src/main.rs` (`find_function_length_violations` を template に file length 版を追加)、順位 48 PR #101 T1-4 実装 +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。順位 48 同 pattern で ~50 行 + test。 + +#### 設計決定 (案) + +- **配置**: `src/hooks-post-tool-comment-lint-rust/src/main.rs` に `find_file_length_violations` を追加 +- **閾値**: `MAX_FILE_LINES = 800` (constant 定義、coding-style.md と同期) +- **touch-trigger ratchet**: 既存 800 行超ファイルは触られた時のみ flag (関数長 ratchet と同 pattern) +- **対象拡張子**: Rust (`.rs`) のみ最初は対象、将来 TS/Py 拡張は別 task +- **MAX_VIOLATIONS との関係**: 既存 `collect_all_violations` の truncate に乗せる (順位 57 contract test 適用済) +- **block message**: 「ファイル長 N 行 > 上限 800 行 (coding-style.md File Organization)」+ 分割提案 + +#### 作業計画 + +- [ ] `find_file_length_violations` 関数を実装 (`source.lines().count()` + line_filter 整合チェック) +- [ ] `collect_all_violations` から呼び出し追加 (順位 57 truncate contract 維持) +- [ ] test 拡充: 800 行未満 (no violation) / 800 行ちょうど (no violation) / 801 行 (violation) / 既存 1000 行ファイル + line_filter touch (violation) / 既存超過 + no touch (grandfather) +- [ ] `pnpm build:hooks-post-tool-comment-lint-rust` で exe deploy + dogfood +- [ ] `~/.claude/rules/common/coding-style.md` § File Organization の縮小 (= block message に集約、rule docs から具体閾値を削除) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 800 行超ファイル編集時に block + 分割提案 feedback +- 既存超過ファイルの未編集箇所は touch-trigger で grandfather (false positive なし) +- 順位 57 truncate contract test pass +- coding-style.md § File Organization 縮小 + +#### 詰まっている箇所 + +- TS / Py 拡張: 本 task は Rust 限定。多言語対応は別 hook (`hooks-post-tool-linter` 系) で実装する場合は別 task に分離 +- 800 行は coding-style.md 記載値。CLAUDE.md (project) の「200-400 lines typical」とは整合 (typical/max の 2 段階) + +--- + +### Test coverage 80% CI gate 追加 — `testing.md` § Minimum Test Coverage 80% 移管 (PR #172 仕組み化方針切替由来) + +> **動機**: `~/.claude/rules/common/testing.md` § Minimum Test Coverage 80% は rule docs 記載のみで実行時 gate なし。`cargo llvm-cov --fail-under-lines 80` を pre-push step または CI step に追加することで、80% 未満 push を構造的に防止する。memory rule に頼らず実行時に gate を働かせることで session 跨ぎ品質一定化。 +> +> **本タスクの位置づけ**: 既存ルール仕組み化バンドル 3 件目。Effort S-M (CI 追加 + 既存カバレッジ実測 + 80% 未満なら段階導入計画)。 +> +> **参照**: `~/.claude/rules/common/testing.md` § Minimum Test Coverage、`push-runner-config.toml` (新 step 追加候補)、`.github/workflows/` (未存在の場合 CI workflow 新設)、`cargo-llvm-cov` crate +> +> **実行優先度**: 🔧 **Tier 2** — Effort S-M。実測カバレッジ次第で段階導入計画が必要 (現状未測定)。 + +#### 設計決定 (案) + +- **配置方式の選択** (実装時判断): + - 案 A: `push-runner-config.toml` の `[quality_gate]` に coverage step 追加 (pre-push 時に gate) + - 案 B: `.github/workflows/coverage.yml` 新設 (CI 時に gate) + - 推奨: 案 A (本リポジトリは takt ベース push-runner で gate 統一済、`.github/workflows/` は未存在で順位 96 で初導入予定) +- **ツール**: `cargo llvm-cov --fail-under-lines 80` (workspace 全体) +- **段階導入**: 現状実測カバレッジが 80% 未満の crate がある場合、crate 別閾値設定 or temporary exception +- **rule docs 縮小**: testing.md § 「Minimum Test Coverage: 80%」は実行時 gate 化により「ガイドライン」記述を削除可能 + +#### 作業計画 + +- [ ] 全 crate の現状カバレッジを実測 (`cargo llvm-cov` で workspace 全体) +- [ ] 80% 未満の crate があれば段階導入計画 (現状値を temporary baseline、増分対象を明示) +- [ ] 案 A/B 選択 (推奨: 案 A、push-runner-config.toml [quality_gate] に integration) +- [ ] `push-runner-config.toml` または `.github/workflows/coverage.yml` に gate step 追加 +- [ ] dogfood: 1-2 PR で gate 動作確認 (80% 切る変更で block される) +- [ ] `~/.claude/rules/common/testing.md` § 80% coverage 記述を実行時 gate に置換 (rule docs 縮小) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- workspace 全体カバレッジが gate で実行時検証される +- 80% 未満 push が block される (or warning で reviewer 判断、段階導入次第) +- testing.md § 80% coverage は実行時 gate への参照のみ残す形に縮小 + +#### 詰まっている箇所 + +- 現状カバレッジ未測定。実装着手前に実測 + baseline 設定が必要 +- 段階導入の影響範囲: 既存 PR workflow が一時的に gate failure になるリスク。段階閾値 (50% → 60% → 70% → 80%) 設計が必要かもしれない + +--- + +### Long-running subprocess pipe truncate hook 拡張 — `development-workflow.md` § subprocess pipe truncate 禁止 移管 (PR #172 仕組み化方針切替由来) + +> **動機**: `~/.claude/rules/common/development-workflow.md` § 長時間 subprocess pipe truncate 禁止 (PR #109 SIGPIPE 事故由来) は既存 `exe-help-block` preset で部分的に機械強制済。具体的には `cli-*.exe --help | head` 等を block する preset だが、`cli-merge-pipeline ... | head` のような副作用ある実 subprocess の出力 truncate は未カバー。本 task では `cli-*.exe ... | (head|tail|awk)` 等のパターン検出を拡張し、SIGPIPE リスクを完全構造化する。 +> +> **本タスクの位置づけ**: 既存ルール仕組み化バンドル 4 件目。既存 `exe-help-block` preset 拡張または新 `subprocess-pipe-truncate-block` preset 追加。 +> +> **参照**: `~/.claude/rules/common/development-workflow.md` § 長時間 subprocess pipe truncate 禁止、`src/hooks-pre-tool-validate/src/main.rs` (`preset_exe_help_block` を template に拡張)、PR #109 SIGPIPE 事故 (ADR-030 root cause) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。既存 preset 拡張 ~30 行 + test。 + +#### 設計決定 (案) + +- **拡張 vs 新 preset**: + - 案 A: 既存 `exe-help-block` preset に pipe truncate 検出を追加 (1 preset で 2 機能、命名 misleading) + - 案 B: 新 `subprocess-pipe-truncate-block` preset 追加 (preset 命名整合) + - 推奨: 案 B (preset の単一責任原則、関係 rule docs と命名整合) +- **block pattern**: + - `cli-*.exe ... | (head|tail|awk)` 系: `(cli-[\w-]+|hooks-[\w-]+|check-ci-[\w-]+)\.exe\s+[^|]*\|\s*(head|tail|awk\b)` + - `gh api ... | head` 系 (rate-limit 中 risk): 順位 44 (gh-token-efficiency) と重複するため scope 重複回避を判断 + - `pnpm push | head` / `pnpm merge-pr | tail` 系: pnpm scripts も同型リスク +- **exception field**: `--jq` / `--json` 経由の structured 抽出は allow (順位 44 と整合) +- **block message**: 「長時間 subprocess の pipe truncate は SIGPIPE で中断される (ADR-030 PR #109 事故の根本原因)。`run_in_background: true` + `--jq` 抽出 / `> /dev/null` 破棄 を推奨」 + +#### 作業計画 + +- [ ] 既存 `preset_exe_help_block` のロジック分析 + 拡張 vs 新 preset 決定 +- [ ] block pattern 実装 (cli-/hooks-/check-ci- 系 exe + pipe truncate) +- [ ] pnpm scripts カバー範囲決定 (pnpm push/merge-pr/create-pr 等の truncate も block するか) +- [ ] exception field で正当な短命確認系 (`ls -la | head -10` 等) を allow +- [ ] test 拡充: block ケース 5+ / allow ケース 5+ / 既存 exe-help-block との non-regression +- [ ] `pnpm build:hooks-pre-tool-validate` で exe deploy + dogfood +- [ ] `~/.claude/rules/common/development-workflow.md` § 該当 section 縮小 (具体的禁止パターンを hook block message に集約) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 副作用ある cli-*.exe 出力 truncate が block される (SIGPIPE 事故再発防止) +- 順位 44 (gh-token-efficiency) との scope 重複が整理される +- 既存 `exe-help-block` preset と non-regression +- development-workflow.md § 長時間 subprocess pipe truncate 禁止 を hook 化記述に縮小 + +#### 詰まっている箇所 + +- pnpm scripts のカバー範囲判断: `pnpm push | head` 等の truncate も block するか (= scope D の wrapper 制限と整合する判断必要) +- 順位 44 との scope 重複整理: `gh api ... | head` は順位 44 で扱い、本 task は cli-*.exe / pnpm scripts に限定する境界明示 + +--- + +### Magic number lint 追加 — `coding-style.md` § Magic Numbers 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = source folder 限定) + +> **動機**: `~/.claude/rules/common/coding-style.md` § Magic Numbers の「Use named constants for meaningful thresholds, delays, and limits」は rule docs 記載のみで機械強制なし。ユーザー判断 (2026-05-25) で「**source folder のみ対象、test/config 除外**」方針確定。数値リテラル定数化を `src/**/*.rs` 等に paths filter 適用で検出する。 +> +> **本タスクの位置づけ**: 既存ルール仕組み化バンドル 5 件目。順位 102 (Phase D D-3) で実装した `paths` filter (順位 118 で適用範囲検討中) を活用する custom lint rule。 +> +> **参照**: `~/.claude/rules/common/coding-style.md` § Magic Numbers、`.claude/custom-lint-rules.toml` (新 rule 追加候補)、順位 102 paths filter 実装、順位 118 rule⑧ paths filter 適用範囲検討 +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。custom lint rule 1 件追加 + paths filter design + test coverage 必要。 + +#### 設計決定 (案) + +- **配置**: `.claude/custom-lint-rules.toml` に新 rule `no-magic-number` 追加 +- **検出 pattern (案、要 dogfood 調整)**: + - 関数 body 内の bare integer literal (regex で 限定的に検出、要試行錯誤): + - 時間定数 candidate: `\b(1000|60|3600|86400)\b` (millisecond / minute / hour / day) + - リトライ回数 candidate: `\b(3|5|10)\s*[;,)]` の文脈付き検出 + - 閾値 candidate: 関数 argument / 比較演算子付きの hardcoded number + - 要試行錯誤: 全 integer literal を flag すると false positive 過多、特定 idiom (時間定数 / リトライ回数 / threshold) に絞る +- **paths filter** (ユーザー判断: source folder のみ): + - `paths = ["src/**/*.rs", "src/**/*.ts", "src/**/*.py"]` 等 + - **除外**: `src/**/tests/**`、`src/**/*.test.*`、`src/**/test_*.rs`、`*.config.*`、`.claude/**`、`docs/**` +- **severity**: warning (false positive リスクのため block しない、reviewer 判断補助) +- **exception**: 関数内で `const` / `let` で名前付き定義済の値は対象外 (regex で前方検索) + +#### 作業計画 + +- [ ] 検出 pattern 設計 (時間定数 / リトライ回数 / threshold の 3 category で MVP) +- [ ] paths filter 設計 (source folder 限定、test/config 除外) +- [ ] `.claude/custom-lint-rules.toml` に rule 追加 + `[rules.test_coverage]` meta field 設定 (testing.md § Custom Lint Rule Test Coverage 適用) +- [ ] test 拡充: positive (時間定数 hardcoded) / negative (定数化済 / test fixture / config) / paths filter 動作確認 +- [ ] dogfood: 1-2 PR で false positive 観測 → pattern 調整 +- [ ] `~/.claude/rules/common/coding-style.md` § Magic Numbers 削除可否判断 (lint で十分カバーされたら docs 縮小) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- source folder の hardcoded 数値リテラル (時間定数等) が warning として検出される +- test fixture / config / docs は false positive なし +- `[rules.test_coverage]` meta field で positive/negative test の存在が cargo test で検証される +- coding-style.md § Magic Numbers 削除 (lint rule の存在で代替) or 縮小 + +#### 詰まっている箇所 + +- pattern 設計の試行錯誤: bare integer literal の全検出は false positive 過多、idiom 限定が現実的だが取りこぼしリスク +- 既存 source code で hardcoded 数値が残存している場合、initial run で大量 warning 発生する可能性 → touch-trigger ratchet 必要か再評価 + +--- + +### PR diff lines check 追加 — `git-workflow.md` § Multi-PR chaining 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = 条件付き block 3 段階) + +> **動機**: `~/.claude/rules/common/git-workflow.md` § Multi-PR chaining の「1 PR あたり 250-800 lines」ガイドラインは rule docs 記載のみ。ユーザー判断 (2026-05-25) で「**条件付き block 3 段階: > 1500 block / 800-1500 warning / < 800 通過、threshold は config 化**」方針確定。pre-push step で line count を check し、巨大 PR を構造的に抑制する。 +> +> **本タスクの位置づけ**: 既存ルール仕組み化バンドル 6 件目。`push-runner-config.toml` に新 `[pr_size_check]` section を追加し、threshold を config 化することで大型 refactoring 時の override も config 経由で柔軟に対応。 +> +> **参照**: `~/.claude/rules/common/git-workflow.md` § Multi-PR chaining、`src/cli-push-runner/src/` (新 stage 追加候補)、`push-runner-config.toml`、PR #119/#120/#121 (250-800 lines/PR ベストプラクティス実証) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。push-runner に新 stage 追加 ~50 行 + config schema + test。 + +#### 設計決定 (案) + +- **配置**: `src/cli-push-runner/src/stages/` に新 stage `pr_size_check.rs` 追加 +- **計測対象**: `jj diff -r 'master..@' --stat` の line count 合計 (additions + deletions) +- **3 段階閾値**: + - `block_threshold` (default 1500): 超過時 push を block + 分割推奨 feedback + - `warning_threshold` (default 800): 超過時 warning 出力 + push 続行 + - 800 未満: 通過、ログにのみ出力 +- **config schema** (`push-runner-config.toml` の新 section): + ```toml + [pr_size_check] + enabled = true + block_threshold = 1500 + warning_threshold = 800 + # 大型 refactoring 時の override: false にして特定 PR で skip 可能 + ``` +- **opt-in 設計**: 既存 push-runner-config.toml に section がない場合は default 値で動作 (= enabled、threshold default) +- **派生プロジェクト transferability**: config schema で threshold 調整可能、プロジェクト規模に応じて変更可 + +#### 作業計画 + +- [ ] `src/cli-push-runner/src/config.rs` に `PrSizeCheckConfig` struct 追加 (`enabled` / `block_threshold` / `warning_threshold`) +- [ ] `src/cli-push-runner/src/stages/pr_size_check.rs` 新 stage 実装 (jj diff stat 計測 + 3 段階判定) +- [ ] `src/cli-push-runner/src/stages/mod.rs` で export + `runner.rs` の stage ordering に挿入 (quality_gate 後 / push 前) +- [ ] `push-runner-config.toml` に `[pr_size_check]` section デフォルト設定追加 +- [ ] test 拡充: line count 計測精度 / 3 段階判定 / config parse / opt-in 動作 +- [ ] dogfood: 本 task PR (推定 ~400 行) で通過、過去 PR (PR #119 sub-PR 200 行 / PR #146 ~600 行) で warning 閾値検証 +- [ ] `~/.claude/rules/common/git-workflow.md` § Multi-PR chaining を実行時 gate 参照に縮小 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- pre-push 時に PR line count が計測され 3 段階判定される +- block_threshold 超過時に push block (config で threshold 変更可能) +- warning_threshold 超過時に warning 出力 + 続行 +- config schema が `push-runner-config.toml` の `toml::from_str` test でカバーされる (順位 91 を template、ただし opt-in classification は 順位 145 と整合) +- git-workflow.md § Multi-PR chaining 縮小 + +#### 詰まっている箇所 + +- jj diff stat の解析: `jj diff --stat` の出力 format が version 依存しないか確認必要 (ADR-017 jj version pin 適用範囲) +- 大型 refactoring 時の override 方法: `enabled = false` (config 編集) vs CLI flag (`--skip-size-check`)。前者推奨だが PR 単位 override は config 編集だけだとセッション横断で漏れるリスク + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +(現時点で本ファイルへの既知課題は無し。docs/todo8.md 末尾の post-merge-feedback workflow stale marker 問題を参照。)