diff --git a/docs/todo-summary.md b/docs/todo-summary.md index b4fac504..7add9599 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -1,93 +1,90 @@ -# TODO 推奨実行順序サマリー - -> **本ファイルの位置付け**: `docs/todo.md` から「推奨実行順序サマリー」section を切り出した index 専用ファイル。各タスクの詳細は「ファイル」列に示された `docs/todoN.md` を参照する。`docs/todo.md` のサイズが 50KB を超え Claude Code 読み取り安定性に影響したため分離 (2026-05-09)。 -> -> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo9.md`、2026-05-25 PR #172 仕組み化方針切替セッション時に todo8.md が 60KB 到達したため todo9.md に移行) に記録する。 - - -## 推奨実行順序サマリー (2026-05-10 更新、ADR-033 採番管理簡素化 land 後) - -開発環境の作業効率への貢献度を基準にした推奨実行順序。詳細は各タスク冒頭の **「実行優先度」** 行を参照。 - -| 順位 | Tier | タスク | ファイル | 工数 | 依存 | -|---|---|---|---|---|---| -| 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | -| 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 | ADR-031 dogfood (本採用済 2026-06-01) + 順位 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 (本採用 2026-06-01) の facet 追加 or aggregate 前 Rust pre-step として組込、long-tail flake と coverage 全体監査 | -| 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 | **PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25)** | todo4.md | M | なし (順位 144 hook 化 dogfood 成功事例を踏襲、3 BlockedPattern = 応答破棄漏れ POST / `--jq` なし GET / CR walkthrough state 混入 を `exception` field 付きで実装、`feedback_pipeline_over_rules.md` 適用で rule → hook 切替、session 毎の rule load コスト不要) | -| 45 | 🔧 Tier 2 | **`check-ci-coderabbit --list-findings` Rust モード追加 (計画書 #D-3) ★ Bundle a Sub-PR 1** | todo4.md | M | なし (Sub-PR 1、cli-pr-monitor が消費する構造化 findings API を提供) | -| 46 | 🔧 Tier 2 | **CodeRabbit rate-limit auto-retry の integration test (PR #100 T2-1) ★ Bundle a Sub-PR 2** | todo4.md | M | 順位 42 と同 PR (Sub-PR 2、rate-limit auto-retry 実装と一体) | -| 49 | 🔧 Tier 2 | **`parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2** | todo7.md | M | 順位 42 / 43 / 46 と同 PR (Sub-PR 2、`unwrap_or_else(\|_\| empty)` silent fail 抑止 + cli-pr-monitor mock infra 流用) | -| 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、利用頻度低く優先度は低) | -| 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 | **`check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25)** | todo7.md | M | 順位 45 (`--list-findings` Rust モード) land が前提、`source: "inline" \| "review_body"` field 追加で同型 finding 化、手動 checklist (= 当初 rule 案、人間が忘れる課題) を programmatic 検出で置換、`feedback_pipeline_over_rules.md` 適用、analyze-coderabbit 連携で merge 前検出を構造化 | -| 78 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up** | todo5.md | S | なし (config が user-editable system boundary のとき `sanitize()` 値域検証を必須化し dependent arithmetic に `// SAFETY: により上限保証` コメントを要求するパターンを ADR + CLAUDE.md に codify、Rust 固有の checked_add + MAX_SAFE capping + time-dependent test の 3 層を明文化。2026-05-16 entry 登録時の旧予約 ADR-038 → ADR-041 振り直し → 順位 139 (PR #168 follow-up) ADR-041 取得に伴い 2026-05-22 再 placeholder 化、land 時 PR で空き番号確定 — 順位 135 codified placeholder policy の実例運用) | -| 79 | 💎 Tier 3 | **`docs-governance.md` § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用)** | todo5.md | XS | なし (PR #117 で順位 15 を Bb-3 で吸収済として削除した際、現 Step 2「残タスクを priority table に登録」が priority table から除外するケース = 完了/deprioritize/defer を未定義だった実証。除外時の commit/PR で 3 値のいずれかを明示する要件を追加して将来の同型 ambiguity を構造的に防ぐ) | -| 81 | 🚀 Tier 1 | **cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer)** | todo5.md | M | 1 観測のみで systemic 性未確認 (§A-2 P-5 PR で defer 判断、ADR-018 §追記 2026-05-08 で re-trigger 条件 = 2 件以上の同型観測を規定) | -| 92 | 🔧 Tier 2 | **scale-aware eval fixtures (200+ 行) — Phase d 投入前の必須 infrastructure (PR #132 T2-#5 採用)** | todo6.md | M | なし (PR #132 smoke で観測した mistral:7b 大規模 diff JSON 不完全 (`missing field 'screen_decision'`) を fixture 化、Phase d 着手前の改善 ループ reference point 確保。順位 91 = Bundle i ペアタスクは既存 test カバー判明で 2026-05-24 削除済) | -| 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、独立並列実施可) | -| 97 | 🔧 Tier 2 | **`with_num_ctx(X)` override 値 serialization 検証テスト (PR #136 T2-#1 採用)** | todo6.md | S | なし (PR #136 で追加した builder method の wiring を mockito で seal、Phase d で num_ctx tweak する局面の silent degrade 防止、CodeRabbit が見逃した test gap を post-merge-feedback agent が独立発見) | -| 100 | 💎 Tier 3 | **`development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用)** | todo6.md | XS | なし (PR #119/#120/#121 sub-PR 分割 + PR #139 partial completion で systemic に観測された 2 暗黙知を `~/.claude/rules/common/development-workflow.md` に codify、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化のため非機械強制でも採用相当) | -| 105 | 💎 Tier 3 | **グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/CLAUDE.md` に `pattern` / `extensions` / `severity` (planned: `paths`) の field 一覧を表形式で追加、派生プロジェクト (techbook-ledger / auto-review-fix-vc) で rule porting 時の理解統一、順位 103 の code comment と相補) | -| 107 | 💎 Tier 3 | **`development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に「マージ後 N 日間 todo.md 残存 → 後続 phase で手動発見」事例を追記、memory `feedback_verify_task_not_already_done` を central rule にも反映、`feedback_todo_no_history` と合わせて「マージ → 即削除」サイクルを強調) | -| 108 | 💎 Tier 3 | **CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用)** | todo6.md | S | なし (`~/.claude/CLAUDE.md` に memory `feedback_no_unenforced_rules` の policy をユーザー可視 table として公開、Tier 2 と称した必須化ルール提案を新セッションでも一貫して却下できる構造、memory ファイル閉鎖を補完) | -| 110 | 💎 Tier 3 | **pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用)** | todo6.md | S | なし (Phase A の `overflow_hint()` をモデル例とし「境界値 / None / 閾値未満」3 パターンの test テンプレを `~/.claude/rules/common/testing.md` に追記、副作用分離の促進、Rust lib 全般で再利用) | -| 111 | 💎 Tier 3 | **`docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用)** | todo6.md | S | なし (Phase/bundle 関連 → todo6、global rules/lint → todo5 等の routing rule を `~/.claude/rules/common/docs-governance.md` に追記、PR #142 で実証された file pointer bifurcation の構造的予防、CR Minor #2 と同根) | -| 117 | 💎 Tier 3 | **`coding-style.md § Cross-File Reference Lifecycle` に ephemeral → permanent 知識移管 edit order 追記 (PR #145 T3-#3 採用)** | todo8.md | S | なし (PR #145 で lib.rs L128-139 → ADR-040 移管 + Phase C/D empirical data 移管の 2 観測。既存ルール (参照方向制約) と complementary な「① permanent target 先行作成・validate → ② 参照追加 → ③ 参照元削除」3 ステップ原則を `~/.claude/rules/common/coding-style.md` に codify、次回 ephemeral 計画書 retire 時の checklist として再利用) | -| 118 | 💎 Tier 3 | **rule⑧ への paths filter 適用範囲検討 (順位 102 land 時の意図的保留、follow-up)** | todo8.md | XS | 順位 102 (PR #148 land 済、Phase D D-3) で paths filter は実装済だが、rule⑧ への `paths = ["docs/**/*.md"]` migration は D-2 (PR #146、順位 101) で追加した root-level MD fire intent を壊すため保留。4 案 (保留継続 / broader glob / explicit list / rule split) の trade-off 評価を ADR-007 amendment (順位 104) と整合させて結論を出す | -| 128 | 💎 Tier 3 | **CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用)** | todo8.md | XS | なし (PR #133 (todo.md 分割) + PR #153 (analysis.md 分割) の successful pattern を明文化、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | -| 133 | 💎 Tier 3 | **docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = grep hit は実ファイル Read で確認」明記 (PR #156 T3 #1 採用)** | todo8.md | XS | なし (PR #156 で 5 件以上の false alarm 発生、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | -| 135 | 💎 Tier 3 | **todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来)** | todo8.md | XS | なし (順位 78 (旧 ADR-038 → ADR-041) で番号 conflict が顕在化、queue 滞留 entry の hardcode が後発 PR の採番と衝突する構造リスクを convention で予防、`~/.claude/rules/common/docs-governance.md` に 2-3 行追記。採番予約簿は管理コスト過剰のため見送り、land 時 PR で空き番号確定の軽量運用に統一) | -| 140 | 💎 Tier 3 | **順位 135「codified placeholder policy」を正式 ADR に昇格 (PR #169 T3-#2 採用)** | todo8.md | S | なし (順位 135 entry を retire し、ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy として永続化。PR #111/#132/#169 の 3+ PR で適用実証済 — PR #169 で「ADR-038 → 041 → NNN」3 段振り直し dogfood が land、ephemeral todo entry 限りでは派生プロジェクトへの transferability 不足、`feedback_no_unenforced_rules.md` 例外 = 既存実践 (3 PR で実証) の明文化 + 後続 entry が同 policy を参照する際の永続 reference 確保) | -| 143 | 🔧 Tier 2 | **複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171** | todo8.md | S | なし (PR #151/#171 の 2 PR 横断で multi-byte fixture 手動組み立てコストが Frequency Medium で観測、Japanese / emoji / combining chars helper 3 関数を標準化して新規 string-processing 関数追加時の boundary test コスト削減 + silent regression early detection、順位 142 + 144 と同 PR で land 推奨) | -| 145 | 🔧 Tier 2 | **preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用)** | todo8.md | M | なし (PR #172 Phase 3 で `jj-message-required` が opt-in preset であることを前提とせず test を書き rewrite が必要になった経緯、preset architecture の implicit assumption (always-enabled vs config-selectable) を classification 表として test レベルで codify、新 preset 追加時に matrix 更新を強制する mechanical enforcement で design misalignment を構造的検出、target は main.rs (feedback report の lib.rs 記載は誤り)) | -| 146 | 🚀 Tier 1 | **Secret detection PreToolUse hook 追加 — AWS/OpenAI/GitHub token 等の hardcoded secret 検出 (PR #172 仕組み化方針切替由来、`security.md` § Secret Management 移管) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`~/.claude/rules/common/security.md` § Secret Management 記述のみで機械強制なし、AWS Access Key / OpenAI sk- / GitHub ghp_/gho_/ghs_ / Anthropic sk-ant- 等 6+ 種 pattern を `preset_secret_detection` で regex 検出 + 即 block、順位 144 hook 化 template 踏襲、security-critical かつ漏洩観測前の preventive 層として Tier 1、rule docs § Secret Management を hook block message に集約で縮小) | -| 147 | 🔧 Tier 2 | **File length lint (800 行 max) 追加 — `coding-style.md` § File Organization 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`~/.claude/rules/common/coding-style.md` § File Organization の 800 行 max を `hooks-post-tool-comment-lint-rust` に追加、順位 48 関数長と同 touch-trigger ratchet pattern で grandfather 適用、Rust 限定 MVP、順位 57 truncate contract 整合、rule docs から具体閾値削除で縮小) | -| 148 | 🔧 Tier 2 | **Test coverage 80% CI gate 追加 — `testing.md` § Minimum Test Coverage 80% 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S-M | なし (`~/.claude/rules/common/testing.md` § 80% coverage ガイドラインを実行時 gate に変換、`cargo llvm-cov --fail-under-lines 80` を push-runner-config.toml [quality_gate] に integration 推奨、現状未測定のため段階導入計画必要、rule docs § 80% coverage を実行時 gate 参照に縮小) | -| 149 | 🔧 Tier 2 | **Long-running subprocess pipe truncate hook 拡張 — `development-workflow.md` § subprocess pipe truncate 禁止 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (既存 `exe-help-block` preset を `cli-*.exe ... \| (head\|tail\|awk)` 等の副作用ある subprocess 出力 truncate にも拡張 or 新 `subprocess-pipe-truncate-block` preset 追加、PR #109 SIGPIPE 事故 root cause の構造化、順位 44 (gh-token-efficiency) との scope 境界整理必要、development-workflow.md § 該当 section 縮小) | -| 150 | 🔧 Tier 2 | **Magic number lint 追加 — `coding-style.md` § Magic Numbers 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = source folder 限定) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`.claude/custom-lint-rules.toml` に `no-magic-number` rule 追加、source folder paths filter で test/config 除外、時間定数 / リトライ回数 / threshold の 3 category MVP、severity warning で reviewer 判断補助、順位 102 paths filter + 順位 118 適用範囲検討と整合、coding-style.md § Magic Numbers 削除可否は dogfood 後判断) | -| 151 | 🔧 Tier 2 | **PR diff lines check 追加 — `git-workflow.md` § Multi-PR chaining 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = 条件付き block 3 段階) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`src/cli-push-runner/src/stages/pr_size_check.rs` 新 stage 追加、`push-runner-config.toml` `[pr_size_check]` section で threshold 設定可能化 (default: block 1500 / warning 800)、jj diff stat 計測、大型 refactoring 時の override は config 編集、git-workflow.md § Multi-PR chaining 縮小) | -| 152 | 🔧 Tier 2 | **todo entry 削除時の事前 land 確認手順 — 順位 136 hook 拡張 or 独立 follow-up (PR #173 T2-1 採用、2026-05-26)** | todo9.md | XS-S | 順位 136 (working copy staleness + 既実装 grep) と同型機械強制、lifecycle 補完 = 順位 136 (add/edit 時) + 本タスク (delete 時)。PreToolUse hook で `docs/todo*.md` 削除時に対応 land commit を `jj log` で grep 検証、land 確認なら allow + 証跡出力、未確認なら warning (block しない)。順位 136 hook 統合 (~+15 行) or 独立 (~40 行) のいずれか、ADR-042 § Decision matrix 適用 (mechanizable + FP 低 + Adoption Risk None) | -| 153 | 🔧 Tier 2 | **`review-harness-whole` facet 追加 — 観点 ① 独立 facet 化 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | S | ADR-031 本採用後 (2026-06-01) の Phase B+1 拡張、extract 不要と判明したら close、順位 146-151 Bundle 既存ルール仕組み化の継続的発見源、architecture-whole から ① 観点を extract して context 圧迫回避 | -| 154 | 🔧 Tier 2 | **`review-todo-whole` facet + aggregate 前 file size pre-step — 観点 ⑤ ⑦ 拡張 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | M | 順位 136 land + ADR-031 本採用 (2026-06-01) 後着手、cli-docs-lint (preamble) / 順位 147 (file length) と scope 整理必要 (CI 即時 vs 週次 batch)、ADR-031 3 層分離原則で file size は LLM 不要の Rust pre-step に分離 | -| 157 | 🔧 Tier 2 | **Bundle 1 dogfood checklist 実行 — `__test.ps1` block + override env 確認 (PR #174 T2-#2 採用、ADR-039 bounded lifetime data point #1)** | todo9.md | XS | なし (PR #174 PR body の未消化 dogfood、Bundle 2 PR merge 前の前提条件として消化、結果は Bundle 2 PR body に記録) | -| 160 | 💎 Tier 3 | **`docs-governance.md` に「ADR multi-variant pattern section 追加時の checklist」codify (PR #176 T3-#1 採用)** | todo9.md | XS | なし (PR #175 Minor + PR #176 Nitpick の 2 連続観測 = Frequency Medium で採用条件成立、ADR 拡張時の variant 網羅性 + 擬似コード vs 実コード齟齬を reviewer / Claude 視点で防止する checklist、global file `~/.claude/rules/common/docs-governance.md` 編集のため本リポジトリ外で実施、`feedback_global_config_backup` 適用) | -| 161 | 🔧 Tier 2 | **Subprocess timeout+kill lifecycle 検証テスト追加 (PR #177 T2-#1 採用)** | todo9.md | M | なし (PR #177 Major #2 「jj kill on timeout 漏れ」fix の回帰テスト、`Child::is_finished` で 2 hook の `run_jj_with_timeout` lifecycle 検証、Severity High + Frequency Medium、ADR-024 shared lib 統合候補との関係明示) | -| 162 | 🔧 Tier 2 | **fail-closed error path (Option::None) 個別テスト追加 (PR #177 T2-#2 採用)** | todo9.md | S | なし (PR #177 Major #1 「`behind.unwrap_or(0)` fail-closed 漏れ」fix の回帰テスト、`check_todo_staleness` / `build_todo_staleness_message` の None ケース独立検証、Severity High + Frequency Medium、security gate + Option return pattern の reference) | -| 163 | 🔧 Tier 2 | **Cross-ref edge case test coverage 追加 — percent-encode / GFM heading slug / relative path normalize (PR #179 T2-#1 採用)** | todo9.md | S | なし (PR #179 で cli-docs-lint の cross_ref validator を新規実装したが、percent-encode (`%20` / `%23`) / heading slug / `../` resolve の edge case が fixture テストで明示的に保護されていない silent regression リスク回避) | -| 165 | 🔧 Tier 2 | **`pnpm create-pr` PR body truncation 回避を検証する e2e/integration test 追加 (PR #181 T2-#1 採用)** | todo9.md | S | なし (PR #134 + #181 の 2 回観測で Medium frequency に昇格、memory `feedback_pnpm_create_pr_body` の `--body-file` workaround を自動 regression gate 化、shell argument truncation の境界 (行数/バイト数) を fixture で測定、silent UX 劣化の早期検出、cli-pr-monitor の argv 組み立て層を test 対象、順位 166 と相補 = test 層 vs docs 層) | -| 170 | 💎 Tier 3 | **`git-workflow.md § Multi-PR chaining` を「1 PR 内 multi-commit + intent 明記」パターンに拡張 (PR #183 T3-#1 採用)** | todo9.md | S | なし (PR #119/#120/#121 + #183 の 4 観測で Frequency High、commit 分割判断 + intent 記述ガイドを既存 section に追記、`~/.claude/rules/common/git-workflow.md` 編集、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須) | -| 171 | 💎 Tier 3 | **`docs-governance.md` に「Operational reference vs Pointer reference」区別 section を追加 (PR #183 T3-#2 採用) ★ Bundle DG-RULES** | todo9.md | S | 順位 172 と同 PR 推奨、PR #183 A01 修正で実適用した判定ロジック (operational = workflow 動作記述 = 保持可 / pointer = section 名・順位番号参照 = 置換必要) を `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section として codify、ADR-031 lines 79-302 中 line 270 のみが真の pointer だった実例を inline cite、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須 | -| 172 | 💎 Tier 3 | **CR ephemeral artifact Nitpick の統一 skip 基準を memory に codify (PR #183 T3-#3 採用) ★ Bundle DG-RULES** | todo9.md | XS | 順位 171 と同 PR 推奨、CR が `docs/todo*.md` 系 ephemeral artifact 内の行番号参照を Nitpick 指摘した場合は skip 推奨という判断基準を新 memory `feedback_coderabbit_ephemeral_nitpick.md` に codify、既存 memory `feedback_coderabbit_no_actionable_merge_signal` の補完、本リポジトリ専用 (派生プロジェクトには波及しない)、`feedback_global_config_backup` 適用推奨 | -| 173 | 🔧 Tier 2 | **`combine_output` 5 crate 重複を `lib-runner-utils` (or 既存 lib-*) に extract (PR #182 dry-run S01 採用)** | todo9.md | S-M | なし (`src/cli-pr-monitor/src/runner.rs:80-89` の `combine_output` 8 行関数が `#[allow(dead_code)]` 付与で生産未使用、同関数が 4 他 crate (cli-push-runner, cli-push-pipeline, cli-merge-pipeline, hooks-post-tool-linter) にも複製 = 5 crate 横断 systemic duplication、ADR-026 Cargo workspace + ADR-012 lib-* naming で解決、Phase B dogfood の最初の実体ベース finding (A01 と並ぶ)、A01 は PR #183 で fix 済) | -| 176 | 🔧 Tier 2 | **check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用)** | todo10.md | M | なし (順位 167-169 Bundle CR-RL の follow-up、bold-wrapper variant (`**More reviews will be available**`) / 短形態 (secs のみ) / 複数 separator / wait time なし graceful failure の 4 fixture 追加、PR #182 + #185 の 2 PR 連続観測で CR format 多様性 systemic、`extract_old_format_wait_time` / `extract_new_format_wait_time` の coverage gap 補填、regex 拡張 vs fixture 先行の 2 アプローチを着手時判断、analyzer rationale の「Edit 集中 = test gap signal」は incidental で採用根拠から除外、true 採用根拠は format 多様性 + 防御的 variant) | -| 177 | 🚀 Tier 1 | **PostToolUse hook — Edit / Write したファイルのサイズ閾値超過を検出してファイル分割を促す (2026-05-29 ユーザー追加要望)** | todo10.md | S-M | なし (本セッション PR #181-#185 chain で `docs/todo9.md` が 50KB 超 + 1168 行に到達し `docs/todo10.md` split した実体観測ベース、PR #133 (todo.md → todo2.md) / PR #172 (todo8.md → todo9.md) / 本 PR (todo9.md → todo10.md) の 3 PR 観測で systemic、PostToolUse Edit/Write 直後にサイズチェックを mechanical 強制、`.claude/hooks-config.toml` の `[post_tool_use.file_size_check]` で `enabled = false` default OFF (ADR-039 opt-in) + `threshold_bytes` (default 51200 = 50KB) + `paths` glob + `touch_trigger` ratchet を設定可能、配置先は option A = 新 binary `hooks-post-tool-file-size-check` / option B = 既存 `hooks-post-tool-linter` 統合の 2 案を着手時判断、ADR-007 custom-linter layer boundary に位置付け追記) | -| 178 | 🔧 Tier 2 | **`state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/cli-pr-monitor/src/state.rs:226-510` の test が JSON round-trip のみ、`rate_limit=Some` 時 CI 更新 skip 等の behavioral invariant 未検証、ADR-041 sentinel 事前投入 + mutation 不在 assert pattern で 3-5 test 追加、memory `feedback_test_dry_antipattern` 適用、Effort S で high value catches state regression) | -| 179 | 🔧 Tier 2 | **rate-limit retry decision boundary test を rstest parameterized で追加 (週次レビュー 2026-05-30 S03 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/cli-pr-monitor/src/config.rs:94-122` + `stages/poll.rs` の `max_retries=3` 固定 test のみで boundary (0/1/3/off-by-one) 未検証、rstest parameterized で 3-4 case 追加 ~15 行、rstest 既存使用 + Bundle CR-RL = 順位 167-169 隣接領域 follow-up、off-by-one regression が test で検出可能化) | -| 180 | 🔧 Tier 2 | **`lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/lib-report-formatter/src/lib.rs:51-79` の `format_table()` が PR title / commit message の `|` / `\n` を escape せず markdown table 構造を破壊 → downstream AI facet で prompt injection リスク、`escape_markdown_pipe()` 5 行 utility + call site escape + 5 variant test で defense-in-depth 確立、本セッション 5 PR chain で AI facet 連鎖が systemic 化したため継続価値高) | -| 181 | 🔧 Tier 2 | **`aggregate-weekly` facet の `findings.json` 出力を raw JSON にする (Phase D dogfood D-A 採用)** | todo10.md | XS-S | なし (本セッション 2026-05-30 Phase D dogfood で実観測した facet 出力 bug、`aggregate-weekly.md` instruction が「raw JSON 出力必須、markdown code fence で囲まない」を明示せず facet LLM が ` \`\`\`json...\`\`\` ` で wrap してしまう、skill 側の手動 fence strip workaround を不要化、修正後の次 `/weekly-review` で raw JSON 出力を dogfood 観測、Phase E 試験運用前の整備) | -| 182 | 🔧 Tier 2 | **`/weekly-review` skill に重複検出 (簡易 grep) を Phase 4 で追加 (Phase D dogfood D-B 採用)** | todo10.md | XS-S | なし (本セッション 2026-05-30 Phase D dogfood で WR-2026-05-30-S05 と既存 順位 173 が完全重複していた実観測、ADR-031 § Phase 4 「重複検出は MVP では実装しない」を「MVP+1 (簡易 grep + 3 択 AskUserQuestion: augment/新規/skip)」相当に格上げ、自動 merge なし原則は維持、description 先頭 40 chars の grep ヒット警告 → user 判断、`feedback_global_config_backup` 適用必須 (~/.claude/skills/ 編集前 snapshot)) | - -**戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 - -**Bundle 履歴**: 完了済 Bundle / post-merge-feedback 反映の経緯詳細は [docs/bundle-history.md](bundle-history.md) を参照 (2026-05-25 分離、本ファイルの index 責務集中のため)。 +# TODO 推奨実行順序サマリー + +> **本ファイルの位置付け**: `docs/todo.md` から「推奨実行順序サマリー」section を切り出した index 専用ファイル。各タスクの詳細は「ファイル」列に示された `docs/todoN.md` を参照する。`docs/todo.md` のサイズが 50KB を超え Claude Code 読み取り安定性に影響したため分離 (2026-05-09)。 +> +> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo10.md`、2026-05-29 PR #186 時点で新設、以降の新規エントリ受入先) に記録する。なお `docs/todo11.md` は 2026-06-06 todo9.md 分割で新設された専用ファイル (順位 157, 160-173 を収容) で、新規追加先ではない。 + + +## 推奨実行順序サマリー (2026-05-10 更新、ADR-033 採番管理簡素化 land 後) + +開発環境の作業効率への貢献度を基準にした推奨実行順序。詳細は各タスク冒頭の **「実行優先度」** 行を参照。 + +| 順位 | Tier | タスク | ファイル | 工数 | 依存 | +|---|---|---|---|---|---| +| 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | +| 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 | なし (Status update 2026-06-06: ADR-018 park モデル / ADR-030 短命プロセス移行後の再現確認が前段必要、未再現なら削除候補) | +| 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 後推奨 (Status update 2026-06-06: ADR-037 fix-trust shortcut / ADR-043 fail-closed / PR #194 mechanical gate land 後の残余 case baseline 観測が前段、5-10 PR で iteration 上限到達確認後に着手判断) | +| 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 | ADR-031 dogfood (本採用済 2026-06-01) + 順位 20 | +| 22 | 💎 Tier 3 | ADR-032 PR-δ: dogfood + メトリクス検証 | todo2.md | (運用) | 順位 21 | +| 27 | 🧹 Tier 4 | ADR-030 Phase E/F: 旧機構廃止 + dogfood | todo.md | 中 | なし (cleanup、Status update 2026-06-06: Phase D-7 = PR #154 land 済、残 Phase E 旧機構廃止 + Phase F dogfood) | +| 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 採用昇格済 (PR #192) → Bundle W/X (順位 34/35/36/37) land のみ残依存、facet 追加 or aggregate 前 Rust pre-step として組込 | +| 40 | 🚀 Tier 1 | **prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2)** | todo4.md | XS | なし (Status update 2026-06-06: PR #175 で push-runner 側 `bookmark_check.rs` stage 実装済 → skill 側は二重防御 + 派生プロジェクト未 deploy 環境向け knowledge transfer に縮小) | +| 44 | 💎 Tier 3 | **PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25)** | todo4.md | M | なし (順位 144 hook 化 dogfood 成功事例を踏襲、3 BlockedPattern = 応答破棄漏れ POST / `--jq` なし GET / CR walkthrough state 混入 を `exception` field 付きで実装、`feedback_pipeline_over_rules.md` 適用で rule → hook 切替、session 毎の rule load コスト不要) | +| 49 | 🔧 Tier 2 | **`parse_findings` 系の error-path test infrastructure (PR #101 T2-1)** | todo7.md | M | なし (Status update 2026-06-06: 元 Bundle a Sub-PR 2 (順位 42/43/46) は段階 land 完了で消滅、本 task は単独で `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 | なし (Status update 2026-06-06: 採用案 C = `fix.md` instruction 追加は land 済、残作業 = dogfood 観測のみ、6-iter outlier 解消確認後に削除可) | +| 52 | 💎 Tier 3 | **comment-lint hook の MultiEdit 対応 (順位 50 follow-up)** | todo7.md | S | なし (順位 50 で v1 = Edit のみ実装、MultiEdit は whole-file fallback で no-regression、利用頻度低く優先度は低) | +| 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 | **`check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25)** | todo7.md | M | なし (Status update 2026-06-06: 旧依存 順位 45 = `--list-findings` Rust モードは PR #101 で land 済、本 task は `source: "inline" \| "review_body"` field 追加で同型 finding 化、手動 checklist (= 当初 rule 案) を programmatic 検出で置換、`feedback_pipeline_over_rules.md` 適用、analyze-coderabbit 連携で merge 前検出を構造化、即着手可能) | +| 78 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up** | todo5.md | S | なし (config が user-editable system boundary のとき `sanitize()` 値域検証を必須化し dependent arithmetic に `// SAFETY: により上限保証` コメントを要求するパターンを ADR + CLAUDE.md に codify、Rust 固有の checked_add + MAX_SAFE capping + time-dependent test の 3 層を明文化。2026-05-16 entry 登録時の旧予約 ADR-038 → ADR-041 振り直し → 順位 139 (PR #168 follow-up) ADR-041 取得に伴い 2026-05-22 再 placeholder 化、land 時 PR で空き番号確定 — 順位 135 codified placeholder policy の実例運用) | +| 79 | 💎 Tier 3 | **`docs-governance.md` § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用)** | todo5.md | XS | なし (PR #117 で順位 15 を Bb-3 で吸収済として削除した際、現 Step 2「残タスクを priority table に登録」が priority table から除外するケース = 完了/deprioritize/defer を未定義だった実証。除外時の commit/PR で 3 値のいずれかを明示する要件を追加して将来の同型 ambiguity を構造的に防ぐ) | +| 81 | 🚀 Tier 1 | **cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer)** | todo5.md | M | 1 観測のみで systemic 性未確認 (§A-2 P-5 PR で defer 判断、ADR-018 §追記 2026-05-08 で re-trigger 条件 = 2 件以上の同型観測を規定) | +| 92 | 🔧 Tier 2 | **scale-aware eval fixtures (200+ 行) — 大規模 diff dogfood 信頼性継続改善 (PR #132 T2-#5 採用)** | todo6.md | M | なし (Status update 2026-06-06: ADR-038 採用昇格済 (PR #156) で Phase d は運用入り、動機を「投入前 infrastructure」→「運用中の継続改善」に書き換え、優先度 must→should に若干低下するが大規模 diff の fallback rate 測定 infrastructure として継続価値あり) | +| 100 | 💎 Tier 3 | **`development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用)** | todo6.md | XS | なし (PR #119/#120/#121 sub-PR 分割 + PR #139 partial completion で systemic に観測された 2 暗黙知を `~/.claude/rules/common/development-workflow.md` に codify、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化のため非機械強制でも採用相当) | +| 105 | 💎 Tier 3 | **グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/CLAUDE.md` に `pattern` / `extensions` / `severity` (planned: `paths`) の field 一覧を表形式で追加、派生プロジェクト (techbook-ledger / auto-review-fix-vc) で rule porting 時の理解統一、順位 103 の code comment と相補) | +| 107 | 💎 Tier 3 | **`development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に「マージ後 N 日間 todo.md 残存 → 後続 phase で手動発見」事例を追記、memory `feedback_verify_task_not_already_done` を central rule にも反映、`feedback_todo_no_history` と合わせて「マージ → 即削除」サイクルを強調) | +| 108 | 💎 Tier 3 | **CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用)** | todo6.md | S | なし (`~/.claude/CLAUDE.md` に memory `feedback_no_unenforced_rules` の policy をユーザー可視 table として公開、Tier 2 と称した必須化ルール提案を新セッションでも一貫して却下できる構造、memory ファイル閉鎖を補完) | +| 110 | 💎 Tier 3 | **pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用)** | todo6.md | S | なし (Phase A の `overflow_hint()` をモデル例とし「境界値 / None / 閾値未満」3 パターンの test テンプレを `~/.claude/rules/common/testing.md` に追記、副作用分離の促進、Rust lib 全般で再利用) | +| 111 | 💎 Tier 3 | **`docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用)** | todo6.md | S | なし (Phase/bundle 関連 → todo6、global rules/lint → todo5 等の routing rule を `~/.claude/rules/common/docs-governance.md` に追記、PR #142 で実証された file pointer bifurcation の構造的予防、CR Minor #2 と同根) | +| 117 | 💎 Tier 3 | **`coding-style.md § Cross-File Reference Lifecycle` に ephemeral → permanent 知識移管 edit order 追記 (PR #145 T3-#3 採用)** | todo8.md | S | なし (PR #145 で lib.rs L128-139 → ADR-040 移管 + Phase C/D empirical data 移管の 2 観測。既存ルール (参照方向制約) と complementary な「① permanent target 先行作成・validate → ② 参照追加 → ③ 参照元削除」3 ステップ原則を `~/.claude/rules/common/coding-style.md` に codify、次回 ephemeral 計画書 retire 時の checklist として再利用) | +| 118 | 💎 Tier 3 | **rule⑧ への paths filter 適用範囲検討 (順位 102 land 時の意図的保留、follow-up)** | todo8.md | XS | 順位 102 (PR #148 land 済、Phase D D-3) で paths filter は実装済だが、rule⑧ への `paths = ["docs/**/*.md"]` migration は D-2 (PR #146、順位 101) で追加した root-level MD fire intent を壊すため保留。4 案 (保留継続 / broader glob / explicit list / rule split) の trade-off 評価を ADR-007 amendment (順位 104) と整合させて結論を出す | +| 128 | 💎 Tier 3 | **CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用)** | todo8.md | XS | なし (PR #133 (todo.md 分割) + PR #153 (analysis.md 分割) の successful pattern を明文化、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | +| 133 | 💎 Tier 3 | **docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = grep hit は実ファイル Read で確認」明記 (PR #156 T3 #1 採用)** | todo8.md | XS | なし (PR #156 で 5 件以上の false alarm 発生、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | +| 135 | 💎 Tier 3 | **todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来)** | todo8.md | XS | なし (順位 78 (旧 ADR-038 → ADR-041) で番号 conflict が顕在化、queue 滞留 entry の hardcode が後発 PR の採番と衝突する構造リスクを convention で予防、`~/.claude/rules/common/docs-governance.md` に 2-3 行追記。採番予約簿は管理コスト過剰のため見送り、land 時 PR で空き番号確定の軽量運用に統一) | +| 140 | 💎 Tier 3 | **順位 135「codified placeholder policy」を正式 ADR に昇格 (PR #169 T3-#2 採用)** | todo8.md | S | なし (順位 135 entry を retire し、ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy として永続化。PR #111/#132/#169 の 3+ PR で適用実証済 — PR #169 で「ADR-038 → 041 → NNN」3 段振り直し dogfood が land、ephemeral todo entry 限りでは派生プロジェクトへの transferability 不足、`feedback_no_unenforced_rules.md` 例外 = 既存実践 (3 PR で実証) の明文化 + 後続 entry が同 policy を参照する際の永続 reference 確保) | +| 143 | 🔧 Tier 2 | **複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171** | todo8.md | S | なし (PR #151/#171 の 2 PR 横断で multi-byte fixture 手動組み立てコストが Frequency Medium で観測、Japanese / emoji / combining chars helper 3 関数を標準化して新規 string-processing 関数追加時の boundary test コスト削減 + silent regression early detection、順位 142 + 144 と同 PR で land 推奨) | +| 145 | 🔧 Tier 2 | **preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用)** | todo8.md | M | なし (PR #172 Phase 3 で `jj-message-required` が opt-in preset であることを前提とせず test を書き rewrite が必要になった経緯、preset architecture の implicit assumption (always-enabled vs config-selectable) を classification 表として test レベルで codify、新 preset 追加時に matrix 更新を強制する mechanical enforcement で design misalignment を構造的検出、target は main.rs (feedback report の lib.rs 記載は誤り)) | +| 146 | 🚀 Tier 1 | **Secret detection PreToolUse hook 追加 — AWS/OpenAI/GitHub token 等の hardcoded secret 検出 (PR #172 仕組み化方針切替由来、`security.md` § Secret Management 移管) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`~/.claude/rules/common/security.md` § Secret Management 記述のみで機械強制なし、AWS Access Key / OpenAI sk- / GitHub ghp_/gho_/ghs_ / Anthropic sk-ant- 等 6+ 種 pattern を `preset_secret_detection` で regex 検出 + 即 block、順位 144 hook 化 template 踏襲、security-critical かつ漏洩観測前の preventive 層として Tier 1、rule docs § Secret Management を hook block message に集約で縮小) | +| 147 | 🔧 Tier 2 | **File length lint (800 行 max) 追加 — `coding-style.md` § File Organization 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`~/.claude/rules/common/coding-style.md` § File Organization の 800 行 max を `hooks-post-tool-comment-lint-rust` に追加、順位 48 関数長と同 touch-trigger ratchet pattern で grandfather 適用、Rust 限定 MVP、順位 57 truncate contract 整合、rule docs から具体閾値削除で縮小) | +| 148 | 🔧 Tier 2 | **Test coverage 80% CI gate 追加 — `testing.md` § Minimum Test Coverage 80% 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S-M | なし (`~/.claude/rules/common/testing.md` § 80% coverage ガイドラインを実行時 gate に変換、`cargo llvm-cov --fail-under-lines 80` を push-runner-config.toml [quality_gate] に integration 推奨、現状未測定のため段階導入計画必要、rule docs § 80% coverage を実行時 gate 参照に縮小) | +| 149 | 🔧 Tier 2 | **Long-running subprocess pipe truncate hook 拡張 — `development-workflow.md` § subprocess pipe truncate 禁止 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (既存 `exe-help-block` preset を `cli-*.exe ... \| (head\|tail\|awk)` 等の副作用ある subprocess 出力 truncate にも拡張 or 新 `subprocess-pipe-truncate-block` preset 追加、PR #109 SIGPIPE 事故 root cause の構造化、順位 44 (gh-token-efficiency) との scope 境界整理必要、development-workflow.md § 該当 section 縮小) | +| 150 | 🔧 Tier 2 | **Magic number lint 追加 — `coding-style.md` § Magic Numbers 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = source folder 限定) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`.claude/custom-lint-rules.toml` に `no-magic-number` rule 追加、source folder paths filter で test/config 除外、時間定数 / リトライ回数 / threshold の 3 category MVP、severity warning で reviewer 判断補助、順位 102 paths filter + 順位 118 適用範囲検討と整合、coding-style.md § Magic Numbers 削除可否は dogfood 後判断) | +| 151 | 🔧 Tier 2 | **PR diff lines check 追加 — `git-workflow.md` § Multi-PR chaining 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = 条件付き block 3 段階) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`src/cli-push-runner/src/stages/pr_size_check.rs` 新 stage 追加、`push-runner-config.toml` `[pr_size_check]` section で threshold 設定可能化 (default: block 1500 / warning 800)、jj diff stat 計測、大型 refactoring 時の override は config 編集、git-workflow.md § Multi-PR chaining 縮小) | +| 152 | 🔧 Tier 2 | **todo entry 削除時の事前 land 確認手順 — 順位 136 hook 拡張 or 独立 follow-up (PR #173 T2-1 採用、2026-05-26)** | todo9.md | XS-S | 順位 136 (working copy staleness + 既実装 grep) と同型機械強制、lifecycle 補完 = 順位 136 (add/edit 時) + 本タスク (delete 時)。PreToolUse hook で `docs/todo*.md` 削除時に対応 land commit を `jj log` で grep 検証、land 確認なら allow + 証跡出力、未確認なら warning (block しない)。順位 136 hook 統合 (~+15 行) or 独立 (~40 行) のいずれか、ADR-042 § Decision matrix 適用 (mechanizable + FP 低 + Adoption Risk None) | +| 153 | 🔧 Tier 2 | **`review-harness-whole` facet 追加 — 観点 ① 独立 facet 化 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | S | ADR-031 本採用後 (2026-06-01) の Phase B+1 拡張、extract 不要と判明したら close、順位 146-151 Bundle 既存ルール仕組み化の継続的発見源、architecture-whole から ① 観点を extract して context 圧迫回避 | +| 154 | 🔧 Tier 2 | **`review-todo-whole` facet + aggregate 前 file size pre-step — 観点 ⑤ ⑦ 拡張 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | M | 順位 136 land + ADR-031 本採用 (2026-06-01) 後着手、cli-docs-lint (preamble) / 順位 147 (file length) と scope 整理必要 (CI 即時 vs 週次 batch)、ADR-031 3 層分離原則で file size は LLM 不要の Rust pre-step に分離 | +| 157 | 🔧 Tier 2 | **Bundle 1 dogfood checklist 実行 — `__test.ps1` block + override env 確認 (PR #174 T2-#2 採用、ADR-039 bounded lifetime data point #1)** | todo11.md | XS | なし (PR #174 PR body の未消化 dogfood、Bundle 2 PR merge 前の前提条件として消化、結果は Bundle 2 PR body に記録) | +| 160 | 💎 Tier 3 | **`docs-governance.md` に「ADR multi-variant pattern section 追加時の checklist」codify (PR #176 T3-#1 採用)** | todo11.md | XS | なし (PR #175 Minor + PR #176 Nitpick の 2 連続観測 = Frequency Medium で採用条件成立、ADR 拡張時の variant 網羅性 + 擬似コード vs 実コード齟齬を reviewer / Claude 視点で防止する checklist、global file `~/.claude/rules/common/docs-governance.md` 編集のため本リポジトリ外で実施、`feedback_global_config_backup` 適用) | +| 161 | 🔧 Tier 2 | **Subprocess timeout+kill lifecycle 検証テスト追加 (PR #177 T2-#1 採用)** | todo11.md | M | なし (PR #177 Major #2 「jj kill on timeout 漏れ」fix の回帰テスト、`Child::is_finished` で 2 hook の `run_jj_with_timeout` lifecycle 検証、Severity High + Frequency Medium、ADR-024 shared lib 統合候補との関係明示) | +| 162 | 🔧 Tier 2 | **fail-closed error path (Option::None) 個別テスト追加 (PR #177 T2-#2 採用)** | todo11.md | S | なし (PR #177 Major #1 「`behind.unwrap_or(0)` fail-closed 漏れ」fix の回帰テスト、`check_todo_staleness` / `build_todo_staleness_message` の None ケース独立検証、Severity High + Frequency Medium、security gate + Option return pattern の reference) | +| 163 | 🔧 Tier 2 | **Cross-ref edge case test coverage 追加 — percent-encode / GFM heading slug / relative path normalize (PR #179 T2-#1 採用)** | todo11.md | S | なし (PR #179 で cli-docs-lint の cross_ref validator を新規実装したが、percent-encode (`%20` / `%23`) / heading slug / `../` resolve の edge case が fixture テストで明示的に保護されていない silent regression リスク回避) | +| 165 | 🔧 Tier 2 | **`pnpm create-pr` PR body truncation 回避を検証する e2e/integration test 追加 (PR #181 T2-#1 採用)** | todo11.md | S | なし (PR #134 + #181 の 2 回観測で Medium frequency に昇格、memory `feedback_pnpm_create_pr_body` の `--body-file` workaround を自動 regression gate 化、shell argument truncation の境界 (行数/バイト数) を fixture で測定、silent UX 劣化の早期検出、cli-pr-monitor の argv 組み立て層を test 対象、順位 166 と相補 = test 層 vs docs 層) | +| 170 | 💎 Tier 3 | **`git-workflow.md § Multi-PR chaining` を「1 PR 内 multi-commit + intent 明記」パターンに拡張 (PR #183 T3-#1 採用)** | todo11.md | S | なし (PR #119/#120/#121 + #183 の 4 観測で Frequency High、commit 分割判断 + intent 記述ガイドを既存 section に追記、`~/.claude/rules/common/git-workflow.md` 編集、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須) | +| 171 | 💎 Tier 3 | **`docs-governance.md` に「Operational reference vs Pointer reference」区別 section を追加 (PR #183 T3-#2 採用) ★ Bundle DG-RULES** | todo11.md | S | 順位 172 と同 PR 推奨、PR #183 A01 修正で実適用した判定ロジック (operational = workflow 動作記述 = 保持可 / pointer = section 名・順位番号参照 = 置換必要) を `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section として codify、ADR-031 lines 79-302 中 line 270 のみが真の pointer だった実例を inline cite、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須 | +| 172 | 💎 Tier 3 | **CR ephemeral artifact Nitpick の統一 skip 基準を memory に codify (PR #183 T3-#3 採用) ★ Bundle DG-RULES** | todo11.md | XS | 順位 171 と同 PR 推奨、CR が `docs/todo*.md` 系 ephemeral artifact 内の行番号参照を Nitpick 指摘した場合は skip 推奨という判断基準を新 memory `feedback_coderabbit_ephemeral_nitpick.md` に codify、既存 memory `feedback_coderabbit_no_actionable_merge_signal` の補完、本リポジトリ専用 (派生プロジェクトには波及しない)、`feedback_global_config_backup` 適用推奨 | +| 173 | 🔧 Tier 2 | **`combine_output` 5 crate 重複を `lib-runner-utils` (or 既存 lib-*) に extract (PR #182 dry-run S01 採用)** | todo11.md | S-M | なし (`src/cli-pr-monitor/src/runner.rs:80-89` の `combine_output` 8 行関数が `#[allow(dead_code)]` 付与で生産未使用、同関数が 4 他 crate (cli-push-runner, cli-push-pipeline, cli-merge-pipeline, hooks-post-tool-linter) にも複製 = 5 crate 横断 systemic duplication、ADR-026 Cargo workspace + ADR-012 lib-* naming で解決、Phase B dogfood の最初の実体ベース finding (A01 と並ぶ)、A01 は PR #183 で fix 済) | +| 176 | 🔧 Tier 2 | **check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用)** | todo10.md | M | なし (順位 167-169 Bundle CR-RL の follow-up、bold-wrapper variant (`**More reviews will be available**`) / 短形態 (secs のみ) / 複数 separator / wait time なし graceful failure の 4 fixture 追加、PR #182 + #185 の 2 PR 連続観測で CR format 多様性 systemic、`extract_old_format_wait_time` / `extract_new_format_wait_time` の coverage gap 補填、regex 拡張 vs fixture 先行の 2 アプローチを着手時判断、analyzer rationale の「Edit 集中 = test gap signal」は incidental で採用根拠から除外、true 採用根拠は format 多様性 + 防御的 variant) | +| 177 | 🚀 **Tier 1 (優先実装)** | **PostToolUse hook — Edit / Write したファイルのサイズ閾値超過を検出してファイル分割を促す (2026-05-29 ユーザー追加要望、2026-06-06 優先度引上げ)** | todo10.md | S-M | なし (**Status update 2026-06-06**: 本セッションの todo9.md → todo11.md 手動分割で **4 回目の同型観測** = Very High frequency 達成、PR #133 / #172 / #186 + 本セッション、ユーザー指示で Tier 1 内優先実装に格上げ、Bundle 195-FB-Followup の次の最優先候補、直近 PR で消化推奨、PostToolUse Edit/Write 直後にサイズチェックを mechanical 強制、`.claude/hooks-config.toml` の `[post_tool_use.file_size_check]` で `enabled = false` default OFF (ADR-039 opt-in) + `threshold_bytes` (default 51200 = 50KB) + `paths` glob + `touch_trigger` ratchet を設定可能、配置先は option A = 新 binary `hooks-post-tool-file-size-check` / option B = 既存 `hooks-post-tool-linter` 統合の 2 案を着手時判断、ADR-007 custom-linter layer boundary に位置付け追記) | +| 178 | 🔧 Tier 2 | **`state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/cli-pr-monitor/src/state.rs:226-510` の test が JSON round-trip のみ、`rate_limit=Some` 時 CI 更新 skip 等の behavioral invariant 未検証、ADR-041 sentinel 事前投入 + mutation 不在 assert pattern で 3-5 test 追加、memory `feedback_test_dry_antipattern` 適用、Effort S で high value catches state regression) | +| 179 | 🔧 Tier 2 | **rate-limit retry decision boundary test を rstest parameterized で追加 (週次レビュー 2026-05-30 S03 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/cli-pr-monitor/src/config.rs:94-122` + `stages/poll.rs` の `max_retries=3` 固定 test のみで boundary (0/1/3/off-by-one) 未検証、rstest parameterized で 3-4 case 追加 ~15 行、rstest 既存使用 + Bundle CR-RL = 順位 167-169 隣接領域 follow-up、off-by-one regression が test で検出可能化) | +| 180 | 🔧 Tier 2 | **`lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/lib-report-formatter/src/lib.rs:51-79` の `format_table()` が PR title / commit message の `|` / `\n` を escape せず markdown table 構造を破壊 → downstream AI facet で prompt injection リスク、`escape_markdown_pipe()` 5 行 utility + call site escape + 5 variant test で defense-in-depth 確立、本セッション 5 PR chain で AI facet 連鎖が systemic 化したため継続価値高) | +| 181 | 🔧 Tier 2 | **`aggregate-weekly` facet の `findings.json` 出力を raw JSON にする (Phase D dogfood D-A 採用)** | todo10.md | XS-S | なし (本セッション 2026-05-30 Phase D dogfood で実観測した facet 出力 bug、`aggregate-weekly.md` instruction が「raw JSON 出力必須、markdown code fence で囲まない」を明示せず facet LLM が ` \`\`\`json...\`\`\` ` で wrap してしまう、skill 側の手動 fence strip workaround を不要化、修正後の次 `/weekly-review` で raw JSON 出力を dogfood 観測、Phase E 試験運用前の整備) | +| 182 | 🔧 Tier 2 | **`/weekly-review` skill に重複検出 (簡易 grep) を Phase 4 で追加 (Phase D dogfood D-B 採用)** | todo10.md | XS-S | なし (本セッション 2026-05-30 Phase D dogfood で WR-2026-05-30-S05 と既存 順位 173 が完全重複していた実観測、ADR-031 § Phase 4 「重複検出は MVP では実装しない」を「MVP+1 (簡易 grep + 3 択 AskUserQuestion: augment/新規/skip)」相当に格上げ、自動 merge なし原則は維持、description 先頭 40 chars の grep ヒット警告 → user 判断、`feedback_global_config_backup` 適用必須 (~/.claude/skills/ 編集前 snapshot)) | + +| 193 | 🔧 Tier 2 | **Companion helper group 署名整合 compile-time validation test (PR #196 T2-1 採用) ★ Bundle 195-FB follow-up** | todo10.md | S | なし (Bundle 195-FB で 3 関数目の signature drift が CR Major + pre-push F-1 で systemic 観測、rule⑫ は literal hardcode 層、本タスクは API signature 整合性層、関数ポインタ cast による compile-time witness で signature drift を test 不通過に。`code-review.md` § Review Checklist に reviewer 注意 1 項目追加で 3 層防御 = rule⑫ + compile-time test + reviewer 注意、`feedback_global_config_backup` 適用必須) | +| 194 | 💎 Tier 3 | **`development-workflow.md` 「1. Plan First」に「task 着手前に grep で既存 section 確認」step 追記 (PR #196 T3-5 採用)** | todo10.md | XS | なし (PR #123 + #196 で「既実装 section の重複計画」事象を Frequency Medium で観測、`~/.claude/rules/common/development-workflow.md` "1. Plan First" に Codification 重複確認 step を 1-2 行追記、`grep -rn` 手順 + 由来 cite (PR #123, #196)、派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及、`feedback_global_config_backup` 適用必須) | + +**戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 + +**直近優先 (2026-06-06 ユーザー指示)**: **順位 177** (PostToolUse hook ファイルサイズ検出) は **4 回目の同型観測 (Very High frequency)** に到達したため Tier 1 内でも最優先。Bundle 195-FB-Followup (順位 193 + 194) の次の PR で消化推奨。todo.md / docs ファイル分割を user 判断ベースから mechanical layer に移管することで、認知負荷削減 + 早期検出が実現する。 + +**Bundle 履歴**: 完了済 Bundle / post-merge-feedback 反映の経緯詳細は [docs/bundle-history.md](bundle-history.md) を参照 (2026-05-25 分離、本ファイルの index 責務集中のため)。 diff --git a/docs/todo.md b/docs/todo.md index 80658fa7..5707e957 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -70,6 +70,8 @@ > > **本タスクの位置づけ**: ADR-029 を partial supersede する新 ADR-030 を起案し、takt 経由の決定論的フィードバック機構へ移行する。本タスク完了で post-merge-feedback skill / pending file / Stop hook (hooks-stop-feedback-dispatch) はすべて廃止される。 > +> **Status update (2026-06-06)**: Phase D-7 (Drop guard + orphan reaper + ADR-030 spec) は **PR #154 (`c872da229df3`) で land 済**。L1 Floor / L2 Recovery / Drop guard / orphan reaper の決定論層は本採用昇格相当で運用中。残るは **Phase E (旧機構廃止 = post-merge-feedback skill + hooks-stop-feedback-dispatch crate + lib-pending-file + ADR-029/014 ステータス更新)** と **Phase F (dogfood 検証)**。Phase E 着手前提条件 (Phase D-7 land) は満たされた。 +> > **実行優先度**: 🧹 **Tier 4** — Phase A〜D は merged 済で workflow は機能。残る Phase E (旧機構廃止) / Phase F (dogfood) は cleanup 中心で daily efficiency への直接効果は小。Tier 1〜3 完了後の片付けタイミングで実施推奨。 #### 背景: ADR-029 の構造的欠陥 (PR #74 dogfood で実証) diff --git a/docs/todo10.md b/docs/todo10.md index f5601b98..130aa40b 100644 --- a/docs/todo10.md +++ b/docs/todo10.md @@ -1,378 +1,475 @@ -# TODO (Part 10) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo9.md がファイルサイズ 50KB を超え行数 1100+ 行に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #185 = Bundle CR-RL land 後、2026-05-29 ユーザー判断)。todo.md / todo2.md 〜 todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用) - -> **動機**: PR #185 (Bundle CR-RL) で `extract_old_format_wait_time` / `extract_new_format_wait_time` の 2 helper 関数に分離し 3 新規 fixture (full / minutes-only / 旧新混在) を追加したが、analyzer (post-merge-feedback) は **bold-wrapper variant** (例: `**More reviews will be available in N minutes and S seconds**`) や **その他の組合せ variant** の coverage gap を指摘。PR #182 (30+ 分 polling 浪費の実観測) + PR #185 (format 多様性対応) の 2 PR 連続観測で、CR の format は引き続き variants を生む可能性が高く、防御的 fixture coverage 追加が systemic 価値あり。 -> -> **本タスクの位置づけ**: PR #185 post-merge-feedback Tier 2 #4 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None、2026-05-29 ユーザー承認)。順位 167-169 (Bundle CR-RL) の follow-up として next format drift での silent regression 防止網を厚くする。 -> -> **参照**: `.claude/feedback-reports/185.md` Tier 2 #4、`src/check-ci-coderabbit/src/main.rs` の `#[cfg(test)]` mod (既存 9 fixture = 6 旧 format + 3 新 format)、`extract_old_format_wait_time` / `extract_new_format_wait_time` の regex (現状 markdown bold `\*?\*?` は旧 format のみ対応、新 format は bold 想定なし) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。fixture 追加のみで runtime 影響なし。 -> -> **注意 (analyzer rationale の一部に弱点)**: post-merge-feedback report は「PR #185 で 6 回の Edit が同一ファイルに集中した incremental development パターンは test coverage gap の兆候」と述べているが、これは incidental development pattern であり test coverage の真の signal ではない。採用根拠は **CR format 多様性 (PR #182 + #185 の 2 PR 連続観測) + bold-wrapper 等の防御的 variant 追加の妥当性** であり、Edit 集中は無関係。 - -#### 設計決定 (案) - -追加候補 fixture (memory `feedback_test_dry_antipattern`: 各 variant 独立 setup): - -- **bold-wrapper 新 format**: `**More reviews will be available in 15 minutes and 30 seconds**` — CR が markdown bold を新 format に追加した場合の検出 - - 現 `extract_new_format_wait_time` の regex はこの場合 fail する (旧 format の `\*?\*?` 相当を新 format regex にも追加する必要あり) - - もし fail を assertion で確認するなら fixture は「現状の振る舞いを pin」、もし regex を pre-emptively 拡張するなら「拡張後の動作 verify」 -- **secs だけ provided 新 format**: `More reviews will be available in 45 seconds` (minutes 0 + seconds N の variant、CR が短時間 rate-limit を表現する場合) -- **複数 separator 旧 format**: `Please wait 5 minutes, 13 seconds` (`and` ではなく `,` 使用、観測例なしだが defensive) -- **HTML マーカーのみで wait time 文言なし**: ` ## Review limit reached` のみ → wait time 抽出失敗 = `parse_rate_limit` が None を返すことを assert (graceful failure verify) - -#### 設計判断 (regex 拡張 vs fixture のみ追加) - -2 つのアプローチ: - -1. **regex 拡張先行**: `extract_new_format_wait_time` の regex に `\*?\*?` 等を pre-emptively 追加し、それを fixture で verify する (= 想定 variant への先回り対応) -2. **fixture 先行 + 観測後 regex 拡張**: 現状の regex で fixture を書き、bold-wrapper variant では fail することを assert (= 現状の振る舞いを pin、観測ベース対応に倣う) - -どちらを採るかは本タスク着手時に判断。memory `feedback_no_unenforced_rules` の「未観測の preventive over-engineering を避ける」原則からは 2 が一貫性あり。1 を採るならその根拠 (=「regex 拡張は trivial で false positive リスクなし」) を commit description に明示する。 - -#### 作業計画 - -- [ ] 既存 9 fixture (`#[cfg(test)]` mod) を Read で全件確認、coverage gap を整理 -- [ ] 追加 4 fixture を独立 `#[test]` 関数として追加 (helper 共通化なし、memory `feedback_test_dry_antipattern` 適用) -- [ ] `cargo test -p check-ci-coderabbit` で全 fixture pass を確認 (新 + 既存 backward compat 維持) -- [ ] regex 拡張アプローチを採る場合は `extract_*_format_wait_time` の regex を更新、対応する `--release` test 確認 -- [ ] ADR-034 § 既知 CR rate-limit format 一覧 table に新 variant を 1 行 append (発見時期 = 「2026-05-29 防御的追加 (順位 176 land 時)」) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 4 新規 fixture が `cargo test -p check-ci-coderabbit` で全 pass -- bold-wrapper / 短形態 / graceful failure 等の variant coverage 確立 -- silent regression を test で 1 件以上検出できる構造 (= regex を意図的に元に戻すと新 fixture test が落ちる) -- ADR-034 § 既知 format 一覧 table の append による永続 reference 整合 - -#### 詰まっている箇所 - -regex 拡張アプローチ (#1) vs fixture のみ追加 (#2) の選択。本タスク着手時に bold-wrapper の CR 実観測例が増えていれば #1、increase なしなら #2 を採る判断が memory `feedback_no_unenforced_rules` の原則に整合する。 - ---- - -### PostToolUse hook — Edit / Write したファイルのサイズ閾値超過を検出してファイル分割を促す (2026-05-29 ユーザー追加要望) - -> **動機**: 本セッション (PR #181 → #182 → #183 → #184 → #185 chain) で **docs/todo9.md が 50KB 超 + 1168 行に到達し読み取り安定性に支障**、user 判断で docs/todo10.md に split した実体観測がある (本ファイル自身がその split 結果)。同型の問題はこれまでも todo.md → todo2.md (PR #133) / todo8.md → todo9.md (PR #172) で繰り返し発生しており、現状は user 判断ベースでファイル分割している。**PostToolUse hook で Edit / Write 直後にサイズチェックを自動化** し、閾値超過時にファイル分割を促す error feedback を出すことで、user が認知負荷で気づく前に mechanical layer で promote できる構造的改善。 -> -> **本タスクの位置づけ**: PR #185 land 後の本セッション内 user 追加要望 (2026-05-29、post-merge-feedback 経由ではない直接タスク化)。memory `feedback_pipeline_over_rules` の体系適用 — user が「ファイル大きくなりすぎたら split する」を rule で覚えるのではなく、hook で機械強制する。touch-trigger ratchet pattern (= 既存超過ファイルは触られるまで grandfather) で backward compat 確保。 -> -> **参照**: `src/hooks-post-tool-comment-lint-rust/` (PostToolUse hook 既存実装、関数長 50 行制限の touch-trigger ratchet 参考)、`src/hooks-post-tool-linter/` (汎用 linter hook 既存)、`.claude/hooks-config.toml` の `[post_tool_use]` config 構造、PR #133 (todo.md → todo2.md split) / PR #172 (todo8.md → todo9.md split) / 本セッション PR (todo9.md → todo10.md split) の 3 PR 観測 -> -> **実行優先度**: 🚀 **Tier 1** — Effort S-M。`hooks-config.toml` への新 sub-feature 追加 + hook binary の Edit/Write 拡張で完結、touch-trigger ratchet で既存超過 grandfather。 - -#### 設計決定 (案) - -##### 1. 配置先 (2 案、着手時判断) - -- **option A**: 新 hook binary `hooks-post-tool-file-size-check` を新設。専用性高く責務分離明確、ADR-026 Cargo workspace の lib-* / hooks-* pattern に整合 -- **option B**: 既存 `hooks-post-tool-linter` (generic linter) に新 check として統合。新 binary 追加せず Edit/Write 1 hook で済む、deploy 簡素 - -option B が Effort S 寄り、option A が将来拡張 (例: バイナリサイズ / generated ファイルサイズ等の別 check と分離) しやすい。 - -##### 2. config schema - -`.claude/hooks-config.toml` に新 section: - -```toml -# [post_tool_use.file_size_check] -# Edit / Write 直後にファイルサイズを確認し、threshold 超過なら error で -# split を促す。touch-trigger ratchet で既存超過ファイルは grandfather。 -[post_tool_use.file_size_check] -enabled = false # ADR-039 opt-in (default OFF、repo config で明示 enable) -threshold_bytes = 51200 # default 50KB (= 50 * 1024 bytes) -# 対象ファイル glob。default は markdown + Rust source。 -paths = ["docs/**/*.md", "src/**/*.rs"] -# touch-trigger ratchet: true = 既存超過ファイルは触られるまで grandfather (= 触られたら即チェック) -# false = strict mode (= 触ったかどうかに関わらず全 enabled paths を毎回チェック) -touch_trigger = true -``` - -##### 3. 動作仕様 - -- PostToolUse Edit / Write 直後に発火 -- 編集された file path が `paths` glob に match するか確認 (no match → skip) -- file size が `threshold_bytes` 超過か確認 (no 超過 → skip) -- 超過時の error 出力 (stderr JSON で hook protocol に整合): - - error message: `": ファイルサイズ bytes が threshold bytes を超過しています。ファイル分割を推奨します。"` - - recovery hint: `"docs/todo*.md の場合は新 todo.md を新設、Rust source の場合は module 分割を検討。"` - - kill-switch: `enabled = false` で完全停止 (ADR-039 § Kill-switch 整合、診断メッセージは実装の受理値を網羅する原則も適用) - -##### 4. touch-trigger ratchet の意義 - -- 既存 `docs/todo.md` (~30KB) や `docs/todo8.md` (~50KB 弱) など、本 hook 導入時に閾値近辺のファイルが存在する -- `touch_trigger = true` (default) なら未編集ファイルは grandfather、編集した瞬間にチェックが発火 = 「触ったら直す」原則 -- `touch_trigger = false` (strict) は全 enabled paths を毎回 fail する可能性 = 導入直後に大量 error を生む、適用は dogfood 後に判断 - -#### 作業計画 - -- [ ] 配置先選定 (option A = 新 binary vs option B = 既存 linter 統合) を `src/hooks-post-tool-linter/` の structure を Read で確認して決定 -- [ ] `.claude/hooks-config.toml` に `[post_tool_use.file_size_check]` section を追加 (default OFF、上記 config schema) -- [ ] hook binary 実装: Edit / Write path 取得 → glob match → size 確認 → error/PASS -- [ ] memory `feedback_test_dry_antipattern` 適用の test 追加: enabled=false / paths 不一致 / size 未超過 / size 超過 / touch_trigger=false の 5+ variant 独立 setup -- [ ] cargo clippy + cargo test pass 確認 -- [ ] dogfood: 本タスク実装後に `docs/todo10.md` を意図的に閾値超過させて hook が error を返すことを実観測 -- [ ] `pnpm build:all` + `pnpm deploy:hooks` で派生プロジェクト 2 件 (techbook-ledger / auto-review-fix-vc) へ配布判断 (各派生プロジェクトの `hooks-config.toml` で個別 enable / disable 制御可能) -- [ ] ADR-007 (custom-linter layer boundary) に本 hook の位置付けを 2-3 行追記 (= ファイルサイズは AST 解析不要の正規表現未満の単純 check 層に位置) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- PostToolUse Edit / Write で対象 path 編集 → サイズ閾値超過時に error 通知が出る -- `enabled = false` で完全停止可能 (kill-switch、ADR-039 整合) -- threshold_bytes / paths / touch_trigger が config から設定可能 -- touch-trigger ratchet で既存超過ファイルは未編集なら grandfather -- 5+ variant test で各分岐独立検証 -- `cargo clippy --workspace -- -D warnings` clean (順位 175 land 後は stop_quality でも mechanical 強制) - -#### 詰まっている箇所 - -なし。Effort S-M で structural improvement、本セッション体験の直接対策。配置先 option A vs B のみが着手時の判断点。 - ---- - -### `state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用) - -> **動機**: 週次レビュー WR-2026-05-30-S02 で検出。`src/cli-pr-monitor/src/state.rs:226-510` の test は JSON round-trip (serde 直列化 / 逆直列化) のみを検証し、**behavioral invariant** (例: `rate_limit` が `Some` の場合に `update_state_from_check_result()` が `ci` field を populate しない) を test していない。状態遷移 regression が test suite を通り抜ける構造的リスク。ADR-041 (Test Isolation Patterns for Multi-Condition Guards) で確立された「sentinel 事前投入 + mutation 不在を assert」pattern が本リポジトリの canonical 対策。 -> -> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。analyzer rationale: "Concrete, low-effort (add 3-5 tests), high value (catches state regression bugs). ADR-041 is already the project's documented pattern for this exact problem type." -> -> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/state.rs:226-510` (既存 test、JSON round-trip のみ)、`docs/adr/adr-041-test-isolation-patterns.md` (適用 pattern source) -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。3-5 test 追加で済む、既存 ADR-041 pattern 流用。 - -#### 設計決定 (案) - -- **対象 invariant 候補** (analyzer 提案 + 派生): - 1. `rate_limit` が `Some` 時、`update_state_from_check_result()` は `ci` field を更新しない - 2. `rate_limit.until_unix_secs` が過去時刻になった場合、次回 update で `rate_limit` が `None` に reset される (timer expiry) - 3. `notified` flag が `true` の場合、再度 `update_state_*` を呼んでも `notified` は維持される (idempotency) - 4. (実装側で発見し次第追加) -- **ADR-041 pattern 適用**: - - 各 test variant は独立 setup (`memory feedback_test_dry_antipattern`) - - sentinel value を事前投入 (`ci.overall = "MUTATION_CHECK_SENTINEL"` 等)、mutation が起こったか否かを明示的に assert - - guard condition を partial に偽にする setup で「他 guard が真でも mutation が起こらないこと」を保証 - -#### 作業計画 - -- [ ] `src/cli-pr-monitor/src/state.rs:226-510` を Read で全件確認、現状の test スコープと不足 invariant を整理 -- [ ] ADR-041 § Test Isolation Patterns を Read で再確認 -- [ ] 3-5 behavioral invariant test を `#[cfg(test)]` mod に追加 (memory `feedback_test_dry_antipattern` 適用、各 variant 独立 setup) -- [ ] cargo test -p cli-pr-monitor で全 pass 確認 -- [ ] mutation regression check: 意図的に invariant を破る変更 (例: rate_limit check を削除) を local で適用して新 test が落ちるか手動検証 -- [ ] cargo clippy clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 3-5 behavioral invariant test が追加され全 pass -- silent regression を test で 1 件以上検出できる構造 (意図破壊で新 test 落ちる確認済) -- ADR-041 pattern の rationale を test コメントで cite (sentinel 事前投入 + mutation 不在 assert) - -#### 詰まっている箇所 - -なし。Effort S、既存 pattern + 既存 test 構造への追加で完結。 - ---- - -### rate-limit retry decision boundary test を rstest parameterized で追加 (週次レビュー 2026-05-30 S03 採用) - -> **動機**: 週次レビュー WR-2026-05-30-S03 で検出。`src/cli-pr-monitor/src/config.rs:94-122` の rate-limit retry logic + `stages/poll.rs` 周辺で、`max_retries=3` (固定値) のみが test されており **decision boundary** (`max_retries=0` で retry されない / `max_retries=1` で 1 回だけ retry / `max_retries=3` で boundary 通過後 `action_required` 遷移) が未検証。off-by-one error (`<` vs `<=`) が silent regression として通る構造的リスク。rstest crate は既に本リポジトリで使用済のため新 dep 不要。 -> -> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。Bundle CR-RL (順位 167-169) と隣接領域 (= rate-limit detection の周辺 logic) のため follow-up 価値高。analyzer rationale: "Low effort (rstest parameterized test, ~15 lines). rstest is already in use in the codebase. High value: catches the exact off-by-one class that single-value tests miss." -> -> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/config.rs:94-122` (RateLimitConfig + max_retries field)、`src/cli-pr-monitor/src/stages/poll.rs` (retry 適用 site)、Bundle CR-RL (順位 167-169) の隣接 context、`feedback_test_dry_antipattern` 適用 - -#### 設計決定 (案) - -- **rstest parameterized test 構造**: - - ```rust - #[rstest] - #[case(0, vec![])] // max_retries=0: retry なし - #[case(1, vec![true, false])] // max_retries=1: 1 retry 後 stop - #[case(3, vec![true, true, true, false])] // max_retries=3: full boundary coverage - fn rate_limit_retry_boundary(#[case] max_retries: u32, #[case] expected_continues: Vec) { - // setup + execution + assert - } - ``` - -- **boundary 観点**: - - 0 retry: 最初の attempt の後 `action_required` 遷移を確認 - - max_retries 到達: 連続 retry 後の最終 attempt で `action_required` に遷移 - - off-by-one: `< max_retries` か `<= max_retries` かを test 経由で pin (実装の `<` を `<=` に変えると新 test が落ちる) - -#### 作業計画 - -- [ ] `src/cli-pr-monitor/src/config.rs` の `RateLimitConfig::max_retries` 周辺 + `stages/poll.rs` の retry decision logic を Read で確認 -- [ ] 既存 rstest 使用箇所を grep で確認、import / pattern を踏襲 -- [ ] `#[cfg(test)]` mod に `rate_limit_retry_boundary` parameterized test を追加 (3-4 case) -- [ ] cargo test -p cli-pr-monitor で全 pass 確認 -- [ ] off-by-one regression check: `<` を `<=` に意図的変更で test が落ちることを手動検証 -- [ ] cargo clippy clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 3-4 parameterized case が全 pass -- off-by-one error が test で検出可能 (`<` ↔ `<=` mutation で test 落ちる) -- 既存単一値 test は維持 (backward compat) - -#### 詰まっている箇所 - -なし。Effort S、rstest pattern 既存使用 + 約 15 行で完結。 - ---- - -### `lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用) - -> **動機**: 週次レビュー WR-2026-05-30-C01 で検出。`src/lib-report-formatter/src/lib.rs:51-79` の `format_table()` が PR title / commit message を markdown table 行に直接埋め込むが、`|` / `\n` を escape していない。「`Fix | Critical | src/main.rs`」のような PR title が markdown table 構造を破壊し、**downstream AI facet が malformed row を Read 時に misinterpret する prompt injection リスク** が存在。PR title は外部 actor (= PR 作成者) が制御可能な input source のため defense-in-depth 重要。 -> -> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=security, category=prompt-injection、2026-05-30 ユーザー承認)。本セッションの 5 PR chain で AI facet 連鎖が systemic 化したため、prompt injection 防御層は今後の facet 拡張 (順位 153 / 154 等) でも継続価値あり。 -> -> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/lib-report-formatter/src/lib.rs:51-79` (format_table 実装)、`src/cli-merge-pipeline/src/feedback.rs:114-123` (PR title データ source)、ADR-022 (責務分離) との整合 (= utility は lib-* に集約) - -#### 設計決定 (案) - -- **`escape_markdown_pipe(s: &str) -> String`** ユーティリティを `lib-report-formatter` に追加: - - ```rust - pub fn escape_markdown_pipe(input: &str) -> String { - input.replace('|', "\\|").replace('\n', " ") - } - ``` - -- **call site 修正**: `format_table()` で user-controlled field (PR title / commit message / author) を embed する箇所に `escape_markdown_pipe()` を適用 -- **test 追加** (memory `feedback_test_dry_antipattern` 適用、各 variant 独立): - - 通常 ASCII (pipe / newline なし) → 変更なし - - pipe 単独 (`a | b`) → `a \| b` - - newline 単独 (`a\nb`) → `a b` - - pipe + newline 混合 - - empty string - -#### 作業計画 - -- [ ] `src/lib-report-formatter/src/lib.rs:51-79` を Read で `format_table()` 全体確認、user-controlled embed 箇所を特定 -- [ ] `escape_markdown_pipe()` を lib に追加、pub export -- [ ] `format_table()` の embed call site を escape 経由に書き換え -- [ ] `#[cfg(test)]` に 5 variant test を独立 setup で追加 -- [ ] cargo test + cargo clippy clean -- [ ] 受け先 (cli-merge-pipeline 等) で test がまだ pass することを cargo test --workspace で確認 (call signature 変更なしのため backward compat 維持) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `escape_markdown_pipe()` が `lib-report-formatter` に pub function として追加される -- 5 variant test が独立 pass -- `format_table()` の user-controlled embed が escape 経由になる -- markdown table 構造破壊 PR title (`Fix | Critical`) を fixture で渡しても table 整合維持を assert - -#### 詰まっている箇所 - -なし。Effort S、5 行 utility + call site 修正 + 5 test で完結。 - ---- - -### `aggregate-weekly` facet の `findings.json` 出力を raw JSON にする (Phase D dogfood D-A 採用) - -> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で検出した skill 統合 bug。`aggregate-weekly` facet が write する `findings.json` が ` ```json ... ``` ` の markdown code fence で wrap されており、Phase C skill (`/weekly-review`) が JSON parser に直接渡せない。本 dogfood では skill 内で fence を手動 strip して pending JSON を構築したが、**facet 出力を raw JSON にすれば skill 側の workaround が不要**になる。 -> -> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) の skill flow 実観測で発見、本 PR の dogfood 観測点 (D-A) として user 承認 (2026-05-30)。週次レビュー (ADR-031) facet 出力の整合性確保。 -> -> **参照**: `.takt/facets/instructions/aggregate-weekly.md` (修正対象)、`.takt/runs/20260529-150611-weekly-review-2026-05-30/reports/findings.json` (Phase D dogfood で実観測した fence 付き出力)、`~/.claude/skills/weekly-review/SKILL.md` Phase 2 (現 skill が手動 fence strip した workaround) - -#### 設計決定 (案) - -- **`aggregate-weekly.md` の output 指示を明確化**: - - 現状: instruction が「JSON は ... `findings.json` というファイル名で write する」と書いてあるが、facet LLM が markdown 出力癖 (` ```json...``` ` 自動 wrap) で fence 付きで write してしまう - - 修正: instruction で「**raw JSON のみ** (markdown code fence なし) で write する。先頭は `{` で始まり、末尾は `}` で終わる必要がある」を明示 - - test 文言例: `{"run_date": "...", ...}` から始まる、` ```json` で始まらない、を強調 -- **alternative**: skill 側で fence 検出 + strip を実装する (但し source-of-truth が facet 側であるべき) - -#### 作業計画 - -- [ ] `.takt/facets/instructions/aggregate-weekly.md` の `## Phase 3` (= JSON 生成 section) に「**raw JSON 出力必須、markdown code fence で囲まない**」warning を追加 -- [ ] JSON 出力例の前後 context を Edit で明確化 -- [ ] dogfood: 修正後に次の `/weekly-review` 実行で `findings.json` が raw JSON で出力されることを実観測 (Phase E で確認) -- [ ] (option) Phase C skill SKILL.md にも「fence wrap された場合の defensive strip 手順」を補足追記 (= belt-and-suspenders) -- [ ] markdownlint clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `aggregate-weekly.md` instruction で raw JSON 出力要件が明示される -- 次回 `/weekly-review` 実行で `findings.json` が raw JSON (= ` ```` ` で wrap されない) で出力される dogfood 観測 - -#### 詰まっている箇所 - -facet 側の文言修正のみで facet LLM の出力 habit を矯正できるかは未確定。修正後の dogfood 結果次第で alternative (= skill 側 strip) に切り替える判断あり。Effort XS-S。 - ---- - -### `/weekly-review` skill に重複検出 (簡易 grep) を Phase 4 で追加 (Phase D dogfood D-B 採用) - -> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で **WR-2026-05-30-S05 (`combine_output` dead-code) が既存 順位 173 (PR #182 dry-run S01 採用) と完全重複**であることを実観測。ADR-031 § Phase 4 で「**重複検出は MVP では実装しない**」と明示済だが、本 dogfood で「2 PR で同じ finding が出る」を実証したため、最低限の grep ベース簡易検出を後追い追加する妥当性が確立。MVP は description 先頭 40 chars の grep ヒットを警告表示するのみで、自動 merge は行わない (user 判断に委ねる ADR-031 原則維持)。 -> -> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) で observability gain (= 重複が見える) を実証、user 承認 (2026-05-30) で skill 拡張採用。Phase E 試験運用 dogfood の前に整備しておくと user 判断負荷を圧縮。 -> -> **参照**: `~/.claude/skills/weekly-review/SKILL.md` Phase 4 (修正対象)、ADR-031 § todo.md 反映ルール (「重複検出は MVP では実装しない」記述、本タスクで「MVP+1」相当に拡張)、Phase D dogfood の実観測 (WR-2026-05-30-S05 ↔ 順位 173 重複) - -#### 設計決定 (案) - -- **簡易 grep 重複検出 in Phase 4**: - - ```bash - # finding を docs/todo.md 系列に書き込む前に実行 - TITLE_PREFIX=$(echo "$finding_description" | head -c 40) - HITS=$(grep -li "$TITLE_PREFIX" docs/todo.md docs/todo*.md 2>/dev/null) - if [ -n "$HITS" ]; then - # AskUserQuestion で「augment / 新規 / skip」を聞く - fi - ``` - -- **3 択 AskUserQuestion**: - 1. **augment**: 既存 entry に補足追記 (= 「重複 observation を別 dogfood で再確認、優先度上昇」記録) - 2. **新規**: 重複と認識した上で別 entry 化 (= scope or角度 が異なる場合) - 3. **skip**: 重複と認識して書き込まない (= 既存 entry で十分) -- **自動 merge は行わない**: ADR-031 原則の「重複検出は MVP では実装しない」(自動 merge は MVP 超過、observability のみ提供) は維持 -- **grep target**: `docs/todo.md docs/todo2-10.md` 全件 (= 現在の todo file 集合、新 todoN+1.md 追加時は SKILL.md update が必要) - -#### 作業計画 - -- [ ] `~/.claude/skills/weekly-review/SKILL.md` Phase 4 § 重複検出 (簡易) を expansion: 現状の grep + 警告のみ → 警告 + 3 択 AskUserQuestion に変更 -- [ ] grep target file 列を docs/todo*.md glob 化、追加ファイル時の自動追従 (固定 list 回避) -- [ ] dogfood 観測の cite を skill 内 inline で明示 (= Phase D 2026-05-30 で WR-2026-05-30-S05 ↔ 順位 173 重複検出済、本 logic が機能した実例) -- [ ] **`feedback_global_config_backup` 適用**: ~/.claude/skills/ 編集前 snapshot 取得 -- [ ] markdownlint clean -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への skill 配布判断は別タスク (本 skill は global 配置だが ADR-031 自体は本リポジトリ ADR、派生展開は要検討) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- skill Phase 4 で grep 重複検出 → 3 択 AskUserQuestion → user 判断 経路が実装される -- 次回 `/weekly-review` 実行で重複候補が user 提示される dogfood 観測 -- ADR-031 「重複検出 MVP 未実装」を「MVP+1 (簡易 grep)」相当に格上げ、但し自動 merge なし原則は維持 -- skill 編集前後の ~/.claude snapshot が backup される - -#### 詰まっている箇所 - -なし。Effort XS-S、SKILL.md の Phase 4 section 拡張 + Bash snippet 追加で完結。 - ---- - -## 既知課題 (記録のみ、本セッションで未対応) - -(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。) +# TODO (Part 10) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo9.md がファイルサイズ 50KB を超え行数 1100+ 行に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #185 = Bundle CR-RL land 後、2026-05-29 ユーザー判断)。todo.md / todo2.md 〜 todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用) + +> **動機**: PR #185 (Bundle CR-RL) で `extract_old_format_wait_time` / `extract_new_format_wait_time` の 2 helper 関数に分離し 3 新規 fixture (full / minutes-only / 旧新混在) を追加したが、analyzer (post-merge-feedback) は **bold-wrapper variant** (例: `**More reviews will be available in N minutes and S seconds**`) や **その他の組合せ variant** の coverage gap を指摘。PR #182 (30+ 分 polling 浪費の実観測) + PR #185 (format 多様性対応) の 2 PR 連続観測で、CR の format は引き続き variants を生む可能性が高く、防御的 fixture coverage 追加が systemic 価値あり。 +> +> **本タスクの位置づけ**: PR #185 post-merge-feedback Tier 2 #4 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None、2026-05-29 ユーザー承認)。順位 167-169 (Bundle CR-RL) の follow-up として next format drift での silent regression 防止網を厚くする。 +> +> **参照**: `.claude/feedback-reports/185.md` Tier 2 #4、`src/check-ci-coderabbit/src/main.rs` の `#[cfg(test)]` mod (既存 9 fixture = 6 旧 format + 3 新 format)、`extract_old_format_wait_time` / `extract_new_format_wait_time` の regex (現状 markdown bold `\*?\*?` は旧 format のみ対応、新 format は bold 想定なし) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。fixture 追加のみで runtime 影響なし。 +> +> **注意 (analyzer rationale の一部に弱点)**: post-merge-feedback report は「PR #185 で 6 回の Edit が同一ファイルに集中した incremental development パターンは test coverage gap の兆候」と述べているが、これは incidental development pattern であり test coverage の真の signal ではない。採用根拠は **CR format 多様性 (PR #182 + #185 の 2 PR 連続観測) + bold-wrapper 等の防御的 variant 追加の妥当性** であり、Edit 集中は無関係。 + +#### 設計決定 (案) + +追加候補 fixture (memory `feedback_test_dry_antipattern`: 各 variant 独立 setup): + +- **bold-wrapper 新 format**: `**More reviews will be available in 15 minutes and 30 seconds**` — CR が markdown bold を新 format に追加した場合の検出 + - 現 `extract_new_format_wait_time` の regex はこの場合 fail する (旧 format の `\*?\*?` 相当を新 format regex にも追加する必要あり) + - もし fail を assertion で確認するなら fixture は「現状の振る舞いを pin」、もし regex を pre-emptively 拡張するなら「拡張後の動作 verify」 +- **secs だけ provided 新 format**: `More reviews will be available in 45 seconds` (minutes 0 + seconds N の variant、CR が短時間 rate-limit を表現する場合) +- **複数 separator 旧 format**: `Please wait 5 minutes, 13 seconds` (`and` ではなく `,` 使用、観測例なしだが defensive) +- **HTML マーカーのみで wait time 文言なし**: ` ## Review limit reached` のみ → wait time 抽出失敗 = `parse_rate_limit` が None を返すことを assert (graceful failure verify) + +#### 設計判断 (regex 拡張 vs fixture のみ追加) + +2 つのアプローチ: + +1. **regex 拡張先行**: `extract_new_format_wait_time` の regex に `\*?\*?` 等を pre-emptively 追加し、それを fixture で verify する (= 想定 variant への先回り対応) +2. **fixture 先行 + 観測後 regex 拡張**: 現状の regex で fixture を書き、bold-wrapper variant では fail することを assert (= 現状の振る舞いを pin、観測ベース対応に倣う) + +どちらを採るかは本タスク着手時に判断。memory `feedback_no_unenforced_rules` の「未観測の preventive over-engineering を避ける」原則からは 2 が一貫性あり。1 を採るならその根拠 (=「regex 拡張は trivial で false positive リスクなし」) を commit description に明示する。 + +#### 作業計画 + +- [ ] 既存 9 fixture (`#[cfg(test)]` mod) を Read で全件確認、coverage gap を整理 +- [ ] 追加 4 fixture を独立 `#[test]` 関数として追加 (helper 共通化なし、memory `feedback_test_dry_antipattern` 適用) +- [ ] `cargo test -p check-ci-coderabbit` で全 fixture pass を確認 (新 + 既存 backward compat 維持) +- [ ] regex 拡張アプローチを採る場合は `extract_*_format_wait_time` の regex を更新、対応する `--release` test 確認 +- [ ] ADR-034 § 既知 CR rate-limit format 一覧 table に新 variant を 1 行 append (発見時期 = 「2026-05-29 防御的追加 (順位 176 land 時)」) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 4 新規 fixture が `cargo test -p check-ci-coderabbit` で全 pass +- bold-wrapper / 短形態 / graceful failure 等の variant coverage 確立 +- silent regression を test で 1 件以上検出できる構造 (= regex を意図的に元に戻すと新 fixture test が落ちる) +- ADR-034 § 既知 format 一覧 table の append による永続 reference 整合 + +#### 詰まっている箇所 + +regex 拡張アプローチ (#1) vs fixture のみ追加 (#2) の選択。本タスク着手時に bold-wrapper の CR 実観測例が増えていれば #1、increase なしなら #2 を採る判断が memory `feedback_no_unenforced_rules` の原則に整合する。 + +--- + +### PostToolUse hook — Edit / Write したファイルのサイズ閾値超過を検出してファイル分割を促す (2026-05-29 ユーザー追加要望) + +> **動機**: 本セッション (PR #181 → #182 → #183 → #184 → #185 chain) で **docs/todo9.md が 50KB 超 + 1168 行に到達し読み取り安定性に支障**、user 判断で docs/todo10.md に split した実体観測がある (本ファイル自身がその split 結果)。同型の問題はこれまでも todo.md → todo2.md (PR #133) / todo8.md → todo9.md (PR #172) で繰り返し発生しており、現状は user 判断ベースでファイル分割している。**PostToolUse hook で Edit / Write 直後にサイズチェックを自動化** し、閾値超過時にファイル分割を促す error feedback を出すことで、user が認知負荷で気づく前に mechanical layer で promote できる構造的改善。 +> +> **本タスクの位置づけ**: PR #185 land 後の本セッション内 user 追加要望 (2026-05-29、post-merge-feedback 経由ではない直接タスク化)。memory `feedback_pipeline_over_rules` の体系適用 — user が「ファイル大きくなりすぎたら split する」を rule で覚えるのではなく、hook で機械強制する。touch-trigger ratchet pattern (= 既存超過ファイルは触られるまで grandfather) で backward compat 確保。 +> +> **Status update (2026-06-06、優先度引上げ)**: 本セッション (stale-cleanup + todo9.md → todo11.md 手動分割) で **4 回目の同型観測** が発生 (PR #133 / #172 / #186 + 本セッション)。Frequency が Medium → **Very High** に格上げ、CLAUDE.md `~/.claude/rules/common/code-review.md § 同型 finding の閾値判定` で「2 件以上同 PR 内で見つかった時点で `medium+` 扱いに昇格」「3 観測 = Tier 1 昇格」を超え、systemic risk の閾値に達している。**Bundle 195-FB-Followup (順位 193 + 194) の次の最優先候補**、ユーザー指示 (2026-06-06) で Tier 1 内でも優先実装対象に格上げ。直近 PR で消化推奨。 +> +> **参照**: `src/hooks-post-tool-comment-lint-rust/` (PostToolUse hook 既存実装、関数長 50 行制限の touch-trigger ratchet 参考)、`src/hooks-post-tool-linter/` (汎用 linter hook 既存)、`.claude/hooks-config.toml` の `[post_tool_use]` config 構造、PR #133 (todo.md → todo2.md split) / PR #172 (todo8.md → todo9.md split) / PR #186 (todo9.md → todo10.md split) / 本セッション 2026-06-06 (todo9.md → todo11.md split) の **4 PR 観測 (Very High frequency)** +> +> **実行優先度**: 🚀 **Tier 1 (優先実装)** — Effort S-M。`hooks-config.toml` への新 sub-feature 追加 + hook binary の Edit/Write 拡張で完結、touch-trigger ratchet で既存超過 grandfather。**2026-06-06 ユーザー指示で Tier 1 内でも優先実装に格上げ** (4 観測 = Very High frequency 達成)。 + +#### 設計決定 (案) + +##### 1. 配置先 (2 案、着手時判断) + +- **option A**: 新 hook binary `hooks-post-tool-file-size-check` を新設。専用性高く責務分離明確、ADR-026 Cargo workspace の lib-* / hooks-* pattern に整合 +- **option B**: 既存 `hooks-post-tool-linter` (generic linter) に新 check として統合。新 binary 追加せず Edit/Write 1 hook で済む、deploy 簡素 + +option B が Effort S 寄り、option A が将来拡張 (例: バイナリサイズ / generated ファイルサイズ等の別 check と分離) しやすい。 + +##### 2. config schema + +`.claude/hooks-config.toml` に新 section: + +```toml +# [post_tool_use.file_size_check] +# Edit / Write 直後にファイルサイズを確認し、threshold 超過なら error で +# split を促す。touch-trigger ratchet で既存超過ファイルは grandfather。 +[post_tool_use.file_size_check] +enabled = false # ADR-039 opt-in (default OFF、repo config で明示 enable) +threshold_bytes = 51200 # default 50KB (= 50 * 1024 bytes) +# 対象ファイル glob。default は markdown + Rust source。 +paths = ["docs/**/*.md", "src/**/*.rs"] +# touch-trigger ratchet: true = 既存超過ファイルは触られるまで grandfather (= 触られたら即チェック) +# false = strict mode (= 触ったかどうかに関わらず全 enabled paths を毎回チェック) +touch_trigger = true +``` + +##### 3. 動作仕様 + +- PostToolUse Edit / Write 直後に発火 +- 編集された file path が `paths` glob に match するか確認 (no match → skip) +- file size が `threshold_bytes` 超過か確認 (no 超過 → skip) +- 超過時の error 出力 (stderr JSON で hook protocol に整合): + - error message: `": ファイルサイズ bytes が threshold bytes を超過しています。ファイル分割を推奨します。"` + - recovery hint: `"docs/todo*.md の場合は新 todo.md を新設、Rust source の場合は module 分割を検討。"` + - kill-switch: `enabled = false` で完全停止 (ADR-039 § Kill-switch 整合、診断メッセージは実装の受理値を網羅する原則も適用) + +##### 4. touch-trigger ratchet の意義 + +- 既存 `docs/todo.md` (~30KB) や `docs/todo8.md` (~50KB 弱) など、本 hook 導入時に閾値近辺のファイルが存在する +- `touch_trigger = true` (default) なら未編集ファイルは grandfather、編集した瞬間にチェックが発火 = 「触ったら直す」原則 +- `touch_trigger = false` (strict) は全 enabled paths を毎回 fail する可能性 = 導入直後に大量 error を生む、適用は dogfood 後に判断 + +#### 作業計画 + +- [ ] 配置先選定 (option A = 新 binary vs option B = 既存 linter 統合) を `src/hooks-post-tool-linter/` の structure を Read で確認して決定 +- [ ] `.claude/hooks-config.toml` に `[post_tool_use.file_size_check]` section を追加 (default OFF、上記 config schema) +- [ ] hook binary 実装: Edit / Write path 取得 → glob match → size 確認 → error/PASS +- [ ] memory `feedback_test_dry_antipattern` 適用の test 追加: enabled=false / paths 不一致 / size 未超過 / size 超過 / touch_trigger=false の 5+ variant 独立 setup +- [ ] cargo clippy + cargo test pass 確認 +- [ ] dogfood: 本タスク実装後に `docs/todo10.md` を意図的に閾値超過させて hook が error を返すことを実観測 +- [ ] `pnpm build:all` + `pnpm deploy:hooks` で派生プロジェクト 2 件 (techbook-ledger / auto-review-fix-vc) へ配布判断 (各派生プロジェクトの `hooks-config.toml` で個別 enable / disable 制御可能) +- [ ] ADR-007 (custom-linter layer boundary) に本 hook の位置付けを 2-3 行追記 (= ファイルサイズは AST 解析不要の正規表現未満の単純 check 層に位置) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- PostToolUse Edit / Write で対象 path 編集 → サイズ閾値超過時に error 通知が出る +- `enabled = false` で完全停止可能 (kill-switch、ADR-039 整合) +- threshold_bytes / paths / touch_trigger が config から設定可能 +- touch-trigger ratchet で既存超過ファイルは未編集なら grandfather +- 5+ variant test で各分岐独立検証 +- `cargo clippy --workspace -- -D warnings` clean (順位 175 land 後は stop_quality でも mechanical 強制) + +#### 詰まっている箇所 + +なし。Effort S-M で structural improvement、本セッション体験の直接対策。配置先 option A vs B のみが着手時の判断点。 + +--- + +### `state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用) + +> **動機**: 週次レビュー WR-2026-05-30-S02 で検出。`src/cli-pr-monitor/src/state.rs:226-510` の test は JSON round-trip (serde 直列化 / 逆直列化) のみを検証し、**behavioral invariant** (例: `rate_limit` が `Some` の場合に `update_state_from_check_result()` が `ci` field を populate しない) を test していない。状態遷移 regression が test suite を通り抜ける構造的リスク。ADR-041 (Test Isolation Patterns for Multi-Condition Guards) で確立された「sentinel 事前投入 + mutation 不在を assert」pattern が本リポジトリの canonical 対策。 +> +> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。analyzer rationale: "Concrete, low-effort (add 3-5 tests), high value (catches state regression bugs). ADR-041 is already the project's documented pattern for this exact problem type." +> +> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/state.rs:226-510` (既存 test、JSON round-trip のみ)、`docs/adr/adr-041-test-isolation-patterns.md` (適用 pattern source) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。3-5 test 追加で済む、既存 ADR-041 pattern 流用。 + +#### 設計決定 (案) + +- **対象 invariant 候補** (analyzer 提案 + 派生): + 1. `rate_limit` が `Some` 時、`update_state_from_check_result()` は `ci` field を更新しない + 2. `rate_limit.until_unix_secs` が過去時刻になった場合、次回 update で `rate_limit` が `None` に reset される (timer expiry) + 3. `notified` flag が `true` の場合、再度 `update_state_*` を呼んでも `notified` は維持される (idempotency) + 4. (実装側で発見し次第追加) +- **ADR-041 pattern 適用**: + - 各 test variant は独立 setup (`memory feedback_test_dry_antipattern`) + - sentinel value を事前投入 (`ci.overall = "MUTATION_CHECK_SENTINEL"` 等)、mutation が起こったか否かを明示的に assert + - guard condition を partial に偽にする setup で「他 guard が真でも mutation が起こらないこと」を保証 + +#### 作業計画 + +- [ ] `src/cli-pr-monitor/src/state.rs:226-510` を Read で全件確認、現状の test スコープと不足 invariant を整理 +- [ ] ADR-041 § Test Isolation Patterns を Read で再確認 +- [ ] 3-5 behavioral invariant test を `#[cfg(test)]` mod に追加 (memory `feedback_test_dry_antipattern` 適用、各 variant 独立 setup) +- [ ] cargo test -p cli-pr-monitor で全 pass 確認 +- [ ] mutation regression check: 意図的に invariant を破る変更 (例: rate_limit check を削除) を local で適用して新 test が落ちるか手動検証 +- [ ] cargo clippy clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 3-5 behavioral invariant test が追加され全 pass +- silent regression を test で 1 件以上検出できる構造 (意図破壊で新 test 落ちる確認済) +- ADR-041 pattern の rationale を test コメントで cite (sentinel 事前投入 + mutation 不在 assert) + +#### 詰まっている箇所 + +なし。Effort S、既存 pattern + 既存 test 構造への追加で完結。 + +--- + +### rate-limit retry decision boundary test を rstest parameterized で追加 (週次レビュー 2026-05-30 S03 採用) + +> **動機**: 週次レビュー WR-2026-05-30-S03 で検出。`src/cli-pr-monitor/src/config.rs:94-122` の rate-limit retry logic + `stages/poll.rs` 周辺で、`max_retries=3` (固定値) のみが test されており **decision boundary** (`max_retries=0` で retry されない / `max_retries=1` で 1 回だけ retry / `max_retries=3` で boundary 通過後 `action_required` 遷移) が未検証。off-by-one error (`<` vs `<=`) が silent regression として通る構造的リスク。rstest crate は既に本リポジトリで使用済のため新 dep 不要。 +> +> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。Bundle CR-RL (順位 167-169) と隣接領域 (= rate-limit detection の周辺 logic) のため follow-up 価値高。analyzer rationale: "Low effort (rstest parameterized test, ~15 lines). rstest is already in use in the codebase. High value: catches the exact off-by-one class that single-value tests miss." +> +> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/config.rs:94-122` (RateLimitConfig + max_retries field)、`src/cli-pr-monitor/src/stages/poll.rs` (retry 適用 site)、Bundle CR-RL (順位 167-169) の隣接 context、`feedback_test_dry_antipattern` 適用 + +#### 設計決定 (案) + +- **rstest parameterized test 構造**: + + ```rust + #[rstest] + #[case(0, vec![])] // max_retries=0: retry なし + #[case(1, vec![true, false])] // max_retries=1: 1 retry 後 stop + #[case(3, vec![true, true, true, false])] // max_retries=3: full boundary coverage + fn rate_limit_retry_boundary(#[case] max_retries: u32, #[case] expected_continues: Vec) { + // setup + execution + assert + } + ``` + +- **boundary 観点**: + - 0 retry: 最初の attempt の後 `action_required` 遷移を確認 + - max_retries 到達: 連続 retry 後の最終 attempt で `action_required` に遷移 + - off-by-one: `< max_retries` か `<= max_retries` かを test 経由で pin (実装の `<` を `<=` に変えると新 test が落ちる) + +#### 作業計画 + +- [ ] `src/cli-pr-monitor/src/config.rs` の `RateLimitConfig::max_retries` 周辺 + `stages/poll.rs` の retry decision logic を Read で確認 +- [ ] 既存 rstest 使用箇所を grep で確認、import / pattern を踏襲 +- [ ] `#[cfg(test)]` mod に `rate_limit_retry_boundary` parameterized test を追加 (3-4 case) +- [ ] cargo test -p cli-pr-monitor で全 pass 確認 +- [ ] off-by-one regression check: `<` を `<=` に意図的変更で test が落ちることを手動検証 +- [ ] cargo clippy clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 3-4 parameterized case が全 pass +- off-by-one error が test で検出可能 (`<` ↔ `<=` mutation で test 落ちる) +- 既存単一値 test は維持 (backward compat) + +#### 詰まっている箇所 + +なし。Effort S、rstest pattern 既存使用 + 約 15 行で完結。 + +--- + +### `lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用) + +> **動機**: 週次レビュー WR-2026-05-30-C01 で検出。`src/lib-report-formatter/src/lib.rs:51-79` の `format_table()` が PR title / commit message を markdown table 行に直接埋め込むが、`|` / `\n` を escape していない。「`Fix | Critical | src/main.rs`」のような PR title が markdown table 構造を破壊し、**downstream AI facet が malformed row を Read 時に misinterpret する prompt injection リスク** が存在。PR title は外部 actor (= PR 作成者) が制御可能な input source のため defense-in-depth 重要。 +> +> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=security, category=prompt-injection、2026-05-30 ユーザー承認)。本セッションの 5 PR chain で AI facet 連鎖が systemic 化したため、prompt injection 防御層は今後の facet 拡張 (順位 153 / 154 等) でも継続価値あり。 +> +> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/lib-report-formatter/src/lib.rs:51-79` (format_table 実装)、`src/cli-merge-pipeline/src/feedback.rs:114-123` (PR title データ source)、ADR-022 (責務分離) との整合 (= utility は lib-* に集約) + +#### 設計決定 (案) + +- **`escape_markdown_pipe(s: &str) -> String`** ユーティリティを `lib-report-formatter` に追加: + + ```rust + pub fn escape_markdown_pipe(input: &str) -> String { + input.replace('|', "\\|").replace('\n', " ") + } + ``` + +- **call site 修正**: `format_table()` で user-controlled field (PR title / commit message / author) を embed する箇所に `escape_markdown_pipe()` を適用 +- **test 追加** (memory `feedback_test_dry_antipattern` 適用、各 variant 独立): + - 通常 ASCII (pipe / newline なし) → 変更なし + - pipe 単独 (`a | b`) → `a \| b` + - newline 単独 (`a\nb`) → `a b` + - pipe + newline 混合 + - empty string + +#### 作業計画 + +- [ ] `src/lib-report-formatter/src/lib.rs:51-79` を Read で `format_table()` 全体確認、user-controlled embed 箇所を特定 +- [ ] `escape_markdown_pipe()` を lib に追加、pub export +- [ ] `format_table()` の embed call site を escape 経由に書き換え +- [ ] `#[cfg(test)]` に 5 variant test を独立 setup で追加 +- [ ] cargo test + cargo clippy clean +- [ ] 受け先 (cli-merge-pipeline 等) で test がまだ pass することを cargo test --workspace で確認 (call signature 変更なしのため backward compat 維持) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `escape_markdown_pipe()` が `lib-report-formatter` に pub function として追加される +- 5 variant test が独立 pass +- `format_table()` の user-controlled embed が escape 経由になる +- markdown table 構造破壊 PR title (`Fix | Critical`) を fixture で渡しても table 整合維持を assert + +#### 詰まっている箇所 + +なし。Effort S、5 行 utility + call site 修正 + 5 test で完結。 + +--- + +### `aggregate-weekly` facet の `findings.json` 出力を raw JSON にする (Phase D dogfood D-A 採用) + +> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で検出した skill 統合 bug。`aggregate-weekly` facet が write する `findings.json` が ` ```json ... ``` ` の markdown code fence で wrap されており、Phase C skill (`/weekly-review`) が JSON parser に直接渡せない。本 dogfood では skill 内で fence を手動 strip して pending JSON を構築したが、**facet 出力を raw JSON にすれば skill 側の workaround が不要**になる。 +> +> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) の skill flow 実観測で発見、本 PR の dogfood 観測点 (D-A) として user 承認 (2026-05-30)。週次レビュー (ADR-031) facet 出力の整合性確保。 +> +> **参照**: `.takt/facets/instructions/aggregate-weekly.md` (修正対象)、`.takt/runs/20260529-150611-weekly-review-2026-05-30/reports/findings.json` (Phase D dogfood で実観測した fence 付き出力)、`~/.claude/skills/weekly-review/SKILL.md` Phase 2 (現 skill が手動 fence strip した workaround) + +#### 設計決定 (案) + +- **`aggregate-weekly.md` の output 指示を明確化**: + - 現状: instruction が「JSON は ... `findings.json` というファイル名で write する」と書いてあるが、facet LLM が markdown 出力癖 (` ```json...``` ` 自動 wrap) で fence 付きで write してしまう + - 修正: instruction で「**raw JSON のみ** (markdown code fence なし) で write する。先頭は `{` で始まり、末尾は `}` で終わる必要がある」を明示 + - test 文言例: `{"run_date": "...", ...}` から始まる、` ```json` で始まらない、を強調 +- **alternative**: skill 側で fence 検出 + strip を実装する (但し source-of-truth が facet 側であるべき) + +#### 作業計画 + +- [ ] `.takt/facets/instructions/aggregate-weekly.md` の `## Phase 3` (= JSON 生成 section) に「**raw JSON 出力必須、markdown code fence で囲まない**」warning を追加 +- [ ] JSON 出力例の前後 context を Edit で明確化 +- [ ] dogfood: 修正後に次の `/weekly-review` 実行で `findings.json` が raw JSON で出力されることを実観測 (Phase E で確認) +- [ ] (option) Phase C skill SKILL.md にも「fence wrap された場合の defensive strip 手順」を補足追記 (= belt-and-suspenders) +- [ ] markdownlint clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `aggregate-weekly.md` instruction で raw JSON 出力要件が明示される +- 次回 `/weekly-review` 実行で `findings.json` が raw JSON (= ` ```` ` で wrap されない) で出力される dogfood 観測 + +#### 詰まっている箇所 + +facet 側の文言修正のみで facet LLM の出力 habit を矯正できるかは未確定。修正後の dogfood 結果次第で alternative (= skill 側 strip) に切り替える判断あり。Effort XS-S。 + +--- + +### `/weekly-review` skill に重複検出 (簡易 grep) を Phase 4 で追加 (Phase D dogfood D-B 採用) + +> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で **WR-2026-05-30-S05 (`combine_output` dead-code) が既存 順位 173 (PR #182 dry-run S01 採用) と完全重複**であることを実観測。ADR-031 § Phase 4 で「**重複検出は MVP では実装しない**」と明示済だが、本 dogfood で「2 PR で同じ finding が出る」を実証したため、最低限の grep ベース簡易検出を後追い追加する妥当性が確立。MVP は description 先頭 40 chars の grep ヒットを警告表示するのみで、自動 merge は行わない (user 判断に委ねる ADR-031 原則維持)。 +> +> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) で observability gain (= 重複が見える) を実証、user 承認 (2026-05-30) で skill 拡張採用。Phase E 試験運用 dogfood の前に整備しておくと user 判断負荷を圧縮。 +> +> **参照**: `~/.claude/skills/weekly-review/SKILL.md` Phase 4 (修正対象)、ADR-031 § todo.md 反映ルール (「重複検出は MVP では実装しない」記述、本タスクで「MVP+1」相当に拡張)、Phase D dogfood の実観測 (WR-2026-05-30-S05 ↔ 順位 173 重複) + +#### 設計決定 (案) + +- **簡易 grep 重複検出 in Phase 4**: + + ```bash + # finding を docs/todo.md 系列に書き込む前に実行 + TITLE_PREFIX=$(echo "$finding_description" | head -c 40) + HITS=$(grep -li "$TITLE_PREFIX" docs/todo.md docs/todo*.md 2>/dev/null) + if [ -n "$HITS" ]; then + # AskUserQuestion で「augment / 新規 / skip」を聞く + fi + ``` + +- **3 択 AskUserQuestion**: + 1. **augment**: 既存 entry に補足追記 (= 「重複 observation を別 dogfood で再確認、優先度上昇」記録) + 2. **新規**: 重複と認識した上で別 entry 化 (= scope or角度 が異なる場合) + 3. **skip**: 重複と認識して書き込まない (= 既存 entry で十分) +- **自動 merge は行わない**: ADR-031 原則の「重複検出は MVP では実装しない」(自動 merge は MVP 超過、observability のみ提供) は維持 +- **grep target**: `docs/todo.md docs/todo2-11.md` 全件 (= 現在の todo file 集合、新 todoN+1.md 追加時は SKILL.md update が必要) + +#### 作業計画 + +- [ ] `~/.claude/skills/weekly-review/SKILL.md` Phase 4 § 重複検出 (簡易) を expansion: 現状の grep + 警告のみ → 警告 + 3 択 AskUserQuestion に変更 +- [ ] grep target file 列を docs/todo*.md glob 化、追加ファイル時の自動追従 (固定 list 回避) +- [ ] dogfood 観測の cite を skill 内 inline で明示 (= Phase D 2026-05-30 で WR-2026-05-30-S05 ↔ 順位 173 重複検出済、本 logic が機能した実例) +- [ ] **`feedback_global_config_backup` 適用**: ~/.claude/skills/ 編集前 snapshot 取得 +- [ ] markdownlint clean +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への skill 配布判断は別タスク (本 skill は global 配置だが ADR-031 自体は本リポジトリ ADR、派生展開は要検討) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- skill Phase 4 で grep 重複検出 → 3 択 AskUserQuestion → user 判断 経路が実装される +- 次回 `/weekly-review` 実行で重複候補が user 提示される dogfood 観測 +- ADR-031 「重複検出 MVP 未実装」を「MVP+1 (簡易 grep)」相当に格上げ、但し自動 merge なし原則は維持 +- skill 編集前後の ~/.claude snapshot が backup される + +#### 詰まっている箇所 + +なし。Effort XS-S、SKILL.md の Phase 4 section 拡張 + Bash snippet 追加で完結。 + +--- + +### Companion helper group 署名整合 compile-time validation test (PR #196 T2-1 採用) + +> **動機**: Bundle 195-FB (PR #196) で `count_empty_in_pr_range` だけ `default_branch` 引数化が漏れていた問題 (CR Major + pre-push F-1) を rule⑫ で **literal hardcode 層** では機械検出するようになったが、companion helper group (`assert_descriptions_absent/present_in_pr_range` / `count_empty_in_pr_range` / 将来追加される helper) の **API signature 整合性** は lint rule では catch できない (= AST レベル complexity)。4 番目以降の helper 追加時に signature drift が発生しても rule⑫ は fire しない silent regression リスク。 +> +> **本タスクの位置づけ**: PR #196 post-merge-feedback Tier 2 #2 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-06-05 ユーザー承認)。test-level validation で構造強制、Bundle 195-FB Layer 1 (rule⑫) + Layer 2 (parameterize) の seal 層として位置付け。analyzer は Tier 1 lint rule (item 1) を ROI 不釣合いとして却下推奨済、本 test approach は Tier 2 内 alternative。 +> +> **参照**: `.claude/feedback-reports/196.md` Tier 2 #2、`src/cli-pr-monitor/src/fix_commit.rs` (test module 内 companion helper group)、PR #195 commit `9663dd68` (前 2 関数の修正)、PR #196 commit `qntnzyxt` (Layer 2 = 3 関数目の整合) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。compile-time witness (関数ポインタキャスト) で signature drift を test 不通過にする構造。 + +#### 設計決定 (案) + +Rust の compile-time check で signature drift を検出する pattern: + +```rust +#[test] +fn companion_helpers_share_default_branch_signature() { + // Compile-time witness: 各 helper が (&Path, &str, ...) signature を取ることを強制。 + // 新 helper を group に追加した際は本 test の末尾に同型 cast を追加して compile-time + // 整合性を seal する。signature が drift すると本 test が compile error で落ちる。 + let _: fn(&std::path::Path, &str, &[&str]) = assert_descriptions_absent_in_pr_range; + let _: fn(&std::path::Path, &str, &[&str]) = assert_descriptions_present_in_pr_range; + let _: fn(&std::path::Path, &str) -> usize = count_empty_in_pr_range; +} +``` + +- 関数ポインタへの cast は compile-time check (= test 関数 body 内の statement だが実行時 cost ≒ 0) +- signature drift → compile error → cargo test 不通過 +- 新 helper 追加時の運用: companion group の prefix (`*_in_pr_range` 等) で命名一致するなら本 test に 1 行追加を **`code-review.md` § Review Checklist** で reviewer 注意喚起 (rule⑫ + 本 test + Reviewer 注意の 3 層防御) + +#### 作業計画 + +- [ ] `src/cli-pr-monitor/src/fix_commit.rs` の `#[cfg(test)] mod tests` 内に `companion_helpers_share_default_branch_signature` test を追加 +- [ ] `cargo test --bin cli-pr-monitor fix_commit::tests::companion_helpers_share_default_branch_signature` で pass 確認 +- [ ] mutation regression check: 意図的に 1 関数の signature を変更 (例: `count_empty_in_pr_range(&Path) -> usize`) して compile error で落ちることを手動確認 +- [ ] `~/.claude/rules/common/code-review.md` § Review Checklist の末尾に「companion helper group の signature 整合は compile-time witness test で seal、新 helper 追加時は test に 1 行追加」を 1 項目追加 (3 層防御の reviewer 喚起層) +- [ ] cargo clippy clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- compile-time witness test が `fix_commit.rs` test module に追加され pass +- signature 意図変更で compile error 観測 (dogfood) +- code-review.md § Review Checklist に reviewer 注意項目追加 (global rule、派生プロジェクト波及) + +#### 詰まっている箇所 + +なし。Effort S、3-5 行 test 追加 + code-review.md 1 行追加で完結。 + +--- + +### development-workflow.md 「1. Plan First」に「task 着手前に grep で既存 section 確認」step 追記 (PR #196 T3-5 採用) + +> **動機**: PR #196 pre-push reviewer OBS-1 で「tasks 191/192 が既実装 sections を再度計画対象としていた」と指摘 (実態は cleanup diff の誤読だが、similar pattern は PR #123 でも観測済で Frequency Medium)。task 計画段階で「対象 section が既に global rules / ADR に存在するか `grep` で確認する」step を `~/.claude/rules/common/development-workflow.md` "1. Plan First" に追記し、後続 task 計画時の redundant 提案を構造的に予防する。 +> +> **本タスクの位置づけ**: PR #196 post-merge-feedback Tier 3 #5 採用 (Severity Medium / Frequency Medium / Effort XS / Adoption Risk None、2026-06-05 ユーザー承認)。development-workflow.md への 1-2 行追記のみ、派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及。 +> +> **参照**: `.claude/feedback-reports/196.md` Tier 3 #5、PR #196 pre-push OBS-1 (`.takt/runs/20260605-054100-pre-push-review/`)、PR #123 同型事象 (analyzer report 内 cite)、memory `feedback_global_config_backup` (snapshot 必須) +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule への 1-2 行追記。 + +#### 設計決定 (案) + +`~/.claude/rules/common/development-workflow.md` の **Feature Implementation Workflow** "1. Plan First" sub-step に以下を追記: + +```markdown +- **Codification 重複の事前確認**: 計画段階で「対象 section が既に global rules (`~/.claude/rules/common/*.md`) / ADR (`docs/adr/*.md`) / 既存 docs に存在するか」を `grep -n` で必ず確認する。重複追加は reviewer 混乱 + global rule の冗長化を招く。確認手順: + - `grep -rn "
" ~/.claude/rules/common/ docs/adr/ docs/` + - hit があれば既存 codification を読み、追記 vs 新規 vs skip を判断 + - 由来: PR #123 / PR #196 で同型「既実装 section の重複計画」事象を観測 +``` + +- **適用範囲**: 「ADR/global rule への新規 section codify」を含む全 task 計画 +- **派生プロジェクト波及**: `~/.claude/rules/common/` 配下のため techbook-ledger / auto-review-fix-vc に自動 + +#### 作業計画 + +- [ ] `~/.claude` snapshot 取得 (memory `feedback_global_config_backup` per) +- [ ] `~/.claude/rules/common/development-workflow.md` Feature Implementation Workflow "1. Plan First" sub-step に上記項目を追加 +- [ ] PR #123 + #196 を実例として inline cite +- [ ] markdownlint clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- development-workflow.md "1. Plan First" に Codification 重複確認 step が追記 +- 派生プロジェクトに global rule として波及 +- 由来 cite (PR #123, #196) で reviewer / Claude が rule 背景を理解可能 + +#### 詰まっている箇所 + +なし。Effort XS、docs 編集のみ。 + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。) diff --git a/docs/todo11.md b/docs/todo11.md new file mode 100644 index 00000000..bbc4748b --- /dev/null +++ b/docs/todo11.md @@ -0,0 +1,453 @@ +# TODO (Part 11) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo9.md がファイルサイズ 75KB 超 (890 行) に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して、PR-specific follow-up entries (PR #174 以降の post-merge-feedback 採用 entry) を本ファイルに分離 (2026-06-06)。todo9.md には「既存ルール仕組み化バンドル + 週次レビュー拡張」themed entries が残る。todo.md / todo2.md 〜 todo10.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### Bundle 1 dogfood checklist 実行 — `__test.ps1` block + override env 確認 (PR #174 T2-#2 採用、ADR-039 bounded lifetime data point #1) + +> **動機**: PR #174 で実装した `scratch_file_warning` stage は ADR-039 § 3 Bounded lifetime 準拠で「3-5 PR の dogfood 後に default-ON 昇格 or 却下を判定」する設計。PR #174 の PR body に未消化の dogfood checklist が残っており (`__test.ps1` を意図的に作って push し block 動作確認 / override env でバイパス確認)、これが ADR-039 bounded lifetime の初回データポイント。次の PR (Bundle 2 等) merge 前の前提条件として消化が必要。 +> +> **本タスクの位置づけ**: PR #174 post-merge-feedback Tier 2 #2 採用 (Severity Low / Frequency Low / Effort XS / Adoption Risk None)。manual operation で完結、Bundle 1 自身の運用検証 + ADR-039 bounded lifetime 体系の初回稼働確認。 +> +> **参照**: `.claude/feedback-reports/174.md` Tier 2 #2、PR #174 PR body の Test Plan unchecked items、`docs/adr/adr-039-experimental-feature-standard-pattern.md` § 3 Bounded lifetime、`src/cli-push-runner/src/stages/scratch_file_warning.rs` (`SCRATCH_FILE_WARNING_OVERRIDE` env) +> +> **実行優先度**: 🔧 **Tier 2** — Effort XS。手動 dogfood 1 セット、~10 分。 + +#### 設計決定 (案) + +- 手順: + 1. ローカル working dir に `__test_dummy.ps1` (or `.txt`) を作成 (中身は無害な dummy) + 2. `jj describe -m "test: scratch hook dogfood"` 等で commit + 3. `pnpm push` を実行 → scratch_file_warning stage が block する (EXIT_SCRATCH_FILE_WARNING = 6) を確認 + 4. `$env:SCRATCH_FILE_WARNING_OVERRIDE = "1"; pnpm push` で override → 通過確認 + 5. dogfood 完了後、`__test_dummy.ps1` ファイル削除 + commit abandon で working dir clean +- 記録: dogfood 結果 (block message / override 動作 / false positive 有無) を Bundle 2 PR body に「ADR-039 bounded lifetime data point #1」として記載 +- 注意: 本 dogfood は本リポジトリで実施。派生プロジェクトへの deploy 後の dogfood は別タスク (派生プロジェクト側の bounded lifetime data point として記録) + +#### 作業計画 + +- [ ] `__test_dummy.ps1` を working dir に作成 +- [ ] `jj describe + pnpm push` で block 動作確認 +- [ ] `$env:SCRATCH_FILE_WARNING_OVERRIDE = "1"; pnpm push` で override 動作確認 +- [ ] cleanup: `__test_dummy.ps1` 削除 + commit abandon +- [ ] 結果を Bundle 2 PR body に記録 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- block 動作: scratch_file_warning stage が `__test_dummy.ps1` を検出し EXIT 6 で push を block する +- override 動作: env var 設定後に同 stage を通過、push が成功する +- ADR-039 bounded lifetime data point #1 が記録される + +#### 詰まっている箇所 + +なし。Effort XS、manual operation で完結。 + +--- + +### docs-governance.md に「ADR multi-variant pattern section 追加時の checklist」を codify (PR #176 T3-#1 採用) + +> **動機**: PR #175 (Minor: variant 網羅性不足) + PR #176 (Nitpick: 擬似コード vs 実コード齟齬) の 2 連続観測で、ADR の multi-variant pattern section を追加する際の「参照実装リスト完全性」「実装コード例の表記精度」取りこぼしが pattern 化された。本 PR #176 で追加した ADR-041 § State Preservation Invariant section が CR Nitpick を受けた事例も同パターン。Frequency Medium (2 観測) + Effort XS で採用条件成立。 +> +> **本タスクの位置づけ**: PR #176 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`~/.claude/rules/common/docs-governance.md` に 5-8 行 checklist を追記、ADR 拡張 PR の reviewer / Claude が逆引きで参照できる reusable rule に昇格。`feedback_no_unenforced_rules.md` 例外 = 2 PR で実証 + ADR 形式 (= 設計判断 doc) への追加で機械強制不要、reviewer の judgment 補助。 +> +> **参照**: `.claude/feedback-reports/176.md` Tier 3 #1、PR #175 CR Minor finding 1 件、PR #176 CR Nitpick 1 件、`~/.claude/rules/common/docs-governance.md` (global rule、本リポジトリ外) +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule への 5-8 行追記、本リポジトリ外 (`~/.claude/`) ファイル編集。 + +#### 設計決定 (案) + +- **配置**: `~/.claude/rules/common/docs-governance.md` の document lifecycle classification 周辺、もしくは新 section "ADR Multi-Variant Pattern Authoring Checklist" +- **追記内容案** (5-8 行 checklist): + - ADR に multi-variant pattern (variant 1/2/3 等の列挙) section を追加する場合: + 1. **参照実装リストの完全性**: 各 variant に対応する参照実装 (test 関数 or 実装関数) を 1 件以上 cite。variant が言及されているのに参照実装が無い (例: variant 2 だけ書いて test が無い) ことを避ける + 2. **実装コード例の表記精度**: コード例が擬似コード (簡略化) か実コード (literal copy) かを明示。擬似コードなら「(概念)」「(簡略化)」等のマーカーを付け、実コードならパスと行番号を cite (`poll.rs:839-842` 等) + 3. **既存資料との関係**: 該当 ADR の「既存資料との関係」section に cross-link を追加 + - 由来: PR #175 (variant 網羅性不足、Minor) + PR #176 (擬似コード vs 実コード齟齬、Nitpick) の 2 連続観測 +- **派生プロジェクト transferability**: global rule のため本リポジトリで合意した内容は派生プロジェクトにも自動波及 (本 PR で `~/.claude/` 配下を直接編集する必要がある制約) + +#### 作業計画 + +- [ ] memory `feedback_global_config_backup` 適用でバックアップ取得 (`~/.claude/rules/common/docs-governance.md` を `.backup-YYYYMMDD` 等で snapshot) +- [ ] `~/.claude/rules/common/docs-governance.md` に checklist 5-8 行を新 section "ADR Multi-Variant Pattern Authoring Checklist" として追記 +- [ ] PR #175 / PR #176 を実例 cite として 1-line 引用 +- [ ] markdownlint clean 確認 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `docs-governance.md` に ADR multi-variant pattern checklist が明文化される +- 将来の ADR 拡張 PR で variant 網羅性 + 表記精度の取りこぼしが reviewer 視点で防止される +- PR #175 / PR #176 が実例として reverse-lookup 可能 + +#### 詰まっている箇所 + +- 本タスクは `~/.claude/` 配下 (本リポジトリ外) のため、repo PR には含められない。実装は別途グローバル設定編集として実施 +- バックアップ要 (memory `feedback_global_config_backup` 適用) + +--- + +### Subprocess timeout+kill lifecycle 検証テスト追加 (PR #177 T2-#1 採用) + +> **動機**: PR #177 で CR Major #2 「`run_jj_with_timeout` が timeout 後に jj 子プロセスを kill しない」を fix push したが、修正の正当性 (child process が timeout 到達時に確実に terminate される) を OS レベルで assert する回帰テストが現在ゼロ。fix は `spawn()` + `try_wait()` polling + timeout 時 `kill()` + `wait()` に書き換えたが、テストなしでは将来の変更で同型 leak 再導入が silent regression する。 +> +> **本タスクの位置づけ**: PR #177 post-merge-feedback Tier 2 #1 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None)。Major fix の回帰テスト + 今後の hook 実装で subprocess timeout pattern を使う際の reference test。Severity High = subprocess リーク (resource leak) は debug 困難な silent failure mode。Frequency Medium = 2 hook ファイル (hooks-session-start / hooks-pre-tool-validate) で同一 pattern 確認済、今後の hook 実装でも反復見込み。 +> +> **参照**: `.claude/feedback-reports/177.md` Tier 2 #1、PR #177 CR Major finding (id 3309140888 hooks-session-start / 関連 fix in hooks-pre-tool-validate)、`src/hooks-session-start/src/main.rs` `run_jj_with_timeout` / `src/hooks-pre-tool-validate/src/main.rs` `run_jj_with_timeout` (両方が同一 pattern) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。両 hook test module で integration test 風の subprocess lifecycle 検証 (~80-120 行 + helper)。 + +#### 設計決定 (案) + +- **対象 helper**: `run_jj_with_timeout` (両 hook で実装、ADR-024 で shared lib 統合候補) +- **検証内容**: + 1. **正常完了 case**: jj コマンドが timeout 内に完了 → output が返る、child は `try_wait` で reaped 済 + 2. **timeout case**: 意図的に slow command (例: `jj log` で巨大 revset / 存在しない remote への `git fetch`) → timeout 到達 → kill 発火 → child が is_finished 状態に遷移していることを assert + 3. **kill 後の resource cleanup**: kill 後 `wait()` で zombie 化していないことを assert (Unix では `waitpid` で確認、Windows では `Child::id()` の OS handle が closed か) +- **テスト fixture**: + - `Child::is_finished()` (Rust 1.18+) で kill 後の状態確認 + - `Command::new("sleep")` or `Command::new("cmd")` `/c "ping -n 100 127.0.0.1 > NUL"` (Windows) で意図的 slow command + - timeout は短く (~500ms) して test 全体を 1-2 秒で完結 +- **OS 依存性**: Windows / Linux 両対応のため `#[cfg(target_os = ...)]` で fixture を分ける、または `jj log` で確実に時間がかかる revset を使う方式に統一 +- **配置**: 両 hook の `#[cfg(test)] mod tests` 内 + 共通 helper を `tests/common/mod.rs` 等に切り出す検討 +- **memory `feedback_test_dry_antipattern.md`**: 各 test は独立 fixture で記述 (DRY 適用しない) + +#### 作業計画 + +- [ ] `Child::is_finished` (or `wait_timeout`) で lifecycle 検証手段を確定 +- [ ] hooks-session-start / hooks-pre-tool-validate の `run_jj_with_timeout` test module に 3 case 追加 +- [ ] OS 依存 fixture (slow command) を Windows / Linux で動作確認 +- [ ] dogfood: 意図的に timeout を踏ませる test を CI で安定して走らせられるか確認 (flaky test 回避) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 両 hook の `run_jj_with_timeout` で timeout 後の child kill + cleanup が OS レベルで検証される +- 同型 leak の silent regression が future PR で検出可能 +- ADR-024 (shared jj helpers library) 統合時に test も統合対象として再評価可能な構造 + +#### 詰まっている箇所 + +- OS 依存性: Windows の subprocess lifecycle API (`is_finished`) と Linux の `waitpid` で挙動差異あり。`Child::is_finished` (stable 1.78+) が両 OS 対応で推奨 +- flaky test 回避: timeout を踏ませる test は CI 環境の jitter で flaky 化リスク、500ms ~ 1s の余裕を持つ調整必要 + +--- + +### fail-closed error path (Option::None) 個別テスト追加 (PR #177 T2-#2 採用) + +> **動機**: PR #177 の CR Major #1 「`check_todo_staleness` / `build_todo_staleness_message` が `behind.unwrap_or(0) > 0` で None を non-stale 扱いし fail-closed をバイパス」については現状コード (`src/hooks-pre-tool-validate/src/main.rs:796, 846-849`) で `check_todo_staleness` 側が依然 `behind.unwrap_or(0) > 0` のまま gate バイパスの可能性が残り、`build_todo_staleness_message` 側は `if behind.is_none() { return None; }` で early return しているが回帰テスト不在。本タスクは **実装側 fix (unwrap_or → map_or(true, ...) への修正)** + **回帰テスト追加** の両方を scope に含める。security gate 関数 (Option 返値 + jj 呼び出し) の error path 検証は今後の hook でも反復必要。 +> +> **本タスクの位置づけ**: PR #177 post-merge-feedback Tier 2 #2 採用 (Severity High / Frequency Medium / Effort S / Adoption Risk None)。Major fix の回帰テスト + security gate pattern の standard reference。Severity High = fail-closed バイパスは silent security 退化。Frequency Medium = security gate + Option return pattern は今後の hooks でも反復適用見込み。 +> +> **参照**: `.claude/feedback-reports/177.md` Tier 2 #2、PR #177 CR Major finding (id 3309140878)、`src/hooks-pre-tool-validate/src/main.rs` の `check_todo_staleness` / `build_todo_staleness_message` / `count_commits_branch_ahead` +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。test module への追加 ~30-50 行、unit test で独立検証可能。 + +#### 設計決定 (案) + +- **対象 function**: `check_todo_staleness` (fail-closed 判定)、`build_todo_staleness_message` (None ケース message 出力) +- **実装側 fix (本 PR で同時に land)**: + - `check_todo_staleness` line 796: `behind.unwrap_or(0) > 0` → `behind.map_or(true, |n| n > 0)` (None を stale=true として fail-closed 化) + - `build_todo_staleness_message` line 846-849: 現状 `if behind.is_none() { return None; }` で early return しているが、明示的な fail-closed message を返す形に変更検討 (caller が None を「メッセージ無し」と非 stale 解釈しないよう調整) +- **検証 case** (memory `feedback_test_dry_antipattern.md` 適用、各 variant 独立 fixture): + 1. **`check_todo_staleness_returns_stale_when_lineage_none`**: `count_commits_branch_ahead` mock で None を返すよう注入 → result.stale = true、message に「lineage 判定不能」を含む + 2. **`build_todo_staleness_message_none_behind_marks_stale`**: `behind = None` で msg を生成 → "fail-closed で block" 文言を含む + 3. **`check_todo_staleness_normal_paths_unchanged`**: behind = Some(0) / Some(3) で従来通り動作 (regression 防止) +- **mock 戦略**: `count_commits_branch_ahead` は jj 実行依存のため、function を引数で受け取る形に refactor or test 専用 stub を導入。簡易には `count_commits_branch_ahead` を `pub(crate)` で公開し、test で別ロジック (constant None / Some(n) を返す closure) を builder で渡す pattern +- **回帰検出**: 将来 `map_or(true, ...)` を `unwrap_or(0)` 等に戻す変更で test が failing する構造を確保 +- **memory `feedback_test_dry_antipattern.md`**: 各 case は独立 setup (mock 値別)、共通 helper 化しない + +#### 作業計画 + +- [ ] `check_todo_staleness` を mock 注入可能な形に minor refactor (or test 専用 stub 追加) +- [ ] 3 case の unit test 追加 +- [ ] cargo test で pass 確認 + 意図的に fail-closed 削除して test が落ちることを手動検証 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `check_todo_staleness` / `build_todo_staleness_message` の None ケース挙動 (fail-closed) が unit test で independent 検証 +- 将来 `map_or(true, ...)` を逆向きに変更した時に 1 test が落ちる構造 +- security gate + Option return pattern の test reference として hook 実装者が参照可能 + +#### 詰まっている箇所 + +- mock 注入 vs 簡易 stub の trade-off: dependency injection で全 hook で reusable にするか、test 専用 closure で local 化するか。後者 (local stub) のが Effort S で確実 +- function signature 変更の影響範囲: `check_todo_staleness` を refactor すると call site (main.rs handle_write_edit_tool) も追従必要。最小 diff 優先で stub closure 内 mock 推奨 + +--- + +### Cross-ref edge case test coverage 追加 (PR #179 T2-#1 採用) + +> **動機**: PR #179 で cli-docs-lint の cross_ref validator を新規実装し push-runner quality_gate に統合したが、percent-encode (`%20` / `%23`)、GFM heading slug、relative path normalize (`../`) の各 variant が fixture テストで明示的に保護されていない。validator のロジック劣化を silent regression として放置するリスクがある。 +> +> **本タスクの位置づけ**: PR #179 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort S / Adoption Risk None、2026-05-28 ユーザー承認)。cross_ref validator の edge case coverage 拡充による silent regression 防止。 +> +> **参照**: `.claude/feedback-reports/179.md` Tier 2 #1、`src/cli-docs-lint/src/cross_ref.rs` (既存 9 tests に追加)、PR #179 (cli-docs-lint 本体 land) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。既存 tests と同 pattern で fixture 追加。 + +#### 設計決定 (案) + +- **対象 edge case**: + 1. **percent-encode**: 日本語 file name の percent-encode (例: `%20` 空白、`%E3...` UTF-8) を含む link を resolve できるか + 2. **GFM heading slug**: heading anchor (`#section-with-spaces` 等) の小文字化 / 空白→`-` 変換が GFM 仕様に従うか + 3. **relative path normalize**: 多段 `../` を含む link (例: docs/ から 2 階層上 root → 別 path) を正しく resolve できるか (現状の base_dir.join + canonicalize 経路) +- **fixture pattern**: 既存 cross_ref.rs の `#[cfg(test)]` mod 内の tempdir + 動的 fixture 生成 pattern を踏襲 +- **memory `feedback_test_dry_antipattern`**: 各 variant 独立 setup、共通 helper 化しない + +> NOTE: 本 entry の編集時に edge case の link 例を Markdown link 形式 (角括弧 + 丸括弧) で書くと、cli-docs-lint の cross_ref validator が backtick 内 link も誤検出する (= 本 entry land 時に発覚した false positive)。validator 自体の backtick-aware 化も本 entry 着手時に検討余地あり (現状は description + 拡張子のみで回避)。 + +#### 作業計画 + +- [ ] `src/cli-docs-lint/src/cross_ref.rs` の `#[cfg(test)]` mod に 3 case の fixture test を追加 +- [ ] cargo test で pass 確認 + 意図的に validator から正規化ロジックを抜いて test が落ちるか手動検証 +- [ ] (任意) validator の backtick-aware 化 (inline code 内の link を無視) を本 entry に同梱検討 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 3 edge case (percent-encode / GFM heading slug / relative path normalize) が unit test で independent 検証 +- silent regression を test で 1 件以上検出できる構造 +- 既存 9 tests と整合性を保つ + +#### 詰まっている箇所 + +なし。Effort S、cli-docs-lint 内のみで完結。 + +--- + +### `pnpm create-pr` PR body truncation 回避を検証する e2e/integration test 追加 (PR #181 T2-#1 採用) + +> **動機**: PR #134 + #181 で 2 回観測された `pnpm create-pr` (= `cli-pr-monitor.exe` の PR 作成モード) における PR body 切り詰め問題。複数 section・複数行の body を `--body "..."` で渡すと shell argument 解釈で改行が delimiter 処理されて body が途中で切れる silent UX 劣化が発生する。memory `feedback_pnpm_create_pr_body` で `--body-file ` workaround を採用済だが、回避策が正常動作することを担保する自動 regression gate が存在しない。 +> +> **本タスクの位置づけ**: PR #181 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-05-29 ユーザー承認)。PR #134・#181 の 2 回観測で Medium frequency に昇格、`--body-file` workaround の regression gate として採用条件成立。 +> +> **参照**: `.claude/feedback-reports/181.md` Tier 2 #1、memory `feedback_pnpm_create_pr_body`、`src/cli-pr-monitor/src/main.rs` (PR 作成モード本体)、`src/cli-pr-monitor/src/stages/` 周辺の `run_create_pr` 実装、PR #134 / #181 の create-pr 実行例 +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。既存 cli-pr-monitor test infra の流用、shell argument truncation 境界の fixture 測定。 + +#### 設計決定 (案) + +- **検証対象**: `pnpm create-pr -- --title "..." --body-file ` 経由で PR を作成した際、body 内容が source file と一致すること (truncation なし、改行保持) +- **境界測定**: PR body 文字数 (行数 / バイト数) を段階的に増やし、shell 直渡し `--body "..."` パスが切り詰める閾値と `--body-file` が切り詰めない閾値の境界を fixture で測定、regression gate として記録 +- **test 方式**: `gh pr create` の dry-run option がないため、cli-pr-monitor の argv 組み立て層を unit test 対象にする (実 PR 作成は行わない)、または integration test で mock gh CLI を介して argv の最終 shape を assert +- **memory `feedback_test_dry_antipattern`**: 各 variant 独立 setup、共通 helper 化しない + +#### 作業計画 + +- [ ] cli-pr-monitor の PR 作成モードで argv 組み立て層を関数化 (test 可能な shape に refactor、必要なら) +- [ ] `#[cfg(test)]` mod に 3 fixture を追加: (a) 短い single-line body、(b) 複数行 body 経由 `--body-file`、(c) 直接 `--body` を渡した場合の truncation 再現 +- [ ] cargo test で pass 確認 + 既存 cli-pr-monitor test との独立性確認 +- [ ] truncation 境界の測定結果を test コメントに記録 (将来の閾値変更時の reference) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `--body-file` 経由が複数行 body で truncation なしに動作することが unit test で保護 +- shell 直渡し `--body "..."` で truncation が起こる境界が fixture で測定済 +- silent regression を test で 1 件以上検出できる構造 +- 既存 cli-pr-monitor test との独立性 (mock 設定の交差なし) + +#### 詰まっている箇所 + +`gh pr create` 自体に dry-run option がないため、実 PR 作成を伴わない検証戦略を要設計 (argv 組み立て層の関数化 or mock gh CLI)。Effort S 想定だが test 戦略次第で M に膨らむ可能性あり。 + +#### 補足 (PR #182 T2-#2 採用候補との関係、2026-05-29 ユーザー判断) + +- PR #182 post-merge-feedback の T2-#2 (`pnpm-create-pr-body-guard` hook の guard test 追加) は本 165 と test 層 scope が重複するため、独立 entry 化せず本 entry に集約。analyzer は「本 session で `pnpm-create-pr-body-guard` hook による mitigate 実施」と articulate したが、これは hallucination (本 session では `--body-file` workaround を使ったのみで guard hook は触れていない) +- 重要な supplementary fact: PR #134 post-merge-feedback で `pnpm-create-pr-body-guard` hook 追加が **✅ 採用判定されたが、実装は完了していない状態** (= unfulfilled adoption、`.claude/feedback-reports/134.md` Tier 1 #1 参照)。順位 152 (todo 削除時の事前 land 確認手順) と関連する process learning として記録 +- 本 165 着手時に guard hook が実装済なら test 範囲を 2 層に拡張する: + 1. (本 entry の主旨) `--body-file` workaround が複数行 body で truncation なしに動作することを verify + 2. (拡張) guard hook が `pnpm create-pr -- ... --body "..."` を block して `--body-file` に誘導することを verify +- hook 未実装のまま本 165 を land する場合、guard 層の test は将来の guard 実装 follow-up entry に切り出す + +--- + +### `git-workflow.md § Multi-PR chaining` を「1 PR 内 multi-commit + intent 明記」パターンに拡張 (PR #183 T3-#1 採用) + +> **動機**: PR #119/#120/#121 + 本 PR #183 で **4 回観測された** multi-commit single-PR bundling パターンを `~/.claude/rules/common/git-workflow.md` § Multi-PR chaining に codify する。現状の同 section は「複数 PR の分割」を扱うが、「1 PR 内で commit を分離する判断基準」「各 commit message での intent 明記の重要性」が未記載。reviewer (CodeRabbit / 人間) が PR diff を読む際、commit description 単位の intent が明確だと review 効率が向上する。Frequency High に到達したため Tier 3 codify 条件成立。 +> +> **本タスクの位置づけ**: PR #183 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency High / Effort S / Adoption Risk None、2026-05-29 ユーザー承認)。`~/.claude/` global 配下のため派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ自動波及。 +> +> **参照**: `.claude/feedback-reports/183.md` Tier 3 #1、`~/.claude/rules/common/git-workflow.md` § Multi-PR chaining ベストプラクティス (既存 section、拡張対象)、観測 PR: #119/#120/#121/#183 + +#### 設計決定 (案) + +`git-workflow.md § Multi-PR chaining ベストプラクティス` に以下を追記: + +- **「1 PR 内の multi-commit 分離」の判断基準**: 異なる論理単位 (例: docs update + feature impl) は **commit を分けて 1 PR で land** することで、reviewer が論理単位ごとに review focus を切り替えられる +- **commit message の intent 明記**: 各 commit description は単独で「何を / なぜ」を理解できる形で記述。`docs(todo): X 採用` / `feat(takt): Y 実装` 等の Conventional Commits + intent suffix のパターンを推奨 +- **典型例**: PR #181 (handoff doc + post-merge-feedback adoption の 2 commit)、PR #183 (Bundle CR-RL todo + A01 ADR fix の 2 commit) を実例として cite +- **single-commit vs multi-commit の境界**: 同一論理単位は 1 commit (例: 単一 facet の implementation + test)。**論理単位が異なる** ときに分離する (例: docs update commit + impl commit) + +#### 作業計画 + +- [ ] `~/.claude/rules/common/git-workflow.md` § Multi-PR chaining ベストプラクティス に新 sub-section 「1 PR 内 multi-commit の判断基準」を追加 (~10-15 行) +- [ ] PR #181 / #183 の commit 構成を実例として inline cite +- [ ] **`feedback_global_config_backup`** 適用: ~/.claude/* を触る前に snapshot 取得 (`cp -r ~/.claude ~/__claude-backup-YYYYMMDD`) +- [ ] markdownlint clean 確認 +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への展開は別タスク +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `~/.claude/rules/common/git-workflow.md` に「1 PR 内 multi-commit 分離」と「intent 明記」のガイドが codify される +- 将来の AI / 人間セッションで commit 分割判断と intent 記述が一貫した形で適用される +- markdownlint clean + +#### 詰まっている箇所 + +なし。Effort S、既存 section への追記のみで scope 明確。 + +--- + +### `docs-governance.md` に「Operational reference vs Pointer reference」区別 section を追加 (PR #183 T3-#2 採用) ★ Bundle DG-RULES + +> **動機**: PR #183 で A01 修正 (8 ADR の ephemeral todo 参照を permanent reference に置換) を実施する際、各 reference が以下のどちらに該当するか判定する作業が発生した: +> - **operational reference**: workflow / behavior が ephemeral artifact をどう扱うかを記述するもの (例: 「ADR-031 workflow が `docs/todo.md` に追記する」)。dead-pointer リスクなし、保持可能 +> - **pointer reference**: 特定の section 名 / 順位 N / Phase A-F 等を指すもの (例: 「Phase A-F section を参照」)。dead-pointer リスクあり、置換必要 +> +> 現状の `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle は「permanent → ephemeral 参照は dead-pointer 化する」を codify しているが、**「operational reference は除外」という重要な判定基準が未記載**。本 PR の修正で ADR-031 lines 79-302 の中で line 270 のみが真の pointer reference だった実例が示すように、operational reference を pointer と誤認すると過剰修正で workflow 記述自体を壊す可能性がある。 +> +> **本タスクの位置づけ**: PR #183 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None、2026-05-29 ユーザー承認)。`~/.claude/` global 配下のため派生プロジェクトへ自動波及。Bundle DG-RULES (本 entry + 順位 172) で同 PR land 推奨。 +> +> **参照**: `.claude/feedback-reports/183.md` Tier 3 #2、`~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle (既存 section、拡張対象)、PR #183 の 8 ADR 修正 commit (実例として cite) + +#### 設計決定 (案) + +`docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section「Operational vs Pointer Reference」を追加: + +- **Operational reference の定義**: workflow / 仕様 / behavior が ephemeral artifact (todo.md 等) を「どう扱うか」を記述するもの。**保持可能**。dead-pointer 化しない理由 = ephemeral artifact の特定 entry を指していないため。 + - 例: 「skill `/weekly-review` は採用 finding を `docs/todo.md` の新セクションに追記する」(動作記述、section 名は workflow が生成するため stale 化しない) + - 例: 「reviewer は `docs/todo.md` を作業計画ファイルとして扱う」(classification、特定 entry を指さない) +- **Pointer reference の定義**: 特定の section 名 / 順位 N / Phase A-F 等を指すもの。**dead-pointer 化リスクあり = 置換必要**。 + - 例: 「Phase B-F は `docs/todo.md` の section X を参照」(stale 化) + - 例: 「順位 42 を読む」(entry 削除で dead pointer) +- **判定基準**: reference が指す対象が「現在存在する specific entry / section」なら pointer、「workflow が描く general behavior」なら operational +- **実例**: PR #183 の ADR-031 line 270 (pointer、置換) vs lines 79-302 内の workflow 記述 (operational、保持)。ADR-034 の 順位 N + PR # pair (PR # 側が permanent reference として fallback、ephemeral 単独参照ではない) も example として cite + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section 「Operational vs Pointer Reference」を追加 (~15-20 行) +- [ ] PR #183 の修正例を inline cite (8 ADR の修正と「operational reference として保持」の判断根拠) +- [ ] **`feedback_global_config_backup`** 適用: ~/.claude/* を触る前に snapshot 取得 +- [ ] markdownlint clean 確認 +- [ ] 順位 172 (memory 追加) と同 PR で land 推奨 (Bundle DG-RULES、docs/rule + memory の 2 層) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `~/.claude/rules/common/docs-governance.md` に operational vs pointer の区別が codify される +- 将来の reviewer / AI が ADR 修正時に過剰修正 (operational reference の誤置換) を回避できる +- 派生プロジェクトへの自動波及で一貫した判定基準が確立 +- markdownlint clean + +#### 詰まっている箇所 + +なし。Effort S、既存 section への sub-section 追加で scope 明確。 + +--- + +### CR ephemeral artifact Nitpick の統一 skip 基準を memory に codify (PR #183 T3-#3 採用) ★ Bundle DG-RULES + +> **動機**: PR #183 で CodeRabbit が docs/todo9.md (= ephemeral artifact) 内の行番号参照 (`lines 1298-1370` 等) を Nitpick として指摘した。これは「行番号は将来 drift する」という general principle としては正しいが、**ephemeral artifact (todo entry) は完了時に削除される設計** のため、永続化を求めるルールを適用するのは over-engineering。本 PR では skip 判断したが、同パターンが構造的に recurring と予想される (CR は ephemeral artifact を permanent doc と同等に扱う傾向)。判断基準を memory entry に codify することで、将来のセッションで一貫した skip 判断が可能になる。 +> +> **本タスクの位置づけ**: PR #183 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-05-29 ユーザー承認)。`~/.claude/projects/.../memory/` 配下のため**派生プロジェクトには波及しない** (本リポジトリ専用)。Bundle DG-RULES (順位 171 + 本 entry) で同 PR land 推奨。 +> +> **参照**: `.claude/feedback-reports/183.md` Tier 3 #3、既存 memory `feedback_coderabbit_no_actionable_merge_signal.md` (補完関係)、PR #183 の Nitpick 2 件 (CR-N1: 順位 168 line 1298-1370 / CR-N2: 順位 169 line 64/185-186) + +#### 設計決定 (案) + +新 memory ファイル `feedback_coderabbit_ephemeral_nitpick.md` を作成: + +- **rule 名**: `feedback_coderabbit_ephemeral_nitpick` +- **type**: feedback +- **description**: CR が ephemeral artifact (`docs/todo*.md` 等) 内の行番号参照を Nitpick (💤 Low value) として指摘した場合は skip 推奨 +- **content**: + - **why**: ephemeral artifact (todo entry) は完了時に削除される設計のため、永続化を求めるルール (line drift 防止 = symbol/section 参照推奨) の適用は over-engineering + - **how to apply**: CR Nitpick が `docs/todo*.md` 系 ephemeral artifact に対する line/symbol drift を指摘した場合、skip + merge 判断を維持。既存 memory `feedback_coderabbit_no_actionable_merge_signal` の「Nitpick 💤 Low value は skip 推奨」の補完。entry 実装着手時には自然に symbol 参照に置き換わる流れになるため、todo entry レベルで先取り fix する価値は低い + - **境界**: permanent artifact (ADR / coding-style.md 等) への同種指摘は通常通り対応する。判定基準 = 対象 file の lifecycle (ephemeral or permanent)。本 rule は ephemeral artifact 専用 + - **実例**: PR #183 の CR-N1 / CR-N2 (docs/todo9.md の行番号参照を skip した実例) + +#### 作業計画 + +- [ ] `~/.claude/projects/E--work-claude-code-hook-test/memory/feedback_coderabbit_ephemeral_nitpick.md` を新規作成 (~30-50 行、frontmatter 含む) +- [ ] `~/.claude/projects/E--work-claude-code-hook-test/memory/MEMORY.md` index に 1 行追加 (各 entry が「タイトル + 1 行 hook」の MEMORY.md 規約に従い、新 memory `feedback_coderabbit_ephemeral_nitpick.md` への 1 行 link を追加) +- [ ] **`feedback_global_config_backup`** 適用: 念のため memory ディレクトリの snapshot 取得 (`cp -r ~/.claude/projects/.../memory ~/__memory-backup-YYYYMMDD`) +- [ ] markdownlint clean 確認 (memory ファイル + MEMORY.md の両方) +- [ ] 順位 171 (docs-governance.md 拡張) と同 PR で land 推奨 (Bundle DG-RULES、docs/rule + memory の 2 層補強) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 新 memory ファイル `feedback_coderabbit_ephemeral_nitpick.md` が作成される +- MEMORY.md index に登録される +- 将来のセッションで CR が ephemeral artifact 内 Nitpick を出した場合、本 rule から逆引き可能になる +- markdownlint clean + +#### 詰まっている箇所 + +なし。Effort XS、新規 memory ファイル + index 1 行追加のみ。 + +--- + +### subprocess utils 5 crate 重複 (combine_output + drain_pipe + wait_with_timeout + run_cmd) を `lib-subprocess-utils` に extract (PR #182 dry-run S01 + Phase E dogfood WR-2026-06-01-S01 採用) + +> **動機**: PR #182 Phase B dry-run で検出された finding WR-2026-05-29-S01 に加え、**Phase E dogfood (2026-06-01) で WR-2026-06-01-S01 (High) として scope が拡大**: subprocess 管理 utility 群が 4-5 crate 横断で重複している。 +> +> **重複対象 (scope 拡大版)**: +> - `combine_output(stdout, stderr)` 8 行関数: 5 crate (`cli-pr-monitor` / `cli-push-runner` / `cli-push-pipeline` / `cli-merge-pipeline` / `hooks-post-tool-linter`) で重複 (cli-pr-monitor では `#[allow(dead_code)]` 付与で生産 path 未到達) +> - `drain_pipe` / `wait_with_timeout` / `run_cmd`: 4 crate (`cli-push-runner/src/runner.rs` / `cli-pr-monitor/src/runner.rs` / `cli-merge-pipeline/src/main.rs` / `cli-push-pipeline/src/main.rs`) で重複 +> - `MAX_LINES` 定数: 4 crate 間で不整合 (40 / 200 / なし) — callsite 設定可能パラメータとして公開する +> +> ADR-026 Cargo workspace + ADR-012 lib-* naming の既存パターンで解決コスト低、保守リスクが各 PR で蓄積中。 +> +> **本タスクの位置づけ**: PR #182 dry-run S01 採用 (2026-05-29 ユーザー承認) + Phase E dogfood (2026-06-01) WR-2026-06-01-S01 (Severity High) で augment 採用。ADR-031 § Phase 4 「重複検出は MVP では実装しない」運用の partial overlap 検出 → augment 判断のフローが機能した実例 (skill 重複検出 → 3 択 → user augment 選択)。 +> +> **参照**: PR #182 dry-run report、Phase E dogfood report (`.claude/weekly-reviews/2026-06-01.md` および `.takt/runs/20260601-095710-weekly-review-2026-06-01/reports/`)、`src/cli-pr-monitor/src/runner.rs:80-89` (function) + `:282-298` (tests)、`src/cli-push-runner/src/runner.rs` / `src/cli-merge-pipeline/src/main.rs` / `src/cli-push-pipeline/src/main.rs` (drain_pipe 等の重複)、`src/hooks-post-tool-linter/` (他 4 crate の重複)、ADR-024 (shared jj-helpers library パターン)、ADR-026 (Cargo workspace) +> +> **実行優先度**: 🔧 **Tier 2** → 🚀 **Tier 1 検討余地** — Effort S-M。Phase E dogfood で High severity 再確認、4-5 crate 横断で更新コスト線形成長中。Cargo workspace 内の単純な lib extract、5 crate を順次差し替え。 + +#### 設計決定 (案) + +- **採用 strategy** (analyzer Option A 推奨): `lib-runner-utils` 新 crate (or `lib-process-helpers` 等の既存 lib-* crate を選定) に `combine_output(stdout, stderr) -> String` を移管。5 crate (`cli-*` 4 件 + `hooks-post-tool-linter`) から `pub use lib_runner_utils::combine_output;` で再 export +- **不採用 strategy** (analyzer Option B): cli-pr-monitor からのみ削除する最小修正案 → 他 4 crate に同じ未使用問題が残るため不採用、Option A の方が systemic 解決 +- **crate 名選定**: 既存 lib-* 一覧を `cargo metadata` で確認、`lib-runner-utils` / `lib-process-helpers` / `lib-subprocess` 等の候補から選定。新規作成より既存 lib-* (例: shared-jj-helpers) への追加が好ましい (ADR-024 の流れ) +- **test 移管**: 既存 4 test の集約版を新 crate の `#[cfg(test)]` に 1 set のみ配置、各 cli-* / hooks-* 側の test は削除 +- **memory `feedback_test_dry_antipattern`**: test は移管後も独立 variant を維持 (helper で共通化しない) + +#### 作業計画 + +- [ ] `cargo metadata --no-deps` で既存 lib-* crate を列挙、`combine_output` の論理 location として最も自然な crate を選定 +- [ ] 選定 crate (新規 or 既存) に `combine_output` を pub 関数として追加 + 集約 test を 1 set 配置 +- [ ] cli-pr-monitor / cli-push-runner / cli-push-pipeline / cli-merge-pipeline / hooks-post-tool-linter の 5 crate の各 `Cargo.toml` に新 dep を追加 (新規 lib の場合) +- [ ] 各 crate の `combine_output` impl + tests を削除、`use ::combine_output;` に置換 +- [ ] cargo test で 5 crate 全 pass 確認 +- [ ] cargo clippy で `#[allow(dead_code)]` が消えることを確認 (extract により生産 path に乗る、または未使用なら別 PR で削除判断) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `combine_output` 関数の単一 source of truth が新 crate (または選定 lib-*) に確立 +- 5 cli-*/hooks-* crate が再 export 経由で同 impl を共有 +- 既存 test が集約版 1 set + 各 crate での 4 set 削除で計 4 set 削減 +- `#[allow(dead_code)]` 付与が不要になる (extract 後の lib では pub function として正規 export 経路) +- cargo workspace 全体で cargo test + cargo clippy が pass + +#### 詰まっている箇所 + +extract 先の crate 選定: 既存 lib-* に追加するか新規 `lib-runner-utils` を作るかの判断。新規 crate は Cargo workspace に 1 line 追加で済むが、既存 lib-* (例: lib-pr-monitor-common 等の既存 shared crate) への追加の方が **Effort S** 寄り、新規作成だと **Effort M** に近づく。`cargo metadata` 結果次第。 + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。) diff --git a/docs/todo2.md b/docs/todo2.md index 591016d7..544136ba 100644 --- a/docs/todo2.md +++ b/docs/todo2.md @@ -368,9 +368,11 @@ Phase 2 (任意、段階的緩和) > > **本タスクの位置づけ**: `cli-pr-monitor` の正常終了パスに smoke test または integration test を追加。`pnpm create-pr` 完了後にプロセスが exit するかを timeout 付きで検証する。 > -> **参照**: `.claude/feedback-reports/85.md` Tier 2 #2 +> **Status update (2026-06-06)**: PR #85 当時の cli-pr-monitor は **daemon 永続常駐モデル** だった。ADR-018 (PR #113 land) で **CronCreate park モデル + ADR-030 (PR #154) で短命プロセス + state file 再起動** に移行し、終了経路自体の構造が変わった。PR #85 で観測された「termination 残留」は park 移行後に再現するか不明。**着手前の root cause 再調査が必要** (現状の park モデルでも問題が残っているかを smoke で確認 → 残っていれば smoke を test 化、解消済なら本 entry 削除候補)。 > -> **実行優先度**: 🔧 **Tier 2** — S 工数、回帰防止が主目的。発生頻度は低いが UX への直接影響あり (手動 kill 必要)。 +> **参照**: `.claude/feedback-reports/85.md` Tier 2 #2、ADR-018 (CronCreate park モデル移行)、ADR-030 (deterministic post-merge feedback) +> +> **実行優先度**: 🔧 **Tier 2** — S 工数、回帰防止が主目的。発生頻度は低いが UX への直接影響あり (手動 kill 必要)。Status update により、まず再現確認が前段に必要。 #### 設計決定 (案) diff --git a/docs/todo3.md b/docs/todo3.md index 0bb9a1d2..56f17748 100644 --- a/docs/todo3.md +++ b/docs/todo3.md @@ -1,227 +1,229 @@ -# TODO (Part 3) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo2.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #88 以降の新規エントリは本ファイルに記録した。本ファイルも PR #96 セッションで 50KB 接近のため、それ以降の新規エントリは [docs/todo4.md](todo4.md) へ。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### `vitest` を devDependencies に固定 (PR #88 T2-3) - -> **動機**: Stop hook の `pnpm test` → `npx vitest run` が `pnpm-lock.yaml` に vitest なしのため npx がネット DL を試みて偽陽性 FAIL する事象を観測。ネット環境・キャッシュ依存の不確実性を排除し、Stop gate を deterministic にする。 -> -> **本タスクの位置づけ**: PR #88 で markdownlint-cli2 を `--no-install` で安定化させたのと同じ思想。テスト実行が外部 DL なしで完結する状態を維持する。 -> -> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #3 finding -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Small。Stop gate の偽陽性 FAIL を排除する効果は中-高 (毎回の Stop で発生する潜在リスクの解消)。 - -#### 背景 - -- `package.json` の `"test": "npx vitest run"` は vitest がローカルにあれば走るが、なければ npx が DL を試みる -- ネット未接続環境やプロキシ環境で偽陽性 FAIL → 開発体験悪化 -- markdownlint-cli2 は PR #88 で `--no-install` を付けて DL を抑止、devDependencies で版固定済 → 同じパターンを vitest にも適用 - -#### 設計決定 (案) - -- 案 A: `vitest` を devDependencies に追加し `pnpm-lock.yaml` に固定。`pnpm test` script は変更不要 (`npx --no-install vitest run` とするか `vitest run` 直呼びにするかは実装時判断) -- 案 B: `pnpm test` script を `npx --no-install vitest run` に変更し、明示的にローカル参照を強制 -- 推奨: 案 A + script 側を `--no-install` 付きに変更 (二重防御) -- 既存テストが現行通り動作することを確認 (既存の vitest 設定は不変、依存固定のみ) - -#### 作業計画 - -- [ ] `vitest` の現行バージョン確認 (`npx vitest --version` 等) -- [ ] `pnpm add -D vitest` (またはインスタンス化済バージョンで固定) -- [ ] `package.json` の test script を `npx --no-install vitest run` に更新 -- [ ] `pnpm test` 動作確認 -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- `pnpm test` がローカルの vitest のみで動作 (ネット切断状態で実行可) -- Stop hook の偽陽性 FAIL が発生しなくなる -- `pnpm-lock.yaml` に vitest が固定されている - -#### 詰まっている箇所 - -なし (Effort Small、devDep 追加 + script 修正のみ) - ---- - -### `pnpm create-pr` 必須引数未指定時のヘルプ改善 (PR #88 T2-5) - -> **動機**: 引数なしで `pnpm create-pr` を実行すると `gh pr create` が `must provide --title and --body (or --fill or fill-first or --fillverbose)` エラーのみ出力し、使用例が示されない。今回 PR 作成時に手動ワークアラウンド (`pnpm prepare-pr-body` で `.tmp-pr-body.md` 生成 → `pnpm create-pr -- --title "..." --body-file .tmp-pr-body.md`) が必要になった。`gh` のエラーをそのまま流す現設計だと、Claude や人間が次の手を察するのに余計な往復が発生する。 -> -> **本タスクの位置づけ**: cli-pr-monitor の UX 改善。現実装は `gh pr create` への薄い wrapper だが、必須引数チェックを wrapper 側で実施することで使用例付きエラーを返せる。 -> -> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #5 finding -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Small。daily efficiency への影響中 (PR 作成は頻繁ではないが、エラー時の摩擦が高い)。 - -#### 背景 - -- 現実装: `cli-pr-monitor.exe` (PR 作成モード) は受け取った args をそのまま `gh pr create` に forwarding -- `gh` のエラーは英語かつ汎用的。プロジェクト固有の推奨 (prepare-pr-body スクリプトを使う等) は反映されない -- Claude / 人間の双方が「`pnpm prepare-pr-body` を先に呼ぶ」運用を覚える必要がある - -#### 設計決定 (案) - -- cli-pr-monitor の PR 作成モード入口で `--title` / `--body` / `--body-file` / `--fill*` 系のいずれかが指定されているかチェック -- 未指定なら使用例付きエラーを stderr に出力して非 0 で exit: - -```text -Error: PR title and body are required. -Usage: - pnpm create-pr -- --title "feat: ..." --body-file .tmp-pr-body.md - pnpm create-pr -- --title "feat: ..." --fill-verbose -Hint: - Run `pnpm prepare-pr-body` first to generate `.tmp-pr-body.md` from stdin. -``` - -- gh の実行は引数チェック後にのみ進む - -#### 作業計画 - -- [ ] cli-pr-monitor の PR 作成モード入口で arg validation 追加 -- [ ] エラーメッセージ作成 (上記の使用例ベース) -- [ ] dogfood: 引数なしで `pnpm create-pr` 実行 → 改善されたエラーが出ることを確認 -- [ ] 既存の正常系 (--title --body-file 指定時) が変わらず動作することを確認 -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- 引数なし実行でプロジェクト固有の使用例 + Hint がエラーに含まれる -- `--title` + `--body-file` または `--fill*` 指定時は従来通り PR 作成が走る - -#### 詰まっている箇所 - -なし (Effort Small、cli-pr-monitor 入口の arg parser 拡張のみ) - ---- - -### `.failed` marker への recovery 手順自己文書化 (PR #90 T2-2) - -> **動機**: ADR-030 で確立した soft-fail 機構 (`.md.failed` marker + L2 recovery) は PR #89 セッションで実際に発火し、UserPromptSubmit hook 経由で recovery が機能することが実証された。しかし現状の marker file は識別子のみで、recovery に必要な手順 (再実行コマンド、必要な引数、想定所要時間、よくある失敗原因) が外部 (ADR-030 / skill SKILL.md) を参照しないと分からない。marker 自体に手順を埋め込めば、将来 (ドキュメント所在を忘れた時 / ADR-030 が改訂された時 / 派生プロジェクトでの再現時) の recovery が省力化される。 -> -> **本タスクの位置づけ**: ADR-030 の運用負荷削減。soft-fail 機構そのものは正しく動作しているため、UX 改善カテゴリ。marker file の content をテンプレート化し、生成側 (cli-merge-pipeline) で recovery 手順 + コマンド例 + ADR-030 への参照を含める。 -> -> **参照**: `.claude/feedback-reports/90.md` の Tier 2 #2 finding -> -> **実行優先度**: 🔧 **Tier 2** — 工数 S。daily efficiency への影響中 (recovery 発生頻度は低いが、発生時の摩擦を低減)。rate-limit 系 task (cli-pr-monitor ポーリング延長 PR #88 T2-4、完了済 / post-pr-review rate-limit 自動検出) ほど critical ではないが、ADR-030 の long-term 運用品質に寄与。 - -#### 背景 - -- ADR-030 の L1 (cli-merge-pipeline → takt workflow 同期実行) が失敗した場合、`.claude/feedback-reports/.md.failed` marker が残存する設計 -- L2 recovery (UserPromptSubmit hook) が次セッションで marker を検出し additionalContext で再実行を促す -- PR #89 セッションで実際に soft-fail が発火し、recovery 経路が機能した実証あり -- 課題: marker file の content が空 or 識別用の最小情報のみで、再実行手順は外部ドキュメント (ADR-030 / skill SKILL.md) を参照する必要がある -- 将来リスク: ADR-030 改訂・派生プロジェクト展開・時間経過による参照先不明化により、recovery が高摩擦化する可能性 - -#### 設計決定 (案) - -- cli-merge-pipeline (or takt workflow 失敗時の marker 書込み箇所) で marker content をテンプレート化 -- テンプレート例: - -~~~markdown -# Post-Merge Feedback Failed: PR # - -This marker indicates the post-merge feedback workflow failed for PR #. -The L2 recovery hook (UserPromptSubmit) will detect this file on the next -prompt and prompt Claude to re-run the workflow. - -## Manual Recovery (if L2 hook does not fire) - -1. Check the takt run logs at `.takt/runs//` for the failure reason. -2. Re-run the workflow: - - ```sh - takt run post-merge-feedback.yaml --input pr= - ``` - -3. On success this marker will be replaced by `.claude/feedback-reports/.md`. - -## Failure Context - -- Failed at: -- takt run id: -- Last error (truncated to 500 chars): - -## Reference - -- ADR-030: docs/adr/adr-030-deterministic-post-merge-feedback.md -~~~ - -- marker 内容は ADR 改訂耐性のため「ADR-030 への参照リンク + 当時の手順」を共存させる -- 失敗の context (timestamp / run-id / stderr tail) を含めることで、再実行前に原因切り分けがしやすくなる -- 本タスク完了後、L2 hook の additionalContext からも marker content を読ませる構成にすれば自己完結度が上がる (本タスクの拡張、必須ではない) - -#### 作業計画 - -- [ ] cli-merge-pipeline の `.failed` marker 書込みロジックを確認 (現状 content がどう生成されているか) -- [ ] テンプレート文字列を crate 内 const として定義 or 外部 template ファイル化を判定 -- [ ] timestamp / run-id / stderr tail を marker に埋め込む実装 -- [ ] L2 hook (`hooks-user-prompt-feedback-recovery` 等) の additionalContext 出力で marker content を流用するか判定 (本タスクの scope 内 or 別タスク化) -- [ ] dogfood: 意図的に takt fail を inject し、marker に手順 + context が含まれることを確認 -- [ ] ADR-030 を更新 (marker format の section を追記) -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- `.failed` marker file に recovery 手順 + コマンド例 + ADR-030 参照 + failure context が含まれる -- ADR-030 の本文に marker format が明文化される -- 派生プロジェクトでも同じ template が機能する (ADR-030 が外部 reference として読める前提) - -#### 詰まっている箇所 - -なし (Effort S、cli-merge-pipeline の marker 書込み箇所のテンプレート化のみ) - ---- - -### takt ハーネスの `REJECT-ESCALATE` terminal verdict 実装 (PR #91 T2-2) - -> **動機**: PR #91 の post-pr-review で `supervise` step が 4 回、`fix_supervisor` step が 4 回の計 8 ステップを「修正不可能な制約あり」と繰り返し報告したにもかかわらず、takt harness はループを継続した。`.claude/` filter + ADR-030 制約明記 task (PR #91 T2-1 + T3-2 Bundle) が path-based に解決するのに対し、本 task は **iteration 上限到達前に「人間判断に委譲する」と AI 自身が宣言できる verdict** を提供する一般解。 -> -> **本タスクの位置づけ**: takt の condition routing に新 terminal verdict `reject-escalate` を追加。`supervise` / `fix_supervisor` step がこのシグナルを返したら harness は即終了 + ユーザー committee `.takt/runs/.../reports/escalation.md` を生成し、Claude が次セッションで読んで判断できる経路を提供。 -> -> **参照**: `.claude/feedback-reports/91.md` の Tier 2 #2 -> -> **実行優先度**: 🔧 **Tier 2** — 工数 M (数日)。takt 本体改修なので大きい。**rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) の land 後に実施推奨**。本 task は根本解だが、post-pr-review fix loop の `.claude/` filter (Bundle T で land 済) で path-related な pathological loop は既に解決済み。 - -#### 設計決定 (案) - -- takt のループ制御ロジックに新 terminal verdict `reject-escalate` を追加 - - 既存 verdict: `approved` / `needs_fix` / `user_decision` - - 新規: `reject-escalate` (= "AI 自己判断で escalate、harness 即終了") -- supervise / fix_supervisor instruction の verdict 一覧に `reject-escalate` を追加 - - 発火条件: 「修正不可能な制約 (sensitive file / external dependency / philosophical disagreement) を 2 iteration 連続で観測」 -- harness 側の処理: - - `reject-escalate` 検出時は loop break + `escalation.md` 生成 (理由 + 経緯) - - report phase は scoped-down で短縮実行 -- iteration 消費削減効果の測定: 既存 telemetry に `early_terminate_count` を追加 - -#### 作業計画 - -- [ ] takt 本体に `reject-escalate` verdict を追加 -- [ ] facets instruction (`supervise.md` / `fix_supervisor.md`) に発火条件と例文を追記 -- [ ] harness ループ制御ロジックを実装 -- [ ] `escalation.md` テンプレート作成 -- [ ] dogfood: `.claude/` filter (T2-1+T3-2 Bundle) 完了後、本実装前に意図的な reject-escalate ケースを inject して動作確認 -- [ ] takt-test-vc にも反映 (将来) -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- `supervise` / `fix_supervisor` が `reject-escalate` を返すと harness が即終了 -- iteration 上限到達による空費が削減される (定量化可能) -- escalation.md が次セッションで読める形で生成される - -#### 詰まっている箇所 - -- takt 本体改修のため `~/.claude/projects/takt-test-vc/` 連動も視野に入れる必要あり -- rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) の land 後に着手することで、verdict ベースの一般解として完成する。post-pr-review fix loop の `.claude/` filter (Bundle T、完了済) は path-based 解決の対 (補完関係) - +# TODO (Part 3) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo2.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #88 以降の新規エントリは本ファイルに記録した。本ファイルも PR #96 セッションで 50KB 接近のため、それ以降の新規エントリは [docs/todo4.md](todo4.md) へ。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### `vitest` を devDependencies に固定 (PR #88 T2-3) + +> **動機**: Stop hook の `pnpm test` → `npx vitest run` が `pnpm-lock.yaml` に vitest なしのため npx がネット DL を試みて偽陽性 FAIL する事象を観測。ネット環境・キャッシュ依存の不確実性を排除し、Stop gate を deterministic にする。 +> +> **本タスクの位置づけ**: PR #88 で markdownlint-cli2 を `--no-install` で安定化させたのと同じ思想。テスト実行が外部 DL なしで完結する状態を維持する。 +> +> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #3 finding +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Small。Stop gate の偽陽性 FAIL を排除する効果は中-高 (毎回の Stop で発生する潜在リスクの解消)。 + +#### 背景 + +- `package.json` の `"test": "npx vitest run"` は vitest がローカルにあれば走るが、なければ npx が DL を試みる +- ネット未接続環境やプロキシ環境で偽陽性 FAIL → 開発体験悪化 +- markdownlint-cli2 は PR #88 で `--no-install` を付けて DL を抑止、devDependencies で版固定済 → 同じパターンを vitest にも適用 + +#### 設計決定 (案) + +- 案 A: `vitest` を devDependencies に追加し `pnpm-lock.yaml` に固定。`pnpm test` script は変更不要 (`npx --no-install vitest run` とするか `vitest run` 直呼びにするかは実装時判断) +- 案 B: `pnpm test` script を `npx --no-install vitest run` に変更し、明示的にローカル参照を強制 +- 推奨: 案 A + script 側を `--no-install` 付きに変更 (二重防御) +- 既存テストが現行通り動作することを確認 (既存の vitest 設定は不変、依存固定のみ) + +#### 作業計画 + +- [ ] `vitest` の現行バージョン確認 (`npx vitest --version` 等) +- [ ] `pnpm add -D vitest` (またはインスタンス化済バージョンで固定) +- [ ] `package.json` の test script を `npx --no-install vitest run` に更新 +- [ ] `pnpm test` 動作確認 +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- `pnpm test` がローカルの vitest のみで動作 (ネット切断状態で実行可) +- Stop hook の偽陽性 FAIL が発生しなくなる +- `pnpm-lock.yaml` に vitest が固定されている + +#### 詰まっている箇所 + +なし (Effort Small、devDep 追加 + script 修正のみ) + +--- + +### `pnpm create-pr` 必須引数未指定時のヘルプ改善 (PR #88 T2-5) + +> **動機**: 引数なしで `pnpm create-pr` を実行すると `gh pr create` が `must provide --title and --body (or --fill or fill-first or --fillverbose)` エラーのみ出力し、使用例が示されない。今回 PR 作成時に手動ワークアラウンド (`pnpm prepare-pr-body` で `.tmp-pr-body.md` 生成 → `pnpm create-pr -- --title "..." --body-file .tmp-pr-body.md`) が必要になった。`gh` のエラーをそのまま流す現設計だと、Claude や人間が次の手を察するのに余計な往復が発生する。 +> +> **本タスクの位置づけ**: cli-pr-monitor の UX 改善。現実装は `gh pr create` への薄い wrapper だが、必須引数チェックを wrapper 側で実施することで使用例付きエラーを返せる。 +> +> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #5 finding +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Small。daily efficiency への影響中 (PR 作成は頻繁ではないが、エラー時の摩擦が高い)。 + +#### 背景 + +- 現実装: `cli-pr-monitor.exe` (PR 作成モード) は受け取った args をそのまま `gh pr create` に forwarding +- `gh` のエラーは英語かつ汎用的。プロジェクト固有の推奨 (prepare-pr-body スクリプトを使う等) は反映されない +- Claude / 人間の双方が「`pnpm prepare-pr-body` を先に呼ぶ」運用を覚える必要がある + +#### 設計決定 (案) + +- cli-pr-monitor の PR 作成モード入口で `--title` / `--body` / `--body-file` / `--fill*` 系のいずれかが指定されているかチェック +- 未指定なら使用例付きエラーを stderr に出力して非 0 で exit: + +```text +Error: PR title and body are required. +Usage: + pnpm create-pr -- --title "feat: ..." --body-file .tmp-pr-body.md + pnpm create-pr -- --title "feat: ..." --fill-verbose +Hint: + Run `pnpm prepare-pr-body` first to generate `.tmp-pr-body.md` from stdin. +``` + +- gh の実行は引数チェック後にのみ進む + +#### 作業計画 + +- [ ] cli-pr-monitor の PR 作成モード入口で arg validation 追加 +- [ ] エラーメッセージ作成 (上記の使用例ベース) +- [ ] dogfood: 引数なしで `pnpm create-pr` 実行 → 改善されたエラーが出ることを確認 +- [ ] 既存の正常系 (--title --body-file 指定時) が変わらず動作することを確認 +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- 引数なし実行でプロジェクト固有の使用例 + Hint がエラーに含まれる +- `--title` + `--body-file` または `--fill*` 指定時は従来通り PR 作成が走る + +#### 詰まっている箇所 + +なし (Effort Small、cli-pr-monitor 入口の arg parser 拡張のみ) + +--- + +### `.failed` marker への recovery 手順自己文書化 (PR #90 T2-2) + +> **動機**: ADR-030 で確立した soft-fail 機構 (`.md.failed` marker + L2 recovery) は PR #89 セッションで実際に発火し、UserPromptSubmit hook 経由で recovery が機能することが実証された。しかし現状の marker file は識別子のみで、recovery に必要な手順 (再実行コマンド、必要な引数、想定所要時間、よくある失敗原因) が外部 (ADR-030 / skill SKILL.md) を参照しないと分からない。marker 自体に手順を埋め込めば、将来 (ドキュメント所在を忘れた時 / ADR-030 が改訂された時 / 派生プロジェクトでの再現時) の recovery が省力化される。 +> +> **本タスクの位置づけ**: ADR-030 の運用負荷削減。soft-fail 機構そのものは正しく動作しているため、UX 改善カテゴリ。marker file の content をテンプレート化し、生成側 (cli-merge-pipeline) で recovery 手順 + コマンド例 + ADR-030 への参照を含める。 +> +> **参照**: `.claude/feedback-reports/90.md` の Tier 2 #2 finding +> +> **実行優先度**: 🔧 **Tier 2** — 工数 S。daily efficiency への影響中 (recovery 発生頻度は低いが、発生時の摩擦を低減)。rate-limit 系 task (cli-pr-monitor ポーリング延長 PR #88 T2-4、完了済 / post-pr-review rate-limit 自動検出) ほど critical ではないが、ADR-030 の long-term 運用品質に寄与。 + +#### 背景 + +- ADR-030 の L1 (cli-merge-pipeline → takt workflow 同期実行) が失敗した場合、`.claude/feedback-reports/.md.failed` marker が残存する設計 +- L2 recovery (UserPromptSubmit hook) が次セッションで marker を検出し additionalContext で再実行を促す +- PR #89 セッションで実際に soft-fail が発火し、recovery 経路が機能した実証あり +- 課題: marker file の content が空 or 識別用の最小情報のみで、再実行手順は外部ドキュメント (ADR-030 / skill SKILL.md) を参照する必要がある +- 将来リスク: ADR-030 改訂・派生プロジェクト展開・時間経過による参照先不明化により、recovery が高摩擦化する可能性 + +#### 設計決定 (案) + +- cli-merge-pipeline (or takt workflow 失敗時の marker 書込み箇所) で marker content をテンプレート化 +- テンプレート例: + +~~~markdown +# Post-Merge Feedback Failed: PR # + +This marker indicates the post-merge feedback workflow failed for PR #. +The L2 recovery hook (UserPromptSubmit) will detect this file on the next +prompt and prompt Claude to re-run the workflow. + +## Manual Recovery (if L2 hook does not fire) + +1. Check the takt run logs at `.takt/runs//` for the failure reason. +2. Re-run the workflow: + + ```sh + takt run post-merge-feedback.yaml --input pr= + ``` + +3. On success this marker will be replaced by `.claude/feedback-reports/.md`. + +## Failure Context + +- Failed at: +- takt run id: +- Last error (truncated to 500 chars): + +## Reference + +- ADR-030: docs/adr/adr-030-deterministic-post-merge-feedback.md +~~~ + +- marker 内容は ADR 改訂耐性のため「ADR-030 への参照リンク + 当時の手順」を共存させる +- 失敗の context (timestamp / run-id / stderr tail) を含めることで、再実行前に原因切り分けがしやすくなる +- 本タスク完了後、L2 hook の additionalContext からも marker content を読ませる構成にすれば自己完結度が上がる (本タスクの拡張、必須ではない) + +#### 作業計画 + +- [ ] cli-merge-pipeline の `.failed` marker 書込みロジックを確認 (現状 content がどう生成されているか) +- [ ] テンプレート文字列を crate 内 const として定義 or 外部 template ファイル化を判定 +- [ ] timestamp / run-id / stderr tail を marker に埋め込む実装 +- [ ] L2 hook (`hooks-user-prompt-feedback-recovery` 等) の additionalContext 出力で marker content を流用するか判定 (本タスクの scope 内 or 別タスク化) +- [ ] dogfood: 意図的に takt fail を inject し、marker に手順 + context が含まれることを確認 +- [ ] ADR-030 を更新 (marker format の section を追記) +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- `.failed` marker file に recovery 手順 + コマンド例 + ADR-030 参照 + failure context が含まれる +- ADR-030 の本文に marker format が明文化される +- 派生プロジェクトでも同じ template が機能する (ADR-030 が外部 reference として読める前提) + +#### 詰まっている箇所 + +なし (Effort S、cli-merge-pipeline の marker 書込み箇所のテンプレート化のみ) + +--- + +### takt ハーネスの `REJECT-ESCALATE` terminal verdict 実装 (PR #91 T2-2) + +> **動機**: PR #91 の post-pr-review で `supervise` step が 4 回、`fix_supervisor` step が 4 回の計 8 ステップを「修正不可能な制約あり」と繰り返し報告したにもかかわらず、takt harness はループを継続した。`.claude/` filter + ADR-030 制約明記 task (PR #91 T2-1 + T3-2 Bundle) が path-based に解決するのに対し、本 task は **iteration 上限到達前に「人間判断に委譲する」と AI 自身が宣言できる verdict** を提供する一般解。 +> +> **本タスクの位置づけ**: takt の condition routing に新 terminal verdict `reject-escalate` を追加。`supervise` / `fix_supervisor` step がこのシグナルを返したら harness は即終了 + ユーザー committee `.takt/runs/.../reports/escalation.md` を生成し、Claude が次セッションで読んで判断できる経路を提供。 +> +> **Status update (2026-06-06)**: 本タスク起案後に **複数の構造的対策が land 済**: (1) **ADR-037 fix-trust shortcut (試験運用)** — `convergence_verdict` による Iter 3 短絡で wasted iteration が減少、(2) **ADR-043 fail-closed (試験運用)** — Security/Quality Gate の fail-closed 原則明文化、(3) **PR #194 merge 前 mechanical gate 強化** — clippy + 空 commit sweep で iteration 上限前に block。これらと組合せた **残余 case** (pathological loop が依然発生する状況) で reject-escalate が必要かを再評価する必要あり。実装着手前に「2026-06-06 以降の 5-10 PR で iteration 上限到達が観測されるか」の baseline 観測を推奨。 +> +> **参照**: `.claude/feedback-reports/91.md` の Tier 2 #2、ADR-037 (fix-trust shortcut)、ADR-043 (fail-closed 原則)、PR #194 (mechanical gate 強化) +> +> **実行優先度**: 🔧 **Tier 2** — 工数 M (数日)。takt 本体改修なので大きい。**rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) の land 後に実施推奨**。本 task は根本解だが、post-pr-review fix loop の `.claude/` filter (Bundle T で land 済) で path-related な pathological loop は既に解決済み。Status update により残余 case の baseline 観測を実装前に先行。 + +#### 設計決定 (案) + +- takt のループ制御ロジックに新 terminal verdict `reject-escalate` を追加 + - 既存 verdict: `approved` / `needs_fix` / `user_decision` + - 新規: `reject-escalate` (= "AI 自己判断で escalate、harness 即終了") +- supervise / fix_supervisor instruction の verdict 一覧に `reject-escalate` を追加 + - 発火条件: 「修正不可能な制約 (sensitive file / external dependency / philosophical disagreement) を 2 iteration 連続で観測」 +- harness 側の処理: + - `reject-escalate` 検出時は loop break + `escalation.md` 生成 (理由 + 経緯) + - report phase は scoped-down で短縮実行 +- iteration 消費削減効果の測定: 既存 telemetry に `early_terminate_count` を追加 + +#### 作業計画 + +- [ ] takt 本体に `reject-escalate` verdict を追加 +- [ ] facets instruction (`supervise.md` / `fix_supervisor.md`) に発火条件と例文を追記 +- [ ] harness ループ制御ロジックを実装 +- [ ] `escalation.md` テンプレート作成 +- [ ] dogfood: `.claude/` filter (T2-1+T3-2 Bundle) 完了後、本実装前に意図的な reject-escalate ケースを inject して動作確認 +- [ ] takt-test-vc にも反映 (将来) +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- `supervise` / `fix_supervisor` が `reject-escalate` を返すと harness が即終了 +- iteration 上限到達による空費が削減される (定量化可能) +- escalation.md が次セッションで読める形で生成される + +#### 詰まっている箇所 + +- takt 本体改修のため `~/.claude/projects/takt-test-vc/` 連動も視野に入れる必要あり +- rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) の land 後に着手することで、verdict ベースの一般解として完成する。post-pr-review fix loop の `.claude/` filter (Bundle T、完了済) は path-based 解決の対 (補完関係) + diff --git a/docs/todo4.md b/docs/todo4.md index e29331b9..61c5cb45 100644 --- a/docs/todo4.md +++ b/docs/todo4.md @@ -1,596 +1,356 @@ -# TODO (Part 4) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo3.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録していた。**本ファイルも 50KB に到達したため、PR #101 セッション以降の新規エントリは [docs/todo5.md](todo5.md) へ**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### property-based testing (proptest) 導入 — 仕様を executable contract で明文化 (PR #96 T1-flaky) - -> **動機**: PR #96 (cli-pr-monitor lock + poll 延長) で 2 件の flaky bug (Finding D: `saturating_sub` の silent semantic mismatch / Finding E: concurrency test の guard 即 drop) が advisor + takt-fix の 2 layer を貫通して CodeRabbit に到達した。両者とも「Rust 的に正しいコードがドメイン的に間違う」典型例で、test と code が「整合」していても **spec が test に articulate されていなければ bug が漏れる**。proptest による property-based testing で「未来日時の lock は fresh ではない」「8 thread concurrent acquire で Acquired は exactly 1」等の invariant を executable contract として記述する。 -> -> **本タスクの位置づけ**: Bundle W (PBT + 型強化) の **L0 layer**。順位 35 (型で意味を表現) と同 PR で land 推奨 (PBT が型に守られて記述しやすくなる相補関係)。Bundle X (cargo-mutants + stress runner) の前提となる「PBT で書かれた property を後付け検証する」階層構造の最上層。 -> -> **参照**: PR #96 セッション内議論 (本セッション)、CR finding D / E 実例。 -> -> **実行優先度**: 🚀 **Tier 1** — 工数 Medium。AI が flaky 実装を書ける窓を spec 層で塞ぐ最大 ROI 対策。順位 13 (rate-limit 自動検出) / 順位 19 (REJECT-ESCALATE) land 後着手をユーザー指示。 - -#### 背景 - -- PR #96 で実証された bug class: - - **Finding D**: `parse_age_secs` の `saturating_sub` が future timestamp で 0 (= "fresh") を返す → crash recovery が機能しない - - **Finding E**: concurrent test が `matches!(acquire_at(...), Acquired(_))` で guard 即 drop → 8 thread が逐次的に Acquired を取れる race window -- 両者とも compile 通過、clippy 警告なし、idiomatic Rust。**code surface には bug が「ない」が、code が「言わなかったこと」が bug** -- ガイドライン (claude_md_rule) は ask-based のため、AI が認識から漏れた edge case を強制的に列挙させる仕組みが必要 - -#### 設計決定 (案) - -- **配置先**: `cli-pr-monitor` を pilot crate として `proptest` を `[dev-dependencies]` に追加 -- **記述する properties (案、順位 35 の型導入と相補)**: - - `parse_age_secs_never_negative`: `prop_assert!(age >= 0)` で常識的不変条件 - - `future_timestamp_returns_none`: `prop_assert!(parse_age_secs(future) == None)` で Finding D 直接対応 - - `acquire_then_drop_leaves_no_file`: lock 取得→ drop 後に file 残存しないこと - - `concurrent_acquire_invariant`: 8 thread sampling で Acquired count == 1 (loom と併用) -- **既存 unit test との関係**: 置換ではなく並走 (proptest は input space sampling、unit test は specific assertion) -- **派生プロジェクト展開**: pilot 後 takt-test-vc / techbook-ledger / auto-review-fix-vc にも横展開 - -#### 作業計画 - -- [ ] `cli-pr-monitor/Cargo.toml` に `proptest = "1"` を `[dev-dependencies]` 追加 -- [ ] `lock.rs` に proptest properties 5-10 件記述 -- [ ] CI で全 properties が pass することを確認 (case 数は default 256) -- [ ] 派生プロジェクト deploy 計画策定 (Bundle W land 後の別 task として todo 登録) -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- `cli-pr-monitor` の主要関数 (`parse_age_secs` / `acquire_at`) に proptest properties が記述される -- Finding D / E 相当の bug を proptest が検出することを再現実験で確認 (regression test として保持) -- pre-push pipeline での実行時間影響が +1 秒以内 - -#### 詰まっている箇所 - -- proptest による concurrency test は data generation には強いが thread interleaving の網羅は苦手。loom 併用 or stress runner との役割分担を Bundle W 着手時に再検討する。 - ---- - -### 型で意味を表現 (PastTime newtype 等) — saturating_sub 系 silent semantic mismatch を構造的に排除 (PR #96 T1-flaky) - -> **動機**: PR #96 Finding D の根本原因は `saturating_sub(now, then)` が future timestamp で 0 を返す semantic mismatch だが、より深い root cause は **「時間の意味」が型に乗っていない** こと。`now: i64` と `then: i64` は型上区別できないため、saturating_sub の「負値クランプ」と「過去経過秒」を取り違える bug が書ける。`PastTime(SystemTime)` / `FutureTime(SystemTime)` のような newtype を導入し、`parse_age_secs(t: PastTime) -> i64` に signature 変更すると、未来 timestamp は **コンパイル時に書けなくなる**。 -> -> **本タスクの位置づけ**: Bundle W (PBT + 型強化) の **横断 layer**。順位 34 (PBT) と同 PR で land 推奨。proptest が record する property を、型レベルでは impossible-to-misexpress に格上げする本質対応。 -> -> **参照**: PR #96 セッション内議論 (本セッション)、ユーザーフィードバック「型で意味を表現する (本質対応)」。 -> -> **実行優先度**: 🚀 **Tier 1** — 工数 Small。`lock.rs` 内のみで閉じた refactor として開始可能。Bundle W の 2 task のうち効果範囲が広い側。 - -#### 背景 - -- 現状の `parse_age_secs` signature: `fn parse_age_secs(iso8601: &str) -> Option` -- 内部で `then: i64` と `now: i64` を直接比較し subtract する設計が saturating_sub bug を許容する温床 -- `Result` を返す `SystemTime::duration_since` は標準 lib 級の防御だが、ドメイン的な「過去 / 現在 / 未来」の区別を呼び出し側に強制しない - -#### 設計決定 (案) - -選択肢を 2 つ用意。Bundle W 着手時にどちらか 1 つを採用 (or hybrid): - -- **選択肢 A: newtype 構造体** - - ```rust - struct PastTime(SystemTime); - impl PastTime { - fn parse(iso8601: &str) -> Result { /* future なら Err */ } - } - fn parse_age_secs(t: PastTime) -> i64 { /* future が来ないので safe */ } - ``` - -- **選択肢 B: enum 分類** - - ```rust - enum Timestamp { Past(SystemTime), Future(SystemTime) } - impl Timestamp { - fn parse(iso8601: &str) -> Self { /* SystemTime::now() と比較 */ } - } - match Timestamp::parse(...) { - Past(t) => parse_age_secs(t), // 通常経路 - Future(_) => return None, // stale 扱い - } - ``` - -- **比較**: - - A は parse 時点で「ここから先は Past 確定」を保証する単純さ - - B は呼び出し側に Past/Future 両方の処理を強制する exhaustive さ - - 本ケースでは Past のみ扱う関数なので A が cleaner、B は将来 future timestamp を扱う場面が出たら拡張容易 - -#### 作業計画 - -- [ ] 選択肢 A / B のどちらを採用するか決定 (Bundle W 着手時、proptest との相性で評価) -- [ ] `lock.rs` 内に PastTime / Timestamp 型を導入 -- [ ] `parse_age_secs` の signature を新型に変更 -- [ ] 既存 test を新 signature に追従 -- [ ] 派生プロジェクト展開時の互換性検討 (lib export しているなら API 変更) -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- `parse_age_secs` 内で saturating_sub bug が **コンパイル時に書けない** 状態 -- 既存 unit test + proptest properties が新型で pass -- bug class (silent semantic mismatch in time arithmetic) が type 層で排除されたことを Bundle W PR description で明記 - -#### 詰まっている箇所 - -- なし (Effort Small、`lock.rs` 局所 refactor で閉じる)。派生プロジェクトへの API 互換性は Bundle W land 時に別 task で扱う。 - ---- - -### cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) - -> **動機**: Bundle W (PBT + 型) で書かれた properties が「実装を本当に制約しているか」を後段で機械的に測定する layer。`cargo mutants` は production code に微小変異を注入し、全 mutant が少なくとも 1 つの test で fail することを要求する。survivor mutant は「test がこのコードを制約していない」の直接的証拠で、PBT の弱さや coverage gap を mechanical に暴く。Bundle W で「仕様を articulate」、Bundle X で「articulate された仕様の強さを測定」の二層構造を完成させる。 -> -> **本タスクの位置づけ**: Bundle X の **L2 layer (post-PR)**。順位 37 (pre-push stress runner) と同 PR で land 推奨。Bundle W land 後に着手 (PBT が書かれていない状態で mutants を回しても弱い test と弱い PBT の区別がつかない)。 -> -> **参照**: PR #96 セッション内議論、ユーザーフィードバック「mutation scope を 変更ファイル + 依存モジュール 1 層 に拡大」。 -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Medium。post-PR pipeline (post-pr-monitor の前後) に組み込み、PR 単位で 1-5 分追加。user 待機 0 (async)。 - -#### 背景 - -- 試算: cli-pr-monitor (4724 LoC) で 150-500 mutants → 5-17 分 -- 変更 crate のみ + 1-hop 依存に scope 限定: 50-150 mutants → 1-5 分 -- 既存 cli-pr-monitor で実測しないと正確な数字は出ない (試算の桁ずれリスクあり) - -#### 設計決定 (案) - -- **scope 戦略**: 変更 file + `cargo metadata` で抽出した 1-hop 依存 module -- **配置先**: post-pr-review takt workflow の analyze step 前後に新 step として追加 (analyze → fix → **mutate** → conclude) -- **survivor 報告 format**: CR-style table (severity/file/mutant variant/原因仮説) として state file に書き出し、Claude が「test を強化」または「実装を簡素化」を判断 -- **失敗ポリシー**: survivor mutant が 1 件でも残ったら post-pr-review で warning。PR は block しない (false positive 多発を考慮) -- **CI 環境**: pnpm push 時の post-PR 経路で実行。手元 push のみで CI 環境 fork なし - -#### 作業計画 - -- [ ] `cargo install cargo-mutants` を develop 環境で確認 -- [ ] cli-pr-monitor で実測: 全 crate / 変更 file のみ / +1-hop での mutants 数と所要時間 -- [ ] post-pr-monitor の Rust 実装に mutate step を組み込み (`runner::run_cmd_direct` を流用) -- [ ] survivor を `.takt/mutation-report.md` に書き出す -- [ ] takt facet (analyze-mutation.md 新規) で survivor の人間可読 summary を生成 -- [ ] dogfood: 既知の弱い test を意図的に書いて mutate が survivor を検出することを確認 -- [ ] 派生プロジェクトへ deploy -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- post-PR pipeline で cargo-mutants が変更 crate + 1-hop 依存に対して走る -- survivor mutant が 0 ⇔ test が impl を制約している (Bundle W の properties が機能している) ことの相関を 3 PR 以上で確認 -- pipeline 追加時間が PR 単位で 5 分以内 - -#### 詰まっている箇所 - -- 1-hop 依存 scope の自動算出ロジックが未調査。`cargo metadata --format-version=1` の dependencies graph を解析する Rust util が必要。 -- false positive (test では catch する意義のない mutant) の filter 戦略を着手時に検討する。 - ---- - -### pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) - -> **動機**: PR #96 Finding E (concurrency test の guard 即 drop) は scheduling 空間の race を逐次実行で誤魔化していた。`#[stress] N=100` で同 test を 100 回回すと、scheduler の偶然性で flaky window が露出する確率が劇的に向上する。pre-push に組み込めば AI が flaky concurrency test を書いた瞬間に push が止まる。 -> -> **本タスクの位置づけ**: Bundle X の **L1 layer (pre-push)**。順位 36 (cargo-mutants post-PR) と同 PR で land 推奨。Bundle W (PBT + 型) で記述された concurrency contract を、pre-push の最終防衛として deterministic に検証する補完層。 -> -> **参照**: PR #96 セッション内議論、ユーザーフィードバック「stress test は scheduling 空間の探索」。 -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Small。cli-push-runner に +~1 秒 step として追加。Bundle W で書かれた loom test と相補的 (loom は in-memory 限定、stress は filesystem も含む実環境 race)。 - -#### 背景 - -- 実測: `concurrent_acquire_only_one_wins` 単発 ~10 ms、N=100 で ~1 秒 -- 1000 倍 (N=1000) は long-tail flake catch には有用だが pre-push に毎回は過剰 (順位 38 の L3 weekly に配置) - -#### 設計決定 (案) - -- **タグ方式**: `#[stress]` cfg attribute or test name suffix で stress test を識別 -- **実行**: cli-push-runner の Rust pipeline に `cargo test --release stress::` step を追加 -- **N=100 設定**: テストコード内で `for _ in 0..100 { ... }` (proptest macro と独立、tunable) -- **失敗時挙動**: 1 度でも失敗したら push 全体を fail (skip 不可) - -#### 作業計画 - -- [ ] stress test 命名規約決定 (`#[stress]` cfg vs `_stress_` prefix) -- [ ] cli-push-runner に stress runner step 追加 -- [ ] 既存 `concurrent_acquire_only_one_wins` を stress 化し N=100 ループで実行 -- [ ] dogfood: 意図的に flaky な test を書いて stress runner が検出することを確認 -- [ ] 派生プロジェクトへ deploy -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- pre-push pipeline で stress test が N=100 回実行される -- pipeline 追加時間が +2 秒以内 -- Finding E 相当の bug を stress runner が pre-push で catch することを再現実験で確認 - -#### 詰まっている箇所 - -- なし (Effort Small、cli-push-runner の Rust step に 1 つ追加するのみ)。 - ---- - -### L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky) - -> **動機**: Bundle W (PBT + 型) と Bundle X (mutants + stress) は per-PR / per-push の防御層だが、long-tail flake (N=100 では catch されないが N=1000 で出る) と workspace 全体の coverage gap (PR で触らない crate の test 弱さ) は別途 audit が必要。ADR-031 (週次レビュー、本採用 2026-06-01) に facet 拡張 / aggregate 前 pre-step として組込むことで、週次の人間不在時間に 30-60 分の audit を回す。 -> -> **本タスクの位置づけ**: Bundle W / X の **L3 layer (weekly)**。ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 Rust pre-step として組込。daily efficiency への直接効果は小さいが、long-term の test debt 蓄積を防ぐ。 -> -> **参照**: PR #96 セッション内議論、ADR-031 (週次レビューパイプライン、本採用 2026-06-01)。 -> -> **実行優先度**: 💎 **Tier 3** — 工数 Small (ADR-031 への追加扱い)。Bundle W / X land 後に着手。 - -#### 背景 - -- ADR-031 (本採用 2026-06-01) は weekly-review 本体が land 済、本タスクは facet 拡張 / pre-step 追加として独立着手可能 -- L3 を独立 task にせず、ADR-031 facet 拡張として load すれば pipeline duplication なし - -#### 設計決定 (案) - -- **scope**: workspace 全体 (`cargo mutants -p '*'` 相当) -- **stress runner**: N=1000 で全 stress test を回す -- **配置**: ADR-031 で予定されている週次 cron / GitHub Actions schedule に追加 step -- **報告**: survivor mutant + stress flake を週次レビュー report に統合 (既存 weekly report format に追記) -- **action 連携**: 検出された問題を post-merge-feedback と同型の Tier 分類で todo 登録 - -#### 作業計画 - -- [ ] ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 pre-step として設計書作成 -- [ ] 週次 schedule に cargo-mutants workspace 全体 + stress N=1000 を追加 -- [ ] survivor / flake の自動 todo 登録ロジック (post-merge-feedback と同型 takt workflow) -- [ ] dogfood: 1 週間運用して week 1/2/3 の survivor 数推移を観察 -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- 週次 cron で workspace 全体 mutants + stress N=1000 が走る -- survivor / flake が検出されたら自動で todo 登録される -- ADR-031 weekly report に mutation / stress 結果が含まれる - -#### 詰まっている箇所 - -- ADR-031 (本採用 2026-06-01) は land 済、本 task は独立着手可能 (Bundle W / X land 完了が前提)。 - ---- - -### prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2) - -> **動機**: PR #98 セッションで、Bundle Y2 commit の `jj describe` 後の `pnpm push` がローカル bookmark 未作成のまま実行され、`jj git push` の default revset (`remote_bookmarks(remote=origin)..@`) で対象 0 件 → "Nothing changed" warning となり実質 push 失敗。push-runner は bookmark 自動採番ロジックを持たず、prepare-pr skill の Step 1 fallback (bookmark `/` 自動採番) でリカバリしたが、Step 1 の state 確認コマンド一覧に `jj bookmark list` の output 確認が明示されておらず、検出が「Step 1 fallback 表の `local_bookmarks` 空判定」に依存していた。 -> -> **本タスクの位置づけ**: prepare-pr skill Step 1 の state 確認フローに bookmark 存在チェックを明示追加し、push 失敗を事前検出。skill 自体は global (`~/.claude/skills/prepare-pr/`) なので本リポジトリの patch ではなく skill repository (`E:\work\claude-code-skills`) で更新する。 -> -> **参照**: `.claude/feedback-reports/98.md` Tier 1 #2 -> -> **実行優先度**: 🚀 **Tier 1** — Effort XS。SKILL.md Step 1 に確認コマンド 1 行 + fallback 表への明示マッピング追加のみ。 - -#### 設計決定 (案) - -- **追加場所**: `~/.claude/skills/prepare-pr/SKILL.md` Step 1 「現状確認 + 前提工程 fallback」セクション -- **追加内容**: state コマンド一覧に `jj bookmark list 2>&1 | head -20` を追加し、output に `:` 行が含まれない場合を fallback 表「local bookmark なし」行に明示マッピング -- **既存 fallback 表との関係**: `local_bookmarks` template での判定は引き続き primary signal。本タスクは「読み手 (Claude / 人間) の state 確認 step で見落とさない」ための明示化 -- **evals 補強**: 「bookmark 未作成 → fallback で bookmark 作成 → push 成功」の Scenario を `evals/evals.json` に追加 (feedback-report Tier 2 #1 相当、同 PR で land 推奨) - -#### 作業計画 - -- [ ] `E:\work\claude-code-skills\prepare-pr\SKILL.md` の Step 1 を編集 (state コマンド + fallback 表強化) -- [ ] `~/.claude/skills/prepare-pr/SKILL.md` に sync (claude-code-skills repo の deploy 経路に従う) -- [ ] `~/.claude/skills/prepare-pr/evals/evals.json` に新 Scenario 追加 (bookmark 未作成正常 path) -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- prepare-pr skill Step 1 の state 確認コマンドに bookmark 存在チェックが明示 -- 新 Scenario が evals.json に追加され、bookmark 未作成 fallback の正常動作が検証される -- 本セッション類似の push 失敗が再現した場合、Step 1 で fallback 実行が即時発火 - -#### 詰まっている箇所 - -- skill repository (`E:\work\claude-code-skills`) の deploy / sync 経路の確認が必要 (本リポジトリの `deploy:hooks` とは別経路)。 - ---- - -### Bundle Y2 効果の定量計測 — post-merge-feedback / post-pr-review の avg time 比較 (PR #98 T2-2) - -> **動機**: Bundle Y2 (PR #98) で analyze 系 step を sonnet → haiku に変更したが、ROI 根拠は `docs/pipeline-token-efficiency.md` の推定値 (PR #78 dogfood 12m13s → 並列化想定 7m30s) のみ。PR #98 セッション内観測 (post-pr-review takt 1m 13s / post-merge-feedback 8m 9s) は単発データで baseline (PR #97 セッション、avg 8.9 分) との比較が systematic にドキュメント化されていない。Bundle Z (#B-*) / Bundle Z2 (#D-*) の ROI 判断材料として PR #97 (sonnet baseline) vs PR #98 以降 (haiku) の実測比較を 3-5 PR 分集計し記録する。 -> -> **本タスクの位置づけ**: Bundle Y2 効果検証層。**注: 動機の主軸 (Bundle Z / Z2 ROI 判断材料) は失効** — Bundle Z は PR #99/#103/#106 で完成、Bundle Z2 = #D-4 はユーザー判断で不採用 (ADR-034 参照)。本 task は obsolete 候補だが、takt パイプライン効率の継続観測としてなら価値あり。**本格着手前にユーザー判断要 (削除 vs 縮小スコープで継続)**。検証方法は (削除済) `docs/pipeline-token-efficiency.md` 「検証方法」セクションに記載されていた jsonl セッションメトリクス + takt run meta.json 集計。 -> -> **参照**: `.claude/feedback-reports/98.md` Tier 2 #2、(削除済) `docs/pipeline-token-efficiency.md` 「検証方法」セクション (内容は git log で復元可能) -> -> **実行優先度**: 🔧 **Tier 2** — Effort Medium。3-5 PR の merge 経過後のデータ集計タスクで、即時着手ではなく観察ベース。Bundle Z / Z2 着手前のベースライン整理として有用。 - -#### 設計決定 (案) - -- **計測対象**: - - takt パイプライン別 avg time (post-merge-feedback / post-pr-review / pre-push-review) - - 一意 cache_creation tokens (jsonl usage 集計) - - 該当 step の billable input token 削減幅 (haiku は sonnet の約 1/3 cost 想定) -- **比較期間**: - - baseline: PR #97 セッション (2026-04-30 〜 2026-05-01 JST) — (削除済) `docs/pipeline-token-efficiency.md` の「観測データ」セクション既値 (git log で復元可能) - - 計測期間: PR #98 merge 後 3-5 PR (Bundle Z / Z2 着手前まで) -- **記録先**: - - **(計画書 retire 済 = 2026-05-04)** 旧計画は `docs/pipeline-token-efficiency.md` 末尾に「実測検証データ」追記、想定削減量達成判定に基づく retire / Bundle 追加提案だった。計画書削除済のため、本 task を継続する場合は本 entry 内に直接記録する設計に変更すべき - -#### 作業計画 - -- [ ] PR #98 merge 後 3-5 PR 経過するまで観察 (本タスクの inception は条件待ち) -- [ ] 検証方法 ① (jsonl セッションメトリクス集計) を実行 -- [ ] 検証方法 ② (takt run meta.json 集計) を実行 -- [ ] baseline (PR #97) と比較し削減幅を表に記録 -- [ ] 想定削減量 (session あたり 15-20 分削減) との乖離を分析 -- [ ] 結果を本 entry または新規 ADR に記録 (= 完了) -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- PR #98 merge 後 3-5 PR の実測値が本 entry または新規 ADR に記録される -- baseline (PR #97) との削減幅が Bundle Y2 の想定削減量と比較され、達成 / 未達の判定がある - -#### 詰まっている箇所 - -- 計測期間 3-5 PR の間に rate-limit 不安定期 / 大規模変更 PR / docs-only PR が混在すると平均値の比較ノイズが大きい。中央値での比較や PR 性質による normalization 方式を着手時に検討。 - ---- - -### cli-pr-monitor の rate-limit auto-retry + `@coderabbitai review` auto-trigger 実装 (PR #99 T2-4) - -> **動機**: PR #99 で CR rate-limit が **複数回** 発生し、解除後の `@coderabbitai review` 再投稿が **手動必要** だった。Bundle Y2 効果でパイプラインが加速 (pre-push + post-pr takt が 1〜2m/iter) した結果、CR への commit push 頻度が増えて rate-limit に達しやすくなった逆説的副作用。本セッションで実施した手順 (1) walkthrough comment の `updated_at` から解除時刻計算 → (2) sleep + 1 分 → (3) `@coderabbitai review` 投稿 → (4) Round N+1 review trigger 確認、を `cli-pr-monitor` 内で全自動化する。 -> -> **本タスクの位置づけ**: Bundle a の **実装層**。ADR-018 / ADR-009 の rate-limit retry ポリシー明文化 と同 PR で land 推奨 (実装と設計判断の整合確保)。Phase 4 (PR #97) で land された `handle_rate_limit_retry` は既存だが、検出 gap (review state = `not_found` 時に rate-limit を見落とす、本セッション中盤で確認) と auto-trigger 不発の改善が必要。 -> -> **参照**: `.claude/feedback-reports/99.md` Tier 2 #4、本セッション内のユーザー要望「全自動化したい」、PR #97 Phase 4 で land された rate-limit auto-retry の検出ロジック gap 観測 -> -> **実行優先度**: 🔧 **Tier 2** — Effort Medium。本セッションで明示された運用痛 (手動 `@coderabbitai review` 投稿が複数回必要) への直接対策。 - -#### 設計決定 (案) - -- **検出ロジック改善** (本セッションで判明した gap): - - CR rate-limit は **walkthrough comment (PR の最初の CR comment) を上書き** する形で表現される (memory `project_coderabbit_rate_limit_overlay.md` 参照) - - 既存の `state.rate_limit` 検出は review state = `not_found` 時に rate-limit overlay を見落とす可能性 - - 修正: walkthrough comment の body content + `updated_at` を直接 polling し、`Rate limit exceeded` パターンを検出 -- **解除時刻計算**: - - body 内の `Please wait N minutes and M seconds` を regex 抽出 - - `updated_at` + N min M s = 解除予定時刻 - - 解除 + 1 分後を auto-trigger 時刻として設定 (本セッションで実証された安全マージン) -- **auto-trigger 実装**: - - `cli-pr-monitor` に sleep + retry スケジューラ追加 (Rust `tokio` or `std::thread::sleep` ベース) - - sleep 中に session を超えても良いように `.claude/cli-pr-monitor-state.json` に解除予定時刻を永続化 - - 解除後 `gh api -X POST issues/N/comments -f body='@coderabbitai review' > /dev/null 2>&1` を実行 - - state を更新して再 polling 開始 -- **Budget 管理**: - - 既存の `max_duration_secs` (監視残り予算) と sleep 時間の比較ロジックは継続使用 - - sleep が予算超過する場合は `.claude/cli-pr-monitor-state.json` に「次セッションで再開」フラグを書いて exit、SessionStart hook で recovery - -#### 作業計画 - -- [ ] `cli-pr-monitor` の rate-limit detection ロジックを walkthrough comment ベースに改善 (review state non-依存) -- [ ] body 内 `Please wait N minutes and M seconds` パターン抽出ロジック追加 -- [ ] sleep + auto-trigger スケジューラ実装 (session 超え対応含む) -- [ ] `.claude/cli-pr-monitor-state.json` schema 拡張 (rate_limit_unlock_at, scheduled_retry_post 等) -- [ ] integration test: 模擬 rate-limit comment を walkthrough に置いて auto-trigger が発火するか確認 -- [ ] dogfood: 実 PR で rate-limit を引き起こして自動回復を観察 (1〜2 PR) -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- CR rate-limit 発生時に walkthrough comment overlay が確実に検出される (review state = not_found でも) -- 解除予定時刻の 1 分後に `@coderabbitai review` が自動投稿される (session 超え含む) -- 手動 `@coderabbitai review` 投稿は不要になる (PR #99 セッションで観測された運用痛の解消) -- ADR-018 / ADR-009 (Bundle a 同 PR) で設計判断が文書化される - -#### 詰まっている箇所 - -- session 超え auto-trigger の機構選定: `cli-pr-monitor` 自身が長時間 sleep して投稿するか、SessionStart hook + state file 経由で次セッション起動時に recovery するか — 運用パターンを着手時に評価。 -- 既存 `handle_rate_limit_retry` (PR #97 Phase 4) との関係整理: 既存ロジックを拡張するか、新ロジックに置き換えるか。 - ---- - -### ADR-018 / ADR-009 の rate-limit retry ポリシー明文化 (PR #99 T3-5) - -> **動機**: 現状の `cli-pr-monitor` 設計では rate-limit recovery が partial (PR #97 Phase 4 で land された `handle_rate_limit_retry` はあるが detection gap あり)、かつ設計判断が ADR に明文化されていないため、改修時の判断基準が不明瞭。本タスクで設計判断を ADR に記録し、cli-pr-monitor の rate-limit auto-retry 実装と整合させる。 -> -> **本タスクの位置づけ**: Bundle a の **設計判断層**。cli-pr-monitor の rate-limit auto-retry 実装 と同 PR で land 推奨。実装変更時の判断軸として後続改修者が参照する。 -> -> **参照**: `.claude/feedback-reports/99.md` Tier 3 #5、ADR-018 (cli-pr-monitor takt 化)、ADR-009 (Post-PR Monitor 旧設計、Superseded by ADR-018 部分あり) -> -> **実行優先度**: 💎 **Tier 3** — Effort Small。実装 (Bundle a 実装層) と同 PR で同時 land。 - -#### 設計決定 (案) - -- **記述する内容**: - - rate-limit detection の 2 層構造: review state ベース (既存) + walkthrough comment overlay ベース (新規追加、本タスクで明文化) - - backoff 戦略: 解除予定時刻 + 1 分の安全マージン (本セッションで実証) - - auto-trigger 投稿の冪等性確保: `state.rate_limit_last_retriggered_at` での dedup (PR #97 Phase 4 で実装済) - - `X-RateLimit-Remaining` ヘッダー監視は **対象外** (CR API は public ではないため)。walkthrough comment body parsing で代替 - - session 超え recovery: `.claude/cli-pr-monitor-state.json` の `rate_limit_unlock_at` フィールドを SessionStart hook が読み、補完的に auto-trigger -- **追記先**: - - 主: ADR-018 (cli-pr-monitor takt 移行、rate-limit auto-retry の主体) に追記 - - 従: ADR-009 (Post-PR Monitor 旧設計) は Superseded 部分の補足として「rate-limit retry ポリシーは ADR-018 で明文化」と navigation コメントを追加 -- **整合確保**: - - 実装 PR (Bundle a 実装層) と同コミット範囲で land、ADR の記述と実コードが一致することを保証 - -#### 作業計画 - -- [ ] ADR-018 に「rate-limit detection / retry / auto-trigger」セクション追加 -- [ ] ADR-009 に navigation 注記追加 (rate-limit 関連は ADR-018 を参照) -- [ ] 実装 (Bundle a 実装層) と同 PR で land、CodeRabbit / pre-push-review で整合性を check -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- ADR-018 に rate-limit retry ポリシーが明記される -- 実装と ADR の記述が同期 (新たな乖離リスクなし) -- 後続改修者が ADR-018 を読めば改修方針を判断できる - -#### 詰まっている箇所 - -- なし (Effort Small、ADR-018 への追記のみで完結)。実装 (Bundle a 実装層) の設計確定後に着手するのが効率的。 - ---- - -### PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25) - -> **動機**: PR #97 / #99 セッションで観測された gh tool_result の token bloat (POST 応答 24KB / GET 過剰 metadata 44KB) を、当初 rule 追加 (`~/.claude/rules/common/git-workflow.md`) で抑制する計画だった。しかし PR #172 で 順位 144 (`jj-message-required` preset) の dogfood が成功し、「rule 化は session 毎に読み込みコストがかかり、別セッションでも結果が一定にならない」課題が顕在化。仕組み化 (PreToolUse hook) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。 -> -> 抑制対象 3 パターン (rule 設計時点で確定済): -> -> 1. **POST 操作 (作成・更新)** の応答破棄漏れ: `gh api .../replies` 等で `> /dev/null 2>&1` がない → 24KB の reply body が context 汚染 -> 2. **GET 操作 (取得)** で `--jq` filter 不使用: `gh api .../comments` 等で生 JSON 全取得 → 44KB の不要 metadata 流入 -> 3. **CR walkthrough internal state 混入**: `gh pr view --json comments` で CR walkthrough の base64 encoded state が含まれる (1 PR で 30KB+) → 確認時は `--jq 'del(.comments[].body)'` 等で除外必須 -> -> **本タスクの位置づけ**: 順位 144 (jj-message-required hook) の同型実装パターン。`feedback_pipeline_over_rules.md` 適用 = パイプライン側機械的修正で Claude 判断介入を排除、session 毎の rule load コスト不要、別セッションでも結果が一定。Bundle a の **Sub-PR 1 token 削減層** だが docs 化 → hook 化への切替に伴い Bundle a との結合は緩む。 -> -> **参照**: ADR-034 (CodeRabbit 監視・対話の自動化戦略)、PR #99 / #97 session log (token bloat 実観測)、PR #172 (順位 144 = `jj-message-required` preset 実装事例)、`src/hooks-pre-tool-validate/src/main.rs` の `preset_jj_message_required` を template に追加 -> -> **実行優先度**: 💎 **Tier 3** — Effort M (順位 144 と同型実装で工数把握済、~90 分見込み)。Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) でも `gh api` を使うため Sub-PR 1 で先行 land 推奨。 - -#### 設計決定 (案、順位 144 hook 実装を template に踏襲) - -- **配置**: `src/hooks-pre-tool-validate/src/main.rs` に新 preset `gh-token-efficiency` 追加 -- **`BlockedPattern.exception` を活用** (順位 144 で導入済、再利用) -- **block 対象 3 種類** (個別 BlockedPattern として実装): - - (1) **POST 応答破棄漏れ**: pattern = `gh\s+(api\s+-X\s+POST|api\s+(?!.*-X\s+GET)[^|]*-f\s+)`、exception = `>\s*/dev/null|>\s*NUL`、message = 「`> /dev/null 2>&1` で応答 body 破棄を推奨 (24KB context 汚染防止)」 - - (2) **`gh api` の `--jq` 不使用**: pattern = `gh\s+api\s+[^|]*`、exception = `--jq\b|\|\s*jq\b|>\s*/dev/null`、message = 「`--jq` で必要 field のみ抽出を推奨 (生 JSON 過剰流入防止)」 - - (3) **CR walkthrough state 混入**: pattern = `gh\s+pr\s+view\s+[^|]*--json\s+[^|]*comments`、exception = `del\(\.comments|--jq.*comments.*\|\s*map`、message = 「CR walkthrough base64 internal state を含むため `--jq 'del(.comments[].body)'` 等で除外を推奨」 -- **hooks-config.toml**: `blocked_patterns` に `"gh-token-efficiency"` を追加 (opt-in preset、派生プロジェクト breaking change リスク軽減) -- **opt-in 設計**: `default_preset_names()` の fallback には含めない (`gh-pr-create-guard` 等と同じ classification) - -#### 作業計画 (順位 144 と同 phase 構造) - -- [ ] **Phase 1**: 既存 preset 構造を理解し、`preset_gh_token_efficiency()` 関数を実装 (3 BlockedPattern を vec で返す) -- [ ] **Phase 2**: `build_blocked_patterns` の `resolve_preset_or_custom` dispatch に登録 + `.claude/hooks-config.toml` の `blocked_patterns` に `"gh-token-efficiency"` 追加 + コメント section に説明追加 -- [ ] **Phase 3**: test 拡充 — block ケース (応答破棄漏れ POST / `--jq` なし GET / walkthrough exclusion なし) × 3 + allow ケース (3 規則すべて遵守) × 3 + non-regression (既存 preset との干渉なし) -- [ ] **Phase 4**: `pnpm build:hooks-pre-tool-validate` で exe deploy + dogfood (本 todo を読んだ後の `gh api` 呼び出しで block 動作確認) -- [ ] **Phase 5**: `pnpm push` (AI review) + `pnpm create-pr` -- [ ] **post-merge**: 本リポジトリ 1-2 PR の dogfood で false positive 観測 → 派生プロジェクト deploy 判断 -- [ ] 本 todo4.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `jj-message-required` と同型の `gh-token-efficiency` preset が稼働 (3 BlockedPattern が block + exception 機能で正規パターン allow) -- `gh api .../replies -f body='...'` (応答破棄なし) → block + 修正手順 feedback -- `gh api .../comments` (`--jq` なし) → block + 修正手順 feedback -- `gh pr view 171 --json comments` (walkthrough 除外なし) → block + 修正手順 feedback -- 規則遵守版 (`> /dev/null 2>&1` 付き POST / `--jq` 抽出 / `del(.comments[].body)` 除外) は通過 -- 既存 preset との non-regression (jj-main-guard / git push block 等は継続動作) -- `cargo test -p hooks-pre-tool-validate` pass - -#### 詰まっている箇所 - -- 順位 144 実装パターンを踏襲することで設計判断は最小化される -- false positive リスク: `gh api ... | jq` のような piped jq は exception regex で吸収可能 (`\|\s*jq\b` を含める) -- 派生プロジェクト deploy timing: 本リポジトリ先行 dogfood (1-2 PR) → 観測後判断 (`feedback_dogfood_evals_two_phase.md` 適用) - ---- - -### `check-ci-coderabbit --list-findings` Rust モード追加 (計画書 #D-3) - -> **動機**: CR review listing で `gh api .../pulls/N/reviews` + `pulls/N/comments` の重複取得が発生し、44KB 級の生 metadata が context に乗る (cache_creation 9x で 約 400K tokens 蓄積)。Rust 側で構造化 findings JSON を一度で取得することで、`gh api` 重複呼び出しを消滅させる。加えて、Bundle a Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) が同 API を消費する設計のため、Sub-PR 1 で先行実装が必要。 -> -> **本タスクの位置づけ**: Bundle a の **Sub-PR 1 token 削減層 (cli-pr-monitor 連携 API 提供)**。gh CLI 使用規則追記 と同 PR で land 推奨。Sub-PR 2 (rate-limit auto-retry 実装) の前提条件。 -> -> **参照**: ADR-034 (CodeRabbit 監視・対話の自動化戦略)、(削除済) `docs/pipeline-token-efficiency.md` #D-3 セクション (経緯は ADR-034 で保存)、ADR-022 (自動化コンポーネントの責務分離原則 — Rust 側実装が ADR-022 と整合する根拠) -> -> **実行優先度**: 🔧 **Tier 2** — Effort Medium。Rust 実装 + テスト。`check-ci-coderabbit` crate (既存) への mode 追加で、新 crate 作成は不要 (ADR-026 Cargo workspace member 構成変更なし)。 - -#### 設計決定 (案) - -- **追加先**: `src/check-ci-coderabbit/` (既存 crate) -- **CLI**: `check-ci-coderabbit.exe --list-findings --pr ` で構造化 JSON を stdout 出力 -- **JSON schema (案)**: - - ```json - { - "findings": [ - {"severity": "major", "file": "src/.../main.rs", "line": 415, "summary": "...", "url": "..."} - ] - } - ``` - -- **入力ソース**: `gh api .../pulls/N/comments` + `pulls/N/reviews` を内部的に呼び、重複 metadata を除去して構造化 -- **severity 抽出**: CR の `_⚠️ Potential issue_ | _🔴 Critical_` 等のパターンから抽出 (Critical / Major / Minor / Nitpick の 4 段階) -- **outdated 解釈**: `in_reply_to_id` を辿って `resolved:` reply のあるスレッドを除外 -- **cli-pr-monitor からの消費**: Sub-PR 2 で `cli-pr-monitor` が本コマンドを spawn、構造化 findings を読んで rate-limit auto-retry のロジックに統合 -- **既存 `check-ci-coderabbit` の他モード** (CI 状態 check 等) との関係: 既存モードは保持、`--list-findings` が新規 sub-command として追加 - -#### 作業計画 - -- [ ] `src/check-ci-coderabbit/` の既存 CLI 構造を確認 (clap 定義、既存 sub-command の有無) -- [ ] `--list-findings --pr ` sub-command を追加 -- [ ] `gh api` 呼び出しを内部実装 (既存 `runner::run_gh_quiet` 等を流用) -- [ ] severity 抽出ロジック (regex で `Potential issue \| 🔴 Critical` 等のパターン) -- [ ] outdated 解釈ロジック (resolved reply のスレッド除外) -- [ ] 単体テスト (sample CR review JSON を fixture として配置、severity 抽出 / outdated 解釈の網羅) -- [ ] `package.json` の `build:check-ci-coderabbit` で release exe 生成 (既存 script、変更不要) -- [ ] dogfood: 1〜2 PR で `pnpm cr:findings ` 相当の動作を確認 (本 PR ではなく実 PR で smoke test) -- [ ] cli-pr-monitor (Sub-PR 2) からの消費を統合 (Sub-PR 2 のスコープだが、本 task の API 設計時に呼び出し側の interface も合わせて確定) -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- `check-ci-coderabbit.exe --list-findings --pr ` で JSON 出力が得られる -- severity / file / line / summary / url の 5 field が揃う -- 単体テストで sample fixture から正しく findings を抽出 -- Sub-PR 2 の cli-pr-monitor が本 API を呼んで rate-limit auto-retry のロジックを完成させる -- gh api 重複取得が消滅し、CR review listing token 量が削減される (現状 4 round 計 ~20KB → 目標 ~5KB) - -#### 詰まっている箇所 - -- CR の review body format が将来変わった場合の severity 抽出 fragility (regex 依存)。**個人開発向けで仕様変更時に対応する想定** (ADR-034 の方針と整合) -- `in_reply_to_id` chain の outdated 解釈で false negative (resolved reply があるのに findings に残る) や false positive (resolved 扱いのものを未対応として出力) のチューニングが必要 — 着手時に実 CR data で評価。 - ---- - -### CodeRabbit rate-limit auto-retry の integration test (PR #100 T2-1) - -> **動機**: Bundle a Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry + auto-trigger 実装) で導入する rate-limit 検出 → backoff → retry サイクルが正常動作することを継続的に保証する integration test を追加する。Sub-PR 2 のロジックは複数 actor (CR walkthrough overlay / session 超え recovery / dedup) が絡む複雑系で、unit test のみでは end-to-end の連携バグを catch しにくい。 -> -> **本タスクの位置づけ**: Bundle a の **Sub-PR 2 実装と同 PR で land**。test 追加で実装と分離するメリットが薄い (実装変更時に test も同期改修が必要) ため、Sub-PR 2 の作業範囲に統合する。 -> -> **参照**: `.claude/feedback-reports/100.md` Tier 2 #1、ADR-034 (CodeRabbit 監視・対話の自動化戦略)、PR #99 post-merge-feedback の Tier 2 #4 (Bundle a Sub-PR 2 設計の起源) -> -> **実行優先度**: 🔧 **Tier 2** — Effort Medium。Sub-PR 2 と一体実装、独立 PR として land しない。 - -#### 設計決定 (案) - -- **配置先**: `src/cli-pr-monitor/tests/` (integration test 専用ディレクトリ、既存 unit test と分離) -- **テスト対象シナリオ (4 件)**: - - **正常 retry**: walkthrough overlay の `Rate limit exceeded` 検出 → 解除予定時刻計算 → 解除 + 1 分マージン待機 → `@coderabbitai review` 自動投稿 → re-detection で findings 取得 - - **dedup**: 同一 `comment_event_time` の rate-limit overlay は `rate_limit_last_retriggered_at` で重複投稿を防止 - - **max_retries 超過**: `rate_limit_config.max_retries` 到達後は action_required で抜ける (manual fallback) - - **session 超え recovery**: state file の `rate_limit_unlock_at` を SessionStart hook が読んで cli-pr-monitor を recovery mode で再起動 -- **モック戦略**: - - GitHub API (`gh api`) のモック化: 実環境を呼ばず、固定 fixture を返す stub (HTTP mock library `mockito` or shell wrapper どちらかは Sub-PR 2 着手時の `cli-pr-monitor` 実装方針に合わせて選定) - - 時刻のモック化: `chrono` の time provider を test で差し替え (sleep 短縮で test 高速化) - - state file: `tempfile` で test 専用 dir に作成し isolation 確保 -- **既存 unit test との関係**: parse_rate_limit / parse_age_secs 等の細部ロジックは unit test で網羅。integration test は **end-to-end の連携 (detection → retry → re-detection) と state 永続化** に focus - -#### 作業計画 - -- [ ] `src/cli-pr-monitor/tests/rate_limit_integration_test.rs` 等の test ファイル作成 (Cargo workspace member 既存、ファイル追加のみで OK) -- [ ] gh API モック (stub) を `tests/fixtures/` に配置: rate-limit walkthrough overlay JSON + 通常 review JSON -- [ ] 主要 4 シナリオ (正常 retry / dedup / max_retries 超過 / session 超え recovery) を実装 -- [ ] `cargo test --workspace` で pass を確認 -- [ ] dogfood: 実 PR で rate-limit 模擬発生時に integration test の coverage 範囲が実 path で発火することを確認 -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- 主要 4 シナリオの integration test が pass -- Sub-PR 2 の rate-limit auto-retry ロジック改修時にも同 test が継続的に green -- regression catch: ロジック改修で意図せぬ挙動変化があった場合に test が fail することを再現実験で確認 (test 自体の sensitivity 検証) -- pre-push pipeline 実行時間への影響が +5 秒以内 (integration test の重さで pre-push が肥大化しないこと) - -#### 詰まっている箇所 - -- gh API モックの strategy 選定 (HTTP mock library vs shell wrapper スタブ): Sub-PR 2 着手時の `cli-pr-monitor` 実装方針 (どこまで gh CLI を直接呼ぶか) と合わせて決定 -- session 超え recovery シナリオの reproducibility: state file 永続化を test で再現する際に SessionStart hook 起動を模擬する手段が要検討 (hook を直接呼ぶか、state 直接書き込み + cli-pr-monitor recovery mode 起動で代替するか) +# TODO (Part 4) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo3.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録していた。**本ファイルも 50KB に到達したため、PR #101 セッション以降の新規エントリは [docs/todo5.md](todo5.md) へ**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### property-based testing (proptest) 導入 — 仕様を executable contract で明文化 (PR #96 T1-flaky) + +> **動機**: PR #96 (cli-pr-monitor lock + poll 延長) で 2 件の flaky bug (Finding D: `saturating_sub` の silent semantic mismatch / Finding E: concurrency test の guard 即 drop) が advisor + takt-fix の 2 layer を貫通して CodeRabbit に到達した。両者とも「Rust 的に正しいコードがドメイン的に間違う」典型例で、test と code が「整合」していても **spec が test に articulate されていなければ bug が漏れる**。proptest による property-based testing で「未来日時の lock は fresh ではない」「8 thread concurrent acquire で Acquired は exactly 1」等の invariant を executable contract として記述する。 +> +> **本タスクの位置づけ**: Bundle W (PBT + 型強化) の **L0 layer**。順位 35 (型で意味を表現) と同 PR で land 推奨 (PBT が型に守られて記述しやすくなる相補関係)。Bundle X (cargo-mutants + stress runner) の前提となる「PBT で書かれた property を後付け検証する」階層構造の最上層。 +> +> **参照**: PR #96 セッション内議論 (本セッション)、CR finding D / E 実例。 +> +> **実行優先度**: 🚀 **Tier 1** — 工数 Medium。AI が flaky 実装を書ける窓を spec 層で塞ぐ最大 ROI 対策。順位 13 (rate-limit 自動検出) / 順位 19 (REJECT-ESCALATE) land 後着手をユーザー指示。 + +#### 背景 + +- PR #96 で実証された bug class: + - **Finding D**: `parse_age_secs` の `saturating_sub` が future timestamp で 0 (= "fresh") を返す → crash recovery が機能しない + - **Finding E**: concurrent test が `matches!(acquire_at(...), Acquired(_))` で guard 即 drop → 8 thread が逐次的に Acquired を取れる race window +- 両者とも compile 通過、clippy 警告なし、idiomatic Rust。**code surface には bug が「ない」が、code が「言わなかったこと」が bug** +- ガイドライン (claude_md_rule) は ask-based のため、AI が認識から漏れた edge case を強制的に列挙させる仕組みが必要 + +#### 設計決定 (案) + +- **配置先**: `cli-pr-monitor` を pilot crate として `proptest` を `[dev-dependencies]` に追加 +- **記述する properties (案、順位 35 の型導入と相補)**: + - `parse_age_secs_never_negative`: `prop_assert!(age >= 0)` で常識的不変条件 + - `future_timestamp_returns_none`: `prop_assert!(parse_age_secs(future) == None)` で Finding D 直接対応 + - `acquire_then_drop_leaves_no_file`: lock 取得→ drop 後に file 残存しないこと + - `concurrent_acquire_invariant`: 8 thread sampling で Acquired count == 1 (loom と併用) +- **既存 unit test との関係**: 置換ではなく並走 (proptest は input space sampling、unit test は specific assertion) +- **派生プロジェクト展開**: pilot 後 takt-test-vc / techbook-ledger / auto-review-fix-vc にも横展開 + +#### 作業計画 + +- [ ] `cli-pr-monitor/Cargo.toml` に `proptest = "1"` を `[dev-dependencies]` 追加 +- [ ] `lock.rs` に proptest properties 5-10 件記述 +- [ ] CI で全 properties が pass することを確認 (case 数は default 256) +- [ ] 派生プロジェクト deploy 計画策定 (Bundle W land 後の別 task として todo 登録) +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- `cli-pr-monitor` の主要関数 (`parse_age_secs` / `acquire_at`) に proptest properties が記述される +- Finding D / E 相当の bug を proptest が検出することを再現実験で確認 (regression test として保持) +- pre-push pipeline での実行時間影響が +1 秒以内 + +#### 詰まっている箇所 + +- proptest による concurrency test は data generation には強いが thread interleaving の網羅は苦手。loom 併用 or stress runner との役割分担を Bundle W 着手時に再検討する。 + +--- + +### 型で意味を表現 (PastTime newtype 等) — saturating_sub 系 silent semantic mismatch を構造的に排除 (PR #96 T1-flaky) + +> **動機**: PR #96 Finding D の根本原因は `saturating_sub(now, then)` が future timestamp で 0 を返す semantic mismatch だが、より深い root cause は **「時間の意味」が型に乗っていない** こと。`now: i64` と `then: i64` は型上区別できないため、saturating_sub の「負値クランプ」と「過去経過秒」を取り違える bug が書ける。`PastTime(SystemTime)` / `FutureTime(SystemTime)` のような newtype を導入し、`parse_age_secs(t: PastTime) -> i64` に signature 変更すると、未来 timestamp は **コンパイル時に書けなくなる**。 +> +> **本タスクの位置づけ**: Bundle W (PBT + 型強化) の **横断 layer**。順位 34 (PBT) と同 PR で land 推奨。proptest が record する property を、型レベルでは impossible-to-misexpress に格上げする本質対応。 +> +> **参照**: PR #96 セッション内議論 (本セッション)、ユーザーフィードバック「型で意味を表現する (本質対応)」。 +> +> **実行優先度**: 🚀 **Tier 1** — 工数 Small。`lock.rs` 内のみで閉じた refactor として開始可能。Bundle W の 2 task のうち効果範囲が広い側。 + +#### 背景 + +- 現状の `parse_age_secs` signature: `fn parse_age_secs(iso8601: &str) -> Option` +- 内部で `then: i64` と `now: i64` を直接比較し subtract する設計が saturating_sub bug を許容する温床 +- `Result` を返す `SystemTime::duration_since` は標準 lib 級の防御だが、ドメイン的な「過去 / 現在 / 未来」の区別を呼び出し側に強制しない + +#### 設計決定 (案) + +選択肢を 2 つ用意。Bundle W 着手時にどちらか 1 つを採用 (or hybrid): + +- **選択肢 A: newtype 構造体** + + ```rust + struct PastTime(SystemTime); + impl PastTime { + fn parse(iso8601: &str) -> Result { /* future なら Err */ } + } + fn parse_age_secs(t: PastTime) -> i64 { /* future が来ないので safe */ } + ``` + +- **選択肢 B: enum 分類** + + ```rust + enum Timestamp { Past(SystemTime), Future(SystemTime) } + impl Timestamp { + fn parse(iso8601: &str) -> Self { /* SystemTime::now() と比較 */ } + } + match Timestamp::parse(...) { + Past(t) => parse_age_secs(t), // 通常経路 + Future(_) => return None, // stale 扱い + } + ``` + +- **比較**: + - A は parse 時点で「ここから先は Past 確定」を保証する単純さ + - B は呼び出し側に Past/Future 両方の処理を強制する exhaustive さ + - 本ケースでは Past のみ扱う関数なので A が cleaner、B は将来 future timestamp を扱う場面が出たら拡張容易 + +#### 作業計画 + +- [ ] 選択肢 A / B のどちらを採用するか決定 (Bundle W 着手時、proptest との相性で評価) +- [ ] `lock.rs` 内に PastTime / Timestamp 型を導入 +- [ ] `parse_age_secs` の signature を新型に変更 +- [ ] 既存 test を新 signature に追従 +- [ ] 派生プロジェクト展開時の互換性検討 (lib export しているなら API 変更) +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- `parse_age_secs` 内で saturating_sub bug が **コンパイル時に書けない** 状態 +- 既存 unit test + proptest properties が新型で pass +- bug class (silent semantic mismatch in time arithmetic) が type 層で排除されたことを Bundle W PR description で明記 + +#### 詰まっている箇所 + +- なし (Effort Small、`lock.rs` 局所 refactor で閉じる)。派生プロジェクトへの API 互換性は Bundle W land 時に別 task で扱う。 + +--- + +### cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) + +> **動機**: Bundle W (PBT + 型) で書かれた properties が「実装を本当に制約しているか」を後段で機械的に測定する layer。`cargo mutants` は production code に微小変異を注入し、全 mutant が少なくとも 1 つの test で fail することを要求する。survivor mutant は「test がこのコードを制約していない」の直接的証拠で、PBT の弱さや coverage gap を mechanical に暴く。Bundle W で「仕様を articulate」、Bundle X で「articulate された仕様の強さを測定」の二層構造を完成させる。 +> +> **本タスクの位置づけ**: Bundle X の **L2 layer (post-PR)**。順位 37 (pre-push stress runner) と同 PR で land 推奨。Bundle W land 後に着手 (PBT が書かれていない状態で mutants を回しても弱い test と弱い PBT の区別がつかない)。 +> +> **参照**: PR #96 セッション内議論、ユーザーフィードバック「mutation scope を 変更ファイル + 依存モジュール 1 層 に拡大」。 +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Medium。post-PR pipeline (post-pr-monitor の前後) に組み込み、PR 単位で 1-5 分追加。user 待機 0 (async)。 + +#### 背景 + +- 試算: cli-pr-monitor (4724 LoC) で 150-500 mutants → 5-17 分 +- 変更 crate のみ + 1-hop 依存に scope 限定: 50-150 mutants → 1-5 分 +- 既存 cli-pr-monitor で実測しないと正確な数字は出ない (試算の桁ずれリスクあり) + +#### 設計決定 (案) + +- **scope 戦略**: 変更 file + `cargo metadata` で抽出した 1-hop 依存 module +- **配置先**: post-pr-review takt workflow の analyze step 前後に新 step として追加 (analyze → fix → **mutate** → conclude) +- **survivor 報告 format**: CR-style table (severity/file/mutant variant/原因仮説) として state file に書き出し、Claude が「test を強化」または「実装を簡素化」を判断 +- **失敗ポリシー**: survivor mutant が 1 件でも残ったら post-pr-review で warning。PR は block しない (false positive 多発を考慮) +- **CI 環境**: pnpm push 時の post-PR 経路で実行。手元 push のみで CI 環境 fork なし + +#### 作業計画 + +- [ ] `cargo install cargo-mutants` を develop 環境で確認 +- [ ] cli-pr-monitor で実測: 全 crate / 変更 file のみ / +1-hop での mutants 数と所要時間 +- [ ] post-pr-monitor の Rust 実装に mutate step を組み込み (`runner::run_cmd_direct` を流用) +- [ ] survivor を `.takt/mutation-report.md` に書き出す +- [ ] takt facet (analyze-mutation.md 新規) で survivor の人間可読 summary を生成 +- [ ] dogfood: 既知の弱い test を意図的に書いて mutate が survivor を検出することを確認 +- [ ] 派生プロジェクトへ deploy +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- post-PR pipeline で cargo-mutants が変更 crate + 1-hop 依存に対して走る +- survivor mutant が 0 ⇔ test が impl を制約している (Bundle W の properties が機能している) ことの相関を 3 PR 以上で確認 +- pipeline 追加時間が PR 単位で 5 分以内 + +#### 詰まっている箇所 + +- 1-hop 依存 scope の自動算出ロジックが未調査。`cargo metadata --format-version=1` の dependencies graph を解析する Rust util が必要。 +- false positive (test では catch する意義のない mutant) の filter 戦略を着手時に検討する。 + +--- + +### pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) + +> **動機**: PR #96 Finding E (concurrency test の guard 即 drop) は scheduling 空間の race を逐次実行で誤魔化していた。`#[stress] N=100` で同 test を 100 回回すと、scheduler の偶然性で flaky window が露出する確率が劇的に向上する。pre-push に組み込めば AI が flaky concurrency test を書いた瞬間に push が止まる。 +> +> **本タスクの位置づけ**: Bundle X の **L1 layer (pre-push)**。順位 36 (cargo-mutants post-PR) と同 PR で land 推奨。Bundle W (PBT + 型) で記述された concurrency contract を、pre-push の最終防衛として deterministic に検証する補完層。 +> +> **参照**: PR #96 セッション内議論、ユーザーフィードバック「stress test は scheduling 空間の探索」。 +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Small。cli-push-runner に +~1 秒 step として追加。Bundle W で書かれた loom test と相補的 (loom は in-memory 限定、stress は filesystem も含む実環境 race)。 + +#### 背景 + +- 実測: `concurrent_acquire_only_one_wins` 単発 ~10 ms、N=100 で ~1 秒 +- 1000 倍 (N=1000) は long-tail flake catch には有用だが pre-push に毎回は過剰 (順位 38 の L3 weekly に配置) + +#### 設計決定 (案) + +- **タグ方式**: `#[stress]` cfg attribute or test name suffix で stress test を識別 +- **実行**: cli-push-runner の Rust pipeline に `cargo test --release stress::` step を追加 +- **N=100 設定**: テストコード内で `for _ in 0..100 { ... }` (proptest macro と独立、tunable) +- **失敗時挙動**: 1 度でも失敗したら push 全体を fail (skip 不可) + +#### 作業計画 + +- [ ] stress test 命名規約決定 (`#[stress]` cfg vs `_stress_` prefix) +- [ ] cli-push-runner に stress runner step 追加 +- [ ] 既存 `concurrent_acquire_only_one_wins` を stress 化し N=100 ループで実行 +- [ ] dogfood: 意図的に flaky な test を書いて stress runner が検出することを確認 +- [ ] 派生プロジェクトへ deploy +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- pre-push pipeline で stress test が N=100 回実行される +- pipeline 追加時間が +2 秒以内 +- Finding E 相当の bug を stress runner が pre-push で catch することを再現実験で確認 + +#### 詰まっている箇所 + +- なし (Effort Small、cli-push-runner の Rust step に 1 つ追加するのみ)。 + +--- + +### L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky) + +> **動機**: Bundle W (PBT + 型) と Bundle X (mutants + stress) は per-PR / per-push の防御層だが、long-tail flake (N=100 では catch されないが N=1000 で出る) と workspace 全体の coverage gap (PR で触らない crate の test 弱さ) は別途 audit が必要。ADR-031 (週次レビュー、本採用 2026-06-01) に facet 拡張 / aggregate 前 pre-step として組込むことで、週次の人間不在時間に 30-60 分の audit を回す。 +> +> **本タスクの位置づけ**: Bundle W / X の **L3 layer (weekly)**。ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 Rust pre-step として組込。daily efficiency への直接効果は小さいが、long-term の test debt 蓄積を防ぐ。 +> +> **Status update (2026-06-06)**: ADR-031 は **2026-06-01 本採用昇格済 (PR #192)** で weekly-review pipeline は安定運用入り。本タスクの依存は **Bundle W / X (順位 34/35/36/37) の land のみ** に減縮 (旧依存「ADR-031 dogfood 完了」は満たされた)。Bundle W/X が land したら即着手可能。 +> +> **参照**: PR #96 セッション内議論、ADR-031 (週次レビューパイプライン、本採用 2026-06-01、PR #192)。 +> +> **実行優先度**: 💎 **Tier 3** — 工数 Small (ADR-031 への追加扱い)。Bundle W / X land 後に着手。 + +#### 背景 + +- ADR-031 (本採用 2026-06-01) は weekly-review 本体が land 済、本タスクは facet 拡張 / pre-step 追加として独立着手可能 +- L3 を独立 task にせず、ADR-031 facet 拡張として load すれば pipeline duplication なし + +#### 設計決定 (案) + +- **scope**: workspace 全体 (`cargo mutants -p '*'` 相当) +- **stress runner**: N=1000 で全 stress test を回す +- **配置**: ADR-031 で予定されている週次 cron / GitHub Actions schedule に追加 step +- **報告**: survivor mutant + stress flake を週次レビュー report に統合 (既存 weekly report format に追記) +- **action 連携**: 検出された問題を post-merge-feedback と同型の Tier 分類で todo 登録 + +#### 作業計画 + +- [ ] ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 pre-step として設計書作成 +- [ ] 週次 schedule に cargo-mutants workspace 全体 + stress N=1000 を追加 +- [ ] survivor / flake の自動 todo 登録ロジック (post-merge-feedback と同型 takt workflow) +- [ ] dogfood: 1 週間運用して week 1/2/3 の survivor 数推移を観察 +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- 週次 cron で workspace 全体 mutants + stress N=1000 が走る +- survivor / flake が検出されたら自動で todo 登録される +- ADR-031 weekly report に mutation / stress 結果が含まれる + +#### 詰まっている箇所 + +- ADR-031 (本採用 2026-06-01) は land 済、本 task は独立着手可能 (Bundle W / X land 完了が前提)。 + +--- + +### prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2) + +> **動機**: PR #98 セッションで、Bundle Y2 commit の `jj describe` 後の `pnpm push` がローカル bookmark 未作成のまま実行され、`jj git push` の default revset (`remote_bookmarks(remote=origin)..@`) で対象 0 件 → "Nothing changed" warning となり実質 push 失敗。push-runner は bookmark 自動採番ロジックを持たず、prepare-pr skill の Step 1 fallback (bookmark `/` 自動採番) でリカバリしたが、Step 1 の state 確認コマンド一覧に `jj bookmark list` の output 確認が明示されておらず、検出が「Step 1 fallback 表の `local_bookmarks` 空判定」に依存していた。 +> +> **本タスクの位置づけ**: prepare-pr skill Step 1 の state 確認フローに bookmark 存在チェックを明示追加し、push 失敗を事前検出。skill 自体は global (`~/.claude/skills/prepare-pr/`) なので本リポジトリの patch ではなく skill repository (`E:\work\claude-code-skills`) で更新する。 +> +> **Status update (2026-06-06)**: 本リポジトリ側で **PR #175 (Bundle 2) で `src/cli-push-runner/src/stages/bookmark_check.rs` stage が land 済**。push-runner 自体が bookmark 不在を mechanical 検出するため、skill 側の primary 検出責務は機械化済。本タスクは「skill 側 (派生プロジェクト未 deploy 環境向け二重防御 + skill SKILL.md 教育)」として scope 縮小可能。当初予定の Step 1 state 確認コマンド追加 + fallback 表強化は、push-runner 側仕様に追従して docs 同期する位置付けに変更。 +> +> **参照**: `.claude/feedback-reports/98.md` Tier 1 #2、PR #175 Bundle 2 (push-runner bookmark_check stage 実装) +> +> **実行優先度**: 🚀 **Tier 1** — Effort XS。SKILL.md Step 1 に確認コマンド 1 行 + fallback 表への明示マッピング追加のみ。Status update により push-runner との二重防御 / 派生プロジェクト向け knowledge transfer として位置付け。 + +#### 設計決定 (案) + +- **追加場所**: `~/.claude/skills/prepare-pr/SKILL.md` Step 1 「現状確認 + 前提工程 fallback」セクション +- **追加内容**: state コマンド一覧に `jj bookmark list 2>&1 | head -20` を追加し、output に `:` 行が含まれない場合を fallback 表「local bookmark なし」行に明示マッピング +- **既存 fallback 表との関係**: `local_bookmarks` template での判定は引き続き primary signal。本タスクは「読み手 (Claude / 人間) の state 確認 step で見落とさない」ための明示化 +- **evals 補強**: 「bookmark 未作成 → fallback で bookmark 作成 → push 成功」の Scenario を `evals/evals.json` に追加 (feedback-report Tier 2 #1 相当、同 PR で land 推奨) + +#### 作業計画 + +- [ ] `E:\work\claude-code-skills\prepare-pr\SKILL.md` の Step 1 を編集 (state コマンド + fallback 表強化) +- [ ] `~/.claude/skills/prepare-pr/SKILL.md` に sync (claude-code-skills repo の deploy 経路に従う) +- [ ] `~/.claude/skills/prepare-pr/evals/evals.json` に新 Scenario 追加 (bookmark 未作成正常 path) +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- prepare-pr skill Step 1 の state 確認コマンドに bookmark 存在チェックが明示 +- 新 Scenario が evals.json に追加され、bookmark 未作成 fallback の正常動作が検証される +- 本セッション類似の push 失敗が再現した場合、Step 1 で fallback 実行が即時発火 + +#### 詰まっている箇所 + +- skill repository (`E:\work\claude-code-skills`) の deploy / sync 経路の確認が必要 (本リポジトリの `deploy:hooks` とは別経路)。 + +--- + +### PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25) + +> **動機**: PR #97 / #99 セッションで観測された gh tool_result の token bloat (POST 応答 24KB / GET 過剰 metadata 44KB) を、当初 rule 追加 (`~/.claude/rules/common/git-workflow.md`) で抑制する計画だった。しかし PR #172 で 順位 144 (`jj-message-required` preset) の dogfood が成功し、「rule 化は session 毎に読み込みコストがかかり、別セッションでも結果が一定にならない」課題が顕在化。仕組み化 (PreToolUse hook) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。 +> +> 抑制対象 3 パターン (rule 設計時点で確定済): +> +> 1. **POST 操作 (作成・更新)** の応答破棄漏れ: `gh api .../replies` 等で `> /dev/null 2>&1` がない → 24KB の reply body が context 汚染 +> 2. **GET 操作 (取得)** で `--jq` filter 不使用: `gh api .../comments` 等で生 JSON 全取得 → 44KB の不要 metadata 流入 +> 3. **CR walkthrough internal state 混入**: `gh pr view --json comments` で CR walkthrough の base64 encoded state が含まれる (1 PR で 30KB+) → 確認時は `--jq 'del(.comments[].body)'` 等で除外必須 +> +> **本タスクの位置づけ**: 順位 144 (jj-message-required hook) の同型実装パターン。`feedback_pipeline_over_rules.md` 適用 = パイプライン側機械的修正で Claude 判断介入を排除、session 毎の rule load コスト不要、別セッションでも結果が一定。Bundle a の **Sub-PR 1 token 削減層** だが docs 化 → hook 化への切替に伴い Bundle a との結合は緩む。 +> +> **参照**: ADR-034 (CodeRabbit 監視・対話の自動化戦略)、PR #99 / #97 session log (token bloat 実観測)、PR #172 (順位 144 = `jj-message-required` preset 実装事例)、`src/hooks-pre-tool-validate/src/main.rs` の `preset_jj_message_required` を template に追加 +> +> **実行優先度**: 💎 **Tier 3** — Effort M (順位 144 と同型実装で工数把握済、~90 分見込み)。Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) でも `gh api` を使うため Sub-PR 1 で先行 land 推奨。 + +#### 設計決定 (案、順位 144 hook 実装を template に踏襲) + +- **配置**: `src/hooks-pre-tool-validate/src/main.rs` に新 preset `gh-token-efficiency` 追加 +- **`BlockedPattern.exception` を活用** (順位 144 で導入済、再利用) +- **block 対象 3 種類** (個別 BlockedPattern として実装): + - (1) **POST 応答破棄漏れ**: pattern = `gh\s+(api\s+-X\s+POST|api\s+(?!.*-X\s+GET)[^|]*-f\s+)`、exception = `>\s*/dev/null|>\s*NUL`、message = 「`> /dev/null 2>&1` で応答 body 破棄を推奨 (24KB context 汚染防止)」 + - (2) **`gh api` の `--jq` 不使用**: pattern = `gh\s+api\s+[^|]*`、exception = `--jq\b|\|\s*jq\b|>\s*/dev/null`、message = 「`--jq` で必要 field のみ抽出を推奨 (生 JSON 過剰流入防止)」 + - (3) **CR walkthrough state 混入**: pattern = `gh\s+pr\s+view\s+[^|]*--json\s+[^|]*comments`、exception = `del\(\.comments|--jq.*comments.*\|\s*map`、message = 「CR walkthrough base64 internal state を含むため `--jq 'del(.comments[].body)'` 等で除外を推奨」 +- **hooks-config.toml**: `blocked_patterns` に `"gh-token-efficiency"` を追加 (opt-in preset、派生プロジェクト breaking change リスク軽減) +- **opt-in 設計**: `default_preset_names()` の fallback には含めない (`gh-pr-create-guard` 等と同じ classification) + +#### 作業計画 (順位 144 と同 phase 構造) + +- [ ] **Phase 1**: 既存 preset 構造を理解し、`preset_gh_token_efficiency()` 関数を実装 (3 BlockedPattern を vec で返す) +- [ ] **Phase 2**: `build_blocked_patterns` の `resolve_preset_or_custom` dispatch に登録 + `.claude/hooks-config.toml` の `blocked_patterns` に `"gh-token-efficiency"` 追加 + コメント section に説明追加 +- [ ] **Phase 3**: test 拡充 — block ケース (応答破棄漏れ POST / `--jq` なし GET / walkthrough exclusion なし) × 3 + allow ケース (3 規則すべて遵守) × 3 + non-regression (既存 preset との干渉なし) +- [ ] **Phase 4**: `pnpm build:hooks-pre-tool-validate` で exe deploy + dogfood (本 todo を読んだ後の `gh api` 呼び出しで block 動作確認) +- [ ] **Phase 5**: `pnpm push` (AI review) + `pnpm create-pr` +- [ ] **post-merge**: 本リポジトリ 1-2 PR の dogfood で false positive 観測 → 派生プロジェクト deploy 判断 +- [ ] 本 todo4.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `jj-message-required` と同型の `gh-token-efficiency` preset が稼働 (3 BlockedPattern が block + exception 機能で正規パターン allow) +- `gh api .../replies -f body='...'` (応答破棄なし) → block + 修正手順 feedback +- `gh api .../comments` (`--jq` なし) → block + 修正手順 feedback +- `gh pr view 171 --json comments` (walkthrough 除外なし) → block + 修正手順 feedback +- 規則遵守版 (`> /dev/null 2>&1` 付き POST / `--jq` 抽出 / `del(.comments[].body)` 除外) は通過 +- 既存 preset との non-regression (jj-main-guard / git push block 等は継続動作) +- `cargo test -p hooks-pre-tool-validate` pass + +#### 詰まっている箇所 + +- 順位 144 実装パターンを踏襲することで設計判断は最小化される +- false positive リスク: `gh api ... | jq` のような piped jq は exception regex で吸収可能 (`\|\s*jq\b` を含める) +- 派生プロジェクト deploy timing: 本リポジトリ先行 dogfood (1-2 PR) → 観測後判断 (`feedback_dogfood_evals_two_phase.md` 適用) diff --git a/docs/todo5.md b/docs/todo5.md index 7351782b..b9d667dc 100644 --- a/docs/todo5.md +++ b/docs/todo5.md @@ -1,130 +1,130 @@ -# TODO (Part 5) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: 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-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up - - - -> **動機**: PR #115 で「config が user-editable system boundary のとき、sanitize() で値域検証 + 下流 arithmetic で安全範囲保証」というパターンが実証された (CR Major #1 + #2 が両方とも同型の「config 値→arithmetic 入力」cross-layer integrity 問題)。同型の bug class は今後も Rust + config 駆動の component で発生しうるため、組織的 learning として codify。 -> -> **本タスクの位置づけ**: 順位 76 / 77 (test 層) の補完層 = ドキュメント / ADR 層。3 つを別 PR で land すると依存関係が読みやすい (test 層先 → 後で ADR が test を参照)。post-merge-feedback Tier 3 #1 採用。 -> -> **参照**: PR #115 CR Major #1+#2 解消経緯、`.claude/feedback-reports/115.md` Tier 3 #1、CLAUDE.md `security.md` (input validation)、ADR-022 (責務分離原則) の延長 -> -> **実行優先度**: 💎 **Tier 3** — Effort S。順位 76 / 77 が land した後の codification PR。 - -#### 設計決定 (案) - -- **ADR-NNN (新規)**: `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を作成 (番号は land 時 PR で確定) - - **タイトル**: Rust timestamp arithmetic の overflow safety pattern - - **Context**: PR #115 で sanitize() が `i64::MAX as u64` を valid として通したが downstream の `now_unix + wait as i64` で overflow した CR Major #2 を引用 - - **Decision**: 以下 3 層で overflow を構造的に防ぐ - 1. **Sanitize layer**: config に `MAX_SAFE_WAIT_SECS` 等の上限を設定し、`sanitize()` で値域違反を default fallback - 2. **Arithmetic layer**: `now_unix + wait as i64` のような cast point に `// SAFETY: 以下を保証` コメント (人間レビュー時の手がかり) - 3. **Test layer**: `now + sanitize 後の値 < i64::MAX` invariant を `checked_add` で machine-enforce (順位 76/77 で実装) - - **Consequences**: cross-module overflow を test layer で構造的に検知。`MAX_SAFE_WAIT_SECS` の根拠が future-proof (2100 年でも safe) -- **CLAUDE.md `security.md` (`~/.claude/rules/common/security.md`) 拡充**: 「config は user-editable system boundary、必ず sanitize() で値域検証」+ 「Rust の `as` cast は overflow check しない、`checked_add` を併用」を追加。global rule なので全 Rust project に適用される -- **本 PR の効果**: ADR + CLAUDE.md で codified 後、将来同型 bug が発生したら「本 ADR (採番後の実番号) 違反」として一発で指摘可能 - -#### 作業計画 - -- [ ] `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を新規作成 (Context / Decision / Consequences、番号は land 時 PR で確定) -- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 -- [ ] `~/.claude/rules/common/security.md` に「config sanitize + Rust arithmetic safety」セクション追加 -- [ ] (任意) `~/.claude/rules/rust/coding-style.md` に `// SAFETY:` コメント pattern を補足 -- [ ] 順位 76/77 が land 済の前提で「Test layer で検証する」を ADR で言及 (前後関係を明示) -- [ ] 派生プロジェクト deploy には影響なし (docs / global rule のみ) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- 該当 ADR (land 時 PR で番号確定) が land し、CLAUDE.md からリンクされる -- `~/.claude/rules/common/security.md` に Rust arithmetic safety pattern が追加される -- 将来「config 値が arithmetic で overflow」という形の bug が出たら、本 ADR (採番後の実番号) を引用して一発で指摘できる - -#### 詰まっている箇所 - -- 順位 76/77 land 前後の順番: ADR で test layer に言及するため、test 実装が先のほうが自然。ただし ADR を先 land して「test を本 ADR (採番後の実番号) に従って実装する」流れも可能。実装時に ROI で判断 (test PR と ADR PR を分けるか、まとめるか) -- `~/.claude/` 配下の global rule 編集は本 repo 外への影響あり、慎重に (memory `feedback_no_unenforced_rules.md` 「強制力のないルール追加は却下」原則を踏まえる必要あり = 機械検知できないルールは却下されうる)。本 task は ADR + 既存 rule 拡充で「機械検知の根拠」を提供する形なので OK だが、CLAUDE.md security.md の追記内容が「ルールだけ増やす」と評価されないよう、順位 76/77 の test との連携を明示する - ---- - -### docs-governance.md § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用) - -> **動機**: PR #117 (`docs/coderabbit-monitoring-efficiency.md` retirement) で順位 15 (cli-pr-monitor 通知 Recovery 経路) を「Bb-3 SessionStart catch-up nudge で吸収済」として priority table から削除した際、現 `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2「残タスクを priority table に登録」は **priority table から除外するケース (= 完了/意図的 deprioritize/defer) を未定義**。reviewer (post-merge-feedback agent) は私の commit message に「Bb-3 で吸収済」と書かれていることは認識したが、rule として 3 値分類が明文化されていない点を指摘。 -> -> **本タスクの位置づけ**: PR #117 post-merge-feedback Tier 3 #1 採用。retirement workflow 自体を強化する meta-task で、将来の同型 ambiguity を構造的に防止。 -> -> **参照**: PR #117 retirement の経緯 (`docs/coderabbit-monitoring-efficiency.md` 削除)、`.claude/feedback-reports/117.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。1 セクションに 5-10 行追記。 - -#### 設計決定 (案) - -- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Retirement Workflow (planning markdowns)` セクション内、Step 2「Migrate residual tasks」を拡充 -- **追記内容案** (Step 2 改訂): - - 現状: 「Migrate residual tasks — register any remaining work to `docs/todo*.md` priority table」 - - 改訂: priority table から除外する場合は commit/PR description で 3 値のいずれかを明示する要件を追加 - - **完了 (subsumed)**: 別タスクで実質達成済 (例: 順位 15 → Bb-3 で吸収)。subsuming task / PR を引用 - - **意図的 deprioritize**: 優先度を下げて当面着手しない。理由を引用 - - **defer**: 後続 bundle で扱う。次の bundle context を引用 - - 「分類なしの単純削除は禁止」と明記し、`grep` 等での検証可能性を担保 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件を追記 (5-10 行) -- [ ] PR #117 を retroactive example として引用 (順位 15 = subsumed by Bb-3 のケース) -- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- `docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件が明記される -- 将来の retirement PR で「priority table 削除時の理由を 3 値のどれか明示」が rule として参照可能になる -- 順位 15 のような subsumed なタスクが「単純削除」として誤解されないよう、convention で守られる - -#### 詰まっている箇所 - -- ルール追加自体は機械検知不可だが、本 task は **既存の retirement workflow の Step 2 を拡充するもの** (新規 rule の追加ではなく既存 rule の精緻化) なので、memory `feedback_no_unenforced_rules.md` の「強制力のないルール追加は却下」原則とは性質が異なる。retirement workflow を実行する commit/PR で `grep -E "完了|deprioritize|defer"` 等の機械検知を後付け可能 (ただし本 task の scope 外) -- 3 値分類が実用的な粒度か、より細かい分類が必要か (例: `subsumed` を `merged into bundle` / `replaced by ADR` 等に分割) は実装時に dogfood で判断 - ---- - -### cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer) - -> **動機**: PR #120 dogfood で CR walkthrough overlay が `Failed to post review comments` (rate-limit ではない transient failure) を表示するも `parse_rate_limit_status` が detected せず、auto-retry が発火しなかった。1 観測だが auto-retry の silent failure として機能不全。 -> -> **参照**: PR #120 walkthrough comment (16:41Z 投稿)、`.claude/feedback-reports/120.md` Tier 1 #2、[ADR-018 §追記 2026-05-08](adr/adr-018-pr-monitor-takt-migration.md) -> -> **実行優先度**: 🚀 **Tier 1 (defer)** — §A-2 P-5 PR (2026-05-08) で Defer 判定。1 観測のみで systemic 性未確認のため、ユーザー方針 `feedback_no_unenforced_rules` (機械検知不可なら何もしない方がマシ) と整合させて 3 PR 観測閾値到達まで待つ。 -> -> **Re-trigger 条件**: `Failed to post review comments` (またはそれに類する rate-limit 以外の CR transient failure) が他の PR で 1 件以上追加観測 (合計 2 件以上) されたら本タスクを再活性化、実装に着手。 - -#### 作業計画 (defer 中、参考) - -- [ ] `Review failed` / `Failed to post review comments` 等の transient failure pattern を detection に追加 -- [ ] rate-limit 系と統合する場合は state field を `transient_failure: Option` に一般化検討 -- [ ] ADR-018 §追記 2026-05-08 の「対象 transient failure 分類」表を「⏳ 未実装」→「✅ 実装済」に更新 - -#### 完了基準 - -- `Failed to post review comments` を含む walkthrough overlay 検出時に auto-retry が発火する -- regression test (failure pattern 注入 → auto-retry 発火) が green -- ADR-018 §追記 2026-05-08 と整合 - ---- - +# TODO (Part 5) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: 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-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up + + + +> **動機**: PR #115 で「config が user-editable system boundary のとき、sanitize() で値域検証 + 下流 arithmetic で安全範囲保証」というパターンが実証された (CR Major #1 + #2 が両方とも同型の「config 値→arithmetic 入力」cross-layer integrity 問題)。同型の bug class は今後も Rust + config 駆動の component で発生しうるため、組織的 learning として codify。 +> +> **本タスクの位置づけ**: 順位 76 / 77 (test 層) の補完層 = ドキュメント / ADR 層。3 つを別 PR で land すると依存関係が読みやすい (test 層先 → 後で ADR が test を参照)。post-merge-feedback Tier 3 #1 採用。 +> +> **参照**: PR #115 CR Major #1+#2 解消経緯、`.claude/feedback-reports/115.md` Tier 3 #1、CLAUDE.md `security.md` (input validation)、ADR-022 (責務分離原則) の延長 +> +> **実行優先度**: 💎 **Tier 3** — Effort S。順位 76 / 77 が land した後の codification PR。 + +#### 設計決定 (案) + +- **ADR-NNN (新規)**: `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を作成 (番号は land 時 PR で確定) + - **タイトル**: Rust timestamp arithmetic の overflow safety pattern + - **Context**: PR #115 で sanitize() が `i64::MAX as u64` を valid として通したが downstream の `now_unix + wait as i64` で overflow した CR Major #2 を引用 + - **Decision**: 以下 3 層で overflow を構造的に防ぐ + 1. **Sanitize layer**: config に `MAX_SAFE_WAIT_SECS` 等の上限を設定し、`sanitize()` で値域違反を default fallback + 2. **Arithmetic layer**: `now_unix + wait as i64` のような cast point に `// SAFETY: 以下を保証` コメント (人間レビュー時の手がかり) + 3. **Test layer**: `now + sanitize 後の値 < i64::MAX` invariant を `checked_add` で machine-enforce (順位 76/77 で実装) + - **Consequences**: cross-module overflow を test layer で構造的に検知。`MAX_SAFE_WAIT_SECS` の根拠が future-proof (2100 年でも safe) +- **CLAUDE.md `security.md` (`~/.claude/rules/common/security.md`) 拡充**: 「config は user-editable system boundary、必ず sanitize() で値域検証」+ 「Rust の `as` cast は overflow check しない、`checked_add` を併用」を追加。global rule なので全 Rust project に適用される +- **本 PR の効果**: ADR + CLAUDE.md で codified 後、将来同型 bug が発生したら「本 ADR (採番後の実番号) 違反」として一発で指摘可能 + +#### 作業計画 + +- [ ] `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を新規作成 (Context / Decision / Consequences、番号は land 時 PR で確定) +- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 +- [ ] `~/.claude/rules/common/security.md` に「config sanitize + Rust arithmetic safety」セクション追加 +- [ ] (任意) `~/.claude/rules/rust/coding-style.md` に `// SAFETY:` コメント pattern を補足 +- [ ] 順位 76/77 が land 済の前提で「Test layer で検証する」を ADR で言及 (前後関係を明示) +- [ ] 派生プロジェクト deploy には影響なし (docs / global rule のみ) +- [ ] 本 todo5.md エントリを削除 + +#### 完了基準 + +- 該当 ADR (land 時 PR で番号確定) が land し、CLAUDE.md からリンクされる +- `~/.claude/rules/common/security.md` に Rust arithmetic safety pattern が追加される +- 将来「config 値が arithmetic で overflow」という形の bug が出たら、本 ADR (採番後の実番号) を引用して一発で指摘できる + +#### 詰まっている箇所 + +- 順位 76/77 land 前後の順番: ADR で test layer に言及するため、test 実装が先のほうが自然。ただし ADR を先 land して「test を本 ADR (採番後の実番号) に従って実装する」流れも可能。実装時に ROI で判断 (test PR と ADR PR を分けるか、まとめるか) +- `~/.claude/` 配下の global rule 編集は本 repo 外への影響あり、慎重に (memory `feedback_no_unenforced_rules.md` 「強制力のないルール追加は却下」原則を踏まえる必要あり = 機械検知できないルールは却下されうる)。本 task は ADR + 既存 rule 拡充で「機械検知の根拠」を提供する形なので OK だが、CLAUDE.md security.md の追記内容が「ルールだけ増やす」と評価されないよう、順位 76/77 の test との連携を明示する + +--- + +### docs-governance.md § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用) + +> **動機**: PR #117 (`docs/coderabbit-monitoring-efficiency.md` retirement) で順位 15 (cli-pr-monitor 通知 Recovery 経路) を「Bb-3 SessionStart catch-up nudge で吸収済」として priority table から削除した際、現 `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2「残タスクを priority table に登録」は **priority table から除外するケース (= 完了/意図的 deprioritize/defer) を未定義**。reviewer (post-merge-feedback agent) は私の commit message に「Bb-3 で吸収済」と書かれていることは認識したが、rule として 3 値分類が明文化されていない点を指摘。 +> +> **本タスクの位置づけ**: PR #117 post-merge-feedback Tier 3 #1 採用。retirement workflow 自体を強化する meta-task で、将来の同型 ambiguity を構造的に防止。 +> +> **参照**: PR #117 retirement の経緯 (`docs/coderabbit-monitoring-efficiency.md` 削除)、`.claude/feedback-reports/117.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。1 セクションに 5-10 行追記。 + +#### 設計決定 (案) + +- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Retirement Workflow (planning markdowns)` セクション内、Step 2「Migrate residual tasks」を拡充 +- **追記内容案** (Step 2 改訂): + - 現状: 「Migrate residual tasks — register any remaining work to `docs/todo*.md` priority table」 + - 改訂: priority table から除外する場合は commit/PR description で 3 値のいずれかを明示する要件を追加 + - **完了 (subsumed)**: 別タスクで実質達成済 (例: 順位 15 → Bb-3 で吸収)。subsuming task / PR を引用 + - **意図的 deprioritize**: 優先度を下げて当面着手しない。理由を引用 + - **defer**: 後続 bundle で扱う。次の bundle context を引用 + - 「分類なしの単純削除は禁止」と明記し、`grep` 等での検証可能性を担保 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件を追記 (5-10 行) +- [ ] PR #117 を retroactive example として引用 (順位 15 = subsumed by Bb-3 のケース) +- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) +- [ ] 本 todo5.md エントリを削除 + +#### 完了基準 + +- `docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件が明記される +- 将来の retirement PR で「priority table 削除時の理由を 3 値のどれか明示」が rule として参照可能になる +- 順位 15 のような subsumed なタスクが「単純削除」として誤解されないよう、convention で守られる + +#### 詰まっている箇所 + +- ルール追加自体は機械検知不可だが、本 task は **既存の retirement workflow の Step 2 を拡充するもの** (新規 rule の追加ではなく既存 rule の精緻化) なので、memory `feedback_no_unenforced_rules.md` の「強制力のないルール追加は却下」原則とは性質が異なる。retirement workflow を実行する commit/PR で `grep -E "完了|deprioritize|defer"` 等の機械検知を後付け可能 (ただし本 task の scope 外) +- 3 値分類が実用的な粒度か、より細かい分類が必要か (例: `subsumed` を `merged into bundle` / `replaced by ADR` 等に分割) は実装時に dogfood で判断 + +--- + +### cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer) + +> **動機**: PR #120 dogfood で CR walkthrough overlay が `Failed to post review comments` (rate-limit ではない transient failure) を表示するも `parse_rate_limit_status` が detected せず、auto-retry が発火しなかった。1 観測だが auto-retry の silent failure として機能不全。 +> +> **参照**: PR #120 walkthrough comment (16:41Z 投稿)、`.claude/feedback-reports/120.md` Tier 1 #2、[ADR-018 §追記 2026-05-08](adr/adr-018-pr-monitor-takt-migration.md) +> +> **実行優先度**: 🚀 **Tier 1 (defer)** — §A-2 P-5 PR (2026-05-08) で Defer 判定。1 観測のみで systemic 性未確認のため、ユーザー方針 `feedback_no_unenforced_rules` (機械検知不可なら何もしない方がマシ) と整合させて 3 PR 観測閾値到達まで待つ。 +> +> **Re-trigger 条件**: `Failed to post review comments` (またはそれに類する rate-limit 以外の CR transient failure) が他の PR で 1 件以上追加観測 (合計 2 件以上) されたら本タスクを再活性化、実装に着手。 + +#### 作業計画 (defer 中、参考) + +- [ ] `Review failed` / `Failed to post review comments` 等の transient failure pattern を detection に追加 +- [ ] rate-limit 系と統合する場合は state field を `transient_failure: Option` に一般化検討 +- [ ] ADR-018 §追記 2026-05-08 の「対象 transient failure 分類」表を「⏳ 未実装」→「✅ 実装済」に更新 + +#### 完了基準 + +- `Failed to post review comments` を含む walkthrough overlay 検出時に auto-retry が発火する +- regression test (failure pattern 注入 → auto-retry 発火) が green +- ADR-018 §追記 2026-05-08 と整合 + +--- + diff --git a/docs/todo6.md b/docs/todo6.md index 11614647..a8a4c911 100644 --- a/docs/todo6.md +++ b/docs/todo6.md @@ -1,296 +1,221 @@ -# TODO (Part 6) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo5.md / 本ファイルが 50KB に到達 (PR #143 T3-#1) のため **新規エントリは [docs/todo8.md](todo8.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### 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` 系) と組み合わせで教育効果が強化される - ---- - -### `with_num_ctx(X)` override 値 serialization 検証テスト (PR #136 T2-#1 採用) - -> **動機**: PR #136 (§8.D / num_ctx 8192 land) で `OllamaClient::with_num_ctx` builder method を追加した際、test として `num_ctx_is_serialized_into_request_body` を入れたが、これは default 値 (8192) のみを mockito で assert する。`with_num_ctx(X)` を経由した override (例: 16384) が実際に request body に反映されるかは未検証で、builder chaining が壊れた場合 (例: `with_num_ctx` body の typo `self.num_ctx = num_ctx` → `self.num_ctx = self.num_ctx`) に **silent degrade** = default 値が常に送信されて override が無視される、を test で捕捉できない。 -> -> **本タスクの位置づけ**: PR #136 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort S / Adoption Risk None)。CodeRabbit nitpick 起点ではなく post-merge-feedback agent が独立に発見した test gap (CodeRabbit は同 method の `0` guard は指摘したが override-serialization wiring までは見抜かなかった)。 -> -> **参照**: `.claude/feedback-reports/136.md` Tier 2 #1、`src/lib-ollama-client/src/lib.rs` の既存 test `num_ctx_is_serialized_into_request_body` (default 値検証) と `num_ctx_defaults_and_overrides_apply` (struct field 検証) の合間にある wire-level wiring gap -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。Phase d (PR-based 実環境 dogfood) で num_ctx tweak (16384 / 32768 等) する局面に入る前の安全網。 - -#### 設計決定 (案) - -- **配置先**: `src/lib-ollama-client/src/lib.rs` の `#[cfg(test)] mod tests` -- **test 名 (案)**: `with_num_ctx_override_is_serialized_into_request_body` -- **実装方針**: 既存 `num_ctx_is_serialized_into_request_body` の mockito pattern を踏襲し、`OllamaClient::new(...).with_num_ctx(16384)` で構築 → request body に `num_ctx:16384` が含まれることを `Matcher::PartialJsonString` で assert -- **代替案**: `with_num_ctx(8192)` (= default 同値) でも builder chain が走ることを assert する pure unit test (mockito 不要) を追加し、wire-level test と組み合わせる二層構造も可 - -#### 作業計画 - -- [ ] 既存 `num_ctx_is_serialized_into_request_body` test を template に override 値検証 test を追加 -- [ ] `with_num_ctx(16384)` を builder chain 経由で適用 → mockito の `Matcher::PartialJsonString` で `{"options":{"num_ctx":16384}}` を assert -- [ ] cargo test -p lib-ollama-client で 12 tests pass を確認 (現状 11 + 新 1) -- [ ] 本 todo6.md エントリを削除 - -#### 完了基準 - -- `with_num_ctx(X)` の builder chain が壊れた場合 (e.g. body の self-assign 化、struct field rename) に test が即 fail する -- Phase d で num_ctx を tweak する局面で、override 値が実際に Ollama に伝わっているかを test 層で seal できる - -#### 詰まっている箇所 - -なし。Effort S / 既存 test の duplicate 風で実装容易。 - ---- - -### `development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用) - -> **動機**: PR #139 (Bundle h+g-2 land) の post-merge-feedback で 2 つの暗黙知が systemic に観測された: -> -> 1. **同一ファイル複数編集の 1 task 統合**: PR #119/#120/#121 の sub-PR 分割では同一ファイル (`~/.claude/rules/common/*`) の複数編集を 1 task に統合した方が review 重複を回避できた。明文化されていないため次回類似 sub-PR で再発する余地 -> 2. **partial completion + 後続 PR 追補明記**: PR #139 で Bundle g-2 (順位 87+88) を land したが Bundle g-1 (順位 85+86) は未着手という partial completion を PR body / analysis.md で明記する pattern。Bundle h でも同様 (8 試験運用 ADR への back-link は本 PR 範囲外と明示)。明文化されていないと「全部やった」誤認や曖昧 review が生じる -> -> **本タスクの位置づけ**: PR #139 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 方針との整合: 本提案は「既存実践の明文化」であり機械検知不可なルール追加ではない (review/PR body 記述で人間の意識付けに用いる目安) ため例外的に採用相当。 -> -> **参照**: `.claude/feedback-reports/139.md` Tier 3 #1、`~/.claude/rules/common/development-workflow.md`、PR #119/#120/#121 (sub-PR 分割実例)、PR #139 (partial completion 実例) - -#### 作業計画 - -- [ ] `~/.claude/rules/common/development-workflow.md` の Feature Implementation Workflow 直後 (現 § Edge case 観測頻度の前後 etc.) に新 section を追加 - - **(a) 同一ファイル複数編集の 1 task 統合**: 「sub-PR 分割時、同一ファイルへの複数 task 編集は 1 commit / 1 task に統合する。理由: review 重複回避 + diff の局所化」 - - **(b) partial completion + 後続 PR 追補明記**: 「bundle / scope を全消化できない場合、PR body の "Out of scope" や planning doc に未消化分を明示。理由: 「全部やった」誤認の防止 + 後続 PR の起点として trackable」 -- [ ] 既存 § Edge case 観測頻度との接続 (相互参照 or 配置順序検討) -- [ ] markdownlint clean 確認 -- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 上記 2 pattern が rule として codify される -- 次回 sub-PR 分割時 / partial completion 時に reviewer/Claude が rule から逆引き可能になる -- markdownlint clean - -#### 詰まっている箇所 - -なし。Effort XS、global rule への追記のみで副作用最小。配置先 (Feature Implementation Workflow 直後 vs 別 § で独立) は実装時の判断。 - ---- - -### グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用) - -> **動機**: 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) で hooks を porting する際、lint runner がサポートするフィールド (`pattern` / `extensions` / `severity` / `message` / `why`、planned: `paths`) を一目で把握できる reference が グローバル CLAUDE.md に存在しない。順位 103 (code comment) と相補的で、cross-project 可視性を即時向上。 -> -> **本タスクの位置づけ**: PR #140 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/140.md` Tier 3 #2、`~/.claude/CLAUDE.md` (global、リンクのみ方針 = `feedback_claude_md_link_only.md`)、`src/hooks-post-tool-linter/src/main.rs` `CustomRule` struct - -#### 設計決定の余地 - -- **`feedback_claude_md_link_only.md` との整合**: グローバル CLAUDE.md は「リンクのみ」方針。table 形式で field 一覧を inline すると memory rule に違反する可能性 -- **代替案 1**: グローバル CLAUDE.md には「lint runner field reference は `~/.claude/rules/...` 配下に独立 doc」とリンクのみ書き、本体 doc は `~/.claude/rules//lint-runner-fields.md` 等に配置 -- **代替案 2**: project 内 ADR-007 amendment (順位 104) で field 一覧を含めて、グローバル CLAUDE.md は ADR-007 へのリンクのみ -- **判断**: 順位 104 land 後に決定。重複が無いように lifecycle 整合性を取る - -#### 作業計画 - -- [ ] 順位 104 (ADR-007 amendment) の land 後、配置案 1 / 2 / 別案を決定 -- [ ] `feedback_claude_md_link_only.md` 方針を再確認 -- [ ] 配置先に table 追加 (現サポート field + planned + 派生プロジェクト porting 時の参照点) -- [ ] グローバル CLAUDE.md にリンク追加 (memory rule 遵守) -- [ ] 派生プロジェクト 2 つ (techbook-ledger / auto-review-fix-vc) に本変更を伝播する deploy step を確認 -- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 派生プロジェクトの rule porting 時に field reference を 1 hop で参照可能 -- `feedback_claude_md_link_only.md` 違反なし - -#### 詰まっている箇所 - -- 配置先決定が順位 104 (ADR-007 amendment) の land と依存。順位 104 で field 一覧を inline するなら本タスクはリンク追加のみで済むが、ADR は判断基準中心であれば独立 reference doc が必要 - ---- - -### `development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用) - -> **動機**: memory `feedback_verify_task_not_already_done.md` (PR #141 セッションで追加) は session-scoped で「PR #125 → #141 で 4 日間 stale todo 残存 → P-3 起動時に手動発見」事例を含むが、`~/.claude/rules/common/development-workflow.md` の central rule 側には反映されていない。`feedback_todo_no_history.md` と合わせて central 化することで、memory file 閉鎖の structural risk を軽減する。 -> -> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium = 2 観測 / Effort XS / Adoption Risk None)。memory rule の central reference への昇格パターン。 -> -> **参照**: `.claude/feedback-reports/141.md` Tier 3 #2、`~/.claude/rules/common/development-workflow.md`、memory `feedback_verify_task_not_already_done.md` / `feedback_todo_no_history.md`、PR #125 / PR #141 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に 2-3 行追記: - - 「マージ後 N 日間 stale entry 残存 → 後続 phase で手動発見」anti-pattern 事例 (PR #125 → #141) - - 「マージ → 即削除」サイクル強調 (memory `feedback_todo_no_history` central 化) - - 「task 着手時に jj log + 既存 test で land 済確認」recovery layer (memory `feedback_verify_task_not_already_done` central 化) -- [ ] central rule から両 memory file への双方向参照を追加 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- central rule に PR #125→#141 anti-pattern が anchor として記録される -- 新セッションでも両 memory rule の趣旨を central から逆引き可能になる - ---- - -### CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用) - -> **動機**: PR #140 / PR #141 で post-merge-feedback agent が Tier 2 (テスト/自動化) と称した提案を出したが、中身は ルール追加 / checklist 必須化 等の **unenforced rule** で、ユーザー判断で却下相当 (memory `feedback_no_unenforced_rules.md` で codify 済)。memory ファイルは session-scoped で新セッション AI からは見えにくく「Tier 2 = 採用必須」と誤解する構造的リスクがある。グローバル CLAUDE.md に signal + 却下パターン table を可視化し、policy をユーザー可視 + 新セッション AI からも逆引き可能にする。 -> -> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium = 複数 session 観測 / Effort S / Adoption Risk None)。memory policy の central reference への昇格パターン。 -> -> **参照**: `.claude/feedback-reports/141.md` Tier 3 #3、`~/.claude/CLAUDE.md`、memory `feedback_no_unenforced_rules.md` (PR #140 / #141 で追記済) - -#### 設計決定 - -- **`feedback_claude_md_link_only.md` との整合**: CLAUDE.md は「リンクのみ」方針。table を inline すると memory rule に違反するため、別 stable doc (`~/.claude/rules/common/post-merge-feedback-policy.md` 等) に table を移し、CLAUDE.md からリンクする運用を推奨 - -#### 検知 signal table 案 - -| Signal | 例 | 判定 | -|---|---|---| -| target field に `*.md` / `test convention` 等 **文書 path** | "lint rule テスト checklist に <条件> を必須化" | ⚠️ Tier 2 偽装疑い | -| description に「**必須化**」「**標準化**」「**チェックリスト追加**」 | "lint rule テストで大文字バリアント必須化" | ⚠️ unenforced rule 強い signal | -| 機械強制 (CI / lint / test 存在検証) なし | "verbal checklist", "guideline 追記" | ❌ 却下相当 | - -#### 作業計画 - -- [ ] 配置先 (新 doc / 既存 doc) を決定 -- [ ] 上記 signal table を新 doc or 既存 doc に追加 -- [ ] CLAUDE.md に link 追加 (memory rule 遵守) -- [ ] 派生プロジェクトへの伝播も検討 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 新セッション AI が CLAUDE.md → link → table の動線で Tier 2 偽装判定を逆引き可能になる -- `feedback_claude_md_link_only` 違反なし - ---- - - -### pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用) - -> **動機**: Phase A (PR #142) の `overflow_hint()` は副作用なしの純粋関数で、境界値 (90%) / None (metadata 欠落) / 閾値未満 (90% 未満) の 3 パターンで test 化できる構造になっていた。このパターンを `~/.knee/rules/common/testing.md` にテンプレ化することで、Rust lib 全般で副作用分離と test 容易性が促進される。 -> -> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 2 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/142.md` Tier 2 #3、`~/.claude/rules/common/testing.md`、`src/lib-ollama-client/src/lib.rs` の `overflow_hint()` (PR #142) - -#### 作業計画 - -- [ ] `~/.claude/rules/common/testing.md` に「Pure function test pattern」section を追加 (境界値 / None / 閾値未満 の 3 パターン例) -- [ ] `overflow_hint()` (PR #142) をモデル例として cite -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- testing.md に template が記載され、次回 Rust lib で副作用分離する局面で参照可能になる - ---- - -### `docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用) - -> **動機**: PR #142 で CR Minor #2 として「todo-summary.md 順位 106-108 が todo5.md を指すが intro policy は todo6.md」の bifurcation 指摘あり、本 PR 内で修正済。しかし routing rule が文書化されておらず次回も同型 bifurcation の再発リスクがある。docs-governance.md に「新規詳細は todo6.md」routing rule + 50KB 超過時の対応方針を明文化することで構造的予防。 -> -> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/142.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md`、PR #142 CR Minor #2 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` に「todo*.md 新規詳細 routing rule」section を追加: 新規詳細は最新の todoN.md (現在 = todo6.md)、50KB 超過時は todo(N+1).md を新設 -- [ ] todo*.md 既存 file の preamble との整合確認 (todo6.md / todo7.md の冒頭文と矛盾しないか) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回 todo*.md 50KB 超過時に routing 判断が明確になり、CR Minor #2 と同型の bifurcation が再発しない - +# TODO (Part 6) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo5.md / 本ファイルが 50KB に到達 (PR #143 T3-#1) のため **新規エントリは [docs/todo8.md](todo8.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### scale-aware eval fixtures (200+ 行) — 大規模 diff dogfood 信頼性継続改善 (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 で、本番 PR 投入時に頻発するリスクが顕在化していた。fixture 化することで再現可能化し、§8.D prompt v3 / v4 改善ループの reference point として固定する。 +> +> **本タスクの位置づけ**: PR #132 post-merge-feedback Tier 2 #5 採用 (Frequency Medium / Effort M / Adoption Risk None)。 +> +> **Status update (2026-06-06)**: 当初動機は「Phase d 投入前の必須 infrastructure」だったが、**ADR-038 (Local LLM finding classification) は PR #156 で採用昇格済**、関連 ephemeral 計画書も retire 済で **Phase d は既に運用入り**。動機は「Phase d 着手前」→「**採用昇格後の大規模 diff dogfood 信頼性向上 (継続改善)**」に書き換え。優先度は若干低下 (must → should) するが、リアル PR で 200+ 行 diff の fallback rate を測定する infrastructure はまだ価値あり (週次レビュー Phase D dogfood で fallback 観測継続中)。 +> +> **参照**: `.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 観測)、ADR-038 (採用昇格 PR #156) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。順位 91 land 済のため独立着手可。Phase d 運用中の継続改善として位置付け。 + +#### 追加する 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。 + +--- + +### `development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用) + +> **動機**: PR #139 (Bundle h+g-2 land) の post-merge-feedback で 2 つの暗黙知が systemic に観測された: +> +> 1. **同一ファイル複数編集の 1 task 統合**: PR #119/#120/#121 の sub-PR 分割では同一ファイル (`~/.claude/rules/common/*`) の複数編集を 1 task に統合した方が review 重複を回避できた。明文化されていないため次回類似 sub-PR で再発する余地 +> 2. **partial completion + 後続 PR 追補明記**: PR #139 で Bundle g-2 (順位 87+88) を land したが Bundle g-1 (順位 85+86) は未着手という partial completion を PR body / analysis.md で明記する pattern。Bundle h でも同様 (8 試験運用 ADR への back-link は本 PR 範囲外と明示)。明文化されていないと「全部やった」誤認や曖昧 review が生じる +> +> **本タスクの位置づけ**: PR #139 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 方針との整合: 本提案は「既存実践の明文化」であり機械検知不可なルール追加ではない (review/PR body 記述で人間の意識付けに用いる目安) ため例外的に採用相当。 +> +> **参照**: `.claude/feedback-reports/139.md` Tier 3 #1、`~/.claude/rules/common/development-workflow.md`、PR #119/#120/#121 (sub-PR 分割実例)、PR #139 (partial completion 実例) + +#### 作業計画 + +- [ ] `~/.claude/rules/common/development-workflow.md` の Feature Implementation Workflow 直後 (現 § Edge case 観測頻度の前後 etc.) に新 section を追加 + - **(a) 同一ファイル複数編集の 1 task 統合**: 「sub-PR 分割時、同一ファイルへの複数 task 編集は 1 commit / 1 task に統合する。理由: review 重複回避 + diff の局所化」 + - **(b) partial completion + 後続 PR 追補明記**: 「bundle / scope を全消化できない場合、PR body の "Out of scope" や planning doc に未消化分を明示。理由: 「全部やった」誤認の防止 + 後続 PR の起点として trackable」 +- [ ] 既存 § Edge case 観測頻度との接続 (相互参照 or 配置順序検討) +- [ ] markdownlint clean 確認 +- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 上記 2 pattern が rule として codify される +- 次回 sub-PR 分割時 / partial completion 時に reviewer/Claude が rule から逆引き可能になる +- markdownlint clean + +#### 詰まっている箇所 + +なし。Effort XS、global rule への追記のみで副作用最小。配置先 (Feature Implementation Workflow 直後 vs 別 § で独立) は実装時の判断。 + +--- + +### グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用) + +> **動機**: 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) で hooks を porting する際、lint runner がサポートするフィールド (`pattern` / `extensions` / `severity` / `message` / `why`、planned: `paths`) を一目で把握できる reference が グローバル CLAUDE.md に存在しない。順位 103 (code comment) と相補的で、cross-project 可視性を即時向上。 +> +> **本タスクの位置づけ**: PR #140 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/140.md` Tier 3 #2、`~/.claude/CLAUDE.md` (global、リンクのみ方針 = `feedback_claude_md_link_only.md`)、`src/hooks-post-tool-linter/src/main.rs` `CustomRule` struct + +#### 設計決定の余地 + +- **`feedback_claude_md_link_only.md` との整合**: グローバル CLAUDE.md は「リンクのみ」方針。table 形式で field 一覧を inline すると memory rule に違反する可能性 +- **代替案 1**: グローバル CLAUDE.md には「lint runner field reference は `~/.claude/rules/...` 配下に独立 doc」とリンクのみ書き、本体 doc は `~/.claude/rules//lint-runner-fields.md` 等に配置 +- **代替案 2**: project 内 ADR-007 amendment (順位 104) で field 一覧を含めて、グローバル CLAUDE.md は ADR-007 へのリンクのみ +- **判断**: 順位 104 land 後に決定。重複が無いように lifecycle 整合性を取る + +#### 作業計画 + +- [ ] 順位 104 (ADR-007 amendment) の land 後、配置案 1 / 2 / 別案を決定 +- [ ] `feedback_claude_md_link_only.md` 方針を再確認 +- [ ] 配置先に table 追加 (現サポート field + planned + 派生プロジェクト porting 時の参照点) +- [ ] グローバル CLAUDE.md にリンク追加 (memory rule 遵守) +- [ ] 派生プロジェクト 2 つ (techbook-ledger / auto-review-fix-vc) に本変更を伝播する deploy step を確認 +- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 派生プロジェクトの rule porting 時に field reference を 1 hop で参照可能 +- `feedback_claude_md_link_only.md` 違反なし + +#### 詰まっている箇所 + +- 配置先決定が順位 104 (ADR-007 amendment) の land と依存。順位 104 で field 一覧を inline するなら本タスクはリンク追加のみで済むが、ADR は判断基準中心であれば独立 reference doc が必要 + +--- + +### `development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用) + +> **動機**: memory `feedback_verify_task_not_already_done.md` (PR #141 セッションで追加) は session-scoped で「PR #125 → #141 で 4 日間 stale todo 残存 → P-3 起動時に手動発見」事例を含むが、`~/.claude/rules/common/development-workflow.md` の central rule 側には反映されていない。`feedback_todo_no_history.md` と合わせて central 化することで、memory file 閉鎖の structural risk を軽減する。 +> +> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium = 2 観測 / Effort XS / Adoption Risk None)。memory rule の central reference への昇格パターン。 +> +> **参照**: `.claude/feedback-reports/141.md` Tier 3 #2、`~/.claude/rules/common/development-workflow.md`、memory `feedback_verify_task_not_already_done.md` / `feedback_todo_no_history.md`、PR #125 / PR #141 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に 2-3 行追記: + - 「マージ後 N 日間 stale entry 残存 → 後続 phase で手動発見」anti-pattern 事例 (PR #125 → #141) + - 「マージ → 即削除」サイクル強調 (memory `feedback_todo_no_history` central 化) + - 「task 着手時に jj log + 既存 test で land 済確認」recovery layer (memory `feedback_verify_task_not_already_done` central 化) +- [ ] central rule から両 memory file への双方向参照を追加 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- central rule に PR #125→#141 anti-pattern が anchor として記録される +- 新セッションでも両 memory rule の趣旨を central から逆引き可能になる + +--- + +### CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用) + +> **動機**: PR #140 / PR #141 で post-merge-feedback agent が Tier 2 (テスト/自動化) と称した提案を出したが、中身は ルール追加 / checklist 必須化 等の **unenforced rule** で、ユーザー判断で却下相当 (memory `feedback_no_unenforced_rules.md` で codify 済)。memory ファイルは session-scoped で新セッション AI からは見えにくく「Tier 2 = 採用必須」と誤解する構造的リスクがある。グローバル CLAUDE.md に signal + 却下パターン table を可視化し、policy をユーザー可視 + 新セッション AI からも逆引き可能にする。 +> +> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium = 複数 session 観測 / Effort S / Adoption Risk None)。memory policy の central reference への昇格パターン。 +> +> **参照**: `.claude/feedback-reports/141.md` Tier 3 #3、`~/.claude/CLAUDE.md`、memory `feedback_no_unenforced_rules.md` (PR #140 / #141 で追記済) + +#### 設計決定 + +- **`feedback_claude_md_link_only.md` との整合**: CLAUDE.md は「リンクのみ」方針。table を inline すると memory rule に違反するため、別 stable doc (`~/.claude/rules/common/post-merge-feedback-policy.md` 等) に table を移し、CLAUDE.md からリンクする運用を推奨 + +#### 検知 signal table 案 + +| Signal | 例 | 判定 | +|---|---|---| +| target field に `*.md` / `test convention` 等 **文書 path** | "lint rule テスト checklist に <条件> を必須化" | ⚠️ Tier 2 偽装疑い | +| description に「**必須化**」「**標準化**」「**チェックリスト追加**」 | "lint rule テストで大文字バリアント必須化" | ⚠️ unenforced rule 強い signal | +| 機械強制 (CI / lint / test 存在検証) なし | "verbal checklist", "guideline 追記" | ❌ 却下相当 | + +#### 作業計画 + +- [ ] 配置先 (新 doc / 既存 doc) を決定 +- [ ] 上記 signal table を新 doc or 既存 doc に追加 +- [ ] CLAUDE.md に link 追加 (memory rule 遵守) +- [ ] 派生プロジェクトへの伝播も検討 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 新セッション AI が CLAUDE.md → link → table の動線で Tier 2 偽装判定を逆引き可能になる +- `feedback_claude_md_link_only` 違反なし + +--- + + +### pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用) + +> **動機**: Phase A (PR #142) の `overflow_hint()` は副作用なしの純粋関数で、境界値 (90%) / None (metadata 欠落) / 閾値未満 (90% 未満) の 3 パターンで test 化できる構造になっていた。このパターンを `~/.knee/rules/common/testing.md` にテンプレ化することで、Rust lib 全般で副作用分離と test 容易性が促進される。 +> +> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 2 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/142.md` Tier 2 #3、`~/.claude/rules/common/testing.md`、`src/lib-ollama-client/src/lib.rs` の `overflow_hint()` (PR #142) + +#### 作業計画 + +- [ ] `~/.claude/rules/common/testing.md` に「Pure function test pattern」section を追加 (境界値 / None / 閾値未満 の 3 パターン例) +- [ ] `overflow_hint()` (PR #142) をモデル例として cite +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- testing.md に template が記載され、次回 Rust lib で副作用分離する局面で参照可能になる + +--- + +### `docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用) + +> **動機**: PR #142 で CR Minor #2 として「todo-summary.md 順位 106-108 が todo5.md を指すが intro policy は todo6.md」の bifurcation 指摘あり、本 PR 内で修正済。しかし routing rule が文書化されておらず次回も同型 bifurcation の再発リスクがある。docs-governance.md に「新規詳細は todo6.md」routing rule + 50KB 超過時の対応方針を明文化することで構造的予防。 +> +> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/142.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md`、PR #142 CR Minor #2 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` に「todo*.md 新規詳細 routing rule」section を追加: 新規詳細は最新の todoN.md (現在 = todo6.md)、50KB 超過時は todo(N+1).md を新設 +- [ ] todo*.md 既存 file の preamble との整合確認 (todo6.md / todo7.md の冒頭文と矛盾しないか) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回 todo*.md 50KB 超過時に routing 判断が明確になり、CR Minor #2 と同型の bifurcation が再発しない + diff --git a/docs/todo7.md b/docs/todo7.md index ea20430f..93e2c830 100644 --- a/docs/todo7.md +++ b/docs/todo7.md @@ -1,280 +1,242 @@ -# 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-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### `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 追加。 - -#### 設計決定 (D-6 セッションで確定、2026-05-13) - -- **refresh タイミング**: fix step が `convergence_verdict` を emit する直前に refresh (= 次 reviewer iteration が読み始める時点で post-fix 状態) -- **実装方針 (3 案を評価)**: - - **案 A: takt workflow の reviewer step に precondition step を挟む** — ❌ **不可**。takt v0.35.3 schema (`PieceMovement` / `PieceConfig`) を確認した結果、per-step `before:` / `pre-step:` / `hooks:` field は存在しない。piece レベルの `runtime.prepare` は workflow 開始時 1 回のみ実行され、step 間に挟まらない (`node_modules/.pnpm/takt@0.35.3/node_modules/takt/dist/core/models/piece-types.d.ts` Line 74-98 / `runtime-environment.js` Line 171-191) - - **案 B: cli-push-runner 側で fix step の終了を検出して diff を更新** — ❌ **scope 不適合**。`stages/takt.rs` は `run_cmd_inherit` で takt を spawn-and-wait するのみ。filesystem watcher で `.takt/runs//reports/*.md` の生成を監視する案は ~100-200 行の Rust + race condition 対応が必要で、AI-driven 案で塞げる範囲を超える複雑度 - - **案 C: fix.md instruction に "Pre-completion diff refresh" section を追加** — ✅ **採用**。既存の Bundle Z #B-β `Pre-completion deterministic check (Bundle Z Phase 2 / #B-β)` と同形の precedent あり (`scripts/fix-metrics-check.ps1` を Bash 呼び出しする pattern)。失敗 mode (= AI が refresh を skip) は現状と同等 (no regression) -- **採用案 C の実装**: `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 (advisor 推奨)。`jj diff -r @ > .takt/review-diff.txt` を `convergence_verdict` emit 直前に必須実行 -- **共有 instruction の影響**: `fix.md` は pre-push-review.yaml と post-pr-review.yaml の両方で使用される。post-pr-review は `.takt/review-diff.txt` を読まないが、refresh は冪等で副作用なし (~1s 程度の `jj diff` invocation cost のみ) -- **派生プロジェクト deploy**: `scripts/deploy-hooks.ts` は exe + `settings.local.json` のみ転送し、`.takt/facets/instructions/*` は派生 (techbook-ledger / auto-review-fix-vc) 各自が管理。よって本変更の自動 propagate は不要 (手動 port が必要だが scope 外、follow-up task) - -#### 作業計画 - -- [x] takt workflow の hook 仕様を確認 → 案 A 不可と確定 -- [x] cli-push-runner の takt invocation 構造を確認 → 案 B も scope 不適合と確定 -- [x] advisor に方針相談 → 案 C (instruction-level) 採用 + 共有 instruction 影響 / deploy 経路を検証 -- [x] `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 -- [ ] dogfood: D-6 PR push 自体で本 instruction が機能するかを観察 (fix step が refresh を実行 → 次 reviewer iter が post-fix 状態を読むか) -- [ ] dogfood 1〜2 PR で実 6-iter outlier scenario が再発しないことを観測 -- [x] Bundle Z #B-β との競合確認: `fix-metrics-check.ps1` invocation は fix step 内部の Bash 実行で完結し、本 task の diff refresh は同 fix step の最終段 Bash 実行で独立。両者は時系列で順序通り走り競合なし -- [ ] 本 todo7.md エントリを削除 (PR D-6 merge + 1-2 PR の dogfood 完了後) - -#### 完了基準 - -- 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 救済責務が消える) - -#### 残課題 / dogfood リスク - -- AI-driven 案の弱点: fix step の AI が refresh 命令を skip する可能性。Bundle Z #B-β `metrics_check` invocation の実行率を baseline として比較し、refresh 実行率 > 90% を初期目標とする。dogfood で実行率 < 90% なら **案 D (PostToolUse hook ベースの決定論層)** へ escalate を検討 -- 派生プロジェクト port: `~/.takt/facets/instructions/fix.md` (global) や techbook-ledger / auto-review-fix-vc の同等ファイルへの転載が follow-up task (本 task scope 外) - ---- - -### 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 を読むので効果は残る。 - ---- - -### 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 を追加 - ---- - -### `check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25) - -> **動機**: PR #108 で CodeRabbit が `Outside diff range comment` として review body 内に投稿した Minor finding (`docs/todo4.md` line 371/378 の retire 済前提と旧フロー混在) を、takt の `analyze-coderabbit` step が検出漏れした。`analyze-coderabbit` は `pulls/N/comments` (= inline review comment) ベースで動作するため、review.body 内のコメントは parse 対象外。結果、PR #108 で line 371/378 の修正が merge 後 follow-up commit (`vokyspww`) になった。 -> -> 当初計画では暫定緩和策として **手動 checklist** (post-PR フローに目視確認 step) を追加する rule 化方針だったが、PR #172 で「rule 化は session 毎に読み込みコストがかかり、人間が忘れる」課題が顕在化。仕組み化 (`check-ci-coderabbit` 拡張で programmatic 検出) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。当初 Tier 1 として位置づけていた analyzer 拡張を本 task で先行実施する形。 -> -> **本タスクの位置づけ**: PR #108 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。手動 checklist の根本解決 = 検出漏れを programmatic に消滅させる。手動 step が持続性低い (= 人間が忘れる) ため、CLI 拡張で session 跨いだ品質一定化が確保される。 -> -> **参照**: `.claude/feedback-reports/108.md` Tier 2 #1、PR #108 review (`Outside diff range comments` セクション、reviewer comment id 4217897113)、`src/check-ci-coderabbit/src/main.rs` (`parse_findings` 系 + `--list-findings` mode = 順位 45)、`.takt/facets/instructions/analyze-coderabbit.md`、PR #172 (順位 144 hook 化の dogfood 成功事例) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。`check-ci-coderabbit` 既存 crate への parse 機能追加 + analyze-coderabbit 連携。 - -#### 設計決定 (案) - -- **対象 source**: `gh api repos/{owner}/{repo}/pulls/{N}/reviews --jq '.[].body'` で取得する review.body markdown 文字列 -- **parse 対象セクション** (CR の出力フォーマットに準拠): - - `## Outside diff range comments` セクション内の bullet list (file:line 参照 + comment body) - - `## Caution` / `## Warning` セクション内の bullet (severity-marked findings) - - 行番号参照のある generic comment (regex: `\b(file|line)\s*[:=]\s*\d+|`L\d+`|`:`) -- **JSON schema 拡張**: 既存 `--list-findings` mode (順位 45) の出力に `source: "inline" | "review_body"` field を追加して同型 findings として扱う: - - ```json - { - "findings": [ - {"severity": "minor", "file": "docs/todo4.md", "line": 371, "summary": "...", "source": "review_body"} - ] - } - ``` - -- **analyze-coderabbit 連携**: 既存 `analyze-coderabbit` step が `--list-findings` 出力を取得する形になっていれば、source field を追加するだけで本 task の出力が自動的に下流に流れる -- **検出時の挙動**: inline findings と同じく severity 評価 → fix commit 追加 → resolve reply の通常 flow に乗る (本 task で flow 自体は変更しない) - -#### 作業計画 - -- [ ] `check-ci-coderabbit` 現状確認 (`--list-findings` mode が 順位 45 として実装済か、未実装なら本 task 着手前に 順位 45 を land) -- [ ] review.body 取得 API (`gh api .../pulls/{N}/reviews`) wrapper 実装 (既存の gh CLI wrapper が `src/check-ci-coderabbit/src/` にあれば再利用) -- [ ] markdown parser: `## Outside diff range comments` / `## Caution` / `## Warning` セクション抽出 + bullet 毎の file:line + body 抽出 -- [ ] JSON schema 拡張: `source` field 追加 (既存 schema は inline 想定なので default 値 `"inline"` で後方互換) -- [ ] test 拡充: 実 PR #108 の review.body を fixture 化 + parse 結果が期待 finding を返す test -- [ ] `analyze-coderabbit` 連携検証: source 別の handling が必要か (`outside-diff-range` の重み付けは inline と同等で進める想定) -- [ ] dogfood: 次 1-2 PR の post-pr-review で review.body finding が自動検出されることを観測 -- [ ] 派生プロジェクト deploy 検討 (`check-ci-coderabbit.exe` は本リポジトリ exe なので deploy で配布、scope 内) -- [ ] 本 todo7.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `check-ci-coderabbit --list-findings --pr 108` が PR #108 の outside-diff-range finding (line 371/378) を構造化 JSON で返す -- `source` field で inline vs review_body の区別が可能 -- `analyze-coderabbit` 連携で merge 前に outside-diff-range finding が actionable として扱われる -- 既存 inline finding 検出に regression なし -- `cargo test -p check-ci-coderabbit` pass - -#### 詰まっている箇所 - -- 順位 45 (`check-ci-coderabbit --list-findings` Rust モード) の land 状況確認が前提。未 land なら本 task 着手前に 順位 45 を先に進める -- CR 側 review.body フォーマットの変更耐性: section header (`## Outside diff range comments`) が CR の出力変更で変わる可能性がある。fail-soft 設計 (parse 失敗時は空 findings で続行 + warn log) で運用継続性を確保 -- false positive リスク: 行番号らしき文字列 (`L42` 等) が誤検出される可能性。CR 公式フォーマット section に限定した parse でリスク軽減 - ---- - +# 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-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### `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% 近くに抑える。 +> +> **Status update (2026-06-06)**: **採用案 C (`.takt/facets/instructions/fix.md` に refresh section 追加) は既に land 済** — entry 内 checklist `[x]` で完了表示 + `fix.md` に「Pre-completion diff refresh (REQUIRED)」section 確認。残るは **dogfood 観測** (PR D-6 merge + 1-2 PR の 6-iter outlier 非再発確認 + AI 実行率 > 90%) のみ。継続観測なら本 entry は **削除候補に近接**。次セッションで dogfood log を確認後、6-iter outlier が解消していれば即削除可。 +> +> **参照**: `.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 追加。Status update により実装は完了、残作業は dogfood 観測のみ。 + +#### 設計決定 (D-6 セッションで確定、2026-05-13) + +- **refresh タイミング**: fix step が `convergence_verdict` を emit する直前に refresh (= 次 reviewer iteration が読み始める時点で post-fix 状態) +- **実装方針 (3 案を評価)**: + - **案 A: takt workflow の reviewer step に precondition step を挟む** — ❌ **不可**。takt v0.35.3 schema (`PieceMovement` / `PieceConfig`) を確認した結果、per-step `before:` / `pre-step:` / `hooks:` field は存在しない。piece レベルの `runtime.prepare` は workflow 開始時 1 回のみ実行され、step 間に挟まらない (`node_modules/.pnpm/takt@0.35.3/node_modules/takt/dist/core/models/piece-types.d.ts` Line 74-98 / `runtime-environment.js` Line 171-191) + - **案 B: cli-push-runner 側で fix step の終了を検出して diff を更新** — ❌ **scope 不適合**。`stages/takt.rs` は `run_cmd_inherit` で takt を spawn-and-wait するのみ。filesystem watcher で `.takt/runs//reports/*.md` の生成を監視する案は ~100-200 行の Rust + race condition 対応が必要で、AI-driven 案で塞げる範囲を超える複雑度 + - **案 C: fix.md instruction に "Pre-completion diff refresh" section を追加** — ✅ **採用**。既存の Bundle Z #B-β `Pre-completion deterministic check (Bundle Z Phase 2 / #B-β)` と同形の precedent あり (`scripts/fix-metrics-check.ps1` を Bash 呼び出しする pattern)。失敗 mode (= AI が refresh を skip) は現状と同等 (no regression) +- **採用案 C の実装**: `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 (advisor 推奨)。`jj diff -r @ > .takt/review-diff.txt` を `convergence_verdict` emit 直前に必須実行 +- **共有 instruction の影響**: `fix.md` は pre-push-review.yaml と post-pr-review.yaml の両方で使用される。post-pr-review は `.takt/review-diff.txt` を読まないが、refresh は冪等で副作用なし (~1s 程度の `jj diff` invocation cost のみ) +- **派生プロジェクト deploy**: `scripts/deploy-hooks.ts` は exe + `settings.local.json` のみ転送し、`.takt/facets/instructions/*` は派生 (techbook-ledger / auto-review-fix-vc) 各自が管理。よって本変更の自動 propagate は不要 (手動 port が必要だが scope 外、follow-up task) + +#### 作業計画 + +- [x] takt workflow の hook 仕様を確認 → 案 A 不可と確定 +- [x] cli-push-runner の takt invocation 構造を確認 → 案 B も scope 不適合と確定 +- [x] advisor に方針相談 → 案 C (instruction-level) 採用 + 共有 instruction 影響 / deploy 経路を検証 +- [x] `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 +- [ ] dogfood: D-6 PR push 自体で本 instruction が機能するかを観察 (fix step が refresh を実行 → 次 reviewer iter が post-fix 状態を読むか) +- [ ] dogfood 1〜2 PR で実 6-iter outlier scenario が再発しないことを観測 +- [x] Bundle Z #B-β との競合確認: `fix-metrics-check.ps1` invocation は fix step 内部の Bash 実行で完結し、本 task の diff refresh は同 fix step の最終段 Bash 実行で独立。両者は時系列で順序通り走り競合なし +- [ ] 本 todo7.md エントリを削除 (PR D-6 merge + 1-2 PR の dogfood 完了後) + +#### 完了基準 + +- 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 救済責務が消える) + +#### 残課題 / dogfood リスク + +- AI-driven 案の弱点: fix step の AI が refresh 命令を skip する可能性。Bundle Z #B-β `metrics_check` invocation の実行率を baseline として比較し、refresh 実行率 > 90% を初期目標とする。dogfood で実行率 < 90% なら **案 D (PostToolUse hook ベースの決定論層)** へ escalate を検討 +- 派生プロジェクト port: `~/.takt/facets/instructions/fix.md` (global) や techbook-ledger / auto-review-fix-vc の同等ファイルへの転載が follow-up task (本 task scope 外) + +--- + +### 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 を読むので効果は残る。 + +--- + +### 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 を追加 + +--- + +### `check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25) + +> **動機**: PR #108 で CodeRabbit が `Outside diff range comment` として review body 内に投稿した Minor finding (`docs/todo4.md` line 371/378 の retire 済前提と旧フロー混在) を、takt の `analyze-coderabbit` step が検出漏れした。`analyze-coderabbit` は `pulls/N/comments` (= inline review comment) ベースで動作するため、review.body 内のコメントは parse 対象外。結果、PR #108 で line 371/378 の修正が merge 後 follow-up commit (`vokyspww`) になった。 +> +> 当初計画では暫定緩和策として **手動 checklist** (post-PR フローに目視確認 step) を追加する rule 化方針だったが、PR #172 で「rule 化は session 毎に読み込みコストがかかり、人間が忘れる」課題が顕在化。仕組み化 (`check-ci-coderabbit` 拡張で programmatic 検出) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。当初 Tier 1 として位置づけていた analyzer 拡張を本 task で先行実施する形。 +> +> **本タスクの位置づけ**: PR #108 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。手動 checklist の根本解決 = 検出漏れを programmatic に消滅させる。手動 step が持続性低い (= 人間が忘れる) ため、CLI 拡張で session 跨いだ品質一定化が確保される。 +> +> **参照**: `.claude/feedback-reports/108.md` Tier 2 #1、PR #108 review (`Outside diff range comments` セクション、reviewer comment id 4217897113)、`src/check-ci-coderabbit/src/main.rs` (`parse_findings` 系 + `--list-findings` mode = 順位 45)、`.takt/facets/instructions/analyze-coderabbit.md`、PR #172 (順位 144 hook 化の dogfood 成功事例) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。`check-ci-coderabbit` 既存 crate への parse 機能追加 + analyze-coderabbit 連携。 + +#### 設計決定 (案) + +- **対象 source**: `gh api repos/{owner}/{repo}/pulls/{N}/reviews --jq '.[].body'` で取得する review.body markdown 文字列 +- **parse 対象セクション** (CR の出力フォーマットに準拠): + - `## Outside diff range comments` セクション内の bullet list (file:line 参照 + comment body) + - `## Caution` / `## Warning` セクション内の bullet (severity-marked findings) + - 行番号参照のある generic comment (regex: `\b(file|line)\s*[:=]\s*\d+|`L\d+`|`:`) +- **JSON schema 拡張**: 既存 `--list-findings` mode (順位 45) の出力に `source: "inline" | "review_body"` field を追加して同型 findings として扱う: + + ```json + { + "findings": [ + {"severity": "minor", "file": "docs/todo4.md", "line": 371, "summary": "...", "source": "review_body"} + ] + } + ``` + +- **analyze-coderabbit 連携**: 既存 `analyze-coderabbit` step が `--list-findings` 出力を取得する形になっていれば、source field を追加するだけで本 task の出力が自動的に下流に流れる +- **検出時の挙動**: inline findings と同じく severity 評価 → fix commit 追加 → resolve reply の通常 flow に乗る (本 task で flow 自体は変更しない) + +#### 作業計画 + +- [ ] `check-ci-coderabbit` 現状確認 (`--list-findings` mode が 順位 45 として実装済か、未実装なら本 task 着手前に 順位 45 を land) +- [ ] review.body 取得 API (`gh api .../pulls/{N}/reviews`) wrapper 実装 (既存の gh CLI wrapper が `src/check-ci-coderabbit/src/` にあれば再利用) +- [ ] markdown parser: `## Outside diff range comments` / `## Caution` / `## Warning` セクション抽出 + bullet 毎の file:line + body 抽出 +- [ ] JSON schema 拡張: `source` field 追加 (既存 schema は inline 想定なので default 値 `"inline"` で後方互換) +- [ ] test 拡充: 実 PR #108 の review.body を fixture 化 + parse 結果が期待 finding を返す test +- [ ] `analyze-coderabbit` 連携検証: source 別の handling が必要か (`outside-diff-range` の重み付けは inline と同等で進める想定) +- [ ] dogfood: 次 1-2 PR の post-pr-review で review.body finding が自動検出されることを観測 +- [ ] 派生プロジェクト deploy 検討 (`check-ci-coderabbit.exe` は本リポジトリ exe なので deploy で配布、scope 内) +- [ ] 本 todo7.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `check-ci-coderabbit --list-findings --pr 108` が PR #108 の outside-diff-range finding (line 371/378) を構造化 JSON で返す +- `source` field で inline vs review_body の区別が可能 +- `analyze-coderabbit` 連携で merge 前に outside-diff-range finding が actionable として扱われる +- 既存 inline finding 検出に regression なし +- `cargo test -p check-ci-coderabbit` pass + +#### 詰まっている箇所 + +- 順位 45 (`check-ci-coderabbit --list-findings` Rust モード) の land 状況確認が前提。未 land なら本 task 着手前に 順位 45 を先に進める +- CR 側 review.body フォーマットの変更耐性: section header (`## Outside diff range comments`) が CR の出力変更で変わる可能性がある。fail-soft 設計 (parse 失敗時は空 findings で続行 + warn log) で運用継続性を確保 +- false positive リスク: 行番号らしき文字列 (`L42` 等) が誤検出される可能性。CR 公式フォーマット section に限定した parse でリスク軽減 + +--- + diff --git a/docs/todo8.md b/docs/todo8.md index c43fae67..3a4bab9c 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -1,312 +1,312 @@ -# TODO (Part 8) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #143 T3-#1 採用時 = 2026-05-11 から新規エントリは本ファイルに記録していた。**本ファイルも 60KB に到達したため、PR #172 仕組み化方針切替セッション = 2026-05-25 以降の新規エントリは [docs/todo9.md](todo9.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md / todo7.md / todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### rule⑧ への paths filter 適用範囲検討 (順位 102 land 時に意図的保留、follow-up) - -> **動機**: 順位 102 (PR #148 想定で land 中、Phase D D-3) で paths filter が lint runner に実装されたが、当初計画した rule⑧ への `paths = ["docs/**/*.md"]` migration は **意図的に保留**。理由: D-2 (PR #146、順位 101) で追加した「root-level MD (CLAUDE.md / README.md) からの `../docs/` 参照を fire = true positive で扱う」design intent が、`paths = ["docs/**/*.md"]` 適用で scope narrow されて壊れる (root-level MD の実 path が docs/ 配下ではないため rule 対象外になり、broken link 検出を失う)。本タスクで以下のいずれを採用するか検討する: -> -> 1. **保留継続** (現状維持): rule⑧ は `extensions = ["md"]` のみで run、root-level fire を保護 -> 2. **broader glob**: `paths = ["**/*.md"]` で全 .md 受容 (= extensions filter と機能的同等、demonstration 用途) -> 3. **explicit list**: `paths = ["docs/**/*.md", "*.md", ".claude/**/*.md"]` で docs/ + root + .claude/ をカバー -> 4. **rule split**: rule⑧-docs (docs/ scope) + rule⑧-root (root scope) に分割 -> -> **本タスクの位置づけ**: 順位 102 follow-up (Severity Low / Frequency Low = 1 観測 / Effort XS / Adoption Risk None)。実 production lint behavior に影響しない range で trade-off 評価。 -> -> **参照**: PR #148 (順位 102 land) の TOML rule⑧ コメント、PR #146 (D-2、順位 101) の `md_no_docs_relative_detects_root_*` tests - -#### 作業計画 - -- [ ] 4 案の trade-off を ADR-007 amendment (順位 104) と整合させて評価 -- [ ] 採用案を `.claude/custom-lint-rules.toml` rule⑧ に適用 (案 1 保留継続なら no-op だが、本エントリ削除で結論明示) -- [ ] 既存 test (`md_no_docs_relative_*` group) との整合性確認 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- rule⑧ scope の設計判断が ADR-007 amendment と本タスク entry で明確化される -- 同型 trade-off (filter scope narrow vs coverage 保持) を将来 rule 追加時に逆引きできる - ---- - -### `coding-style.md § Cross-File Reference Lifecycle` に「ephemeral → permanent 知識移管 edit order」追記 (PR #145 T3-#3 採用) - -> **動機**: PR #145 で lib.rs L128-139 dogfood evolution コメントを ADR-040 に migrate した際、edit 順序が曖昧だった (ADR-040 を先に作るべきか、lib.rs 側の参照削除を先にすべきか)。同パターンが (1) lib.rs コメント → ADR-040、(2) Phase C/D empirical data → ADR-040 で 2 回観測。既存の Cross-File Reference Lifecycle ルール は「参照方向の制約」(permanent → ephemeral 禁止) に特化しており、移管作業の edit order checklist は complementary で重複なし。次回同型の永続化作業 (ephemeral 計画書 retire 時の permanent value 移管 等) で再発防止策として codify する。 -> -> **本タスクの位置づけ**: PR #145 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/145.md` Tier 3 #3、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle - -#### 提案する 3 ステップ原則 - -1. **permanent target 先行作成・validate**: 移管先の permanent artifact (ADR / stable docs) を先に作成し、内容の正確性 (cross-reference の妥当性 / 数値整合性 / markdownlint pass) を確認 -2. **参照追加**: ephemeral 側 (lib.rs コメント / config コメント / scratch markdown 等) から permanent への参照 link を追加 (1-2 行) -3. **参照元削除**: ephemeral 側の冗長な内容を削除し、参照 link のみ残す。同一 commit で 3 step すべてを実施 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle 末尾に「ephemeral → permanent 知識移管 edit order」 subsection を追加 -- [ ] 3 ステップ原則を inline で記述、PR #145 (lib.rs L128-139 → ADR-040) を実例として cite -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 計画も検討 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回 permanent 化作業時に edit order が決定論的に決まる -- ephemeral 計画書 retire 時の permanent value 移管プロセスが checklist 化される - ---- - -### CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用) - -> **動機**: PR #153 で旧 `docs/local-llm-offload-analysis.md` を `phase-d-outcomes.md` に分割した際 (3 ファイルは Phase E 採用昇格 = 2026-05-15 に retire 済)、retirement clause を **3 ファイル (analysis.md / history.md / phase-d-outcomes.md) 同時削除** に統一する作業が developer/AI の手動 review でしか担保されていなかった。advisor 指摘で明示的に「3 ファイルすべてに同じ retirement clause を書く」ステップを踏んだが、これは structural pattern として再利用可能 (今後の docs/* 50KB 分割でも同じ checklist が必要)。同パターンが drift すると ephemeral artifact の lifecycle 整合が崩れ、stale pointer が増殖するリスクあり。 -> -> **本タスクの位置づけ**: PR #153 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。**既存実践 (PR #133 todo.md 分割 + PR #153 analysis.md 分割) の明文化 + 機械強制ではなく guide 効果** のため、`feedback_no_unenforced_rules.md` の例外条件 (順位 122 / 127 と同じロジック) を満たす。 -> -> **参照**: `.claude/feedback-reports/153.md` Tier 3 #2、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow - -#### 作業計画 - -- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に「多ファイル同時削除時の retirement condition consistency checklist」section を追加 (3-5 項目程度の bullet list) - - 「N ファイルを同時削除する設計の場合、全 N ファイルの header に同一の retirement clause が記載されているか」 - - 「retirement workflow の Step 3 (参照更新) で `grep -rn ''` を全ファイル分実施したか」 - - 「新ファイル追加時に既存ファイルの retirement clause にも追記したか」 - - 「参照先 (ADR / docs-governance.md) が permanent artifact であることを確認」 -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 -- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回多ファイル分割 (例: history.md 50KB 接近時) で同 checklist を踏むことで drift が構造的に防止される -- PR #133 (todo.md 分割) / PR #153 (analysis.md 分割) の successful pattern が明文化され、3 例目以降の reproducibility が確保される - ---- - -### docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = 必ず grep で実ファイル確認」を明記 (PR #156 T3 #1 採用) - -> **動機**: PR #156 で ephemeral 4 ファイル retire を実施した際、`grep` 結果に含まれる **diff context 行が実ファイルの最新内容ではなく PR 直前の状態を反映する** ため、削除対象ファイルへの参照が「残存」と誤検出される false alarm が 5 件以上発生。fact-check の grep 実行に時間を要した。XS の文言追加で将来セッションの reviewer / Claude が同一の確認コストを繰り返すことを防止できる。ephemeral 退役ワークフローは今後も繰り返されるため Frequency Medium。 -> -> **本タスクの位置づけ**: PR #156 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 例外条件 = 既存実践の明文化 + guide 効果のため採用 (順位 122 / 127 と同じロジック)。 -> -> **参照**: `.claude/feedback-reports/156.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` §Retirement Workflow - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` §Retirement Workflow の Step 3 (参照更新) に「diff context 由来 false alarm 防止」note 追加 (2-3 行) - - 「`grep -rn ''` で hit した参照は **必ず該当ファイルを Read で開き、最新内容に対象参照が実在することを確認** する。diff context は PR 直前の旧状態を反映するため、retire 対象ファイルへの参照が context として残存しているように見えても、現行 working copy では既に削除されている場合がある」 - - 具体例: PR #156 (4 ファイル同時 retire) で 5 件以上の false alarm が発生 -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 -- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回 ephemeral 退役 workflow で同 false alarm が発生しても、明文化された手順により fact-check の認知コストが低減する -- guide として PR review / Claude session 双方で参照可能 - -#### 詰まっている箇所 - -なし。Effort XS、global rule への追記のみで副作用最小。 - ---- - -### todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来) - -> **動機**: 順位 78 (旧 ADR-038 Rust timestamp arithmetic safety、PR #115 T3-1) は entry 登録時 (2026 年序盤) に新規 ADR として ADR-038 を予約のつもりで hardcode していたが、queue 滞留中に Bundle Z 系列の連続採用で `ADR-037 / 038 / 039 / 040` がすべて占有され、2026-05-16 セッションで番号 conflict が顕在化 (ADR-041 へ振り直し)。さらに 2026-05-22 に順位 139 (PR #168 follow-up) が ADR-041 を取得したため順位 78 を再 placeholder 化 = **同一 entry が 3 回 (038 → 041 → NNN) 番号変更を経た実証ベース**で、queue 深度と滞留期間の積に比例して同型 conflict が再発する構造リスクを convention で予防する必要がある。 -> -> **本タスクの位置づけ**: 順位 78 振り直し対応の **再発防止 convention**。採番予約簿 (`docs/adr/RESERVED.md` 等) は管理コストが過剰なため見送り、entry 登録時は placeholder で済ませて land 時の PR で空き番号を確定する運用に統一する (作業着手時に採番するだけの軽量運用、ユーザー判断 2026-05-16)。 -> -> **参照**: 順位 78 entry ([docs/todo5.md](todo5.md) § ADR-NNN Rust timestamp arithmetic safety + CLAUDE.md security 拡充)、`~/.claude/rules/common/docs-governance.md` -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule に 2-3 行追記。 - -#### 設計決定 (案) - -- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Document Lifecycle Classification` 周辺、もしくは新規 `## ADR 採番の運用` section -- **追記内容案** (2-3 行): - - todo entry / planning markdown で新規 ADR を予告する際は、番号を hardcode せず **`ADR-NNN (採番未確定、land 時に確定)`** placeholder で記述する - - land 時の PR で `docs/adr/` を確認し空き番号を確定。同時に当該 entry / markdown / table 内の placeholder を実番号に置換 - - 採番予約簿の運用は行わない (queue 滞留 entry の管理コストが回収可能性に見合わない) -- **本タスクの効果**: queue 滞留 entry が後発 PR の採番と衝突する構造リスクを convention で予防、作業着手時の軽量採番で十分運用可能 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` に上記 placeholder 採用方針を 2-3 行追記 -- [ ] 既存 todo entries 内に他の hardcode された ADR 予告番号が残っていないか `grep -rn 'ADR-[0-9]\+ (新規)' docs/` 等で確認 (順位 78 振り直し後の漏れ検出) -- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `docs-governance.md` に ADR 番号 hardcode 撤廃方針が明記される -- 将来 todo entry で新規 ADR を予告する際に placeholder 形式が convention として参照可能 -- 既存 todo に他の hardcode 予告番号が残っていないことが grep で確認される - -#### 詰まっている箇所 - -- ルール追加自体は機械検知不可だが、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + 簡素な代替手順を提示。grep ベースの後付け検証も容易 (`grep -nE 'ADR-[0-9]+ \(新規\)' docs/`) - ---- - -### ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment (PR #169 T3-#2 採用) - -> **動機**: 順位 135 で codify された「ADR 番号は entry 登録時に hardcode せず `ADR-NNN (採番未確定)` placeholder で記述し、land 時 PR で空き番号を確定する」運用が、PR #111 / PR #132 / PR #169 の **3+ PR で適用実証済**になった。特に PR #169 では同一 entry (順位 78) が `ADR-038 → 041 → NNN` の **3 段振り直し** を経た live dogfood が完了し、queue 滞留 entry と後発 PR の採番衝突を convention 層で完全予防できる状態が確立された。現在 policy は `~/.claude/rules/common/docs-governance.md` の 2-3 行追記として ephemeral todo (順位 135) 内で codify されているが、ephemeral artifact 限りでは派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への transferability に欠ける。正式 ADR に昇格して永続化する。 -> -> **本タスクの位置づけ**: PR #169 post-merge-feedback Tier 3 #2 採用。`feedback_no_unenforced_rules.md` の例外 = 既存実践 (3 PR で実証済) の明文化 + multi-PR race-freedom rationale + history の codify。Severity Low / **Frequency Medium (PR #111/#132/#169 の 3+ PR で適用実証)** / Effort S / Adoption Risk None。 -> -> **参照**: `.claude/feedback-reports/169.md` Tier 3 #2、順位 135 entry (`docs/todo8.md` 内、本 ADR 昇格後に retire 候補)、`~/.claude/rules/common/docs-governance.md` (現状 codify 先)、PR #111 / PR #132 / PR #169 history -> -> **実行優先度**: 💎 **Tier 3** — Effort S。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記 + 順位 135 entry retire (= todo8.md から削除)。 - -#### ADR 番号 - -順位 135 codified policy 自身に従い、本 entry では番号を `ADR-NNN (採番未確定)` placeholder とする (= dogfood 自己適用)。**land 時 PR で空き番号を確定**する (現時点既存: ADR-041 まで確定、ADR-NNN slot は順位 78 で「Rust timestamp arithmetic safety」用に予約中)。本 entry が順位 78 より先に land する場合は次の空き番号を本件に割り当て、順位 78 の placeholder は維持。 - -#### 設計決定 (案) - -- **ADR タイトル候補**: `ADR-NNN: ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment` (内容を反映、派生プロジェクトでも理解可能な英文タイトル) -- **内容構成**: - - **コンテキスト**: queue 滞留 entry の ADR 番号 hardcode が後発 PR の採番と衝突する構造リスク。PR #111/#132/#169 の history (順位 78 が `ADR-038 → 041 → NNN` の 3 段振り直しを経た live dogfood) - - **決定**: ① entry 登録時は `ADR-NNN (採番未確定、land 時に確定)` placeholder で記述、② land 時 PR で `docs/adr/` の空き番号を確定、③ 同一 PR で当該 entry / markdown / table 内 placeholder を実番号に同時置換、④ 採番予約簿 (`RESERVED.md` 等) は導入しない (queue 滞留 entry の管理コストが回収可能性に見合わない) - - **帰結**: queue 滞留期間と queue 深度の積に比例する番号衝突リスクが convention 層で予防される。派生プロジェクトでも同 policy を採用すれば multi-PR race-freedom が確保される。コスト: entry 著者は placeholder を維持する規律が必要、land 時 PR では multi-point sync (todo + ADR + CLAUDE.md) を同 commit で揃える必要 - - **適用範囲**: 全 ADR (試験運用 / 永続採用問わず)。既存 ADR (ADR-001〜ADR-041) には遡及適用しない - - **既存資料との関係**: `~/.claude/rules/common/docs-governance.md` の 2-3 行追記 (順位 135 で codified 予定) を ADR で補完する layer。global rule は entry author への 1-line guidance、ADR は派生プロジェクトを含む reference layer -- **CLAUDE.md ADR list 追加**: project-local の Architecture Decisions list に link 追記 -- **順位 135 entry retire**: 本 ADR で内容を完全 codify した時点で順位 135 を todo8.md から削除 (ephemeral → permanent への migration、`feedback_todo_no_history` 適用) - -#### 作業計画 - -- [ ] `docs/adr/adr-NNN-adr-numbering-strategy.md` を新規作成 (番号は land 時 PR で確定) -- [ ] 内容構成 (上記 5 項目) を記述 -- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 (番号確定時) -- [ ] 順位 135 entry を todo8.md から削除 (本 ADR が retire 先になる) -- [ ] PR description で `docs/adr/adr-NNN-adr-numbering-strategy.md` への link と「順位 135 内容を permanent ADR に migrate、派生プロジェクト transferability 確保」要約を明記 (PR 作成時) - -#### 完了基準 - -- ADR ファイルが新規作成され、PR #111/#132/#169 の history + placeholder policy + multi-PR race-freedom rationale が記述される -- CLAUDE.md の ADR リストに該当 entry が追加される -- 順位 135 entry が todo8.md から削除される -- 次回 ADR 採番が必要な entry を書く際の reference として global rule (docs-governance.md) から本 ADR にリンク可能になる - -#### 詰まっている箇所 - -なし。記述のみで実装変更不要。順位 135 と内容重複しないよう「global rule = 1-line entry author guidance / ADR = full rationale + history + transferability」で役割分離を明示する。 - ---- - - -### 複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171 - -> **動機**: PR #151 (`byte_offset_to_line` char-boundary panic 発見) + PR #171 (`build_violation_json` defensive test 追加) の 2 PR 横断で multi-byte content fixture を手動で組み立てるコストが顕在化。Japanese / emoji / combining chars の各 sample を helper として標準化することで、新規 string-processing 関数追加時の boundary test 実装コストを低減し silent regression を early detection できる。 -> -> **本タスクの位置づけ**: PR #171 post-merge-feedback Tier 2 #4 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。Bundle 171 のコア (順位 142 ADR-041 補強 + 順位 144 jj hook と同 PR で land 推奨)。 -> -> **参照**: `.claude/feedback-reports/171.md` Tier 2 #4、`src/hooks-post-tool-linter/src/main.rs` (`run_custom_rules_line_number_correct_with_multibyte_content` を helper 化対象)、PR #151 / PR #171 -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。Bundle 171 ペアタスク。 - -#### 設計決定 (案) - -- **helper API** (3 関数): - - `multibyte_fixture_japanese() -> &'static str` — 3 bytes/char (例: `// 日本語コメント`) - - `multibyte_fixture_emoji() -> &'static str` — 4 bytes/char (例: `// 🦀 rust`) - - `multibyte_fixture_combining() -> &'static str` — e + U+0301 結合文字 (例: `// caf\u{00e9}`) -- **配置先候補**: `src/hooks-post-tool-linter/src/main.rs` の test mod 内 (in-crate) vs 共有 test util crate (cross-crate 再利用)。本タスクでは前者を採用し、再利用ニーズが顕在化したタイミングで後者へ migrate -- **既存 test refactor**: PR #171 で追加した `run_custom_rules_line_number_correct_with_multibyte_content` を helper を呼ぶ形に書き換え - -#### 作業計画 - -- [ ] helper 配置先決定 (in-crate test mod を優先採用) -- [ ] 3 helper 関数を実装 (Japanese / emoji / combining) -- [ ] PR #171 で追加した既存 test を helper を使う形に refactor -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 考慮 (in-crate なら porting 容易) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 3 helper 関数が公開され、test mod 内から呼べる -- 既存 test の refactor 完了 (動作不変、`cargo test` pass) -- 新規 string-processing 関数追加時に 1 行で multi-byte boundary test を書ける状態になる - -#### 詰まっている箇所 - -なし。Effort S、Bundle 171 内で 順位 142 + 順位 144 と並列実施可能。 - ---- - -### preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用) - -> **動機**: PR #172 で `jj-message-required` preset 実装の Phase 3 において、当初 `is_blocked("jj new")` (default config 使用) で block を assert する test を書いたが、`jj-message-required` が `default_preset_names()` の fallback list に含まれない opt-in preset であることを前提とせず、test rewrite が必要になった。preset architecture の implicit assumption (always-enabled vs config-selectable) を test 設計レベルで codify することで、将来の新 preset 追加時の design misalignment を構造的に防止する。 -> -> **本タスクの位置づけ**: PR #172 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。matrix test で preset 分類を明示する mechanical enforcement 層を追加。 -> -> **参照**: `.claude/feedback-reports/172.md` Tier 2 #1、`src/hooks-pre-tool-validate/src/main.rs` の `default_preset_names()` + test module、PR #172 Phase 3 (test rewrite 経緯) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。Bundle 171 残タスク (順位 142 + 143) との並列実施可能。 - -#### 設計決定 (案) - -- **配置先**: `src/hooks-pre-tool-validate/src/main.rs` の test module (feedback report は lib.rs と記載するが本 crate は binary crate のため main.rs を採用) -- **matrix 構成** (2 軸): - - axis 1: `default fallback (always-enabled)` vs `config-selectable (opt-in)` - - axis 2: 各 preset 名 -- **classification 期待値** (本セッション時点): - - always-enabled (`default_preset_names()` 内): `default` / `git` / `jj-immutable` / `jj-main-guard` / `jj-push-guard` / `electron` - - config-selectable: `gh-pr-create-guard` / `gh-pr-merge-guard` / `polling-anti-pattern` / `exe-help-block` / `jj-message-required` -- **test 案**: - - `preset_default_fallback_classification`: 各 always-enabled preset 名が `default_preset_names()` の return に含まれることを assert - - `preset_config_selectable_opt_in_classification`: 各 config-selectable preset 名が `default_preset_names()` に含まれないことを assert - - `preset_matrix_full_coverage`: 既知 preset 名の全集合が classification 表 (always-enabled ∪ config-selectable) と一致することを assert (= 新 preset 追加時に matrix 更新を強制) - -#### 作業計画 - -- [ ] preset 分類表を const として定義 (`ALWAYS_ENABLED_PRESETS` + `CONFIG_SELECTABLE_PRESETS`) -- [ ] matrix test 関数 3 件追加 (default fallback / config-selectable / full coverage) -- [ ] 既存 test (`default_config_enables_all_presets` / `jj_message_required_not_in_default_fallback_is_opt_in` 等) との重複整理 (削除 or matrix への移行) -- [ ] `resolve_preset_or_custom` の dispatch arm 列挙との整合性確認 (matrix の preset 名 = dispatch arm 名) -- [ ] 派生プロジェクト transferability 考慮 (porting 時に preset 分類を即把握できる) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- preset の分類 (always-enabled vs config-selectable) が test レベルで codify される -- 将来の新 preset 追加時に classification 表を更新せざるを得ない構造になり、design misalignment が構造的に検出される -- 既存 test (158 件) との regression なし -- `resolve_preset_or_custom` の arm 列挙との不整合 (preset 追加忘れ等) が test で catch される - -#### 詰まっている箇所 - -- feedback report は target を `src/hooks-pre-tool-validate/src/lib.rs` と記載するが、本 crate は binary crate (main.rs のみ) で lib.rs は存在しない → main.rs を採用 (target 是正) -- 「config-selectable preset 名が default に含まれない」test は `jj_message_required_not_in_default_fallback_is_opt_in` で 1 件既存。matrix 化で全 5 preset に拡張する - ---- - -## 既知課題 (記録のみ、本セッションで未対応) - -### post-merge-feedback workflow が長時間 stale marker を残す問題 (PR #119 marker observed 2026-05-15) - -> **観測**: 2026-05-15 セッション開始時、`.claude/feedback-reports/119.md.failed` marker が **606,269 秒 (約 7 日)** 経過した状態で UserPromptSubmit hook により検出。PR #119 (ADR-038 Phase 5: cli-finding-classifier 統合) のマージ後に起動した post-merge-feedback workflow (run id `20260506-141736-post-merge-feedback-for-119`) が abrupt 終了 (kill -9 / SIGKILL / power loss / OOM 等) で中断され、Drop guard 経路を経由せず orphan reaper の 1500 秒閾値も大幅に超過した state で marker が残存。 -> -> **解釈**: 単発事象として記録のみ留め、即時手動 recovery (`pnpm exec takt -w post-merge-feedback -t 'post-merge-feedback for #119'`) は実施しない (PR #119 は 7 日前 land 済で、対応するレビュー知見は後続 PR で既に消化済の可能性が高い)。次回 stale marker の自然 cleanup 機構 (ADR-030 §L2 orphan reaper / D-7 / 順位 64) の dogfood で本 marker も同時に reap されるかを観察する材料として残す。 -> -> **本タスクの位置づけ**: **既知課題のみ、todo 着手は予定なし**。merge pipeline の長期化 / abrupt 終了が原因と推定されるが、systemic な再発 (Frequency Medium 以上) を確認するまで実装側の改修は scope 外。Bundle c-1 (PR #154、L1 Drop guard + L2 reaper) で recovery 機構自体は実装済のため、本 marker は単に「reaper 投入前に取り残された artifact」として扱う。 -> -> **参照**: `.claude/feedback-reports/119.md.failed`、ADR-030 §L1/L2 spec、Bundle c-1 (PR #154、L2 orphan reaper の本セッションでの初回完全 dogfood) - -#### 想定される追加観察項目 (Frequency が上がった場合に着手) - -- abrupt 終了 (Drop guard 不発) の root cause: takt subprocess 階層のどこで SIGKILL が起きたか (cli-merge-pipeline / takt 本体 / Claude Code session 終了 etc.) の事後 forensic -- L2 orphan reaper が古い marker をどう扱うか (immediate cleanup vs warn-only vs leave alone) の policy 評価 -- 7 日経過 marker を Claude Code セッション開始時に毎回提示するべきか (UserPromptSubmit hook の signal-to-noise) の検討 - ---- +# TODO (Part 8) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #143 T3-#1 採用時 = 2026-05-11 から新規エントリは本ファイルに記録していた。**本ファイルも 60KB に到達したため、PR #172 仕組み化方針切替セッション = 2026-05-25 以降の新規エントリは [docs/todo9.md](todo9.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md / todo7.md / todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### rule⑧ への paths filter 適用範囲検討 (順位 102 land 時に意図的保留、follow-up) + +> **動機**: 順位 102 (PR #148 想定で land 中、Phase D D-3) で paths filter が lint runner に実装されたが、当初計画した rule⑧ への `paths = ["docs/**/*.md"]` migration は **意図的に保留**。理由: D-2 (PR #146、順位 101) で追加した「root-level MD (CLAUDE.md / README.md) からの `../docs/` 参照を fire = true positive で扱う」design intent が、`paths = ["docs/**/*.md"]` 適用で scope narrow されて壊れる (root-level MD の実 path が docs/ 配下ではないため rule 対象外になり、broken link 検出を失う)。本タスクで以下のいずれを採用するか検討する: +> +> 1. **保留継続** (現状維持): rule⑧ は `extensions = ["md"]` のみで run、root-level fire を保護 +> 2. **broader glob**: `paths = ["**/*.md"]` で全 .md 受容 (= extensions filter と機能的同等、demonstration 用途) +> 3. **explicit list**: `paths = ["docs/**/*.md", "*.md", ".claude/**/*.md"]` で docs/ + root + .claude/ をカバー +> 4. **rule split**: rule⑧-docs (docs/ scope) + rule⑧-root (root scope) に分割 +> +> **本タスクの位置づけ**: 順位 102 follow-up (Severity Low / Frequency Low = 1 観測 / Effort XS / Adoption Risk None)。実 production lint behavior に影響しない range で trade-off 評価。 +> +> **参照**: PR #148 (順位 102 land) の TOML rule⑧ コメント、PR #146 (D-2、順位 101) の `md_no_docs_relative_detects_root_*` tests + +#### 作業計画 + +- [ ] 4 案の trade-off を ADR-007 amendment (順位 104) と整合させて評価 +- [ ] 採用案を `.claude/custom-lint-rules.toml` rule⑧ に適用 (案 1 保留継続なら no-op だが、本エントリ削除で結論明示) +- [ ] 既存 test (`md_no_docs_relative_*` group) との整合性確認 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- rule⑧ scope の設計判断が ADR-007 amendment と本タスク entry で明確化される +- 同型 trade-off (filter scope narrow vs coverage 保持) を将来 rule 追加時に逆引きできる + +--- + +### `coding-style.md § Cross-File Reference Lifecycle` に「ephemeral → permanent 知識移管 edit order」追記 (PR #145 T3-#3 採用) + +> **動機**: PR #145 で lib.rs L128-139 dogfood evolution コメントを ADR-040 に migrate した際、edit 順序が曖昧だった (ADR-040 を先に作るべきか、lib.rs 側の参照削除を先にすべきか)。同パターンが (1) lib.rs コメント → ADR-040、(2) Phase C/D empirical data → ADR-040 で 2 回観測。既存の Cross-File Reference Lifecycle ルール は「参照方向の制約」(permanent → ephemeral 禁止) に特化しており、移管作業の edit order checklist は complementary で重複なし。次回同型の永続化作業 (ephemeral 計画書 retire 時の permanent value 移管 等) で再発防止策として codify する。 +> +> **本タスクの位置づけ**: PR #145 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/145.md` Tier 3 #3、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle + +#### 提案する 3 ステップ原則 + +1. **permanent target 先行作成・validate**: 移管先の permanent artifact (ADR / stable docs) を先に作成し、内容の正確性 (cross-reference の妥当性 / 数値整合性 / markdownlint pass) を確認 +2. **参照追加**: ephemeral 側 (lib.rs コメント / config コメント / scratch markdown 等) から permanent への参照 link を追加 (1-2 行) +3. **参照元削除**: ephemeral 側の冗長な内容を削除し、参照 link のみ残す。同一 commit で 3 step すべてを実施 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle 末尾に「ephemeral → permanent 知識移管 edit order」 subsection を追加 +- [ ] 3 ステップ原則を inline で記述、PR #145 (lib.rs L128-139 → ADR-040) を実例として cite +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 計画も検討 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回 permanent 化作業時に edit order が決定論的に決まる +- ephemeral 計画書 retire 時の permanent value 移管プロセスが checklist 化される + +--- + +### CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用) + +> **動機**: PR #153 で旧 `docs/local-llm-offload-analysis.md` を `phase-d-outcomes.md` に分割した際 (3 ファイルは Phase E 採用昇格 = 2026-05-15 に retire 済)、retirement clause を **3 ファイル (analysis.md / history.md / phase-d-outcomes.md) 同時削除** に統一する作業が developer/AI の手動 review でしか担保されていなかった。advisor 指摘で明示的に「3 ファイルすべてに同じ retirement clause を書く」ステップを踏んだが、これは structural pattern として再利用可能 (今後の docs/* 50KB 分割でも同じ checklist が必要)。同パターンが drift すると ephemeral artifact の lifecycle 整合が崩れ、stale pointer が増殖するリスクあり。 +> +> **本タスクの位置づけ**: PR #153 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。**既存実践 (PR #133 todo.md 分割 + PR #153 analysis.md 分割) の明文化 + 機械強制ではなく guide 効果** のため、`feedback_no_unenforced_rules.md` の例外条件 (順位 122 / 127 と同じロジック) を満たす。 +> +> **参照**: `.claude/feedback-reports/153.md` Tier 3 #2、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow + +#### 作業計画 + +- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に「多ファイル同時削除時の retirement condition consistency checklist」section を追加 (3-5 項目程度の bullet list) + - 「N ファイルを同時削除する設計の場合、全 N ファイルの header に同一の retirement clause が記載されているか」 + - 「retirement workflow の Step 3 (参照更新) で `grep -rn ''` を全ファイル分実施したか」 + - 「新ファイル追加時に既存ファイルの retirement clause にも追記したか」 + - 「参照先 (ADR / docs-governance.md) が permanent artifact であることを確認」 +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 +- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回多ファイル分割 (例: history.md 50KB 接近時) で同 checklist を踏むことで drift が構造的に防止される +- PR #133 (todo.md 分割) / PR #153 (analysis.md 分割) の successful pattern が明文化され、3 例目以降の reproducibility が確保される + +--- + +### docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = 必ず grep で実ファイル確認」を明記 (PR #156 T3 #1 採用) + +> **動機**: PR #156 で ephemeral 4 ファイル retire を実施した際、`grep` 結果に含まれる **diff context 行が実ファイルの最新内容ではなく PR 直前の状態を反映する** ため、削除対象ファイルへの参照が「残存」と誤検出される false alarm が 5 件以上発生。fact-check の grep 実行に時間を要した。XS の文言追加で将来セッションの reviewer / Claude が同一の確認コストを繰り返すことを防止できる。ephemeral 退役ワークフローは今後も繰り返されるため Frequency Medium。 +> +> **本タスクの位置づけ**: PR #156 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 例外条件 = 既存実践の明文化 + guide 効果のため採用 (順位 122 / 127 と同じロジック)。 +> +> **参照**: `.claude/feedback-reports/156.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` §Retirement Workflow + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` §Retirement Workflow の Step 3 (参照更新) に「diff context 由来 false alarm 防止」note 追加 (2-3 行) + - 「`grep -rn ''` で hit した参照は **必ず該当ファイルを Read で開き、最新内容に対象参照が実在することを確認** する。diff context は PR 直前の旧状態を反映するため、retire 対象ファイルへの参照が context として残存しているように見えても、現行 working copy では既に削除されている場合がある」 + - 具体例: PR #156 (4 ファイル同時 retire) で 5 件以上の false alarm が発生 +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 +- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回 ephemeral 退役 workflow で同 false alarm が発生しても、明文化された手順により fact-check の認知コストが低減する +- guide として PR review / Claude session 双方で参照可能 + +#### 詰まっている箇所 + +なし。Effort XS、global rule への追記のみで副作用最小。 + +--- + +### todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来) + +> **動機**: 順位 78 (旧 ADR-038 Rust timestamp arithmetic safety、PR #115 T3-1) は entry 登録時 (2026 年序盤) に新規 ADR として ADR-038 を予約のつもりで hardcode していたが、queue 滞留中に Bundle Z 系列の連続採用で `ADR-037 / 038 / 039 / 040` がすべて占有され、2026-05-16 セッションで番号 conflict が顕在化 (ADR-041 へ振り直し)。さらに 2026-05-22 に順位 139 (PR #168 follow-up) が ADR-041 を取得したため順位 78 を再 placeholder 化 = **同一 entry が 3 回 (038 → 041 → NNN) 番号変更を経た実証ベース**で、queue 深度と滞留期間の積に比例して同型 conflict が再発する構造リスクを convention で予防する必要がある。 +> +> **本タスクの位置づけ**: 順位 78 振り直し対応の **再発防止 convention**。採番予約簿 (`docs/adr/RESERVED.md` 等) は管理コストが過剰なため見送り、entry 登録時は placeholder で済ませて land 時の PR で空き番号を確定する運用に統一する (作業着手時に採番するだけの軽量運用、ユーザー判断 2026-05-16)。 +> +> **参照**: 順位 78 entry ([docs/todo5.md](todo5.md) § ADR-NNN Rust timestamp arithmetic safety + CLAUDE.md security 拡充)、`~/.claude/rules/common/docs-governance.md` +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule に 2-3 行追記。 + +#### 設計決定 (案) + +- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Document Lifecycle Classification` 周辺、もしくは新規 `## ADR 採番の運用` section +- **追記内容案** (2-3 行): + - todo entry / planning markdown で新規 ADR を予告する際は、番号を hardcode せず **`ADR-NNN (採番未確定、land 時に確定)`** placeholder で記述する + - land 時の PR で `docs/adr/` を確認し空き番号を確定。同時に当該 entry / markdown / table 内の placeholder を実番号に置換 + - 採番予約簿の運用は行わない (queue 滞留 entry の管理コストが回収可能性に見合わない) +- **本タスクの効果**: queue 滞留 entry が後発 PR の採番と衝突する構造リスクを convention で予防、作業着手時の軽量採番で十分運用可能 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` に上記 placeholder 採用方針を 2-3 行追記 +- [ ] 既存 todo entries 内に他の hardcode された ADR 予告番号が残っていないか `grep -rn 'ADR-[0-9]\+ (新規)' docs/` 等で確認 (順位 78 振り直し後の漏れ検出) +- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `docs-governance.md` に ADR 番号 hardcode 撤廃方針が明記される +- 将来 todo entry で新規 ADR を予告する際に placeholder 形式が convention として参照可能 +- 既存 todo に他の hardcode 予告番号が残っていないことが grep で確認される + +#### 詰まっている箇所 + +- ルール追加自体は機械検知不可だが、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + 簡素な代替手順を提示。grep ベースの後付け検証も容易 (`grep -nE 'ADR-[0-9]+ \(新規\)' docs/`) + +--- + +### ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment (PR #169 T3-#2 採用) + +> **動機**: 順位 135 で codify された「ADR 番号は entry 登録時に hardcode せず `ADR-NNN (採番未確定)` placeholder で記述し、land 時 PR で空き番号を確定する」運用が、PR #111 / PR #132 / PR #169 の **3+ PR で適用実証済**になった。特に PR #169 では同一 entry (順位 78) が `ADR-038 → 041 → NNN` の **3 段振り直し** を経た live dogfood が完了し、queue 滞留 entry と後発 PR の採番衝突を convention 層で完全予防できる状態が確立された。現在 policy は `~/.claude/rules/common/docs-governance.md` の 2-3 行追記として ephemeral todo (順位 135) 内で codify されているが、ephemeral artifact 限りでは派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への transferability に欠ける。正式 ADR に昇格して永続化する。 +> +> **本タスクの位置づけ**: PR #169 post-merge-feedback Tier 3 #2 採用。`feedback_no_unenforced_rules.md` の例外 = 既存実践 (3 PR で実証済) の明文化 + multi-PR race-freedom rationale + history の codify。Severity Low / **Frequency Medium (PR #111/#132/#169 の 3+ PR で適用実証)** / Effort S / Adoption Risk None。 +> +> **参照**: `.claude/feedback-reports/169.md` Tier 3 #2、順位 135 entry (`docs/todo8.md` 内、本 ADR 昇格後に retire 候補)、`~/.claude/rules/common/docs-governance.md` (現状 codify 先)、PR #111 / PR #132 / PR #169 history +> +> **実行優先度**: 💎 **Tier 3** — Effort S。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記 + 順位 135 entry retire (= todo8.md から削除)。 + +#### ADR 番号 + +順位 135 codified policy 自身に従い、本 entry では番号を `ADR-NNN (採番未確定)` placeholder とする (= dogfood 自己適用)。**land 時 PR で空き番号を確定**する (現時点既存: ADR-041 まで確定、ADR-NNN slot は順位 78 で「Rust timestamp arithmetic safety」用に予約中)。本 entry が順位 78 より先に land する場合は次の空き番号を本件に割り当て、順位 78 の placeholder は維持。 + +#### 設計決定 (案) + +- **ADR タイトル候補**: `ADR-NNN: ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment` (内容を反映、派生プロジェクトでも理解可能な英文タイトル) +- **内容構成**: + - **コンテキスト**: queue 滞留 entry の ADR 番号 hardcode が後発 PR の採番と衝突する構造リスク。PR #111/#132/#169 の history (順位 78 が `ADR-038 → 041 → NNN` の 3 段振り直しを経た live dogfood) + - **決定**: ① entry 登録時は `ADR-NNN (採番未確定、land 時に確定)` placeholder で記述、② land 時 PR で `docs/adr/` の空き番号を確定、③ 同一 PR で当該 entry / markdown / table 内 placeholder を実番号に同時置換、④ 採番予約簿 (`RESERVED.md` 等) は導入しない (queue 滞留 entry の管理コストが回収可能性に見合わない) + - **帰結**: queue 滞留期間と queue 深度の積に比例する番号衝突リスクが convention 層で予防される。派生プロジェクトでも同 policy を採用すれば multi-PR race-freedom が確保される。コスト: entry 著者は placeholder を維持する規律が必要、land 時 PR では multi-point sync (todo + ADR + CLAUDE.md) を同 commit で揃える必要 + - **適用範囲**: 全 ADR (試験運用 / 永続採用問わず)。既存 ADR (ADR-001〜ADR-041) には遡及適用しない + - **既存資料との関係**: `~/.claude/rules/common/docs-governance.md` の 2-3 行追記 (順位 135 で codified 予定) を ADR で補完する layer。global rule は entry author への 1-line guidance、ADR は派生プロジェクトを含む reference layer +- **CLAUDE.md ADR list 追加**: project-local の Architecture Decisions list に link 追記 +- **順位 135 entry retire**: 本 ADR で内容を完全 codify した時点で順位 135 を todo8.md から削除 (ephemeral → permanent への migration、`feedback_todo_no_history` 適用) + +#### 作業計画 + +- [ ] `docs/adr/adr-NNN-adr-numbering-strategy.md` を新規作成 (番号は land 時 PR で確定) +- [ ] 内容構成 (上記 5 項目) を記述 +- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 (番号確定時) +- [ ] 順位 135 entry を todo8.md から削除 (本 ADR が retire 先になる) +- [ ] PR description で `docs/adr/adr-NNN-adr-numbering-strategy.md` への link と「順位 135 内容を permanent ADR に migrate、派生プロジェクト transferability 確保」要約を明記 (PR 作成時) + +#### 完了基準 + +- ADR ファイルが新規作成され、PR #111/#132/#169 の history + placeholder policy + multi-PR race-freedom rationale が記述される +- CLAUDE.md の ADR リストに該当 entry が追加される +- 順位 135 entry が todo8.md から削除される +- 次回 ADR 採番が必要な entry を書く際の reference として global rule (docs-governance.md) から本 ADR にリンク可能になる + +#### 詰まっている箇所 + +なし。記述のみで実装変更不要。順位 135 と内容重複しないよう「global rule = 1-line entry author guidance / ADR = full rationale + history + transferability」で役割分離を明示する。 + +--- + + +### 複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171 + +> **動機**: PR #151 (`byte_offset_to_line` char-boundary panic 発見) + PR #171 (`build_violation_json` defensive test 追加) の 2 PR 横断で multi-byte content fixture を手動で組み立てるコストが顕在化。Japanese / emoji / combining chars の各 sample を helper として標準化することで、新規 string-processing 関数追加時の boundary test 実装コストを低減し silent regression を early detection できる。 +> +> **本タスクの位置づけ**: PR #171 post-merge-feedback Tier 2 #4 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。Bundle 171 のコア (順位 142 ADR-041 補強 + 順位 144 jj hook と同 PR で land 推奨)。 +> +> **参照**: `.claude/feedback-reports/171.md` Tier 2 #4、`src/hooks-post-tool-linter/src/main.rs` (`run_custom_rules_line_number_correct_with_multibyte_content` を helper 化対象)、PR #151 / PR #171 +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。Bundle 171 ペアタスク。 + +#### 設計決定 (案) + +- **helper API** (3 関数): + - `multibyte_fixture_japanese() -> &'static str` — 3 bytes/char (例: `// 日本語コメント`) + - `multibyte_fixture_emoji() -> &'static str` — 4 bytes/char (例: `// 🦀 rust`) + - `multibyte_fixture_combining() -> &'static str` — e + U+0301 結合文字 (例: `// caf\u{00e9}`) +- **配置先候補**: `src/hooks-post-tool-linter/src/main.rs` の test mod 内 (in-crate) vs 共有 test util crate (cross-crate 再利用)。本タスクでは前者を採用し、再利用ニーズが顕在化したタイミングで後者へ migrate +- **既存 test refactor**: PR #171 で追加した `run_custom_rules_line_number_correct_with_multibyte_content` を helper を呼ぶ形に書き換え + +#### 作業計画 + +- [ ] helper 配置先決定 (in-crate test mod を優先採用) +- [ ] 3 helper 関数を実装 (Japanese / emoji / combining) +- [ ] PR #171 で追加した既存 test を helper を使う形に refactor +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 考慮 (in-crate なら porting 容易) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 3 helper 関数が公開され、test mod 内から呼べる +- 既存 test の refactor 完了 (動作不変、`cargo test` pass) +- 新規 string-processing 関数追加時に 1 行で multi-byte boundary test を書ける状態になる + +#### 詰まっている箇所 + +なし。Effort S、Bundle 171 内で 順位 142 + 順位 144 と並列実施可能。 + +--- + +### preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用) + +> **動機**: PR #172 で `jj-message-required` preset 実装の Phase 3 において、当初 `is_blocked("jj new")` (default config 使用) で block を assert する test を書いたが、`jj-message-required` が `default_preset_names()` の fallback list に含まれない opt-in preset であることを前提とせず、test rewrite が必要になった。preset architecture の implicit assumption (always-enabled vs config-selectable) を test 設計レベルで codify することで、将来の新 preset 追加時の design misalignment を構造的に防止する。 +> +> **本タスクの位置づけ**: PR #172 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。matrix test で preset 分類を明示する mechanical enforcement 層を追加。 +> +> **参照**: `.claude/feedback-reports/172.md` Tier 2 #1、`src/hooks-pre-tool-validate/src/main.rs` の `default_preset_names()` + test module、PR #172 Phase 3 (test rewrite 経緯) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。Bundle 171 残タスク (順位 142 + 143) との並列実施可能。 + +#### 設計決定 (案) + +- **配置先**: `src/hooks-pre-tool-validate/src/main.rs` の test module (feedback report は lib.rs と記載するが本 crate は binary crate のため main.rs を採用) +- **matrix 構成** (2 軸): + - axis 1: `default fallback (always-enabled)` vs `config-selectable (opt-in)` + - axis 2: 各 preset 名 +- **classification 期待値** (本セッション時点): + - always-enabled (`default_preset_names()` 内): `default` / `git` / `jj-immutable` / `jj-main-guard` / `jj-push-guard` / `electron` + - config-selectable: `gh-pr-create-guard` / `gh-pr-merge-guard` / `polling-anti-pattern` / `exe-help-block` / `jj-message-required` +- **test 案**: + - `preset_default_fallback_classification`: 各 always-enabled preset 名が `default_preset_names()` の return に含まれることを assert + - `preset_config_selectable_opt_in_classification`: 各 config-selectable preset 名が `default_preset_names()` に含まれないことを assert + - `preset_matrix_full_coverage`: 既知 preset 名の全集合が classification 表 (always-enabled ∪ config-selectable) と一致することを assert (= 新 preset 追加時に matrix 更新を強制) + +#### 作業計画 + +- [ ] preset 分類表を const として定義 (`ALWAYS_ENABLED_PRESETS` + `CONFIG_SELECTABLE_PRESETS`) +- [ ] matrix test 関数 3 件追加 (default fallback / config-selectable / full coverage) +- [ ] 既存 test (`default_config_enables_all_presets` / `jj_message_required_not_in_default_fallback_is_opt_in` 等) との重複整理 (削除 or matrix への移行) +- [ ] `resolve_preset_or_custom` の dispatch arm 列挙との整合性確認 (matrix の preset 名 = dispatch arm 名) +- [ ] 派生プロジェクト transferability 考慮 (porting 時に preset 分類を即把握できる) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- preset の分類 (always-enabled vs config-selectable) が test レベルで codify される +- 将来の新 preset 追加時に classification 表を更新せざるを得ない構造になり、design misalignment が構造的に検出される +- 既存 test (158 件) との regression なし +- `resolve_preset_or_custom` の arm 列挙との不整合 (preset 追加忘れ等) が test で catch される + +#### 詰まっている箇所 + +- feedback report は target を `src/hooks-pre-tool-validate/src/lib.rs` と記載するが、本 crate は binary crate (main.rs のみ) で lib.rs は存在しない → main.rs を採用 (target 是正) +- 「config-selectable preset 名が default に含まれない」test は `jj_message_required_not_in_default_fallback_is_opt_in` で 1 件既存。matrix 化で全 5 preset に拡張する + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +### post-merge-feedback workflow が長時間 stale marker を残す問題 (PR #119 marker observed 2026-05-15) + +> **観測**: 2026-05-15 セッション開始時、`.claude/feedback-reports/119.md.failed` marker が **606,269 秒 (約 7 日)** 経過した状態で UserPromptSubmit hook により検出。PR #119 (ADR-038 Phase 5: cli-finding-classifier 統合) のマージ後に起動した post-merge-feedback workflow (run id `20260506-141736-post-merge-feedback-for-119`) が abrupt 終了 (kill -9 / SIGKILL / power loss / OOM 等) で中断され、Drop guard 経路を経由せず orphan reaper の 1500 秒閾値も大幅に超過した state で marker が残存。 +> +> **解釈**: 単発事象として記録のみ留め、即時手動 recovery (`pnpm exec takt -w post-merge-feedback -t 'post-merge-feedback for #119'`) は実施しない (PR #119 は 7 日前 land 済で、対応するレビュー知見は後続 PR で既に消化済の可能性が高い)。次回 stale marker の自然 cleanup 機構 (ADR-030 §L2 orphan reaper / D-7 / 順位 64) の dogfood で本 marker も同時に reap されるかを観察する材料として残す。 +> +> **本タスクの位置づけ**: **既知課題のみ、todo 着手は予定なし**。merge pipeline の長期化 / abrupt 終了が原因と推定されるが、systemic な再発 (Frequency Medium 以上) を確認するまで実装側の改修は scope 外。Bundle c-1 (PR #154、L1 Drop guard + L2 reaper) で recovery 機構自体は実装済のため、本 marker は単に「reaper 投入前に取り残された artifact」として扱う。 +> +> **参照**: `.claude/feedback-reports/119.md.failed`、ADR-030 §L1/L2 spec、Bundle c-1 (PR #154、L2 orphan reaper の本セッションでの初回完全 dogfood) + +#### 想定される追加観察項目 (Frequency が上がった場合に着手) + +- abrupt 終了 (Drop guard 不発) の root cause: takt subprocess 階層のどこで SIGKILL が起きたか (cli-merge-pipeline / takt 本体 / Claude Code session 終了 etc.) の事後 forensic +- L2 orphan reaper が古い marker をどう扱うか (immediate cleanup vs warn-only vs leave alone) の policy 評価 +- 7 日経過 marker を Claude Code セッション開始時に毎回提示するべきか (UserPromptSubmit hook の signal-to-noise) の検討 + +--- diff --git a/docs/todo9.md b/docs/todo9.md index 49e6f245..6c554b39 100644 --- a/docs/todo9.md +++ b/docs/todo9.md @@ -2,7 +2,7 @@ > **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイルの位置付け**: docs/todo8.md がファイルサイズ 60KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #172 仕組み化方針切替セッション = 2026-05-25)。todo.md / todo2.md 〜 todo8.md の既存エントリは引き続き有効、相互に独立。新セッションでは十一つすべてを確認すること (todo.md / todo2-10.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo8.md がファイルサイズ 60KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #172 仕組み化方針切替セッション = 2026-05-25)。todo.md / todo2.md 〜 todo8.md の既存エントリは引き続き有効、相互に独立。**2026-06-06 分割**: 本ファイルが 75KB / 890 行に到達したため、PR-specific follow-up entries (順位 157, 160-173) を [docs/todo11.md](todo11.md) に分離。残置: 既存ルール仕組み化バンドル (順位 146-151) + 週次レビュー拡張 (順位 152-154)。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 @@ -447,443 +447,7 @@ --- -### Bundle 1 dogfood checklist 実行 — `__test.ps1` block + override env 確認 (PR #174 T2-#2 採用、ADR-039 bounded lifetime data point #1) - -> **動機**: PR #174 で実装した `scratch_file_warning` stage は ADR-039 § 3 Bounded lifetime 準拠で「3-5 PR の dogfood 後に default-ON 昇格 or 却下を判定」する設計。PR #174 の PR body に未消化の dogfood checklist が残っており (`__test.ps1` を意図的に作って push し block 動作確認 / override env でバイパス確認)、これが ADR-039 bounded lifetime の初回データポイント。次の PR (Bundle 2 等) merge 前の前提条件として消化が必要。 -> -> **本タスクの位置づけ**: PR #174 post-merge-feedback Tier 2 #2 採用 (Severity Low / Frequency Low / Effort XS / Adoption Risk None)。manual operation で完結、Bundle 1 自身の運用検証 + ADR-039 bounded lifetime 体系の初回稼働確認。 -> -> **参照**: `.claude/feedback-reports/174.md` Tier 2 #2、PR #174 PR body の Test Plan unchecked items、`docs/adr/adr-039-experimental-feature-standard-pattern.md` § 3 Bounded lifetime、`src/cli-push-runner/src/stages/scratch_file_warning.rs` (`SCRATCH_FILE_WARNING_OVERRIDE` env) -> -> **実行優先度**: 🔧 **Tier 2** — Effort XS。手動 dogfood 1 セット、~10 分。 - -#### 設計決定 (案) - -- 手順: - 1. ローカル working dir に `__test_dummy.ps1` (or `.txt`) を作成 (中身は無害な dummy) - 2. `jj describe -m "test: scratch hook dogfood"` 等で commit - 3. `pnpm push` を実行 → scratch_file_warning stage が block する (EXIT_SCRATCH_FILE_WARNING = 6) を確認 - 4. `$env:SCRATCH_FILE_WARNING_OVERRIDE = "1"; pnpm push` で override → 通過確認 - 5. dogfood 完了後、`__test_dummy.ps1` ファイル削除 + commit abandon で working dir clean -- 記録: dogfood 結果 (block message / override 動作 / false positive 有無) を Bundle 2 PR body に「ADR-039 bounded lifetime data point #1」として記載 -- 注意: 本 dogfood は本リポジトリで実施。派生プロジェクトへの deploy 後の dogfood は別タスク (派生プロジェクト側の bounded lifetime data point として記録) - -#### 作業計画 - -- [ ] `__test_dummy.ps1` を working dir に作成 -- [ ] `jj describe + pnpm push` で block 動作確認 -- [ ] `$env:SCRATCH_FILE_WARNING_OVERRIDE = "1"; pnpm push` で override 動作確認 -- [ ] cleanup: `__test_dummy.ps1` 削除 + commit abandon -- [ ] 結果を Bundle 2 PR body に記録 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- block 動作: scratch_file_warning stage が `__test_dummy.ps1` を検出し EXIT 6 で push を block する -- override 動作: env var 設定後に同 stage を通過、push が成功する -- ADR-039 bounded lifetime data point #1 が記録される - -#### 詰まっている箇所 - -なし。Effort XS、manual operation で完結。 - ---- - -### docs-governance.md に「ADR multi-variant pattern section 追加時の checklist」を codify (PR #176 T3-#1 採用) - -> **動機**: PR #175 (Minor: variant 網羅性不足) + PR #176 (Nitpick: 擬似コード vs 実コード齟齬) の 2 連続観測で、ADR の multi-variant pattern section を追加する際の「参照実装リスト完全性」「実装コード例の表記精度」取りこぼしが pattern 化された。本 PR #176 で追加した ADR-041 § State Preservation Invariant section が CR Nitpick を受けた事例も同パターン。Frequency Medium (2 観測) + Effort XS で採用条件成立。 -> -> **本タスクの位置づけ**: PR #176 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`~/.claude/rules/common/docs-governance.md` に 5-8 行 checklist を追記、ADR 拡張 PR の reviewer / Claude が逆引きで参照できる reusable rule に昇格。`feedback_no_unenforced_rules.md` 例外 = 2 PR で実証 + ADR 形式 (= 設計判断 doc) への追加で機械強制不要、reviewer の judgment 補助。 -> -> **参照**: `.claude/feedback-reports/176.md` Tier 3 #1、PR #175 CR Minor finding 1 件、PR #176 CR Nitpick 1 件、`~/.claude/rules/common/docs-governance.md` (global rule、本リポジトリ外) -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule への 5-8 行追記、本リポジトリ外 (`~/.claude/`) ファイル編集。 - -#### 設計決定 (案) - -- **配置**: `~/.claude/rules/common/docs-governance.md` の document lifecycle classification 周辺、もしくは新 section "ADR Multi-Variant Pattern Authoring Checklist" -- **追記内容案** (5-8 行 checklist): - - ADR に multi-variant pattern (variant 1/2/3 等の列挙) section を追加する場合: - 1. **参照実装リストの完全性**: 各 variant に対応する参照実装 (test 関数 or 実装関数) を 1 件以上 cite。variant が言及されているのに参照実装が無い (例: variant 2 だけ書いて test が無い) ことを避ける - 2. **実装コード例の表記精度**: コード例が擬似コード (簡略化) か実コード (literal copy) かを明示。擬似コードなら「(概念)」「(簡略化)」等のマーカーを付け、実コードならパスと行番号を cite (`poll.rs:839-842` 等) - 3. **既存資料との関係**: 該当 ADR の「既存資料との関係」section に cross-link を追加 - - 由来: PR #175 (variant 網羅性不足、Minor) + PR #176 (擬似コード vs 実コード齟齬、Nitpick) の 2 連続観測 -- **派生プロジェクト transferability**: global rule のため本リポジトリで合意した内容は派生プロジェクトにも自動波及 (本 PR で `~/.claude/` 配下を直接編集する必要がある制約) - -#### 作業計画 - -- [ ] memory `feedback_global_config_backup` 適用でバックアップ取得 (`~/.claude/rules/common/docs-governance.md` を `.backup-YYYYMMDD` 等で snapshot) -- [ ] `~/.claude/rules/common/docs-governance.md` に checklist 5-8 行を新 section "ADR Multi-Variant Pattern Authoring Checklist" として追記 -- [ ] PR #175 / PR #176 を実例 cite として 1-line 引用 -- [ ] markdownlint clean 確認 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `docs-governance.md` に ADR multi-variant pattern checklist が明文化される -- 将来の ADR 拡張 PR で variant 網羅性 + 表記精度の取りこぼしが reviewer 視点で防止される -- PR #175 / PR #176 が実例として reverse-lookup 可能 - -#### 詰まっている箇所 - -- 本タスクは `~/.claude/` 配下 (本リポジトリ外) のため、repo PR には含められない。実装は別途グローバル設定編集として実施 -- バックアップ要 (memory `feedback_global_config_backup` 適用) - ---- - -### Subprocess timeout+kill lifecycle 検証テスト追加 (PR #177 T2-#1 採用) - -> **動機**: PR #177 で CR Major #2 「`run_jj_with_timeout` が timeout 後に jj 子プロセスを kill しない」を fix push したが、修正の正当性 (child process が timeout 到達時に確実に terminate される) を OS レベルで assert する回帰テストが現在ゼロ。fix は `spawn()` + `try_wait()` polling + timeout 時 `kill()` + `wait()` に書き換えたが、テストなしでは将来の変更で同型 leak 再導入が silent regression する。 -> -> **本タスクの位置づけ**: PR #177 post-merge-feedback Tier 2 #1 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None)。Major fix の回帰テスト + 今後の hook 実装で subprocess timeout pattern を使う際の reference test。Severity High = subprocess リーク (resource leak) は debug 困難な silent failure mode。Frequency Medium = 2 hook ファイル (hooks-session-start / hooks-pre-tool-validate) で同一 pattern 確認済、今後の hook 実装でも反復見込み。 -> -> **参照**: `.claude/feedback-reports/177.md` Tier 2 #1、PR #177 CR Major finding (id 3309140888 hooks-session-start / 関連 fix in hooks-pre-tool-validate)、`src/hooks-session-start/src/main.rs` `run_jj_with_timeout` / `src/hooks-pre-tool-validate/src/main.rs` `run_jj_with_timeout` (両方が同一 pattern) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。両 hook test module で integration test 風の subprocess lifecycle 検証 (~80-120 行 + helper)。 - -#### 設計決定 (案) - -- **対象 helper**: `run_jj_with_timeout` (両 hook で実装、ADR-024 で shared lib 統合候補) -- **検証内容**: - 1. **正常完了 case**: jj コマンドが timeout 内に完了 → output が返る、child は `try_wait` で reaped 済 - 2. **timeout case**: 意図的に slow command (例: `jj log` で巨大 revset / 存在しない remote への `git fetch`) → timeout 到達 → kill 発火 → child が is_finished 状態に遷移していることを assert - 3. **kill 後の resource cleanup**: kill 後 `wait()` で zombie 化していないことを assert (Unix では `waitpid` で確認、Windows では `Child::id()` の OS handle が closed か) -- **テスト fixture**: - - `Child::is_finished()` (Rust 1.18+) で kill 後の状態確認 - - `Command::new("sleep")` or `Command::new("cmd")` `/c "ping -n 100 127.0.0.1 > NUL"` (Windows) で意図的 slow command - - timeout は短く (~500ms) して test 全体を 1-2 秒で完結 -- **OS 依存性**: Windows / Linux 両対応のため `#[cfg(target_os = ...)]` で fixture を分ける、または `jj log` で確実に時間がかかる revset を使う方式に統一 -- **配置**: 両 hook の `#[cfg(test)] mod tests` 内 + 共通 helper を `tests/common/mod.rs` 等に切り出す検討 -- **memory `feedback_test_dry_antipattern.md`**: 各 test は独立 fixture で記述 (DRY 適用しない) - -#### 作業計画 - -- [ ] `Child::is_finished` (or `wait_timeout`) で lifecycle 検証手段を確定 -- [ ] hooks-session-start / hooks-pre-tool-validate の `run_jj_with_timeout` test module に 3 case 追加 -- [ ] OS 依存 fixture (slow command) を Windows / Linux で動作確認 -- [ ] dogfood: 意図的に timeout を踏ませる test を CI で安定して走らせられるか確認 (flaky test 回避) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 両 hook の `run_jj_with_timeout` で timeout 後の child kill + cleanup が OS レベルで検証される -- 同型 leak の silent regression が future PR で検出可能 -- ADR-024 (shared jj helpers library) 統合時に test も統合対象として再評価可能な構造 - -#### 詰まっている箇所 - -- OS 依存性: Windows の subprocess lifecycle API (`is_finished`) と Linux の `waitpid` で挙動差異あり。`Child::is_finished` (stable 1.78+) が両 OS 対応で推奨 -- flaky test 回避: timeout を踏ませる test は CI 環境の jitter で flaky 化リスク、500ms ~ 1s の余裕を持つ調整必要 - ---- - -### fail-closed error path (Option::None) 個別テスト追加 (PR #177 T2-#2 採用) - -> **動機**: PR #177 の CR Major #1 「`check_todo_staleness` / `build_todo_staleness_message` が `behind.unwrap_or(0) > 0` で None を non-stale 扱いし fail-closed をバイパス」については現状コード (`src/hooks-pre-tool-validate/src/main.rs:796, 846-849`) で `check_todo_staleness` 側が依然 `behind.unwrap_or(0) > 0` のまま gate バイパスの可能性が残り、`build_todo_staleness_message` 側は `if behind.is_none() { return None; }` で early return しているが回帰テスト不在。本タスクは **実装側 fix (unwrap_or → map_or(true, ...) への修正)** + **回帰テスト追加** の両方を scope に含める。security gate 関数 (Option 返値 + jj 呼び出し) の error path 検証は今後の hook でも反復必要。 -> -> **本タスクの位置づけ**: PR #177 post-merge-feedback Tier 2 #2 採用 (Severity High / Frequency Medium / Effort S / Adoption Risk None)。Major fix の回帰テスト + security gate pattern の standard reference。Severity High = fail-closed バイパスは silent security 退化。Frequency Medium = security gate + Option return pattern は今後の hooks でも反復適用見込み。 -> -> **参照**: `.claude/feedback-reports/177.md` Tier 2 #2、PR #177 CR Major finding (id 3309140878)、`src/hooks-pre-tool-validate/src/main.rs` の `check_todo_staleness` / `build_todo_staleness_message` / `count_commits_branch_ahead` -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。test module への追加 ~30-50 行、unit test で独立検証可能。 - -#### 設計決定 (案) - -- **対象 function**: `check_todo_staleness` (fail-closed 判定)、`build_todo_staleness_message` (None ケース message 出力) -- **実装側 fix (本 PR で同時に land)**: - - `check_todo_staleness` line 796: `behind.unwrap_or(0) > 0` → `behind.map_or(true, |n| n > 0)` (None を stale=true として fail-closed 化) - - `build_todo_staleness_message` line 846-849: 現状 `if behind.is_none() { return None; }` で early return しているが、明示的な fail-closed message を返す形に変更検討 (caller が None を「メッセージ無し」と非 stale 解釈しないよう調整) -- **検証 case** (memory `feedback_test_dry_antipattern.md` 適用、各 variant 独立 fixture): - 1. **`check_todo_staleness_returns_stale_when_lineage_none`**: `count_commits_branch_ahead` mock で None を返すよう注入 → result.stale = true、message に「lineage 判定不能」を含む - 2. **`build_todo_staleness_message_none_behind_marks_stale`**: `behind = None` で msg を生成 → "fail-closed で block" 文言を含む - 3. **`check_todo_staleness_normal_paths_unchanged`**: behind = Some(0) / Some(3) で従来通り動作 (regression 防止) -- **mock 戦略**: `count_commits_branch_ahead` は jj 実行依存のため、function を引数で受け取る形に refactor or test 専用 stub を導入。簡易には `count_commits_branch_ahead` を `pub(crate)` で公開し、test で別ロジック (constant None / Some(n) を返す closure) を builder で渡す pattern -- **回帰検出**: 将来 `map_or(true, ...)` を `unwrap_or(0)` 等に戻す変更で test が failing する構造を確保 -- **memory `feedback_test_dry_antipattern.md`**: 各 case は独立 setup (mock 値別)、共通 helper 化しない - -#### 作業計画 - -- [ ] `check_todo_staleness` を mock 注入可能な形に minor refactor (or test 専用 stub 追加) -- [ ] 3 case の unit test 追加 -- [ ] cargo test で pass 確認 + 意図的に fail-closed 削除して test が落ちることを手動検証 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `check_todo_staleness` / `build_todo_staleness_message` の None ケース挙動 (fail-closed) が unit test で independent 検証 -- 将来 `map_or(true, ...)` を逆向きに変更した時に 1 test が落ちる構造 -- security gate + Option return pattern の test reference として hook 実装者が参照可能 - -#### 詰まっている箇所 - -- mock 注入 vs 簡易 stub の trade-off: dependency injection で全 hook で reusable にするか、test 専用 closure で local 化するか。後者 (local stub) のが Effort S で確実 -- function signature 変更の影響範囲: `check_todo_staleness` を refactor すると call site (main.rs handle_write_edit_tool) も追従必要。最小 diff 優先で stub closure 内 mock 推奨 - ---- - -### Cross-ref edge case test coverage 追加 (PR #179 T2-#1 採用) - -> **動機**: PR #179 で cli-docs-lint の cross_ref validator を新規実装し push-runner quality_gate に統合したが、percent-encode (`%20` / `%23`)、GFM heading slug、relative path normalize (`../`) の各 variant が fixture テストで明示的に保護されていない。validator のロジック劣化を silent regression として放置するリスクがある。 -> -> **本タスクの位置づけ**: PR #179 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort S / Adoption Risk None、2026-05-28 ユーザー承認)。cross_ref validator の edge case coverage 拡充による silent regression 防止。 -> -> **参照**: `.claude/feedback-reports/179.md` Tier 2 #1、`src/cli-docs-lint/src/cross_ref.rs` (既存 9 tests に追加)、PR #179 (cli-docs-lint 本体 land) -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。既存 tests と同 pattern で fixture 追加。 - -#### 設計決定 (案) - -- **対象 edge case**: - 1. **percent-encode**: 日本語 file name の percent-encode (例: `%20` 空白、`%E3...` UTF-8) を含む link を resolve できるか - 2. **GFM heading slug**: heading anchor (`#section-with-spaces` 等) の小文字化 / 空白→`-` 変換が GFM 仕様に従うか - 3. **relative path normalize**: 多段 `../` を含む link (例: docs/ から 2 階層上 root → 別 path) を正しく resolve できるか (現状の base_dir.join + canonicalize 経路) -- **fixture pattern**: 既存 cross_ref.rs の `#[cfg(test)]` mod 内の tempdir + 動的 fixture 生成 pattern を踏襲 -- **memory `feedback_test_dry_antipattern`**: 各 variant 独立 setup、共通 helper 化しない - -> NOTE: 本 entry の編集時に edge case の link 例を Markdown link 形式 (角括弧 + 丸括弧) で書くと、cli-docs-lint の cross_ref validator が backtick 内 link も誤検出する (= 本 entry land 時に発覚した false positive)。validator 自体の backtick-aware 化も本 entry 着手時に検討余地あり (現状は description + 拡張子のみで回避)。 - -#### 作業計画 - -- [ ] `src/cli-docs-lint/src/cross_ref.rs` の `#[cfg(test)]` mod に 3 case の fixture test を追加 -- [ ] cargo test で pass 確認 + 意図的に validator から正規化ロジックを抜いて test が落ちるか手動検証 -- [ ] (任意) validator の backtick-aware 化 (inline code 内の link を無視) を本 entry に同梱検討 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 3 edge case (percent-encode / GFM heading slug / relative path normalize) が unit test で independent 検証 -- silent regression を test で 1 件以上検出できる構造 -- 既存 9 tests と整合性を保つ - -#### 詰まっている箇所 - -なし。Effort S、cli-docs-lint 内のみで完結。 - ---- - -### `pnpm create-pr` PR body truncation 回避を検証する e2e/integration test 追加 (PR #181 T2-#1 採用) - -> **動機**: PR #134 + #181 で 2 回観測された `pnpm create-pr` (= `cli-pr-monitor.exe` の PR 作成モード) における PR body 切り詰め問題。複数 section・複数行の body を `--body "..."` で渡すと shell argument 解釈で改行が delimiter 処理されて body が途中で切れる silent UX 劣化が発生する。memory `feedback_pnpm_create_pr_body` で `--body-file ` workaround を採用済だが、回避策が正常動作することを担保する自動 regression gate が存在しない。 -> -> **本タスクの位置づけ**: PR #181 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-05-29 ユーザー承認)。PR #134・#181 の 2 回観測で Medium frequency に昇格、`--body-file` workaround の regression gate として採用条件成立。 -> -> **参照**: `.claude/feedback-reports/181.md` Tier 2 #1、memory `feedback_pnpm_create_pr_body`、`src/cli-pr-monitor/src/main.rs` (PR 作成モード本体)、`src/cli-pr-monitor/src/stages/` 周辺の `run_create_pr` 実装、PR #134 / #181 の create-pr 実行例 -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。既存 cli-pr-monitor test infra の流用、shell argument truncation 境界の fixture 測定。 - -#### 設計決定 (案) - -- **検証対象**: `pnpm create-pr -- --title "..." --body-file ` 経由で PR を作成した際、body 内容が source file と一致すること (truncation なし、改行保持) -- **境界測定**: PR body 文字数 (行数 / バイト数) を段階的に増やし、shell 直渡し `--body "..."` パスが切り詰める閾値と `--body-file` が切り詰めない閾値の境界を fixture で測定、regression gate として記録 -- **test 方式**: `gh pr create` の dry-run option がないため、cli-pr-monitor の argv 組み立て層を unit test 対象にする (実 PR 作成は行わない)、または integration test で mock gh CLI を介して argv の最終 shape を assert -- **memory `feedback_test_dry_antipattern`**: 各 variant 独立 setup、共通 helper 化しない - -#### 作業計画 - -- [ ] cli-pr-monitor の PR 作成モードで argv 組み立て層を関数化 (test 可能な shape に refactor、必要なら) -- [ ] `#[cfg(test)]` mod に 3 fixture を追加: (a) 短い single-line body、(b) 複数行 body 経由 `--body-file`、(c) 直接 `--body` を渡した場合の truncation 再現 -- [ ] cargo test で pass 確認 + 既存 cli-pr-monitor test との独立性確認 -- [ ] truncation 境界の測定結果を test コメントに記録 (将来の閾値変更時の reference) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `--body-file` 経由が複数行 body で truncation なしに動作することが unit test で保護 -- shell 直渡し `--body "..."` で truncation が起こる境界が fixture で測定済 -- silent regression を test で 1 件以上検出できる構造 -- 既存 cli-pr-monitor test との独立性 (mock 設定の交差なし) - -#### 詰まっている箇所 - -`gh pr create` 自体に dry-run option がないため、実 PR 作成を伴わない検証戦略を要設計 (argv 組み立て層の関数化 or mock gh CLI)。Effort S 想定だが test 戦略次第で M に膨らむ可能性あり。 - -#### 補足 (PR #182 T2-#2 採用候補との関係、2026-05-29 ユーザー判断) - -- PR #182 post-merge-feedback の T2-#2 (`pnpm-create-pr-body-guard` hook の guard test 追加) は本 165 と test 層 scope が重複するため、独立 entry 化せず本 entry に集約。analyzer は「本 session で `pnpm-create-pr-body-guard` hook による mitigate 実施」と articulate したが、これは hallucination (本 session では `--body-file` workaround を使ったのみで guard hook は触れていない) -- 重要な supplementary fact: PR #134 post-merge-feedback で `pnpm-create-pr-body-guard` hook 追加が **✅ 採用判定されたが、実装は完了していない状態** (= unfulfilled adoption、`.claude/feedback-reports/134.md` Tier 1 #1 参照)。順位 152 (todo 削除時の事前 land 確認手順) と関連する process learning として記録 -- 本 165 着手時に guard hook が実装済なら test 範囲を 2 層に拡張する: - 1. (本 entry の主旨) `--body-file` workaround が複数行 body で truncation なしに動作することを verify - 2. (拡張) guard hook が `pnpm create-pr -- ... --body "..."` を block して `--body-file` に誘導することを verify -- hook 未実装のまま本 165 を land する場合、guard 層の test は将来の guard 実装 follow-up entry に切り出す - ---- - -### `git-workflow.md § Multi-PR chaining` を「1 PR 内 multi-commit + intent 明記」パターンに拡張 (PR #183 T3-#1 採用) - -> **動機**: PR #119/#120/#121 + 本 PR #183 で **4 回観測された** multi-commit single-PR bundling パターンを `~/.claude/rules/common/git-workflow.md` § Multi-PR chaining に codify する。現状の同 section は「複数 PR の分割」を扱うが、「1 PR 内で commit を分離する判断基準」「各 commit message での intent 明記の重要性」が未記載。reviewer (CodeRabbit / 人間) が PR diff を読む際、commit description 単位の intent が明確だと review 効率が向上する。Frequency High に到達したため Tier 3 codify 条件成立。 -> -> **本タスクの位置づけ**: PR #183 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency High / Effort S / Adoption Risk None、2026-05-29 ユーザー承認)。`~/.claude/` global 配下のため派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ自動波及。 -> -> **参照**: `.claude/feedback-reports/183.md` Tier 3 #1、`~/.claude/rules/common/git-workflow.md` § Multi-PR chaining ベストプラクティス (既存 section、拡張対象)、観測 PR: #119/#120/#121/#183 - -#### 設計決定 (案) - -`git-workflow.md § Multi-PR chaining ベストプラクティス` に以下を追記: - -- **「1 PR 内の multi-commit 分離」の判断基準**: 異なる論理単位 (例: docs update + feature impl) は **commit を分けて 1 PR で land** することで、reviewer が論理単位ごとに review focus を切り替えられる -- **commit message の intent 明記**: 各 commit description は単独で「何を / なぜ」を理解できる形で記述。`docs(todo): X 採用` / `feat(takt): Y 実装` 等の Conventional Commits + intent suffix のパターンを推奨 -- **典型例**: PR #181 (handoff doc + post-merge-feedback adoption の 2 commit)、PR #183 (Bundle CR-RL todo + A01 ADR fix の 2 commit) を実例として cite -- **single-commit vs multi-commit の境界**: 同一論理単位は 1 commit (例: 単一 facet の implementation + test)。**論理単位が異なる** ときに分離する (例: docs update commit + impl commit) - -#### 作業計画 - -- [ ] `~/.claude/rules/common/git-workflow.md` § Multi-PR chaining ベストプラクティス に新 sub-section 「1 PR 内 multi-commit の判断基準」を追加 (~10-15 行) -- [ ] PR #181 / #183 の commit 構成を実例として inline cite -- [ ] **`feedback_global_config_backup`** 適用: ~/.claude/* を触る前に snapshot 取得 (`cp -r ~/.claude ~/__claude-backup-YYYYMMDD`) -- [ ] markdownlint clean 確認 -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への展開は別タスク -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `~/.claude/rules/common/git-workflow.md` に「1 PR 内 multi-commit 分離」と「intent 明記」のガイドが codify される -- 将来の AI / 人間セッションで commit 分割判断と intent 記述が一貫した形で適用される -- markdownlint clean - -#### 詰まっている箇所 - -なし。Effort S、既存 section への追記のみで scope 明確。 - ---- - -### `docs-governance.md` に「Operational reference vs Pointer reference」区別 section を追加 (PR #183 T3-#2 採用) ★ Bundle DG-RULES - -> **動機**: PR #183 で A01 修正 (8 ADR の ephemeral todo 参照を permanent reference に置換) を実施する際、各 reference が以下のどちらに該当するか判定する作業が発生した: -> - **operational reference**: workflow / behavior が ephemeral artifact をどう扱うかを記述するもの (例: 「ADR-031 workflow が `docs/todo.md` に追記する」)。dead-pointer リスクなし、保持可能 -> - **pointer reference**: 特定の section 名 / 順位 N / Phase A-F 等を指すもの (例: 「Phase A-F section を参照」)。dead-pointer リスクあり、置換必要 -> -> 現状の `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle は「permanent → ephemeral 参照は dead-pointer 化する」を codify しているが、**「operational reference は除外」という重要な判定基準が未記載**。本 PR の修正で ADR-031 lines 79-302 の中で line 270 のみが真の pointer reference だった実例が示すように、operational reference を pointer と誤認すると過剰修正で workflow 記述自体を壊す可能性がある。 -> -> **本タスクの位置づけ**: PR #183 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None、2026-05-29 ユーザー承認)。`~/.claude/` global 配下のため派生プロジェクトへ自動波及。Bundle DG-RULES (本 entry + 順位 172) で同 PR land 推奨。 -> -> **参照**: `.claude/feedback-reports/183.md` Tier 3 #2、`~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle (既存 section、拡張対象)、PR #183 の 8 ADR 修正 commit (実例として cite) - -#### 設計決定 (案) - -`docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section「Operational vs Pointer Reference」を追加: - -- **Operational reference の定義**: workflow / 仕様 / behavior が ephemeral artifact (todo.md 等) を「どう扱うか」を記述するもの。**保持可能**。dead-pointer 化しない理由 = ephemeral artifact の特定 entry を指していないため。 - - 例: 「skill `/weekly-review` は採用 finding を `docs/todo.md` の新セクションに追記する」(動作記述、section 名は workflow が生成するため stale 化しない) - - 例: 「reviewer は `docs/todo.md` を作業計画ファイルとして扱う」(classification、特定 entry を指さない) -- **Pointer reference の定義**: 特定の section 名 / 順位 N / Phase A-F 等を指すもの。**dead-pointer 化リスクあり = 置換必要**。 - - 例: 「Phase B-F は `docs/todo.md` の section X を参照」(stale 化) - - 例: 「順位 42 を読む」(entry 削除で dead pointer) -- **判定基準**: reference が指す対象が「現在存在する specific entry / section」なら pointer、「workflow が描く general behavior」なら operational -- **実例**: PR #183 の ADR-031 line 270 (pointer、置換) vs lines 79-302 内の workflow 記述 (operational、保持)。ADR-034 の 順位 N + PR # pair (PR # 側が permanent reference として fallback、ephemeral 単独参照ではない) も example として cite - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section 「Operational vs Pointer Reference」を追加 (~15-20 行) -- [ ] PR #183 の修正例を inline cite (8 ADR の修正と「operational reference として保持」の判断根拠) -- [ ] **`feedback_global_config_backup`** 適用: ~/.claude/* を触る前に snapshot 取得 -- [ ] markdownlint clean 確認 -- [ ] 順位 172 (memory 追加) と同 PR で land 推奨 (Bundle DG-RULES、docs/rule + memory の 2 層) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `~/.claude/rules/common/docs-governance.md` に operational vs pointer の区別が codify される -- 将来の reviewer / AI が ADR 修正時に過剰修正 (operational reference の誤置換) を回避できる -- 派生プロジェクトへの自動波及で一貫した判定基準が確立 -- markdownlint clean - -#### 詰まっている箇所 - -なし。Effort S、既存 section への sub-section 追加で scope 明確。 - ---- - -### CR ephemeral artifact Nitpick の統一 skip 基準を memory に codify (PR #183 T3-#3 採用) ★ Bundle DG-RULES - -> **動機**: PR #183 で CodeRabbit が docs/todo9.md (= ephemeral artifact) 内の行番号参照 (`lines 1298-1370` 等) を Nitpick として指摘した。これは「行番号は将来 drift する」という general principle としては正しいが、**ephemeral artifact (todo entry) は完了時に削除される設計** のため、永続化を求めるルールを適用するのは over-engineering。本 PR では skip 判断したが、同パターンが構造的に recurring と予想される (CR は ephemeral artifact を permanent doc と同等に扱う傾向)。判断基準を memory entry に codify することで、将来のセッションで一貫した skip 判断が可能になる。 -> -> **本タスクの位置づけ**: PR #183 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-05-29 ユーザー承認)。`~/.claude/projects/.../memory/` 配下のため**派生プロジェクトには波及しない** (本リポジトリ専用)。Bundle DG-RULES (順位 171 + 本 entry) で同 PR land 推奨。 -> -> **参照**: `.claude/feedback-reports/183.md` Tier 3 #3、既存 memory `feedback_coderabbit_no_actionable_merge_signal.md` (補完関係)、PR #183 の Nitpick 2 件 (CR-N1: 順位 168 line 1298-1370 / CR-N2: 順位 169 line 64/185-186) - -#### 設計決定 (案) - -新 memory ファイル `feedback_coderabbit_ephemeral_nitpick.md` を作成: - -- **rule 名**: `feedback_coderabbit_ephemeral_nitpick` -- **type**: feedback -- **description**: CR が ephemeral artifact (`docs/todo*.md` 等) 内の行番号参照を Nitpick (💤 Low value) として指摘した場合は skip 推奨 -- **content**: - - **why**: ephemeral artifact (todo entry) は完了時に削除される設計のため、永続化を求めるルール (line drift 防止 = symbol/section 参照推奨) の適用は over-engineering - - **how to apply**: CR Nitpick が `docs/todo*.md` 系 ephemeral artifact に対する line/symbol drift を指摘した場合、skip + merge 判断を維持。既存 memory `feedback_coderabbit_no_actionable_merge_signal` の「Nitpick 💤 Low value は skip 推奨」の補完。entry 実装着手時には自然に symbol 参照に置き換わる流れになるため、todo entry レベルで先取り fix する価値は低い - - **境界**: permanent artifact (ADR / coding-style.md 等) への同種指摘は通常通り対応する。判定基準 = 対象 file の lifecycle (ephemeral or permanent)。本 rule は ephemeral artifact 専用 - - **実例**: PR #183 の CR-N1 / CR-N2 (docs/todo9.md の行番号参照を skip した実例) - -#### 作業計画 - -- [ ] `~/.claude/projects/E--work-claude-code-hook-test/memory/feedback_coderabbit_ephemeral_nitpick.md` を新規作成 (~30-50 行、frontmatter 含む) -- [ ] `~/.claude/projects/E--work-claude-code-hook-test/memory/MEMORY.md` index に 1 行追加 (各 entry が「タイトル + 1 行 hook」の MEMORY.md 規約に従い、新 memory `feedback_coderabbit_ephemeral_nitpick.md` への 1 行 link を追加) -- [ ] **`feedback_global_config_backup`** 適用: 念のため memory ディレクトリの snapshot 取得 (`cp -r ~/.claude/projects/.../memory ~/__memory-backup-YYYYMMDD`) -- [ ] markdownlint clean 確認 (memory ファイル + MEMORY.md の両方) -- [ ] 順位 171 (docs-governance.md 拡張) と同 PR で land 推奨 (Bundle DG-RULES、docs/rule + memory の 2 層補強) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 新 memory ファイル `feedback_coderabbit_ephemeral_nitpick.md` が作成される -- MEMORY.md index に登録される -- 将来のセッションで CR が ephemeral artifact 内 Nitpick を出した場合、本 rule から逆引き可能になる -- markdownlint clean - -#### 詰まっている箇所 - -なし。Effort XS、新規 memory ファイル + index 1 行追加のみ。 - ---- - -### subprocess utils 5 crate 重複 (combine_output + drain_pipe + wait_with_timeout + run_cmd) を `lib-subprocess-utils` に extract (PR #182 dry-run S01 + Phase E dogfood WR-2026-06-01-S01 採用) - -> **動機**: PR #182 Phase B dry-run で検出された finding WR-2026-05-29-S01 に加え、**Phase E dogfood (2026-06-01) で WR-2026-06-01-S01 (High) として scope が拡大**: subprocess 管理 utility 群が 4-5 crate 横断で重複している。 -> -> **重複対象 (scope 拡大版)**: -> - `combine_output(stdout, stderr)` 8 行関数: 5 crate (`cli-pr-monitor` / `cli-push-runner` / `cli-push-pipeline` / `cli-merge-pipeline` / `hooks-post-tool-linter`) で重複 (cli-pr-monitor では `#[allow(dead_code)]` 付与で生産 path 未到達) -> - `drain_pipe` / `wait_with_timeout` / `run_cmd`: 4 crate (`cli-push-runner/src/runner.rs` / `cli-pr-monitor/src/runner.rs` / `cli-merge-pipeline/src/main.rs` / `cli-push-pipeline/src/main.rs`) で重複 -> - `MAX_LINES` 定数: 4 crate 間で不整合 (40 / 200 / なし) — callsite 設定可能パラメータとして公開する -> -> ADR-026 Cargo workspace + ADR-012 lib-* naming の既存パターンで解決コスト低、保守リスクが各 PR で蓄積中。 -> -> **本タスクの位置づけ**: PR #182 dry-run S01 採用 (2026-05-29 ユーザー承認) + Phase E dogfood (2026-06-01) WR-2026-06-01-S01 (Severity High) で augment 採用。ADR-031 § Phase 4 「重複検出は MVP では実装しない」運用の partial overlap 検出 → augment 判断のフローが機能した実例 (skill 重複検出 → 3 択 → user augment 選択)。 -> -> **参照**: PR #182 dry-run report、Phase E dogfood report (`.claude/weekly-reviews/2026-06-01.md` および `.takt/runs/20260601-095710-weekly-review-2026-06-01/reports/`)、`src/cli-pr-monitor/src/runner.rs:80-89` (function) + `:282-298` (tests)、`src/cli-push-runner/src/runner.rs` / `src/cli-merge-pipeline/src/main.rs` / `src/cli-push-pipeline/src/main.rs` (drain_pipe 等の重複)、`src/hooks-post-tool-linter/` (他 4 crate の重複)、ADR-024 (shared jj-helpers library パターン)、ADR-026 (Cargo workspace) -> -> **実行優先度**: 🔧 **Tier 2** → 🚀 **Tier 1 検討余地** — Effort S-M。Phase E dogfood で High severity 再確認、4-5 crate 横断で更新コスト線形成長中。Cargo workspace 内の単純な lib extract、5 crate を順次差し替え。 - -#### 設計決定 (案) - -- **採用 strategy** (analyzer Option A 推奨): `lib-runner-utils` 新 crate (or `lib-process-helpers` 等の既存 lib-* crate を選定) に `combine_output(stdout, stderr) -> String` を移管。5 crate (`cli-*` 4 件 + `hooks-post-tool-linter`) から `pub use lib_runner_utils::combine_output;` で再 export -- **不採用 strategy** (analyzer Option B): cli-pr-monitor からのみ削除する最小修正案 → 他 4 crate に同じ未使用問題が残るため不採用、Option A の方が systemic 解決 -- **crate 名選定**: 既存 lib-* 一覧を `cargo metadata` で確認、`lib-runner-utils` / `lib-process-helpers` / `lib-subprocess` 等の候補から選定。新規作成より既存 lib-* (例: shared-jj-helpers) への追加が好ましい (ADR-024 の流れ) -- **test 移管**: 既存 4 test の集約版を新 crate の `#[cfg(test)]` に 1 set のみ配置、各 cli-* / hooks-* 側の test は削除 -- **memory `feedback_test_dry_antipattern`**: test は移管後も独立 variant を維持 (helper で共通化しない) - -#### 作業計画 - -- [ ] `cargo metadata --no-deps` で既存 lib-* crate を列挙、`combine_output` の論理 location として最も自然な crate を選定 -- [ ] 選定 crate (新規 or 既存) に `combine_output` を pub 関数として追加 + 集約 test を 1 set 配置 -- [ ] cli-pr-monitor / cli-push-runner / cli-push-pipeline / cli-merge-pipeline / hooks-post-tool-linter の 5 crate の各 `Cargo.toml` に新 dep を追加 (新規 lib の場合) -- [ ] 各 crate の `combine_output` impl + tests を削除、`use ::combine_output;` に置換 -- [ ] cargo test で 5 crate 全 pass 確認 -- [ ] cargo clippy で `#[allow(dead_code)]` が消えることを確認 (extract により生産 path に乗る、または未使用なら別 PR で削除判断) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `combine_output` 関数の単一 source of truth が新 crate (または選定 lib-*) に確立 -- 5 cli-*/hooks-* crate が再 export 経由で同 impl を共有 -- 既存 test が集約版 1 set + 各 crate での 4 set 削除で計 4 set 削減 -- `#[allow(dead_code)]` 付与が不要になる (extract 後の lib では pub function として正規 export 経路) -- cargo workspace 全体で cargo test + cargo clippy が pass - -#### 詰まっている箇所 - -extract 先の crate 選定: 既存 lib-* に追加するか新規 `lib-runner-utils` を作るかの判断。新規 crate は Cargo workspace に 1 line 追加で済むが、既存 lib-* (例: lib-pr-monitor-common 等の既存 shared crate) への追加の方が **Effort S** 寄り、新規作成だと **Effort M** に近づく。`cargo metadata` 結果次第。 - ---- +> **2026-06-06 分割**: 順位 157, 160, 161, 162, 163, 165, 170, 171, 172, 173 は [docs/todo11.md](todo11.md) を参照。 ## 既知課題 (記録のみ、本セッションで未対応)