diff --git a/.claude/custom-lint-rules.toml b/.claude/custom-lint-rules.toml index 6697c70..f848701 100644 --- a/.claude/custom-lint-rules.toml +++ b/.claude/custom-lint-rules.toml @@ -165,8 +165,8 @@ steps = [ ] [rules.example] -bad = 'See [推奨実行順序](todo.md#推奨実行順序サマリー)' -good = 'See [推奨実行順序](todo.md#recommended-order-summary) ' +bad = 'See [推奨実行順序](todo-summary.md#推奨実行順序サマリー)' +good = 'See [推奨実行順序](todo-summary.md#recommended-order-summary) ' # ─── ルール⑥: 非 docs ファイルからの ephemeral todo 参照禁止 ─── # diff --git a/docs/adr/adr-034-coderabbit-auto-monitoring.md b/docs/adr/adr-034-coderabbit-auto-monitoring.md index 0a29fbe..cd90b7f 100644 --- a/docs/adr/adr-034-coderabbit-auto-monitoring.md +++ b/docs/adr/adr-034-coderabbit-auto-monitoring.md @@ -147,9 +147,9 @@ PR #99 セッションで以下の運用痛が観測された: - `project_coderabbit_rate_limit_overlay.md`: rate-limit 検出ロジックの根拠 (PR #99 で実証された walkthrough overlay 仕様) - `project_coderabbit_auto_resolve.md`: `resolved:` reply での auto-resolve 挙動 -### todo.md / todo4.md エントリ +### todo-summary.md / todo4.md エントリ -- `docs/todo.md` 推奨実行順序サマリー: 順位 42-45 (Bundle a 4 component) +- `docs/todo-summary.md` 推奨実行順序サマリー: 順位 42-45 (Bundle a 4 component) - `docs/todo4.md`: - cli-pr-monitor の rate-limit auto-retry + `@coderabbitai review` auto-trigger 実装 (PR #99 T2-4) - ADR-018 / ADR-009 の rate-limit retry ポリシー明文化 (PR #99 T3-5) @@ -158,7 +158,7 @@ PR #99 セッションで以下の運用痛が観測された: ### 新セッションで最初に確認すべきこと 1. `git log --oneline -5` で master の最新状態を確認 (Bundle Z Phase 2/3 が land 済か等) -2. `docs/todo.md` の Bundle a 関連 entry (順位 42-45) を読む +2. `docs/todo-summary.md` の Bundle a 関連 entry (順位 42-45) を読む 3. `docs/todo4.md` の Bundle a 詳細 entry を読む 4. 本 ADR (ADR-034) を読む 5. memory `project_coderabbit_rate_limit_overlay.md` を読む diff --git a/docs/local-llm-offload-history.md b/docs/local-llm-offload-history.md index 786b067..9fb07f8 100644 --- a/docs/local-llm-offload-history.md +++ b/docs/local-llm-offload-history.md @@ -180,7 +180,7 @@ Claude Code のトークン消費・レートリミットを抑える目的で ##### Phase 5 dogfood で観測した cli-pr-monitor robustness 課題 → Bundle f として登録 -PR #120 の dogfood で post-pr-monitor の wakeup state 遷移と auto-retry path に複数の edge case を発見。本 doc の retirement 直接条件ではないが、ローカル LLM dogfood の副産物として monitor 堅牢化を進める Bundle f を [docs/todo.md](todo.md) priority table に登録 (順位 80-84): +PR #120 の dogfood で post-pr-monitor の wakeup state 遷移と auto-retry path に複数の edge case を発見。本 doc の retirement 直接条件ではないが、ローカル LLM dogfood の副産物として monitor 堅牢化を進める Bundle f を [docs/todo-summary.md](todo-summary.md) priority table に登録 (順位 80-84): - **順位 80** (Tier 1, Bundle f): rate-limit auto-retry wakeup 予約ロジックの整理 — `auto_retry_enabled=true` でも park 未予約で exit する事象を観測 - **順位 81** (Tier 1, Bundle f): CR 投稿エラー (`Failed to post review comments`) の auto-retry 拡張 — 既存 rate-limit detection をバイパスして retry 未発火 @@ -193,9 +193,9 @@ PR #120 の dogfood で post-pr-monitor の wakeup state 遷移と auto-retry pa #### 2026-05-07: §8.C land (PR #121) — ADR-038 textual fix + Bundle f task registration - **§8.C 実施**: ADR-038 line 61 の `confidence=0.0` → `action_confidence=0.0` に統一 (実装 schema 名称との整合) -- **Bundle f 登録**: 順位 80-84 を `docs/todo.md` priority table + `docs/todo5.md` 詳細エントリに記録 (頻度確認後に優先度判断する方針を明記) +- **Bundle f 登録**: 順位 80-84 を `docs/todo-summary.md` priority table + `docs/todo5.md` 詳細エントリに記録 (頻度確認後に優先度判断する方針を明記) - **PR #121**: docs-only PR → CR 「No actionable comments」 → squash merge `6640dc7b` (2026-05-07T04:47:56Z、master) -- **post-merge-feedback (PR #121)** で Bundle g (順位 85-88) を新規追加: `(review_state, findings) → verdict` 評価ロジックの edge case を 3 PR (#119/#120/#121) 連続観測で頻度確認 → Tier 1 妥当性確定。詳細は [docs/todo5.md](todo5.md) 順位 85-88、bundle commentary は [docs/todo.md](todo.md) Bundle g 段落 +- **post-merge-feedback (PR #121)** で Bundle g (順位 85-88) を新規追加: `(review_state, findings) → verdict` 評価ロジックの edge case を 3 PR (#119/#120/#121) 連続観測で頻度確認 → Tier 1 妥当性確定。詳細は [docs/todo5.md](todo5.md) 順位 85-88、bundle commentary は [docs/todo-summary.md](todo-summary.md) Bundle g 段落 ### 効果実測の現状 diff --git a/docs/todo-summary.md b/docs/todo-summary.md new file mode 100644 index 0000000..ca016c4 --- /dev/null +++ b/docs/todo-summary.md @@ -0,0 +1,109 @@ +# TODO 推奨実行順序サマリー + +> **本ファイルの位置付け**: `docs/todo.md` から「推奨実行順序サマリー」section を切り出した index 専用ファイル。各タスクの詳細は「ファイル」列に示された `docs/todoN.md` を参照する。`docs/todo.md` のサイズが 50KB を超え Claude Code 読み取り安定性に影響したため分離 (2026-05-09)。 +> +> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo6.md`) に記録する。 + + +## 推奨実行順序サマリー (2026-04-29 更新、ADR-033 採番管理簡素化 land 後) + +開発環境の作業効率への貢献度を基準にした推奨実行順序。詳細は各タスク冒頭の **「実行優先度」** 行を参照。 + +| 順位 | Tier | タスク | ファイル | 工数 | 依存 | +|---|---|---|---|---|---| +| 1 | 🚀 Tier 1 | push 前 untracked `__*` ファイル警告 hook (PR #85 T1-4) | todo2.md | Small | なし (PR #85 直接対策) | +| 2 | 🚀 Tier 1 | `cli-push-runner` jj bookmark 未設定 early-exit (PR #85 T1-3) | todo2.md | S | なし | +| 5 | 🚀 Tier 1 | **AI 生成一時スクリプト pattern の pre-push 検出 (PR #88 T1-2)** | todo3.md | Small | 順位 1 と関連 (要擦り合わせ) | +| 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | +| 8 | 🔧 Tier 2 | 週次レビュー (ADR-031) Phase B 実装 | todo.md | 中-高 | なし (順位 20 の compensating check 前提) | +| 10 | 🔧 Tier 2 | ADR-032 PR-broken-link: broken-link-check + 内部アンカー検査 統合 | todo2.md | Small-中 | なし (clean baseline 確立済) | +| 11 | 🔧 Tier 2 | `cli-pr-monitor` プロセス正常終了の integration test (PR #85 T2-2) | todo2.md | S | なし | +| 16 | 🔧 Tier 2 | **`vitest` を devDependencies に固定 (PR #88 T2-3)** | todo3.md | Small | なし | +| 17 | 🔧 Tier 2 | **`pnpm create-pr` 必須引数ヘルプ改善 (PR #88 T2-5)** | todo3.md | Small | なし | +| 18 | 🔧 Tier 2 | **`.failed` marker への recovery 手順自己文書化 (PR #90 T2-2)** | todo3.md | S | なし | +| 19 | 🔧 Tier 2 | **takt ハーネスの `REJECT-ESCALATE` terminal verdict 実装 (PR #91 T2-2)** | todo3.md | M | post-pr-review fix loop の `.claude/` filter (Bundle T、完了済) land 後推奨 | +| 20 | 💎 Tier 3 | ADR-032 PR-β: 実装 (enabled=false default) | todo2.md | 中-高 | 6, 8, 10 | +| 21 | 💎 Tier 3 | ADR-032 PR-γ: enablement (1 行 flip) | todo2.md | XS | 順位 8 dogfood + 順位 20 | +| 22 | 💎 Tier 3 | ADR-032 PR-δ: dogfood + メトリクス検証 | todo2.md | (運用) | 順位 21 | +| 27 | 🧹 Tier 4 | ADR-030 Phase E/F: 旧機構廃止 + dogfood | todo.md | 中 | なし (cleanup) | +| 28 | ⏳ Tier 5 | (追って) ADR-030 の takt-test-vc 反映 | todo.md | 中 | 順位 27 Phase F | +| 34 | 🚀 Tier 1 | **property-based testing (proptest) 導入 — 仕様を executable contract で明文化 (PR #96 T1-flaky) ★ Bundle W** | todo4.md | M | 順位 19 land 後推奨 (PR #96 直接対策、AI が flaky 実装を書ける窓を spec 層で塞ぐ) | +| 35 | 🚀 Tier 1 | **型で意味を表現 (PastTime newtype 等) — saturating_sub 系 silent semantic mismatch を構造的に排除 (PR #96 T1-flaky) ★ Bundle W** | todo4.md | S | 順位 34 と同 PR (Bundle W、PBT が型に守られて記述しやすくなる相補関係) | +| 36 | 🔧 Tier 2 | **cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) ★ Bundle X** | todo4.md | M | Bundle W land 後推奨 (PBT properties の後付け検証層、変更 crate + 1-hop 依存 scope) | +| 37 | 🔧 Tier 2 | **pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) ★ Bundle X** | todo4.md | S | 順位 36 と同 PR (Bundle X、cli-push-runner に +~1 秒 step 追加) | +| 38 | 💎 Tier 3 | **L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky)** | todo4.md | S | ADR-031 Phase B (順位 8) と同 bundle 化推奨、long-tail flake と coverage 全体監査 | +| 39 | 🚀 Tier 1 | **takt workflow `model` フィールド必須化 lint rule (PR #98 T1-1)** | todo4.md | S | なし (Bundle Y2 完全性: post-pr-review.yaml supervise step の `model:` 欠落を契機に決定論的防止層を追加) | +| 40 | 🚀 Tier 1 | **prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2)** | todo4.md | XS | なし (本セッション再現の push 失敗を Step 1 fallback で早期検出。skill repo 側更新) | +| 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 推奨) | +| 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 実装と一体) | +| 47 | 🚀 Tier 1 | **`>` vs `>=` boundary inconsistency lint rule (PR #101 T1-2)** | todo7.md | S | なし (PR #101 直接対策、同一ファイル内 3 関数で latent drift が実証済の高頻度問題) | +| 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 流用) | +| 51 | 🚀 Tier 1 | **`.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測)** | todo7.md | M | なし (PR #103 で stale-diff false positive による wasted iter ×2 = ~10 分浪費を実観測、6-iter outlier の構造的根因対策、Bundle Z 3 層では塞げない独立改善) | +| 52 | 💎 Tier 3 | **comment-lint hook の MultiEdit 対応 (順位 50 follow-up)** | todo7.md | S | なし (順位 50 で v1 = Edit のみ実装、MultiEdit は whole-file fallback で no-regression、利用頻度低く優先度は低) | +| 56 | 🔧 Tier 2 | **comment-lint hook test 拡充 (PR #104 T2-1+T2-2 bundle)** | todo7.md | S | なし (UTF-8 multi-byte 5 パターン + block comment boundary 6 パターンを `locate_string_line_ranges` / `span_overlaps_ranges` の回帰テストとして体系化、PR #104 Critical/Minor fix の固定化) | +| 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 を整備) | +| 63 | 🚀 Tier 1 | **cli-merge-pipeline に Drop guard / signal handler 追加 (PR #109 T1-1 採用) ★ Bundle c** | todo7.md | M | なし (PR #109 SIGPIPE 事故で ADR-030「失敗マーカーによる recovery」仕様の構造的違反が実証、Pre-emptive marker + signal trap で abrupt 経路を多層防御) | +| 64 | 🚀 Tier 1 | **orphan run reaper (`meta.json status=running` 5-15 分放置検出 + 自動再起動) (PR #109 T1-2 採用) ★ Bundle c** | todo7.md | M | なし (順位 63 で救済不可の致命系 = kill -9 / SIGKILL / power loss / OOM の backstop、SessionStart hook または cli-pr-monitor 経路で実装) | +| 65 | 🚀 Tier 1 | **exe + `--help` を PreToolUse でブロックして src/ Read に誘導 (PR #109 T1-3 採用) ★ Bundle c** | todo7.md | S | なし (PR #109 SIGPIPE の直接トリガ = AI が `cli-merge-pipeline.exe --help` 実行 → exe は --help 未対応で merge 本体実行を構造的に防止、今後追加 exe にも自動適用) | +| 66 | 💎 Tier 3 | **長時間 subprocess の pipe truncate 禁止ルールをグローバル明文化 (PR #109 T3-1 採用) ★ Bundle c** | todo7.md | XS | なし (順位 65 = 決定論層、本ルール = 判断ガイド層、`~/.claude/rules/common/development-workflow.md` 等に追加) | +| 67 | 💎 Tier 3 | **ADR-030 に abrupt 終了時の振る舞いを spec として明記 (PR #109 T3-2 採用) ★ Bundle c** | todo7.md | XS | 順位 63 / 64 と同 PR (実装と仕様の整合性確保、L1 in-process Drop guard + L2 out-of-process reaper の責務分離 + SLA 化) | +| 68 | 🔧 Tier 2 | **`no-ephemeral-todo-reference` self-exclusion invariant 単体テスト追加 (PR #110 T2-1 採用) ★ Bundle d** | todo5.md | S | なし (PR #110 直接対策、placeholder N 戦略の machine-enforceable 保護、TP/FP/Edge 3 軸テスト) | +| 69 | 💎 Tier 3 | **`no-ephemeral-todo-reference` の `yaml`/`yml` extensions 追加理由をコメントで明記 (PR #110 T3-1 採用) ★ Bundle d** | todo5.md | XS | なし (rule⑥ コメント欄に 1-2 行追記、設計 doc と実装の経緯保存、git blame 不要化) | +| 78 | 💎 Tier 3 | **ADR-038 (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 層を明文化) | +| 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 件以上の同型観測を規定) | +| 83 | 🔧 Tier 2 | **cli-pr-monitor: 複合 AND guard の各条件を独立テストで検証 (PR #120 T2-1 採用)** | todo5.md | S | なし (PR #120 W-001、`enrich_with_classifier_skips_when_disabled` の test setup で複合条件分離不全) | +| 84 | 💎 Tier 3 | **グローバルルール: code-review.md に「early-return guard テスト分離」チェックリスト追記 (PR #120 T3-1 採用)** | todo5.md | XS | なし (順位 83 の知見を global rule に codify、`~/.claude/rules/common/code-review.md`、独立並列実施可) | +| 85 | 🚀 Tier 1 | **cli-pr-monitor: monitor state machine guard 強化 (`review_state: not_found && findings: []` を pending 据置) (PR #121 T1-1 採用) ★ Bundle g** | todo5.md | S | なし (PR #119/#120/#121 で 3 PR 連続観測、Frequency Medium 閾値到達済み、Severity High = 誤 approved リスク、Bundle f #80 と関連だが verdict logic 側) | +| 86 | 🔧 Tier 2 | **cli-pr-monitor: state transition test の網羅追加 (順位 85 の回帰テスト) (PR #121 T2-4 採用) ★ Bundle g** | todo5.md | S | 順位 85 と同 PR (Bundle g、`(review_state, findings) → verdict` transition matrix を表形式テストで定義、`src/cli-pr-monitor/tests/` 新規作成) | +| 87 | 💎 Tier 3 | **グローバルルール: Multi-PR chaining ベストプラクティスを codify (PR #121 T3-7 採用)** | todo5.md | XS | なし (PR #119→#120→#121 連鎖の dogfood 知見を `~/.claude/rules/common/git-workflow.md` に codify、独立並列実施可、順位 88 と同 PR で land 推奨) | +| 88 | 💎 Tier 3 | **グローバルルール: edge case 観測頻度 3 = Tier 1 昇格基準を codify (PR #121 T3-8 採用)** | todo5.md | XS | なし (post-merge-feedback workflow の暗黙ルール明文化 + ユーザー方針との収束、`~/.claude/rules/common/development-workflow.md` 等、順位 87 と同 PR で land 推奨) | +| 89 | 💎 Tier 3 | **Experimental feature 標準パターン codify (config opt-in + kill-switch + bounded lifetime) (PR #123 T3-1 採用) ★ Bundle h** | todo6.md | XS | なし (ADR-031 / 036 / 038 等の試験運用 ADR で systemic に反復、CLAUDE.md or 別 ADR で codify、順位 90 と同 PR で land 推奨) | +| 90 | 💎 Tier 3 | **グローバルルール: ephemeral 大規模コンテンツの ADR 昇格 + config コメント lifecycle (PR #123 T3-2 採用) ★ Bundle h** | todo6.md | S | 順位 89 と同 PR (Bundle h、`~/.claude/rules/common/{docs-governance,coding-style}.md` の 2 ファイル更新、PR #94 / #110 / #111 系列の lifecycle 違反予防層を強化) | +| 91 | 🔧 Tier 2 | **`[lint_screen]` config parse テスト (PR #132 T2-#4 採用) ★ Bundle i** | todo6.md | S | なし (PR #132 で追加した push-runner-config.toml の `[lint_screen]` section に対する toml::from_str テスト、CodeRabbit nitpick 起点、silent field rename 防止) | +| 92 | 🔧 Tier 2 | **scale-aware eval fixtures (200+ 行) — Phase d 投入前の必須 infrastructure (PR #132 T2-#5 採用) ★ Bundle i** | todo6.md | M | 順位 91 と同 PR 推奨 (Bundle i コア、PR #132 smoke で観測した mistral:7b 大規模 diff JSON 不完全 (`missing field 'screen_decision'`) を fixture 化、Phase d 着手前の改善 ループ reference point 確保) | +| 93 | 💎 Tier 3 | **`coding-style.md` Cross-File Reference Lifecycle に partial fix 例を追記 (PR #132 T3-#8 採用)** | todo6.md | XS | なし (PR #94 / #111 / #132 で反復した「変更差分外ファイルへの partial fix 再発」パターンを anti-pattern 例として codify、独立並列実施可) | + +**戦略**: 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)**: PR #123 (ADR-038 Phase 5: P-0 classifier opt-in + §10 ブランチ分離運用) merge 後の post-merge-feedback で 10 findings 中 **2 件採用** (Tier 3 #1, #2)。共通テーマは「ephemeral / experimental の運用パターンを global rule に codify」。**順位 89** (Tier 3 #1、Experimental feature 標準パターン = config opt-in + kill-switch + bounded lifetime) は ADR-031 / 036 / 038 で systemic 反復、本 PR が kill-switch 経路を PR body に明記した模範例から派生。**順位 90** (Tier 3 #2、ephemeral 大規模コンテンツの ADR 昇格基準 + config コメント lifecycle) は §10 (約 200 行) を ephemeral 計画書に追加した自己違反 + `pr-monitor-config.toml` のコメントが ephemeral 参照する cross-file reference lifecycle 違反の 2 観測から派生。**Sub-PR 分割不要** (Bundle h 全体で XS+S = 同 PR で land 推奨、両者とも `~/.claude/rules/common/*` および `CLAUDE.md` 系の global rule 追記で副作用最小、Adoption Risk None)。**却下** (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)**: PR #121 (ADR-038 textual fix + Bundle f registration) の dogfood で post-pr-monitor の **verdict 評価ロジック** に edge case を再観測 (PR #119/#120/#121 で計 3 PR 連続)。**4 件採用** (Tier 1 #85、Tier 2 #86、Tier 3 #87/#88) で **2 軸対策**: (1) **monitor verdict guard 層** = 順位 85 (`review_state: not_found && findings: []` を pending 据置) + 順位 86 (state transition matrix の表形式テスト)、(2) **session pattern codify 層** = 順位 87 (Multi-PR chaining ベストプラクティス) + 順位 88 (edge case 3 観測 = Tier 1 昇格基準)。**Sub-PR 分割推奨**: g-1 (順位 85 + 86、Rust 実装 + test、Effort S+S、`src/cli-pr-monitor/tests/` 新規作成) / g-2 (順位 87 + 88、global rule 追記、Effort XS+XS、独立並列可)。**Bundle f との関係**: Bundle f は retry logic (rate-limit + 投稿エラー)、Bundle g は verdict logic (review_state 評価) で別軸。両者を land すると post-pr-monitor の robustness が retry/verdict/state 全方向で堅牢化。**頻度評価**: 順位 85 は 3 PR 観測済で Tier 1 妥当性確認済、順位 86 は 85 の dependent、順位 87/88 は global rule 追記で副作用最小なので並列実施可。 + +**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 拡充、Effort S、独立) / f-3 (順位 84、global rule、Effort XS、独立)。Bundle f はローカル LLM dogfood (ADR-038) の副産物として cli-pr-monitor の堅牢化を進める位置づけで、`docs/local-llm-offload-analysis.md` §7 (実装進捗ログ) に dogfood signal として記録。 + +**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)** は placeholder N 戦略の機械的保護で OBS-3 (fragile naming convention) 対策、**順位 69 (T3 yaml/yml コメント)** は OBS-2 (spec-impl 乖離) 対策。順位 70 (code-review checklist) は Bundle e で land 済。残り順位 68 (test infra) と 順位 69 (config コメント) は scope 異なるため独立 PR 推奨。 + +**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。 diff --git a/docs/todo.md b/docs/todo.md index 907452d..2ad893d 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -2,118 +2,21 @@ > **運用ルール**: 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイル + [docs/todo2.md](todo2.md) + [docs/todo3.md](todo3.md) + [docs/todo4.md](todo4.md) + [docs/todo5.md](todo5.md) + [docs/todo6.md](todo6.md) の使い分け** (PR #83 T3-2 で恒久化、2026-04-28 強化、PR #88 で todo3.md 追加、PR #96 セッションで todo4.md 追加、PR #101 セッションで todo5.md 追加、PR #123 セッションで todo6.md 追加): -> - **docs/todo.md**: 既存タスクの編集・完了削除と推奨実行順序サマリー table の管理専用。新規タスクの**詳細エントリ**は追加しない (~50KB 閾値内に維持し Claude Code 読み取り安定性を確保)。table への新規行追加は可 (詳細エントリは現行の追加先ファイル = docs/todo6.md に記録) +> **本ファイル + [docs/todo2.md](todo2.md) + [docs/todo3.md](todo3.md) + [docs/todo4.md](todo4.md) + [docs/todo5.md](todo5.md) + [docs/todo6.md](todo6.md) + [docs/todo7.md](todo7.md) + [docs/todo-summary.md](todo-summary.md) の使い分け** (PR #83 T3-2 で恒久化、2026-04-28 強化、PR #88 で todo3.md 追加、PR #96 セッションで todo4.md 追加、PR #101 セッションで todo5.md 追加、PR #123 セッションで todo6.md 追加、2026-05-09 に todo-summary.md 切り出し + todo5.md 分割で todo7.md 追加): +> - **docs/todo-summary.md**: 推奨実行順序サマリー table 専用 (旧 todo.md から切り出し)。table の新規行追加・既存行編集・順位再採番はここで行う。 +> - **docs/todo.md**: 既存タスクの編集・完了削除専用。新規タスクの**詳細エントリ**は追加しない (~50KB 閾値内に維持し Claude Code 読み取り安定性を確保) > - **docs/todo2.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (50KB に到達したため、PR #88 以降の新規エントリは todo3.md へ) > - **docs/todo3.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (50KB に到達したため、PR #96 セッション以降の新規エントリは todo4.md へ) > - **docs/todo4.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (50KB に到達したため、PR #101 セッション以降の新規エントリは todo5.md へ) -> - **docs/todo5.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (50KB を超過したため、PR #123 セッション以降の新規エントリは todo6.md へ) +> - **docs/todo5.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (2026-05-09 に古い半分を todo7.md へ分割。PR #115 以降のエントリのみ残存。新規エントリは todo6.md へ) > - **docs/todo6.md**: 新規タスクの追加先。50KB に到達するまでは本ファイルへ追加 -> - 例外: 既存 todo.md / todo2.md / todo3.md / todo4.md / todo5.md タスクと **同一ファイル / 同一コンポーネント** を編集する密結合タスクは該当ファイルに追加可 (例: `~/.claude/rules/common/git-workflow.md` 配下のグローバルルール群) -> - **新セッションでは六つすべてを確認すること** +> - **docs/todo7.md**: 既存タスクの編集・完了削除専用 (旧 todo5.md の PR #101〜#109 エントリを 2026-05-09 に分割移動)。**新規タスクは追加しない** +> - 例外: 既存 todo.md / todo2.md 〜 todo7.md タスクと **同一ファイル / 同一コンポーネント** を編集する密結合タスクは該当ファイルに追加可 (例: `~/.claude/rules/common/git-workflow.md` 配下のグローバルルール群) +> - **新セッションでは八つすべてを確認すること** (todo.md / todo2-7.md / todo-summary.md) --- - -## 推奨実行順序サマリー (2026-04-29 更新、ADR-033 採番管理簡素化 land 後) - -開発環境の作業効率への貢献度を基準にした推奨実行順序。詳細は各タスク冒頭の **「実行優先度」** 行を参照。 - -| 順位 | Tier | タスク | ファイル | 工数 | 依存 | -|---|---|---|---|---|---| -| 1 | 🚀 Tier 1 | push 前 untracked `__*` ファイル警告 hook (PR #85 T1-4) | todo2.md | Small | なし (PR #85 直接対策) | -| 2 | 🚀 Tier 1 | `cli-push-runner` jj bookmark 未設定 early-exit (PR #85 T1-3) | todo2.md | S | なし | -| 5 | 🚀 Tier 1 | **AI 生成一時スクリプト pattern の pre-push 検出 (PR #88 T1-2)** | todo3.md | Small | 順位 1 と関連 (要擦り合わせ) | -| 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | -| 8 | 🔧 Tier 2 | 週次レビュー (ADR-031) Phase B 実装 | todo.md | 中-高 | なし (順位 20 の compensating check 前提) | -| 10 | 🔧 Tier 2 | ADR-032 PR-broken-link: broken-link-check + 内部アンカー検査 統合 | todo2.md | Small-中 | なし (clean baseline 確立済) | -| 11 | 🔧 Tier 2 | `cli-pr-monitor` プロセス正常終了の integration test (PR #85 T2-2) | todo2.md | S | なし | -| 16 | 🔧 Tier 2 | **`vitest` を devDependencies に固定 (PR #88 T2-3)** | todo3.md | Small | なし | -| 17 | 🔧 Tier 2 | **`pnpm create-pr` 必須引数ヘルプ改善 (PR #88 T2-5)** | todo3.md | Small | なし | -| 18 | 🔧 Tier 2 | **`.failed` marker への recovery 手順自己文書化 (PR #90 T2-2)** | todo3.md | S | なし | -| 19 | 🔧 Tier 2 | **takt ハーネスの `REJECT-ESCALATE` terminal verdict 実装 (PR #91 T2-2)** | todo3.md | M | post-pr-review fix loop の `.claude/` filter (Bundle T、完了済) land 後推奨 | -| 20 | 💎 Tier 3 | ADR-032 PR-β: 実装 (enabled=false default) | todo2.md | 中-高 | 6, 8, 10 | -| 21 | 💎 Tier 3 | ADR-032 PR-γ: enablement (1 行 flip) | todo2.md | XS | 順位 8 dogfood + 順位 20 | -| 22 | 💎 Tier 3 | ADR-032 PR-δ: dogfood + メトリクス検証 | todo2.md | (運用) | 順位 21 | -| 27 | 🧹 Tier 4 | ADR-030 Phase E/F: 旧機構廃止 + dogfood | todo.md | 中 | なし (cleanup) | -| 28 | ⏳ Tier 5 | (追って) ADR-030 の takt-test-vc 反映 | todo.md | 中 | 順位 27 Phase F | -| 34 | 🚀 Tier 1 | **property-based testing (proptest) 導入 — 仕様を executable contract で明文化 (PR #96 T1-flaky) ★ Bundle W** | todo4.md | M | 順位 19 land 後推奨 (PR #96 直接対策、AI が flaky 実装を書ける窓を spec 層で塞ぐ) | -| 35 | 🚀 Tier 1 | **型で意味を表現 (PastTime newtype 等) — saturating_sub 系 silent semantic mismatch を構造的に排除 (PR #96 T1-flaky) ★ Bundle W** | todo4.md | S | 順位 34 と同 PR (Bundle W、PBT が型に守られて記述しやすくなる相補関係) | -| 36 | 🔧 Tier 2 | **cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) ★ Bundle X** | todo4.md | M | Bundle W land 後推奨 (PBT properties の後付け検証層、変更 crate + 1-hop 依存 scope) | -| 37 | 🔧 Tier 2 | **pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) ★ Bundle X** | todo4.md | S | 順位 36 と同 PR (Bundle X、cli-push-runner に +~1 秒 step 追加) | -| 38 | 💎 Tier 3 | **L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky)** | todo4.md | S | ADR-031 Phase B (順位 8) と同 bundle 化推奨、long-tail flake と coverage 全体監査 | -| 39 | 🚀 Tier 1 | **takt workflow `model` フィールド必須化 lint rule (PR #98 T1-1)** | todo4.md | S | なし (Bundle Y2 完全性: post-pr-review.yaml supervise step の `model:` 欠落を契機に決定論的防止層を追加) | -| 40 | 🚀 Tier 1 | **prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2)** | todo4.md | XS | なし (本セッション再現の push 失敗を Step 1 fallback で早期検出。skill repo 側更新) | -| 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 推奨) | -| 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 実装と一体) | -| 47 | 🚀 Tier 1 | **`>` vs `>=` boundary inconsistency lint rule (PR #101 T1-2)** | todo5.md | S | なし (PR #101 直接対策、同一ファイル内 3 関数で latent drift が実証済の高頻度問題) | -| 49 | 🔧 Tier 2 | **`parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2** | todo5.md | M | 順位 42 / 43 / 46 と同 PR (Sub-PR 2、`unwrap_or_else(\|_\| empty)` silent fail 抑止 + cli-pr-monitor mock infra 流用) | -| 51 | 🚀 Tier 1 | **`.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測)** | todo5.md | M | なし (PR #103 で stale-diff false positive による wasted iter ×2 = ~10 分浪費を実観測、6-iter outlier の構造的根因対策、Bundle Z 3 層では塞げない独立改善) | -| 52 | 💎 Tier 3 | **comment-lint hook の MultiEdit 対応 (順位 50 follow-up)** | todo5.md | S | なし (順位 50 で v1 = Edit のみ実装、MultiEdit は whole-file fallback で no-regression、利用頻度低く優先度は低) | -| 56 | 🔧 Tier 2 | **comment-lint hook test 拡充 (PR #104 T2-1+T2-2 bundle)** | todo5.md | S | なし (UTF-8 multi-byte 5 パターン + block comment boundary 6 パターンを `locate_string_line_ranges` / `span_overlaps_ranges` の回帰テストとして体系化、PR #104 Critical/Minor fix の固定化) | -| 57 | 🔧 Tier 2 | **Aggregation cap integration test (PR #105 T2-1 採用)** | todo5.md | S | なし (`collect_all_violations` の MAX_VIOLATIONS contract を test 化、将来の lint 追加時に `truncate(MAX)` 削除 regression を防止する explicit 安全網) | -| 60 | 💎 Tier 3 | **analyze-session の transcript filter 絞り込み (旧 #A-3)** | todo5.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 採用)** | todo5.md | XS | なし (PR #108 で analyze-coderabbit が review body の outside diff range comment を検出漏れし line 371/378 の修正が後追い、blind spot の暫定緩和策として手動 checklist を整備) | -| 63 | 🚀 Tier 1 | **cli-merge-pipeline に Drop guard / signal handler 追加 (PR #109 T1-1 採用) ★ Bundle c** | todo5.md | M | なし (PR #109 SIGPIPE 事故で ADR-030「失敗マーカーによる recovery」仕様の構造的違反が実証、Pre-emptive marker + signal trap で abrupt 経路を多層防御) | -| 64 | 🚀 Tier 1 | **orphan run reaper (`meta.json status=running` 5-15 分放置検出 + 自動再起動) (PR #109 T1-2 採用) ★ Bundle c** | todo5.md | M | なし (順位 63 で救済不可の致命系 = kill -9 / SIGKILL / power loss / OOM の backstop、SessionStart hook または cli-pr-monitor 経路で実装) | -| 65 | 🚀 Tier 1 | **exe + `--help` を PreToolUse でブロックして src/ Read に誘導 (PR #109 T1-3 採用) ★ Bundle c** | todo5.md | S | なし (PR #109 SIGPIPE の直接トリガ = AI が `cli-merge-pipeline.exe --help` 実行 → exe は --help 未対応で merge 本体実行を構造的に防止、今後追加 exe にも自動適用) | -| 66 | 💎 Tier 3 | **長時間 subprocess の pipe truncate 禁止ルールをグローバル明文化 (PR #109 T3-1 採用) ★ Bundle c** | todo5.md | XS | なし (順位 65 = 決定論層、本ルール = 判断ガイド層、`~/.claude/rules/common/development-workflow.md` 等に追加) | -| 67 | 💎 Tier 3 | **ADR-030 に abrupt 終了時の振る舞いを spec として明記 (PR #109 T3-2 採用) ★ Bundle c** | todo5.md | XS | 順位 63 / 64 と同 PR (実装と仕様の整合性確保、L1 in-process Drop guard + L2 out-of-process reaper の責務分離 + SLA 化) | -| 68 | 🔧 Tier 2 | **`no-ephemeral-todo-reference` self-exclusion invariant 単体テスト追加 (PR #110 T2-1 採用) ★ Bundle d** | todo5.md | S | なし (PR #110 直接対策、placeholder N 戦略の machine-enforceable 保護、TP/FP/Edge 3 軸テスト) | -| 69 | 💎 Tier 3 | **`no-ephemeral-todo-reference` の `yaml`/`yml` extensions 追加理由をコメントで明記 (PR #110 T3-1 採用) ★ Bundle d** | todo5.md | XS | なし (rule⑥ コメント欄に 1-2 行追記、設計 doc と実装の経緯保存、git blame 不要化) | -| 78 | 💎 Tier 3 | **ADR-038 (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 層を明文化) | -| 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 件以上の同型観測を規定) | -| 83 | 🔧 Tier 2 | **cli-pr-monitor: 複合 AND guard の各条件を独立テストで検証 (PR #120 T2-1 採用)** | todo5.md | S | なし (PR #120 W-001、`enrich_with_classifier_skips_when_disabled` の test setup で複合条件分離不全) | -| 84 | 💎 Tier 3 | **グローバルルール: code-review.md に「early-return guard テスト分離」チェックリスト追記 (PR #120 T3-1 採用)** | todo5.md | XS | なし (順位 83 の知見を global rule に codify、`~/.claude/rules/common/code-review.md`、独立並列実施可) | -| 85 | 🚀 Tier 1 | **cli-pr-monitor: monitor state machine guard 強化 (`review_state: not_found && findings: []` を pending 据置) (PR #121 T1-1 採用) ★ Bundle g** | todo5.md | S | なし (PR #119/#120/#121 で 3 PR 連続観測、Frequency Medium 閾値到達済み、Severity High = 誤 approved リスク、Bundle f #80 と関連だが verdict logic 側) | -| 86 | 🔧 Tier 2 | **cli-pr-monitor: state transition test の網羅追加 (順位 85 の回帰テスト) (PR #121 T2-4 採用) ★ Bundle g** | todo5.md | S | 順位 85 と同 PR (Bundle g、`(review_state, findings) → verdict` transition matrix を表形式テストで定義、`src/cli-pr-monitor/tests/` 新規作成) | -| 87 | 💎 Tier 3 | **グローバルルール: Multi-PR chaining ベストプラクティスを codify (PR #121 T3-7 採用)** | todo5.md | XS | なし (PR #119→#120→#121 連鎖の dogfood 知見を `~/.claude/rules/common/git-workflow.md` に codify、独立並列実施可、順位 88 と同 PR で land 推奨) | -| 88 | 💎 Tier 3 | **グローバルルール: edge case 観測頻度 3 = Tier 1 昇格基準を codify (PR #121 T3-8 採用)** | todo5.md | XS | なし (post-merge-feedback workflow の暗黙ルール明文化 + ユーザー方針との収束、`~/.claude/rules/common/development-workflow.md` 等、順位 87 と同 PR で land 推奨) | -| 89 | 💎 Tier 3 | **Experimental feature 標準パターン codify (config opt-in + kill-switch + bounded lifetime) (PR #123 T3-1 採用) ★ Bundle h** | todo6.md | XS | なし (ADR-031 / 036 / 038 等の試験運用 ADR で systemic に反復、CLAUDE.md or 別 ADR で codify、順位 90 と同 PR で land 推奨) | -| 90 | 💎 Tier 3 | **グローバルルール: ephemeral 大規模コンテンツの ADR 昇格 + config コメント lifecycle (PR #123 T3-2 採用) ★ Bundle h** | todo6.md | S | 順位 89 と同 PR (Bundle h、`~/.claude/rules/common/{docs-governance,coding-style}.md` の 2 ファイル更新、PR #94 / #110 / #111 系列の lifecycle 違反予防層を強化) | - -**戦略**: 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)**: PR #123 (ADR-038 Phase 5: P-0 classifier opt-in + §10 ブランチ分離運用) merge 後の post-merge-feedback で 10 findings 中 **2 件採用** (Tier 3 #1, #2)。共通テーマは「ephemeral / experimental の運用パターンを global rule に codify」。**順位 89** (Tier 3 #1、Experimental feature 標準パターン = config opt-in + kill-switch + bounded lifetime) は ADR-031 / 036 / 038 で systemic 反復、本 PR が kill-switch 経路を PR body に明記した模範例から派生。**順位 90** (Tier 3 #2、ephemeral 大規模コンテンツの ADR 昇格基準 + config コメント lifecycle) は §10 (約 200 行) を ephemeral 計画書に追加した自己違反 + `pr-monitor-config.toml` のコメントが ephemeral 参照する cross-file reference lifecycle 違反の 2 観測から派生。**Sub-PR 分割不要** (Bundle h 全体で XS+S = 同 PR で land 推奨、両者とも `~/.claude/rules/common/*` および `CLAUDE.md` 系の global rule 追記で副作用最小、Adoption Risk None)。**却下** (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)**: PR #121 (ADR-038 textual fix + Bundle f registration) の dogfood で post-pr-monitor の **verdict 評価ロジック** に edge case を再観測 (PR #119/#120/#121 で計 3 PR 連続)。**4 件採用** (Tier 1 #85、Tier 2 #86、Tier 3 #87/#88) で **2 軸対策**: (1) **monitor verdict guard 層** = 順位 85 (`review_state: not_found && findings: []` を pending 据置) + 順位 86 (state transition matrix の表形式テスト)、(2) **session pattern codify 層** = 順位 87 (Multi-PR chaining ベストプラクティス) + 順位 88 (edge case 3 観測 = Tier 1 昇格基準)。**Sub-PR 分割推奨**: g-1 (順位 85 + 86、Rust 実装 + test、Effort S+S、`src/cli-pr-monitor/tests/` 新規作成) / g-2 (順位 87 + 88、global rule 追記、Effort XS+XS、独立並列可)。**Bundle f との関係**: Bundle f は retry logic (rate-limit + 投稿エラー)、Bundle g は verdict logic (review_state 評価) で別軸。両者を land すると post-pr-monitor の robustness が retry/verdict/state 全方向で堅牢化。**頻度評価**: 順位 85 は 3 PR 観測済で Tier 1 妥当性確認済、順位 86 は 85 の dependent、順位 87/88 は global rule 追記で副作用最小なので並列実施可。 - -**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 拡充、Effort S、独立) / f-3 (順位 84、global rule、Effort XS、独立)。Bundle f はローカル LLM dogfood (ADR-038) の副産物として cli-pr-monitor の堅牢化を進める位置づけで、`docs/local-llm-offload-analysis.md` §7 (実装進捗ログ) に dogfood signal として記録。 - -**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)** は placeholder N 戦略の機械的保護で OBS-3 (fragile naming convention) 対策、**順位 69 (T3 yaml/yml コメント)** は OBS-2 (spec-impl 乖離) 対策。順位 70 (code-review checklist) は Bundle e で land 済。残り順位 68 (test infra) と 順位 69 (config コメント) は scope 異なるため独立 PR 推奨。 - -**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。 +> **推奨実行順序サマリー**: [`docs/todo-summary.md`](todo-summary.md#recommended-order-summary) を参照。 --- diff --git a/docs/todo2.md b/docs/todo2.md index 8b919fc..6b2c169 100644 --- a/docs/todo2.md +++ b/docs/todo2.md @@ -4,7 +4,7 @@ > > **本ファイルの位置付け**: docs/todo.md がファイルサイズ約 40KB に達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する。todo.md の既存エントリは引き続き有効、相互に独立。新セッションでは両方を確認すること。 > -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo.md](todo.md#recommended-order-summary) を参照。本ファイルに記録する ADR-032 は sub-phase ごとに Tier が分散するため、各 Phase の冒頭に個別の優先度を記載。 +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。本ファイルに記録する ADR-032 は sub-phase ごとに Tier が分散するため、各 Phase の冒頭に個別の優先度を記載。 --- diff --git a/docs/todo3.md b/docs/todo3.md index 495a017..747e217 100644 --- a/docs/todo3.md +++ b/docs/todo3.md @@ -4,7 +4,7 @@ > > **本ファイルの位置付け**: docs/todo2.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #88 以降の新規エントリは本ファイルに記録した。本ファイルも PR #96 セッションで 50KB 接近のため、それ以降の新規エントリは [docs/todo4.md](todo4.md) へ。todo.md / todo2.md / todo3.md / todo4.md の既存エントリは引き続き有効、相互に独立。新セッションでは四つすべてを確認すること。 > -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo.md](todo.md#recommended-order-summary) を参照。 +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 --- diff --git a/docs/todo4.md b/docs/todo4.md index e5d0a0e..846e2c3 100644 --- a/docs/todo4.md +++ b/docs/todo4.md @@ -4,7 +4,7 @@ > > **本ファイルの位置付け**: docs/todo3.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録していた。**本ファイルも 50KB に到達したため、PR #101 セッション以降の新規エントリは [docs/todo5.md](todo5.md) へ**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md / todo3.md / todo5.md の既存エントリは引き続き有効、相互に独立。新セッションでは五つすべてを確認すること。 > -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo.md](todo.md#recommended-order-summary) を参照。 +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 --- diff --git a/docs/todo5.md b/docs/todo5.md index e41c579..b291207 100644 --- a/docs/todo5.md +++ b/docs/todo5.md @@ -2,579 +2,14 @@ > **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイルの位置付け**: docs/todo4.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する。todo.md / todo2.md / todo3.md / todo4.md の既存エントリは引き続き有効、相互に独立。新セッションでは五つすべてを確認すること。 +> **本ファイルの位置付け**: docs/todo4.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #101 セッション以降の新規エントリは本ファイルに記録していた。**本ファイルも 67KB に到達したため、2026-05-09 に PR #101〜#109 由来の古い半分を [docs/todo7.md](todo7.md) へ分離した**。本ファイル残存は PR #110 以降のエントリのみ。新規エントリは [docs/todo6.md](todo6.md) へ。todo.md / todo2.md / todo3.md / todo4.md / todo6.md / todo7.md の既存エントリは引き続き有効、相互に独立。新セッションでは七つすべてを確認すること。 > -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo.md](todo.md#recommended-order-summary) を参照。 +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 --- ## 現在進行中 -### `>` vs `>=` boundary inconsistency lint rule (PR #101 T1-2) - -> **動機**: PR #101 で `parse_listed_findings` の `created_at > push_time` が CodeRabbit から境界 inclusive (`>=`) への揃え修正を指摘された。auto-fix が同一ファイル内 `parse_new_comments` / `parse_findings` にも `>=` を適用 (= 3 関数 latent drift)。`parse_rate_limit` だけが既に `>=` で、後続関数を書くたびに著者が意識せず `>` を選ぶ構造的問題。custom-lint-rule で書いた瞬間に block すれば bug class が排除される。 -> -> **本タスクの位置づけ**: PR #101 post-merge-feedback Tier 1 #2 採用 (高頻度 finding)。Bundle Z #B-α (Rust comment lint hook) と同じ「決定論的防止層」哲学。AST 解析ではなく正規表現層 (ADR-007) で対応可能。 -> -> **参照**: `.claude/feedback-reports/101.md` Tier 1 #2、ADR-007 (custom lint rule の正規表現 / AST 層線引き)、CodeRabbit PR #101 round 1 Minor finding -> -> **実行優先度**: 🚀 **Tier 1** — Effort S。`.claude/custom-lint-rules.toml` への regex rule 追加。 - -#### 設計決定 (案) - -- **配置先**: `.claude/custom-lint-rules.toml` に新規 rule entry -- **検出パターン (正規表現案)**: - - 狭め: `\.(created_at|submitted_at|updated_at)\b.*\.map\(\|\w+\|\s*\w+\s*[><](?!=)\s*(push_time|since)` - - 広め: `\b(created_at|submitted_at|updated_at|comment_event_time|event_time)\b.*[><](?!=)` で時刻フィールドの strict inequality 全般を flag -- **適用対象**: `.rs` ファイル -- **rule 名 (案)**: `time-boundary-strict-inequality` -- **suppress マーカー**: `// SAFETY: <理由>` 行末付与で suppression (例: 意図的に exclusive 比較する場合) - -#### 作業計画 - -- [ ] 既存 `.claude/custom-lint-rules.toml` の rule 構造を確認 -- [ ] regex + path filter を新 rule として記述 -- [ ] PostToolUse hook の lint runner で synthetic test (修正前 `parse_findings` 系の `>` パターンを再現してマッチ確認) -- [ ] 既存 codebase で false positive 影響範囲をグレップして確認 -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 確認 -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- `.claude/custom-lint-rules.toml` に新 rule が追加され `.rs` ファイル内の時刻フィールド strict inequality を検出 -- 1〜2 PR で dogfood し false positive がないこと - -#### 詰まっている箇所 - -- false positive の評価 (時刻フィールド以外で legitimate な `>` が誤 block されないか)。着手時に実 codebase でグレップして影響範囲を確認。 - ---- - -### `parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2 - -> **動機**: PR #101 で `run_list_findings` が `unwrap_or_else(|_| "[]")` で gh api 失敗を `[]` に潰していて CR Major finding を受けた。99.md でも `silent fail` (Windows path mismatch で early return) として類似言及あり。**`unwrap_or_else(|_| empty)` の anti-pattern が複数 PR で再発**。test 層で機械検証することで未然に塞ぐ。本タスクは Bundle a Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) で同 API を消費するので、同一 PR land で test 二重投資なし。 -> -> **本タスクの位置づけ**: PR #101 post-merge-feedback Tier 2 #1 採用 (高頻度 anti-pattern finding)。Bundle a Sub-PR 2 (順位 42 / 43 / 46) と同 PR で land 推奨。CLAUDE.md `coding-style.md` "Never silently swallow errors" 原則の test 層実装。 -> -> **参照**: `.claude/feedback-reports/101.md` Tier 2 #1、`.claude/feedback-reports/99.md`、`~/.claude/rules/common/coding-style.md` "Never silently swallow errors" -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。新 test ファイル + gh API モック。Sub-PR 2 と一体実装。 - -#### 設計決定 (案) - -- **配置先**: `src/check-ci-coderabbit/tests/parse_error_handling_test.rs` (integration test、既存 unit test と分離) -- **テスト対象シナリオ**: - - **gh API HTTP error 返却時**: `run_list_findings` がエラーを propagate するか verify (現状 PR #101 fix で `.map_err(...)?` 化済 → regression 防止) - - **JSON 不正形式入力**: `serde_json::from_str` 失敗時の挙動 (現状 `unwrap_or_else(|e| { eprintln!(...); vec![] })` で warn は出すが空配列返却 = silent fall) — 望ましい設計を test で固定 - - **空 JSON `[]`**: 正常 path (空 findings 返却) の境界条件 -- **モック戦略**: - - gh API 直接モックは不要 (parse 関数は JSON string を受け取る純関数) - - `run_gh` を trait 化して mock injection or `mockito` HTTP mock — Sub-PR 2 の cli-pr-monitor 実装方針と整合 -- **既存 unit test との関係**: 既存 16 件は normal path 中心。本 task は error path 専用 - -#### 作業計画 - -- [ ] `src/check-ci-coderabbit/tests/` ディレクトリ作成 (現在 unit test only) -- [ ] gh API モック戦略の選定 (trait injection or shell wrapper stub) — Sub-PR 2 の cli-pr-monitor 実装方針と整合 -- [ ] error-path シナリオ 3 件 (HTTP error / 不正 JSON / 空 JSON) を実装 -- [ ] `cargo test --workspace` で pass 確認 -- [ ] dogfood: 実 PR で `unwrap_or_else(|_| empty)` を一時的に書き戻して test が fail するか sensitivity 検証 -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- `parse_listed_findings` / `parse_findings` の error-path 3 シナリオ test が pass -- `unwrap_or_else(|_| empty)` の silent fallback パターンが test で fail 検出される -- Sub-PR 2 の cli-pr-monitor 実装で同 mock infrastructure を流用できる - -#### 詰まっている箇所 - -- gh API モック戦略の選定: HTTP mock library `mockito` vs `run_gh` の trait injection — 単純さ優先なら後者、real API 結合に近づけたいなら前者。 -- `eprintln!` (stderr) を assert する仕組みが Rust 標準にないため、`gag::BufferRedirect` や custom logger 注入が必要 — 着手時に評価。 - ---- - -### `.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測) - -> **動機**: PR #103 push の実観測で takt pre-push-review が **6-iter outlier (22m 50s)** を発生させ、うち iter 3+4 の ~10 分が wasted。原因は `.takt/review-diff.txt` が push-runner 起動時 snapshot として固定され、fix step の変更が反映されないこと。reviewer は古い diff を読んで「fix されていない」と機械的 false positive (`persists`) を出し、max iter まで escalate して supervise の live Read で打開する以外に経路がない。supervisor 自身が "structural limit" として診断済 (`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md`)。 -> -> **本タスクの位置づけ**: PR #103 セッション知見 (post-merge-feedback の Tier 3 #1 = ADR 化提案を skip し、機構で塞ぐ実装層対策を採用)。Bundle Z 3 層 (#B-α / #B-β / #B-γ) では完全に塞げない独立改善。reviewer の判定精度を構造的に改善することで 6-iter outlier の発生率を 0% 近くに抑える。 -> -> **参照**: `.claude/feedback-reports/103.md` (Tier 3 #1 で同根因に別アプローチ提案、本 task で代替)、`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md` (false positive 構造診断)、[ADR-036: Bundle Z 3 層アーキテクチャ](../docs/adr/adr-036-bundle-z-three-layer-review.md) (PR #97 ベースライン observation を含む、本 task は Bundle Z 3 層では塞げない独立改善) -> -> **実行優先度**: 🚀 **Tier 1** — Effort M。takt 設定 / pre-push-review.yaml への hook 追加。 - -#### 設計決定 (案) - -- **refresh タイミング**: reviewer step 起動直前に diff を再生成 (fix step 完了直後の状態を反映) -- **実装方針 (2 案)**: - - **案 A: takt workflow の reviewer step に precondition step を挟む** — `.takt/workflows/pre-push-review.yaml` で `before:` / `pre-step:` 的な hook を使い、push-runner と同一の diff 生成コマンドを呼ぶ - - **案 B: cli-push-runner 側で fix step の終了を検出して diff を更新** — Rust コードで takt の step 進行を監視 (実装複雑度大) -- **推奨**: 案 A — takt config で完結、Rust 修正不要、影響範囲が pre-push-review.yaml のみ -- **diff 生成コマンド**: 既存 push-runner と同じロジック (`jj diff` ベース) を再利用、ファイルパス `.takt/review-diff.txt` も同一に保つ -- **冪等性**: 同 fix output から生成される diff は決定的なので複数回 refresh しても問題なし。途中失敗で diff が壊れても次 iteration の冒頭で上書きされる - -#### 作業計画 - -- [ ] takt workflow の hook 仕様 (`before:` / `pre-step:`) を確認 (`.takt/workflows/*.yaml` の他 facets / takt source を grep) -- [ ] case A 不可なら case B (cli-push-runner 改修) にフォールバック -- [ ] `.takt/review-diff.txt` の生成ロジックを単一場所に整理 (DRY、push-runner と shared util にする等) -- [ ] `.takt/workflows/pre-push-review.yaml` に refresh hook を追加 -- [ ] 単体動作確認: 意図的に DRY refactor 指摘 + fix を再現する synthetic シナリオで 3-iter 収束を確認 -- [ ] dogfood 1〜2 PR で実 6-iter outlier scenario が再発しないことを観測 -- [ ] Bundle Z Phase 2 (#B-β) との競合確認 (deterministic check は fix step 内部で動くため、本 task の fix→review 境界 refresh とは独立) -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 確認 -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- fix step 完了後の review iteration で `.takt/review-diff.txt` が最新状態を反映 -- 6-iter outlier の発生率が **0%** に近づく (PR #103 のような scenario が 3-iter で収束) -- supervisor の live Read 救済が不要になる (= supervisor step は workflow に残るが、false positive 救済責務が消える) - -#### 詰まっている箇所 - -- takt workflow の `before:` / `pre-step:` hook 仕様が公式 docs に明記されていない可能性 → 着手時に takt source / 既存 workflow yaml を grep して確認。 - ---- - -### comment-lint hook の MultiEdit 対応 (順位 50 follow-up) - -> **動機**: 順位 50 で comment-lint hook の scope を変更行に限定する v1 実装を完了した。v1 は Edit (single new_string) のみフィルタ対象とし、MultiEdit は whole-file lint にフォールバックする (no-regression)。MultiEdit が頻繁に使われる場合、複数 edit の `edits[].new_string` を順次適用して累積 range を計算する拡張が望ましい。 -> -> **本タスクの位置づけ**: 順位 50 follow-up。MultiEdit 利用頻度が低いため優先度は Tier 3。MultiEdit 由来の 12.6KB 出力が無視できない頻度になった場合、または Bundle Z Phase 3 (#B-γ) で MultiEdit ベースの大規模リファクタが日常化した場合に着手。 -> -> **参照**: 順位 50 PR (`src/hooks-post-tool-comment-lint-rust/src/main.rs` の `compute_changed_lines`)、Claude Code MultiEdit tool spec -> -> **実行優先度**: 💎 **Tier 3** — Effort S。`compute_changed_lines` に MultiEdit branch を追加。 - -#### 設計決定 (案) - -- **MultiEdit input schema**: `tool_input.edits: Vec<{old_string, new_string, replace_all?}>` を順次適用 -- **行 range 計算**: 各 edit の `new_string` を post-edit source 内で全件検索 → 全 edit の match 行 range の union を filter として使用 -- **空 new_string の扱い**: 個別の edit が純削除の場合、その edit はスキップ。全 edit が純削除なら filter は空 = lint skip -- **fallback 条件**: ある edit の `new_string` が見つからない場合 → 安全側に倒し whole-file lint (現 Edit 実装と同じ動作) - -#### 作業計画 - -- [ ] `ToolInput` struct に `edits: Option>` を追加 -- [ ] `compute_changed_lines` に `Some("MultiEdit")` branch を追加 (各 edit の new_string を locate して union) -- [ ] 単体テスト: 複数 edit の union が正しく計算されることを確認 -- [ ] 単体テスト: 一部 edit が純削除の場合の挙動確認 -- [ ] dogfood: MultiEdit を使った PR で hook 出力が変更行のみに絞られることを確認 -- [ ] 派生プロジェクト deploy -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- MultiEdit でも変更行外の pre-existing violations が flag されない -- v1 (Edit) の挙動は不変 -- Phase 3 (#B-γ) で reviewer の役割が「異常検知」に縮小されると本 task の効果も部分的に縮む可能性 (criterion-based finding がそもそも reviewer から消えるため)。ただし Phase 3 完了前の中間期間 + Phase 3 後も「異常検知」自体は diff を読むので効果は残る。 - ---- - - -### comment-lint hook test 拡充 (PR #104 T2-1+T2-2 bundle) - -> **動機**: PR #104 で CodeRabbit Critical (UTF-8 byte boundary) + Minor (multi-line block comment boundary) の 2 件を auto-fix で解消したが、いずれも回帰防止テストは 1 パターンのみで脆い。tree-sitter / Rust version 更新で区間交差判定や UTF-8 境界処理が壊れた場合に検出できないリスク。 -> -> **本タスクの位置づけ**: PR #104 post-merge-feedback Tier 2-1 / Tier 2-2 の bundle。コスト低 (S effort)、test additions のみで scope clean、PR #104 の fix を体系的に固定化する。 -> -> **参照**: `.claude/feedback-reports/104.md` Tier 2 #1, #2、PR #104 (`src/hooks-post-tool-comment-lint-rust/src/main.rs` の `locate_string_line_ranges` / `span_overlaps_ranges`) -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。Bundle b と独立、いつでも単独着手可。 - -#### 設計決定 (案) - -- **UTF-8 multi-byte test 拡充** (T2-1): - - 現状: `locate_string_line_ranges_handles_multibyte_utf8` 1 パターン - - 追加 5 パターン: 漢字 + ASCII 混合 / 漢字単独 / emoji / BMP 外文字 (例: 𝕊) / 結合文字 (例: é = e + ́) - - 各パターンで `search_start = (absolute + needle.len()).min(source.len())` の境界処理を検証 -- **Block comment boundary matrix 拡充** (T2-2): - - 現状: `find_violations_multiline_block_comment_spanning_range_boundary` 1 パターン - - 追加 6 パターン: {開始行のみ被覆, 終了行のみ被覆, 内部完全包含} × {単行 block comment, 複数行 block comment} - - `span_overlaps_ranges(start, end, ranges)` の区間交差判定を体系化 - -#### 作業計画 - -- [ ] UTF-8 multi-byte test 5 パターン追加 -- [ ] Block comment boundary test 6 パターン追加 -- [ ] 既存 1 パターンずつのテストは保持 (regression 防止のため削除しない) -- [ ] 派生プロジェクト deploy は不要 (test のみのため) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- UTF-8 multi-byte test が 6 パターン以上 -- Block comment boundary test が 7 パターン以上 -- `cargo test -p hooks-post-tool-comment-lint-rust` 全 pass - -#### 詰まっている箇所 - -- 結合文字 (`e + ́`) を `new_string` に含むケースは Edit tool が実環境で発生するか不明 (理論的検証としては有効、実際の回帰防止としては効果薄の可能性)。1 パターンで足る - ---- - -### Aggregation cap integration test (PR #105 T2-1 採用) - -> **動機**: PR #105 の auto-fix で `collect_all_violations` に `violations.truncate(MAX_VIOLATIONS)` を追加した (CodeRabbit Minor finding 解消) が、これは contract の暗黙化に過ぎない。将来 `find_xxx_violations` を追加する PR で `extend()` の後に `truncate` を入れ忘れる regression を構造的に防ぐ test がない。 -> -> **本タスクの位置づけ**: PR #105 post-merge-feedback Tier 2 #1 採用。後続の lint 追加 (例: 順位 56 の test 拡充 / 順位 47 の `>=` boundary lint / 将来の Rust 専用 lint) で同 contract を破る regression を test で固定化する。 -> -> **参照**: `.claude/feedback-reports/105.md` Tier 2 #1、`src/hooks-post-tool-comment-lint-rust/src/main.rs` `collect_all_violations` (line 545)、PR #105 Finding #2 (Minor) の auto-fix -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。test 1-2 件追加で完結。 - -#### 設計決定 (案) - -- **シナリオ**: `collect_all_violations(file_path, source_with_15_comments_and_15_long_functions, None)` を呼び、結果が **MAX_VIOLATIONS (= 20) 以下** であることを assert -- **source 構築**: - - 15 個の禁止コメント (`// forbidden 0` 〜 `// forbidden 14`) - - 15 個の 60 行関数 (`fn big_0` 〜 `fn big_14`) - - 合計 30 件の violation 候補 → cap で 20 件に truncate -- **test 名**: `collect_all_violations_truncates_to_max_violations` (spec を test 名に反映、PR #105 T2-3 提案は卻下したが naming-as-spec 自体は意義あり) -- **追加検証** (任意): 個別 `find_violations` / `find_function_length_violations` がそれぞれ 20 件以上返しうることも assert (truncate なしだと 30 件返ることを示す) - -#### 作業計画 - -- [ ] 30 件の violation 候補を含む synthetic source を生成する helper 関数を test module に追加 -- [ ] `collect_all_violations_truncates_to_max_violations` test を追加 -- [ ] 個別 finder の non-truncate 挙動を assert する補助 test を追加 -- [ ] cargo test pass 確認 -- [ ] 派生プロジェクト deploy は不要 (test のみ) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- 結合後の violation 件数が `MAX_VIOLATIONS` 以下であることが test で固定化 -- 将来 `find_xxx_violations` を追加した PR で truncate 削除すると test fail で検出される - -#### 詰まっている箇所 - -- 順位 56 (PR #104 T2-1+T2-2 test 拡充) と同 PR で bundle するか別 PR とするか。両者とも test additions、同ファイル同 test module で scope clean、bundle 推奨。 - ---- - -### analyze-session の transcript filter 絞り込み (旧 #A-3) - -> **動機**: `cli-merge-pipeline` が生成する `.takt/post-merge-feedback-transcript.jsonl` は **session 全履歴** を含むため、analyze-session step が読み込む input token が大きい。当該 PR に直接関連する範囲のみ filter すれば input token 削減 = post-merge-feedback の cache_read 削減。 -> -> **本タスクの位置づけ**: 旧 `docs/pipeline-token-efficiency.md` の #A-3 entry。同計画書は ADR-036 (Bundle Z 3 層) / ADR-037 (fix-trust shortcut) に主要決定を移し終了予定で、残作業として本 task のみ todo に移管。Bundle 化対象なし、独立 PR 推奨。 -> -> **参照**: (削除済) `docs/pipeline-token-efficiency.md` #A-3 セクション、`src/cli-merge-pipeline/` の transcript 生成ロジック -> -> **実行優先度**: 💎 **Tier 3** — Effort M。ROI ★★★ で優先度中程度、dogfood 実測が必要。 - -#### 設計決定 (案) - -- **filter 範囲**: 当該 PR の作成 commit (= cli-pr-monitor が PR を最初に検出した時刻、または `pnpm create-pr` 完了時刻) から merge 完了時刻までの jsonl 行のみ -- **時刻判定**: jsonl の `timestamp` field を使用 (各エントリに ISO 8601 形式で記録あり) -- **境界の扱い**: - - 開始時刻 *以降*: PR 作業中の Claude 対話 + tool 実行履歴 - - 終了時刻 *まで*: merge 完了 (= post-merge-feedback 起動の直前まで) - - 境界外 (PR 作成前 / merge 後): 除外 -- **既存挙動との互換**: 開始時刻取得失敗時 (state file なし等) は全 session フォールバック (no-regression) - -#### 作業計画 - -- [ ] `cli-merge-pipeline` の transcript 生成ロジックを特定 -- [ ] PR 作成時刻 / merge 時刻の取得経路を確定 (`.claude/cli-pr-monitor-state.json` or `gh pr view --json mergedAt` 等) -- [ ] timestamp 比較で jsonl 行を filter する logic を実装 -- [ ] 開始時刻取得失敗時のフォールバック (全 session) を保持 -- [ ] dogfood 1-2 PR で input token 削減量を実測 (analyze-session の billable input tokens で比較) -- [ ] 削減効果が想定 30-50% に届くか確認、届かない場合は filter 設計を見直し -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- analyze-session の input token が PR 作業範囲のみに絞り込まれる -- dogfood で 30-50% 削減を実測 (削減未達なら filter 設計を見直し) -- 開始時刻取得失敗時のフォールバックが機能 (regression なし) - -#### 詰まっている箇所 - -- 「PR 作成前の議論 (設計判断、却下されたアイデア)」が落ちる可能性 → post-merge-feedback の知見質に影響しうる。dogfood で「重要 finding が拾えなくなった」事象が出たら filter 範囲を広げる (例: PR 作成 commit から 2 時間前まで遡る等) -- transcript jsonl の structure 変更時に filter logic が壊れる risk → field name (`timestamp`) を assert する unit test を追加 - ---- - -### post-PR 検証フローに CR review.body 手動スキャン step 追加 (PR #108 T2-1 採用) - -> **動機**: 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 拡張 (= 将来の根本解決) の先行策として機能する。 -> -> **参照**: `.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` -> -> **実行優先度**: 🔧 **Tier 2** — Effort XS。post-PR checklist documentation の更新のみ。 - -#### 設計決定 (案) - -- **配置先候補**: - - `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 で頻度が高ければ昇格) - -#### 作業計画 - -- [ ] `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 固有) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- post-PR workflow に「CR review.body 手動スキャン」step が追記される -- 次 1-2 PR の dogfood で本 checklist の実行が観察される -- review body 内の actionable finding が後追い修正にならない (= merge 前に検出される) - -#### 詰まっている箇所 - -- 配置先選定 (本リポジトリ docs/workflow.md vs グローバル `~/.claude/rules/`)。本タスクは本リポジトリ固有の暫定緩和策のため、本リポジトリ docs/ への追記が妥当か -- 手動 checklist は持続性が低い (人間が忘れる) ため、Tier 1 への昇格 (= analyzer 拡張) の優先度判断が dogfood 結果に依存 - ---- - -### cli-merge-pipeline に Drop guard / signal handler を追加し abrupt 終了時に `.failed` marker を保証 (PR #109 T1-1 採用) ★ Bundle c - -> **動機**: PR #109 merge 直後の post-merge-feedback workflow が SIGPIPE で silent 中断され、`.takt/runs/.../reports/` が空 + `.claude/feedback-reports/109.md` 未生成 + `.failed` marker も無いという fail mode が実証された。原因は `feedback::run()` が `Result::Err` を返した場合のみ `write_failed_marker` を書く実装で、Rust default の SIGPIPE 動作 (parent process abrupt 終了) では Result::Err 経路に到達しない。ADR-030「失敗マーカーによる recovery」仕様を構造的に違反。 -> -> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の中核。Drop guard で `Result::Err` 経路に依存しない unconditional marker 書き出しを保証する。Pre-emptive marker (案 C) と signal trap (案 A) の組み合わせで abrupt 経路を多層防御。 -> -> **参照**: `.claude/feedback-reports/109.md` Tier 1 #1、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md)、`src/cli-merge-pipeline/src/feedback.rs:454-475` (`copy_feedback_report`) / `:1100-1180` (`run`) / `main.rs:555` (caller) -> -> **実行優先度**: 🚀 **Tier 1 Critical** — Effort M。仕様 (ADR-030) と実装の根本ギャップ閉鎖。 - -#### 設計決定 (案) - -- **修正方針**: Explore agent が提示した 3 案 (A: signal trap + Drop guard / B: thread + parent timeout / C: pre-emptive marker) のうち、**A + C の組み合わせ** を採用 (agent 推奨) - - **C (pre-emptive marker)**: `feedback::run` 呼び出し前に `.failed` marker を先制書き込み、正常完了時のみ削除。abrupt 終了の 99% を救済 (Effort XS-S) - - **A (signal trap + Drop guard)**: `tokio::signal` または `nix` crate で SIGPIPE/SIGTERM を trap、RAII Drop guard で marker 書き込みを保証。panic 経路もカバー (Effort M) -- **race 対策**: 同 PR で concurrent merge が走った場合の race は既存 `CONCURRENT_RUN_GUARD_SECS=1500s` で予防されるが、pre-emptive marker の lifecycle と整合性確認が必要 -- **OS 互換性**: signal handling は OS 依存。Windows では SIGPIPE 相当が無いため Ctrl+C / SIGTERM 経路を中心に対応。Unix と Windows のコードパス分岐は cfg gate で実装 - -#### 作業計画 - -- [ ] `src/cli-merge-pipeline/src/feedback.rs` に pre-emptive marker 書き出しを追加 (`run` 冒頭で `write_failed_marker(reason: "pending")`) -- [ ] 正常完了時に marker を削除する path を追加 (`copy_feedback_report` 成功後) -- [ ] `nix` または `tokio::signal` で SIGPIPE/SIGTERM trap を実装 (Unix) + Windows 用 cfg 分岐 -- [ ] RAII Drop guard 構造体を導入し、scope 終了時に marker 書き込みを保証 (正常時 `disarm()` で skip) -- [ ] 既存 `Result::Err` 経路の `write_failed_marker` 呼び出しは維持 (二重書きにならないよう pre-emptive marker と統合) -- [ ] dogfood: 本機能を有効にした状態で `cli-merge-pipeline.exe \| head -40` を実行し marker が残ることを確認 (今回事故の再現テスト) -- [ ] 派生プロジェクトに deploy (cli-merge-pipeline.exe を再ビルド + 配布) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- SIGPIPE / SIGTERM / panic / Result::Err いずれの経路でも `.claude/feedback-reports/.md.failed` が必ず残る -- 正常完了時には `.failed` marker が残らない (false positive ゼロ) -- 今回の事故 (PR #109 SIGPIPE) を再現するテストで pass -- 派生プロジェクト (`techbook-ledger` / `auto-review-fix-vc`) でも同等動作 - -#### 詰まっている箇所 - -- Windows での SIGPIPE 相当の挙動: Rust std はデフォルト SIGPIPE handler を install するが、Windows では pipe broken 時の挙動が異なる (CTRL_BREAK / I/O error)。整合性確保のため OS 別の signal mapping 設計が必要 -- 順位 64 (orphan reaper) との責務分離: Drop guard は process 内、reaper は process 外。両者の trigger 条件が重複しないよう設計 - ---- - -### orphan run reaper (post-merge-feedback の `meta.json status=running` 放置検出 + 自動再起動) (PR #109 T1-2 採用) ★ Bundle c - -> **動機**: 順位 63 (Drop guard) では救済できない致命系 (kill -9 / SIGKILL / power loss / OOM Killer) で post-merge-feedback workflow が中断された場合、`.failed` marker も書かれず orphan run のみが残る。仕様 (= フィードバックは必ず実行) を保証するには process 外からの監視層が必要。 -> -> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の第二防衛層。Drop guard (順位 63) を内側、reaper を外側とする多層防御で「フィードバックは必ず実行する」仕様を multi-layer で保証。 -> -> **参照**: `.claude/feedback-reports/109.md` Tier 1 #2、[ADR-029](adr/adr-029-post-merge-feedback-auto-trigger.md) (pending file 経由の再起動)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) -> -> **実行優先度**: 🚀 **Tier 1 Critical** — Effort M。順位 63 と組み合わせて致命系 hole を塞ぐ。 - -#### 設計決定 (案) - -- **配置先候補** (着手時に決定): - - **案 A**: `cli-pr-monitor` 起動時に `.takt/runs/*/meta.json` を scan (既存 monitor 機構との整合性高い) - - **案 B**: SessionStart hook (`src/hooks-session-start*/`) で scan (Claude Code session 起動毎に走る確定的 trigger) - - 推奨: **案 B** (SessionStart) — cli-pr-monitor は backend daemon 廃止 (ADR-018) で takt 経由になっており trigger 機構が複雑、SessionStart は単純で確実 -- **検出条件**: - - `.takt/runs/*/meta.json` の `status: "running"` かつ `startTime` が現時刻から **5 分以上経過** - - `currentStep` が `analyze` のまま (= 1 step も完了していない極短時間で死んだケース) も含める -- **recovery 動作**: - - 検出した orphan run の `meta.json` を `status: "failed"` に更新 (アトミックに) - - `.claude/feedback-reports/.md.failed` marker を書く (PR 番号は run slug `post-merge-feedback-for-` から抽出) - - ADR-029 pending file (`.claude/post-merge-feedback-pending.json`) を生成し、UserPromptSubmit hook で再起動 trigger -- **冪等性**: 同 orphan を 2 回検出しても重複 trigger しないよう既存 marker / pending file を check - -#### 作業計画 - -- [ ] 配置先 (案 A / B) を grep + `.claude/hooks-config.toml` 確認のうえ決定 -- [ ] `meta.json` parser + 5 分閾値判定ロジック実装 -- [ ] `.failed` marker 書き出し + pending file 生成ロジック実装 -- [ ] 冪等性 guard (既存 marker / pending file 検出時の skip) -- [ ] integration test: 人為的に orphan meta.json を作成して reaper が再起動 trigger することを assert -- [ ] dogfood: 既存の orphan (`.takt/runs/20260504-101353-post-merge-feedback-for-109/`) を fixture として retroactive detection 確認 -- [ ] 派生プロジェクトに deploy -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- kill -9 / power loss シミュレート (forcibly kill) で `.failed` marker と pending file が遅延生成される -- Drop guard (順位 63) が機能している正常 case では reaper が誤検出しない (false positive ゼロ) -- 既存 orphan (PR #109 のもの) を retroactive に処理できる -- 仕様レベル: 「post-merge-feedback はマージ後 5 分以内に必ず完了 or 失敗 marker 化される」が AppCenter 級の SLA で保証される - -#### 詰まっている箇所 - -- SessionStart hook の発火頻度: 1 session 1 回しか走らないと、長時間 session 中に orphan が発生しても拾えない。`cli-pr-monitor` 経路と組み合わせるか、SessionStart + UserPromptSubmit の二段階検出が必要か検討 -- 5 分閾値の妥当性: takt の analyze step は最大 5-10 分かかる場合あり。閾値を 5 分にすると進行中の正常 run を誤検出するリスク。10-15 分が妥当か - ---- - -### exe + `--help` を PreToolUse でブロックして `src//` Read に誘導する hook (PR #109 T1-3 採用) ★ Bundle c - -> **動機**: PR #109 SIGPIPE 事故の **直接トリガ** が「AI が `cli-merge-pipeline.exe --help` を実行 → 当該 exe は `--help` 未対応のため merge 本体を実行 → 出力 truncate で SIGPIPE」だった。ユーザー提案: exe ごとに `--help` を実装する案は exe 数増加で漏れが出るが、`exe + --help` をセットで PreToolUse block すればソース閲覧フローに自動誘導でき、想定外実行を構造的に排除。今後追加される exe にも自動適用される一般解。 -> -> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の trigger pattern 防止層。順位 63 / 64 が「中断されても recovery する」事後対策、本 task は「中断パターンを発生させない」事前対策。 -> -> **参照**: `.claude/feedback-reports/109.md` Tier 1 #3、`.claude/hooks-config.toml` (PreToolUse block_pattern)、`src/hooks-pre-tool-validate*/` -> -> **実行優先度**: 🚀 **Tier 1 High** — Effort S。ユーザー提案の事前防衛策。 - -#### 設計決定 (案) - -- **検出パターン** (regex): - - `(?:\.\\.claude\\|\\./|^|\s)(?:[\w\-]+\.exe|cli-[\w\-]+\.exe)\s+(?:--help|-h|/\?)\b` - - exe 名は `cli-*.exe` / `hooks-*.exe` / `check-*.exe` 等を含む全 Rust exe 想定 - - 引数が `--help` / `-h` / `/?` の **単独実行** に限定 (`exe foo --help` のような subcommand help は対象外) -- **ブロック時の代替誘導メッセージ**: - ```text - exe の --help は本リポジトリで未実装の可能性があります。 - 詳細を見るには次を試してください: - - ソースを Read: src//src/main.rs (引数定義は clap struct を確認) - - 既存 docs を検索: grep -r "" docs/ - ``` -- **配置先**: `src/hooks-pre-tool-validate*/` の Bash command validation ロジック (既存 git block と同居) -- **適用範囲**: Bash tool での実行のみ。Read tool 等での参照は対象外 - -#### 作業計画 - -- [ ] 既存 `hooks-pre-tool-validate*` の構造を確認 (Rust exe か Python か) -- [ ] regex パターン設計 + テストケース作成 (TP / FP の境界明確化) - - TP: `cli-merge-pipeline.exe --help`、`./.claude/foo.exe -h` - - FP: `cargo run --help`、`gh pr view --help`、`exe foo --help` (subcommand) -- [ ] hook に block ロジック追加 + 代替誘導メッセージ実装 -- [ ] integration test: 上記 TP / FP ケースで block / pass を assert -- [ ] dogfood: 本 hook 有効状態で `cli-merge-pipeline.exe --help` を実行し block されることを確認 -- [ ] 派生プロジェクトに deploy -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- `exe + --help` 系コマンドが Bash tool 経由で block される -- block メッセージで「ソースを Read」フローに誘導される -- 既存の正規 `--help` (cargo / gh / pnpm 等) は誤検出しない -- 今後追加される exe にも自動適用される (regex で exe 名を限定列挙しないため) - -#### 詰まっている箇所 - -- regex の精度: `cli-merge-pipeline.exe` は対象だが `cargo --help` は対象外、という線引きを `.exe` suffix の有無で判定するか exe 名 prefix で判定するかで挙動が変わる。本リポジトリの全 exe を grep して命名規則を確認してから決定 -- AI 側の挙動学習: block されたとき AI が代替フロー (ソース Read) に正しく遷移するかの dogfood 観察。失敗するなら block message を強化 - ---- - -### 長時間 subprocess の pipe truncate 禁止ルールをグローバル明文化 (PR #109 T3-1 採用) ★ Bundle c - -> **動機**: PR #109 SIGPIPE 事故は「AI が長時間 subprocess (cli-merge-pipeline) の出力を `\| head -40` で truncate」したのが直接トリガ。順位 65 (PreToolUse block) が決定論層、本ルールは AI/人間の判断ガイド層。二層防御で hole を減らす。 -> -> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の知識層。決定論的 block では捕捉しきれないパターン (例: `pnpm push \| tail`、`gh pr view --json reviews \| jq`) も含めて AI に教育的に指示。 -> -> **参照**: `.claude/feedback-reports/109.md` Tier 3 #5、`~/.claude/rules/common/development-workflow.md`、`~/.claude/rules/common/git-workflow.md` -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。グローバルルール 1 セクション追加。 - -#### 設計決定 (案) - -- **配置先候補** (着手時に決定): - - **案 A**: `~/.claude/rules/common/development-workflow.md` の "Bash 実行ガイド" として新セクション追加 - - **案 B**: `~/.claude/rules/common/git-workflow.md` の "gh CLI 使用規則" の隣に "長時間 subprocess の出力扱い" 節を追加 - - 推奨: **案 A** (development-workflow が development pipeline 全般を扱うため整合性高い) -- **記述内容** (案): - - 長時間 subprocess (`pnpm push` / `pnpm merge-pr` / `cli-*.exe` / takt workflow) を **`\| head` / `\| tail` / `\| tee` で truncate しない** - - 理由: parent process の SIGPIPE で workflow が abrupt 中断され、`.failed` marker や成果物が silent loss する (PR #109 で実証) - - 代替策: 出力をファイルに redirect (`> out.log 2>&1`) または `run_in_background` で実行 (Bash tool のオプション) し、後から `tail out.log` 等で確認 - - 例外: 短命な subprocess (`ls`, `cat` 等) や exit code のみが必要な場合は OK -- **既存ルールとの関係**: gh CLI 使用規則 (token 効率) と相補。token 効率は --jq / -q による絞り込み、本ルールは長時間 process の中断回避 - -#### 作業計画 - -- [ ] 案 A / B のどちらを採用するか決定 (着手時に grep で類似 rule の配置を確認) -- [ ] 配置先に「長時間 subprocess の出力扱い」セクションを追加 (規則 + 理由 + 代替策 + 例外を 1 ページに集約) -- [ ] PR #109 SIGPIPE 事故を実例として inline 引用 (`docs/adr/adr-030-...md` 参照) -- [ ] 派生プロジェクトで global rule 反映を確認 (rule は global、自動適用) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- グローバルルールに「長時間 subprocess の pipe truncate 禁止」が codify される -- 次回 AI が `pnpm push \| head` 系を打とうとした時、ルール参照で自己修正できる -- 順位 65 (block_pattern) と整合 (二層防御の上層 = ガイド、下層 = block) - -#### 詰まっている箇所 - -- 「長時間」の定義 ambiguity: `gh pr view` は通常短命だが rate-limit 中は長時間化する。閾値を秒数で明文化するか、特定 exe を列挙するかの判断 -- 例外列挙の網羅性: AI が「これは例外だろう」と自己判断する余地を残すと block_pattern (順位 65) との整合性が崩れる可能性 - ---- - -### ADR-030 に abrupt 終了時の振る舞いを spec として明記 (PR #109 T3-2 採用) ★ Bundle c - -> **動機**: PR #109 で露呈した「ADR-030 の決定論性が SIGPIPE / kill -9 / power loss で破綻する」問題は、ADR 本文で abrupt 終了時の挙動が **spec として明記されていなかった** ことが根本原因。順位 63 / 64 の実装が ADR-030 の "決定論的" の真の意味を closure する形で land する以上、ADR 本文も同タイミングで spec を拡張する必要がある。 -> -> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の仕様層。順位 63 / 64 の実装と同 PR で land して仕様/実装の整合性を保つ (実装単独で spec ドリフトしない)。 -> -> **参照**: `.claude/feedback-reports/109.md` Tier 3 #6、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) (試験運用) -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR 本文の "失敗マーカーによる recovery" 節を拡張。 - -#### 設計決定 (案) - -- **拡張する節**: ADR-030 の "失敗マーカーによる recovery" を「abrupt 終了 + reaper による多層保証」に拡張 -- **追記内容** (案): - - **L1 (in-process)**: Drop guard / signal trap で `Result::Err` 経路に依存せず `.failed` marker を保証 (順位 63 で実装) - - **L2 (out-of-process)**: orphan run reaper で `meta.json status=running` 5-15 分放置を検出し marker 補完 + 再起動 (順位 64 で実装) - - **致命系の挙動明記**: kill -9 / SIGKILL / power loss / OOM Killer → L1 で救済不可、L2 で救済 - - **仕様の SLA 化**: 「post-merge-feedback はマージ後 N 分以内に必ず完了 or .failed marker 化される」を保証ステートメントとして記述 -- **試験運用フラグの扱い**: 順位 63 / 64 land 後、本 ADR の "試験運用" フラグを外すか継続するかは dogfood 結果次第。本 task では仕様明記のみ、フラグ判断は別途 -- **関連 ADR との cross-link**: ADR-029 (pending file 自動起動) との関係明記、L2 reaper が ADR-029 経路を再利用する旨 - -#### 作業計画 - -- [ ] `docs/adr/adr-030-deterministic-post-merge-feedback.md` を読み、現行の "失敗マーカーによる recovery" 節を確認 -- [ ] 拡張内容を起草 (L1/L2 の責務分離 + SLA 化 + cross-link) -- [ ] 順位 63 / 64 と同 PR で land する前提で実装と整合 -- [ ] CLAUDE.md ADR index の ADR-030 description (試験運用フラグ等) も必要なら更新 -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- ADR-030 本文に L1 (in-process Drop guard) + L2 (out-of-process reaper) の責務分離が記述される -- abrupt 終了 (SIGPIPE / kill -9 / power loss / OOM) 時の挙動が spec として明記される -- post-merge-feedback の SLA (= マージ後 N 分以内に完了 or marker 化) がステートメントとして残る - -#### 詰まっている箇所 - -- 試験運用フラグの去就: 順位 63 / 64 で実装が完成しても、dogfood 期間が必要なら試験運用フラグは残す。本 task では仕様明記のみだが、フラグ判断と整合性を取る必要あり -- SLA の妥当性: 順位 64 の閾値 (5-15 分) と同期する必要があり、閾値が決まらないと SLA も書けない (依存関係) - ---- - ### `no-ephemeral-todo-reference` self-exclusion invariant の単体テスト追加 (PR #110 T2-1 採用) ★ Bundle d > **動機**: PR #110 で導入した `.claude/custom-lint-rules.toml` rule⑥ (`no-ephemeral-todo-reference`) は、ルール定義ファイル自身が `.toml` 拡張子で対象内になるため、message / why / example 内に concrete `docs/todoN.md` (N = digit) を書かない placeholder 戦略で self-trigger を回避している。この invariant は **naming convention 依存** で、将来の例文追記時に concrete digit を含む文字列を入れると self-trigger が発生して silent regression を起こすリスク (PR #110 pre-push reviewer OBS-3 で documented)。 diff --git a/docs/todo6.md b/docs/todo6.md index a62753d..3e912bd 100644 --- a/docs/todo6.md +++ b/docs/todo6.md @@ -2,9 +2,9 @@ > **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイルの位置付け**: docs/todo5.md がファイルサイズ 50KB を超過したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する。todo.md / todo2.md / todo3.md / todo4.md / todo5.md の既存エントリは引き続き有効、相互に独立。新セッションでは六つすべてを確認すること。 +> **本ファイルの位置付け**: docs/todo5.md がファイルサイズ 50KB を超過したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo7.md の既存エントリは引き続き有効、相互に独立。新セッションでは八つすべてを確認すること (todo.md / todo2-7.md / todo-summary.md)。 > -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo.md](todo.md#recommended-order-summary) を参照。 +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 --- @@ -96,3 +96,115 @@ Ephemeral artifact (`docs/*-analysis.md` 等の試験運用計画書) 内に **5 - ephemeral 計画書に大規模 content を追加する際の判断基準が明文化される - config コメント → ephemeral 参照の anti-pattern が global rule に明記される - 順位 89 と同 PR で land (Bundle h コア) + +--- + +### `[lint_screen]` config parse テスト (PR #132 T2-#4 採用) ★ Bundle i + +> **動機**: PR #132 (Phase c MVP) で `push-runner-config.toml` に新 section `[lint_screen]` を追加したが、`config.rs` の test module には parse テストが不在。CodeRabbit nitpick で指摘 (`config_parses_with_diff` 相当が `[lint_screen]` には未存在)。serde TOML は field name の完全一致を要求するため、parse テストがないと将来の field rename / 追加で silent `None` fallback が発生し、機能が無音で停止するリスクがある。 +> +> **本タスクの位置づけ**: PR #132 post-merge-feedback Tier 2 #4 採用 (Frequency Medium / Effort S / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/132.md` Tier 2 #4、`src/cli-push-runner/src/config.rs` (テスト module の `config_parses_with_diff` を template に踏襲)、PR #132 commit `73903d72` (lint_screen config 追加) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。順位 92 と同 PR (Bundle i) 推奨。 + +#### 作業計画 + +- [ ] `src/cli-push-runner/src/config.rs` の `#[cfg(test)] mod tests` に `config_parses_with_lint_screen_section` を追加 +- [ ] 全 7 field (`enabled`, `exe_path`, `model`, `endpoint`, `timeout_secs`, `max_diff_lines`, `output_path`) の deserialize 検証 +- [ ] `enabled = false` でも `Option` が `Some(...)` で構築されることを assert (= section があれば parse される、なくなれば None) +- [ ] 一部 field 省略時に default (`None`) になることを assert (`config.lint_screen.unwrap().exe_path.is_none()` 等) + +#### 完了基準 + +- 上記テストが pass +- 将来 `LintScreenConfig` に field 追加 / rename した時に test 側で気付ける構造になる + +#### 詰まっている箇所 + +なし + +--- + +### scale-aware eval fixtures (200+ 行) — Phase d 投入前の必須 infrastructure (PR #132 T2-#5 採用) ★ Bundle i + +> **動機**: PR #132 smoke dogfood で 868 行の現実 PR diff を mistral:7b に流したところ、JSON 出力が不完全 (`missing field 'screen_decision'`) になり fallback path が作動した。Phase b' eval fixtures (10-30 行/件) では出ない failure mode で、Phase d 本番 PR 投入時に頻発するリスクが顕在化していた。fixture 化することで再現可能化し、 §8.D prompt v3 / v4 改善ループの reference point として固定する。 +> +> **本タスクの位置づけ**: PR #132 post-merge-feedback Tier 2 #5 採用 (Frequency Medium / Effort M / Adoption Risk None)。Phase d 着手前の必須 infrastructure 拡充。 +> +> **参照**: `.claude/feedback-reports/132.md` Tier 2 #5、`src/cli-finding-classifier/evals/lint-screen-evals.json` (eval セット)、`src/cli-finding-classifier/tests/lint_screen_evals.rs` (compare ロジック)、PR #132 PR body §smoke dogfood 結果 (868 行 diff の fallback 観測) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。Phase d 着手前に必須。順位 91 と同 PR (Bundle i) 推奨。 + +#### 追加する fixture 案 (3 件以上) + +| # | 名前 | 規模 | 検証目的 | +|---|---|---|---| +| 13 | eval13-large-refactor-real | ~300 行 / 5 file | mistral:7b の context 限界、fallback 頻度 | +| 14 | eval14-mid-mixed | ~150 行 / 3 file | scale 中域での recall 安定性 | +| 15 | eval15-syntax-stress | ~200 行 / 1 file | 単 file の long diff、JSON 完全性 | + +baseline は Phase a/b' と同じく Claude Code 一次起案 → ユーザー確認。期待結果 (`screen_decision`) は **agreement 75% 維持** が目標、未達なら §8.D v4 prompt 改訂ループ。 + +#### 作業計画 + +- [ ] 200-300 行 diff fixture を 3 件以上作成 (実 PR から抽出 or 合成) +- [ ] 各 fixture に SYNTHETIC FIXTURE comment header (ADR-038 規約) を付与 +- [ ] `lint-screen-evals.json` に baseline + expectations 追加 +- [ ] `eval_set_loads_and_has_phase_b_prime_twelve_entries` test を 15+ 件期待に更新 +- [ ] cargo test --ignored 再走、agreement rate と fallback rate を記録 +- [ ] agreement < 75% なら §8.D v4 prompt 改訂で対処 + +#### 完了基準 + +- 200+ 行 fixture 3 件以上が `evals/files/` に追加 +- cargo test --ignored が pass +- 大規模 diff の fallback rate が記録される (Phase d 改善ループの baseline) +- agreement 75% 以上が維持されているか、未達理由が文書化される + +#### 詰まっている箇所 + +なし。Phase d 本番 PR 投入前の必須 infra。 + +--- + +### `coding-style.md` Cross-File Reference Lifecycle に partial fix 例を追記 (PR #132 T3-#8 採用) + +> **動機**: PR #94 / #111 / #132 で「変更差分外ファイル (`evals/`, `tests/`, ADR 等) に同じ参照が残存して partial fix 再発」というパターンが反復観測された。既存 `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle はあるが「同一概念が変更差分外でも複数箇所に存在し、変更時には family_tag scope で全箇所を揃える必要がある」具体例が不在。Frequency High の anti-pattern として codify することで、機械強制 (lint rule⑥) と教育的ガイダンスの両層で予防する。 +> +> **本タスクの位置づけ**: PR #132 post-merge-feedback Tier 3 #8 採用 (Frequency High / Effort XS / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/132.md` Tier 3 #8、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle (既存ルール)、PR #94 (lint rule extensions 不揃い) / PR #111 (Bundle e cross-file drift) / PR #132 (lint_screen step が config / test / instruction で family_tag を持つ) +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。独立並列実施可。 + +#### 追加する例 + +`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle (= 既存 § "Multi-point synchronization") に「変更差分外への partial fix 再発」anti-pattern 例を追記: + +```text +### Anti-pattern: 変更差分外への partial fix 再発 + +同一概念が複数ファイル (実装 / config / test / fixture / ADR / instruction) に分散している場合、 +変更差分内のみを揃えて差分外の対応箇所を放置すると後続 PR で「あの参照は古い」指摘が無限再発する。 + +由来: PR #94 (lint rule extensions が rule code で更新済だが ADR で未更新) / PR #111 (Bundle e +の family_tag scope で同一概念が docs/ に複数残存) / PR #132 (Phase c の lint_screen step が +config.rs + push-runner-config.toml + review-simplicity.md + ADR で family_tag が分散) で実証。 + +対処: +- family_tag (例: `lint_screen`, `extensions`) を `grep -rn` で全 path 検索し、変更差分外も含めて揃える +- 変更差分外の対応漏れは PR description の "Out of scope" に明記して別 PR に切り出す (= partial fix を意図的にする) +- 何も書かないと reviewer / 自分自身の再 visit 時に消化不良として再発する +``` + +#### 作業計画 + +- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle (or 関連 §) に上記 anti-pattern を追記 +- [ ] PR #94 / #111 / #132 を inline cite で trigger 事例として記録 + +#### 完了基準 + +- coding-style.md に「変更差分外への partial fix 再発」例が codify される +- 既存 lint rule⑥ (`no-ephemeral-todo-reference` 系) と組み合わせで教育効果が強化される diff --git a/docs/todo7.md b/docs/todo7.md new file mode 100644 index 0000000..f08ee5e --- /dev/null +++ b/docs/todo7.md @@ -0,0 +1,576 @@ +# TODO (Part 7) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo5.md がファイルサイズ 67KB に到達して Claude Code の読み取り安定性 (50KB 超で不安定化) を損なったため、2026-05-09 に **PR #101〜#109 由来の古い半分のタスクを本ファイルへ分離** した。todo5.md には PR #110 以降のタスクが残存。本ファイルは既存タスクの編集・完了削除専用、新規タスクは追加しない (新規エントリは [docs/todo6.md](todo6.md) へ)。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md の既存エントリは引き続き有効、相互に独立。新セッションでは八つすべてを確認すること (todo.md / todo2-7.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### `>` vs `>=` boundary inconsistency lint rule (PR #101 T1-2) + +> **動機**: PR #101 で `parse_listed_findings` の `created_at > push_time` が CodeRabbit から境界 inclusive (`>=`) への揃え修正を指摘された。auto-fix が同一ファイル内 `parse_new_comments` / `parse_findings` にも `>=` を適用 (= 3 関数 latent drift)。`parse_rate_limit` だけが既に `>=` で、後続関数を書くたびに著者が意識せず `>` を選ぶ構造的問題。custom-lint-rule で書いた瞬間に block すれば bug class が排除される。 +> +> **本タスクの位置づけ**: PR #101 post-merge-feedback Tier 1 #2 採用 (高頻度 finding)。Bundle Z #B-α (Rust comment lint hook) と同じ「決定論的防止層」哲学。AST 解析ではなく正規表現層 (ADR-007) で対応可能。 +> +> **参照**: `.claude/feedback-reports/101.md` Tier 1 #2、ADR-007 (custom lint rule の正規表現 / AST 層線引き)、CodeRabbit PR #101 round 1 Minor finding +> +> **実行優先度**: 🚀 **Tier 1** — Effort S。`.claude/custom-lint-rules.toml` への regex rule 追加。 + +#### 設計決定 (案) + +- **配置先**: `.claude/custom-lint-rules.toml` に新規 rule entry +- **検出パターン (正規表現案)**: + - 狭め: `\.(created_at|submitted_at|updated_at)\b.*\.map\(\|\w+\|\s*\w+\s*[><](?!=)\s*(push_time|since)` + - 広め: `\b(created_at|submitted_at|updated_at|comment_event_time|event_time)\b.*[><](?!=)` で時刻フィールドの strict inequality 全般を flag +- **適用対象**: `.rs` ファイル +- **rule 名 (案)**: `time-boundary-strict-inequality` +- **suppress マーカー**: `// SAFETY: <理由>` 行末付与で suppression (例: 意図的に exclusive 比較する場合) + +#### 作業計画 + +- [ ] 既存 `.claude/custom-lint-rules.toml` の rule 構造を確認 +- [ ] regex + path filter を新 rule として記述 +- [ ] PostToolUse hook の lint runner で synthetic test (修正前 `parse_findings` 系の `>` パターンを再現してマッチ確認) +- [ ] 既存 codebase で false positive 影響範囲をグレップして確認 +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 確認 +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- `.claude/custom-lint-rules.toml` に新 rule が追加され `.rs` ファイル内の時刻フィールド strict inequality を検出 +- 1〜2 PR で dogfood し false positive がないこと + +#### 詰まっている箇所 + +- false positive の評価 (時刻フィールド以外で legitimate な `>` が誤 block されないか)。着手時に実 codebase でグレップして影響範囲を確認。 + +--- + +### `parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2 + +> **動機**: PR #101 で `run_list_findings` が `unwrap_or_else(|_| "[]")` で gh api 失敗を `[]` に潰していて CR Major finding を受けた。99.md でも `silent fail` (Windows path mismatch で early return) として類似言及あり。**`unwrap_or_else(|_| empty)` の anti-pattern が複数 PR で再発**。test 層で機械検証することで未然に塞ぐ。本タスクは Bundle a Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) で同 API を消費するので、同一 PR land で test 二重投資なし。 +> +> **本タスクの位置づけ**: PR #101 post-merge-feedback Tier 2 #1 採用 (高頻度 anti-pattern finding)。Bundle a Sub-PR 2 (順位 42 / 43 / 46) と同 PR で land 推奨。CLAUDE.md `coding-style.md` "Never silently swallow errors" 原則の test 層実装。 +> +> **参照**: `.claude/feedback-reports/101.md` Tier 2 #1、`.claude/feedback-reports/99.md`、`~/.claude/rules/common/coding-style.md` "Never silently swallow errors" +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。新 test ファイル + gh API モック。Sub-PR 2 と一体実装。 + +#### 設計決定 (案) + +- **配置先**: `src/check-ci-coderabbit/tests/parse_error_handling_test.rs` (integration test、既存 unit test と分離) +- **テスト対象シナリオ**: + - **gh API HTTP error 返却時**: `run_list_findings` がエラーを propagate するか verify (現状 PR #101 fix で `.map_err(...)?` 化済 → regression 防止) + - **JSON 不正形式入力**: `serde_json::from_str` 失敗時の挙動 (現状 `unwrap_or_else(|e| { eprintln!(...); vec![] })` で warn は出すが空配列返却 = silent fall) — 望ましい設計を test で固定 + - **空 JSON `[]`**: 正常 path (空 findings 返却) の境界条件 +- **モック戦略**: + - gh API 直接モックは不要 (parse 関数は JSON string を受け取る純関数) + - `run_gh` を trait 化して mock injection or `mockito` HTTP mock — Sub-PR 2 の cli-pr-monitor 実装方針と整合 +- **既存 unit test との関係**: 既存 16 件は normal path 中心。本 task は error path 専用 + +#### 作業計画 + +- [ ] `src/check-ci-coderabbit/tests/` ディレクトリ作成 (現在 unit test only) +- [ ] gh API モック戦略の選定 (trait injection or shell wrapper stub) — Sub-PR 2 の cli-pr-monitor 実装方針と整合 +- [ ] error-path シナリオ 3 件 (HTTP error / 不正 JSON / 空 JSON) を実装 +- [ ] `cargo test --workspace` で pass 確認 +- [ ] dogfood: 実 PR で `unwrap_or_else(|_| empty)` を一時的に書き戻して test が fail するか sensitivity 検証 +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- `parse_listed_findings` / `parse_findings` の error-path 3 シナリオ test が pass +- `unwrap_or_else(|_| empty)` の silent fallback パターンが test で fail 検出される +- Sub-PR 2 の cli-pr-monitor 実装で同 mock infrastructure を流用できる + +#### 詰まっている箇所 + +- gh API モック戦略の選定: HTTP mock library `mockito` vs `run_gh` の trait injection — 単純さ優先なら後者、real API 結合に近づけたいなら前者。 +- `eprintln!` (stderr) を assert する仕組みが Rust 標準にないため、`gag::BufferRedirect` や custom logger 注入が必要 — 着手時に評価。 + +--- + +### `.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測) + +> **動機**: PR #103 push の実観測で takt pre-push-review が **6-iter outlier (22m 50s)** を発生させ、うち iter 3+4 の ~10 分が wasted。原因は `.takt/review-diff.txt` が push-runner 起動時 snapshot として固定され、fix step の変更が反映されないこと。reviewer は古い diff を読んで「fix されていない」と機械的 false positive (`persists`) を出し、max iter まで escalate して supervise の live Read で打開する以外に経路がない。supervisor 自身が "structural limit" として診断済 (`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md`)。 +> +> **本タスクの位置づけ**: PR #103 セッション知見 (post-merge-feedback の Tier 3 #1 = ADR 化提案を skip し、機構で塞ぐ実装層対策を採用)。Bundle Z 3 層 (#B-α / #B-β / #B-γ) では完全に塞げない独立改善。reviewer の判定精度を構造的に改善することで 6-iter outlier の発生率を 0% 近くに抑える。 +> +> **参照**: `.claude/feedback-reports/103.md` (Tier 3 #1 で同根因に別アプローチ提案、本 task で代替)、`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md` (false positive 構造診断)、[ADR-036: Bundle Z 3 層アーキテクチャ](adr/adr-036-bundle-z-three-layer-review.md) (PR #97 ベースライン observation を含む、本 task は Bundle Z 3 層では塞げない独立改善) +> +> **実行優先度**: 🚀 **Tier 1** — Effort M。takt 設定 / pre-push-review.yaml への hook 追加。 + +#### 設計決定 (案) + +- **refresh タイミング**: reviewer step 起動直前に diff を再生成 (fix step 完了直後の状態を反映) +- **実装方針 (2 案)**: + - **案 A: takt workflow の reviewer step に precondition step を挟む** — `.takt/workflows/pre-push-review.yaml` で `before:` / `pre-step:` 的な hook を使い、push-runner と同一の diff 生成コマンドを呼ぶ + - **案 B: cli-push-runner 側で fix step の終了を検出して diff を更新** — Rust コードで takt の step 進行を監視 (実装複雑度大) +- **推奨**: 案 A — takt config で完結、Rust 修正不要、影響範囲が pre-push-review.yaml のみ +- **diff 生成コマンド**: 既存 push-runner と同じロジック (`jj diff` ベース) を再利用、ファイルパス `.takt/review-diff.txt` も同一に保つ +- **冪等性**: 同 fix output から生成される diff は決定的なので複数回 refresh しても問題なし。途中失敗で diff が壊れても次 iteration の冒頭で上書きされる + +#### 作業計画 + +- [ ] takt workflow の hook 仕様 (`before:` / `pre-step:`) を確認 (`.takt/workflows/*.yaml` の他 facets / takt source を grep) +- [ ] case A 不可なら case B (cli-push-runner 改修) にフォールバック +- [ ] `.takt/review-diff.txt` の生成ロジックを単一場所に整理 (DRY、push-runner と shared util にする等) +- [ ] `.takt/workflows/pre-push-review.yaml` に refresh hook を追加 +- [ ] 単体動作確認: 意図的に DRY refactor 指摘 + fix を再現する synthetic シナリオで 3-iter 収束を確認 +- [ ] dogfood 1〜2 PR で実 6-iter outlier scenario が再発しないことを観測 +- [ ] Bundle Z Phase 2 (#B-β) との競合確認 (deterministic check は fix step 内部で動くため、本 task の fix→review 境界 refresh とは独立) +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 確認 +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- fix step 完了後の review iteration で `.takt/review-diff.txt` が最新状態を反映 +- 6-iter outlier の発生率が **0%** に近づく (PR #103 のような scenario が 3-iter で収束) +- supervisor の live Read 救済が不要になる (= supervisor step は workflow に残るが、false positive 救済責務が消える) + +#### 詰まっている箇所 + +- takt workflow の `before:` / `pre-step:` hook 仕様が公式 docs に明記されていない可能性 → 着手時に takt source / 既存 workflow yaml を grep して確認。 + +--- + +### comment-lint hook の MultiEdit 対応 (順位 50 follow-up) + +> **動機**: 順位 50 で comment-lint hook の scope を変更行に限定する v1 実装を完了した。v1 は Edit (single new_string) のみフィルタ対象とし、MultiEdit は whole-file lint にフォールバックする (no-regression)。MultiEdit が頻繁に使われる場合、複数 edit の `edits[].new_string` を順次適用して累積 range を計算する拡張が望ましい。 +> +> **本タスクの位置づけ**: 順位 50 follow-up。MultiEdit 利用頻度が低いため優先度は Tier 3。MultiEdit 由来の 12.6KB 出力が無視できない頻度になった場合、または Bundle Z Phase 3 (#B-γ) で MultiEdit ベースの大規模リファクタが日常化した場合に着手。 +> +> **参照**: 順位 50 PR (`src/hooks-post-tool-comment-lint-rust/src/main.rs` の `compute_changed_lines`)、Claude Code MultiEdit tool spec +> +> **実行優先度**: 💎 **Tier 3** — Effort S。`compute_changed_lines` に MultiEdit branch を追加。 + +#### 設計決定 (案) + +- **MultiEdit input schema**: `tool_input.edits: Vec<{old_string, new_string, replace_all?}>` を順次適用 +- **行 range 計算**: 各 edit の `new_string` を post-edit source 内で全件検索 → 全 edit の match 行 range の union を filter として使用 +- **空 new_string の扱い**: 個別の edit が純削除の場合、その edit はスキップ。全 edit が純削除なら filter は空 = lint skip +- **fallback 条件**: ある edit の `new_string` が見つからない場合 → 安全側に倒し whole-file lint (現 Edit 実装と同じ動作) + +#### 作業計画 + +- [ ] `ToolInput` struct に `edits: Option>` を追加 +- [ ] `compute_changed_lines` に `Some("MultiEdit")` branch を追加 (各 edit の new_string を locate して union) +- [ ] 単体テスト: 複数 edit の union が正しく計算されることを確認 +- [ ] 単体テスト: 一部 edit が純削除の場合の挙動確認 +- [ ] dogfood: MultiEdit を使った PR で hook 出力が変更行のみに絞られることを確認 +- [ ] 派生プロジェクト deploy +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- MultiEdit でも変更行外の pre-existing violations が flag されない +- v1 (Edit) の挙動は不変 +- Phase 3 (#B-γ) で reviewer の役割が「異常検知」に縮小されると本 task の効果も部分的に縮む可能性 (criterion-based finding がそもそも reviewer から消えるため)。ただし Phase 3 完了前の中間期間 + Phase 3 後も「異常検知」自体は diff を読むので効果は残る。 + +--- + + +### comment-lint hook test 拡充 (PR #104 T2-1+T2-2 bundle) + +> **動機**: PR #104 で CodeRabbit Critical (UTF-8 byte boundary) + Minor (multi-line block comment boundary) の 2 件を auto-fix で解消したが、いずれも回帰防止テストは 1 パターンのみで脆い。tree-sitter / Rust version 更新で区間交差判定や UTF-8 境界処理が壊れた場合に検出できないリスク。 +> +> **本タスクの位置づけ**: PR #104 post-merge-feedback Tier 2-1 / Tier 2-2 の bundle。コスト低 (S effort)、test additions のみで scope clean、PR #104 の fix を体系的に固定化する。 +> +> **参照**: `.claude/feedback-reports/104.md` Tier 2 #1, #2、PR #104 (`src/hooks-post-tool-comment-lint-rust/src/main.rs` の `locate_string_line_ranges` / `span_overlaps_ranges`) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。Bundle b と独立、いつでも単独着手可。 + +#### 設計決定 (案) + +- **UTF-8 multi-byte test 拡充** (T2-1): + - 現状: `locate_string_line_ranges_handles_multibyte_utf8` 1 パターン + - 追加 5 パターン: 漢字 + ASCII 混合 / 漢字単独 / emoji / BMP 外文字 (例: 𝕊) / 結合文字 (例: é = e + ́) + - 各パターンで `search_start = (absolute + needle.len()).min(source.len())` の境界処理を検証 +- **Block comment boundary matrix 拡充** (T2-2): + - 現状: `find_violations_multiline_block_comment_spanning_range_boundary` 1 パターン + - 追加 6 パターン: {開始行のみ被覆, 終了行のみ被覆, 内部完全包含} × {単行 block comment, 複数行 block comment} + - `span_overlaps_ranges(start, end, ranges)` の区間交差判定を体系化 + +#### 作業計画 + +- [ ] UTF-8 multi-byte test 5 パターン追加 +- [ ] Block comment boundary test 6 パターン追加 +- [ ] 既存 1 パターンずつのテストは保持 (regression 防止のため削除しない) +- [ ] 派生プロジェクト deploy は不要 (test のみのため) +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- UTF-8 multi-byte test が 6 パターン以上 +- Block comment boundary test が 7 パターン以上 +- `cargo test -p hooks-post-tool-comment-lint-rust` 全 pass + +#### 詰まっている箇所 + +- 結合文字 (`e + ́`) を `new_string` に含むケースは Edit tool が実環境で発生するか不明 (理論的検証としては有効、実際の回帰防止としては効果薄の可能性)。1 パターンで足る + +--- + +### Aggregation cap integration test (PR #105 T2-1 採用) + +> **動機**: PR #105 の auto-fix で `collect_all_violations` に `violations.truncate(MAX_VIOLATIONS)` を追加した (CodeRabbit Minor finding 解消) が、これは contract の暗黙化に過ぎない。将来 `find_xxx_violations` を追加する PR で `extend()` の後に `truncate` を入れ忘れる regression を構造的に防ぐ test がない。 +> +> **本タスクの位置づけ**: PR #105 post-merge-feedback Tier 2 #1 採用。後続の lint 追加 (例: 順位 56 の test 拡充 / 順位 47 の `>=` boundary lint / 将来の Rust 専用 lint) で同 contract を破る regression を test で固定化する。 +> +> **参照**: `.claude/feedback-reports/105.md` Tier 2 #1、`src/hooks-post-tool-comment-lint-rust/src/main.rs` `collect_all_violations` (line 545)、PR #105 Finding #2 (Minor) の auto-fix +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。test 1-2 件追加で完結。 + +#### 設計決定 (案) + +- **シナリオ**: `collect_all_violations(file_path, source_with_15_comments_and_15_long_functions, None)` を呼び、結果が **MAX_VIOLATIONS (= 20) 以下** であることを assert +- **source 構築**: + - 15 個の禁止コメント (`// forbidden 0` 〜 `// forbidden 14`) + - 15 個の 60 行関数 (`fn big_0` 〜 `fn big_14`) + - 合計 30 件の violation 候補 → cap で 20 件に truncate +- **test 名**: `collect_all_violations_truncates_to_max_violations` (spec を test 名に反映、PR #105 T2-3 提案は卻下したが naming-as-spec 自体は意義あり) +- **追加検証** (任意): 個別 `find_violations` / `find_function_length_violations` がそれぞれ 20 件以上返しうることも assert (truncate なしだと 30 件返ることを示す) + +#### 作業計画 + +- [ ] 30 件の violation 候補を含む synthetic source を生成する helper 関数を test module に追加 +- [ ] `collect_all_violations_truncates_to_max_violations` test を追加 +- [ ] 個別 finder の non-truncate 挙動を assert する補助 test を追加 +- [ ] cargo test pass 確認 +- [ ] 派生プロジェクト deploy は不要 (test のみ) +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- 結合後の violation 件数が `MAX_VIOLATIONS` 以下であることが test で固定化 +- 将来 `find_xxx_violations` を追加した PR で truncate 削除すると test fail で検出される + +#### 詰まっている箇所 + +- 順位 56 (PR #104 T2-1+T2-2 test 拡充) と同 PR で bundle するか別 PR とするか。両者とも test additions、同ファイル同 test module で scope clean、bundle 推奨。 + +--- + +### analyze-session の transcript filter 絞り込み (旧 #A-3) + +> **動機**: `cli-merge-pipeline` が生成する `.takt/post-merge-feedback-transcript.jsonl` は **session 全履歴** を含むため、analyze-session step が読み込む input token が大きい。当該 PR に直接関連する範囲のみ filter すれば input token 削減 = post-merge-feedback の cache_read 削減。 +> +> **本タスクの位置づけ**: 旧 `docs/pipeline-token-efficiency.md` の #A-3 entry。同計画書は ADR-036 (Bundle Z 3 層) / ADR-037 (fix-trust shortcut) に主要決定を移し終了予定で、残作業として本 task のみ todo に移管。Bundle 化対象なし、独立 PR 推奨。 +> +> **参照**: (削除済) `docs/pipeline-token-efficiency.md` #A-3 セクション、`src/cli-merge-pipeline/` の transcript 生成ロジック +> +> **実行優先度**: 💎 **Tier 3** — Effort M。ROI ★★★ で優先度中程度、dogfood 実測が必要。 + +#### 設計決定 (案) + +- **filter 範囲**: 当該 PR の作成 commit (= cli-pr-monitor が PR を最初に検出した時刻、または `pnpm create-pr` 完了時刻) から merge 完了時刻までの jsonl 行のみ +- **時刻判定**: jsonl の `timestamp` field を使用 (各エントリに ISO 8601 形式で記録あり) +- **境界の扱い**: + - 開始時刻 *以降*: PR 作業中の Claude 対話 + tool 実行履歴 + - 終了時刻 *まで*: merge 完了 (= post-merge-feedback 起動の直前まで) + - 境界外 (PR 作成前 / merge 後): 除外 +- **既存挙動との互換**: 開始時刻取得失敗時 (state file なし等) は全 session フォールバック (no-regression) + +#### 作業計画 + +- [ ] `cli-merge-pipeline` の transcript 生成ロジックを特定 +- [ ] PR 作成時刻 / merge 時刻の取得経路を確定 (`.claude/cli-pr-monitor-state.json` or `gh pr view --json mergedAt` 等) +- [ ] timestamp 比較で jsonl 行を filter する logic を実装 +- [ ] 開始時刻取得失敗時のフォールバック (全 session) を保持 +- [ ] dogfood 1-2 PR で input token 削減量を実測 (analyze-session の billable input tokens で比較) +- [ ] 削減効果が想定 30-50% に届くか確認、届かない場合は filter 設計を見直し +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- analyze-session の input token が PR 作業範囲のみに絞り込まれる +- dogfood で 30-50% 削減を実測 (削減未達なら filter 設計を見直し) +- 開始時刻取得失敗時のフォールバックが機能 (regression なし) + +#### 詰まっている箇所 + +- 「PR 作成前の議論 (設計判断、却下されたアイデア)」が落ちる可能性 → post-merge-feedback の知見質に影響しうる。dogfood で「重要 finding が拾えなくなった」事象が出たら filter 範囲を広げる (例: PR 作成 commit から 2 時間前まで遡る等) +- transcript jsonl の structure 変更時に filter logic が壊れる risk → field name (`timestamp`) を assert する unit test を追加 + +--- + +### post-PR 検証フローに CR review.body 手動スキャン step 追加 (PR #108 T2-1 採用) + +> **動機**: 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 拡張 (= 将来の根本解決) の先行策として機能する。 +> +> **参照**: `.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` +> +> **実行優先度**: 🔧 **Tier 2** — Effort XS。post-PR checklist documentation の更新のみ。 + +#### 設計決定 (案) + +- **配置先候補**: + - `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 で頻度が高ければ昇格) + +#### 作業計画 + +- [ ] `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 エントリを削除 + +#### 完了基準 + +- post-PR workflow に「CR review.body 手動スキャン」step が追記される +- 次 1-2 PR の dogfood で本 checklist の実行が観察される +- review body 内の actionable finding が後追い修正にならない (= merge 前に検出される) + +#### 詰まっている箇所 + +- 配置先選定 (本リポジトリ docs/workflow.md vs グローバル `~/.claude/rules/`)。本タスクは本リポジトリ固有の暫定緩和策のため、本リポジトリ docs/ への追記が妥当か +- 手動 checklist は持続性が低い (人間が忘れる) ため、Tier 1 への昇格 (= analyzer 拡張) の優先度判断が dogfood 結果に依存 + +--- + +### cli-merge-pipeline に Drop guard / signal handler を追加し abrupt 終了時に `.failed` marker を保証 (PR #109 T1-1 採用) ★ Bundle c + +> **動機**: PR #109 merge 直後の post-merge-feedback workflow が SIGPIPE で silent 中断され、`.takt/runs/.../reports/` が空 + `.claude/feedback-reports/109.md` 未生成 + `.failed` marker も無いという fail mode が実証された。原因は `feedback::run()` が `Result::Err` を返した場合のみ `write_failed_marker` を書く実装で、Rust default の SIGPIPE 動作 (parent process abrupt 終了) では Result::Err 経路に到達しない。ADR-030「失敗マーカーによる recovery」仕様を構造的に違反。 +> +> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の中核。Drop guard で `Result::Err` 経路に依存しない unconditional marker 書き出しを保証する。Pre-emptive marker (案 C) と signal trap (案 A) の組み合わせで abrupt 経路を多層防御。 +> +> **参照**: `.claude/feedback-reports/109.md` Tier 1 #1、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md)、`src/cli-merge-pipeline/src/feedback.rs:454-475` (`copy_feedback_report`) / `:1100-1180` (`run`) / `main.rs:555` (caller) +> +> **実行優先度**: 🚀 **Tier 1 Critical** — Effort M。仕様 (ADR-030) と実装の根本ギャップ閉鎖。 + +#### 設計決定 (案) + +- **修正方針**: Explore agent が提示した 3 案 (A: signal trap + Drop guard / B: thread + parent timeout / C: pre-emptive marker) のうち、**A + C の組み合わせ** を採用 (agent 推奨) + - **C (pre-emptive marker)**: `feedback::run` 呼び出し前に `.failed` marker を先制書き込み、正常完了時のみ削除。abrupt 終了の 99% を救済 (Effort XS-S) + - **A (signal trap + Drop guard)**: `tokio::signal` または `nix` crate で SIGPIPE/SIGTERM を trap、RAII Drop guard で marker 書き込みを保証。panic 経路もカバー (Effort M) +- **race 対策**: 同 PR で concurrent merge が走った場合の race は既存 `CONCURRENT_RUN_GUARD_SECS=1500s` で予防されるが、pre-emptive marker の lifecycle と整合性確認が必要 +- **OS 互換性**: signal handling は OS 依存。Windows では SIGPIPE 相当が無いため Ctrl+C / SIGTERM 経路を中心に対応。Unix と Windows のコードパス分岐は cfg gate で実装 + +#### 作業計画 + +- [ ] `src/cli-merge-pipeline/src/feedback.rs` に pre-emptive marker 書き出しを追加 (`run` 冒頭で `write_failed_marker(reason: "pending")`) +- [ ] 正常完了時に marker を削除する path を追加 (`copy_feedback_report` 成功後) +- [ ] `nix` または `tokio::signal` で SIGPIPE/SIGTERM trap を実装 (Unix) + Windows 用 cfg 分岐 +- [ ] RAII Drop guard 構造体を導入し、scope 終了時に marker 書き込みを保証 (正常時 `disarm()` で skip) +- [ ] 既存 `Result::Err` 経路の `write_failed_marker` 呼び出しは維持 (二重書きにならないよう pre-emptive marker と統合) +- [ ] dogfood: 本機能を有効にした状態で `cli-merge-pipeline.exe \| head -40` を実行し marker が残ることを確認 (今回事故の再現テスト) +- [ ] 派生プロジェクトに deploy (cli-merge-pipeline.exe を再ビルド + 配布) +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- SIGPIPE / SIGTERM / panic / Result::Err いずれの経路でも `.claude/feedback-reports/.md.failed` が必ず残る +- 正常完了時には `.failed` marker が残らない (false positive ゼロ) +- 今回の事故 (PR #109 SIGPIPE) を再現するテストで pass +- 派生プロジェクト (`techbook-ledger` / `auto-review-fix-vc`) でも同等動作 + +#### 詰まっている箇所 + +- Windows での SIGPIPE 相当の挙動: Rust std はデフォルト SIGPIPE handler を install するが、Windows では pipe broken 時の挙動が異なる (CTRL_BREAK / I/O error)。整合性確保のため OS 別の signal mapping 設計が必要 +- 順位 64 (orphan reaper) との責務分離: Drop guard は process 内、reaper は process 外。両者の trigger 条件が重複しないよう設計 + +--- + +### orphan run reaper (post-merge-feedback の `meta.json status=running` 放置検出 + 自動再起動) (PR #109 T1-2 採用) ★ Bundle c + +> **動機**: 順位 63 (Drop guard) では救済できない致命系 (kill -9 / SIGKILL / power loss / OOM Killer) で post-merge-feedback workflow が中断された場合、`.failed` marker も書かれず orphan run のみが残る。仕様 (= フィードバックは必ず実行) を保証するには process 外からの監視層が必要。 +> +> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の第二防衛層。Drop guard (順位 63) を内側、reaper を外側とする多層防御で「フィードバックは必ず実行する」仕様を multi-layer で保証。 +> +> **参照**: `.claude/feedback-reports/109.md` Tier 1 #2、[ADR-029](adr/adr-029-post-merge-feedback-auto-trigger.md) (pending file 経由の再起動)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) +> +> **実行優先度**: 🚀 **Tier 1 Critical** — Effort M。順位 63 と組み合わせて致命系 hole を塞ぐ。 + +#### 設計決定 (案) + +- **配置先候補** (着手時に決定): + - **案 A**: `cli-pr-monitor` 起動時に `.takt/runs/*/meta.json` を scan (既存 monitor 機構との整合性高い) + - **案 B**: SessionStart hook (`src/hooks-session-start*/`) で scan (Claude Code session 起動毎に走る確定的 trigger) + - 推奨: **案 B** (SessionStart) — cli-pr-monitor は backend daemon 廃止 (ADR-018) で takt 経由になっており trigger 機構が複雑、SessionStart は単純で確実 +- **検出条件**: + - `.takt/runs/*/meta.json` の `status: "running"` かつ `startTime` が現時刻から **5 分以上経過** + - `currentStep` が `analyze` のまま (= 1 step も完了していない極短時間で死んだケース) も含める +- **recovery 動作**: + - 検出した orphan run の `meta.json` を `status: "failed"` に更新 (アトミックに) + - `.claude/feedback-reports/.md.failed` marker を書く (PR 番号は run slug `post-merge-feedback-for-` から抽出) + - ADR-029 pending file (`.claude/post-merge-feedback-pending.json`) を生成し、UserPromptSubmit hook で再起動 trigger +- **冪等性**: 同 orphan を 2 回検出しても重複 trigger しないよう既存 marker / pending file を check + +#### 作業計画 + +- [ ] 配置先 (案 A / B) を grep + `.claude/hooks-config.toml` 確認のうえ決定 +- [ ] `meta.json` parser + 5 分閾値判定ロジック実装 +- [ ] `.failed` marker 書き出し + pending file 生成ロジック実装 +- [ ] 冪等性 guard (既存 marker / pending file 検出時の skip) +- [ ] integration test: 人為的に orphan meta.json を作成して reaper が再起動 trigger することを assert +- [ ] dogfood: 既存の orphan (`.takt/runs/20260504-101353-post-merge-feedback-for-109/`) を fixture として retroactive detection 確認 +- [ ] 派生プロジェクトに deploy +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- kill -9 / power loss シミュレート (forcibly kill) で `.failed` marker と pending file が遅延生成される +- Drop guard (順位 63) が機能している正常 case では reaper が誤検出しない (false positive ゼロ) +- 既存 orphan (PR #109 のもの) を retroactive に処理できる +- 仕様レベル: 「post-merge-feedback はマージ後 5 分以内に必ず完了 or 失敗 marker 化される」が AppCenter 級の SLA で保証される + +#### 詰まっている箇所 + +- SessionStart hook の発火頻度: 1 session 1 回しか走らないと、長時間 session 中に orphan が発生しても拾えない。`cli-pr-monitor` 経路と組み合わせるか、SessionStart + UserPromptSubmit の二段階検出が必要か検討 +- 5 分閾値の妥当性: takt の analyze step は最大 5-10 分かかる場合あり。閾値を 5 分にすると進行中の正常 run を誤検出するリスク。10-15 分が妥当か + +--- + +### exe + `--help` を PreToolUse でブロックして `src//` Read に誘導する hook (PR #109 T1-3 採用) ★ Bundle c + +> **動機**: PR #109 SIGPIPE 事故の **直接トリガ** が「AI が `cli-merge-pipeline.exe --help` を実行 → 当該 exe は `--help` 未対応のため merge 本体を実行 → 出力 truncate で SIGPIPE」だった。ユーザー提案: exe ごとに `--help` を実装する案は exe 数増加で漏れが出るが、`exe + --help` をセットで PreToolUse block すればソース閲覧フローに自動誘導でき、想定外実行を構造的に排除。今後追加される exe にも自動適用される一般解。 +> +> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の trigger pattern 防止層。順位 63 / 64 が「中断されても recovery する」事後対策、本 task は「中断パターンを発生させない」事前対策。 +> +> **参照**: `.claude/feedback-reports/109.md` Tier 1 #3、`.claude/hooks-config.toml` (PreToolUse block_pattern)、`src/hooks-pre-tool-validate*/` +> +> **実行優先度**: 🚀 **Tier 1 High** — Effort S。ユーザー提案の事前防衛策。 + +#### 設計決定 (案) + +- **検出パターン** (regex): + - `(?:\.\\.claude\\|\\./|^|\s)(?:[\w\-]+\.exe|cli-[\w\-]+\.exe)\s+(?:--help|-h|/\?)\b` + - exe 名は `cli-*.exe` / `hooks-*.exe` / `check-*.exe` 等を含む全 Rust exe 想定 + - 引数が `--help` / `-h` / `/?` の **単独実行** に限定 (`exe foo --help` のような subcommand help は対象外) +- **ブロック時の代替誘導メッセージ**: + ```text + exe の --help は本リポジトリで未実装の可能性があります。 + 詳細を見るには次を試してください: + - ソースを Read: src//src/main.rs (引数定義は clap struct を確認) + - 既存 docs を検索: grep -r "" docs/ + ``` +- **配置先**: `src/hooks-pre-tool-validate*/` の Bash command validation ロジック (既存 git block と同居) +- **適用範囲**: Bash tool での実行のみ。Read tool 等での参照は対象外 + +#### 作業計画 + +- [ ] 既存 `hooks-pre-tool-validate*` の構造を確認 (Rust exe か Python か) +- [ ] regex パターン設計 + テストケース作成 (TP / FP の境界明確化) + - TP: `cli-merge-pipeline.exe --help`、`./.claude/foo.exe -h` + - FP: `cargo run --help`、`gh pr view --help`、`exe foo --help` (subcommand) +- [ ] hook に block ロジック追加 + 代替誘導メッセージ実装 +- [ ] integration test: 上記 TP / FP ケースで block / pass を assert +- [ ] dogfood: 本 hook 有効状態で `cli-merge-pipeline.exe --help` を実行し block されることを確認 +- [ ] 派生プロジェクトに deploy +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- `exe + --help` 系コマンドが Bash tool 経由で block される +- block メッセージで「ソースを Read」フローに誘導される +- 既存の正規 `--help` (cargo / gh / pnpm 等) は誤検出しない +- 今後追加される exe にも自動適用される (regex で exe 名を限定列挙しないため) + +#### 詰まっている箇所 + +- regex の精度: `cli-merge-pipeline.exe` は対象だが `cargo --help` は対象外、という線引きを `.exe` suffix の有無で判定するか exe 名 prefix で判定するかで挙動が変わる。本リポジトリの全 exe を grep して命名規則を確認してから決定 +- AI 側の挙動学習: block されたとき AI が代替フロー (ソース Read) に正しく遷移するかの dogfood 観察。失敗するなら block message を強化 + +--- + +### 長時間 subprocess の pipe truncate 禁止ルールをグローバル明文化 (PR #109 T3-1 採用) ★ Bundle c + +> **動機**: PR #109 SIGPIPE 事故は「AI が長時間 subprocess (cli-merge-pipeline) の出力を `\| head -40` で truncate」したのが直接トリガ。順位 65 (PreToolUse block) が決定論層、本ルールは AI/人間の判断ガイド層。二層防御で hole を減らす。 +> +> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の知識層。決定論的 block では捕捉しきれないパターン (例: `pnpm push \| tail`、`gh pr view --json reviews \| jq`) も含めて AI に教育的に指示。 +> +> **参照**: `.claude/feedback-reports/109.md` Tier 3 #5、`~/.claude/rules/common/development-workflow.md`、`~/.claude/rules/common/git-workflow.md` +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。グローバルルール 1 セクション追加。 + +#### 設計決定 (案) + +- **配置先候補** (着手時に決定): + - **案 A**: `~/.claude/rules/common/development-workflow.md` の "Bash 実行ガイド" として新セクション追加 + - **案 B**: `~/.claude/rules/common/git-workflow.md` の "gh CLI 使用規則" の隣に "長時間 subprocess の出力扱い" 節を追加 + - 推奨: **案 A** (development-workflow が development pipeline 全般を扱うため整合性高い) +- **記述内容** (案): + - 長時間 subprocess (`pnpm push` / `pnpm merge-pr` / `cli-*.exe` / takt workflow) を **`\| head` / `\| tail` / `\| tee` で truncate しない** + - 理由: parent process の SIGPIPE で workflow が abrupt 中断され、`.failed` marker や成果物が silent loss する (PR #109 で実証) + - 代替策: 出力をファイルに redirect (`> out.log 2>&1`) または `run_in_background` で実行 (Bash tool のオプション) し、後から `tail out.log` 等で確認 + - 例外: 短命な subprocess (`ls`, `cat` 等) や exit code のみが必要な場合は OK +- **既存ルールとの関係**: gh CLI 使用規則 (token 効率) と相補。token 効率は --jq / -q による絞り込み、本ルールは長時間 process の中断回避 + +#### 作業計画 + +- [ ] 案 A / B のどちらを採用するか決定 (着手時に grep で類似 rule の配置を確認) +- [ ] 配置先に「長時間 subprocess の出力扱い」セクションを追加 (規則 + 理由 + 代替策 + 例外を 1 ページに集約) +- [ ] PR #109 SIGPIPE 事故を実例として inline 引用 (`docs/adr/adr-030-...md` 参照) +- [ ] 派生プロジェクトで global rule 反映を確認 (rule は global、自動適用) +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- グローバルルールに「長時間 subprocess の pipe truncate 禁止」が codify される +- 次回 AI が `pnpm push \| head` 系を打とうとした時、ルール参照で自己修正できる +- 順位 65 (block_pattern) と整合 (二層防御の上層 = ガイド、下層 = block) + +#### 詰まっている箇所 + +- 「長時間」の定義 ambiguity: `gh pr view` は通常短命だが rate-limit 中は長時間化する。閾値を秒数で明文化するか、特定 exe を列挙するかの判断 +- 例外列挙の網羅性: AI が「これは例外だろう」と自己判断する余地を残すと block_pattern (順位 65) との整合性が崩れる可能性 + +--- + +### ADR-030 に abrupt 終了時の振る舞いを spec として明記 (PR #109 T3-2 採用) ★ Bundle c + +> **動機**: PR #109 で露呈した「ADR-030 の決定論性が SIGPIPE / kill -9 / power loss で破綻する」問題は、ADR 本文で abrupt 終了時の挙動が **spec として明記されていなかった** ことが根本原因。順位 63 / 64 の実装が ADR-030 の "決定論的" の真の意味を closure する形で land する以上、ADR 本文も同タイミングで spec を拡張する必要がある。 +> +> **本タスクの位置づけ**: Bundle c (PR #109 post-merge-feedback 堅牢化) の仕様層。順位 63 / 64 の実装と同 PR で land して仕様/実装の整合性を保つ (実装単独で spec ドリフトしない)。 +> +> **参照**: `.claude/feedback-reports/109.md` Tier 3 #6、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) (試験運用) +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR 本文の "失敗マーカーによる recovery" 節を拡張。 + +#### 設計決定 (案) + +- **拡張する節**: ADR-030 の "失敗マーカーによる recovery" を「abrupt 終了 + reaper による多層保証」に拡張 +- **追記内容** (案): + - **L1 (in-process)**: Drop guard / signal trap で `Result::Err` 経路に依存せず `.failed` marker を保証 (順位 63 で実装) + - **L2 (out-of-process)**: orphan run reaper で `meta.json status=running` 5-15 分放置を検出し marker 補完 + 再起動 (順位 64 で実装) + - **致命系の挙動明記**: kill -9 / SIGKILL / power loss / OOM Killer → L1 で救済不可、L2 で救済 + - **仕様の SLA 化**: 「post-merge-feedback はマージ後 N 分以内に必ず完了 or .failed marker 化される」を保証ステートメントとして記述 +- **試験運用フラグの扱い**: 順位 63 / 64 land 後、本 ADR の "試験運用" フラグを外すか継続するかは dogfood 結果次第。本 task では仕様明記のみ、フラグ判断は別途 +- **関連 ADR との cross-link**: ADR-029 (pending file 自動起動) との関係明記、L2 reaper が ADR-029 経路を再利用する旨 + +#### 作業計画 + +- [ ] `docs/adr/adr-030-deterministic-post-merge-feedback.md` を読み、現行の "失敗マーカーによる recovery" 節を確認 +- [ ] 拡張内容を起草 (L1/L2 の責務分離 + SLA 化 + cross-link) +- [ ] 順位 63 / 64 と同 PR で land する前提で実装と整合 +- [ ] CLAUDE.md ADR index の ADR-030 description (試験運用フラグ等) も必要なら更新 +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- ADR-030 本文に L1 (in-process Drop guard) + L2 (out-of-process reaper) の責務分離が記述される +- abrupt 終了 (SIGPIPE / kill -9 / power loss / OOM) 時の挙動が spec として明記される +- post-merge-feedback の SLA (= マージ後 N 分以内に完了 or marker 化) がステートメントとして残る + +#### 詰まっている箇所 + +- 試験運用フラグの去就: 順位 63 / 64 で実装が完成しても、dogfood 期間が必要なら試験運用フラグは残す。本 task では仕様明記のみだが、フラグ判断と整合性を取る必要あり +- SLA の妥当性: 順位 64 の閾値 (5-15 分) と同期する必要があり、閾値が決まらないと SLA も書けない (依存関係) + +---