diff --git a/docs/todo-summary.md b/docs/todo-summary.md index f7bd51f5..177037d6 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -2,13 +2,16 @@ > **本ファイルの位置付け**: `docs/todo.md` から「推奨実行順序サマリー」section を切り出した index 専用ファイル。各タスクの詳細は「ファイル」列に示された `docs/todoN.md` を参照する。`docs/todo.md` のサイズが 50KB を超え Claude Code 読み取り安定性に影響したため分離 (2026-05-09)。 > -> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo14.md`、2026-07-19 週次レビュー WR-2026-07-19-T02 採用で新設。従来の追加先 `docs/todo13.md` が約 171KB = 50KB 安定読み取り閾値の約 3.4 倍に達したため移行、todo13.md は以降 既存エントリの編集・完了削除専用) に記録する。なお `docs/todo10.md` は 2026-06-29 PR #224 セッションで todo13.md へ追加先が移行するまでの旧追加先 (以降 既存エントリの編集・完了削除専用)、`docs/todo11.md` は 2026-06-06 todo9.md 分割で新設された専用ファイル (順位 157, 160-173 を収容)、`docs/todo12.md` は 2026-06-12 PR #204 で todo10.md 分割により新設された専用ファイル (順位 176/178/179/180/181/182/193/194 = PR #185 〜 PR #196 era を収容) で、いずれも新規追加先ではない。 +> **更新方針**: table への新規行追加・既存行の削除・順位の再採番は本 index (todo-summary.md + [docs/todo-summary2.md](todo-summary2.md)) で実施する (2026-07-20 に順位 220 以降を todo-summary2.md へ物理分割、docs 50KB 超過解消。新規行は末尾 = todo-summary2.md 側に追加)。詳細エントリは現行の追加先ファイル (= `docs/todo14.md`、2026-07-19 週次レビュー WR-2026-07-19-T02 採用で新設。従来の追加先 `docs/todo13.md` が約 171KB = 50KB 安定読み取り閾値の約 3.4 倍に達したため移行、todo13.md は以降 既存エントリの編集・完了削除専用) に記録する。なお `docs/todo10.md` は 2026-06-29 PR #224 セッションで todo13.md へ追加先が移行するまでの旧追加先 (以降 既存エントリの編集・完了削除専用)、`docs/todo11.md` は 2026-06-06 todo9.md 分割で新設された専用ファイル (順位 157, 160-173 を収容)、`docs/todo12.md` は 2026-06-12 PR #204 で todo10.md 分割により新設された専用ファイル (順位 176/178/179/180/181/182/193/194 = PR #185 〜 PR #196 era を収容) で、いずれも新規追加先ではない。 + ## 推奨実行順序サマリー (2026-07-19 更新、順位 329-333 追加 (329-332 は PR-N1〜N3 (#299-#301) post-merge feedback 採用登録 #302、333 は週次レビュー WR-2026-07-19 findings 採用)。326-328 も 07-19 追加、323-324 は 07-18 追加、325 = push per-run メトリクス JSONL 永続化は R3 (#294) で実装完了し削除) 開発環境の作業効率への貢献度を基準にした推奨実行順序。詳細は各タスク冒頭の **「実行優先度」** 行を参照。 +> **順位 220 以降は [docs/todo-summary2.md](todo-summary2.md) を参照** (2026-07-20 docs 50KB 超過解消の 2 分割。cli-docs-lint の priority-inversion / preamble check は両ファイルを統合検査)。 + | 順位 | Tier | タスク | ファイル | 工数 | 依存 | |---|---|---|---|---|---| | 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | @@ -67,8 +70,8 @@ | 176 | 🔧 Tier 2 | **check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用)** | todo12.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) | | 178 | 🔧 Tier 2 | **`state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用)** | todo12.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 採用)** | todo12.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 採用)** | todo12.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 採用)** | todo12.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 試験運用前の整備) | +| 180 | 🔧 Tier 2 | **`lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用)** | todo12.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 採用)** | todo12.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 採用)** | todo12.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** | todo12.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` 適用必須) | @@ -84,102 +87,8 @@ | 206 | 💎 Tier 3 | **`~/.claude/rules/common/development-workflow.md` § 1. Plan First に「todo*.md 分割時の todo-summary.md 同一 commit 更新」checklist 追加 (PR #204 post-merge-feedback T3-1 採用)** | todo10.md | S | なし (PR #133 + #153 + #204 の 3 PR 連続観測で multi-file artifact split 時の永続 index 更新漏れが Frequency Medium 閾値到達、3 step checklist (分割エントリ列挙 / sed 一括 file 列更新 / 同一 commit) を § 1. Plan First の Codification 重複確認 step 直後に配置、coding-style.md § Cross-File Reference Lifecycle の具体化事例として cite、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ global 経由で自動波及、`feedback_global_config_backup` 適用必須) | | 207 | 💎 Tier 3 | **`~/.claude/rules/common/patterns.md` § Experimental Feature 設計時の参照必須 に「mechanical lint は ADR-039 scope 外」境界 case 追加 (PR #204 post-merge-feedback T3-2 採用)** | todo10.md | S | なし (PR #204 で project-local adr-039 § 1.b 追加した知見の global 投影、派生プロジェクトでの同型 over-application 防止、4 条件 (non-blocking / 決定論 / scope 限定 / recovery hint 明確) + 該当例 (file-length / file-size lint) と非該当例 (post-merge-feedback / weekly-review / local-llm) を境界 case として明示、順位 200/202/205 と同 pattern = project-local 知見の global codification、`feedback_global_config_backup` 適用必須) | | 211 | 💎 Tier 3 | **`~/.claude/rules/common/testing.md` に「単複・閾値・時制で出力形式が変わる関数は N=0 / N=1 / N≥2 の 3 境界 variant 必須」guideline 追加 (PR #210 post-merge-feedback T3-2 採用)** | todo10.md | XS | なし (PR #210 で `drain_pipe_capped_reporting_n_plus_1_truncates_one_appends_summary` が当初 `"1 lines truncated"` 誤期待値で takt-fix auto-fix された実観測、N-1/N/N+1 境界値と直交する「N=1 単複境界 + ゼロ近傍」次元の guideline 化、順位 110 pure function test pattern と相補、派生プロジェクトに global 経由で自動波及、`feedback_global_config_backup` 適用必須) | -| 215 | 💎 Tier 3 | **`~/.claude/rules/common/coding-style.md` に「Defensive State Reset in State Machines」section 追加 (PR #214 post-merge-feedback T3-1 採用)** | todo10.md | S | なし (PR #214 round 2 で `finalize_initial_review_park` の `state.pr` / `state.repo` / `state.started_at` を `read_state()` 後に無条件上書きする pattern が CR Major #4 の fix として land、CR Major #1 (`head_commit`) + CR Major #2 (`review_recheck_count`) と同型の defensive reset が既に 3 field 適用済 = `review_recheck.rs` 内で複数 instance あり、将来の reviewer が「redundant」と誤判定して削除すると prior cycle の stale state が混入して silent bug 化、global rules への docs 追記で派生プロジェクト (techbook-ledger / auto-review-fix-vc) に自動波及、simplicity-review LLM が同 file を読むため "enforced via review" として機能し memory `feedback_no_unenforced_rules` 例外を満たす、`feedback_global_config_backup` 適用必須) | -| 216 | 🔧 Tier 2 | **`no-workstream-seq-names-in-config` lint rule 追加 — config comment 内 `PR-[0-9]+` ephemeral workstream sequence 検出 (PR #216 post-merge-feedback T1-1 採用) ★ Bundle 216-217** | todo10.md | S | なし (PR #216 で `hooks-config.toml` comment に "PR-1" / "PR-3" workstream sequence を書き込んだ違反を post-merge-feedback T1-1 で捕捉、rule⑥ `no-ephemeral-todo-reference` は `docs/todo*.md` file path のみ catch するが workstream sequence names は対象外、pattern `(?i)\bPR-[0-9]+\b` で `.toml`/`.yaml`/`.yml`/`.jsonc`/`.json` comment を対象、`#NNN` GitHub PR 表記は exception で除外、rule⑫ と同 pattern (TOML `test_coverage` meta field + main.rs test) で Effort S、順位 217 と同根 = 1 PR bundle 推奨。**Tier 列との不整合補足**: analyzer feedback report の `Tier 1: Hooks/Linter 改善` カテゴリは project Tier 1 (🚀 high-impact urgent) ではなく memory `feedback_tier_classification` の re-classification rule (mechanical enforcement = T2 / docs 修正 = T3) に従い project Tier 2 (🔧 tooling improvements) に再分類) | -| 217 | 💎 Tier 3 | **`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に config file comments の permanent artifact 扱い + workstream sequence 禁止例追加 (PR #216 post-merge-feedback T3-1 採用) ★ Bundle 216-217** | todo10.md | XS | なし (順位 216 lint rule と同根、本 task は文書層 = author 理解促進、機械層 (216) との 2 層防御、coding-style.md 既存 § Cross-File Reference Lifecycle は markdown 内 cross-ref を主想定で config file comments の permanent artifact 扱いが暗黙的、workstream sequence names (`PR-1`/`PR-3` 等) 禁止例 + GitHub PR numbers (`#NNN`) 代替を明示、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ global 経由で自動波及、`feedback_global_config_backup` 適用必須、順位 216 と 1 PR bundle 推奨) | -| 218 | 💎 Tier 3 | **ADR-039 § Bounded Lifetime + `~/.claude/rules/common/patterns.md` に provisional `enabled` 変更時の todo entry 必須化を追加 (PR #216 post-merge-feedback T3-2 採用)** | todo10.md | XS | なし (PR #216 で `weekly_review_reminder.enabled = true` の provisional 状態を config comment のみで tracking した silent aging risk を post-merge-feedback T3-2 で捕捉、ADR-039 6-point design checklist に「provisional `enabled` 変更時は `docs/todo*.md` に移行 tracking entry を作成」を追加、`~/.claude/rules/common/patterns.md` § Experimental Feature 設計時の参照必須 にも同旨 note 追加、Frequency Low (初観測) + Adoption Risk None で早期 codify、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ global 経由で自動波及、`feedback_global_config_backup` 適用必須) | -| 219 | 💎 Tier 3 | **`~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に「commit description 言及 ≠ 実装完了」明文化 (PR #216 post-merge-feedback T3-3 採用)** | todo10.md | XS | なし (本 PR で「commit description で順位 N 言及 = 実装完了」naïve assumption から analyzer が 6 entry 削除計画を立てたが、grep で実体確認した結果 5 entry が正解 (順位 215 救出) の実観測、「PR commit description で順位 N や feature X を言及していても、実際のファイル変更を `jj diff` / `grep` で確認するまで completion 判定しない」guideline を追加、Frequency Low (初観測) + Severity Medium (analyzer / Claude 誤判定リスクが今後も継続)、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ global 経由で自動波及、`feedback_global_config_backup` 適用必須) | -| 220 | 🔧 Tier 2 | **subprocess stress test (>64KB stdout) を ADR-031 weekly-review pipeline 経由で週次実行 (PR #217 post-merge-feedback T2-1 採用、ユーザー判断 2026-06-23 = hooks/pre-push には組み込まず週次に分離)** | todo10.md | M | なし (PR #217 で 2 module (jj_helpers.rs / todo_staleness.rs) に同型 subprocess deadlock pattern が独立観測 = Severity High + Frequency Medium、ただし手動検証困難な大 buffer 顕在化テストは毎回実行 (Stop hook / pre-push) には不適切で開発速度に影響、`#[ignore]` 付きで cargo test default skip + ADR-031 weekly workflow の rust-stress step として明示実行 (`cargo test -- --ignored --test-threads=1` 想定)、対象 = lib-subprocess の `drain_pipe_unlimited` + `wait_with_timeout_basic` 利用箇所、順位 221 (ADR docs) と test+docs の 2 層防御で相補) | -| 221 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Safe Subprocess Stdout Pattern を ADR-016 appendix or 新 ADR で codify (PR #217 post-merge-feedback T3-1 採用)** | todo10.md | S | なし (PR #217 で `Stdio::piped()` を伴う `jj` spawn が 2 module で同一 pattern 違反 (concurrent drain なし → pipe buffer 枯渇 deadlock) を independent 観測、Severity Low + Frequency Medium + None risk、解決 pattern (`spawn_stdout_drainer` + `poll_child_with_deadline` または `lib_subprocess::drain_pipe_unlimited` + `wait_with_timeout_basic` の wrap、もしくは `Command::output()` / `Stdio::null()` の 3 択) を ADR-016 § 長時間コマンド戦略 への appendix or 新 ADR として明文化、ADR-025 CwdRestore guard pattern を precedent として cite、派生プロジェクト transferability 確保、順位 220 (test 層) と 1 PR bundle 推奨) | -| 222 | 💎 Tier 3 | **`~/.claude/CLAUDE.md` に「複数セッション跨ぎの計画文書作成時は AI が先走らずユーザー確認後に方針報告し GO/NO-GO を得る」ルール追加 (PR #218 post-merge-feedback #5 採用)** | todo10.md | XS | なし (PR #218 (docs PR) 本セッション内で Plan file 作成完了報告後、AI がユーザー承認なしに PR-W0 着手しようとして `[Request interrupted by user]` で停止された実観測、Severity Medium (AI 暴走 = UX 劣化) + Frequency Low (初観測) + Effort XS + Adoption Risk None、`~/.claude/CLAUDE.md` への 1 段落追記で全プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須、memory `feedback_no_unauthorized_reorder` の補強として「計画書 / planning doc 作成のような大きな task 完了時は GO/NO-GO 確認を待つ」を明文化、本 ルール採用後は Auto mode でも planning doc レベルの完了時点では明示承認待ちが必須となる) | -| 223 | 🔧 Tier 2 | **`ACTIVE_RUN_FRESH_THRESHOLD_SECS` と `ORPHAN_THRESHOLD_SECS` の compile-time 同期 (PR #222 post-merge-feedback T1-1 採用) ★ Bundle 222-FB** | todo10.md | M | なし (PR #222 で hooks-stop-quality に追加した `ACTIVE_RUN_FRESH_THRESHOLD_SECS = 1500` と hooks-session-start reaper の `ORPHAN_THRESHOLD_SECS = 1500` は同値必須 = 非対称になると両防御層の隙間に挟まる run が漏れる、現状はコメント契約のみで mechanical enforcement 欠落、`cli-merge-pipeline/src/feedback.rs:60` の derived const + 上流定数 precedent を cross-crate に拡張、Option C ベース (const re-export + `const _: () = assert!(...)` compile-time check) を MVP 推奨、analyzer Tier 1 = mechanical enforcement → memory `feedback_tier_classification` per project Tier 2 に再分類、順位 224 と 1 PR bundle 推奨 = mechanical + docs 2 層防御) | -| 224 | 💎 Tier 3 | **ADR-043 (Security/Quality Gate Fail-Closed) に hooks-stop-quality の error handling を具体例として追記 (PR #222 post-merge-feedback T3-1 採用) ★ Bundle 222-FB** | todo10.md | XS | なし (PR #222 `meta_is_fresh()` / `meta_is_active_run()` / `takt_subsession_active()` の 4 error path (mtime 取得失敗 / clock skew / malformed JSON / file read error) すべてが `false` 返却 → gate effective に倒れる fail-closed 構造を ADR-043 の concrete instantiation として codify、ADR が「概念定義 + 具体例 list」型に進化、派生プロジェクトへの transferability 向上、Severity Low + Frequency Medium + Effort XS + Adoption Risk None、順位 223 (mechanical) と相補 = 1 PR bundle 推奨、PR #222 / ADR-004 / ADR-043 の 3 文書 cross-reference 成立) | -| 225 | 🚀 Tier 1 | **auto-push gate-bypass の是正 — A1 (fix facet で `--ignored` 必須) + B1-loop (auto-push に gate + convergence ループ差し戻し、fail-closed) (PR #224 セッション合意)** | todo13.md | M | なし (Status update 2026-07-03: PR-1 で A1 + B1 (gate 即 escalation 方式、docs-only skip 付き) 実装済。B1-loop は docs/auto-push-gate-dogfood.md の観測ログ + GO/NO-GO 基準による dogfood 判定待ち — 期限: PR-1 merge + 6 週間 / gate FAIL 2 件 / auto-push 発火 10 回のいずれか先) | -| 226 | 🚀 Tier 1 | **fmt baseline cleanup + `cargo fmt --check` gate 導入 + rustfmt 固定 (PR #224 セッション合意)** | todo13.md | M | なし (fmt enforcement がリポジトリに皆無で workspace 29 ファイルが rustfmt-clean でないドリフト蓄積。(A) `cargo fmt --all` 一括正規化 → (B) fmt --check を Stop/push gate に追加 → (C) rust-toolchain.toml で rustfmt 固定、の順。file_length plan と同型「clean baseline → gate」) | -| 227 | 🚀 Tier 1 | **rule⑬: 非テストコードでの理由なし `#[allow(...)]` 禁止 custom lint (PR #224 セッション合意)** | todo13.md | S | なし (`#[allow]` = lint の握り潰し、既存 swallowed-error 系 rule③/④/⑩ と同 philosophy。justification マーカー無しの `#[allow(...)]` を warning 検出、test code 除外方式は着手時判断、rule_test_coverage_check で positive/negative test 機械強制) | -| 228 | 🔧 Tier 2 | **`rate_limit_signal::cr_clean` の regression test (PR #224 post-merge-feedback T2-1 採用)** | todo13.md | S | なし (Fix 3 で拡張した `unresolved_threads` / `new_comments` / `actionable_comments` 3 field の clean 判定の回帰防止、None/境界ケース網羅、silent-clean 誤認の保護) | -| 231 | 💎 Tier 3 | **ADR-022 拡張 — pre-create cleanup flow 例 + agent fmt スコープ指針 (PR #224 post-merge-feedback T3-1 採用)** | todo13.md | S | なし (CodeRabbit が `create_fix_commit` の空 findings 設計を bug 誤判定=却下 CR#2、agent 無差別 fmt の 2 事象を ADR-022 責務分離で codify、doc-only) | -| 232 | 🔧 Tier 2 | **post-merge-feedback / workflow agent の repo 作業ツリー書込禁止 + 検知安全網 (PR #224 セッション合意)** | todo13.md | S-M | なし (merge 時に analyze-session agent が repo root に throwaway script (parse_transcript.py) を残した、日常工程ゆえ累積リスク = コンテキスト汚染。(1) feedback facets に repo 書込禁止 + jq/scratch 使用を明記 (2) post_steps/Stop hook で root 新規 untracked を warning 検知 (3) gitignore は補助) | -| 233 | 🔧 Tier 2 | **post-pr-review (takt) の diff scope を PR 全体に修正 — `@` 限定による docs-only 誤判定解消 (PR #227 観測)** | todo13.md | M | なし (PR #227 で post-pr-review analyze が `@` コミット (docs のみ) の diff を見て PR を docs-only 誤判定し、CodeRabbit が PR 全体で出した finding (create_pr.rs:208) を ADR-035 docs-only filter で誤って適用外化。今回は finding も false positive (composition root) だったため実害なしだが有効 finding 見逃しリスク。根因は ADR-027 pre-push-review の `jj diff -r @` 由来 review-diff.txt 流用 or post-pr-review 独自 @ 限定 diff 生成の疑い。diff scope を PR 全体 (base..head) に修正 or 分類を CodeRabbit findings file path 基準に変更) | -| 234 | 💎 Tier 3 | **memory `feedback-di-over-ambient-global-tests` に serialization primitive 例外境界 + PR #227 具体例を追記 (PR #227 post-merge-feedback T3-1 採用)** | todo13.md | XS | なし (PR #227 が memory 原則「DI over ambient global」の 2 例目 = PR #224 env_override_lock も同根、Frequency Medium。(a) `PR_MONITOR_STATE_FILE_OVERRIDE` race → `state_path: &Path` DI 解消の具体例 (b) serialization primitive `OnceLock>` は複製禁止だが通常 test helper は複製推奨という例外境界、を追記。「DI over ambient global」と「helper 複製推奨」の見かけの矛盾を解消。順位 235 と相補) | -| 235 | 💎 Tier 3 | **ADR-022 に Serialization Primitive Single-Instance Rule の Appendix 追加 (PR #227 post-merge-feedback T3-2 採用)** | todo13.md | S | なし (PR #224 T2-2 共有 env_override_lock helper 抽出 + PR #227 で同根の serialization primitive 単一化問題 2 PR 観測 = Frequency Medium。`OnceLock>` 等を複製すると各々独立した Mutex になり競合排除が破壊される特殊ケースを ADR-022 Appendix で明文化、通常 helper 複製推奨 (DRY) との例外境界を codify。ADR-046 独立化 (feedback T3-3) との overlap は着手時判断、順位 234 と相補) | -| 236 | 🚀 Tier 1 | **tempfile mandate + PID+ms 命名 block の custom lint (PR #229 post-merge-feedback T1-1 採用)** | todo13.md | S | なし (#227 で修正した temp file collision flaky の再導入防止。#229 で本 flaky が push pipeline の `cargo test` を 3 回ブロックした実害。custom lint で `tempfile::Builder` / `NamedTempFile` を mandate + `gh-pr-body-{PID}-{ms}` 形式の手動命名を block。順位 237 = 検出層と二層防御) | -| 237 | 🔧 Tier 2 | **create_pr flaky の高並列 regression test (PR #229 post-merge-feedback T2-1 採用)** | todo13.md | M | なし (#227 flaky fix の再導入検出網。`body_with_literal_newline_converted` を per-test `tempfile::tempdir()` + 高並列 concurrent run で回し collision を恒常 trap。順位 236 = 予防層と二層防御) | -| 238 | 🚀 Tier 1 | **`Command::new("gh")` 直叩き禁止 + timeout wrapper 必須の custom lint (PR #230 post-merge-feedback T1-#1 採用)** | todo13.md | M | なし (fetch_pr_time_range / fetch_pr_diff_summary / run_gh_logged / delete_remote_branch の 4 箇所が `Command::new("gh").output()` 同期実行でネットワーク不調時に無期限ハング = ADR-016 違反、CodeRabbit Major #2/#3。custom lint で直叩きを検出し `run_cmd_shell_capped_reporting` 相当の timeout wrapper を促す。extensions=["rs"] 限定で false positive 軽減。Severity High + Frequency High + Effort M。順位 240 と同 crate、bundle 検討可) | -| 239 | 🔧 Tier 2 | **`filter_transcripts` の複数 jsonl 走査を timestamp ソートで deterministic 化 + regression test (PR #230 post-merge-feedback T2-#1 採用)** | todo13.md | M | なし (`fs::read_dir` の非決定順により複数 Claude セッション時にファイル間時系列順が保証されず downstream takt workflow の context 品質が低下 = ADR-030 determinism 目標と乖離。timestamp ソート + regression test。Severity Medium + Effort M + Adoption Risk None) | -| 240 | 🔧 Tier 2 | **`takt.rs` の spawn/try_wait `Err(_)` 分岐に eprintln 追加 — 原因握り潰し解消 (PR #230 post-merge-feedback T3-#1 採用)** | todo13.md | XS | なし (spawn/try_wait の `Err(_) =>` が詳細を握り潰し `.failed` marker に実原因 (pnpm 未検出 / 権限エラー等) が残らず L2 recovery の debug 困難。`write_pending_marker_logged` 等の確立 eprintln パターン踏襲で XS。Severity Medium + Effort XS + Adoption Risk None、順位 238 と同 crate bundle 検討可) | -| 241 | 💎 Tier 3 | **binary crate の module symbol を `pub(crate)` 限定 + CLAUDE.md 明文化 (PR #230 post-merge-feedback T3-#2 採用)** | todo13.md | S | なし (feedback module 分割で write_failed_marker / fetch_pr_diff_summary / FeedbackInput / run 等が external consumer 不在なのに `pub` export = pub(crate) 方針と乖離。refactor PR ごとに再発する systemic pattern (Frequency Medium)。CLAUDE.md 明文化 + pub→pub(crate) 揃えで Effort S。Adoption Risk None) | -| 243 | 💎 Tier 3 | **`pub(crate)` vs `pub` 可視性チェックリストを module split 手順に追加 (PR #231 post-merge-feedback T3-1 採用)** | todo13.md | XS | なし (W-series module split で visibility scoping の判断が都度必要 = crate 内共有は `pub(crate)`、`pub` は同一 crate 内では有効だが library target 公開時のみ外部 API 化 (binary crate では pub(crate) と実質同等ゆえ pub(crate) 推奨) の違いを具体例付きで明示。Frequency Medium (file-length 強制継続で split 継続) + Effort XS + Adoption Risk None。順位 241 (pub(crate) 方針) と相補、追記先の file-length-enforcement-plan.md は W5 land 後削除予定のため coding-style.md / CLAUDE.md への恒久配置を着手時判断) | -| 244 | 💎 Tier 3 | **per-module test helper 複製方針を coding-style.md に明文化 (PR #231 post-merge-feedback T3-2 採用)** | todo13.md | XS | なし (`unique_temp_root` / `write_meta` / `parked_state` 等の test helper を各 module に複製し shared util module を作らない方針が前提知識化しておらず split の度に混乱。coupling vs isolation トレードオフの根拠 + split レビュー確認項目を coding-style.md に追記。Frequency Medium + Effort XS + Adoption Risk None、memory `feedback_test_dry_antipattern` の恒久 codify) | -| 245 | 💎 Tier 3 | **`PR_SIZE_CHECK_OVERRIDE=1` 適用ポリシーを push-runner-config.toml に明文化 (PR #231 post-merge-feedback T3-3 採用)** | todo13.md | XS | なし (override の使い方が「知っている人だけが知る」暗黙知化、機械的 refactor (削除≒追加) の定義と override 判断基準を push-runner-config.toml の `[pr_size_check]` コメントまたは docs に追記。file-length 強制継続で機械 refactor の override 判断は今後も発生 (Frequency Medium) + Effort XS + Adoption Risk None) | -| 246 | 🔧 Tier 2 | **monitor の CI 完了判定を短絡 — CodeRabbit review-complete + mergeability CLEAN で CI 待機を skip し merge-ready 判定 (PR #232 post-merge-feedback T2-1 採用)** | todo13.md | S | なし (CodeRabbit のみが check の構成 (GitHub Actions 等の実 CI 不在) で monitor が「CI: pending」を無限に誤報し、GitHub API 直接確認 (mergeStateStatus=CLEAN / mergeable=MERGEABLE) で merge 可能を確認する手動対応が PR #231/#232 で 2 回発生 = 幻の CI pending。docs-only PR の共通 pattern で再現見込み。poll ループに「review 完了 + mergeability CLEAN なら CI 待機を短絡」条件分岐を追加 (parse logic 改修不要)。Severity Medium + Frequency Medium + Effort S + Adoption Risk None) | -| 247 | 💎 Tier 3 | **`review-jj-robustness-whole` facet (観点⑧) の dogfood + bounded-lifetime 評価 (ADR-031 拡張、PR-2) ★ 週次拡張** | todo13.md | S | なし (PR-2 で ADR-031 週次に観点⑧ jj-workspace robustness facet 追加。非 colocated / 並列 jj workspace の silent bug 4 class = mtime staleness / `CARGO_MANIFEST_DIR` 実行時読み / `--repo` 無し gh / colocated `.git` 前提 を whole-tree 検出。新規実験 facet ゆえ ADR-039 bounded-lifetime で 2-3 週 dogfood → 採用率 / false positive で定着 or retire 判定。2026-07 セッションで 4 bug class 実観測が起点) | -| 248 | 💎 Tier 3 | **Gate Function Design Checklist を新規 guide として追加 (fail-closed パターン集) (PR #234 post-merge-feedback T3-1 採用)** | todo13.md | S | なし (却下した linter 化 T1-1/T1-2 の補完。fail-closed 実装の失敗/推奨パターンを 1 箇所に集約。PR #234 で collect_oversize_files 初版の `.ok()?` が fail-open bug → CodeRabbit Major #234-1。Severity Medium + Frequency Medium + Effort S + Adoption Risk None、順位 249 と相補) | -| 249 | 💎 Tier 3 | **ADR-043 に fail-open vs fail-closed の具体コード例を追記 (PR #234 post-merge-feedback T3-2 採用)** | todo13.md | S | なし (ADR-043 は security-critical だが具体コード例が未記載で解釈分散が今回の bug を生んだ。`.ok()?` anti-pattern / single-read + ErrorKind idiom / multi-step vs 単一操作の比較を ADR 本文に追記。Severity Medium + Frequency Medium + Effort S + Adoption Risk None、順位 248 と相補) | -| 250 | 💎 Tier 3 | **ADR-021 に「jj revset の base branch は config/arg 化 (hardcode 禁止)」を明文化 (PR #234 post-merge-feedback T3-3 採用)** | todo13.md | XS | なし (PR #234 で `[file_length_gate] base` を config 引数化 = ADR-021 準拠。custom lint ⑫ `no-hardcoded-jj-revset-range` は `.rs` の `master..@` literal を捕捉するが、TOML config / docs / 他ツールへの原則適用は未明文化。Severity Low + Frequency Medium + Effort XS + Adoption Risk None) | -| 252 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): 部分効果 env var anti-pattern の文書化 (PR #239 post-merge-feedback T3-1 採用)** | todo13.md | S | なし (`GH_REPO` が gh pr 系に効き引数なし `gh repo view` に効かない partial coverage が PR #238 で「マージ成功 / feedback silent 消失」を招いた実例を原則化。gh-repo-env-guard preset = 機械層 (PR #239 実装済) に対する文書層の 2 層防御、同型ショートカット提案 (`GH_HOST` 等) への review guard、順位 135 placeholder policy 適用、CLAUDE.md はリンクのみ = ADR-022 方針) | -| 253 | 💎 Tier 3 | **ADR-030 に PR #239 の feedback silent skip 実装記録を追記 (PR #239 post-merge-feedback T3-2 採用)** | todo13.md | XS | なし (owner_repo 検出失敗 → marker 未書込 → L2 recovery 未発動の silent skip シナリオ (PR #238 実観測) と `AiStepContext::SkipWithMarker` による対処を ADR-030 に実装記録として残す。Severity Low = 既修正、次回 ADR-030 参照 PR への同乗で消化可) | -| 254 | 🔧 Tier 2 | **pr_size_check の base を remote tracking ref に変更 — 並列 workspace のローカル master 遅延による誤計測解消 (順位242 push で実観測)** | todo13.md | XS-S | なし (`[pr_size_check] default_branch = "master"` がローカル bookmark 基準の revset `master..@` を使うため、ADR-045 並列 workspace でローカル master が遅延すると merge 済み PR 分を合算して誤計測。順位 242 push で実 diff ~160 行が 1604 行と誤 block された実害、PR #239/#240 でも warning を静かに誤超過。ADR-013 の「remote tracking ref を使う」原則 (sync_local で test 固定済) を pr_size_check にも適用、`[file_length_gate] base` も同点検、順位 250 と相補) | -| 255 | 💎 Tier 3 | **ADR-040 の実測値を新 GPU (RTX PRO 5000 48GB) で再 calibration (ADR-046 WP-01 スパイクで陳腐化を観測)** | todo13.md | S | なし (ADR-038/040 が前提とする RTX 3070 8GB は RTX PRO 5000 Blackwell 48GB に更新済み。27-31B Q4 モデルが 100% GPU で動き VRAM が制約でなくなったため、ADR-040 の VRAM/latency trade-off 表と「VRAM scarcity → model swap 制約」framing が陳腐化。ADR-046 で mistral:7b / gemma4 / qwen3-coder の VRAM・latency を実測済 → ADR-040 amendment に反映、num_ctx 選定 flow の memory 軸を latency 軸へ再重み付け) | -| 256 | ⏳ Tier 5 | **classifier FP 検出強化プロンプトで格上げ候補を再評価 (WP-04 見送りの follow-up、ADR-038 amendment 由来)** | todo13.md | M | なし (WP-04 実測で全候補が FP 検出未達 = 能力限界か `classify.txt` の mistral 向け tune 不適合かが未分離。FP 検出強化プロンプト版で qwen3-coder:30b 等を再測し、能力限界と確認できれば恒久見送り、プロンプト不適合なら該当モデル + 専用プロンプトで格上げ。eval 手法・gold セットは scratchpad WP-04 資産を再利用。materially better な新モデル出現時も再評価トリガー) | -| 257 | ⏳ Tier 5 | **push pipeline の `cargo test` を cargo-nextest 化 (WP-05 で Stop hook には無効と判明、push 側 follow-up)** | todo13.md | S-M | なし (WP-05 実測: Stop hook は cargo test 不在で nextest 非適用、真因は逐次実行→並列化で解決済。ただし push pipeline (cli-push-runner quality_gate) の `cargo test -- --ignored` は実測 ~80s で nextest 高速化の余地あり。ツール依存追加 = ADR-017 pinning + 派生プロジェクト配布のコスト、push が Stop より低頻度な点を踏まえた費用対効果を評価。doctest は nextest 非実行のため `cargo test --doc` 併走が必要) | -| 264 | 🔧 Tier 2 | **pre-push review-diff.txt の生成形式を `jj diff --git` に切替 — LLM レビュアーの add/delete 誤読解消 (PR #256 post-merge-feedback Tier1 #1 採用)** | todo13.md | S | なし (`push-runner-config.toml:113` の `[diff] command = "jj diff -r @"` は色+行番号2列形式で、色を落とした review-diff.txt では削除が `-` マーカー無しになり LLM レビュアーが「追加」と誤読。PR #256 で todo 25行削除を simplicity-review が false positive REJECT し ~19分浪費。`jj diff --git -r @` へ切替で解消、`templates/push-runner-config.toml:52` も同 PR で修正必須 (deploy:hooks 配布)、Adoption Risk None、memory `prepush-review-diff-plain-format-misread.md`) | -| 272 | 🚀 Tier 1 | **cli-docs-lint に ADR 重複採番 + CLAUDE.md 索引整合チェック追加 (PR #261 post-merge-feedback T1-#2 採用)** | todo13.md | S | なし (PR #261 で ADR-052/053 採番衝突が実発生、既存 cli-docs-lint の check-mode 骨格流用。順位 135 placeholder policy は todo entry 側の「ルール」で本 entry は land 済ファイルの「仕組み」検知、相補で重複ではない) | -| 275 | 🔧 Tier 2 | **層別テストテンプレート (StubOllama パターン・integration 独立性) の共有化 (PR #265 post-merge-feedback T2-1 採用)** | todo13.md | M | なし (WP-11/ADR-054 の多層防御実装で「空 StubOllama による LLM 未呼び出し証明」「tempdir+jj init+CwdRestore の integration 独立性」を都度設計。WP-17 の classifier/scope guard 拡張で同種判断が再発見込み。shared crate 化の境界は ADR-044 で判定、WP-17 着手前の実施が効果的) | -| 276 | 💎 Tier 3 | **ADR-007 に「コメント配置の意思決定フロー」を追加 (PR #265 post-merge-feedback T3-2 採用)** | todo13.md | S | なし (PR #265 で非 doc コメントの Bundle Z block が 2 回発生 = doc コメント/識別子名/マーカー付き Why の配置判断が未文書化。linter 自動化は NLP 必要で却下済み、既存 Q1-Q3 形式で人間/AI の判断補助を doc 化。バッチ PR で消化可) | -| 277 | 💎 Tier 3 | **PR body 配置タイミング規約を dev-conventions に明記 (PR #265 post-merge-feedback T3-3 採用)** | todo13.md | XS | なし (push パイプライン実行中の working copy に `__pr-body.md` を作成し snapshot 混入をかろうじて回避したヒヤリハット実発生。「push 完了後に scratchpad で準備し --body-file に絶対パス」を規約化。バッチ PR 消化可、並列安全化 PR docs への相乗りも可) | -| 281 | 🚀 Tier 1 | **config-reading hook の current_dir() 解決を検出する lint rule (PR #267 post-merge-feedback T1-1 採用)** | todo13.md | S | なし (新規 hook が cwd 基準 config 解決を実装し pre-push REJECT → fix 修正の実例。cwd drift による silent fail-open は新規 hook のたびに再発しうる。Severity High。順位 287 と同一 PR bundle 推奨) | -| 282 | 🚀 Tier 1 | **jj-op-verify の変更系 verb 網羅拡大 — undo/restore/split/bookmark move 等 (PR #267 post-merge-feedback T1-2 採用)** | todo13.md | M | なし (特に `jj undo` の検出漏れは lost-update 再発リスク高。拡張時は expected_op_keyword を jj 0.42 実機の op log 出力と要照合) | -| 283 | 🚀 Tier 1 | **jj-op-verify の verb 検出を command-boundary に anchor (PR #267 post-merge-feedback T1-3 採用)** | todo13.md | S | なし (commit message 引用符内の "jj new" 等での false positive 防止。実装時に accepted risk で一度見送った経緯あり = 着手時に実観測 0 件のままか再確認。順位 285 と表裏) | -| 284 | 🔧 Tier 2 | **stale_check_enabled の TOML パーステスト追加 (PR #267 post-merge-feedback T2-1 採用)** | todo13.md | XS | なし (新フィールドのパース経路が未テスト = silent degrade リスク。既存テストへの数行追加で完備) | -| 285 | 🔧 Tier 2 | **jj keyword を含む commit message の tokenization edge-case テスト (PR #267 post-merge-feedback T2-2 採用)** | todo13.md | S | なし (順位 283 と表裏。283 の着手有無に関わらず現行挙動を regression test で固定する価値が独立して残る。283 と同一 PR 消化が効率的) | -| 286 | 🔧 Tier 2 | **config path 解決の cwd 跨ぎ integration test (PR #267 post-merge-feedback T2-3 採用)** | todo13.md | M | なし (FIXED 済 cwd-config bug の regression guard。既存テストは pure parser のみで file-lookup 経路未カバー。Severity High、Adoption Risk = OS 依存) | -| 287 | 💎 Tier 3 | **「config 読み hook は exe-relative 解決必須」convention の明文化 (PR #267 post-merge-feedback T3-1 採用)** | todo13.md | XS | なし (順位 281 の文書層補完。**281 と同一 PR bundle 推奨**、別作業に切り出す価値は低い) | -| 288 | 🚀 Tier 1 | **pre-push review が PR 全体をカバーしない — post-merge の全 run 集約 + push-runner `[diff]` stage の tip-only 範囲修正 (PR #268/#300/#301 feedback 採用、Severity High 3連続再発)** | todo13.md | M | なし (根因は `[diff]` stage `jj diff -r @` が tip のみ = 祖先 code が AI レビュー未経由で merge。`docs_only_routing` は PR 範囲へ修正済だが `[diff]` は非対称。単一 push では全 run 集約でも救えず [diff] 範囲拡張 + bookmark_check 祖先検証が根治。ADR-027 射程はユーザー判断。独立 PR 推奨) | -| 292 | 🔧 Tier 2 | **cli-pr-monitor の lock.rs を token 方式の所有権検証へ統一** | todo13.md | S-M | なし (PR #271 で pipeline_lock.rs に導入した token ベース所有権検証と同型の Drop 無条件削除バグが cli-pr-monitor/src/lock.rs にも残存。参照実装が既にあるため低リスク) | -| 293 | ⏳ Tier 5 | **push-runner の stack push モード (opt-in、YAGNI につき見送り継続)** | todo13.md | M | なし (stacked bookmark 運用の実績が現状なく、必要になった時点で着手する opt-in 拡張として記録のみ) | -| 294 | 💎 Tier 3 | **jj-op-verify hook の位置づけ再整理 — 並列 workspace 安全化ではなく混線緩和層として再分類** | todo13.md | S | なし (検知対象は出力混線の症状であり並列 workspace とは独立に価値を持つ。ADR-045→ADR-053 の枠組みへ紐付け直すドキュメント再整理のみ) | -| 295 | 💎 Tier 3 | **ADR-045 にコミット消失事故の「並列原因」診断が未検証である旨の注記追加** | todo13.md | XS | なし (診断は事後の自己分析に依拠し一次証拠未到達。混線起因の可能性も残ることを confirmation bias の記録として注記) | -| 296 | 🔧 Tier 2 | **Lock stale takeover + Drop の concurrency scenario 拡張テスト (271.md T2-2 採用)** | todo13.md | M | なし (token-based ownership Drop の前提を takeover 後の旧 guard drop までの full cycle で検証、既存 concurrent_stale_takeover_only_one_wins の拡張) | -| 297 | 🔧 Tier 2 | **Pipeline 段階間の状態遷移 E2E テスト (271.md T2-3 採用)** | todo13.md | M | なし (Stage -1〜Stage 3 の段階間 hidden coupling を regression test 化、bookmark が @ に遅延した状態遷移を明示的にカバー) | -| 298 | 💎 Tier 3 | **token ベース ownership check の convention 化 (271.md T3-1 採用)** | todo13.md | S | なし (PID 再利用リスクという業界知見を dev-conventions.md に一般化して記載) | -| 299 | 💎 Tier 3 | **revset で workspace 所有権を判定できない旨の convention 明記 (271.md T3-2 採用)** | todo13.md | XS | なし (`@` 厳密一致の設計判断という negative result を CLAUDE.md に明文化) | -| 300 | 💎 Tier 3 | **Push pipeline 段階間依存性チェック項目の追加 (271.md T3-3 採用)** | todo13.md | S | なし (PR #271 の hidden coupling incident から得た教訓を CLAUDE.md / dev-conventions.md に恒久化) | -| 301 | 🚀 Tier 1 | **TOCTOU (remove+create_new) パターン検出 lint rule — exclusive lock 実装限定 (273.md T1-1 採用)** | todo13.md | S | なし (二重 Acquired バグの根本原因パターンを検出。cli-pr-monitor/lock.rs は設計判断済みのため scope 除外必須) | -| 302 | 💎 Tier 3 | **`takeover_stale_lock_skips_remove_when_snapshot_is_stale` パターンを deterministic concurrency test テンプレートとして記録 (273.md T2-3 採用)** | todo13.md | XS | なし (実スレッドレースより状態不一致を直接注入する決定論的テストパターンを次の並行処理系 PR 向けに記録) | -| 303 | 💎 Tier 3 | **Advisory lock (fail-open) の TOCTOU window 許容可否を明示コメントで残す設計チェックリスト (273.md T3-1 採用)** | todo13.md | XS | なし (cli-pr-monitor/lock.rs が既に実践している判断根拠明示の practice をチェックリスト化) | -| 304 | 💎 Tier 3 | **quality gate 実行中に発見したバグ修正が別 PR に混入した際の jj split + jj rebase 復旧パターンを記録 (273.md T3-3 採用)** | todo13.md | XS | なし (PR #272/#273 分離で実証済みの復旧手順、ADR-045 の並列 workspace リスクとは別種の単一 session 内混入事故。復旧は事後対応であり、分離後は混在した変更に対する gate 実行結果を無効化し各 PR で再実行する手順を含む) | -| 305 | 💎 Tier 3 | **Metrics violation の pre-existing 判定基準の明文化 (273.md T3-4 採用)** | todo13.md | XS | なし (file_size_check / file_length_gate 等 metrics 系 gate が複数稼働中で反復しうる override 正当性の判定基準を明文化) | -| 306 | 💎 Tier 3 | **quality gate isolation 機構を見送り、recovery による risk acceptance とした判断の記録 (negative result) (273.md T3-5 採用)** | todo13.md | S | なし (spike 見送り convention に従い、isolation 機構を却下し recovery コストの低さ (順位304) を理由に risk acceptance した根拠を記録。recovery は isolation の代替ではなく、予防機能の欠如という残存リスクと再検討条件を明記する) | -| 307 | 🔧 Tier 2 | **WP-12 step 2: 発火テレメトリ ROI 棚卸し pre-step (発火 0 の rule/preset/hook を削除候補提示)** | todo13.md | M | なし (**着手条件 = ADR-055 収集層マージから 28 日 warm-up 後**。それ以前は全項目が発火 0 = データ無しで判定無意味。集計は Rust exe、weekly-review に file-length-watchlist 同型 facet で接続、incident 由来ルールは発火 0 でも維持推奨の区別) | -| 308 | 💎 Tier 3 | **WP-12 step 3: ADR-039 bounded lifetime 判定の発火数機械化** | todo13.md | S | 順位 307 (step 2 の集計基盤に依存)。試験運用 ADR 機構の卒業/廃止検討を発火数で自動 promote。step 3 完了で WP-12 完了 | -| 309 | 🚀 Tier 1 | **telemetry の block 記録を実 quality 違反に限定(infra エラー混入除外)(275.md T1-1 採用)** | todo13.md | M | なし (CodeRabbit Major。ADR-055 で「emit 総数」と意図的定義したが WP-12 ROI 棚卸しが infra エラー〔stdin/parse 失敗〕混入で歪むため実 violation パス限定に絞る。3 hook 横断で分割 PR 推奨、ADR-055 amendment 併記) | -| 310 | 🚀 Tier 1 | **custom-regex preset の生 regex が telemetry id に流れる privacy footgun 是正(非ブロッキング follow-up 統合)(275.md T1-2 採用)** | todo13.md | S | なし (現行 config は named preset のみで非発火だが派生プロジェクトの latent footgun。fallback を合成 id〔"custom-block"〕に正規化 + ADR-055 に config privacy 注記) | -| 311 | 🚀 Tier 1 | **逐語的関数複製(3+ コピー)を pre-push 検出する DRY lint rule (275.md T1-3 採用)** | todo13.md | M | なし (is_truthy 三重複製事案。ADR-007 regex 層に threshold 検出追加。順位 313 の fixture と抱き合わせ) | -| 312 | 🔧 Tier 2 | **`.claude/telemetry/` の per-pid×日次 partition ファイル retention/cleanup (275.md T2-1 採用)** | todo13.md | M | 順位 307 (WP-12 step 2 と同時期=step1 マージから 28 日後 2026-08-12 頃に着手) | -| 313 | 🔧 Tier 2 | **is_truthy 三重複製を ADR-049 incident fixture 化 (275.md T2-4 採用)** | todo13.md | XS | 順位 311 (DRY lint rule と抱き合わせ) | -| 314 | 🔧 Tier 2 | **bookmark 未作成での push 失敗(exit 7)のエラーメッセージ改善 (275.md T2-5 採用)** | todo13.md | S | なし (本セッションで実発生。bookmark 自動作成は ADR-011 の明示命名意図と緊張するためメッセージ改善のみ) | -| 315 | 💎 Tier 3 | **ADR-055 telemetry の bounded lifetime 期限を config コメントに明記 (275.md T3-1 採用)** | todo13.md | XS | なし (warm-up 期限 2026-08-12 頃 + 順位 307/308 リンクを `[telemetry]` section コメントに追記) | -| 316 | 💎 Tier 3 | **ADR-044「2nd consumer で共通化」原則の明確化・判定基準の例示 (275.md T3-2 採用)** | todo13.md | S | なし (is_truthy の非対称性を case study 化。順位 317 と対) | -| 317 | 💎 Tier 3 | **utility 関数追加前のチェックリスト(workspace grep)(275.md T3-3 採用)** | todo13.md | XS | 順位 316 (ADR-044 明確化と対) | -| 318 | 🚀 Tier 1 | **CR rate-limit 第3 format (`Next review available in: N minutes`) 未対応 + marker 一致/regex 不一致の silent 化 (PR #287 で実観測)** | todo13.md | S | なし (ADR-034 § 検出 logic 更新手順 の 4-6 をそのまま適用可。silent 化解消は追加設計) | -| 319 | 🚀 Tier 1 | **pr-monitor.yml バックストップの重複ガードが構造的に機能しない — CR 投稿ごとに分析コメントを再投稿 (PR #287 で 5 件実観測)** | todo13.md | S | なし (ガードが LLM prompt 内にあり、トリガー事象自身が skip 条件を無効化するトートロジー) | -| 320 | 🔧 Tier 2 | **CodeRabbit status check は実レビュー有無に関わらず `pass` — 緑チェックを「レビュー済み」の根拠にしない (PR #287 で実観測)** | todo13.md | S | 順位 318 (決定論的な rate-limit 検知が前提) | -| 321 | 🔧 Tier 2 | **ADR-019/WP-03 クォータ設計の前提 stale (無料枠 → Pro + adaptive limit) + 初回レビュー処理中 push のレビュー欠落穴** | todo13.md | S | なし (dev-conventions 順位 262「外部 SaaS 無料枠/制限の調査チェックリスト」の適用対象) | -| 322 | 🚀 Tier 1 | **post-merge-feedback が repo root に scratch script を残し `scratch_file_warning` の pattern をすり抜ける (near-miss 実観測)** | todo13.md | S | なし (PR #85 と同一クラス。pattern 列挙 (deny-list) の構造的限界が露呈) | -| 323 | 🚀 Tier 1 | **`lib-subprocess` `run_cmd_shell_*` の timeout が wall-clock を縛れない — 孫プロセス残存で join がブロック (push-pipeline-fix-plan §6 backlog 10 移管)** | todo13.md | S | なし (quality_gate step_timeout / push timeout / cli-merge-pipeline のハング打ち切りが実質無効。#286 post-merge-feedback の orphan/stale marker と同根の実害 1 件観測済。回帰テストに経過時間 assert 必須 = T6 教訓) | -| 324 | 🚀 Tier 1 | **`cli-pr-monitor::push_to_remote` に push 拒否検知が無く post-PR re-push が無言で失敗し得る (push-pipeline-fix-plan §6 backlog 9 移管)** | todo13.md | XS | なし (T5 = PR #282 が cli-push-runner 側で塞いだ silent-failure push と同型の穴。出力は `run_cmd_direct` で全量取得済のため判定追加のみ) | -| 326 | 🔧 Tier 2 | **並列設計レビュアー (design-fit reviewer) の実験起案 — 見落とし実績の事前調査付き (R4/ADR-047 却下分析の代替案)** | todo13.md | S (Phase 0) / M (Phase 1 条件付き) | なし (Phase 0 の需要調査で見落とし実績ゼロなら見送り = negative result 永続化。ADR-047 却下確定 = refute.yaml 削除 revert PR とは独立に進められる) | -| 327 | 🔧 Tier 3 | **多段コミットの ADR/observability 更新チェックリストを dev-conventions に追加 (#295/#296 post-merge feedback 採用: status 同期 / plain-text 参照 / セクション同期)** | todo13.md | S | なし (実害は各 PR review/feedback で捕捉済。doc checklist のみ、機械化は再発観測後にエスカレーション) | -| 328 | 🚀 Tier 1 | **post-merge feedback が成功後に `post-merge-feedback-context.json` を残し次マージの feedback を誤 bail させる (cleanup gap、#296 マージで実観測)** | todo13.md | S | なし (連続マージで後発 PR の再発防止分析が構造的に skip。成功時 cleanup の追加 + 回帰テスト。ADR-030 L2 recovery で今回は手動救済済) | -| 329 | 💎 Tier 3 | **新規 ADR 起案時の「判断根拠 × 既存 ADR 定義」矛盾チェックリストを dev-conventions に追加 (#301 post-merge feedback 採用)** | todo13.md | S | なし (ADR-055 初版が自定義の `decision` 軸と矛盾する除外根拠を採用→Amendment 撤回の手戻り。ADR 59件超で同型見落とし再発しうる。#327 と対の doc-only 対処) | -| 330 | 💎 Tier 3 | **「行動要求 nudge は 2 チャネル返却」+「多義的戻り値は struct 化」convention の明文化 (#299 post-merge feedback 採用)** | todo13.md | XS | なし (ADR-059 の 2 チャネルパターンと `WeeklyReviewNudge` struct 化。第2弾展開 3件で再利用見込み。dev-conventions 1節追記) | -| 331 | 🔧 Tier 2 | **hooks-session-start に systemMessage を含む JSON 出力の exe-spawn E2E テスト追加 (#299 post-merge feedback 採用)** | todo13.md | S | なし (現状 pure function レベルのみ、実 config パース込み exe 駆動の検証なし。ADR-049 exe-spawn E2E 先例流用。UI 実描画確認は別途 dogfood) | -| 332 | 🔧 Tier 2 | **`pnpm build:all` 前に git usr/bin (cp.exe) PATH 未設定を自動検出・追加 (#301 post-merge feedback 採用)** | todo13.md | S | なし (Windows で pnpm が cmd.exe 経由実行のため `cp` 解決失敗。memory 既記録だが再発2回目。Windows 限定 additive 分岐、他OS非影響) | -| 333 | 🔧 Tier 2 | **VSCode 拡張が hook `systemMessage` を UI 描画するかの調査 (ADR-059 dogfood / 削除条件 2、2026-07-19 週次レビュー観測)** | todo14.md | S | なし (2026-07-19 dogfood で VSCode UI での systemMessage 独立描画が未確認 = additionalContext 経由のみ観測。ターミナル CLI との挙動差を切り分け。ADR-059 bounded-lifetime 判定 期限 2026-08-16 の blocker。描画なしでも defense-in-depth backstop あり revert 不要) | -| 334 | 🚀 Tier 1 | **docs/todo*.md 本文の順位番号表記を検出する custom lint rule (ADR-033 使用禁止の仕組み化、#303 post-merge feedback 採用)** | todo14.md | S | なし (ADR-033 が禁止規定 + 将来の展望で lint 検討済みだが未実装 約3ヶ月。検証 grep 実証済み、literal-ban rule⑥/⑪ と同型) | -| 335 | 🔧 Tier 2 | **post-merge-feedback の transcript 分析を cli-merge-pipeline 生成 summary index に置換 (#303 post-merge feedback 採用)** | todo14.md | M | なし (session-analysis facet が約 1.5MB transcript で 25K token limit 衝突・避難措置を自己観測。既存 filter の自然な拡張、Frequency High) | - -**戦略**: 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 責務集中のため)。 +| 215 | 💎 Tier 3 | **`~/.claude/rules/common/coding-style.md` に「Defensive State Reset in State Machines」section 追加 (PR #214 post-merge-feedback T3-1 採用)** | todo18.md | S | なし (PR #214 round 2 で `finalize_initial_review_park` の `state.pr` / `state.repo` / `state.started_at` を `read_state()` 後に無条件上書きする pattern が CR Major #4 の fix として land、CR Major #1 (`head_commit`) + CR Major #2 (`review_recheck_count`) と同型の defensive reset が既に 3 field 適用済 = `review_recheck.rs` 内で複数 instance あり、将来の reviewer が「redundant」と誤判定して削除すると prior cycle の stale state が混入して silent bug 化、global rules への docs 追記で派生プロジェクト (techbook-ledger / auto-review-fix-vc) に自動波及、simplicity-review LLM が同 file を読むため "enforced via review" として機能し memory `feedback_no_unenforced_rules` 例外を満たす、`feedback_global_config_backup` 適用必須) | +| 216 | 🔧 Tier 2 | **`no-workstream-seq-names-in-config` lint rule 追加 — config comment 内 `PR-[0-9]+` ephemeral workstream sequence 検出 (PR #216 post-merge-feedback T1-1 採用) ★ Bundle 216-217** | todo18.md | S | なし (PR #216 で `hooks-config.toml` comment に "PR-1" / "PR-3" workstream sequence を書き込んだ違反を post-merge-feedback T1-1 で捕捉、rule⑥ `no-ephemeral-todo-reference` は `docs/todo*.md` file path のみ catch するが workstream sequence names は対象外、pattern `(?i)\bPR-[0-9]+\b` で `.toml`/`.yaml`/`.yml`/`.jsonc`/`.json` comment を対象、`#NNN` GitHub PR 表記は exception で除外、rule⑫ と同 pattern (TOML `test_coverage` meta field + main.rs test) で Effort S、順位 217 と同根 = 1 PR bundle 推奨。**Tier 列との不整合補足**: analyzer feedback report の `Tier 1: Hooks/Linter 改善` カテゴリは project Tier 1 (🚀 high-impact urgent) ではなく memory `feedback_tier_classification` の re-classification rule (mechanical enforcement = T2 / docs 修正 = T3) に従い project Tier 2 (🔧 tooling improvements) に再分類) | +| 217 | 💎 Tier 3 | **`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に config file comments の permanent artifact 扱い + workstream sequence 禁止例追加 (PR #216 post-merge-feedback T3-1 採用) ★ Bundle 216-217** | todo18.md | XS | なし (順位 216 lint rule と同根、本 task は文書層 = author 理解促進、機械層 (216) との 2 層防御、coding-style.md 既存 § Cross-File Reference Lifecycle は markdown 内 cross-ref を主想定で config file comments の permanent artifact 扱いが暗黙的、workstream sequence names (`PR-1`/`PR-3` 等) 禁止例 + GitHub PR numbers (`#NNN`) 代替を明示、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ global 経由で自動波及、`feedback_global_config_backup` 適用必須、順位 216 と 1 PR bundle 推奨) | +| 218 | 💎 Tier 3 | **ADR-039 § Bounded Lifetime + `~/.claude/rules/common/patterns.md` に provisional `enabled` 変更時の todo entry 必須化を追加 (PR #216 post-merge-feedback T3-2 採用)** | todo18.md | XS | なし (PR #216 で `weekly_review_reminder.enabled = true` の provisional 状態を config comment のみで tracking した silent aging risk を post-merge-feedback T3-2 で捕捉、ADR-039 6-point design checklist に「provisional `enabled` 変更時は `docs/todo*.md` に移行 tracking entry を作成」を追加、`~/.claude/rules/common/patterns.md` § Experimental Feature 設計時の参照必須 にも同旨 note 追加、Frequency Low (初観測) + Adoption Risk None で早期 codify、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ global 経由で自動波及、`feedback_global_config_backup` 適用必須) | +| 219 | 💎 Tier 3 | **`~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に「commit description 言及 ≠ 実装完了」明文化 (PR #216 post-merge-feedback T3-3 採用)** | todo18.md | XS | なし (本 PR で「commit description で順位 N 言及 = 実装完了」naïve assumption から analyzer が 6 entry 削除計画を立てたが、grep で実体確認した結果 5 entry が正解 (順位 215 救出) の実観測、「PR commit description で順位 N や feature X を言及していても、実際のファイル変更を `jj diff` / `grep` で確認するまで completion 判定しない」guideline を追加、Frequency Low (初観測) + Severity Medium (analyzer / Claude 誤判定リスクが今後も継続)、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ global 経由で自動波及、`feedback_global_config_backup` 適用必須) | diff --git a/docs/todo-summary2.md b/docs/todo-summary2.md new file mode 100644 index 00000000..5347e8fa --- /dev/null +++ b/docs/todo-summary2.md @@ -0,0 +1,102 @@ +# TODO 推奨実行順序サマリー (続き、順位 220 以降) + +> **本ファイルの位置付け**: [docs/todo-summary.md](todo-summary.md) の推奨実行順序 table を docs 50KB 超過解消のため 2 分割した後半 (順位 220 以降を収容、2026-07-20)。全体の位置付け・更新方針・順位 6-219・anchor は [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。新規行 (高 順位) の追加・順位再採番は本ファイル (末尾) で行い、todo-summary.md 側の更新方針に従う。cli-docs-lint の priority-inversion / preamble check は両ファイルを統合して検査する。 + +## 推奨実行順序サマリー (続き、順位 220 以降) + +| 順位 | Tier | タスク | ファイル | 工数 | 依存 | +|---|---|---|---|---|---| +| 220 | 🔧 Tier 2 | **subprocess stress test (>64KB stdout) を ADR-031 weekly-review pipeline 経由で週次実行 (PR #217 post-merge-feedback T2-1 採用、ユーザー判断 2026-06-23 = hooks/pre-push には組み込まず週次に分離)** | todo19.md | M | なし (PR #217 で 2 module (jj_helpers.rs / todo_staleness.rs) に同型 subprocess deadlock pattern が独立観測 = Severity High + Frequency Medium、ただし手動検証困難な大 buffer 顕在化テストは毎回実行 (Stop hook / pre-push) には不適切で開発速度に影響、`#[ignore]` 付きで cargo test default skip + ADR-031 weekly workflow の rust-stress step として明示実行 (`cargo test -- --ignored --test-threads=1` 想定)、対象 = lib-subprocess の `drain_pipe_unlimited` + `wait_with_timeout_basic` 利用箇所、順位 221 (ADR docs) と test+docs の 2 層防御で相補) | +| 221 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Safe Subprocess Stdout Pattern を ADR-016 appendix or 新 ADR で codify (PR #217 post-merge-feedback T3-1 採用)** | todo19.md | S | なし (PR #217 で `Stdio::piped()` を伴う `jj` spawn が 2 module で同一 pattern 違反 (concurrent drain なし → pipe buffer 枯渇 deadlock) を independent 観測、Severity Low + Frequency Medium + None risk、解決 pattern (`spawn_stdout_drainer` + `poll_child_with_deadline` または `lib_subprocess::drain_pipe_unlimited` + `wait_with_timeout_basic` の wrap、もしくは `Command::output()` / `Stdio::null()` の 3 択) を ADR-016 § 長時間コマンド戦略 への appendix or 新 ADR として明文化、ADR-025 CwdRestore guard pattern を precedent として cite、派生プロジェクト transferability 確保、順位 220 (test 層) と 1 PR bundle 推奨) | +| 222 | 💎 Tier 3 | **`~/.claude/CLAUDE.md` に「複数セッション跨ぎの計画文書作成時は AI が先走らずユーザー確認後に方針報告し GO/NO-GO を得る」ルール追加 (PR #218 post-merge-feedback #5 採用)** | todo19.md | XS | なし (PR #218 (docs PR) 本セッション内で Plan file 作成完了報告後、AI がユーザー承認なしに PR-W0 着手しようとして `[Request interrupted by user]` で停止された実観測、Severity Medium (AI 暴走 = UX 劣化) + Frequency Low (初観測) + Effort XS + Adoption Risk None、`~/.claude/CLAUDE.md` への 1 段落追記で全プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須、memory `feedback_no_unauthorized_reorder` の補強として「計画書 / planning doc 作成のような大きな task 完了時は GO/NO-GO 確認を待つ」を明文化、本 ルール採用後は Auto mode でも planning doc レベルの完了時点では明示承認待ちが必須となる) | +| 223 | 🔧 Tier 2 | **`ACTIVE_RUN_FRESH_THRESHOLD_SECS` と `ORPHAN_THRESHOLD_SECS` の compile-time 同期 (PR #222 post-merge-feedback T1-1 採用) ★ Bundle 222-FB** | todo19.md | M | なし (PR #222 で hooks-stop-quality に追加した `ACTIVE_RUN_FRESH_THRESHOLD_SECS = 1500` と hooks-session-start reaper の `ORPHAN_THRESHOLD_SECS = 1500` は同値必須 = 非対称になると両防御層の隙間に挟まる run が漏れる、現状はコメント契約のみで mechanical enforcement 欠落、`cli-merge-pipeline/src/feedback.rs:60` の derived const + 上流定数 precedent を cross-crate に拡張、Option C ベース (const re-export + `const _: () = assert!(...)` compile-time check) を MVP 推奨、analyzer Tier 1 = mechanical enforcement → memory `feedback_tier_classification` per project Tier 2 に再分類、順位 224 と 1 PR bundle 推奨 = mechanical + docs 2 層防御) | +| 224 | 💎 Tier 3 | **ADR-043 (Security/Quality Gate Fail-Closed) に hooks-stop-quality の error handling を具体例として追記 (PR #222 post-merge-feedback T3-1 採用) ★ Bundle 222-FB** | todo19.md | XS | なし (PR #222 `meta_is_fresh()` / `meta_is_active_run()` / `takt_subsession_active()` の 4 error path (mtime 取得失敗 / clock skew / malformed JSON / file read error) すべてが `false` 返却 → gate effective に倒れる fail-closed 構造を ADR-043 の concrete instantiation として codify、ADR が「概念定義 + 具体例 list」型に進化、派生プロジェクトへの transferability 向上、Severity Low + Frequency Medium + Effort XS + Adoption Risk None、順位 223 (mechanical) と相補 = 1 PR bundle 推奨、PR #222 / ADR-004 / ADR-043 の 3 文書 cross-reference 成立) | +| 225 | 🚀 Tier 1 | **auto-push gate-bypass の是正 — A1 (fix facet で `--ignored` 必須) + B1-loop (auto-push に gate + convergence ループ差し戻し、fail-closed) (PR #224 セッション合意)** | todo13.md | M | なし (Status update 2026-07-03: PR-1 で A1 + B1 (gate 即 escalation 方式、docs-only skip 付き) 実装済。B1-loop は docs/auto-push-gate-dogfood.md の観測ログ + GO/NO-GO 基準による dogfood 判定待ち — 期限: PR-1 merge + 6 週間 / gate FAIL 2 件 / auto-push 発火 10 回のいずれか先) | +| 226 | 🚀 Tier 1 | **fmt baseline cleanup + `cargo fmt --check` gate 導入 + rustfmt 固定 (PR #224 セッション合意)** | todo13.md | M | なし (fmt enforcement がリポジトリに皆無で workspace 29 ファイルが rustfmt-clean でないドリフト蓄積。(A) `cargo fmt --all` 一括正規化 → (B) fmt --check を Stop/push gate に追加 → (C) rust-toolchain.toml で rustfmt 固定、の順。file_length plan と同型「clean baseline → gate」) | +| 227 | 🚀 Tier 1 | **rule⑬: 非テストコードでの理由なし `#[allow(...)]` 禁止 custom lint (PR #224 セッション合意)** | todo13.md | S | なし (`#[allow]` = lint の握り潰し、既存 swallowed-error 系 rule③/④/⑩ と同 philosophy。justification マーカー無しの `#[allow(...)]` を warning 検出、test code 除外方式は着手時判断、rule_test_coverage_check で positive/negative test 機械強制) | +| 228 | 🔧 Tier 2 | **`rate_limit_signal::cr_clean` の regression test (PR #224 post-merge-feedback T2-1 採用)** | todo13.md | S | なし (Fix 3 で拡張した `unresolved_threads` / `new_comments` / `actionable_comments` 3 field の clean 判定の回帰防止、None/境界ケース網羅、silent-clean 誤認の保護) | +| 231 | 💎 Tier 3 | **ADR-022 拡張 — pre-create cleanup flow 例 + agent fmt スコープ指針 (PR #224 post-merge-feedback T3-1 採用)** | todo13.md | S | なし (CodeRabbit が `create_fix_commit` の空 findings 設計を bug 誤判定=却下 CR#2、agent 無差別 fmt の 2 事象を ADR-022 責務分離で codify、doc-only) | +| 232 | 🔧 Tier 2 | **post-merge-feedback / workflow agent の repo 作業ツリー書込禁止 + 検知安全網 (PR #224 セッション合意)** | todo13.md | S-M | なし (merge 時に analyze-session agent が repo root に throwaway script (parse_transcript.py) を残した、日常工程ゆえ累積リスク = コンテキスト汚染。(1) feedback facets に repo 書込禁止 + jq/scratch 使用を明記 (2) post_steps/Stop hook で root 新規 untracked を warning 検知 (3) gitignore は補助) | +| 233 | 🔧 Tier 2 | **post-pr-review (takt) の diff scope を PR 全体に修正 — `@` 限定による docs-only 誤判定解消 (PR #227 観測)** | todo13.md | M | なし (PR #227 で post-pr-review analyze が `@` コミット (docs のみ) の diff を見て PR を docs-only 誤判定し、CodeRabbit が PR 全体で出した finding (create_pr.rs:208) を ADR-035 docs-only filter で誤って適用外化。今回は finding も false positive (composition root) だったため実害なしだが有効 finding 見逃しリスク。根因は ADR-027 pre-push-review の `jj diff -r @` 由来 review-diff.txt 流用 or post-pr-review 独自 @ 限定 diff 生成の疑い。diff scope を PR 全体 (base..head) に修正 or 分類を CodeRabbit findings file path 基準に変更) | +| 234 | 💎 Tier 3 | **memory `feedback-di-over-ambient-global-tests` に serialization primitive 例外境界 + PR #227 具体例を追記 (PR #227 post-merge-feedback T3-1 採用)** | todo13.md | XS | なし (PR #227 が memory 原則「DI over ambient global」の 2 例目 = PR #224 env_override_lock も同根、Frequency Medium。(a) `PR_MONITOR_STATE_FILE_OVERRIDE` race → `state_path: &Path` DI 解消の具体例 (b) serialization primitive `OnceLock>` は複製禁止だが通常 test helper は複製推奨という例外境界、を追記。「DI over ambient global」と「helper 複製推奨」の見かけの矛盾を解消。順位 235 と相補) | +| 235 | 💎 Tier 3 | **ADR-022 に Serialization Primitive Single-Instance Rule の Appendix 追加 (PR #227 post-merge-feedback T3-2 採用)** | todo13.md | S | なし (PR #224 T2-2 共有 env_override_lock helper 抽出 + PR #227 で同根の serialization primitive 単一化問題 2 PR 観測 = Frequency Medium。`OnceLock>` 等を複製すると各々独立した Mutex になり競合排除が破壊される特殊ケースを ADR-022 Appendix で明文化、通常 helper 複製推奨 (DRY) との例外境界を codify。ADR-046 独立化 (feedback T3-3) との overlap は着手時判断、順位 234 と相補) | +| 236 | 🚀 Tier 1 | **tempfile mandate + PID+ms 命名 block の custom lint (PR #229 post-merge-feedback T1-1 採用)** | todo13.md | S | なし (#227 で修正した temp file collision flaky の再導入防止。#229 で本 flaky が push pipeline の `cargo test` を 3 回ブロックした実害。custom lint で `tempfile::Builder` / `NamedTempFile` を mandate + `gh-pr-body-{PID}-{ms}` 形式の手動命名を block。順位 237 = 検出層と二層防御) | +| 237 | 🔧 Tier 2 | **create_pr flaky の高並列 regression test (PR #229 post-merge-feedback T2-1 採用)** | todo13.md | M | なし (#227 flaky fix の再導入検出網。`body_with_literal_newline_converted` を per-test `tempfile::tempdir()` + 高並列 concurrent run で回し collision を恒常 trap。順位 236 = 予防層と二層防御) | +| 238 | 🚀 Tier 1 | **`Command::new("gh")` 直叩き禁止 + timeout wrapper 必須の custom lint (PR #230 post-merge-feedback T1-#1 採用)** | todo13.md | M | なし (fetch_pr_time_range / fetch_pr_diff_summary / run_gh_logged / delete_remote_branch の 4 箇所が `Command::new("gh").output()` 同期実行でネットワーク不調時に無期限ハング = ADR-016 違反、CodeRabbit Major #2/#3。custom lint で直叩きを検出し `run_cmd_shell_capped_reporting` 相当の timeout wrapper を促す。extensions=["rs"] 限定で false positive 軽減。Severity High + Frequency High + Effort M。順位 240 と同 crate、bundle 検討可) | +| 239 | 🔧 Tier 2 | **`filter_transcripts` の複数 jsonl 走査を timestamp ソートで deterministic 化 + regression test (PR #230 post-merge-feedback T2-#1 採用)** | todo13.md | M | なし (`fs::read_dir` の非決定順により複数 Claude セッション時にファイル間時系列順が保証されず downstream takt workflow の context 品質が低下 = ADR-030 determinism 目標と乖離。timestamp ソート + regression test。Severity Medium + Effort M + Adoption Risk None) | +| 240 | 🔧 Tier 2 | **`takt.rs` の spawn/try_wait `Err(_)` 分岐に eprintln 追加 — 原因握り潰し解消 (PR #230 post-merge-feedback T3-#1 採用)** | todo13.md | XS | なし (spawn/try_wait の `Err(_) =>` が詳細を握り潰し `.failed` marker に実原因 (pnpm 未検出 / 権限エラー等) が残らず L2 recovery の debug 困難。`write_pending_marker_logged` 等の確立 eprintln パターン踏襲で XS。Severity Medium + Effort XS + Adoption Risk None、順位 238 と同 crate bundle 検討可) | +| 241 | 💎 Tier 3 | **binary crate の module symbol を `pub(crate)` 限定 + CLAUDE.md 明文化 (PR #230 post-merge-feedback T3-#2 採用)** | todo13.md | S | なし (feedback module 分割で write_failed_marker / fetch_pr_diff_summary / FeedbackInput / run 等が external consumer 不在なのに `pub` export = pub(crate) 方針と乖離。refactor PR ごとに再発する systemic pattern (Frequency Medium)。CLAUDE.md 明文化 + pub→pub(crate) 揃えで Effort S。Adoption Risk None) | +| 243 | 💎 Tier 3 | **`pub(crate)` vs `pub` 可視性チェックリストを module split 手順に追加 (PR #231 post-merge-feedback T3-1 採用)** | todo13.md | XS | なし (W-series module split で visibility scoping の判断が都度必要 = crate 内共有は `pub(crate)`、`pub` は同一 crate 内では有効だが library target 公開時のみ外部 API 化 (binary crate では pub(crate) と実質同等ゆえ pub(crate) 推奨) の違いを具体例付きで明示。Frequency Medium (file-length 強制継続で split 継続) + Effort XS + Adoption Risk None。順位 241 (pub(crate) 方針) と相補、追記先の file-length-enforcement-plan.md は W5 land 後削除予定のため coding-style.md / CLAUDE.md への恒久配置を着手時判断) | +| 244 | 💎 Tier 3 | **per-module test helper 複製方針を coding-style.md に明文化 (PR #231 post-merge-feedback T3-2 採用)** | todo13.md | XS | なし (`unique_temp_root` / `write_meta` / `parked_state` 等の test helper を各 module に複製し shared util module を作らない方針が前提知識化しておらず split の度に混乱。coupling vs isolation トレードオフの根拠 + split レビュー確認項目を coding-style.md に追記。Frequency Medium + Effort XS + Adoption Risk None、memory `feedback_test_dry_antipattern` の恒久 codify) | +| 245 | 💎 Tier 3 | **`PR_SIZE_CHECK_OVERRIDE=1` 適用ポリシーを push-runner-config.toml に明文化 (PR #231 post-merge-feedback T3-3 採用)** | todo13.md | XS | なし (override の使い方が「知っている人だけが知る」暗黙知化、機械的 refactor (削除≒追加) の定義と override 判断基準を push-runner-config.toml の `[pr_size_check]` コメントまたは docs に追記。file-length 強制継続で機械 refactor の override 判断は今後も発生 (Frequency Medium) + Effort XS + Adoption Risk None) | +| 246 | 🔧 Tier 2 | **monitor の CI 完了判定を短絡 — CodeRabbit review-complete + mergeability CLEAN で CI 待機を skip し merge-ready 判定 (PR #232 post-merge-feedback T2-1 採用)** | todo13.md | S | なし (CodeRabbit のみが check の構成 (GitHub Actions 等の実 CI 不在) で monitor が「CI: pending」を無限に誤報し、GitHub API 直接確認 (mergeStateStatus=CLEAN / mergeable=MERGEABLE) で merge 可能を確認する手動対応が PR #231/#232 で 2 回発生 = 幻の CI pending。docs-only PR の共通 pattern で再現見込み。poll ループに「review 完了 + mergeability CLEAN なら CI 待機を短絡」条件分岐を追加 (parse logic 改修不要)。Severity Medium + Frequency Medium + Effort S + Adoption Risk None) | +| 247 | 💎 Tier 3 | **`review-jj-robustness-whole` facet (観点⑧) の dogfood + bounded-lifetime 評価 (ADR-031 拡張、PR-2) ★ 週次拡張** | todo13.md | S | なし (PR-2 で ADR-031 週次に観点⑧ jj-workspace robustness facet 追加。非 colocated / 並列 jj workspace の silent bug 4 class = mtime staleness / `CARGO_MANIFEST_DIR` 実行時読み / `--repo` 無し gh / colocated `.git` 前提 を whole-tree 検出。新規実験 facet ゆえ ADR-039 bounded-lifetime で 2-3 週 dogfood → 採用率 / false positive で定着 or retire 判定。2026-07 セッションで 4 bug class 実観測が起点) | +| 248 | 💎 Tier 3 | **Gate Function Design Checklist を新規 guide として追加 (fail-closed パターン集) (PR #234 post-merge-feedback T3-1 採用)** | todo15.md | S | なし (却下した linter 化 T1-1/T1-2 の補完。fail-closed 実装の失敗/推奨パターンを 1 箇所に集約。PR #234 で collect_oversize_files 初版の `.ok()?` が fail-open bug → CodeRabbit Major #234-1。Severity Medium + Frequency Medium + Effort S + Adoption Risk None、順位 249 と相補) | +| 249 | 💎 Tier 3 | **ADR-043 に fail-open vs fail-closed の具体コード例を追記 (PR #234 post-merge-feedback T3-2 採用)** | todo15.md | S | なし (ADR-043 は security-critical だが具体コード例が未記載で解釈分散が今回の bug を生んだ。`.ok()?` anti-pattern / single-read + ErrorKind idiom / multi-step vs 単一操作の比較を ADR 本文に追記。Severity Medium + Frequency Medium + Effort S + Adoption Risk None、順位 248 と相補) | +| 250 | 💎 Tier 3 | **ADR-021 に「jj revset の base branch は config/arg 化 (hardcode 禁止)」を明文化 (PR #234 post-merge-feedback T3-3 採用)** | todo15.md | XS | なし (PR #234 で `[file_length_gate] base` を config 引数化 = ADR-021 準拠。custom lint ⑫ `no-hardcoded-jj-revset-range` は `.rs` の `master..@` literal を捕捉するが、TOML config / docs / 他ツールへの原則適用は未明文化。Severity Low + Frequency Medium + Effort XS + Adoption Risk None) | +| 252 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): 部分効果 env var anti-pattern の文書化 (PR #239 post-merge-feedback T3-1 採用)** | todo15.md | S | なし (`GH_REPO` が gh pr 系に効き引数なし `gh repo view` に効かない partial coverage が PR #238 で「マージ成功 / feedback silent 消失」を招いた実例を原則化。gh-repo-env-guard preset = 機械層 (PR #239 実装済) に対する文書層の 2 層防御、同型ショートカット提案 (`GH_HOST` 等) への review guard、順位 135 placeholder policy 適用、CLAUDE.md はリンクのみ = ADR-022 方針) | +| 253 | 💎 Tier 3 | **ADR-030 に PR #239 の feedback silent skip 実装記録を追記 (PR #239 post-merge-feedback T3-2 採用)** | todo15.md | XS | なし (owner_repo 検出失敗 → marker 未書込 → L2 recovery 未発動の silent skip シナリオ (PR #238 実観測) と `AiStepContext::SkipWithMarker` による対処を ADR-030 に実装記録として残す。Severity Low = 既修正、次回 ADR-030 参照 PR への同乗で消化可) | +| 254 | 🔧 Tier 2 | **pr_size_check の base を remote tracking ref に変更 — 並列 workspace のローカル master 遅延による誤計測解消 (順位242 push で実観測)** | todo15.md | XS-S | なし (`[pr_size_check] default_branch = "master"` がローカル bookmark 基準の revset `master..@` を使うため、ADR-045 並列 workspace でローカル master が遅延すると merge 済み PR 分を合算して誤計測。順位 242 push で実 diff ~160 行が 1604 行と誤 block された実害、PR #239/#240 でも warning を静かに誤超過。ADR-013 の「remote tracking ref を使う」原則 (sync_local で test 固定済) を pr_size_check にも適用、`[file_length_gate] base` も同点検、順位 250 と相補) | +| 255 | 💎 Tier 3 | **ADR-040 の実測値を新 GPU (RTX PRO 5000 48GB) で再 calibration (ADR-046 WP-01 スパイクで陳腐化を観測)** | todo15.md | S | なし (ADR-038/040 が前提とする RTX 3070 8GB は RTX PRO 5000 Blackwell 48GB に更新済み。27-31B Q4 モデルが 100% GPU で動き VRAM が制約でなくなったため、ADR-040 の VRAM/latency trade-off 表と「VRAM scarcity → model swap 制約」framing が陳腐化。ADR-046 で mistral:7b / gemma4 / qwen3-coder の VRAM・latency を実測済 → ADR-040 amendment に反映、num_ctx 選定 flow の memory 軸を latency 軸へ再重み付け) | +| 256 | ⏳ Tier 5 | **classifier FP 検出強化プロンプトで格上げ候補を再評価 (WP-04 見送りの follow-up、ADR-038 amendment 由来)** | todo15.md | M | なし (WP-04 実測で全候補が FP 検出未達 = 能力限界か `classify.txt` の mistral 向け tune 不適合かが未分離。FP 検出強化プロンプト版で qwen3-coder:30b 等を再測し、能力限界と確認できれば恒久見送り、プロンプト不適合なら該当モデル + 専用プロンプトで格上げ。eval 手法・gold セットは scratchpad WP-04 資産を再利用。materially better な新モデル出現時も再評価トリガー) | +| 257 | ⏳ Tier 5 | **push pipeline の `cargo test` を cargo-nextest 化 (WP-05 で Stop hook には無効と判明、push 側 follow-up)** | todo15.md | S-M | なし (WP-05 実測: Stop hook は cargo test 不在で nextest 非適用、真因は逐次実行→並列化で解決済。ただし push pipeline (cli-push-runner quality_gate) の `cargo test -- --ignored` は実測 ~80s で nextest 高速化の余地あり。ツール依存追加 = ADR-017 pinning + 派生プロジェクト配布のコスト、push が Stop より低頻度な点を踏まえた費用対効果を評価。doctest は nextest 非実行のため `cargo test --doc` 併走が必要) | +| 264 | 🔧 Tier 2 | **pre-push review-diff.txt の生成形式を `jj diff --git` に切替 — LLM レビュアーの add/delete 誤読解消 (PR #256 post-merge-feedback Tier1 #1 採用)** | todo15.md | S | なし (`push-runner-config.toml:113` の `[diff] command = "jj diff -r @"` は色+行番号2列形式で、色を落とした review-diff.txt では削除が `-` マーカー無しになり LLM レビュアーが「追加」と誤読。PR #256 で todo 25行削除を simplicity-review が false positive REJECT し ~19分浪費。`jj diff --git -r @` へ切替で解消、`templates/push-runner-config.toml:52` も同 PR で修正必須 (deploy:hooks 配布)、Adoption Risk None、memory `prepush-review-diff-plain-format-misread.md`) | +| 272 | 🚀 Tier 1 | **cli-docs-lint に ADR 重複採番 + CLAUDE.md 索引整合チェック追加 (PR #261 post-merge-feedback T1-#2 採用)** | todo15.md | S | なし (PR #261 で ADR-052/053 採番衝突が実発生、既存 cli-docs-lint の check-mode 骨格流用。順位 135 placeholder policy は todo entry 側の「ルール」で本 entry は land 済ファイルの「仕組み」検知、相補で重複ではない) | +| 275 | 🔧 Tier 2 | **層別テストテンプレート (StubOllama パターン・integration 独立性) の共有化 (PR #265 post-merge-feedback T2-1 採用)** | todo15.md | M | なし (WP-11/ADR-054 の多層防御実装で「空 StubOllama による LLM 未呼び出し証明」「tempdir+jj init+CwdRestore の integration 独立性」を都度設計。WP-17 の classifier/scope guard 拡張で同種判断が再発見込み。shared crate 化の境界は ADR-044 で判定、WP-17 着手前の実施が効果的) | +| 276 | 💎 Tier 3 | **ADR-007 に「コメント配置の意思決定フロー」を追加 (PR #265 post-merge-feedback T3-2 採用)** | todo15.md | S | なし (PR #265 で非 doc コメントの Bundle Z block が 2 回発生 = doc コメント/識別子名/マーカー付き Why の配置判断が未文書化。linter 自動化は NLP 必要で却下済み、既存 Q1-Q3 形式で人間/AI の判断補助を doc 化。バッチ PR で消化可) | +| 277 | 💎 Tier 3 | **PR body 配置タイミング規約を dev-conventions に明記 (PR #265 post-merge-feedback T3-3 採用)** | todo15.md | XS | なし (push パイプライン実行中の working copy に `__pr-body.md` を作成し snapshot 混入をかろうじて回避したヒヤリハット実発生。「push 完了後に scratchpad で準備し --body-file に絶対パス」を規約化。バッチ PR 消化可、並列安全化 PR docs への相乗りも可) | +| 281 | 🚀 Tier 1 | **config-reading hook の current_dir() 解決を検出する lint rule (PR #267 post-merge-feedback T1-1 採用)** | todo15.md | S | なし (新規 hook が cwd 基準 config 解決を実装し pre-push REJECT → fix 修正の実例。cwd drift による silent fail-open は新規 hook のたびに再発しうる。Severity High。順位 287 と同一 PR bundle 推奨) | +| 282 | 🚀 Tier 1 | **jj-op-verify の変更系 verb 網羅拡大 — undo/restore/split/bookmark move 等 (PR #267 post-merge-feedback T1-2 採用)** | todo15.md | M | なし (特に `jj undo` の検出漏れは lost-update 再発リスク高。拡張時は expected_op_keyword を jj 0.42 実機の op log 出力と要照合) | +| 283 | 🚀 Tier 1 | **jj-op-verify の verb 検出を command-boundary に anchor (PR #267 post-merge-feedback T1-3 採用)** | todo15.md | S | なし (commit message 引用符内の "jj new" 等での false positive 防止。実装時に accepted risk で一度見送った経緯あり = 着手時に実観測 0 件のままか再確認。順位 285 と表裏) | +| 284 | 🔧 Tier 2 | **stale_check_enabled の TOML パーステスト追加 (PR #267 post-merge-feedback T2-1 採用)** | todo15.md | XS | なし (新フィールドのパース経路が未テスト = silent degrade リスク。既存テストへの数行追加で完備) | +| 285 | 🔧 Tier 2 | **jj keyword を含む commit message の tokenization edge-case テスト (PR #267 post-merge-feedback T2-2 採用)** | todo15.md | S | なし (順位 283 と表裏。283 の着手有無に関わらず現行挙動を regression test で固定する価値が独立して残る。283 と同一 PR 消化が効率的) | +| 286 | 🔧 Tier 2 | **config path 解決の cwd 跨ぎ integration test (PR #267 post-merge-feedback T2-3 採用)** | todo15.md | M | なし (FIXED 済 cwd-config bug の regression guard。既存テストは pure parser のみで file-lookup 経路未カバー。Severity High、Adoption Risk = OS 依存) | +| 287 | 💎 Tier 3 | **「config 読み hook は exe-relative 解決必須」convention の明文化 (PR #267 post-merge-feedback T3-1 採用)** | todo15.md | XS | なし (順位 281 の文書層補完。**281 と同一 PR bundle 推奨**、別作業に切り出す価値は低い) | +| 288 | 🚀 Tier 1 | **pre-push review が PR 全体をカバーしない — post-merge の全 run 集約 + push-runner `[diff]` stage の tip-only 範囲修正 (PR #268/#300/#301 feedback 採用、Severity High 3連続再発)** | todo15.md | M | なし (根因は `[diff]` stage `jj diff -r @` が tip のみ = 祖先 code が AI レビュー未経由で merge。`docs_only_routing` は PR 範囲へ修正済だが `[diff]` は非対称。単一 push では全 run 集約でも救えず [diff] 範囲拡張 + bookmark_check 祖先検証が根治。ADR-027 射程はユーザー判断。独立 PR 推奨) | +| 292 | 🔧 Tier 2 | **cli-pr-monitor の lock.rs を token 方式の所有権検証へ統一** | todo15.md | S-M | なし (PR #271 で pipeline_lock.rs に導入した token ベース所有権検証と同型の Drop 無条件削除バグが cli-pr-monitor/src/lock.rs にも残存。参照実装が既にあるため低リスク) | +| 293 | ⏳ Tier 5 | **push-runner の stack push モード (opt-in、YAGNI につき見送り継続)** | todo15.md | M | なし (stacked bookmark 運用の実績が現状なく、必要になった時点で着手する opt-in 拡張として記録のみ) | +| 294 | 💎 Tier 3 | **jj-op-verify hook の位置づけ再整理 — 並列 workspace 安全化ではなく混線緩和層として再分類** | todo15.md | S | なし (検知対象は出力混線の症状であり並列 workspace とは独立に価値を持つ。ADR-045→ADR-053 の枠組みへ紐付け直すドキュメント再整理のみ) | +| 295 | 💎 Tier 3 | **ADR-045 にコミット消失事故の「並列原因」診断が未検証である旨の注記追加** | todo15.md | XS | なし (診断は事後の自己分析に依拠し一次証拠未到達。混線起因の可能性も残ることを confirmation bias の記録として注記) | +| 296 | 🔧 Tier 2 | **Lock stale takeover + Drop の concurrency scenario 拡張テスト (271.md T2-2 採用)** | todo15.md | M | なし (token-based ownership Drop の前提を takeover 後の旧 guard drop までの full cycle で検証、既存 concurrent_stale_takeover_only_one_wins の拡張) | +| 297 | 🔧 Tier 2 | **Pipeline 段階間の状態遷移 E2E テスト (271.md T2-3 採用)** | todo16.md | M | なし (Stage -1〜Stage 3 の段階間 hidden coupling を regression test 化、bookmark が @ に遅延した状態遷移を明示的にカバー) | +| 298 | 💎 Tier 3 | **token ベース ownership check の convention 化 (271.md T3-1 採用)** | todo16.md | S | なし (PID 再利用リスクという業界知見を dev-conventions.md に一般化して記載) | +| 299 | 💎 Tier 3 | **revset で workspace 所有権を判定できない旨の convention 明記 (271.md T3-2 採用)** | todo16.md | XS | なし (`@` 厳密一致の設計判断という negative result を CLAUDE.md に明文化) | +| 300 | 💎 Tier 3 | **Push pipeline 段階間依存性チェック項目の追加 (271.md T3-3 採用)** | todo16.md | S | なし (PR #271 の hidden coupling incident から得た教訓を CLAUDE.md / dev-conventions.md に恒久化) | +| 301 | 🚀 Tier 1 | **TOCTOU (remove+create_new) パターン検出 lint rule — exclusive lock 実装限定 (273.md T1-1 採用)** | todo16.md | S | なし (二重 Acquired バグの根本原因パターンを検出。cli-pr-monitor/lock.rs は設計判断済みのため scope 除外必須) | +| 302 | 💎 Tier 3 | **`takeover_stale_lock_skips_remove_when_snapshot_is_stale` パターンを deterministic concurrency test テンプレートとして記録 (273.md T2-3 採用)** | todo16.md | XS | なし (実スレッドレースより状態不一致を直接注入する決定論的テストパターンを次の並行処理系 PR 向けに記録) | +| 303 | 💎 Tier 3 | **Advisory lock (fail-open) の TOCTOU window 許容可否を明示コメントで残す設計チェックリスト (273.md T3-1 採用)** | todo16.md | XS | なし (cli-pr-monitor/lock.rs が既に実践している判断根拠明示の practice をチェックリスト化) | +| 304 | 💎 Tier 3 | **quality gate 実行中に発見したバグ修正が別 PR に混入した際の jj split + jj rebase 復旧パターンを記録 (273.md T3-3 採用)** | todo16.md | XS | なし (PR #272/#273 分離で実証済みの復旧手順、ADR-045 の並列 workspace リスクとは別種の単一 session 内混入事故。復旧は事後対応であり、分離後は混在した変更に対する gate 実行結果を無効化し各 PR で再実行する手順を含む) | +| 305 | 💎 Tier 3 | **Metrics violation の pre-existing 判定基準の明文化 (273.md T3-4 採用)** | todo16.md | XS | なし (file_size_check / file_length_gate 等 metrics 系 gate が複数稼働中で反復しうる override 正当性の判定基準を明文化) | +| 306 | 💎 Tier 3 | **quality gate isolation 機構を見送り、recovery による risk acceptance とした判断の記録 (negative result) (273.md T3-5 採用)** | todo16.md | S | なし (spike 見送り convention に従い、isolation 機構を却下し recovery コストの低さ (順位304) を理由に risk acceptance した根拠を記録。recovery は isolation の代替ではなく、予防機能の欠如という残存リスクと再検討条件を明記する) | +| 307 | 🔧 Tier 2 | **WP-12 step 2: 発火テレメトリ ROI 棚卸し pre-step (発火 0 の rule/preset/hook を削除候補提示)** | todo16.md | M | なし (**着手条件 = ADR-055 収集層マージから 28 日 warm-up 後**。それ以前は全項目が発火 0 = データ無しで判定無意味。集計は Rust exe、weekly-review に file-length-watchlist 同型 facet で接続、incident 由来ルールは発火 0 でも維持推奨の区別) | +| 308 | 💎 Tier 3 | **WP-12 step 3: ADR-039 bounded lifetime 判定の発火数機械化** | todo16.md | S | 順位 307 (step 2 の集計基盤に依存)。試験運用 ADR 機構の卒業/廃止検討を発火数で自動 promote。step 3 完了で WP-12 完了 | +| 309 | 🚀 Tier 1 | **telemetry の block 記録を実 quality 違反に限定(infra エラー混入除外)(275.md T1-1 採用)** | todo16.md | M | なし (CodeRabbit Major。ADR-055 で「emit 総数」と意図的定義したが WP-12 ROI 棚卸しが infra エラー〔stdin/parse 失敗〕混入で歪むため実 violation パス限定に絞る。3 hook 横断で分割 PR 推奨、ADR-055 amendment 併記) | +| 310 | 🚀 Tier 1 | **custom-regex preset の生 regex が telemetry id に流れる privacy footgun 是正(非ブロッキング follow-up 統合)(275.md T1-2 採用)** | todo16.md | S | なし (現行 config は named preset のみで非発火だが派生プロジェクトの latent footgun。fallback を合成 id〔"custom-block"〕に正規化 + ADR-055 に config privacy 注記) | +| 311 | 🚀 Tier 1 | **逐語的関数複製(3+ コピー)を pre-push 検出する DRY lint rule (275.md T1-3 採用)** | todo16.md | M | なし (is_truthy 三重複製事案。ADR-007 regex 層に threshold 検出追加。順位 313 の fixture と抱き合わせ) | +| 312 | 🔧 Tier 2 | **`.claude/telemetry/` の per-pid×日次 partition ファイル retention/cleanup (275.md T2-1 採用)** | todo16.md | M | 順位 307 (WP-12 step 2 と同時期=step1 マージから 28 日後 2026-08-12 頃に着手) | +| 313 | 🔧 Tier 2 | **is_truthy 三重複製を ADR-049 incident fixture 化 (275.md T2-4 採用)** | todo16.md | XS | 順位 311 (DRY lint rule と抱き合わせ) | +| 314 | 🔧 Tier 2 | **bookmark 未作成での push 失敗(exit 7)のエラーメッセージ改善 (275.md T2-5 採用)** | todo16.md | S | なし (本セッションで実発生。bookmark 自動作成は ADR-011 の明示命名意図と緊張するためメッセージ改善のみ) | +| 315 | 💎 Tier 3 | **ADR-055 telemetry の bounded lifetime 期限を config コメントに明記 (275.md T3-1 採用)** | todo16.md | XS | なし (warm-up 期限 2026-08-12 頃 + 順位 307/308 リンクを `[telemetry]` section コメントに追記) | +| 316 | 💎 Tier 3 | **ADR-044「2nd consumer で共通化」原則の明確化・判定基準の例示 (275.md T3-2 採用)** | todo16.md | S | なし (is_truthy の非対称性を case study 化。順位 317 と対) | +| 317 | 💎 Tier 3 | **utility 関数追加前のチェックリスト(workspace grep)(275.md T3-3 採用)** | todo16.md | XS | 順位 316 (ADR-044 明確化と対) | +| 318 | 🚀 Tier 1 | **CR rate-limit 第3 format (`Next review available in: N minutes`) 未対応 + marker 一致/regex 不一致の silent 化 (PR #287 で実観測)** | todo16.md | S | なし (ADR-034 § 検出 logic 更新手順 の 4-6 をそのまま適用可。silent 化解消は追加設計) | +| 319 | 🚀 Tier 1 | **pr-monitor.yml バックストップの重複ガードが構造的に機能しない — CR 投稿ごとに分析コメントを再投稿 (PR #287 で 5 件実観測)** | todo17.md | S | なし (ガードが LLM prompt 内にあり、トリガー事象自身が skip 条件を無効化するトートロジー) | +| 320 | 🔧 Tier 2 | **CodeRabbit status check は実レビュー有無に関わらず `pass` — 緑チェックを「レビュー済み」の根拠にしない (PR #287 で実観測)** | todo17.md | S | 順位 318 (決定論的な rate-limit 検知が前提) | +| 321 | 🔧 Tier 2 | **ADR-019/WP-03 クォータ設計の前提 stale (無料枠 → Pro + adaptive limit) + 初回レビュー処理中 push のレビュー欠落穴** | todo17.md | S | なし (dev-conventions 順位 262「外部 SaaS 無料枠/制限の調査チェックリスト」の適用対象) | +| 322 | 🚀 Tier 1 | **post-merge-feedback が repo root に scratch script を残し `scratch_file_warning` の pattern をすり抜ける (near-miss 実観測)** | todo17.md | S | なし (PR #85 と同一クラス。pattern 列挙 (deny-list) の構造的限界が露呈) | +| 323 | 🚀 Tier 1 | **`lib-subprocess` `run_cmd_shell_*` の timeout が wall-clock を縛れない — 孫プロセス残存で join がブロック (push-pipeline-fix-plan §6 backlog 10 移管)** | todo17.md | S | なし (quality_gate step_timeout / push timeout / cli-merge-pipeline のハング打ち切りが実質無効。#286 post-merge-feedback の orphan/stale marker と同根の実害 1 件観測済。回帰テストに経過時間 assert 必須 = T6 教訓) | +| 324 | 🚀 Tier 1 | **`cli-pr-monitor::push_to_remote` に push 拒否検知が無く post-PR re-push が無言で失敗し得る (push-pipeline-fix-plan §6 backlog 9 移管)** | todo17.md | XS | なし (T5 = PR #282 が cli-push-runner 側で塞いだ silent-failure push と同型の穴。出力は `run_cmd_direct` で全量取得済のため判定追加のみ) | +| 326 | 🔧 Tier 2 | **並列設計レビュアー (design-fit reviewer) の実験起案 — 見落とし実績の事前調査付き (R4/ADR-047 却下分析の代替案)** | todo17.md | S (Phase 0) / M (Phase 1 条件付き) | なし (Phase 0 の需要調査で見落とし実績ゼロなら見送り = negative result 永続化。ADR-047 却下確定 = refute.yaml 削除 revert PR とは独立に進められる) | +| 327 | 🔧 Tier 3 | **多段コミットの ADR/observability 更新チェックリストを dev-conventions に追加 (#295/#296 post-merge feedback 採用: status 同期 / plain-text 参照 / セクション同期)** | todo17.md | S | なし (実害は各 PR review/feedback で捕捉済。doc checklist のみ、機械化は再発観測後にエスカレーション) | +| 328 | 🚀 Tier 1 | **post-merge feedback が成功後に `post-merge-feedback-context.json` を残し次マージの feedback を誤 bail させる (cleanup gap、#296 マージで実観測)** | todo17.md | S | なし (連続マージで後発 PR の再発防止分析が構造的に skip。成功時 cleanup の追加 + 回帰テスト。ADR-030 L2 recovery で今回は手動救済済) | +| 329 | 💎 Tier 3 | **新規 ADR 起案時の「判断根拠 × 既存 ADR 定義」矛盾チェックリストを dev-conventions に追加 (#301 post-merge feedback 採用)** | todo17.md | S | なし (ADR-055 初版が自定義の `decision` 軸と矛盾する除外根拠を採用→Amendment 撤回の手戻り。ADR 59件超で同型見落とし再発しうる。#327 と対の doc-only 対処) | +| 330 | 💎 Tier 3 | **「行動要求 nudge は 2 チャネル返却」+「多義的戻り値は struct 化」convention の明文化 (#299 post-merge feedback 採用)** | todo17.md | XS | なし (ADR-059 の 2 チャネルパターンと `WeeklyReviewNudge` struct 化。第2弾展開 3件で再利用見込み。dev-conventions 1節追記) | +| 331 | 🔧 Tier 2 | **hooks-session-start に systemMessage を含む JSON 出力の exe-spawn E2E テスト追加 (#299 post-merge feedback 採用)** | todo17.md | S | なし (現状 pure function レベルのみ、実 config パース込み exe 駆動の検証なし。ADR-049 exe-spawn E2E 先例流用。UI 実描画確認は別途 dogfood) | +| 332 | 🔧 Tier 2 | **`pnpm build:all` 前に git usr/bin (cp.exe) PATH 未設定を自動検出・追加 (#301 post-merge feedback 採用)** | todo17.md | S | なし (Windows で pnpm が cmd.exe 経由実行のため `cp` 解決失敗。memory 既記録だが再発2回目。Windows 限定 additive 分岐、他OS非影響) | +| 333 | 🔧 Tier 2 | **VSCode 拡張が hook `systemMessage` を UI 描画するかの調査 (ADR-059 dogfood / 削除条件 2、2026-07-19 週次レビュー観測)** | todo14.md | S | なし (2026-07-19 dogfood で VSCode UI での systemMessage 独立描画が未確認 = additionalContext 経由のみ観測。ターミナル CLI との挙動差を切り分け。ADR-059 bounded-lifetime 判定 期限 2026-08-16 の blocker。描画なしでも defense-in-depth backstop あり revert 不要) | +| 334 | 🚀 Tier 1 | **docs/todo*.md 本文の順位番号表記を検出する custom lint rule (ADR-033 使用禁止の仕組み化、#303 post-merge feedback 採用)** | todo14.md | S | なし (ADR-033 が禁止規定 + 将来の展望で lint 検討済みだが未実装 約3ヶ月。検証 grep 実証済み、literal-ban rule⑥/⑪ と同型) | +| 335 | 🔧 Tier 2 | **post-merge-feedback の transcript 分析を cli-merge-pipeline 生成 summary index に置換 (#303 post-merge feedback 採用)** | todo14.md | M | なし (session-analysis facet が約 1.5MB transcript で 25K token limit 衝突・避難措置を自己観測。既存 filter の自然な拡張、Frequency High) | + +**戦略**: 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 責務集中のため)。 diff --git a/docs/todo.md b/docs/todo.md index 53854f6e..7ba52bb1 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -2,8 +2,10 @@ > **運用ルール**: 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイル + [docs/todo2.md](todo2.md) 〜 [docs/todo14.md](todo14.md) + [docs/todo-summary.md](todo-summary.md) の使い分け** (PR #83 T3-2 で恒久化、2026-04-28 強化、PR #88 で todo3.md 追加、PR #96 セッションで todo4.md 追加、PR #101 セッションで todo5.md 追加、PR #123 セッションで todo6.md 追加、2026-05-09 に todo-summary.md 切り出し + todo5.md 分割で todo7.md 追加、PR #143 = 2026-05-11 で todo8.md 追加、PR #172 仕組み化方針切替 = 2026-05-25 で todo9.md 追加、PR #185 land 後 2026-05-29 で todo10.md 追加、2026-06-06 todo9.md 分割で todo11.md 追加、2026-06-12 PR #204 で todo10.md 分割により todo12.md 追加、2026-06-29 PR #224 セッションで todo13.md 追加、2026-07-19 週次レビュー WR-2026-07-19-T02 採用で todo14.md 追加): -> - **docs/todo-summary.md**: 推奨実行順序サマリー table 専用 (旧 todo.md から切り出し)。table の新規行追加・既存行編集・順位再採番はここで行う。 +> **本ファイル + [docs/todo2.md](todo2.md) 〜 [docs/todo19.md](todo19.md) + [docs/todo-summary.md](todo-summary.md) の使い分け** (PR #83 T3-2 で恒久化、2026-04-28 強化、PR #88 で todo3.md 追加、PR #96 セッションで todo4.md 追加、PR #101 セッションで todo5.md 追加、PR #123 セッションで todo6.md 追加、2026-05-09 に todo-summary.md 切り出し + todo5.md 分割で todo7.md 追加、PR #143 = 2026-05-11 で todo8.md 追加、PR #172 仕組み化方針切替 = 2026-05-25 で todo9.md 追加、PR #185 land 後 2026-05-29 で todo10.md 追加、2026-06-06 todo9.md 分割で todo11.md 追加、2026-06-12 PR #204 で todo10.md 分割により todo12.md 追加、2026-06-29 PR #224 セッションで todo13.md 追加、2026-07-19 週次レビュー WR-2026-07-19-T02 採用で todo14.md 追加、2026-07-20 docs 50KB 超過解消で todo13.md を todo15/16/17・todo10.md を todo18/19 へ物理分割): +> +> - **docs/todo-summary.md**: 推奨実行順序サマリー table 専用 (旧 todo.md から切り出し)、順位 6-219 を収容。既存行編集・順位再採番はここで行う。 +> - **docs/todo-summary2.md**: todo-summary.md の table を 2026-07-20 に docs 50KB 超過解消で分割した後半 (順位 220 以降を収容)。新規行追加は末尾 = 本ファイルで行う。cli-docs-lint の priority-inversion / preamble は両 summary を統合検査。 > - **docs/todo.md**: 既存タスクの編集・完了削除専用。新規タスクの**詳細エントリ**は追加しない (~50KB 閾値内に維持し Claude Code 読み取り安定性を確保) > - **docs/todo2.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (50KB に到達したため、PR #88 以降の新規エントリは todo3.md へ) > - **docs/todo3.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (50KB に到達したため、PR #96 セッション以降の新規エントリは todo4.md へ) @@ -13,13 +15,18 @@ > - **docs/todo7.md**: 既存タスクの編集・完了削除専用 (旧 todo5.md の PR #101〜#109 エントリを 2026-05-09 に分割移動)。**新規タスクは追加しない** > - **docs/todo8.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (60KB に到達したため、PR #172 仕組み化方針切替 = 2026-05-25 以降の新規エントリは todo9.md へ) > - **docs/todo9.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (50KB 超 1100+ 行に到達したため、PR #185 land 後 2026-05-29 以降の新規エントリは todo10.md へ。2026-06-06 に PR-specific follow-up entries を todo11.md へ分離) -> - **docs/todo10.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (約95KB に到達したため、PR #224 セッション = 2026-06-29 以降の新規エントリは todo13.md へ。2026-06-12 PR #204 で PR #185〜#196 era のエントリを todo12.md へ分離) +> - **docs/todo10.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (約95KB に到達したため、PR #224 セッション = 2026-06-29 以降の新規エントリは todo13.md へ。2026-06-12 PR #204 で PR #185〜#196 era のエントリを todo12.md へ分離。2026-07-20 に順位 215-224 を todo18/todo19 へ物理分割し 50KB 以下に縮小) > - **docs/todo11.md**: 既存タスクの編集・完了削除専用 (2026-06-06 todo9.md 分割で新設、PR-specific follow-up entries 収容)。**新規タスクは追加しない** > - **docs/todo12.md**: 既存タスクの編集・完了削除専用 (2026-06-12 PR #204 で todo10.md 分割により新設、PR #185〜#196 era のエントリ収容)。**新規タスクは追加しない** -> - **docs/todo13.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (約171KB に到達したため、週次レビュー WR-2026-07-19-T02 採用 = 2026-07-19 以降の新規エントリは todo14.md へ) +> - **docs/todo13.md**: 既存タスクの編集・完了削除専用。**新規タスクは追加しない** (約171KB に到達したため、週次レビュー WR-2026-07-19-T02 採用 = 2026-07-19 以降の新規エントリは todo14.md へ。2026-07-20 に順位 248-332 を todo15/todo16/todo17 へ物理分割し 50KB 以下に縮小) > - **docs/todo14.md**: 新規タスクの追加先。50KB に到達するまでは本ファイルへ追加 (2026-07-19 週次レビュー WR-2026-07-19-T02 採用で新設) -> - 例外: 既存 todo.md / todo2.md 〜 todo14.md タスクと **同一ファイル / 同一コンポーネント** を編集する密結合タスクは該当ファイルに追加可 (例: `~/.claude/rules/common/git-workflow.md` 配下のグローバルルール群) -> - **新セッションでは十五つすべてを確認すること** (todo.md / todo2-14.md / todo-summary.md) +> - **docs/todo15.md**: 既存タスクの編集・完了削除専用 (2026-07-20 todo13.md 分割で新設、順位 248-296 収容)。**新規タスクは追加しない** +> - **docs/todo16.md**: 既存タスクの編集・完了削除専用 (2026-07-20 todo13.md 分割で新設、順位 297-318 収容)。**新規タスクは追加しない** +> - **docs/todo17.md**: 既存タスクの編集・完了削除専用 (2026-07-20 todo13.md 分割で新設、順位 319-332 収容)。**新規タスクは追加しない** +> - **docs/todo18.md**: 既存タスクの編集・完了削除専用 (2026-07-20 todo10.md 分割で新設、順位 215-219 収容)。**新規タスクは追加しない** +> - **docs/todo19.md**: 既存タスクの編集・完了削除専用 (2026-07-20 todo10.md 分割で新設、順位 220-224 収容)。**新規タスクは追加しない** +> - 例外: 既存 todo.md / todo2.md 〜 todo19.md タスクと **同一ファイル / 同一コンポーネント** を編集する密結合タスクは該当ファイルに追加可 (例: `~/.claude/rules/common/git-workflow.md` 配下のグローバルルール群) +> - **新セッションでは全 todo ファイルを確認すること** (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md) --- @@ -41,15 +48,15 @@ > > **参照**: `.claude/weekly-reviews/2026-07-19.md` WR-2026-07-19-J01、`src/hooks-session-start/src/jj_helpers.rs:12-25`、[ADR-039](adr/adr-039-experimental-feature-standard-pattern.md) (jj-robustness facet の bounded lifetime dogfood 文脈) -##### 背景: 本 bug class (jj 操作による mtime リセット) は 2026-07 セッションで実観測済みで、新設 jj-robustness facet (ADR-039 bounded lifetime dogfood) が再検出した good signal。ただし jj new / workspace 操作が実際に `.git/FETCH_HEAD` の mtime を書き換える具体的機序は本レビューで再現検証しておらず、実装前に経験的確認を推奨する。 +##### 背景: 本 bug class (jj 操作による mtime リセット) は 2026-07 セッションで実観測済みで、新設 jj-robustness facet (ADR-039 bounded lifetime dogfood) が再検出した good signal。ただし jj new / workspace 操作が実際に `.git/FETCH_HEAD` の mtime を書き換える具体的機序は本レビューで再現検証しておらず、実装前に経験的確認を推奨する -##### 設計決定: mtime 依存を廃し、jj git fetch 成功後に `.claude/fetch-last-run.json` 等へ埋め込みタイムスタンプを書き込み、そこから鮮度判定する方式に置換する (weekly-review last-run / telemetry と同じ「内容 timestamp は checkout 不変」方式、CR #233 の mtime リセット教訓と整合)。 +##### 設計決定: mtime 依存を廃し、jj git fetch 成功後に `.claude/fetch-last-run.json` 等へ埋め込みタイムスタンプを書き込み、そこから鮮度判定する方式に置換する (weekly-review last-run / telemetry と同じ「内容 timestamp は checkout 不変」方式、CR #233 の mtime リセット教訓と整合) - [ ] jj 操作が FETCH_HEAD mtime を書き換える機序を経験的に確認 (前提検証) - [ ] 埋め込み timestamp 方式へ置換 + mtime リセットを模擬する回帰テスト - [ ] 本エントリ削除 -##### 完了基準: jj workspace 操作後も fetch 鮮度が正しく判定されること (mtime リセット模擬の回帰テストで seal)。 +##### 完了基準: jj workspace 操作後も fetch 鮮度が正しく判定されること (mtime リセット模擬の回帰テストで seal) #### gh 呼び出しに --repo を付与 — 非 colocated jj workspace の PR 検出 silent 失敗 (週次レビュー WR-2026-07-19-J02 採用) @@ -59,15 +66,15 @@ > > **参照**: `.claude/weekly-reviews/2026-07-19.md` WR-2026-07-19-J02、`src/cli-merge-pipeline/src/github.rs:92-99`、`src/cli-pr-monitor/src/util.rs:31-68`、[ADR-045](adr/adr-045-jj-workspace-parallel-sessions.md)、PR #238 (実インシデント) -##### 背景: 既に実インシデント化しており、`.claude/hooks-config.toml` の gh-repo-env-guard preset コメントが PR #238 / ADR-045 を明記している。既存 guard は誤った回避策 (`GH_REPO=` の場当たり利用) をブロックするのみで、根本原因 (呼び出し箇所の `--repo` 欠落) は未修正。J01 と同じ ADR-039 dogfood 文脈。 +##### 背景: 既に実インシデント化しており、`.claude/hooks-config.toml` の gh-repo-env-guard preset コメントが PR #238 / ADR-045 を明記している。既存 guard は誤った回避策 (`GH_REPO=` の場当たり利用) をブロックするのみで、根本原因 (呼び出し箇所の `--repo` 欠落) は未修正。J01 と同じ ADR-039 dogfood 文脈 -##### 設計決定: `GH_REPO` 環境変数 or jj remote 由来で owner/repo を明示的に解決し、全 gh 呼び出しに `--repo` を付与する。 +##### 設計決定: `GH_REPO` 環境変数 or jj remote 由来で owner/repo を明示的に解決し、全 gh 呼び出しに `--repo` を付与する - [ ] github.rs / util.rs の gh 呼び出しに owner/repo 解決 + `--repo` 付与 - [ ] 非 colocated workspace を模擬した PR 検出の回帰テスト - [ ] 本エントリ削除 -##### 完了基準: 非 colocated jj workspace でも merge/monitor パイプラインが PR を正しく検出できること (回帰テストで seal)。 +##### 完了基準: 非 colocated jj workspace でも merge/monitor パイプラインが PR を正しく検出できること (回帰テストで seal) --- @@ -83,9 +90,9 @@ > > **参照**: `.claude/weekly-reviews/2026-07-01.md` WR-2026-07-01-A01、`.claude/hooks-config.toml` `[stop_quality]` (修正対象)、`push-runner-config.toml` `[quality_gate]` (lint/test single authority 候補)、`docs/file-length-enforcement-plan.md` PR-W5 (整合先)、ADR-004 (Stop hook 品質ゲート)、ADR-015 (push-runner 移行)、ADR-022 (責務分離) -##### 背景: ADR-015 で push-time quality gate を push-runner-config.toml に集約した際、ADR-004 由来の Stop hook `[stop_quality]` の lint/test step が削除されず残存。push-runner-config.toml 自身のコメントが「Stop hook では実行しない」と意図を明記しているため意図と実装の乖離が明白。ただし `[stop_quality]` は PR-W5 の file-length gate 受け皿としての将来用途があるため、セクション全削除ではなく重複 step の選択的除去が必要。 +##### 背景: ADR-015 で push-time quality gate を push-runner-config.toml に集約した際、ADR-004 由来の Stop hook `[stop_quality]` の lint/test step が削除されず残存。push-runner-config.toml 自身のコメントが「Stop hook では実行しない」と意図を明記しているため意図と実装の乖離が明白。ただし `[stop_quality]` は PR-W5 の file-length gate 受け皿としての将来用途があるため、セクション全削除ではなく重複 step の選択的除去が必要 -##### 設計決定: Option A' (推奨、PR-W5 整合版) — `[stop_quality]` から push-runner `[quality_gate]` と重複する lint/clippy/test step のみを削除し、session 固有チェック (PR-W5 の file-length step 等) の受け皿としてセクションは維持。quality_gate を lint/test の single authority とする。ADR-004 と ADR-015 に責務境界 (Stop hook = session 固有 / push gate = lint/test authority) を明記。Option B (意図的 defense-in-depth として両 ADR にコスト試算コメント追記) は代替案。 +##### 設計決定: Option A' (推奨、PR-W5 整合版) — `[stop_quality]` から push-runner `[quality_gate]` と重複する lint/clippy/test step のみを削除し、session 固有チェック (PR-W5 の file-length step 等) の受け皿としてセクションは維持。quality_gate を lint/test の single authority とする。ADR-004 と ADR-015 に責務境界 (Stop hook = session 固有 / push gate = lint/test authority) を明記。Option B (意図的 defense-in-depth として両 ADR にコスト試算コメント追記) は代替案 - [ ] PR-W5 (file-length gate) land 後に着手 or 並行時は `[stop_quality.steps]` 追加先の整合を確認 - [ ] `[stop_quality]` の重複 lint/test step を特定し選択的削除 (file-length step は残す) @@ -105,9 +112,9 @@ > > **参照**: `.claude/weekly-reviews/2026-06-01.md` WR-2026-06-01-C02、`src/cli-merge-pipeline/src/feedback.rs:156-207` (修正対象)、`src/lib-pending-file/src/lib.rs` `is_valid_owner_repo()` (既存 validator)、ADR-022 § defense-in-depth 原則 -##### 背景: cli-merge-pipeline の feedback path は merge 完了後に `gh pr view` / `gh api` で PR メタデータを取得する経路で、入力 `owner_repo` は pending file 由来。hook 経由の通常 path では `is_valid_owner_repo()` が呼ばれるが、broken pending file (Claude 編集ミス / 手動修正等) が cli-merge-pipeline に直接到達した場合は無検証で gh CLI に渡る (cli-merge-pipeline は hook と独立して起動可能)。 +##### 背景: cli-merge-pipeline の feedback path は merge 完了後に `gh pr view` / `gh api` で PR メタデータを取得する経路で、入力 `owner_repo` は pending file 由来。hook 経由の通常 path では `is_valid_owner_repo()` が呼ばれるが、broken pending file (Claude 編集ミス / 手動修正等) が cli-merge-pipeline に直接到達した場合は無検証で gh CLI に渡る (cli-merge-pipeline は hook と独立して起動可能) -##### 設計決定: `fetch_pr_time_range()` 先頭で `is_valid_owner_repo(owner_repo)` を呼び出し、無効時は `Err` 返却。もしくは関数 signature を `&PendingFile` 受取に変更し型不変条件で保証 (より構造的)。 +##### 設計決定: `fetch_pr_time_range()` 先頭で `is_valid_owner_repo(owner_repo)` を呼び出し、無効時は `Err` 返却。もしくは関数 signature を `&PendingFile` 受取に変更し型不変条件で保証 (より構造的) - [ ] Option A 採用判断 (1 行 guard) or Option B 採用判断 (型 signature 変更) - [ ] `is_valid_owner_repo()` の re-export / dependency 確認 (lib-pending-file → cli-merge-pipeline) @@ -127,9 +134,9 @@ > > **参照**: `.claude/weekly-reviews/2026-06-01.md` WR-2026-06-01-A01、`.claude/weekly-reviews/2026-07-01.md` WR-2026-07-01-A02 (再検出)、`CLAUDE.md:5-45` (ADR index、修正対象)、`docs/adr/adr-033-todo-numbering-simplification.md:40-42, 81, 95, 130` (`ADR-032 PR-β` 参照 4 箇所、修正対象)、`docs/todo2.md:232` (ADR-032 reserved 文脈) -##### 背景: ADR-032 は「docs-only fast-path」関連の試験運用 ADR として `docs/todo2.md` 順位 20 で起案予定だが未作成。一方 ADR-033 は task naming 例示として `ADR-032 PR-β` を使用済みで、CLAUDE.md は ADR-031 → ADR-033 へジャンプする状態。reader が CLAUDE.md から ADR-032 を辿ろうとすると broken-link、ADR-033 から ADR-032 を辿ろうとしても dead-pointer。 +##### 背景: ADR-032 は「docs-only fast-path」関連の試験運用 ADR として `docs/todo2.md` 順位 20 で起案予定だが未作成。一方 ADR-033 は task naming 例示として `ADR-032 PR-β` を使用済みで、CLAUDE.md は ADR-031 → ADR-033 へジャンプする状態。reader が CLAUDE.md から ADR-032 を辿ろうとすると broken-link、ADR-033 から ADR-032 を辿ろうとしても dead-pointer -##### 設計決定: Option A (recommended、reservation 明示) — CLAUDE.md ADR index に `- ADR-032: (reserved — docs-only fast-path、起案 docs/todo2.md 順位 20)` のスタブ行を追加し、ADR-033 内の `ADR-032 PR-β` を **実在 ADR (例: ADR-031 PR-β 相当の task 名)** に差し替えるか、`(reserved ADR-032 のタスク名例)` 等の reservation 明示 wording に変更。Option B (ADR-032 を本作業で実体化) は scope creep のため不採用、別 task として `docs/todo2.md` 順位 20 で trackable。 +##### 設計決定: Option A (recommended、reservation 明示) — CLAUDE.md ADR index に `- ADR-032: (reserved — docs-only fast-path、起案 docs/todo2.md 順位 20)` のスタブ行を追加し、ADR-033 内の `ADR-032 PR-β` を **実在 ADR (例: ADR-031 PR-β 相当の task 名)** に差し替えるか、`(reserved ADR-032 のタスク名例)` 等の reservation 明示 wording に変更。Option B (ADR-032 を本作業で実体化) は scope creep のため不採用、別 task として `docs/todo2.md` 順位 20 で trackable - [ ] CLAUDE.md ADR index に `ADR-032: (reserved)` 行追加 (位置: ADR-031 と ADR-033 の間) - [ ] `docs/adr/adr-033-todo-numbering-simplification.md:40-42, 81, 95, 130` の `ADR-032 PR-β` 参照 4 箇所を差し替え判断 (実在 ADR 引用 or reservation 明示 wording) diff --git a/docs/todo10.md b/docs/todo10.md index 5643dfa2..9abbe0d9 100644 --- a/docs/todo10.md +++ b/docs/todo10.md @@ -2,7 +2,7 @@ > **運用ルール** ([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 ユーザー判断)。**新規エントリの追加先は引き続き本ファイル** (2026-06-12 PR #204 で PR #185 〜 PR #196 era の 8 エントリを [docs/todo12.md](todo12.md) に分離して file_size_check 50KB threshold 内に収めた、todo12.md は新規追加先ではない)。todo.md / todo2.md 〜 todo9.md / todo11.md / todo12.md の既存エントリは引き続き有効、相互に独立。新セッションでは十五つすべてを確認すること (todo.md / todo2-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo9.md がファイルサイズ 50KB を超え行数 1100+ 行に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #185 = Bundle CR-RL land 後、2026-05-29 ユーザー判断)。**本ファイルは既存タスクの編集・完了削除専用** (新規エントリの追加先は PR #224 セッション = 2026-06-29 で [docs/todo13.md](todo13.md) へ移行、現在は [docs/todo14.md](todo14.md)。2026-06-12 PR #204 で PR #185 〜 PR #196 era の 8 エントリを [docs/todo12.md](todo12.md) に分離して file_size_check 50KB threshold 内に収めた、todo12.md は新規追加先ではない)。todo.md / todo2.md 〜 todo9.md / todo11.md / todo12.md の既存エントリは引き続き有効、相互に独立。**2026-07-20 に順位 215-224 を todo18.md/todo19.md へ物理分割し、本ファイルは順位 198-214 のみ収容 (docs 50KB 超過解消、39KB 台に縮小)。**新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 @@ -464,546 +464,3 @@ ADR-039 (Experimental Feature 標準パターン) は「behavior の妥当性が #### 詰まっている箇所 なし。Effort XS、global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 - ---- - -### `~/.claude/rules/common/coding-style.md` に「Defensive State Reset in State Machines」section 追加 (PR #214 post-merge-feedback T3-1 採用) - -> **動機**: PR #214 round 2 で CR Major #4 (`既存 state 再利用時も現在の push 情報に更新してください`) の fix として `finalize_initial_review_park` 内で `read_state()` 後に `state.pr` / `state.repo` / `state.started_at` を `ctx` 値で **無条件上書き** する pattern を land した。この pattern は同 function 内の既存 reset と同型 (CR Major #1 fix で `head_commit` 上書き、CR Major #2 fix で `review_recheck_count = 0`) で、現時点で 3 field に適用済の確立された defensive pattern。 -> -> ただしこの「無条件上書き」は新規 reader / reviewer から見ると一見「冗長 (= `unwrap_or_else(|| ::new(...))` で既に同値を設定済だから不要)」に見える危険性がある。同型コードを future PR で reviewer (人間 / AI 両方) が「redundant resets は削除すべき」と誤判定して削除した場合、prior cycle の stale state (古い PR 番号 / repo / 開始時刻) が混入する silent bug を導入するリスクが顕在化する。 -> -> **本タスクの位置づけ**: PR #214 post-merge-feedback Tier 3 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-06-20 ユーザー承認)。analyzer rationale: 「PR #214 の `review_recheck.rs` で positive pattern として land (lines 185–187)。同型コード (`review_recheck_count`, `head_commit` 上書き) との一貫性がある確立されたパターン。Frequency Medium = cli-pr-monitor には複数の state machine があり再発確実。Effort S、Adoption Risk None → ✅ 採用候補と判定」。pre-push:simplicity + pre-push:security の独立 2 ソース検出。 -> -> **参照**: `.claude/feedback-reports/214.md` Tier 3 #1、[src/cli-pr-monitor/src/stages/poll/review_recheck.rs:177-193](../src/cli-pr-monitor/src/stages/poll/review_recheck.rs#L177-L193) (現行 `finalize_initial_review_park` の defensive reset block)、memory `feedback_no_unenforced_rules.md` (enforcement 要件)、memory `feedback_global_config_backup.md` (snapshot 必須)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort S。global rules への docs 追記 ~30 行で完結、`feedback_global_config_backup` snapshot を忘れない。 - -#### 設計決定 (案) - -- **追加先**: `~/.claude/rules/common/coding-style.md` の末尾 (`## Code Quality Checklist` の直前) または `## Error Handling` 直後に新 section「Defensive State Reset in State Machines」を追加 -- **rule 内容**: 「State machine 内で `read_state()` / `load_state()` 等の persisted state を再利用する場合、`new()` で設定される identity field と同等の **無条件上書き reset** を `read_state()` 後に明示的に書く。これは『冗長』に見えるが、prior cycle の stale state (古い PR 番号 / repo / session ID 等) が再利用 path で混入する silent bug を防ぐ defensive pattern。reviewer (人間 / AI) は redundant 削除を提案しないこと」 -- **anti-pattern 警告**: `let state = read_state().unwrap_or_else(|| State::new(id, repo, time));` だけで identity field を `ctx` で上書きしないと、prior cycle の値が残留する -- **good pattern 例**: PR #214 `review_recheck.rs:177-193` を inline cite (`state.pr` / `state.repo` / `state.started_at` / `state.review_recheck_count` / `state.head_commit` の 5 field reset) -- **由来 cite**: PR #214 の CR Major #4 が「既存 state 再利用時も現在の push 情報に更新してください」として独立検出した実証 -- **enforcement layer**: 機械 lint は困難 (`read_state` pattern の構文認識 + identity field 列挙が必要) だが、simplicity-review LLM が `coding-style.md` を読むため "enforced via review" として機能、memory `feedback_no_unenforced_rules` 例外を満たす -- **派生プロジェクト波及**: `~/.claude/rules/common/` 配下のため techbook-ledger / auto-review-fix-vc に自動 - -#### 作業計画 - -- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) -- [ ] `~/.claude/rules/common/coding-style.md` に新 section「Defensive State Reset in State Machines」追記 (anti-pattern + good pattern + PR #214 由来 cite、約 30 行) -- [ ] markdownlint clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `~/.claude/rules/common/coding-style.md` に「Defensive State Reset in State Machines」section が追加される -- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 -- 由来 cite (PR #214 CR Major #4 + `review_recheck.rs:177-193`) で reviewer / Claude が rule 背景を理解可能 -- simplicity-review LLM が future PR で同型 `read_state()` を含む state machine 編集を review する際、本 section の anti-pattern 警告を参照可能 - -#### 詰まっている箇所 - -なし。Effort S、global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 - ---- - -### `no-workstream-seq-names-in-config` lint rule 追加 — config comment 内 `PR-[0-9]+` ephemeral workstream sequence 検出 (PR #216 post-merge-feedback T1-1 採用) - -> **動機**: PR #216 で `.claude/hooks-config.toml` の `weekly_review_reminder` section comment に `(2026-06-23、PR-1)` および `次 PR (PR-3) で移行予定` を書き込んだ。これは ephemeral workstream sequence names (= マルチ PR 計画のローカル連番、GitHub PR `#NNN` ではない) を permanent artifact (config file comments) に embed する違反であり、`coding-style.md` § Cross-File Reference Lifecycle の「permanent → ephemeral 禁止」原則と同根。 -> -> 既存の rule⑥ `no-ephemeral-todo-reference` は `docs/todo*.md` file path 直接参照を検出するが、本ケースのような workstream sequence names (`PR-N`) は対象外。PR シリーズ完了後に「PR-3 とは何だったか」が文脈喪失し dead pointer 化するリスクが構造的に残る。 -> -> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 1 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-06-23 ユーザー承認)。順位 217 (文書層) と同根 = 1 PR bundle 推奨。analyzer rationale: 「config file comment は permanent artifact であり dead pointer 化の直接トリガ。pattern `(?i)PR-[0-9]+` の FP リスクは軽微 (config コメントで企業コード等との混同は稀)」。Prepush T1-1 + Session T1-1 + Session T1-2 の 3 ソース独立検出。 -> -> **Tier 列との不整合補足**: analyzer feedback report (`.claude/feedback-reports/216.md`) では `Tier 1: Hooks/Linter 改善` カテゴリに分類されているが、本 todo entry の Tier 列および「実行優先度」行では **🔧 Tier 2** に再分類している。memory `feedback_tier_classification` の re-classification rule (= analyzer の Tier 1/3 分類は鵜呑みにせず実体ベース ⟨mechanical enforcement = T1 / docs 修正 = T3⟩ で再分類) に従い、project tier 定義 (🚀 Tier 1 = high-impact urgent / 🔧 Tier 2 = tooling improvements) と整合させた意図的再分類。 -> -> **参照**: `.claude/feedback-reports/216.md` Tier 1 #1、PR #216 commit `65963197e6c0` の hooks-config.toml diff、既存 rule⑥ `no-ephemeral-todo-reference` (template)、rule⑫ `no-hardcoded-jj-revset-range` (TOML meta field test_coverage pattern の template)、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle、`.claude/custom-lint-rules.toml` (rule 配置先)。 -> -> **実行優先度**: 🔧 **Tier 2** (project 分類、上記 re-classification 後) — Effort S。rule 追加 (~30 行 TOML + meta field) + test 追加 (~50 行 main.rs) で約 80 行、順位 217 と bundle すれば 1 PR diff < 200 行見込み。 - -#### 設計決定 (案) - -- **rule id**: `no-workstream-seq-names-in-config` -- **pattern**: `(?i)\bPR-[0-9]+\b` -- **extensions**: `["toml", "yaml", "yml", "jsonc"]` (config formats、plain `json` は comment 構文を持たず rule 対象外なので除外) -- **検出範囲**: comment 行のみ (TOML `#`、YAML `#`、JSONC `//` 等)。**実装注**: 多くの project-local lint rule は file 全体に regex match している。本 rule は comment 行検出が本質だが、初期実装は file 全体マッチで MVP として開始し、false positive 観測後に comment 行限定への絞り込みを判断する (= 同 pattern の rule⑥/⑫ と整合的な段階導入) -- **exception**: GitHub PR number `#[0-9]+` 形式は対象外。実装上は positive pattern `(?i)\bPR-[0-9]+\b` が `#NNN` を match しない (`#` prefix 形式は別) ため exception 不要。ただし test で「`#216`」「`PR #216`」のようなケースが fire しないことを negative test で固定 -- **severity**: `warning` (block しない、author への hint 機能優先、rule⑫ と同 pattern) -- **block message**: 「Ephemeral workstream sequence name (`PR-N`) detected in config comment. Permanent artifacts (config files) must not reference ephemeral workstream sequences. Use GitHub PR `#NNN` for stable cite, or inline rationale instead of "PR-3 で移行予定". See coding-style.md § Cross-File Reference Lifecycle.」 -- **TOML meta field** (`test_coverage` schema、rule⑫ と同 pattern): - ```toml - [rules.test_coverage] - other_ext_tests = ["no_workstream_seq_detects_pr_dash_n_in_jsonc_comment"] - - [rules.test_coverage.main_ext_tests] - toml = ["no_workstream_seq_detects_pr_dash_n_in_toml_comment", "no_workstream_seq_skips_github_pr_number"] - yaml = ["no_workstream_seq_detects_pr_dash_n_in_yaml_comment"] - yml = ["no_workstream_seq_detects_pr_dash_n_in_yml_comment"] - ``` - -#### 作業計画 - -- [ ] `.claude/custom-lint-rules.toml` に `[[rules]]` entry 追加 (id / pattern / extensions / severity / message / test_coverage) -- [ ] `src/hooks-post-tool-linter/src/main.rs` の `mod tests` に positive test 4 件 (toml / yaml / yml / jsonc 各 1) + negative test 1 件 (`#216` / `PR #216` が fire しない) を追加 -- [ ] `cargo test -p hooks-post-tool-linter` で rule_test_coverage_check が pass することを確認 -- [ ] dogfood: 本 PR で `hooks-config.toml` から `PR-1` / `PR-3` 表記が削除 or `#216`/`#NNN` 表記に置換されることを確認 -- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 - -#### 完了基準 - -- `no-workstream-seq-names-in-config` rule が `.toml` / `.yaml` / `.yml` / `.jsonc` / `.json` comment 内の `PR-[0-9]+` を warning として検出 -- `#216` / `PR #216` のような GitHub PR number は fire しない (negative test pass) -- rule_test_coverage_check が main_ext_tests / other_ext_tests 整合性を強制 -- 順位 217 (文書層) と同 PR で land した場合、`coding-style.md` への具体例追加と機械強制の 2 層防御が確立される - -#### 詰まっている箇所 - -- comment 行限定 vs file 全体 match: MVP は file 全体 match で開始、false positive 観測後に絞り込み判断 (rule⑥/⑫ と同段階導入)。順位 217 の docs 追加で「config comment」の意図を明示化することで、author が non-comment context での意図的使用を回避できれば file 全体 match でも実用性高い -- `#NNN` vs `PR-NNN` 境界: regex `\bPR-[0-9]+\b` は `#` prefix を含まないため除外可能、ただし将来 `PR-#216` のような mixed 表記が登場した場合は pattern 拡張が必要 - ---- - -### `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に config file comments の permanent artifact 扱い明記 + workstream sequence 禁止例追加 (PR #216 post-merge-feedback T3-1 採用) - -> **動機**: 既存 `coding-style.md` § Cross-File Reference Lifecycle は markdown 内 cross-reference (docs/ADR/README 等) を主に想定して書かれており、**config file comments (`.toml`/`.json`/`.yaml`) も permanent artifact** であることが暗黙的にしか扱われていない。PR #216 で `hooks-config.toml` comment に "PR-1" / "PR-3" ephemeral workstream sequence を embed した違反は、author が「config の comment は注釈であって rule の対象外」と暗黙的に判断していた可能性が高い。 -> -> 順位 216 の lint rule が機械的に防止するが、author の理解を促す **文書層** として補完することで「なぜ config comment にも reference lifecycle が適用されるか」を理解可能にする。機械層 (216) + 文書層 (本 task) の 2 層防御は順位 200/202/205 と同 pattern。 -> -> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。順位 216 (機械層) と 1 PR bundle 推奨。analyzer rationale: 「既存ルールは markdown document 内の cross-reference を主に想定しており config file comments の permanent artifact としての扱いが暗黙的。Tier 1-1 の custom lint rule が機械的に防止するが、author の理解を促す文書層として補完。Frequency Medium (cross-file reference violations の systemic pattern と同根)」。Session T3-1 + PR-analysis T3-1 の独立 2 ソース収束。 -> -> **参照**: `.claude/feedback-reports/216.md` Tier 3 #1、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle (現行 section、編集対象)、順位 216 (機械層 = lint rule、本 task の機械強制対応)、memory `feedback_global_config_backup` (snapshot 必須)、PR #216 hooks-config.toml diff (違反実例として inline cite)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。global rules への docs 追記 ~15 行で完結、`feedback_global_config_backup` snapshot を忘れない。 - -#### 設計決定 (案) - -- **追加先**: `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle の anti-pattern examples block (現状 Rust raw string / TOML コメント / JSONC ヘッダーコメント の 3 種を含む) の TOML コメント sub-section に「workstream sequence names も禁止」と明記 -- **追加内容案**: - - ```markdown - - **TOML コメント / config** (拡張): - - BAD: `# 由来: docs/todo.md "" 参照のため` - - BAD: `# 詳細: docs/local-llm-offload-analysis.md §A-2 を参照` (`*-analysis.md` は ephemeral 計画書、retire 時に dead pointer 化) - - BAD (workstream sequence): `# PR-3 で移行予定` / `# 次 PR (PR-1) で実装` (ephemeral workstream sequence、PR シリーズ完了後に文脈喪失で dead pointer 化) - - GOOD: `# 由来: PR #94 (docs lifecycle 整理)` または ADR 参照 - - GOOD: `# 詳細: docs/adr/adr-NNN-feature.md を参照` または config 設計意図を inline で 1-2 行記述 - - GOOD (workstream cite): `# 由来: PR #216` (GitHub PR number は永続 identifier) - ``` - -- **由来 cite**: PR #216 で `hooks-config.toml` の `weekly_review_reminder` comment に `(2026-06-23、PR-1)` / `次 PR (PR-3) で移行予定` を embed した実例を inline cite -- **enforcement layer**: 機械層は順位 216 lint rule で強制、本 task は author の理解促進と「なぜ workstream sequence も dead pointer になるか」の rationale 提供 -- **派生プロジェクト波及**: `~/.claude/rules/common/` 配下のため techbook-ledger / auto-review-fix-vc に自動 - -#### 作業計画 - -- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) -- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle の TOML コメント anti-pattern block に workstream sequence 禁止例を追加 (~5 行) -- [ ] 同 section 末尾近くの GOOD examples block に GitHub PR number 形式 (`# 由来: PR #NNN`) を明示 (~2 行) -- [ ] markdownlint clean -- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 - -#### 完了基準 - -- `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に「workstream sequence names (`PR-1`/`PR-3` 等) も config comment 内で禁止」が明文化される -- GOOD example として GitHub PR number 形式 (`# 由来: PR #NNN`) が提示される -- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 -- 順位 216 (機械層) と同 PR で land した場合、機械強制 + 文書理解の 2 層防御が確立される - -#### 詰まっている箇所 - -なし。Effort XS、global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 - ---- - -### ADR-039 § Bounded Lifetime + `~/.claude/rules/common/patterns.md` に provisional `enabled` 変更時の todo entry 必須化を追加 (PR #216 post-merge-feedback T3-2 採用) - -> **動機**: PR #216 で `weekly_review_reminder.enabled = false → true` を「次 PR-3 (`[features].enabled` allow-list 移行) で真の opt-in 切り替えになるまでの暫定」として config comment に rationale を残したが、対応する `docs/todo*.md` の **移行 tracking entry を作成していなかった**。 -> -> このため: -> -> - 「いつ PR-3 で移行する予定か」が config comment にしか残らず、commit を辿らないと判らない -> - PR-3 が遅延または忘れられた場合、provisional state が silent に永続化する (= silent aging) -> - ADR-039 § Bounded Lifetime の「採否判定タイミングの明示」原則が config comment では弱く、todo entry で明示すべき -> -> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Low / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「provisional state を config comment のみで追跡する pattern が silent aging を招く。ADR-039 の bounded-lifetime checklist に『provisional enabled 変更 → todo entry 追加』を明示することで future PR での遵守を促進。Frequency Low (初観測) だが Adoption Risk None で早期 codify の費用対効果は高い」。Session T3-2 + PR-analysis T3-2 + Prepush T2-1 (ADR 側アプローチ統合) の 3 ソース独立収束。 -> -> **参照**: `.claude/feedback-reports/216.md` Tier 3 #2、`docs/adr/adr-039-experimental-feature-standard-pattern.md` § Bounded Lifetime (編集対象、6-point design checklist 拡張)、`~/.claude/rules/common/patterns.md` § Experimental Feature 設計時の参照必須 (補助編集対象、同旨 note 追加)、PR #216 hooks-config.toml comment (違反実例)、memory `feedback_global_config_backup` (snapshot 必須)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR + global rules への docs 追記 ~10 行で完結、`feedback_global_config_backup` snapshot を忘れない。 - -#### 設計決定 (案) - -- **ADR-039 編集**: § Bounded Lifetime の 6-point design checklist に新 checklist item 追加 (本 ADR は project-local のため snapshot 対象外): - - ```markdown - - [ ] **provisional state の todo tracking**: 試験運用中に config 値を一時的に変更する場合 (例: `enabled = false → true` を本採用判定前に試験的に有効化)、対応する `docs/todo*.md` entry を作成し、移行/採否判定タイミングを明示する。config comment のみで追跡すると silent aging を招く - ``` - -- **`~/.claude/rules/common/patterns.md` 編集** (global、波及対象): § Experimental Feature 設計時の参照必須 の末尾に同旨 note を追加 (~3 行): - - ```markdown - > **provisional state の追跡**: 試験運用中に config 値を一時的に変更する場合 (例: 試験運用元での明示 enable)、必ず `docs/todo*.md` に移行 tracking entry を作成し、採否判定タイミングを明示する。config comment のみの追跡は silent aging を招く (PR #216 で実観測、ADR-039 § Bounded Lifetime 参照)。 - ``` - -- **由来 cite**: PR #216 で `weekly_review_reminder.enabled` の provisional change を config comment のみで tracking した実例を inline cite -- **派生プロジェクト波及**: `~/.claude/rules/common/patterns.md` への追加で techbook-ledger / auto-review-fix-vc に自動波及 - -#### 作業計画 - -- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per、patterns.md 編集のため) -- [ ] `docs/adr/adr-039-experimental-feature-standard-pattern.md` § Bounded Lifetime 6-point checklist に provisional todo tracking item 追加 (~5 行) -- [ ] `~/.claude/rules/common/patterns.md` § Experimental Feature 設計時の参照必須 に同旨 note 追加 (~3 行) -- [ ] markdownlint clean (両 file) -- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 - -#### 完了基準 - -- ADR-039 § Bounded Lifetime に provisional state todo tracking checklist item が追加される -- `~/.claude/rules/common/patterns.md` に同旨 note が追加される -- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 -- future PR で provisional state を導入する際、config comment のみで tracking せず todo entry も作成する慣行が確立される - -#### 詰まっている箇所 - -なし。Effort XS、ADR + global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 - ---- - -### `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に「commit description 言及 ≠ 実装完了」明文化 (PR #216 post-merge-feedback T3-3 採用) - -> **動機**: PR #216 cleanup 作業中、analyzer (Claude) が「PR #215 commit description で 順位 215 を言及している = 実装完了」と naïve に判断し、当初 6 entries (147/151/212/213/214/215) 削除計画を立てた。実際にはユーザーの修正 + grep `"Defensive State Reset" ~/.claude/rules/common/coding-style.md` による実体確認の結果、順位 215 は **todo entry が PR #215 で追加されただけ** で実装は未着手だった (5 entries 削除が正解)。 -> -> この naïve assumption は今後も analyzer / Claude が再発する可能性が高く、誤った削除を実施すると未実装タスクが docs から消える silent loss につながる。development-workflow.md に明文化することで、future Claude session 内で同 anti-pattern を構造的に防止する。 -> -> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 3 #3 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「本 PR で『commit description に順位 N 言及 = 実装完了』の naïve assumption から analyzer が誤った 6 entry 削除計画を立てた実観測。ユーザー修正で 5 entry に訂正。Effort XS、Severity Medium (analyzer の誤判定リスクが今後も継続)、Adoption Risk None」。Session T3-3 の単一ソースだが Severity Medium で採用条件成立。 -> -> **参照**: `.claude/feedback-reports/216.md` Tier 3 #3、`~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック (編集対象)、PR #216 cleanup session log (誤判定 → grep 救出の経緯)、memory `feedback_verify_task_not_already_done` (関連 memory、再確認 verb-noun rule の前提となる「verify」step)、memory `feedback_global_config_backup` (snapshot 必須)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。global rules への docs 追記 ~8 行で完結、`feedback_global_config_backup` snapshot を忘れない。 - -#### 設計決定 (案) - -- **追加先**: `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック の末尾近く (関連 guideline と隣接配置) -- **追加内容案**: - - ```markdown - ### Commit description 言及は実装完了の証拠ではない - - PR commit description で「順位 N」「feature X 実装」「Y を追加」等を言及していても、**実際のファイル変更を `jj diff` / `grep` で確認するまで completion 判定してはならない**。 - - 特に多 commit PR (= 1 PR で複数の論理 unit を扱う場合): - - 「順位 N 削除」commit と「順位 N 実装」commit が分かれていることがある - - todo entry の追加 / docs 更新だけで実装本体が未着手な commit も存在する - - 検証手順: - - 1. commit description で言及されている feature / 順位 N を特定 - 2. `jj diff -r ` で実際のファイル変更を確認 - 3. 実装対象 file を `grep` で確認 (例: 「Defensive State Reset」section が `~/.claude/rules/common/coding-style.md` に実在するか) - 4. 実体確認後に「完了」判定 - - 由来: PR #216 で analyzer が「PR #215 commit description で 順位 215 を言及 = 実装完了」と naïve 判定し誤った削除計画を立てた実観測 (ユーザー修正 + grep 救出で訂正)。memory `feedback_verify_task_not_already_done` と相補的 (前者は task 着手前の verify、本 rule は task 完了判定前の verify)。 - ``` - -- **enforcement layer**: 機械 lint は困難 (commit description の意味解析 + ファイル diff の cross-check が必要) だが、Claude が development-workflow.md を読む文脈で「明示的に書かれた rule」として機能、memory `feedback_no_unenforced_rules` 例外 (= 既存実践の明文化) を満たす -- **派生プロジェクト波及**: `~/.claude/rules/common/development-workflow.md` 配下のため techbook-ledger / auto-review-fix-vc に自動 - -#### 作業計画 - -- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) -- [ ] `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に新 sub-section「Commit description 言及は実装完了の証拠ではない」を追加 (~25 行、設計決定の追加内容案 per) -- [ ] markdownlint clean -- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 - -#### 完了基準 - -- `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に「commit description 言及 ≠ 実装完了」guideline が追加される -- 検証手順 (4 step) が明示される -- PR #216 事例が inline cite として記録される -- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 - -#### 詰まっている箇所 - -なし。Effort XS、global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 - ---- - -### subprocess stress test (>64KB stdout) を ADR-031 weekly-review pipeline 経由で週次実行 (PR #217 post-merge-feedback T2-1 採用) - -> **動機**: PR #217 (refactor PR-3a) の post-pr-review iter 2 で 2 module (`hooks-session-start/src/jj_helpers.rs` + `hooks-pre-tool-validate/src/todo_staleness.rs`) に同型の subprocess deadlock 脆弱性が independent 観測された。具体的な脆弱性は、`Command::new("jj")` を `.stdout(Stdio::piped())` で spawn したあと parent process が `try_wait` ループで wait しつつ child の stdout を drain せず終了後にまとめて read するため、jj log の出力が pipe buffer (Linux default 64KB / Windows 4-64KB) を超えると child が write block → 親が wait block → deadlock。 -> -> CR Major fix として `spawn_stdout_drainer` + `poll_child_with_deadline` 関数を抽出して background drain に変更 (takt-fix iter 2)、さらに iter 3 で `lib_subprocess::drain_pipe_unlimited` + `wait_with_timeout_basic` の既存共通 helper への統合に refactor。本 fix で deadlock は構造的に防止されたが、**実際に >64KB を pipe させる regression test が存在しない** ため future refactor で再発する盲点が残る。 -> -> **本タスクの位置づけ**: PR #217 post-merge-feedback Tier 2 #1 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「2 モジュールで deadlock パターン確認、High severity + Medium frequency で M effort を正当化、deadlock は大 buffer 時のみ顕在化するため手動検証が困難でテスト化が最も確実な防止手段」。 -> -> **ユーザー判断 (2026-06-23)**: 「毎回走るタイプ (hooks など) のテストに組み込むのは適切ではない、週に 1 回程度に頻度を落として通常の開発速度に影響が出ない形で CI に組み込みたい」。Stop hook quality gate (`cargo test`) や pre-push pipeline (`cargo test`) は毎 push 実行のため stress test のような高コスト・低頻度検証は不適切。ADR-031 weekly-review pipeline (週次 cron / 手動 `/weekly-review`) で `cargo test -- --ignored --test-threads=1` 系の追加 step として実行する方針。 -> -> **参照**: `.claude/feedback-reports/217.md` Tier 2 #1、PR #217 takt-fix iter 2 / iter 3 (`lib-subprocess` 統合)、ADR-031 § Phase B (takt workflow + facets)、`#[ignore]` test 慣習 (例: cli-pr-monitor の integration test、ADR-021)、`docs/adr/adr-044-subprocess-utility-extraction-boundary.md` (lib-subprocess の extraction 境界判定)、順位 221 (ADR docs codification、bundle 推奨)。 -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。stress fixture 作成 (~50 行 × 2 module) + ADR-031 weekly workflow への step 追加 + `cargo test -- --ignored` 経由の動作確認。 - -#### 設計決定 (案) - -- **test 配置**: 各 module の既存 `mod tests` に `#[ignore = "stress test, requires explicit --ignored flag (PR #217 T2-1)"]` 付きで追加 -- **fixture 方針**: 実 `jj log` を呼び出すと環境依存になるため、`Command::new("yes")` 系 (Linux) や `Command::new("cmd").args(["/c", "for /L %i in (1,1,N) do @echo ..."])` (Windows) で >64KB の決定論的出力を生成。あるいは `jj log` を repo 内の真の commit history で呼ぶ場合は test 前提として大型 repo を必要とせず、std::process::Command 単体で test 可能な形に -- **検証項目**: - - `> 64KB` の stdout を吐く child を spawn し、`drain_pipe_unlimited` 経由で完全 read できる (`output.len() > 64 * 1024`) - - timeout 内に child が exit する (`child.wait().is_ok()` 系 assert) - - parent が wait 完了する (deadlock していたら test 自体がハングして CI timeout で fail) -- **CI 統合**: ADR-031 weekly-review workflow に新 step `rust-stress` を追加 (`cargo test --workspace -- --ignored --test-threads=1`)。既存 rust-test group (`cargo test --workspace`) とは分離 (前者は毎回、後者は週次) -- **派生プロジェクト transferability**: `lib-subprocess` を採用する他 crate (cli-merge-pipeline / cli-pr-monitor / cli-push-runner / hooks-post-tool-linter) へも同型 stress test を transfer 可能。本 task の MVP は 2 module 限定、3+ module で同 pattern 観測時に拡張判断 (cli-push-pipeline は 2026-07-17 に crate 削除済みのため対象外) -- **memory `feedback_test_dry_antipattern.md`** 適用: 各 module の test 内に独立 helper (`spawn_large_output_child` / `assert_no_deadlock_within`) を duplicate、共有 test module は抽出しない - -#### 作業計画 - -- [ ] hooks-session-start/src/jj_helpers.rs の `mod tests` に `stress_drain_large_stdout_does_not_deadlock` 追加 (~50 行、`#[ignore]` 付き) -- [ ] hooks-pre-tool-validate/src/todo_staleness.rs の `mod tests` に同型 test 追加 (~50 行) -- [ ] `cargo test -p hooks-session-start -- --ignored --test-threads=1` でローカル動作確認 -- [ ] `cargo test -p hooks-pre-tool-validate -- --ignored --test-threads=1` でローカル動作確認 -- [ ] ADR-031 weekly-review workflow (`.takt/workflows/weekly-review.yaml` 等) に rust-stress step 追加 -- [ ] 次回 `/weekly-review` で実発火確認、本 task entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 各 module で `>64KB stdout` を pipe する stress test が `#[ignore]` 付きで存在 -- `cargo test -- --ignored --test-threads=1` で test が pass、deadlock していないこと (timeout しないこと) を確認 -- ADR-031 weekly-review workflow に新 step が追加され、次回 weekly 実行で stress test が走る -- 順位 221 (ADR docs) と合わせ、test 層 (本 task) + docs 層 (221) の 2 層防御が確立 - -#### 詰まっている箇所 - -- Windows での大出力 fixture コマンド: `yes` は Windows に存在しない。`cmd /c for /L` で代替可能だが PowerShell / bash 等の環境差を test 内で吸収する設計が必要 (cross-platform test fixture) -- ADR-031 workflow への step 追加: 既存 weekly-review yaml の構造を確認、rust-stress step の独立 facet 化が必要か、aggregate-weekly facet の pre-step として組み込むかは実装時判断 - ---- - -### ADR-NNN (採番未確定、land 時に確定): Safe Subprocess Stdout Pattern を ADR-016 appendix or 新 ADR で codify (PR #217 post-merge-feedback T3-1 採用) - -> **動機**: PR #217 takt-fix iter 2 で 2 module 同型の subprocess deadlock を fix した実例 (順位 220 参照) から、`Stdio::piped()` を伴う child process の安全な扱い方を ADR で永続化する必要が判明した。同 pattern は本 PR 以前にも `lib-subprocess` 内部で `drain_pipe_unlimited` + `wait_with_timeout_basic` として codify されていたが、**新規 subprocess spawn を書く著者が pipe buffer 制約を知らない場合の防御層が欠落** していた。 -> -> ADR で pattern を明文化することで: -> -> - 機械検知 (T1-1 lint rule、🤔 様子見) より低 risk な代替防止層として機能 -> - 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability を確保 (ADR は global 参照可能) -> - reviewer (人間 / AI) が PR review 時に「Stdio::piped() を見たらこの ADR を確認」する mental check が成立 -> - ADR-025 (CwdRestore Drop guard pattern) の precedent と整合: 「pattern の codify は test/lint に先行する低コスト防止層」 -> -> **本タスクの位置づけ**: PR #217 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「2 モジュールで同一パターン違反、Medium frequency + S effort + None risk、pattern を明文化することで T1-1 の lint rule 化より低 risk な代替防止層として機能、ADR-025 の precedent あり」。 -> -> **参照**: `.claude/feedback-reports/217.md` Tier 3 #1、PR #217 takt-fix iter 2 (`spawn_stdout_drainer` + `poll_child_with_deadline` 初版抽出) / iter 3 (`lib-subprocess` 統合)、`docs/adr/adr-016-long-running-command-strategy.md` (append 候補)、`docs/adr/adr-025-cwd-restore-drop-guard.md` (precedent: pattern codify ADR)、`docs/adr/adr-044-subprocess-utility-extraction-boundary.md` (lib-subprocess 境界判定)、`src/lib-subprocess/src/lib.rs` (`drain_pipe_unlimited` / `wait_with_timeout_basic` 実装)、順位 220 (test 層、bundle 推奨)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort S。ADR appendix or 新 ADR 作成 (~150 行)、3 pattern (background drain / `Command::output()` / `Stdio::null()`) の説明 + lib-subprocess utility cite + anti-pattern 例 (本 PR の deadlock fix 経緯を inline cite)。 - -#### 設計決定 (案) - -- **配置選択**: 2 案あり、ADR 起案時にユーザー判断: - - **Option A** (append): `docs/adr/adr-016-long-running-command-strategy.md` に新 section「Safe Subprocess Stdout Pattern」を追加。ADR-016 が既に subprocess 戦略を扱うため整合的、ADR 数を増やさない - - **Option B** (new): `docs/adr/adr-NNN-safe-subprocess-stdout-pattern.md` として新規 ADR (採番は land 時に確定、順位 135 placeholder policy per)。pattern が ADR-016 の長時間コマンド扱いとは別関心 (= pipe buffer 制約は短時間 subprocess でも発生) のため scope 分離する根拠あり -- **本 task の MVP 推奨**: Option A (append) — ADR 数増加を抑え、ADR-016 § 長時間コマンド戦略 直後の new section として組み込む。実装時の dogfood で B 化判断 -- **記述項目** (3 pattern + anti-pattern): - 1. **Background drain pattern**: `spawn(...)` + `std::thread::spawn(move \|\| out.read_to_end(...))` で stdout を別 thread で drain、parent は `try_wait` ループ。本 PR で `lib_subprocess::drain_pipe_unlimited` + `wait_with_timeout_basic` として codify 済 - 2. **`Command::output()` pattern**: 短時間 subprocess で stdout/stderr を一括 capture する標準慣習。pipe buffer 問題を回避するが timeout 制御不可 - 3. **`Stdio::null()` pattern**: stdout を完全に捨てる場合 (= 副作用のみ目的)。pipe buffer 問題なし、最も simple - 4. **Anti-pattern**: `Stdio::piped()` + drain なしで `try_wait` ループ。pipe buffer 枯渇で deadlock (本 PR の修正前 state、inline cite) -- **由来 cite**: PR #217 takt-fix iter 2 の deadlock 修正経緯と iter 3 の lib-subprocess 統合 refactor を inline 引用 -- **派生プロジェクト波及**: ADR は global 参照可能、本 ADR を `~/.claude/rules/common/` に link することで techbook-ledger / auto-review-fix-vc 等に reference 提供 -- **enforcement layer**: 機械 lint (T1-1) は false positive リスクで 様子見、本 ADR が author 教育 + reviewer 確認の文書層、順位 220 (stress test) が test 層、3 層構成 (docs / test / lint defer) で防御 - -#### 作業計画 - -- [ ] ADR 配置の Option A/B 判断 (Option A = ADR-016 append が MVP 推奨) -- [ ] ADR section / 新 ADR を作成 (~150 行、3 pattern + anti-pattern + cite) -- [ ] CLAUDE.md ADR list 追記 (Option B の場合のみ) -- [ ] ADR-025 precedent との相補性を ADR 内で明示 -- [ ] `~/.claude/rules/common/coding-style.md` (or rust/patterns.md) から本 ADR への link を追加 (派生プロジェクト transferability) -- [ ] 本 task entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR (appendix or new) が land、3 pattern + anti-pattern + 由来 cite を含む -- ADR-016 / ADR-025 / ADR-044 / lib-subprocess との関係性が明確 -- `~/.claude/rules/common/` から本 ADR への参照が追加され、派生プロジェクトで future PR 著者が `Stdio::piped()` を書く際の reference として機能 -- 順位 220 (stress test) と相補的に、docs + test の 2 層防御確立 - -#### 詰まっている箇所 - -- Option A vs B の判断: ADR-016 § 長時間コマンド戦略 が「長時間 = timeout 制御」に focus している場合、本 pattern (pipe buffer = 短時間でも発生) との scope mismatch で別 ADR が綺麗。実装着手時に既存 ADR-016 を read して判断 -- `~/.claude/rules/common/` への link 追加先: `coding-style.md` か `rust/patterns.md` かは Option A/B の結論と整合させる必要あり - ---- - -### `~/.claude/CLAUDE.md` に「複数セッション跨ぎの計画文書作成時は AI が先走らずユーザー確認後に方針報告し GO/NO-GO を得る」ルール追加 (PR #218 post-merge-feedback #5 採用) - -> **動機**: PR #218 (docs PR、ファイルサイズチェックフロー改善計画 + 順位 220/221 採用) のセッション内で、Plan file (`docs/file-length-enforcement-plan.md`) 作成完了報告後、AI (Claude) が **ユーザー承認なしに PR-W0 (weekly audit step 追加) の実装着手を開始** し、ユーザーが `[Request interrupted by user]` で停止 + 「勝手に作業を進めないでください」と明示的に course correction する事案が発生した。Auto mode 下でも「計画書 / planning doc 作成のような **大きな task 完了時** は GO/NO-GO の確認待ちが必須」という規範を CLAUDE.md に明文化することで、本セッション内の事例を後続セッションで再発防止する。 -> -> **本タスクの位置づけ**: PR #218 post-merge-feedback #5 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「AI がユーザー確認なしに計画書作成を開始し `[Request interrupted by user]` で停止させた事例。Severity Medium (AI 暴走 = UX 劣化)・Effort XS・Adoption Risk None → ✅ 条件を満たす。Frequency Low だが Effort が極小なため採用コストが低い」。 -> -> **参照**: `.claude/feedback-reports/218.md` Tier 3 #5、PR #218 session transcript (Plan file 作成完了 → AI 先走り → ユーザー停止 → "勝手に作業を進めないでください" の course correction)、memory `feedback_no_unauthorized_reorder.md` (推奨実行順序の上位タスクが blocked された時点で停止し、ユーザーに pivot 可否を確認する、の補強)、memory `feedback_global_config_backup.md` (snapshot 必須)、`~/.claude/CLAUDE.md` (編集対象 global config)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。global config への 1 段落追記で完結、`feedback_global_config_backup` snapshot を忘れない。 - -#### 設計決定 (案) - -- **追加先**: `~/.claude/CLAUDE.md` の `## Personal Preferences` section 直後 (もしくは `## Doing tasks` 配下の sub-section) -- **rule 内容**: - - ```markdown - ### AI 先走り防止 — 計画文書作成完了時の GO/NO-GO ゲート - - 複数セッション跨ぎの計画文書 (planning doc / 設計ドキュメント) の作成完了時は、 - Auto mode の最中であっても **次の実装着手を一時停止し、ユーザーに方針報告 + - GO/NO-GO 確認を待つ**。 - - 対象となる "大きな task" の例: - - - 新規 planning doc (`docs/-plan.md` / `docs/-analysis.md` 等) の作成完了 - - ADR 起案 - - 複数 PR にまたがる作業計画の決定 - - 既存 planning doc への大規模追記 (Tier 1/2 構成変更等) - - 対象外 (= 通常 task として継続して問題ない): - - - 単一 PR scope 内の段階的 commit - - 既存計画通りの逐次実装 step - - GO/NO-GO 確認のフォーマット例: - - > Plan file 作成完了。次の step は PR-W0 (...) への着手です。進めて OK か? - - Auto mode の「prefer action over planning」原則の例外として、planning doc - レベルの完了点では明示承認待ちが必須。 - ``` - -- **由来 cite**: PR #218 session transcript で実観測した「Plan file 完了報告 → AI が PR-W0 着手 → ユーザー停止 + 'AI 先走り' 指摘」の流れを inline cite -- **memory `feedback_no_unauthorized_reorder` との関係**: 既存 memory は「task が blocked された時点で停止」を扱うが、本 rule は「task 完了時 (= 自然な区切り) で停止」を扱う = lifecycle の異なる stage を扱う相補的 rule -- **派生プロジェクト波及**: `~/.claude/CLAUDE.md` 編集のため全 project に自動波及、planning doc の頻度が高い大型 refactor PR で効果を発揮 -- **Auto mode との関係**: Auto mode 仕様の「prefer action over planning」と本 rule の「planning 完了時は停止」は scope 分離 (前者は通常作業の AI 自律性、後者は planning doc レベルの mile stone 確認) で衝突しない - -#### 作業計画 - -- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) -- [ ] `~/.claude/CLAUDE.md` に新 sub-section「AI 先走り防止 — 計画文書作成完了時の GO/NO-GO ゲート」を追加 (上記設計決定の rule 内容、~30 行) -- [ ] markdownlint clean -- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 - -#### 完了基準 - -- `~/.claude/CLAUDE.md` に新 sub-section が追加される (対象 task 例 / 対象外 / フォーマット例 含む) -- PR #218 事例が inline cite として記録される -- 全プロジェクト (techbook-ledger / auto-review-fix-vc 含む) に global rule として自動波及 -- Auto mode 下でも planning doc 完了時点で AI が明示承認待ちに転じることが、次回以降の planning task で確認可能 - -#### 詰まっている箇所 - -- 対象範囲の境界定義: 「計画文書」「設計ドキュメント」「大きな task」の判定基準が author に依存する余地あり。MVP は上記「対象 task の例」「対象外」リストで運用、3+ 回の dogfood で境界明確化を判断 (順位 207 mechanical lint scope 外 boundary case 追加の pattern と同様) -- Auto mode 仕様との関係明示: `~/.claude/CLAUDE.md` の Auto mode セクションが追加 or 改訂されている場合、本 rule の例外条項 (「prefer action over planning」との関係) を Auto mode セクション側にも cross-reference するか判断 - ---- - -### `ACTIVE_RUN_FRESH_THRESHOLD_SECS` と `ORPHAN_THRESHOLD_SECS` の compile-time 同期 (PR #222 post-merge-feedback T1-1 採用) - -> **動機**: PR #222 で hooks-stop-quality に追加した `ACTIVE_RUN_FRESH_THRESHOLD_SECS = 1500` は、hooks-session-start reaper の `ORPHAN_THRESHOLD_SECS = 1500` と **同値である必要がある** (Stop hook が「active」と判定する window と、reaper が「orphan」と判定する threshold が非対称になると、その隙間に挟まった run が両方の防御層から漏れる)。現状は `hooks-stop-quality/src/main.rs:67` のコメント (「reaper の `ORPHAN_THRESHOLD_SECS` (= 1500s) と同値」) で同期を「人間が読んで覚える」契約に留まり、片方を変更したときに他方を追従する mechanical enforcement が欠落している。 -> -> 同型の precedent として `cli-merge-pipeline/src/feedback.rs:60` の `pub const ORPHAN_THRESHOLD_SECS: u64 = TAKT_TIMEOUT_SECS + 300;` が存在し、derived value として上流定数 (`TAKT_TIMEOUT_SECS`) との関係を compile-time で保証している。本 task は同じ pattern を hooks-stop-quality / hooks-session-start の magic number 同期にも適用する。 -> -> **本タスクの位置づけ**: PR #222 post-merge-feedback Tier 1 #1 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None、2026-06-27 ユーザー承認)。analyzer rationale: 「3 reports 全てで threshold alignment を言及。`cli-merge-pipeline` の precedent (const + assert 方式) が参照実装として存在、実装コスト低。drift 発生時に orphan detection window と quality gate skip window が非対称になるリスクが明確。Effort M かつ Frequency Medium で採用候補」。`feedback_tier_classification` per analyzer Tier 1 (= mechanical enforcement) → project Tier 2 (🔧) に再分類。 -> -> **参照**: `.claude/feedback-reports/222.md` Tier 1 #1、`src/hooks-stop-quality/src/main.rs:67` (現状のコメント契約 + 定数定義)、`src/hooks-session-start/src/reaper.rs:29` (source of truth = `pub(crate) const ORPHAN_THRESHOLD_SECS: u64 = 1500`)、`src/cli-merge-pipeline/src/feedback.rs:60` (precedent: derived const + 上流定数 reference)、ADR-043 (Security/Quality Gate Fail-Closed) — fail-closed threshold の同期が崩れた場合のリスクを ADR で論じる経路、ADR-030 (決定論的 Post-Merge Feedback) § L2 reaper — `ORPHAN_THRESHOLD_SECS` の出処、順位 224 (ADR-043 amendment、bundle 推奨)。 -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。lib 抽出 (shared crate / lib module) vs cross-crate const re-export + compile-time assert の選択 + test 追加。 - -#### 設計決定 (案、land 時に判断) - -3 案を比較し、本 task 着手時に Option 選択: - -- **Option A** (shared lib crate 新設): `src/lib-takt-constants/` 等の新 crate を作成し `ORPHAN_THRESHOLD_SECS` / `ACTIVE_RUN_FRESH_THRESHOLD_SECS` を pub const として公開。reaper と stop-hook 双方が dep として import。**Pros**: 単一の source of truth、将来 takt 関連の magic number 追加に scale。**Cons**: 新 crate のため Cargo workspace への追加 + build graph 拡張、ADR-026 (Cargo workspace) との整合確認、過剰一般化のリスク (Effort M の上限) -- **Option B** (cross-crate const re-export): hooks-session-start の `reaper::ORPHAN_THRESHOLD_SECS` を `pub` に昇格、hooks-stop-quality が `[dependencies] hooks-session-start = { path = "..." }` で依存し `use hooks_session_start::reaper::ORPHAN_THRESHOLD_SECS;` で参照。**Pros**: 新 crate 不要、変更最小。**Cons**: hooks crate 間の依存方向が逆 (本来は SessionStart hook と Stop hook は独立だが、これで一方向 dependency が発生)、cargo workspace の循環依存リスク (現状は問題なくとも将来制約に) -- **Option C** (compile-time assert via `const _: () = assert!(...)`): 各 hook crate で独立に const を定義しつつ、片方の crate 内で `const _: () = assert!(REAPER_ORPHAN_THRESHOLD_SECS == ACTIVE_RUN_FRESH_THRESHOLD_SECS);` 系の compile-time 検証を入れる。**Pros**: dep 依存 0、各 hook crate の autonomy 維持。**Cons**: 検証側 crate に「他 crate の値を埋め込む」必要があり、結局参照経路が必要 (= Option B と同等の依存になる) -- **MVP 推奨**: **Option B と C の hybrid** で、stop-hook 内に `const _: () = assert!(...)` を追加して const 同期を保証 (C 側のメリット) しつつ、`hooks-session-start::reaper::ORPHAN_THRESHOLD_SECS` を pub 昇格して hooks-stop-quality が dep として参照 (B 側のメリット)。Option A (新 crate) は将来同型 magic number が 3+ 出てきた時に再評価 -- **`cli-merge-pipeline/src/feedback.rs:60` の precedent を inline cite**: 上流定数 (`TAKT_TIMEOUT_SECS`) + derived const + 同 crate 内 const equality assert の構成例。本 task は cross-crate 版に拡張 -- **test 追加**: compile-time assert は失敗時 compile error なので runtime test は不要、ただし「片方の const を変更したら compile error になる」ことを確認する手順を README / コメントに記録 (PR description で dogfood) -- **派生プロジェクト transferability**: 本 pattern (cross-crate const sync) は派生プロジェクト (techbook-ledger / auto-review-fix-vc) でも同型ニーズが発生しうるが、現状は本 repo 固有のため transferability は ADR-016 / ADR-043 等への documentation 経由 - -#### 作業計画 - -- [ ] Option A / B / C 判断 (MVP 推奨 = Option B+C hybrid: assert で同期保証 + pub 昇格して dep 参照) -- [ ] `hooks-session-start::reaper::ORPHAN_THRESHOLD_SECS` を `pub` 昇格 (現状 `pub(crate)`)、必要なら module path の整理 -- [ ] hooks-stop-quality の `Cargo.toml` に `hooks-session-start` dep を追加 (Option B 側のアプローチ) -- [ ] hooks-stop-quality `main.rs` に `const _: () = assert!(ACTIVE_RUN_FRESH_THRESHOLD_SECS == hooks_session_start::reaper::ORPHAN_THRESHOLD_SECS);` を追加 -- [ ] `cargo build --workspace` で compile-time assert が通ることを確認、片方を変更して compile error を観測 (PR description に貼付) -- [ ] hooks-stop-quality の既存コメント (line 67) を「compile-time assert で同期保証」 に更新 -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 片方の const を変更すると `cargo build` が compile error で失敗する -- hooks-stop-quality / hooks-session-start の magic number 同期が compile-time 契約として codified -- `cli-merge-pipeline/src/feedback.rs:60` precedent と同 pattern が確立、将来同型 magic number 追加時の参照実装になる -- ADR-030 §L2 と本 task の関係性が ADR 内で明示される (順位 224 と相補 = T1 mechanical + T3 docs) - -#### 詰まっている箇所 - -- Option A/B/C 判断: 新 crate 追加 vs 既存 dep 追加 vs assert macro のいずれも trade-off あり、ADR-026 (Cargo workspace) との整合性を実装時に確認 -- hooks crate 間の依存方向: SessionStart と Stop は本来独立な lifecycle stage だが、const 共有のため一方向 dep が必要 (Option B/C)。将来 hooks 共通 lib (= 順位 224 関連で hook_stop_quality の `meta_is_fresh` 抽出が浮上した場合) が出てきた際に再整理判断 - ---- - -### ADR-043 (Security/Quality Gate Fail-Closed) に hooks-stop-quality の error handling を具体例として追記 (PR #222 post-merge-feedback T3-1 採用) - -> **動機**: PR #222 で hooks-stop-quality に追加した `meta_is_fresh()` / `meta_is_active_run()` / `takt_subsession_active()` は、すべての error path で `false` を返却することで「gate が effective (= skip しない)」状態に倒す **fail-closed pattern** を踏襲している。具体的には mtime 取得失敗 / system clock skew (future timestamp) / malformed JSON / file read error すべてが「active subsession ではないと判定」→「quality gate を skip しない」= 安全側に倒れる。 -> -> ADR-043 (Security/Quality Gate での Fail-Closed 原則) は **試験運用 ADR** として既に存在するが、現状は abstract な原則記述に留まる。PR #222 の `meta_is_fresh` 実装は ADR-043 の **concrete instantiation** として価値があり、ADR 内の具体例 list に追記することで: -> -> - ADR が「概念定義 + 具体例 list」型に進化、将来同型 fail-closed pattern を実装する author の参照実装になる -> - 派生プロジェクト (techbook-ledger / auto-review-fix-vc) で hook / lint / pipeline を fail-closed で書く際の transferability 向上 (ADR は global 参照可能) -> - 順位 223 (mechanical enforcement) と相補的に、docs 層で fail-closed pattern を author 教育として codify -> -> **本タスクの位置づけ**: PR #222 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-27 ユーザー承認)。analyzer rationale: 「ADR-043 は永続 artifact で既存。追記は XS Effort で ADR の具体例を充実。fail-closed pattern は本 PR 以外でも発生する (Frequency Medium)。Effort XS + None risk で採用候補」。 -> -> **参照**: `.claude/feedback-reports/222.md` Tier 3 #1、`docs/adr/adr-043-security-gates-fail-closed.md` (追記対象、試験運用 ADR)、`src/hooks-stop-quality/src/main.rs` の `meta_is_fresh()` / `meta_is_active_run()` (具体例として cite)、PR #222 (`b0b91978`) (由来 cite)、順位 223 (T1 mechanical、bundle 推奨)、`feedback_global_config_backup` 適用は本リポジトリ docs/ のため不要 (グローバル CLAUDE.md / rules は触らない)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR-043 の既存 § 「concrete examples」 or 末尾に新 sub-section を追加 (~30 行)、mtime 取得失敗 / clock skew / malformed JSON / read error の 4 error path を列挙し、各 path で `false` 返却 → gate effective 維持を inline 説明。 - -#### 設計決定 (案) - -- **追記位置**: ADR-043 に既存「concrete examples」section があればそこへ追加。無ければ末尾 (References 直前) に新 sub-section 「Concrete instantiation: hooks-stop-quality の subsession freshness check (PR #222)」を追加 -- **記述項目**: - - 4 error path 各々で何が起き `false` 返却に倒れるか - - **mtime 取得失敗** (`std::fs::metadata()` error / `metadata.modified()` error): `Err(_) => return false` - - **system clock skew (future timestamp)**: `mtime.elapsed()` が `Err` を返した場合 `Err(_) => false` で skip 不可、orphan 扱いになる - - **malformed JSON**: `serde_json::from_str::` が `Err` → `Ok(_)` 以外は `false` - - **file read error**: 同上、`fs::read_to_string` が `Err` → `false` - - 全ての error path が「subsession active ではない」= 「Stop hook の quality gate を skip しない」に倒れる構造 = fail-closed - - 反対 pattern (fail-open = error path で `true` 返却) の anti-example: orphan 1 件が残るだけで全 session の quality gate が永続 skip → ADR-004 §「freshness check の必要性」で詳細解説 -- **由来 cite**: PR #222 で CR Major 指摘 (orphan 永続 skip リスク) に対応した freshness check 実装、ADR-004 amendment と本 ADR-043 追記の 2 ADR を同時更新した経緯を inline 引用 -- **派生プロジェクト transferability**: ADR は global 参照可能、本 ADR を `~/.claude/rules/common/` から link することで techbook-ledger / auto-review-fix-vc 等に reference 提供 -- **順位 223 との bundle**: 1 PR でまとめて land 推奨 (T1 mechanical layer + T3 docs layer の 2 層防御を 1 PR で確立) - -#### 作業計画 - -- [ ] ADR-043 現状を read、追記位置 (既存 concrete examples or 新 sub-section) を判断 -- [ ] 「Concrete instantiation: hooks-stop-quality の subsession freshness check (PR #222)」sub-section を追加 (~30 行) -- [ ] 4 error path の inline 説明 + anti-example (fail-open) の論理対比 -- [ ] PR #222 + ADR-004 § freshness check との cross-reference 追加 -- [ ] markdownlint clean -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR-043 に hooks-stop-quality の error handling が concrete example として追記される -- 4 error path 各々の `false` 返却 logic と「gate effective」状態への倒し方が明示される -- PR #222 / ADR-004 / ADR-043 の 3 文書間の cross-reference が成立、reader が 1 example から原則 → 適用 → 反対例を辿れる -- 順位 223 と合わせ、mechanical (T2) + docs (T3) の 2 層防御確立 - -#### 詰まっている箇所 - -- ADR-043 が現時点で試験運用 (= ephemeral 性質を残す) のため、concrete example 追記が本採用昇格のトリガーになりうるかは現状 ADR 内容を read してから判断 -- ADR-043 と ADR-004 の責務境界: 「fail-closed 原則の汎用論」(043) vs 「freshness check の必要性」(004) を ambiguous にせず、043 が「why fail-closed」、004 が「how freshness check works」と明確に分業する記述 - ---- - -## 既知課題 (記録のみ、本セッションで未対応) - -(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。) diff --git a/docs/todo11.md b/docs/todo11.md index d165f8eb..88027ba6 100644 --- a/docs/todo11.md +++ b/docs/todo11.md @@ -2,7 +2,7 @@ > **運用ルール** ([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-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: 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 の既存エントリは引き続き有効、相互に独立。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo13.md b/docs/todo13.md index fef67d21..0a2bd61a 100644 --- a/docs/todo13.md +++ b/docs/todo13.md @@ -2,7 +2,7 @@ > **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイルの位置付け**: docs/todo10.md がファイルサイズ約 95KB (50KB 安定読み取り閾値の約 2 倍) に到達したため、新規エントリを本ファイルに記録していた (PR #224 セッション、2026-06-29 ユーザー判断)。**本ファイルも約 171KB に到達したため、新規エントリの追加先は [docs/todo14.md](todo14.md) に移動 (2026-07-19 週次レビュー WR-2026-07-19-T02 採用)。本ファイルは既存タスクの編集・完了削除専用**。todo.md / todo2.md 〜 todo12.md の既存エントリは引き続き有効、相互に独立。 +> **本ファイルの位置付け**: docs/todo10.md がファイルサイズ約 95KB (50KB 安定読み取り閾値の約 2 倍) に到達したため、新規エントリを本ファイルに記録していた (PR #224 セッション、2026-06-29 ユーザー判断)。**本ファイルも約 171KB に到達したため、新規エントリの追加先は [docs/todo14.md](todo14.md) に移動 (2026-07-19 週次レビュー WR-2026-07-19-T02 採用)。本ファイルは既存タスクの編集・完了削除専用**。todo.md / todo2.md 〜 todo12.md の既存エントリは引き続き有効、相互に独立。**2026-07-20 に順位 248-332 を todo15.md/todo16.md/todo17.md へ物理分割し、本ファイルは順位 225-247 のみ収容 (docs 50KB 超過解消、45KB 台に縮小)。** > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 @@ -32,7 +32,7 @@ - [x] B1: auto-push (`repush.rs`) に push 前 quality_gate (`--ignored` 含む) を挿入 (PR-1、`stages/gate.rs` 新設。push-runner-config.toml の quality_gate group を単一ソース参照、docs-only fix diff は ADR-035 path 基準で gate skip、FAIL は `action_required` 即 escalation) - [ ] dogfood: [docs/auto-push-gate-dogfood.md](auto-push-gate-dogfood.md) の観測ログ + GO/NO-GO 判断基準に従い B1-loop 要否を判定 (期限: PR-1 merge + 6 週間 / gate FAIL 2 件 / auto-push 発火 10 回 のいずれか先) - [ ] (GO 判定時のみ) B1-loop: gate FAIL を convergence ループに差し戻す経路 + N 回上限 → `action_required` (fail-closed) — 設計案・不採用案は dogfood doc §5 に保存済み -- [ ] 本 entry 削除 + todo-summary.md 行削除 + dogfood doc 削除 (同一 commit、NO-GO の場合は ADR-043 amendment に知見移管後) +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + dogfood doc 削除 (同一 commit、NO-GO の場合は ADR-043 amendment に知見移管後) #### 完了基準 @@ -67,7 +67,7 @@ - [ ] (C) `rust-toolchain.toml` で channel + rustfmt component 固定 - [ ] (B) fmt `--check` step を Stop gate / push-runner gate に追加 - [ ] dogfood: 意図的に非整形コードを書き gate が block することを確認 -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -102,7 +102,7 @@ - [ ] main.rs に positive/negative test 追加 (justification マーカー有無で discriminate) - [ ] false positive 計測 (既存コードの `#[allow]` を grep、正当なものに justification マーカー付与 or scope 調整) - [ ] `cargo test -p hooks-post-tool-linter` pass -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -129,7 +129,7 @@ - [ ] `unresolved_threads` / `actionable_comments` の None / Some(0) / Some(1)、`new_comments` (型は `usize`) の 0 / 1 を直交させ、各境界で `cr_clean` の true/false を assert する test 追加 - [ ] 既存 `evaluate_rate_limit_shortcut_blocks_when_new_comments_exist` (Fix 3 で追加) との重複排除、各 field 独立の discriminating test - [ ] `cargo test -p cli-pr-monitor` pass -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -152,7 +152,7 @@ - [ ] ADR-022 に (1) Pre-Create Cleanup Flow の具体例 (`jj new` 空 child → takt amend → 変更なければ `try_abandon_empty_fix_commit` で abandon、integration test 参照) を追記 - [ ] ADR-022 に (2) 大規模リファクタリング agent 委譲時の format スコープ指針 (分割対象ファイルのみに fmt 限定、無差別 `cargo fmt` 回避) を追記 - [ ] markdownlint clean -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -182,7 +182,7 @@ - [ ] (2) post_steps / Stop hook に root 直下新規 untracked 検知 + warning を実装 - [ ] dogfood: 次回 merge で feedback workflow が repo root に stray を残さないことを確認 - [ ] (3) 必要なら gitignore に補助パターン追加 -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -215,7 +215,7 @@ - [ ] post-pr-review が docs-only 判定に使う diff の生成箇所を特定 (`review-diff.txt` 流用 or 独自生成) - [ ] diff scope を PR 全体に修正、or 分類基準を findings file path に変更 - [ ] dogfood: code + docs 混在 PR で docs-only 誤判定しないことを確認 -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -245,7 +245,7 @@ #### 作業計画 - [ ] memory `feedback-di-over-ambient-global-tests.md` に (a) 具体例 + (b) 例外境界を追記 -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -278,7 +278,7 @@ - [ ] ADR-022 に Serialization Primitive Single-Instance Rule の Appendix 追加 - [ ] 順位 234 (memory) と cross-reference -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -313,7 +313,7 @@ - [ ] main.rs に positive/negative test 追加 - [ ] 既存 `.rs` の PID+ms temp 命名を grep して false positive 計測 - [ ] `cargo test -p hooks-post-tool-linter` pass -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -340,7 +340,7 @@ - [ ] `convert_body_to_file` を per-test tempdir 注入 + 高並列 concurrent で実行し temp file collision が起きないことを assert する regression test 追加 - [ ] 意図的に PID+ms 命名へ戻すと test が落ちることを確認 (検出網の有効性検証) - [ ] `cargo test -p cli-pr-monitor` pass -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -371,7 +371,7 @@ - [ ] main.rs に positive/negative test 追加 - [ ] 既存 `.rs` の直叩き箇所を grep して false positive 計測 - [ ] `cargo test -p hooks-post-tool-linter` pass -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -394,7 +394,7 @@ - [ ] `filter_transcripts` の `fs::read_dir` 結果を timestamp (または名前) で sort してから処理するよう変更 - [ ] 複数 jsonl の順序が入力順に依らず決定論になることを assert する regression test 追加 - [ ] `cargo test -p cli-merge-pipeline` pass -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -416,7 +416,7 @@ - [ ] `takt.rs` の `spawn()` / `try_wait()` の `Err(e)` を `eprintln!` で記録するよう変更 (握り潰しを解消) - [ ] `cargo test -p cli-merge-pipeline` pass + `cargo clippy` clean -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -439,7 +439,7 @@ - [ ] binary crate (cli-merge-pipeline) 内で external consumer 不在の `pub` シンボルを `pub(crate)` に変更 - [ ] `cargo build` / `cargo clippy --workspace -- -D warnings` clean を確認 (未使用 pub 警告含む) - [ ] CLAUDE.md に「binary crate では cross-module 共有シンボルは pub(crate)、pub は使わない」方針を明文化 -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -462,7 +462,7 @@ - [ ] `pub(crate)` (cross-module 共有) / module-private / `pub` (library API のみ) の判断チェックリストを具体例付きで作成 - [ ] 恒久配置先を決定 (coding-style.md / CLAUDE.md、file-length-enforcement-plan.md は暫定) - [ ] 順位 241 との重複を統合 (bundle 検討) -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -484,7 +484,7 @@ - [ ] coding-style.md に「test helper は各 module 複製、shared util module は anti-pattern」を根拠 (coupling < isolation) 付きで追記 - [ ] split レビュー時の確認項目 (helper が複製されているか) を明示 -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -505,7 +505,7 @@ #### 作業計画 - [ ] push-runner-config.toml `[pr_size_check]` コメントに override 適用基準 (mechanical refactor 定義 + PR description 明記事項) を追記 -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -533,7 +533,7 @@ - [ ] poll の CI 完了判定に「review-complete + mergeability CLEAN」短絡条件を追加 - [ ] CodeRabbit-only 構成の判定 (実 CI check の有無) を実装 - [ ] `cargo test -p cli-pr-monitor` pass + regression test (短絡が誤発火しないこと) -- [ ] 本 entry 削除 + todo-summary.md 行削除 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 #### 完了基準 @@ -558,1430 +558,3 @@ #### 完了基準 - 観点⑧ facet が既知 bug class を再現検出でき、false positive ≤ 5% で定着判定。または retire 判定で facet を除去し軸の空白を記録。 - ---- - -### Gate Function Design Checklist を新規 guide として追加 (fail-closed パターン集) (PR #234 post-merge-feedback T3-1 採用) - -> **動機**: fail-closed 実装の失敗パターンと推奨パターンが複数の ADR / memory に分散しており、新規 gate 実装者が再発させるリスクが高い。PR #234 で `collect_oversize_files` の初版が `.ok()?` で読み取り失敗を握り潰す fail-open bug を含み CodeRabbit Major #234-1 で指摘された。gate 実装の失敗/推奨パターンを 1 箇所に集約する。 -> -> **本タスクの位置づけ**: PR #234 post-merge-feedback Tier 3 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。同 feedback の T1-1 (`filter_map + .ok()?` の linter 化) / T1-2 (TOCTOU linter 化) は false positive 多発リスクで却下推奨となったため、その補完としてドキュメント化が必須。 -> -> **参照**: `.claude/feedback-reports/234.md` Tier 3 #1、`docs/adr/adr-043-security-gates-fail-closed.md` (fail-closed 原則)、順位 249 (ADR-043 コード例追記、相補)、custom lint ⑫ `no-hardcoded-jj-revset-range`。 -> -> **実行優先度**: 💎 **Tier 3** — Effort S。 - -#### 作業計画 - -- [ ] Gate Function Design Checklist を `CLAUDE.md` patterns section または `docs/guides/gate-functions.md` に新設: (1) 判定不能状態は fail-closed、(2) gate 関数内で `filter_map + .ok()?` 禁止、(3) single-pass file access で TOCTOU 回避、(4) iterator chain + `Result::?` idiom で nesting depth 抑制、(5) エラーパスを明示的にテスト -- [ ] ADR-043 (順位 249) との相互リンク -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- fail-closed gate の失敗/推奨パターンが 1 箇所に集約され、新規 gate 実装者が参照して再発を防げる。 - ---- - -### ADR-043 に fail-open vs fail-closed の具体コード例を追記 (PR #234 post-merge-feedback T3-2 採用) - -> **動機**: ADR-043 は security-critical だが具体的なコード例が未記載で、解釈の分散が PR #234 の `.ok()?` fail-open bug を生んだ。`.ok()?` anti-pattern / single-read + `ErrorKind` inspection idiom / multi-step vs 単一操作の比較を ADR 本文に追記し、レビュー時の一貫した判断基準を提供する。 -> -> **本タスクの位置づけ**: PR #234 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。順位 248 (運用チェックリスト) と相補的な決定記録。 -> -> **参照**: `.claude/feedback-reports/234.md` Tier 3 #2、`docs/adr/adr-043-security-gates-fail-closed.md` (追記先)、順位 248 (Gate Function Design Checklist)。 -> -> **実行優先度**: 💎 **Tier 3** — Effort S。 - -#### 作業計画 - -- [ ] ADR-043 に具体コード例 section を追加 (`.ok()?` anti-pattern / single-read + `ErrorKind` idiom / TOCTOU 回避の単一操作) -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- レビュー時に fail-open / fail-closed の判断基準が具体コードで参照でき、解釈の分散が解消される。 - ---- - -### ADR-021 に「jj revset の base branch は config/arg 化 (hardcode 禁止)」を明文化 (PR #234 post-merge-feedback T3-3 採用) - -> **動機**: PR #234 で `[file_length_gate] base` を config 引数化する ADR-021 準拠パターンを実装した (default `master`、`format!("{}..@", base)`)。custom lint ⑫ `no-hardcoded-jj-revset-range` は `.rs` の `master..@` literal を捕捉するが、TOML config / docs / 他ツールへの原則適用は明文化されていない。base branch hardcode 禁止の原則を明文化する。 -> -> **本タスクの位置づけ**: PR #234 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。jj change detection は複数ツールで多用されるため原則の明文化価値がある。 -> -> **参照**: `.claude/feedback-reports/234.md` Tier 3 #3、`docs/adr/adr-021-jj-change-detection-principles.md` (追記先)、custom lint ⑫ `no-hardcoded-jj-revset-range`。 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。 - -#### 作業計画 - -- [ ] ADR-021 (または `CLAUDE.md`) に「jj revset の base branch は config / arg 化し hardcode 禁止」の原則を明文化 (`.rs` / TOML config / docs / 他ツール横断) -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- base branch hardcode 禁止の原則が明文化され、新規 jj 変更検出実装で参照できる。 - ---- - -### ADR-NNN (採番未確定、land 時に確定): 部分効果 env var anti-pattern の文書化 (PR #239 post-merge-feedback T3-1 採用) - -> **動機**: サブコマンドによって効果が異なる env var は「一部のコマンドが成功する」ことで全体が動いていると誤認させ、silent 部分故障を招く。実例 = `GH_REPO` は `gh pr create/merge` には効くが引数なし `gh repo view` には効かず、PR #238 で「マージ成功 / post-merge feedback silent 消失」の部分故障が発生した。`gh-repo-env-guard` preset (PR #239) が GH_REPO 個別には機械防御するが、「なぜ partial coverage が危険か」の原則が未文書化で、同型のショートカット提案 (例: `GH_HOST` 系 env var) を reviewer / implementer が即認識できない。 -> -> **参照**: PR #238 (実害) / PR #239 (preset 実装 + feedback 提案 #1)、ADR-045 § PR 運用時の追加設定、`.claude/hooks-config.toml` gh-repo-env-guard preset。 -> -> **実行優先度**: 💎 Tier 3 — Effort S。Severity Medium + Frequency Medium + Adoption Risk None (PR #239 post-merge-feedback T3-1、ユーザー採用 2026-07-03)。 - -#### 作業計画 - -- [ ] 新 ADR (順位 135 placeholder policy 適用) に「部分効果 env var」anti-pattern を codify: 定義 / PR #238 実例 / 判定基準 (env var による回避策採用時は対象コマンド全系統でのカバレッジ確認を必須化) / 推奨代替 (全系統に効く機構 = GIT_DIR 自動注入型、または明示フラグ) -- [ ] CLAUDE.md の ADR 一覧にリンク追加 (ADR-022 の「CLAUDE.md はリンクに留める」方針に従い本文は ADR 側へ) -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 将来の env var ベースの回避策提案に対し、reviewer / implementer がカバレッジ確認を求める根拠文書が ADR として存在し、CLAUDE.md から辿れること。 - -#### 詰まっている箇所 - -- なし。 - ---- - -### ADR-030 に PR #239 の feedback silent skip 実装記録を追記 (PR #239 post-merge-feedback T3-2 採用) - -> **動機**: 非 colocated jj workspace での owner_repo 検出失敗 → `.failed` marker 未書込 → L2 recovery 未発動という silent skip シナリオ (PR #238 実観測、feedback が recovery 不能なまま消失) と、その対処 (`AiStepContext` enum 化 + `SkipWithMarker` variant + `skip_with_failed_marker()`) を ADR-030 に実装記録として残し、次回同類問題の参照点にする。 -> -> **参照**: PR #238 (実害) / PR #239 (`src/cli-merge-pipeline/src/pipeline.rs` の `AiStepContext::SkipWithMarker`)、ADR-030 (失敗マーカーによる recovery)。 -> -> **実行優先度**: 💎 Tier 3 — Effort XS。Severity Low (既修正) + Frequency Low (PR #239 post-merge-feedback T3-2、ユーザー採用 2026-07-03)。次回 ADR-030 を参照・編集する PR への同乗で消化可。 - -#### 作業計画 - -- [ ] ADR-030 に「owner_repo 検出失敗などの実行前 skip も marker 付き skip とし L2 recovery 対象にする (`AiStepContext::SkipWithMarker`)」の実装記録 sub-section を数行追記 (PR #238 シナリオを inline cite) -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR-030 を読んだ実装者が「feedback の skip 経路はすべて marker を残す」規約を実装記録から把握できること。 - -#### 詰まっている箇所 - -- なし。 - ---- - -### pr_size_check の base を remote tracking ref に変更 — 並列 workspace のローカル master 遅延による誤計測解消 (順位242 push で実観測) - -> **動機**: `push-runner-config.toml` `[pr_size_check]` の `default_branch = "master"` が revset `master..@` のローカル bookmark 基準のため、ADR-045 並列 workspace 運用でローカル `master` (workspace 間共有) が誰にも advance されず遅延していると、過去の merge 済み PR 分を合算して誤計測する。順位 242 の push で実害: 実 diff +123/-35 (~160 行) が「1604 行 > block_threshold 1500」と誤 block され、直前の PR #239/#240 push でも warning 閾値 (800) を静かに誤超過していた。ADR-013 では `sync_local` が「remote tracking ref (`master@origin`) を使い bare local bookmark を使わない」を test で固定済みで、同じ原則を pr_size_check にも適用すべき。 -> -> **参照**: `push-runner-config.toml` `[pr_size_check]`、`src/cli-push-runner` の pr_size_check stage、ADR-013 (sync_local の master@origin 原則 + 固定 test)、ADR-021 / 順位 250 (base branch config/arg 化の明文化、相補)、ADR-045 調整ポイント 2 (ローカル master 共有と遅延の前提)。 -> -> **実行優先度**: 🔧 Tier 2 — Effort XS-S。並列 workspace 運用が続く限り再発する (今回は手動 `jj bookmark set master -r master@origin` で復旧)。 - -#### 作業計画 - -- [ ] `[pr_size_check] default_branch` を `master@origin` に変更 (config 1 行) または pr_size_check 側で remote tracking ref を優先解決する fallback を実装 (着手時に判断、`[file_length_gate] base` も同点検) -- [ ] ローカル master 遅延状態を模した test (revset 解決の単体レベル) を検討 -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ローカル `master` が遅延していても pr_size_check が「master@origin 以降の実 diff」だけを計測すること。 - -#### 詰まっている箇所 - -- なし (根因・復旧手順・実測値あり)。 - ---- - -### ADR-040 の実測値を新 GPU (RTX PRO 5000 48GB) で再 calibration (ADR-046 WP-01 スパイクで陳腐化を観測) - -> **動機**: ADR-038 / ADR-040 は Local LLM の実行環境を **RTX 3070 8GB** として実測値を固定しているが、実機は **NVIDIA RTX PRO 5000 Blackwell 48GB** に更新済み (2026-07-04 に `nvidia-smi` で確認)。この結果、(1) ADR-040 の VRAM/latency trade-off 表 (例: mistral:7b ~2GB at 32K ctx) と (2)「VRAM scarcity → 同時起動不可 / model swap 制約 / KV cache budgeting」という framing が陳腐化した。27-31B Q4 モデルが 100% GPU で動き (qwen3-coder:30b ~21.8GB / gemma4:31b ~20.9GB / gemma4:26b ~17.6GB at num_ctx 32768)、VRAM ではなく latency が実効制約になった。 -> -> **参照**: ADR-040 (Local LLM Context Size、実測値元)、ADR-046 (WP-01 スパイク、4 モデルの VRAM・latency 実測を保持)、ADR-038 (現行 classifier、RTX 3070 前提の記述)、memory `gpu-upgrade-rtx-pro-5000`。 -> -> **実行優先度**: 💎 Tier 3 — Effort S。実装変更を伴わず ADR amendment 中心。分類層 (ADR-038) の運用に直接の不具合はないが、num_ctx 再選定や派生プロジェクト porting 時に誤った RTX 3070 前提を引き継ぐリスクを解消する。 - -#### 作業計画 - -- [ ] ADR-040 に amendment: RTX 3070 8GB の実測表は「旧環境 (historical)」と明示し、新 GPU での再測定値 (ADR-046 の VRAM 実測 + 代表 diff の latency) を追記 -- [ ] 「Context 選定の判断 flow」の memory 軸 (同時起動可否 / swap) を latency 軸へ再重み付け -- [ ] ADR-038 の RTX 3070 前提記述 (§コンテキスト / §帰結の VRAM 8GB 制約) に更新環境への参照を付す -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR-040 を読んだ実装者が、現行 GPU では VRAM が制約でなく latency が実効制約であることを把握でき、RTX 3070 8GB の数値を現行前提と誤認しないこと。 - -#### 詰まっている箇所 - -- なし (GPU 更新の事実・ADR-046 の実測値あり)。 - ---- - -### classifier FP 検出強化プロンプトで格上げ候補を再評価 (WP-04 見送りの follow-up、ADR-038 amendment 由来) - -> **動機**: WP-04 (classifier モデル格上げ) の実測で、mistral:7b からの格上げ候補 (gemma4:12b/26b/31b, qwen3-coder:30b) は **いずれも `false_positive_likely` 検出を改善しなかった** (gold FP 6 件中、正検出は最良 qwen3-coder でも 1 件、全モデルが 3〜4 件を有害な auto_fix に誤分類)。ただし eval で使った `classify.txt` は mistral:7b 向けに tune 済みのため、「FP 検出が能力限界なのか、プロンプト不適合なのか」が未分離。FP 検出を明示的に強化したプロンプト版で候補を再測し、切り分ける。 -> -> **参照**: ADR-038 § classify モデル格上げの評価と見送り (2026-07-05 追記、WP-04)、`src/cli-finding-classifier/prompts/classify.txt`、`src/cli-finding-classifier/src/main.rs` (`--prompt-file` で差し替え可)、WP-04 scratchpad の eval セット (Opus gold 35 件) + ハーネス。ADR-019 § 既知 CodeRabbit FP パターン (キュレート FP 例の出典)。 -> -> **実行優先度**: ⏳ Tier 5 — Effort M。現行 mistral:7b は安全軸完璧・最軽量で運用に支障なく、優先度は低い。materially better な新 local モデル出現時も再評価トリガー。 - -#### 作業計画 - -- [ ] FP 検出強化版 `classify.txt` を作成 (false_positive_likely の positive signal をより明示、Windows 専用/test mock/合成 fixture 等の既知 FP パターンを few-shot 化) -- [ ] WP-04 の Opus gold eval セット (35 件) で qwen3-coder:30b 等を再測、FP recall と human_review 安全軸を確認 -- [ ] 能力限界と確認できれば恒久見送りとして本 entry 削除。プロンプト不適合なら該当モデル + 専用プロンプトで格上げ (ADR-038 の model default 変更 + amendment) -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- FP 検出が「モデル能力限界」か「プロンプト不適合」かが実測で切り分けられ、格上げ採否が結論付けられていること。 - -#### 詰まっている箇所 - -- なし (WP-04 の eval 資産・gold セットあり、プロンプト改訂のみ)。 - ---- - -### push pipeline の `cargo test` を cargo-nextest 化 (WP-05 で Stop hook には無効と判明、push 側 follow-up) - -> **動機**: WP-05 (Stop hook 高速化) の実測で、当初計画の nextest 案は **Stop hook には無効**と判明した (Stop hook は cargo test を実行せず、真因は 7 ステップの逐次実行 → 並列化で解決済、ADR-004 amendment)。一方、**push pipeline (cli-push-runner の quality_gate) は `cargo test -- --ignored --test-threads=1` を実行**しており、実測で ~80s を要する (WP-03 push で観測)。ここは nextest による並列テスト実行で高速化の余地がある。push は Stop hook より低頻度だが、fix→push サイクルの待ち時間に直結する。 -> -> **参照**: `push-runner-config.toml` の `[[quality_gate.groups]]` name=`rust-lint-test`、`src/cli-push-runner` の quality_gate stage、ADR-004 § ステップ並列実行による高速化 (2026-07-05 追記) の scope 外 note、ADR-017 (takt バージョン固定哲学 = nextest 固定の根拠)。 -> -> **実行優先度**: ⏳ Tier 5 — Effort S-M。現行 push は機能上支障なく、優先度は低い。ツール依存追加の費用対効果を要評価。 - -#### 作業計画 - -- [ ] cargo-nextest の導入判断: ツール依存追加 (ADR-017 pinning + `pnpm deploy:hooks` 派生プロジェクト配布) のコスト vs push 高速化の便益を評価 -- [ ] 採用時: `push-runner-config.toml` の `cargo test` step を `cargo nextest run` に置換。**nextest は doctest を実行しないため `cargo test --doc` を併走**させる (doctest 有無を確認: `///` の ` ``` ` を持つ crate) -- [ ] `--ignored` 統合テスト (repush 等) が nextest で正しく実行されることを確認 (nextest の `--run-ignored` フラグ) -- [ ] before/after 実測で push pipeline 時間短縮を確認 -- [ ] 本 entry 削除 + todo-summary.md 行削除 - -#### 完了基準 - -- push pipeline の test 実行時間が短縮され、doctest / `--ignored` 統合テストの網羅性が維持されていること。または費用対効果が見合わないと判断し見送りが記録されていること。 - -#### 詰まっている箇所 - -- なし (WP-05 で Stop 側は完了、push 側の nextest 適用余地とコスト構造は明確)。 - ---- - -### pre-push review-diff.txt の生成形式を jj diff --git に切替 — LLM レビュアーの add/delete 誤読解消 (PR #256 post-merge-feedback Tier1 #1 採用) - -> **動機**: `push-runner-config.toml:113` の `[diff] command = "jj diff -r @"`(jj デフォルト形式)で生成される `.takt/review-diff.txt` は、追加/削除を色 + 行番号2列(`NNN :` = 削除 / ` NNN:` = 追加)で表現する。ファイル化で色が落ちると `-`/`+` マーカーが無くなり、削除が「左列のみ行番号」でしか区別できず、pre-push の LLM レビュアー(simplicity-review 等)が削除ブロックを「追加」と誤読しうる。`--git`(標準 unified diff)は色非依存で `+`/`-` を明示するため誤読しない。PR #256(ADR-051 起票 PR)で todo エントリ25行の**削除**を simplicity-review が「追加」と誤読し stale-tracking-entry として false positive REJECT を出し、レビュー約19分を浪費した実害が発生した。 -> -> **本タスクの位置づけ**: PR #256 post-merge-feedback Tier1 #1 で採用(他6提案は over-engineering として却下)。fix ステップの「hunk-polarity bug」という診断は不正確で、真因は色を落とした平文 diff の LLM 可読性問題。 -> -> **参照**: `push-runner-config.toml:113`(`command = "jj diff -r @"` → `"jj diff --git -r @"`、修正対象)、`templates/push-runner-config.toml:52`(同様の変更、`pnpm deploy:hooks` で派生プロジェクトに配布されるため**両方修正必須**)、memory `prepush-review-diff-plain-format-misread.md`、PR #256 feedback report (`.claude/feedback-reports/256.md`) Tier1 #1 -> -> **実行優先度**: 🔧 Tier 2 — Effort S。false positive で約19分浪費した実害が既に発生しており、config + template 各1箇所の軽微な修正で再発を防止できる。 - -#### 設計決定 (案) - -- `[diff] command` を `jj diff --git -r @` に変更。本番 config と template の2箇所を同一 PR で修正(template 未修正だと派生プロジェクトに同じ false positive が横展開)。 -- review-diff.txt を format-sensitive に parse する `.rs` 箇所は存在せず(LLM facet が読むのみ)、Adoption Risk None。 - -#### 作業計画 - -- [ ] `push-runner-config.toml:113` を `command = "jj diff --git -r @"` に変更 -- [ ] `templates/push-runner-config.toml:52` も同様に変更 -- [ ] review-diff.txt を参照する箇所(facet instruction / `.rs`)が `--git` 形式で問題ないか確認 -- [ ] dogfood: 削除を含む diff で pre-push review が正しく削除を認識することを確認 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- pre-push review が削除ブロックを「追加」と誤読しなくなり、config + template 両方が `--git` 形式、派生プロジェクトへの横展開も解消。 - -#### 詰まっている箇所 - -- なし(変更箇所・影響範囲とも確定済み、PR #256 feedback report で cross-validation 済み)。 - ---- - -### cli-docs-lint に ADR 重複採番 + CLAUDE.md 索引整合チェック追加 (PR #261 post-merge-feedback T1-#2 採用) - -> **動機**: PR #261 で当方が ADR-052 として起草した ADR が、並行 land した PR #260 の ADR-052 (自律実行境界) と採番衝突し、rebase 時にファイル名 + 本文タイトル + ソース内参照 10+ 箇所の置換が発生した実例。ADR は既に 53 件、並行 PR 開発が常態化しており再発頻度 Medium。現状この衝突を機械検知する層が存在しない (発見は rebase 時の CLAUDE.md conflict 頼み)。 -> -> **チェック内容 (案)**: (a) `docs/adr/adr-NNN-*.md` の同一 NNN 重複検出、(b) CLAUDE.md 索引 ⇔ 実ファイルの対応検証 (索引にあるファイルの存在 / 実ファイルの索引掲載)、(c) ファイル名の NNN ⇔ 本文 H1 タイトル番号の一致。 -> -> **参照**: `.claude/feedback-reports/261.md` Tier 1 #2、`src/cli-docs-lint/src/main.rs` (CheckMode 拡張、preamble / cross-ref / priority-inversion の既存 check-mode dispatch と kill-switch 骨格を流用)、ADR-007 (層の線引き)、ADR-039。 -> -> **関連 (重複ではない)**: 順位 135 (todo8.md、ADR-NNN placeholder policy) は todo entry 側の採番 hardcode を防ぐ「ルール」であり、本 entry は land 済みファイル群の衝突を検知する「仕組み」(ADR-042 の役割分担で相補)。feedback report Tier 2 #2 (ADR sanity テスト新設) は本 entry と目的重複のため却下済み。 -> -> **実行優先度**: 🚀 **Tier 1** — Effort S。既存 cli-docs-lint 骨格の流用で新規 module 1 つ + fixture テスト。 - -#### 作業計画 - -- [ ] `src/cli-docs-lint/src/` に adr_consistency validator module を新設 (check 内容 a/b/c) -- [ ] 既存 CheckMode dispatch / kill-switch 設定に統合 (ADR-039 パターン) -- [ ] fixture テスト: 重複採番 / 索引欠落 / 番号不一致の bad fixture + clean fixture -- [ ] push-runner quality_gate (`pnpm lint:docs`) 経由で発火することを確認 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR 採番衝突・索引不整合・ファイル名/タイトル番号不一致が push 前に決定論的に検出され、PR #261 型の rebase 時大量置換が再発しない構造になっていること。 - ---- - -### 層別テストテンプレート (StubOllama パターン・integration 独立性) の共有化 (PR #265 post-merge-feedback T2-1 採用) - -> **動機**: WP-11 (PR #265、ADR-054) の多層防御実装で、層別テスト戦略の設計に時間を要した。具体的には (a) 空 responses の `StubOllama` で「LLM が呼ばれていないこと」を証明する短絡検証パターン、(b) tempdir + `jj git init` + CwdRestore で実 jj repo を立てる integration テストの独立性パターン、の 2 つを都度設計した。WP-17 (自律化) で classifier / scope guard 層を拡張する際に同種の設計判断が再発する見込み。 -> -> **参照**: `.claude/feedback-reports/265.md` Tier 2 #1、`src/cli-finding-classifier/src/lib.rs` (StubOllama)、`src/cli-pr-monitor/src/stages/scope_guard.rs` (integration パターン)、ADR-041 (test isolation patterns)、ADR-025 (CwdRestore)、ADR-044 (共通化と分離の線引き — shared crate 化の境界判定に適用) -> -> **実行優先度**: 🔧 Tier 2 — Effort M。WP-17 着手前の実施が効果的。 - -#### 作業計画 - -- [ ] 対象パターンの棚卸し (StubOllama / tempdir+jj init+CwdRestore / 層別テストの構成方針) -- [ ] ADR-044 の境界判定で shared test crate 化 or fixture + doc 化を判断 -- [ ] 切り出し + 既存呼び出し側 (cli-finding-classifier / cli-pr-monitor) の移行 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 新しい LLM 系 / jj 統合系のテストが共有テンプレートを参照して層別テストを組める状態になっていること。 - ---- - -### ADR-007 に「コメント配置の意思決定フロー」を追加 (PR #265 post-merge-feedback T3-2 採用) - -> **動機**: PR #265 実装中に `classify_one` (cli-finding-classifier) と `config.rs` (cli-pr-monitor) の 2 箇所で非 doc コメントを書き、Bundle Z comment-lint (#B-α) に block された (同種ミス 2 回 = パターン化の価値あり)。「この説明は doc コメント (`///`) に書くべきか、識別子名 / 関数分割で表現して削除すべきか」の判断フローが未文書化。linter 自動化 (feedback Tier 1 #2) は意味論的判定 = NLP が必要なため却下済みで、本エントリは人間 / AI の判断補助ドキュメントとしての補完。 -> -> **参照**: `.claude/feedback-reports/265.md` Tier 3 #2、`docs/adr/adr-007-custom-linter-layer-boundary.md` (既存 Q1-Q3 判断フロー形式で拡張)、`src/hooks-post-tool-comment-lint-rust` (Bundle Z #B-α) -> -> **実行優先度**: 💎 Tier 3 — Effort S。doc のみ、バッチ PR で消化可。 - -#### 作業計画 - -- [ ] ADR-007 に Q 形式の「コメントを書きたくなったときの配置判断フロー」を追記 (doc コメント / 識別子名 / マーカー付き Why コメントの 3 分岐) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- コメント配置の判断が ADR-007 の判断フローで一意に決まり、Bundle Z block の手戻りが減ること。 - ---- - -### PR body 配置タイミング規約を dev-conventions に明記 (PR #265 post-merge-feedback T3-3 採用) - -> **動機**: PR #265 の push パイプライン実行中に working copy へ `__pr-body.md` を作成し、jj snapshot 直前の退避で commit 混入をかろうじて回避したヒヤリハットが実発生。混入すると repo 履歴に残る。「PR body は push 完了後に scratchpad で準備し、`pnpm create-pr -- --body-file` に絶対パスで渡す (push 実行中の working copy に置かない)」というタイミング規約が未文書化。 -> -> **参照**: `.claude/feedback-reports/265.md` Tier 3 #3、`docs/dev-conventions.md` (追記先)、ADR-028 (external-output 実行フロー)、`src/cli-pr-monitor/src/stages/create_pr.rs` (--body-file パススルー実装) -> -> **実行優先度**: 💎 Tier 3 — Effort XS。doc のみ、バッチ PR で消化可 (並列安全化 PR の docs への相乗りも可)。 - -#### 作業計画 - -- [ ] dev-conventions.md に PR body 配置タイミング規約を追記 (scratchpad + 絶対パス推奨 / repo 直下 `__` ファイルは push 完了後のみ) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- PR body ファイルが push パイプラインの snapshot に混入しない手順が規約として参照可能になっていること。 - ---- - - -### config-reading hook の `current_dir()` 解決を検出する lint rule (PR #267 post-merge-feedback T1-1 採用) - -> **動機**: PR #267 で新規 hook (jj-op-verify) が既存 3 hook と異なる `current_dir()` ベースの config 解決を実装し、pre-push simplicity-review が REJECT (`SIM-NEW-jjopverify-cwd-config-L179`、High) → fix step が `current_exe().parent()` へ修正した実例。Bash の cwd drift による silent fail-open (`enabled=false` 扱い) は新規 hook 追加のたびに再発しうる。 -> -> **参照**: `.claude/feedback-reports/267.md` Tier 1 #1、`.claude/custom-lint-rules.toml` (新規ルール)、順位 287 (convention 明文化、同一 PR bundle 推奨) -> -> **実行優先度**: 🚀 Tier 1 — Severity High / Effort S。 - -#### 作業計画 - -- [ ] custom-lint-rules.toml に「hooks-* の .rs で `current_dir()` + `hooks-config.toml` の組合せ」を検出するルール追加 (bad/good fixture + incident 構造) -- [ ] 順位 287 (convention 明文化) を同一 PR で bundle -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- config を cwd 基準で解決する新規 hook が push 前に決定論的に検出されること。 - ---- - -### jj-op-verify の変更系 verb 網羅拡大 (PR #267 post-merge-feedback T1-2 採用) - -> **動機**: 現行の検出対象 (new/describe/abandon/rebase/squash/bookmark 変更系) に `undo` / `restore` / `split` / `bookmark move` / `bookmark track` / `bookmark untrack` が含まれない。特に `jj undo` の検出漏れは lost-update 再発リスクが高く、Operation Verification Checklist 自動化の対象を狭める。 -> -> **参照**: `.claude/feedback-reports/267.md` Tier 1 #2、`src/hooks-post-tool-jj-op-verify/src/main.rs` (match 文)。**拡張時は `expected_op_keyword` を実際の `jj op log` 出力と要照合** -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort M。 - -#### 作業計画 - -- [ ] 各 verb の実際の op description を jj 0.42 実機で確認し keyword map に追加 + テスト -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 変更系 jj 操作の検出網羅率が上がり、`jj undo` 等の op 記録検証が機能すること。 - ---- - -### jj-op-verify の verb 検出を command-boundary に anchor (PR #267 post-merge-feedback T1-3 採用) - -> **動機**: `split_whitespace()` の非 anchored 検出は、commit message 引用符内の `"jj new"` 等で false positive「operation not recorded」を誘発しうる。実装時に accepted risk として一度見送った経緯あり (実害観測 0 件)。採用は「advisory 層の UX 劣化」防止目的で、着手時に実観測状況を再確認すること。 -> -> **参照**: `.claude/feedback-reports/267.md` Tier 1 #3、`src/hooks-post-tool-jj-op-verify/src/main.rs:detect_last_mutating_jj_op`、順位 285 (edge-case テスト、表裏の関係) -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort S。 - -#### 作業計画 - -- [ ] verb 検出をコマンド境界 (`&&` / `;` / `|` / 文頭) anchor に変更 + 引用符内の誤検出テスト -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- commit message 内の jj キーワードで警告が誤発火しないこと。 - ---- - -### stale_check_enabled の TOML パーステスト追加 (PR #267 post-merge-feedback T2-1 採用) - -> **動機**: PR #267 で追加した `StalenessConfig.stale_check_enabled` のパース経路にテストがなく、silent degrade (機能が黙って無効化) のリスク。既存テストへの数行追加で完備できる。 -> -> **参照**: `.claude/feedback-reports/267.md` Tier 2 #1、`src/hooks-session-start/src/hooks_config.rs` の既存パーステスト -> -> **実行優先度**: 🔧 Tier 2 — Effort XS。 - -#### 作業計画 - -- [ ] 既存 fixture に `stale_check_enabled = true` + assert を追加 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 新フィールドのパースが regression test で固定されていること。 - ---- - -### jj keyword を含む commit message の tokenization edge-case テスト (PR #267 post-merge-feedback T2-2 採用) - -> **動機**: 順位 283 (anchor 修正) と表裏。283 の着手有無に関わらず、現行挙動 (既知の限界) を regression test で明示的に固定する価値が独立して残る。 -> -> **参照**: `.claude/feedback-reports/267.md` Tier 2 #2、`src/hooks-post-tool-jj-op-verify/src/main.rs` の tests module -> -> **実行優先度**: 🔧 Tier 2 — Effort S。283 と同一 PR での消化が効率的。 - -#### 作業計画 - -- [ ] `token_detection_ignores_jj_in_message_quotes` 等の edge-case テスト追加 (283 実施後は新挙動を固定) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- tokenization の既知の限界/修正後挙動がテストで明文化されていること。 - ---- - -### config path 解決の cwd 跨ぎ integration test (PR #267 post-merge-feedback T2-3 採用) - -> **動機**: PR #267 で FIXED 済の `SIM-NEW-jjopverify-cwd-config-L179` は、既存テストが pure parser のみで file-lookup 経路を未カバーだったため混入した。非 repo-root cwd から hook を起動して config が読み込まれることを検証する統合テストは、cwd drift シナリオ (ADR-045 の核心リスク) の re-incident 検知網になる。 -> -> **参照**: `.claude/feedback-reports/267.md` Tier 2 #3、`hooks-post-tool-jj-op-verify` test suite。Adoption Risk: OS 依存 (temp dir / path 形式) -> -> **実行優先度**: 🔧 Tier 2 — Severity High / Effort M。 - -#### 作業計画 - -- [ ] 実 exe spawn + 非 repo-root cwd で config 読込を assert する `#[ignore]` integration test -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- exe-relative 解決の退行が統合テストで検出されること。 - ---- - -### 「config 読み hook は exe-relative 解決必須」convention の明文化 (PR #267 post-merge-feedback T3-1 採用) - -> **動機**: 順位 281 (lint rule) の文書層の補完。ADR-045 (または dev-conventions) と該当 hook の inline comment に規約として明文化する。 -> -> **参照**: `.claude/feedback-reports/267.md` Tier 3 #1。**順位 281 と同一 PR での bundle 実装を推奨** (別作業に切り出す価値は低い) -> -> **実行優先度**: 💎 Tier 3 — Effort XS。 - -#### 作業計画 - -- [ ] 順位 281 の PR に同乗して convention を明文化 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 新規 hook 作成時に参照できる規約が存在し、lint rule (281) と 2 層で防御されていること。 - ---- - -### post-merge feedback の pre-push reports を対象 PR の全 run 集約に拡張 (PR #268 post-merge-feedback T2-1 採用) - -> **動機**: `find_latest_prepush_reports_dir()` は「最新 1 run」のみを feedback の分析ソースにするため、複数回 push した PR では最後の push 分に分析が偏る。PR #267 の feedback でも「参照した pre-push run は WP-11 status 更新 (docs-only の最終 push) のみが対象」という evidence-scope 注記が付いた実観測あり。対象 PR の commit 範囲内の全 pre-push-review run を集約し、`post-merge-feedback-context.json` の `prepush_reports_dir` を配列化、`analyze-prepush-reports.md` facet も複数 dir 対応に更新する。 -> -> **再発・優先度見直し (2026-07-19、#300/#301 feedback)**: PR-N2 (#300) / PR-N3 (#301) の feedback で同型 gap が Severity High で再発。根因は本エントリの集約範囲より上流の **push-runner `[diff]` stage** (`push-runner-config.toml` の `[diff] command = "jj diff -r @"`) が **tip コミットのみ**を AI レビュー用 diff に書き出す点。複数コミットを 1 回の `pnpm push` でまとめて送ると、tip 以外の祖先コミット (例 #300 の `resolve_main_workspace_root()` 実装、#301 の `Cargo.toml`/`main.rs` 変更) が local security/simplicity レビューを一度も経ずに merge される (security-review.md が実 diff と矛盾して "docs-only / No dependency changes" と記載)。**単一 push では pre-push run 自体が 1 回のみ**のため、本エントリの「全 run 集約」だけでは救えない。よって本エントリの実装時に、(a) `[diff]` stage の diff 範囲を `docs_only_routing` と同様に `..@` (PR 範囲) へ拡張し、(b) `bookmark_check.rs` の `@` 非 trunk 祖先が未レビューのまま push される穴 (T8 / PR #280 と同クラス) の検証を併せて行う。`docs_only_routing.rs` の skip 判定は既に `..@` に修正済みだが `[diff]` stage 自体は未修正で非対称。ADR-027 (push-time review を diff-local に限定し範囲外は CodeRabbit backstop) の trade-off 射程が security-review にも及ぶかはユーザー判断待ち。 -> -> **参照**: `.claude/feedback-reports/268.md` Tier 2 #1 / `.claude/feedback-reports/300.md` Tier1 #1 / `.claude/feedback-reports/301.md` Tier1 #1、`src/cli-merge-pipeline/src/feedback/context.rs` (`find_latest_prepush_reports_dir`)、`push-runner-config.toml` (`[diff]` section)、`src/cli-push-runner/src/stages/diff.rs`・`src/cli-push-runner/src/stages/bookmark_check.rs`、`src/cli-push-runner/src/config/docs_only_routing.rs` (既に PR 範囲へ修正済の対照)、`.takt/facets/instructions/analyze-prepush-reports.md`、[ADR-027](adr/adr-027-push-review-simplicity-focus.md) -> -> **実行優先度**: 🚀 Tier 1 — Severity High (review gate の silent 覆域縮小が 3 PR 連続で再発) / Frequency Medium (複数コミットを 1 push する運用で恒常発生) / Effort M。context スキーマ変更 + facet 更新 + `[diff]` stage 修正 + テストを伴うため独立 PR 推奨 (旧 Tier 2 から昇格)。 - -#### 作業計画 - -- [ ] **`[diff]` stage の diff 範囲を `..@` (PR 範囲) に拡張** — 祖先コミットの code 変更も AI レビュー用 diff に含める (`docs_only_routing` の skip 判定と同基準に揃える)。 -- [ ] `bookmark_check.rs` で `@` 非 trunk 祖先が未レビューのまま push される穴を検証・塞ぐ (T8 / PR #280 と同クラス)。 -- [ ] 対象 PR の pre-push run dir を列挙する関数に拡張。時刻範囲のみでの絞り込みは対象外 run の混入・対象 run の欠落を招くため、対象 PR のコミット範囲や関連 bookmark 名など複数の識別根拠を突き合わせて対象 run を判定すること (`.takt/runs/*-pre-push-review`) -- [ ] context json の `prepush_reports_dir` を配列化 + facet instruction を複数 dir 対応に (スキーマ契約変更のため: 全 reader の列挙 + 旧 string 形式との後方互換 or schema versioning + 空配列時の挙動を明記) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 複数 push した PR の feedback が、時刻範囲だけでなく対象 PR のコミット範囲等の追加の識別根拠に基づいて集約された、全 pre-push run のレポートを分析対象にすること。 -- 複数コミットを 1 回で push した PR でも、tip 以外の祖先コミットの code 変更が pre-push AI レビュー (security/simplicity) の diff に含まれること (#300/#301 の "docs-only 誤認" が起きないこと)。 -- `bookmark_check` が `..@` の各祖先コミットと pre-push review 証跡を対応付け、いずれかが未レビューなら **fail-closed** で push を拒否すること ([ADR-043](adr/adr-043-security-gates-fail-closed.md))。レビュー済み・未レビュー祖先の両ケースを回帰テストで seal。 - ---- - -### cli-pr-monitor の lock.rs を token 方式の所有権検証へ統一 - -> **動機**: PR #271 で `pipeline_lock.rs` の `Drop` に token ベース所有権検証を追加した (CodeRabbit Major 対応、stale takeover 後に旧プロセスの Drop が新プロセスの lock を誤削除するバグの修正)。`src/cli-pr-monitor/src/lock.rs` の `MonitorLock` の `Drop` (`lock.rs:41-50`) も無条件 `remove_file` で、同型の所有権未検証バグを抱えている。 -> -> **参照**: `src/lib-jj-helpers/src/pipeline_lock.rs` (token 方式の参照実装)、`src/cli-pr-monitor/src/lock.rs:41-50` -> -> **実行優先度**: 🔧 Tier 2 — Effort S-M。 - -#### 作業計画 - -- [ ] `MonitorLock` に token フィールドを追加し、`Drop` を token 一致確認付き削除に変更 (`pipeline_lock.rs` の実装を踏襲) -- [ ] takeover 後に旧 guard の Drop が新 lock を消さないことを確認する regression test 追加 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `cli-pr-monitor` の lock も stale takeover 後の誤削除が起きないことがテストで保証されていること。 - ---- - -### push-runner の stack push モード (opt-in、YAGNI につき見送り継続) - -> **動機**: `bookmark_check.rs` の `OWN_WORKSPACE_BOOKMARKS_REVSET = "@"` (厳密一致) は、stacked bookmark 運用 (`feature/base` → `feature/api` → `feature/ui` を `@` 先頭で一括 push) では `@` の bookmark だけでは不足するというトレードオフを持つ。現状その運用実績はなく、必要になった時点で明示オプトインの stack push モード (`[push] stack_push` 等) を追加する拡張余地として記録する。 -> -> **参照**: `src/cli-push-runner/src/stages/bookmark_check.rs:39-43` (トレードオフの記述箇所、本エントリを指して「todo 登録済み」と既に言及している) -> -> **実行優先度**: ⏳ Tier 5 (YAGNI、実運用実績なし) — Effort M。 - -#### 作業計画 - -- [ ] stacked bookmark 運用が実際に必要になった時点で `[push] stack_push` config を設計 -- [ ] 実績が出ないまま長期化する場合は close 判断も検討 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- (着手判断待ち) 次のいずれかに至ること: (a) stacked bookmark 運用の実需が生じ opt-in モードが設計・実装される、または (b) 実績が出ないまま長期化し close 判断がなされる。 - ---- - -### jj-op-verify hook の位置づけ再整理 — 並列 workspace 安全化ではなく混線緩和層として再分類 - -> **動機**: `hooks-post-tool-jj-op-verify` は PR #267 / ADR-045 上「並列 workspace 安全化」の一部として位置づけられているが、検知対象 (「op が記録されない」症状) は jj の公式並行モデルでは説明できない (並列操作なら stale working copy エラーか divergent operation heads として op log に残るはず)。実体は出力混線 (Opus 4.8 / Fable 5 モデル起源のシリアライズ不具合、ADR-053 が上流バグと断定済み) の症状検出器であり、並列 workspace 運用の有無とは独立に価値を持つ。「並列対策が完了したので撤去可能」という将来の誤判断を防ぐため、ADR-045 ではなく ADR-053 の枠組みに紐付け直す。 -> -> **参照**: `docs/adr/adr-045-jj-workspace-parallel-sessions.md` § Known operational risks、`docs/adr/adr-053-stop-tool-call-leak-detection.md`、`src/hooks-post-tool-jj-op-verify/src/main.rs` -> -> **実行優先度**: 💎 Tier 3 — Effort S (ドキュメント再整理のみ、hook 実装は変更不要)。 - -#### 作業計画 - -- [ ] ADR-053 に「jj-op-verify hook は tool 実行はされたが結果表示の信頼性が疑わしい型の混線を検知する」旨を追記し、当該 hook への参照を追加 -- [ ] ADR-045 の該当 hook の記述を「並列 workspace 対策」から「混線検知 (副次的に並列 workspace 由来の stale 検出にも有効)」に改める -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 将来のセッションが「並列運用をやめたので jj-op-verify は不要」と誤判断しないよう、ADR 上の位置づけが混線緩和層として明記されていること。 - ---- - -### ADR-045 にコミット消失事故の「並列原因」診断が未検証である旨の注記追加 - -> **動機**: WP-11 作業中に発生した「コミット 2 つ消失」事故は「並列 jj workspace の同時操作が原因」と診断され ADR-045 に記録されたが、この診断は当時の一次証拠 (`jj op log` の実データ) ではなく、post-merge-feedback の `analyze-session` facet による事後の自己分析 (未検証) に依拠している。「op が一切記録されない」という症状は jj の公式並行モデルでは説明できず、混線 (モデル起源のシリアライズ不具合) による状態誤認が真因である可能性の方が技術的に整合する。confirmation bias の記録として、この診断の不確実性を ADR-045 に注記する。 -> -> **参照**: `docs/adr/adr-045-jj-workspace-parallel-sessions.md` § Known operational risks、本セッションの調査 (transcript `ed897a3e-85b5-44d1-a78c-ff23973f207e.jsonl` 系列、独立 subagent 検証) -> -> **実行優先度**: 💎 Tier 3 — Effort XS。 - -#### 作業計画 - -- [ ] ADR-045 の該当事故記述に「並列 workspace 原因説は事後分析による推定であり、一次証拠 (当時の jj op log) には未到達。混線 (モデル起源) が真因である可能性も残る」旨を注記 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR-045 を読む将来のセッションが、この診断を「確定事実」ではなく「未検証の有力仮説」として扱えること。 - ---- - -### Lock stale takeover + Drop の concurrency scenario 拡張テスト (271.md T2-2 採用) - -> **動機**: PR #271 が導入した token-based ownership Drop の前提 (「fresh lock は takeover されない」) を、既存 `concurrent_stale_takeover_only_one_wins` に加え、takeover 後の旧 guard drop までの full cycle を長い operation chain で検証する価値が高い。PR #267 (concurrent checkout 事故) の再発防止網としても機能する。 -> -> **参照**: `.claude/feedback-reports/271.md` Tier 2 #2、`src/lib-jj-helpers/src/pipeline_lock.rs` の tests モジュール -> -> **実行優先度**: 🔧 Tier 2 — Effort M。 - -#### 作業計画 - -- [ ] takeover → 旧 guard drop → 新 guard drop の full cycle を検証するテストを既存テストファイルに追加 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- takeover 後の旧 guard drop が新 lock を誤削除しないことが、長い operation chain のシナリオでも保証されていること。 - ---- - -### Pipeline 段階間の状態遷移 E2E テスト (271.md T2-3 採用) - -> **動機**: PR #271 で bookmark 検出の revset 厳密化 (`@` 限定) が push-runner の後続 stage の前提と衝突した実例 (simplicity reviewer が `SIM-NEW-bookmark_check-L43` として検出) があった。Stage -1〜Stage 3 の各段階終了後状態と次段階の前提を突合するテストを追加し、bookmark が `@` に遅延した状態遷移を明示的にカバーする。 -> -> **参照**: `.claude/feedback-reports/271.md` Tier 2 #3、`src/cli-push-runner/tests/pipeline_integration_test.rs` (新設) -> -> **実行優先度**: 🔧 Tier 2 — Effort M。 - -#### 作業計画 - -- [ ] `pipeline_integration_test.rs` を新設し、Stage -1〜Stage 3 の状態遷移契約を突合するテストを追加 -- [ ] 既存 `cargo test` 実行に組み込み、独立 CI step は新設しない -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- pipeline stage 間の hidden coupling が regression test で検出可能になっていること。 - ---- - -### token ベース ownership check の convention 化 (271.md T3-1 採用) - -> **動機**: PR #271 で CodeRabbit Major が指摘した「PID は OS によって再利用されうる」という知見は、`lib-jj-helpers` 以外の multi-process coordination コード追加時にも再発しうる pattern。dev-conventions.md に一般化して記載する価値がある。 -> -> **参照**: `.claude/feedback-reports/271.md` Tier 3 #1、`docs/dev-conventions.md` -> -> **実行優先度**: 💎 Tier 3 — Effort S。 - -#### 作業計画 - -- [ ] token ベース ownership check (PID/start_unix 回避) の convention を `docs/dev-conventions.md` に追記 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 将来 multi-process coordination コードを書く際に参照できる convention が存在すること。 - ---- - -### revset で workspace 所有権を判定できない旨の convention 明記 (271.md T3-2 採用) - -> **動機**: `bookmark_check.rs` の `@` 厳密一致方式 (revset による所有権推定を諦める設計判断) は、将来の jj 運用で参照価値が高い negative result。「共有履歴上の bookmark は他 workspace のものが混ざりうる」旨を project-specific convention として `CLAUDE.md` に追記する。 -> -> **参照**: `.claude/feedback-reports/271.md` Tier 3 #2、`CLAUDE.md` -> -> **実行優先度**: 💎 Tier 3 — Effort XS。 - -#### 作業計画 - -- [ ] `CLAUDE.md` に「revset だけでは workspace 所有権を判定できない」旨と `@` 厳密一致の設計判断を追記 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 将来のセッションが同種の revset ベース所有権判定を再提案しないよう、negative result が明文化されていること。 - ---- - -### Push pipeline 段階間依存性チェック項目の追加 (271.md T3-3 採用) - -> **動機**: PR #271 の hidden coupling incident (revset 厳密化が Stage 3 の前提と衝突) から得た教訓を恒久化する。Pipeline stage 修正時に「この stage の変更が後続 stage の前提を破らないか」を確認する convention を明文化する。 -> -> **参照**: `.claude/feedback-reports/271.md` Tier 3 #3、`CLAUDE.md` / `docs/dev-conventions.md` -> -> **実行優先度**: 💎 Tier 3 — Effort S。 - -#### 作業計画 - -- [ ] `CLAUDE.md` または `docs/dev-conventions.md` に pipeline stage 修正時の段階間依存性チェック項目を追加 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- Pipeline stage 修正時のレビュー観点として、段階間依存性チェックが明文化されていること。 - ---- - -### TOCTOU (remove+create_new) パターン検出 lint rule — exclusive lock 実装限定 (273.md T1-1 採用) - -> **動機**: PR #273 の二重 Acquired バグ (`remove_file` 直前の状態再検証欠落) は data integrity violation の根本原因だった。`remove_file` の直前に安全性を示す justification コメントが無い exclusive lock 実装を検出する custom lint rule (rule⑩ `no-write-result-discard` と同型の comment-presence 検出) を追加する。 -> -> **重要な scope 限定**: `cli-pr-monitor/src/lock.rs` の `MonitorLock` は `std::fs::write` overwrite 方式 + 「stale takeover の race は benign」という設計判断をコメントで既に明示済みであり、本 rule の対象外とすべき (混同すると誤検出になる)。paths を `pipeline_lock.rs` 等の exclusive-lock 実装ファイルに限定して実装すること。 -> -> **既知の限界と過去の関連判断**: 271.md Tier 1 #1 (「Concurrent guard (Drop) の無条件リソース削除検出」regex 検出) は「regex では検証済み/未検証を区別できず ADR-007 の regex 層限界に抵触する」という理由で**既に却下済み**。本エントリの単純な comment-presence 検出も同じ限界 (justification コメントさえあれば実際の再検証コードが無くても通過してしまう) を抱える。CodeRabbit re-review (PR #274) 指摘によりこの限界が具体化したため、下記のとおり検出粒度を「コメント有無」から「再読込→比較→remove_file という 3 ステップの出現順序」の regex/pattern 検出へ強化する (AST 層への格上げは Effort M 相当となり本エントリの Effort S を超えるため、まずは pattern 検出の強化で対応し、それでも false negative が実運用で頻発する場合に AST 層格上げを再検討する)。 -> -> **参照**: `.claude/feedback-reports/273.md` Tier 1 #1、`.claude/feedback-reports/271.md` Tier 1 #1 (関連する過去の却下判断)、`src/lib-jj-helpers/src/pipeline_lock.rs` (今回の fix)、`.claude/custom-lint-rules.toml` -> -> **実行優先度**: 🚀 Tier 1 — Severity High / Effort S。 - -#### 作業計画 - -- [ ] `.claude/custom-lint-rules.toml` に「`remove_file` 呼び出し directly 手前の N 行以内に、読込 (`read_to_string` 等) → 比較 (`==`/`if let` 等) の出現順序があること」を要求する pattern 検出ルールを追加 (単純な comment-presence ではなく構造的な出現順序を見る、paths を exclusive-lock 実装限定) -- [ ] `cli-pr-monitor/src/lock.rs` を誤検出しないことを確認する negative fixture 追加 -- [ ] 「justification コメントはあるが再読込・比較コードが無い」ケースが lint により検出される (= コメントのみでは通過しない) ことを示す negative fixture を追加 -- [ ] lint 検出時に CODE REVIEW で「lock safety pattern verified」を人手確認する運用を `docs/dev-conventions.md` に明文化し、本 rule の false negative となりうるケース (カバレッジ限界) を rule 定義コメントに記録 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 「読込→比較→remove_file」という構造そのものを欠く新規 exclusive lock 実装が、lint rule (pattern 検出) により push 前に検出されること。 -- 「justification コメントのみで再検証コードを欠く」実装が、コメントの存在にかかわらず lint で検出される (= 通過しない) ことが negative fixture で証明されていること。 -- 上記 pattern 検出にも false negative となりうるケースが残るため、lint 検出時に CODE REVIEW で「lock safety pattern verified」であることを人手確認する運用が明文化されていること、かつ本 rule のカバレッジ限界が記録されていること。 - ---- - -### `takeover_stale_lock_skips_remove_when_snapshot_is_stale` パターンを deterministic concurrency test テンプレートとして記録 (273.md T2-3 採用) - -> **動機**: PR #273 で追加した決定論的 regression test (`stale_snapshot` を意図的に不一致にして takeover レースを注入的に再現するパターン) は、実スレッドタイミングに依存する flaky test (`concurrent_stale_takeover_only_one_wins`) より再現性が高い。次の並行処理系 PR で同型テストが必要になった際のテンプレートとして記録する。 -> -> **参照**: `.claude/feedback-reports/273.md` Tier 2 #3、`src/lib-jj-helpers/src/pipeline_lock.rs` の `takeover_stale_lock_skips_remove_when_snapshot_is_stale` -> -> **実行優先度**: 💎 Tier 3 — Effort XS。 - -#### 作業計画 - -- [ ] `docs/dev-conventions.md` に「並行処理の regression test は実スレッドレースより、内部関数を直接呼び状態不一致を注入する決定論的パターンを優先する」旨とコード例を追記 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次の並行処理系バグ修正で、決定論的テストパターンが参照可能な形で存在すること。 - ---- - -### Advisory lock (fail-open) の TOCTOU window 許容可否を明示コメントで残す設計チェックリスト (273.md T3-1 採用) - -> **動機**: `cli-pr-monitor/src/lock.rs` の `MonitorLock` は「stale takeover の race は benign」という判断を既にコメントで明示済みだが、これは実践のみでチェックリスト化されていない。既に実践されている practice を明文化すれば、将来の advisory lock 実装での判断ミス (許容可否を検討せず TOCTOU を放置する、あるいは過剰に厳格化する) を構造的に防止できる。 -> -> **参照**: `.claude/feedback-reports/273.md` Tier 3 #1、`src/cli-pr-monitor/src/lock.rs`、`src/lib-jj-helpers/src/pipeline_lock.rs` (takeover_stale_lock の doc comment) -> -> **実行優先度**: 💎 Tier 3 — Effort XS。 - -#### 作業計画 - -- [ ] `docs/dev-conventions.md` に「advisory lock の TOCTOU window に触れる実装は、許容可否の判断根拠を doc comment に残す」チェックリストを追加 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- advisory lock 実装時に参照できるチェックリストが存在すること。 - ---- - -### quality gate 実行中に発見したバグ修正が別 PR に混入した際の `jj split` + `jj rebase` 復旧パターンを記録 (273.md T3-3 採用) - -> **動機**: PR #272 (docs-only) の push 中に quality gate が実行した `cargo test --workspace` で PR #273 相当のバグを発見し、その場で修正した結果 docs コミットに混入した。`jj split` + `jj rebase` で低コストに復旧できた実務パターンを記録する。ADR-045 の並列 workspace リスクとは別種の事故 (単一 session 内の混入) であり、区別して記録する価値がある。 -> -> **参照**: `.claude/feedback-reports/273.md` Tier 3 #3、本セッションの復旧手順 (`jj split -m ... ` → `jj rebase -s -d ` → `jj rebase -s -d master`) -> -> **実行優先度**: 💎 Tier 3 — Effort XS。 - -#### 作業計画 - -- [ ] `docs/dev-conventions.md` に「push/merge パイプライン実行中に無関係なバグを発見・修正した場合、`jj split` で分離し、それぞれ独立した bookmark/PR にする」復旧手順を追記 -- [ ] `jj split`/`jj rebase` は**混入後の事後対応**であり、混在した変更に対して既に実行された quality gate / pre-push review の結果は汚染されている (予防はできていない) ため、分離後は当該結果を破棄し、分離後の各コミット/PR で quality gate / pre-push review を個別に再実行する手順を追記 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 同種の混入が今後発生した際に、参照できる復旧手順が存在すること。 -- 復旧手順に「混在した変更に対する gate 実行結果は無効であり、分離後に各 PR で個別に再実行する」ことが明記されていること (CodeRabbit 指摘: 復旧は予防の代替ではなく、汚染された gate 結果をそのまま信頼してはならない)。 - ---- - -### Metrics violation の pre-existing 判定基準の明文化 (273.md T3-4 採用) - -> **動機**: metrics 系 gate (`file_size_check` / `file_length_gate` 等) が複数稼働中の本リポジトリでは、violation が先行 PR/feature 由来の pre-existing なものか、今回の変更に起因するものかを判定して override する場面が繰り返し発生する。PR #273 では 4 件の violation が PR #271 由来の pre-existing として人手判断で正しく override されたが、判定基準 (対象 revset の選び方・feature 境界の見極め方) が曖昧なまま自動化すると誤判定リスクがある。判定基準の明文化は Tier 2 #5 (自動 exemption 機構) の検討の前提を整える。 -> -> **参照**: `.claude/feedback-reports/273.md` Tier 3 #4、Tier 2 #5、`docs/dev-conventions.md` -> -> **実行優先度**: 💎 Tier 3 — Effort XS。 - -#### 作業計画 - -- [ ] `docs/dev-conventions.md` に「metrics violation が pre-existing と判断する際の判定基準 (対象 revset の選び方、feature 境界の見極め方など)」チェックリストを追加 (基準時点/現時点の計測結果・差分、判定理由、判定者・判定日時、レビュー承認者を記録する audit trail 要件を含み、証跡が揃わない場合は override 不可とする) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- metrics 系 gate の violation を pre-existing として override する際に、判断根拠として参照できる基準が存在すること。 -- 上記基準に加え、override 判定時に「基準時点と現時点の計測結果・差分」「pre-existing と判断した理由」「判定者・判定日時」「レビュー承認者」を PR/MR コメントまたは `docs/override-log.md` に記録し、これらの証跡が揃わない限り override できないチェックリストになっていること (同一メトリクスの反復 violation を将来 anomaly として検知できるようにするため)。 - ---- - -### quality gate isolation 機構を見送り、recovery による risk acceptance とした判断の記録 (negative result) (273.md T3-5 採用) - -> **動機**: PR #273 の post-merge-feedback は「quality gate 実行を commit group ごとに isolated working copy で行う構造的防止機構」(Tier 2 #4) を提案したが、Effort L・runner 複雑化という Adoption Risk に見合わず却下した。spike 見送り (negative result) 永続化 convention に従い、この却下判断を記録する。 -> -> **CodeRabbit 指摘 (PR #274) による訂正**: **recovery (`jj split`/`jj rebase` 復旧パターン) は isolation (予防) の代替にはならない。** isolation は「混入自体を未然に防ぐ」機構であり、recovery は「混入が起きたことを検知した後に事後対応する」機構であって、両者は異なるリスク層に属する。isolation を見送った真の判断は「recovery で同等の予防効果が得られる」ではなく、「混入は今後も起こりうるが、発生時の recovery コストが低いため、isolation 実装コスト (Effort L) をかけてまで予防する必要はないと risk acceptance した」という判断である。 -> -> **参照**: `.claude/feedback-reports/273.md` Tier 2 #4 (却下 recommendation)、Tier 3 #5、docs/dev-conventions.md § spike 見送り (negative result) 永続化 convention、`jj split`/`jj rebase` 復旧パターンを記録するタスク (本ファイル内) -> -> **実行優先度**: 💎 Tier 3 — Effort S。 - -#### 作業計画 - -- [ ] 関連 ADR (ADR-045 または新規 amendment) に、isolation 機構を見送り、recovery コストの低さを理由に risk acceptance した判断を negative result として記録する。「recovery が isolation の代替になる」という表現は用いない -- [ ] 記録には「isolation を見送ったことで残る予防機能の欠如 (混在した変更に対して quality gate / pre-push review が誤って green 判定を出しうる残存リスク)」を明記する -- [ ] 記録には再検討条件 (例: 同種の混入事故が反復する、isolation の実装コストが下がる、等) を明記する -- [ ] `docs/todo-summary.md` の本エントリ行の説明も「代替」ではなく「recovery コストの低さによる risk acceptance」と表現する -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 将来の再検討時に、この見送り判断の根拠が参照可能であること。 -- 記録が「recovery は isolation の代替である」という誤解を招く表現になっておらず、予防機能の欠如という残存リスクと、再検討条件が明記されていること。 - ---- - - - - -### WP-12 step 2: 発火テレメトリ ROI 棚卸し pre-step (28 日 warm-up 後着手) - -> **動機**: WP-12 step 1 ([ADR-055](adr/adr-055-firing-telemetry-collection.md)) で `lib-telemetry` が `.claude/telemetry/firings-*.jsonl` に発火を収集し始めた。その実データを使って「直近 28 日で発火 0 の rule/preset/hook」を削除候補として機械抽出し、ハーネス複雑度の維持判断を発火実績で機械化する (WP-12 の本来目的)。 -> -> **本タスクの位置づけ**: WP-12 step 1 の後続 PR。**着手条件 = step 1 マージから 28 日経過** (warm-up。それ以前は全項目が発火 0 = データ無しになり削除候補判定が無意味)。 -> -> **参照**: [ADR-055](adr/adr-055-firing-telemetry-collection.md) (収集層)、[ADR-031](adr/adr-031-weekly-review-pipeline.md) (棚卸しの出力先 = weekly-review)、`.takt/facets/instructions/file-length-watchlist.md` (同型の「機械層」pre-step = takt facet + Bash パターン)、`.takt/facets/instructions/aggregate-weekly.md` (`### File Length Watchlist (機械的観測)` セクションの隣に発火統計セクションを追加)、[ADR-049](adr/adr-049-incident-eval-regression-suite.md) (incident 由来ルールは発火 0 でも維持推奨の区別)。 -> -> **実行優先度**: 🔧 Tier 2 — Effort M。step 1 の投資回収に必須だが warm-up 待ちのため即着手不可。 - -#### 設計決定 (案) - -- **集計は Rust exe** (ヒアリング確定)。`firings-*.jsonl` を glob 走査し、rule/preset/hook ごとに直近 28 日の発火数を集計する `cli-*` exe (または既存 crate のサブコマンド)。全 rule/preset/hook の一覧 (custom-lint-rules.toml / preset レジストリ / hook レジストリ) との差分で「発火 0 の項目」を導出する。 -- **takt facet + Bash で weekly-review に接続**。file-length-watchlist と同型で、facet の Bash step が集計 exe を呼び watchlist markdown を出力 → aggregate-weekly が `### 発火統計 (機械的観測)` セクションとして転載する。 -- **incident 由来ルールの区別**: `custom-lint-rules.toml` の `[rules.incident]` を持つルールは発火 0 でも「抑止力として維持推奨」とし、非 incident ルールのみ削除候補にする (ADR-049 の思想)。 -- **warm-up 表示**: 収集開始日から 28 日未満の項目は「観測期間中・判定保留」と出力し、誤って削除候補に出さない。 - -#### 作業計画 - -- [ ] 集計 Rust exe を実装 (28 日窓の発火数集計 + 全項目レジストリとの差分 + incident 区別 + warm-up 判定)。ユニットテストで固定 JSONL fixture から集計値を assert。 -- [ ] takt facet (`file-length-watchlist.md` 同型) を新設し weekly-review.yaml の reviewers parallel block に追加。 -- [ ] aggregate-weekly.md に `### 発火統計 (機械的観測)` セクション転載を追加。 -- [ ] dogfood: 週次レビューレポートに発火統計セクションが出力され、初回実行で削除候補 (または全維持の根拠) が特定されることを確認。 -- [ ] 本エントリ削除 + todo-summary.md 行削除 + [harness-improvement-plan.md](harness-improvement-plan.md) の WP-12 状態更新 (step 2 消化)。 - -#### 完了基準 - -- 週次レビューレポートに発火統計セクションが出力され、直近 28 日で発火 0 の rule/preset/hook が (incident 由来を除いて) 削除候補として、または全維持の根拠とともに特定されること。 - ---- - -### WP-12 step 3: ADR-039 bounded lifetime 判定の発火数機械化 (step 2 に依存) - -> **動機**: ADR-039 の試験運用機能の卒業/廃止判定は現状「手動で観測値を閾値照合」する方式で、機械集計機構が無い。WP-12 step 2 で発火数の集計基盤ができるので、これを使って「試験運用 ADR の機構が N 日発火 0 → 卒業 (廃止 or 本採用) の検討を promote」を機械化する。 -> -> **本タスクの位置づけ**: WP-12 step 3。**step 2 (集計基盤) に依存**。step 2 完了後に着手。 -> -> **参照**: [ADR-039](adr/adr-039-experimental-feature-standard-pattern.md) (§ 3 bounded lifetime、現状は手動 3 値判定)、[ADR-055](adr/adr-055-firing-telemetry-collection.md) (収集層)、WP-12 step 2 (集計基盤、本ファイル内)。 -> -> **実行優先度**: 💎 Tier 3 — Effort S。step 2 の集計結果に卒業/廃止判定ロジックを重ねる薄い層。 - -#### 作業計画 - -- [ ] step 2 の集計出力に「試験運用 ADR の機構ごとの発火数 + bounded lifetime 期限との照合」を追加し、卒業/廃止の検討を promote する判定を機械化する。 -- [ ] ADR-039 に「bounded lifetime 判定の発火数機械化」を amendment として記録。 -- [ ] 本エントリ削除 + todo-summary.md 行削除 + harness-improvement-plan.md の WP-12 状態更新 (step 3 消化 = WP-12 完了)。 - -#### 完了基準 - -- 試験運用機能の卒業/廃止検討が発火数に基づいて週次で自動 promote され、ADR-039 の手動閾値照合が機械化されること。 - ---- - -### telemetry の block 記録を実 quality 違反に限定(infra エラー混入の除外)(275.md T1-1 採用) - -> **動機**: CodeRabbit Major 指摘。`emit_block` / `record_*_firing` が品質違反だけでなく fail-closed の infra エラー(stdin 読込失敗 / JSON parse 失敗)でも発火を記録する。ADR-055 では「hook が block を emit した総数」として意図的にこの設計にしたが、WP-12 の ROI 棚卸し(発火数で hook 維持を判断)では infra エラー混入が発火数を歪めるため、実 quality 違反パス(`block_on_failures` 等)限定に絞り込む方が信号が正確になる。 -> -> **重要**: これは ADR-055 で「意図的」と記録した判断の見直しであり、実装時は ADR-055 の該当記述(emit 総数の定義)も併せて amendment する。3 hook 横断(hooks-stop-quality / hooks-stop-tool-call-leak / hooks-pre-tool-validate)のため実装は分割 PR 推奨。stop-tool-call-leak は実 leak でのみ emit_block を呼ぶため既に実質限定されている点も確認する。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 1 #1、`src/hooks-stop-quality/src/main.rs`(`emit_block` / `record_block_firing`)、[ADR-055](adr/adr-055-firing-telemetry-collection.md) § 計装スコープ、WP-12 step 2(順位 307、集計精度の前提)。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort M。 - -#### 作業計画 - -- [ ] 各 hook の記録呼び出しを実 quality 違反パス限定に移動(infra エラー経路では記録しない)。record 位置の見直し。 -- [ ] [ADR-055](adr/adr-055-firing-telemetry-collection.md) の「emit 総数」定義を amendment(実 violation 限定に方針変更した根拠を記録)。 -- [ ] 各 hook のユニットテストで「infra エラー経路では telemetry を記録しない」ことを検証。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- telemetry の block 記録が実 quality 違反に限定され、infra エラー(stdin/parse 失敗)では記録されないことがテストで保証され、ADR-055 の定義も整合していること。 - ---- - -### custom-regex preset の生 regex が telemetry id に流れる privacy footgun の是正(非ブロッキング follow-up 統合)(275.md T1-2 採用) - -> **動機**: PR #275 の pre-push simplicity review 非ブロッキング warning(= セッション中に検出された「非ブロッキング follow-up」)。`tag_source(name, ...)` の `name` が named preset 名でなく `blocked_patterns` の生正規表現文字列の場合、その regex テキストがそのまま telemetry の `id` フィールドに載り、ADR-055 の「コマンド本文・内容は非記録」プライバシー原則と緊張する。現行 `hooks-config.toml` は named preset のみのため**非発火**だが、派生プロジェクトが raw-regex エントリを足すと該当する latent footgun。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 1 #2、`src/hooks-pre-tool-validate/src/blocked_patterns.rs`(`tag_source`)、`src/hooks-pre-tool-validate/src/handlers.rs`(`record_preset_block`)、[ADR-055](adr/adr-055-firing-telemetry-collection.md) § プライバシー。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort S。 - -#### 作業計画 - -- [ ] custom-regex fallback branch では `source` を合成 id(例 `"custom-block"`)に正規化し、生 regex を telemetry id に載せない。 -- [ ] hooks-config パース時に raw-regex な `blocked_patterns` エントリを検出したら警告する config validation を追加(任意)。 -- [ ] [ADR-055](adr/adr-055-firing-telemetry-collection.md) に「Configuration-Driven Privacy Risks(custom config 変更時のプライバシー implications、派生プロジェクトの責務)」セクションを追記。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- custom-regex な `blocked_patterns` を設定しても生 regex 文字列が telemetry `id` に記録されず、ADR-055 のプライバシー原則が config 由来入力に対しても保たれること。 - ---- - -### 逐語的関数複製(3+ コピー)を pre-push 検出する DRY lint rule (275.md T1-3 採用) - -> **動機**: PR #275 で `is_truthy` が `lib-telemetry` / `hooks-post-tool-comment-lint-rust` / `hooks-stop-tool-call-leak` の 3 crate に逐語一致で存在していた(simplicity review が検出 → fix loop が `lib_telemetry::is_truthy` へ統一)。ADR-007 の regex 層に「同一関数コピーが threshold(3+)を超える」ことを検出するルールを追加すれば、次回同型の DRY を pre-push 段階で先回り検出できる。 -> -> **注意**: regex 層の限界(意味的同一性は検出できない)があるため、まず「逐語一致コピー」に限定した pattern 検出とし、false positive を避ける。より網羅的な依存グラフ型検出は様子見(275.md Tier 2 #2)。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 1 #3、`.claude/custom-lint-rules.toml`、[ADR-007](adr/adr-007-custom-linter-layer-boundary.md)。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort M。 - -#### 作業計画 - -- [ ] workspace 内で同一シグネチャ/本体の関数が 3+ 箇所に逐語一致で存在することを検出する仕組みを追加(custom lint rule または xtask)。 -- [ ] good/bad fixture 追加(順位 313 = ADR-049 incident fixture と抱き合わせ)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 同一関数が 3+ 箇所に逐語複製された状態が push 前に検出され、共有化を促すこと。 - ---- - -### `.claude/telemetry/` の per-pid×日次 partition ファイルの retention/cleanup (275.md T2-1 採用) - -> **動機**: WP-12 step 1 の Windows 並行安全性設計(per-pid × 日次 partition)は warm-up 期間中に小さな `firings-*.jsonl` を多数蓄積する。28 日超過分を削除する retention/cleanup を入れる。WP-12 step 2(集計 pre-step)の前提作業。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 2 #1、`src/lib-telemetry/src/lib.rs`、WP-12 step 2(順位 307)。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Medium / Effort M。**着手条件 = WP-12 step 2 と同時期(step 1 マージから 28 日後、2026-08-12 頃)**。 - -#### 作業計画 - -- [ ] `lib-telemetry` に retention ロジック(N 日超過の firings ファイル削除)を追加、ユニットテスト。 -- [ ] WP-12 step 2 の集計 pre-step と統合(順位 307 と同一 PR 消化が自然)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 28 日を超えた telemetry partition ファイルが自動削除され、warm-up 蓄積が bounded であること。 - ---- - -### `is_truthy` 三重複製を ADR-049 incident suite の fixture として記録 (275.md T2-4 採用) - -> **動機**: PR #275 の `is_truthy` 三重複製を [ADR-049](adr/adr-049-incident-eval-regression-suite.md) の「カスタムルールの由来 incident 再現テスト」convention に沿って fixture 化する。順位 311(DRY lint rule)実装時に good/bad fixture として抱き合わせるのが自然。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 2 #4、[ADR-049](adr/adr-049-incident-eval-regression-suite.md)、順位 311(DRY lint rule)。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Low / Effort XS。 - -#### 作業計画 - -- [ ] 順位 311 の DRY lint rule に対する bad fixture(3+ 逐語複製)と good fixture(共有化済み)を incident suite に追加。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- `is_truthy` 型の逐語複製 incident が回帰テストで再現・防止されること。 - ---- - -### bookmark 未作成での push 失敗(exit 7)のエラーメッセージ改善 (275.md T2-5 採用) - -> **動機**: PR #275 のセッションで、新規ブランチの bookmark を作らずに `pnpm push` して exit code 7 で失敗する process friction が実発生した(`jj bookmark create feat/firing-telemetry -r @` を手動実行して再試行)。push-runner の bookmark 自動作成は [ADR-011](adr/adr-011-jj-push-new-bookmark-strategy.md) の「明示的命名で ambiguity を避ける」設計意図と緊張するため対象外とし、**エラーメッセージの改善のみ**を行う(`jj bookmark create -r @` を命名規約とともに具体的に提示)。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 2 #5、`src/cli-push-runner`(bookmark 未検出時のエラー出力)、[ADR-011](adr/adr-011-jj-push-new-bookmark-strategy.md)。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Low / Effort S。 - -#### 作業計画 - -- [ ] push-runner の bookmark 未検出エラーに、推奨命名(`feat/...`)付きの `jj bookmark create -r @` を具体的に提示する。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 新規ブランチで bookmark 未作成のまま push した際、次に打つべきコマンドがエラーメッセージから即座に分かること。 - ---- - -### ADR-055 telemetry の bounded lifetime 期限を config コメントに明記 (275.md T3-1 採用) - -> **動機**: ADR-055 の telemetry は 28 日 warm-up 後に WP-12 step 2/3 で棚卸しする bounded lifetime 機能。運用者が期限を見落とさないよう、具体日付(step 1 マージ 2026-07-16 + 28 日 = 2026-08-12 頃)と todo-summary.md 順位 307/308 へのリンクを `.claude/hooks-config.toml` の `[telemetry]` section コメントに追記する。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 3 #1、`.claude/hooks-config.toml`(`[telemetry]` section)、順位 307/308。 -> -> **実行優先度**: 💎 Tier 3 — Severity Low / Effort XS。 - -#### 作業計画 - -- [ ] `[telemetry]` section コメントに warm-up 期限(2026-08-12 頃)と順位 307/308 を追記。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- config を読んだ運用者が telemetry の棚卸し期限と後続タスクを把握できること。 - ---- - -### ADR-044「2nd consumer で共通化」原則の明確化・判定基準の例示 (275.md T3-2 採用) - -> **動機**: PR #275 で UTC helper では ADR-044 の「2 番目の消費者」トリガを明示的に論じたのに `is_truthy` では同じ規律を見落とすという非対称性が実発生した(現在は統一済み)。「同一シグネチャ/logic の関数は 2nd consumer 時点で共有 crate に切り出す」という判定基準を明示化し、`is_truthy` を case study として記載する。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 3 #2、`CLAUDE.md`、[ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md)。 -> -> **実行優先度**: 💎 Tier 3 — Severity Low / Effort S。順位 317(チェックリスト)と対で実施すると効果的。 - -#### 作業計画 - -- [ ] [ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md) に「When to extract helper to shared crate」判定基準と `is_truthy` case study を追記。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 同一パターンの関数が複数箇所に現れた際の共有化判断基準が参照可能で、is_truthy 型の見落としが再発しにくくなること。 - ---- - -### utility 関数追加前のチェックリスト(workspace grep)(275.md T3-3 採用) - -> **動機**: 順位 316(ADR-044 明確化)と対で、新規 helper 追加時の実務チェックを `docs/dev-conventions.md` に追加する。「新 helper 追加前に workspace 内の類似パターンを grep し、2+ 箇所に既存すれば ADR-044 に従い共有化を検討する」。 -> -> **参照**: `.claude/feedback-reports/275.md` Tier 3 #3、`docs/dev-conventions.md`、順位 316。 -> -> **実行優先度**: 💎 Tier 3 — Severity Low / Effort XS。 - -#### 作業計画 - -- [ ] `docs/dev-conventions.md` のチェックリストに utility 追加前の grep 手順を追記。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 新規 utility 追加時に既存重複を事前確認する手順が明文化されていること。 - ---- - -### CR rate-limit 第3 format 未対応 + marker 一致/regex 不一致の silent 化 (PR #287 実観測) - -> **動機**: PR #287 で CodeRabbit がレビュー上限に達したが、**決定論層 (`check-ci-coderabbit`) が rate-limit を検知できず**、監視は「CodeRabbit: 新規指摘3件 / findings 0 件 / verdict approved」と報告した。ユーザーからは「レートリミットに引っかかっていることが表向き見えなかった」と観測された。 -> -> **根本原因 (実測で特定)**: CR の wait-time 文言が第3 format に変化していた。 -> -> | 判定 | 対象文字列 | 結果 | -> |---|---|---| -> | `is_rate_limit_comment` | `rate limited by coderabbit.ai` (HTML コメント内) | **TRUE** (marker は一致) | -> | `extract_old_format_wait_time` | `Please wait N minutes and M seconds` | 不一致 | -> | `extract_new_format_wait_time` | `More reviews will be available in N minutes` | 不一致 | -> | **実際の文言 (2026-07 観測)** | **`**Next review available in:** **32 minutes**`** | **どの parser も未対応** | -> -> `parse_rate_limit` は `let (minutes, seconds) = extract_wait_time(body)?;` で **None を返して静かに終了**する (`src/check-ci-coderabbit/src/rate_limit.rs`)。結果、rate-limit comment を検出しているのに「rate-limit 無し」と区別が付かない。 -> -> **ADR-034 の予測は当たっていた**: 同 ADR § 既知 CR rate-limit format 一覧 の「HTML マーカー優先 (CR は UI 文言を変えても internal marker は維持する傾向、本リポジトリ未検証)」は、今回 **marker 安定 / UI 文言変化** として実証された。予測は正しかったが、**wait-time regex 側の脆弱性は対策されていなかった**。 -> -> **ADR-034 の troubleshooting が想定する症状と違う**: 同 ADR § 検出 logic 更新手順 は「`is_rate_limit_comment` が常時 false を返す symptom (PR #182 実観測)」を前提に書かれている。今回は **marker 一致 / regex 不一致**という別の失敗モードで、既存の症状記述では発見できない。 -> -> **これは同一クラスの 3 世代目**: 旧 format (~2026 年初) → 新 format (2026-05 / PR #182・#184 で silent regression 実観測) → 第3 format (2026-07 / 本件)。marker は multi-variant 配列化されたが、regex は format 追従のたびに手当てが要る構造のまま。 -> -> **参照**: `src/check-ci-coderabbit/src/rate_limit.rs` (`extract_wait_time` / `parse_rate_limit`)、`src/check-ci-coderabbit/src/markers.rs` (`RATE_LIMIT_MARKERS`)、[ADR-034](adr/adr-034-coderabbit-auto-monitoring.md) § 既知 CR rate-limit format 一覧 / § 検出 logic 更新手順、[ADR-043](adr/adr-043-security-gates-fail-closed.md) (fail-closed)、PR #287。 -> -> **実行優先度**: 🚀 Tier 1 — Severity **High** (監視の false-green を生む) / Effort S。 - -#### 作業計画 - -- [ ] ADR-034 § 検出 logic 更新手順 の step 4: `extract_next_review_format_wait_time` を追加 (`Next review available in:?\**\s*\**(\d+) minutes?` + `and (\d+) seconds?` 併記 variant)。`extract_wait_time` の or_else 連鎖に追加する。 -- [ ] **silent 化の構造的解消 (本エントリの本丸)**: `is_rate_limit_comment == true` かつ `extract_wait_time == None` の組合せを **loud にする**。現状は「marker 一致だが wait time 不明」= 既知の未知 (known-unknown) を `None` に潰して「rate-limit 無し」と同一視している。最低限 warn ログ + 監視側で「rate-limit 検出・待ち時間不明」を報告し、ADR-043 に従い保守的な既定待ち時間 (例: 30 分) で park する案を検討する。**この修正が入れば第4 format が来ても silent regression にはならない** (regex 追加は追従作業に留まる)。 -- [ ] fixture 追加 (step 5): 第3 format の実 body を 2-3 variant。既存 fixture は backward compat のため維持。**回帰テストは「修正前に実際に落ちること」を確認する** (§2 原則 2 / ADR-049)。marker 一致・regex 不一致の silent ケースも 1 本固定する。 -- [ ] ADR-034 § 既知 CR rate-limit format 一覧 table に第3 format 行を append (step 6)。あわせて § 検出 logic 更新手順 の症状記述に「marker 一致 / regex 不一致 (= 常時 None、silent)」を追記する — 現在の記述は marker 失敗のみ想定で本件を発見できない。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 第3 format の rate-limit comment から待ち時間が抽出でき、監視が park 経路に乗ること (fixture + 実 body で確認)。 -- marker 一致 / wait-time 抽出失敗の組合せが silent に握り潰されず、ログまたは報告に現れること。 - ---- - -### pr-monitor.yml バックストップの重複ガードが構造的に機能しない (PR #287 実観測) - -> **動機**: PR #287 で「🤖 PR Monitor 分析 (GitHub Actions バックストップ)」が **5 件**投稿された。ユーザーから「1 回投稿すれば十分な情報を、CodeRabbit の投稿に反応して毎回投稿する実装になっていないか」と指摘され、実測で裏付けられた。 -> -> **実測 (すべて CR 投稿の直後に発火)**: -> -> | CR 投稿 | → backstop | 遅延 | -> |---|---|---| -> | 12:42:31 | 12:44:13 | +1m42s | -> | 13:09:32/35 | 13:16:16 | — | -> | 13:16:36 (ack のみ) | 13:18:11 | +1m35s | -> | 13:45:03 (ack のみ) | 13:46:09 | +1m06s | -> | 13:46:25 | **13:49:06** | +2m41s (**マージ 13:48:12 の後**) | -> -> **根本原因**: 重複ガードは存在する (`.github/workflows/pr-monitor.yml` prompt 手順 2) が、**構造的トートロジー**になっている。ガードの skip 条件は「過去の分析コメント以降に**新しいコメント等の変化が無い**場合」。しかし本 workflow の起動トリガーは `issue_comment (created) by coderabbitai[bot]` であり、**発火した時点で必ず「新しいコメント」が存在する**。よって issue_comment 経路で skip 条件は永久に成立しない。 -> -> **証拠 (agent 自身が無価値と認識しつつ投稿している)**: 13:18:11 の投稿本文は「前回分析以降に生じたのは CodeRabbit による定型 acknowledgment コメント 1 件のみで、レビュー実体の追加は無し」と自ら述べている。ガードが「新規コメントの有無」を見ており「分析価値のある新情報か」を見ていないため、ack 1 件でも再分析・再投稿に進む。 -> -> **副次問題**: (a) PR が **MERGED/CLOSED でも投稿する** (13:49:06 はマージ後)。state ガードが無い。(b) 1 投稿あたり claude-code-action (sonnet / max-turns 30) が 1 run 走るため、**Max 枠を無駄に消費**する (workflow 冒頭コメントが挙げる「Max 枠の暴走ガード」の意図に反する)。 -> -> **設計上の含意**: ガードを LLM prompt 側 (助言層) に置いたことが原因。`concurrency` は同時実行を潰すが逐次の再投稿は防げない。ADR-042 (ルール vs 仕組み化の境界基準) の観点では、**決定論層 (workflow の `if:` 条件) に移すべき類**。 -> -> **参照**: `.github/workflows/pr-monitor.yml` (prompt 手順 2 / `on:` / `jobs.analyze.if:` / concurrency)、[ADR-022](adr/adr-022-automation-responsibility-separation.md) 原則 6、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md)、PR #287。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium (機能は壊れないが noise + Max 枠浪費) / Effort S。 - -#### 作業計画 - -- [ ] **決定論ガードを `if:` に追加** (LLM prompt に依存しない層へ移す): - - [ ] CR の **ack / 定型応答コメントを除外**する。`github.event.comment.body` に `` (= ack) が含まれる場合は起動しない。分析価値があるのは walkthrough (``) のみ。**本件の再投稿 5 件中 2 件はこの 1 条件で消える**。 - - [ ] PR が **CLOSED / MERGED なら起動しない** (`github.event.issue.state == 'open'`)。 -- [ ] prompt 手順 2 のガード条件を「**新規コメントの有無**」から「**分析価値のある新情報の有無**」へ書き換える (ack / rate-limit 通知 / 自身の分析コメントは新情報に数えない旨を明示)。決定論ガードを主、prompt ガードを従 (二層目) とする。 -- [ ] 起動条件を変えるため **workflow_dispatch でのスモークテスト**を行い、(a) ack で起動しないこと (b) walkthrough で起動すること (c) merged PR で起動しないこと を実測で確認する。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- CR の walkthrough 更新 1 回につき backstop の投稿が高々 1 件で、ack / マージ後には投稿されないこと (実 PR で確認)。 - ---- - -### CodeRabbit status check は実レビュー有無に関わらず `pass` (PR #287 実観測) - -> **動機**: PR #287 で `gh pr checks 287` が一貫して **`CodeRabbit pass`** を返し続けたが、実際にはレビューが 1 度も実行されていなかった (`pulls/287/reviews` = 0 件、インラインコメント = 0 件)。緑チェックが「レビュー済み」を意味しないことが実観測された。 -> -> **実測した表示の変遷 (いずれも `pass`)**: -> -> | 実態 | checks の表示 | -> |---|---| -> | 増分レビュー skip | `pass` — `Review skipped: incremental reviews are disabled` | -> | **rate limit で未実行** | `pass` — (同上のまま。**本文は `Review limit reached` に更新済みなのに check 行は追従しない**) | -> | レビュー完了 | `pass` — `Review completed` | -> -> **2 つの落とし穴**: -> -> 1. **`pass` は「レビューした」ではなく「CodeRabbit が異常終了しなかった」の意**。skip も rate-limit も pass。緑を根拠に「レビュー通過」と判断すると false-green になる。 -> 2. **check 行の summary は stale になる**。CR は**コメント本文を in-place 更新**する (本件では `updated_at` のみ 13:09:39 に更新) が、check の summary 文字列は更新されない。本セッションでは `Review skipped: incremental reviews are disabled` という古い表示のまま、実態は `Review limit reached` だった。**checks 行だけを見ると誤診する**。 -> -> **正しい判定 source (本件で有効だった順)**: (a) `gh pr view --json reviews` の件数、(b) CR walkthrough 本文の `Configuration used` (`Organization UI` = レビュー未開始の症状 / `Path: .coderabbit.yaml` = 実行された証拠)、(c) 本文の `No actionable comments were generated` / `Review limit reached`。**(b) は本件の診断で決定打になった**。 -> -> **参照**: PR #287 (`Configuration used` が `Organization UI` → `Path: .coderabbit.yaml` に変化)、順位 318 (決定論的 rate-limit 検知)、`.takt/facets/instructions/analyze-coderabbit.md`、`.github/workflows/pr-monitor.yml` prompt 手順 1。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Medium (誤診の温床) / Effort S。 - -#### 作業計画 - -- [ ] `analyze-coderabbit.md` と `pr-monitor.yml` prompt に「**CodeRabbit check の `pass` はレビュー実施の根拠にならない / summary 文字列は stale になり得る**」を明記し、判定 source を上記 (a)(b)(c) に固定する。 -- [ ] `check-ci-coderabbit` に「**レビュー実施の有無**」を `reviews` 件数 + walkthrough marker から判定する関数を追加し、`review_state: success` と実レビュー有無を分離して report する (現状 `review_state` が success でも実体ゼロがあり得る)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 監視の report で「CR check は pass だが実レビューは 0 件」の状態が判別でき、approved と誤って報告されないこと。 - ---- - -### ADR-019/WP-03 クォータ設計の前提 stale + 初回レビュー処理中 push のレビュー欠落穴 - -> **動機**: PR #287 の rate-limit 調査で、WP-03 (ADR-019 amendment) のクォータ設計に **2 つの前提ズレ**が判明した。 -> -> **(a) 前提が stale**: `.coderabbit.yaml` 冒頭は「**無料枠レートリミット (3〜4 レビュー/時)** の解除待ちを構造的に削減する」と書かれているが、CR の実際の応答は **`Plan: Pro`**。かつ課金プランのレート制限は固定値ではなく **adaptive per-developer limit** (CR docs: 直近の PR レビュー活動が全ユーザーの 95 パーセンタイル以上に達すると追加レビューの解放が緩やかになる)。**ADR-040 の GPU 前提が stale だった件と同型**で、設計根拠が現状と食い違っている。本件では #276〜#287 の **12 PR を約 24 時間**で投入したことが引き金と強く示唆される (CR 内部カウンタは外部から不可視のため断定はできない)。WP-03 は *PR あたり*のレビュー回数は減らせるが、*developer 単位の rolling window* 枯渇には効かない。 -> -> **(b) レビュー欠落穴**: `auto_incremental_review: false` と「初回レビュー処理中の push」が組み合わさると、**新 head が誰にもレビューされない**状態になる。PR #287 の実際の経緯: 12:44 時点で CR は初回レビューを処理中 (`Currently processing new changes... please wait`) → その直後に手動 push で head 差し替え → 新 head は増分レビュー対象外 (設定どおり) → 初回レビューは宙に浮く → 手動 `@coderabbitai review` が必要になり、そこで rate limit に到達。ADR-019 は「**手動 push 後は `@coderabbitai review` を手動投稿**」(§ 手動 fix push は手動トリガーが必要) と規定しているが、**規約 (人間の記憶) に依存**しており仕組み化されていない。 -> -> **参照**: `.coderabbit.yaml` 冒頭コメント、[ADR-019](adr/adr-019-coderabbit-review-hybrid-policy.md) § WP-03 / § 手動 fix push は手動トリガーが必要、[ADR-051](adr/adr-051-cross-system-config-coupling.md)、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md)、`docs/dev-conventions.md` 順位 262 (外部 SaaS 無料枠 / 制限の調査チェックリスト)、PR #287。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Medium / Effort S。 - -#### 作業計画 - -- [ ] **(a) 前提の是正**: 現行プラン (Pro) と adaptive limit の実態を調査し (`docs/dev-conventions.md` 順位 262 のチェックリストを適用)、`.coderabbit.yaml` 冒頭と ADR-019 § WP-03 の根拠記述を実態に合わせて更新する。**「無料枠 3〜4 レビュー/時」を前提にした設計判断が今も妥当かを再評価する** (adaptive limit なら「PR あたりの削減」より「PR 投入ペース」の方が支配的な可能性)。 -- [ ] **(b) 欠落穴の仕組み化を検討**: 手動 push 後の `@coderabbitai review` 投稿は現状「規約」。ADR-042 の境界基準で仕組み化の是非を判定する。候補: push-runner の push stage 後に「CR 再トリガーが必要」を**警告表示**する (助言層 / fail-open)、または `head_already_reviewed()` を使って未レビュー head を検出し警告する (`review_trigger.rs` に既存の照会ロジックあり)。**自動投稿はレート枠を消費するため慎重に** — ADR-019 § 同一 HEAD への再投稿はレート枠の無駄 と整合させること。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- `.coderabbit.yaml` / ADR-019 のクォータ設計根拠が実プラン・実制限と一致していること。 -- 手動 push で新 head が未レビューのまま放置される経路に、警告または仕組みによる検出があること。 - ---- - -### post-merge-feedback が repo root に scratch script を残し scratch guard をすり抜ける (near-miss 実観測) - -> **動機**: PR #287 のマージ直後 (2026-07-17 22:49)、post-merge-feedback の takt run が **repo root に `analyze_transcript.py` (3.2KB) を作成して残した**。`.takt/post-merge-feedback-transcript.jsonl` を読んで統計を出す一時解析スクリプトで、プロジェクト資産ではない。jj は auto-snapshot するため、**次のコミットに黙って混入する寸前だった** (本エントリを書くセッションで偶然発見。commit 前の `jj status` 確認で気付かなければ backlog PR に混入していた)。 -> -> **なぜ guard が効かないか (構造的問題)**: `push-runner-config.toml` の `[scratch_file_warning]` は `patterns = ["__*", "_tmp_*"]` という **deny-list (pattern 列挙)** で、`analyze_transcript.py` はどちらにも一致しない。PR #85 で実害が出た「scratch ファイル混入」と**同一クラス**だが、当時の対策が「観測された pattern を列挙する」形だったため、**新しい命名の scratch は素通りする**。順位 5 (AI 生成一時スクリプト pattern) で `_tmp_*` を追加した補完アプローチも同じ限界を持つ — **AI が付ける名前を列挙で先回りするのは原理的に不可能**。 -> -> **今回の生成元は自動化コンポーネント**: 人間や interactive Claude ではなく **post-merge-feedback の takt run** (ADR-030) が生成した。ADR-022 (自動化コンポーネントの責務分離) の観点で、**自動化コンポーネントが repo root を汚す**のは責務違反に近い。takt run の作業ファイルは `.takt/runs//` 配下か scratchpad に閉じるべき。 -> -> **検討の方向性 (実装前に判断が要る)**: -> -> - **(a) 生成側を直す (筋が良い)**: post-merge-feedback の instruction facet に「一時スクリプトは repo root に書かない」を明示。ただし instruction = 助言層のため確実性は低い (ADR-042 のルール vs 仕組み化)。 -> - **(b) allow-list 化**: repo root の**追跡外・新規ファイル**を既知の許容リスト以外すべて警告する (deny-list → allow-list の反転)。列挙の限界を構造的に解消できるが、誤検知の運用コストを見積もる必要がある。 -> - **(c) 拡張子/配置ベース**: repo root 直下の `*.py` は本 repo に存在しない (Rust + TS 構成) ため、root の未追跡 `*.py` は高確度で scratch と判定できる。安価だが (b) より弱い。 -> -> **参照**: `push-runner-config.toml` `[scratch_file_warning]`、`src/cli-push-runner/src/stages/scratch_file_warning.rs`、PR #85 (原初の実害)、順位 5 (`_tmp_*` 追加の補完アプローチ)、[ADR-022](adr/adr-022-automation-responsibility-separation.md)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md)、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md)。退避した実物: 本セッションの scratchpad (`analyze_transcript.py`、削除せず保全)。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium (実害は未発生だが near-miss。混入すると PR に無関係ファイルが載り、レビュー・履歴を汚す) / Effort S。 - -#### 作業計画 - -- [ ] **再現確認を先に行う** (§2 原則 2): post-merge-feedback を再実行し、scratch script が repo root に残ることを再現する。再現しない場合は「その run 固有の挙動」の可能性があるため、頻度を見極めてから着手する。 -- [ ] 方向性 (a)(b)(c) を評価して選択する。**(a) 単独は不可** — instruction は助言層で、AI が別の名前で別のファイルを書けば同じことが起きる。(a) + (b または c) の二層が要る。 -- [ ] `scratch_file_warning` の判定を選択した方式で拡張し、**回帰テストは `analyze_transcript.py` を実 fixture として使う** (ADR-049 の incident→eval 流儀。「今回すり抜けた実物」で固定すれば同型の再発を捕まえられる)。 -- [ ] deny-list の限界を `scratch_file_warning.rs` の module doc に記録する (「観測 pattern の列挙では AI 生成の新規命名を先回りできない」= 本件の教訓)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- post-merge-feedback / takt run が repo root に一時ファイルを残した場合に、push 前に検出されること (`analyze_transcript.py` fixture で確認)。 -- 検出方式が「pattern 列挙」に依存しない (新しい命名でも捕まる) こと。 - ---- - -### `lib-subprocess` `run_cmd_shell_*` の timeout が wall-clock を縛れない — 孫プロセス残存で join がブロック (push-pipeline-fix-plan §6 backlog 10 移管) - -> **動機**: T6 (PR #283、diff stage の timeout 追加) の実装中に発見された共有 lib 側の同種欠陥 (push-pipeline-fix-plan §6 backlog 10 から移管。計画ファイルは T99 で削除予定のため要点を本エントリに転記済)。`lib-subprocess` の `run_cmd_shell_with` (= `run_cmd_shell_capped` / `_capped_reporting` / `_unlimited` 3 variant の共通骨格) は timeout 検知後に `child.kill()` → reader thread join するが、`cmd /c ` の**孫プロセス (実際の `cargo` / `jj` 等) は kill 対象外**で pipe の書き込み端を保持し続けるため EOF が来ず、**join が孫の自然終了までブロック**する。実測: `run_cmd_shell_capped` に `timeout_secs = 1` を指定したテストが返るまで 9.23s (`ping -n 10` の自然終了待ち)。既存テストは経過時間を assert しないため素通りしている。 -> -> **影響**: cli-push-runner の quality_gate (`step_timeout = 300`) と push (`timeout = 300`)、cli-merge-pipeline の step 実行 — ハングした `cargo test` / `jj git push` を timeout で打ち切れない (gate のハング保護が実質無効 = ADR-043 fail-closed の空洞化)。**同じ「Windows の `child.kill()` はプロセスツリーを殺せない」根因の実害が 2026-07-17 の post-merge-feedback #286 で発生**: `feedback::run_takt_workflow` の timeout kill (1200s) も descendants を殺せず (`feedback/mod.rs` が PR #78 時点から明記)、orphan takt が kill の約 3 分後に report を完成させたが、reconciliation は kill 直後の 1 回のみのため `.failed` marker が stale に残留。marker 記載の復旧手順 (takt 再実行) は context が後続 PR に上書き済みで誤 PR 分析を誘発する状態だった (2026-07-18 に orphan report の手動 copy で復旧済)。 -> -> **対処案** (§6 backlog 10 の分析より): -> -> - **(a) T6 と同じ「失敗経路では join せず detach」**: 実績ある方式だが、`_capped` 系は表示用出力を捨てることになるためトレードオフの判断が要る (T6 の diff は timeout 時に出力不要だったので単純に採れた)。 -> - **(b) 孫まで殺す (`taskkill /T /F` or Job Object)**: orphan の発生自体を止められるため、post-merge-feedback の stale marker 問題 (上記) にも波及効果がある。Windows 固有実装の複雑さを見積もること。 -> - (b) を採らない場合、`feedback::reconcile_takt_output` の「reconciliation が kill 直後 1 回のみ」の穴 (orphan が後から report を完成させると marker が stale 残留し、以後誰も再チェックしない) への緩和策を別途検討する。 -> -> **参照**: `src/lib-subprocess/src/` (`run_cmd_shell_with`)、`src/cli-merge-pipeline/src/feedback/takt.rs` (`TAKT_TIMEOUT_SECS`) / `feedback/mod.rs` (reconciliation 設計)、T6 実施結果 = PR #283 (経過時間 assert の教訓)、#286 feedback report Tier1 #2 (「優先度を上げて todo 化」推奨)、[ADR-043](adr/adr-043-security-gates-fail-closed.md)、[ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md)。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium-High (ハング保護の実質無効化 + stale marker の実害 1 件観測済) / Effort S。 - -#### 作業計画 - -- [ ] **経過時間 assert 付きの再現テストを先に書く** (T6 の教訓: timeout の回帰テストは Err の内容だけでなく経過時間を assert する。無いと本件は再び素通りする)。 -- [ ] (a) detach vs (b) process-tree kill を評価して選択する。判断は `_capped` 系の出力保全要否と Windows 実装コストの比較で行い、選ばなかった側の理由を `run_cmd_shell_with` の doc に記録する。 -- [ ] 3 variant + 呼び出し元 (cli-push-runner quality_gate / push、cli-merge-pipeline) で回帰確認。サンドボックス実機 E2E は `ping -t` 差し替え + before/after 経過時間比較 (dev-conventions 記載の手法) で行う。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- `timeout_secs = 1` 指定時、孫プロセスが生存していても制御が 1s + ε で戻ること (経過時間 assert で seal)。 -- ハングするコマンド (`ping -t` stub) が quality_gate / push / merge-pipeline の timeout で実際に打ち切られること。 - ---- - -### `cli-pr-monitor::push_to_remote` に push 拒否検知が無く post-PR re-push が無言で失敗し得る (push-pipeline-fix-plan §6 backlog 9 移管) - -> **動機**: T5 (PR #282) の調査で発見された sibling bug (push-pipeline-fix-plan §6 backlog 9 から移管)。jj は新規 bookmark の push 拒否時に **exit 0** を返すことがある (ADR-011 の背景) が、`src/cli-pr-monitor/src/stages/push.rs` の `push_to_remote` は exit code のみで成否判定しており、post-PR の re-push (CodeRabbit 指摘修正後の再 push 等) が**リモート未反映のまま成功扱い**になり得る。T5 が cli-push-runner 側で塞いだ「silent-failure push」= ADR-043 が防ぐ事故そのものと同型の穴。 -> -> **対処**: 出力取得は既に `run_cmd_direct` (全量、truncate 無し) のため、**拒否判定の追加だけ**で済む (T5 と違い truncate 問題は無い)。判定ロジック `push_was_refused` は現在 `cli-push-runner/src/stages/push.rs` の private fn のため、共有化 (lib 移設) か複製かは [ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md) の境界基準 (2nd consumer 出現時の共通化判定) で決める。fail-closed 側に倒す `contains` 判定の根拠は同 fn の doc コメントに恒久化済みで、そのまま踏襲する。 -> -> **参照**: `src/cli-pr-monitor/src/stages/push.rs`、T5 実施結果 = PR #282 (`mod t5_truncated_refusal_detection` 回帰テスト 6 本が参考)、#286 feedback report Tier2 #3 (採用候補)、[ADR-011](adr/adr-011-jj-push-new-bookmark-strategy.md)、[ADR-043](adr/adr-043-security-gates-fail-closed.md)。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium (外部可視の push が無言で未反映になる silent failure。発生は re-push 経路のみ) / Effort XS。 - -#### 作業計画 - -- [ ] 再現テストを先に書く (拒否メッセージ + exit 0 の出力で失敗扱いになることを assert。T5 の回帰テスト群を参考にする)。 -- [ ] `push_was_refused` の共有化可否を ADR-044 基準で判定し、`push_to_remote` に拒否判定を追加する。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 拒否メッセージ + exit 0 の push が `push_to_remote` で失敗として報告されること (回帰テストで seal)。 - ---- - -### 並列設計レビュアー (design-fit reviewer) の実験起案 — 見落とし実績の事前調査付き (R4/ADR-047 却下分析の代替案) - -> **動機**: R4 の ADR-047 採否判定分析 (2026-07-19、[ADR-047](adr/adr-047-prepush-refute-facet.md) 「却下理由の補強」節) から。直列 refute (verify step) は同日導入の [ADR-056](adr/adr-056-review-policy-anomaly-shadow.md) anomaly policy が **inline 反証** (fact-check 義務) として上流で FP を枯らしたため、**26 run で却下 0 件・便益 0** となり却下推奨。これで precision 側 (FP 除去) は ADR-056 が担う体制になったが、**recall 側 (見落とし) は post-PR CodeRabbit 頼みのまま**。一方 reviewers step は並列実行であり、simplicity execute (実測 avg 203s / max 416s) を律速上限として **第 3 の並列レビュアーを wall-clock 追加ゼロで足せる**見込みがある (security execute avg 92s が simplicity の陰に収まっている実績)。観点は「実装内容」ではなく「**設計内容**」— 見落としやすいポイントの指摘・プロジェクト適合性 (ADR / dev-conventions との整合)。 -> -> **重要な区別**: これは反証 (precision フィルタ) の代替ではなく**多視点化 (recall 拡張)**。機能軸が逆であり、「refute の後継」ではなく独立の新実験として評価する。最大リスクは **fix loop 率の再上昇** (現行 8.3% は「finding が減った」直接効果。設計・適合性指摘は anomaly 指摘より主観的で FP を出しやすく、規律なしでは T10 以前の 20〜45% へ逆行し得る)。 -> -> **対処案 (2 phase 構成、Phase 0 必須先行)**: -> -> - **Phase 0 — 需要の実証 (ADR-042 の流儀)**: 「simplicity/security が APPROVE した後に、CodeRabbit または post-merge feedback 分析で初めて検出された**設計起因の見落とし**」の実績数を数える。データソースは実在する 3 系列 — (1) `.claude/feedback-reports/*.md` (post-merge-feedback 蓄積、`.takt/runs` に 54 run 分の生成履歴あり)、(2) merged PR の CodeRabbit resolved threads (`gh api` の reviewThreads で path/body 取得可、PR #294 で手順実証済)、(3) `docs/adr/` の「実害後に塞いだ」記録 (ADR-058 の PR #224 等)。**実績ゼロなら見送り** (negative result は dev-conventions 順位 261 convention で永続化)。あわせて weekly-review ([ADR-031](adr/adr-031-weekly-review-pipeline.md) architecture facet) / post-PR CodeRabbit との役割重複を確認し、並列レビュアーでしか埋まらない穴かを判定する。 -> - **Phase 1 — 実験導入 (Phase 0 で需要が実証された場合のみ、[ADR-039](adr/adr-039-experimental-feature-standard-pattern.md) 3 点セット)**: `pre-push-review.yaml` の reviewers step に design-review sub-step (sonnet) を**並列追加**。規律は ADR-056 と同一 + 追加 1 点 — (a) fact-check 義務 (実コード・実 ADR で検証してから raise)、(b) articulable 要件、(c) [ADR-048](adr/adr-048-facet-findings-handoff-markdown-contract.md) output contract、(d) **指摘には根拠ソース (対象 ADR / dev-conventions / 実コードの file:line) の引用を必須**とし、実データ・実ソースに基づかない speculation を禁止、(e) **blocking にできるのは実害を具体的に示せた場合のみ**、それ以外は non-blocking warning (fix loop 再上昇の抑止)。 -> -> **受け入れ基準 (Phase 1)**: ①採用された設計 finding ≥1 件/実験期間、②fix loop 率が現行 8.3% から有意に悪化しない、③wall-clock が simplicity 律速のまま (design execute ≤ simplicity execute を `scripts/analyze-takt-timings.ps1` で確認 — 別コミットの観測ツール)。計測は R3 の `push-runs-*.jsonl` (総時間・fix 発生) + step 別 timing 抽出で機械的に行う。 -> -> **参照**: [ADR-047](adr/adr-047-prepush-refute-facet.md) §却下理由の補強 (一般反証機構との構成差・本案の出自)、[ADR-056](adr/adr-056-review-policy-anomaly-shadow.md) (inline 反証 = 規律の移植元)、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md) (Phase 0 需要調査の根拠)、`docs/takt-step-timings.md` (step 別実測、別コミット)、[push-pipeline-fix-plan2.md](push-pipeline-fix-plan2.md) R4。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Low〜Medium (現行に実害はない: recall 穴は post-PR CodeRabbit が受けている。改善余地の探索) / Effort: Phase 0 = S、Phase 1 = M (条件付き)。 - -#### 作業計画 - -- [ ] Phase 0: feedback-reports / CodeRabbit resolved threads / ADR 実害記録の 3 系列から「pre-push 通過後に検出された設計起因の見落とし」を集計し、需要の有無を判定する (ゼロなら見送り + negative result 永続化で本エントリ完了)。 -- [ ] Phase 0: weekly-review architecture facet / post-PR CodeRabbit との役割重複を確認し、並列レビュアー固有の担当領域を定義できるか判定する。 -- [ ] Phase 1 (条件付き): design-review facet 作成 + pre-push-review.yaml へ並列追加 (ADR-039 3 点セット、上記規律 (a)〜(e))。 -- [ ] Phase 1 (条件付き): 受け入れ基準 ①〜③ を dogfood で計測し、採否判定を ADR 化する。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- Phase 0 の需要調査結果 (実績数と判定) が記録されていること。見送りなら negative result が dev-conventions convention で永続化されていること。 -- Phase 1 に進んだ場合: design-review が並列で動き、受け入れ基準 ①〜③ の計測データに基づく採否判定が ADR に記録されていること。 - ---- - -### 多段コミットの ADR / observability 更新チェックリストを dev-conventions に追加 (#295/#296 post-merge feedback 採用) - -> **動機**: R4 (ADR-047 却下 / ADR-056 延長) を「判定ドラフト → 却下理由補強 → plan2.md 反映 → 却下確定・撤去 → 観測ツール」と複数コミット・複数 PR に分割して進めた際、齟齬が複数回発生した — (a) timing doc が ADR-047 を「却下」と断定したが該当ブランチの ADR status header は未確定だった (PR #295 の pre-push review が REJECT → fix step が訂正)、(b) timing doc の `docs/takt-step-timings.md` への参照を markdown link にすると中間コミットで cross-ref が壊れるため plain-text に統一する必要があった、(c) ADR status 行と「採否判定」セクションの同期。ADR 58 件超・活発な多段階判定運用の本 repo では同型の反復が見込まれる。#295 と #296 の post-merge feedback がいずれも採用候補と判定。 -> -> **対処案**: `docs/dev-conventions.md` に「多段コミット/多段 PR で ADR・観測 doc を更新するときのチェックリスト」を追加する。項目案: ① doc が外部 ADR の status (試験運用/却下等) に言及する場合は、参照先 ADR の**現行 status header と同期**しているか (未確定を「確定」と書かない)、② 別コミット/別 PR にまたがるファイルへの参照は **markdown link ではなく plain-text パス**にして中間コミットの cross-ref 破壊を避ける (docs-lint cross-ref は markdown link のみ検査)、③ ADR の status 行と「採否判定」セクションの記述を同時更新する。dev-conventions には WP-06/07/08 由来の同種 checklist 先例が複数あり同形式で追加可能。 -> -> **参照**: `.claude/feedback-reports/295.md` Tier3 #2 / `.claude/feedback-reports/296.md` Tier3 #2、`docs/dev-conventions.md`、[ADR-048](adr/adr-048-facet-findings-handoff-markdown-contract.md) (plain-text 参照統一の先例は本 R4 で ADR-047/056 に適用済)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md)。 -> -> **実行優先度**: 🔧 Tier 3 — Severity Low / Frequency Medium / Effort S (doc checklist の追加のみ、機械化はしない)。実害は未観測 (齟齬は各 PR の review / feedback で捕捉できている) のため、より重い自動化 (custom lint / pre-push facet checklist) は再発観測後にエスカレーション。 - -#### 作業計画 - -- [ ] `docs/dev-conventions.md` に上記 3 項目のチェックリストを追加 (WP-06/07/08 の既存 checklist と同形式)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 多段コミットで ADR/observability doc を更新する運用者が、status 同期・plain-text 参照・セクション同期の 3 点を dev-conventions のチェックリストで確認できること。 - ---- - -### post-merge feedback が成功後に `post-merge-feedback-context.json` を残し次マージの feedback を誤 bail させる (cleanup gap、#296 マージで実観測) - -> **動機**: 2026-07-19 の #296 マージで、post_merge_feedback step が「前回の feedback がまだ進行中の可能性 (context.json が 820s 前に書かれた)」と判定して bail し、`.claude/feedback-reports/296.md.failed` marker を残した ([ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) L2 recovery 経路)。原因は **#295 マージの post-merge feedback が正常完了 (295.md 生成) したにもかかわらず自身の `.takt/post-merge-feedback-context.json` を掃除せず残した**こと。約 25 分 (1500s threshold) 以内に次のマージを行うと、前回の leftover context.json を「進行中」と誤判定して feedback が走らない = **連続マージで後発の feedback が構造的に skip される**。今回は手動で context.json 削除 + `--feedback-only 296` で recovery したが、根治は context.json の cleanup。 -> -> **対処案**: post-merge feedback workflow (または cli-merge-pipeline) が feedback の**正常完了時に `post-merge-feedback-context.json` を削除**する。あわせて staleness 判定を「時刻ベース (820s < 1500s)」から「稼働中プロセスの実在確認」等に寄せるか、少なくとも成功時 cleanup で leftover を残さないようにする。fail 時は marker を残す現行 L2 recovery を維持 (真の中断と区別)。 -> -> **参照**: `src/cli-merge-pipeline/src/pipeline.rs` (post_merge_feedback step / context.json の書き出し・cleanup)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) (L1 floor / L2 recovery、marker 運用)、`.takt/post-merge-feedback-context.json`、#296 マージ実観測 (2026-07-19)。 -> -> **実行優先度**: 🚀 Tier 1 — Severity Medium (連続マージで後発 PR の再発防止分析が構造的に skip される。今回は手動 recovery で救済したが、気付かなければ feedback が静かに欠落) / Frequency Low〜Medium (連続マージ運用時) / Effort S (成功時 cleanup の追加)。 - -#### 作業計画 - -- [ ] 再現テスト: leftover context.json がある状態で 2 回目のマージ feedback が誤 bail することを固定 (base_dir 注入等)。 -- [ ] post-merge feedback の**正常完了時に context.json を削除**する (fail 時は marker を残す現行動作を維持)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 連続マージ (前回 feedback 成功後 25 分以内) でも 2 回目の post-merge feedback が leftover context.json で誤 bail せず実行されること (回帰テストで seal)。 - ---- - -### 新規 ADR 起案時の「判断根拠 × 既存 ADR 定義」矛盾チェックリストを追加 (#301 post-merge feedback 採用) - -> **動機**: PR-N3 (#301) で、ADR-055 初版が**自ら定義した `decision` 軸 (block/warn = 発火の重み)** と矛盾する除外根拠 (「nudge は block/warn に乗らない」) を採用しており、本 PR で Amendment を追加して除外根拠を撤回する手戻りが発生した。ADR は既に 59 件超を相互参照しており、新規 ADR が既存 ADR の定義・原則と衝突する見落としは他 ADR でも再発しうる。#301 の post-merge feedback が採用候補と判定 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。 -> -> **対処案**: `CLAUDE.md` または `docs/dev-conventions.md` に「新規 ADR 起案時のチェックリスト」を追加する。項目案: ① ADR が用いる用語・軸 (例 `decision` = 発火の重み) が**既存 ADR の定義と衝突していないか**、② 除外/非除外・採用/却下などの判断根拠が、参照先 ADR が既に定義した原則から**演繹的に導けるか** (別解釈を新設していないか)、③ 衝突が**新規 ADR 初版の誤り**由来なら起案時に初版で解消する。ただし既存 ADR が陳腐化した等で**方針を意図的に変更・supersede する**正当なケースは別扱いとし、Amendment / superseding ADR による明示的更新を妨げない (「初版の誤り」と「既存方針の意図的変更」を区別する項目を設ける)。#327 (多段コミットの ADR/observability 更新チェックリスト) と対をなす doc-only 対処で、同セクションにまとめると発見性が良い。 -> -> **参照**: `.claude/feedback-reports/301.md` Tier3 #1、[ADR-055](adr/adr-055-firing-telemetry-collection.md) (§計装スコープ の `decision` 軸定義と Amendment (2026-07-19) の除外根拠撤回)、`docs/dev-conventions.md`、#327 (関連 checklist)。 -> -> **実行優先度**: 💎 Tier 3 — Severity Medium / Frequency Medium / Effort S (doc checklist のみ、機械化はしない。ADR 相互参照数が多く同型見落としが再発しうるが、実害は各 PR review/feedback で捕捉できているため機械化は再発観測後にエスカレーション)。 - -#### 作業計画 - -- [ ] `CLAUDE.md` または `docs/dev-conventions.md` に上記 3 項目のチェックリストを追加 (#327 と同セクションにまとめる)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 新規 ADR 起案者が、用語・軸の既存 ADR 定義との整合と判断根拠の演繹可能性をチェックリストで確認でき、ADR-055 型の初版自己矛盾 → Amendment 撤回の手戻りを防げること。 - ---- - -### 「行動要求 nudge は 2 チャネル返却」+「多義的戻り値は struct 化」convention の明文化 (#299 post-merge feedback 採用) - -> **動機**: PR-N1 (#299) で、ユーザー行動を要求する nudge (weekly reminder) を `additionalContext` (モデル向け) だけでなく `systemMessage` (ユーザー向け) の 2 チャネルで返す設計 ([ADR-059](adr/adr-059-hook-system-message-visibility.md)) を確立し、その過程で `compute_weekly_review_reminder_nudge` の戻り値を「additional_context + system_message」の struct (`WeeklyReviewNudge`) に変更した。ADR-059 の第2弾展開 (PR monitor catch-up / post-merge recovery / failed marker) で同型パターンの再利用が見込まれる。weekly reminder が 4 週間気付かれなかった実害 (Severity Medium) の再発防止として設計原則を明文化する。#299 の post-merge feedback が採用候補と判定 (Effort XS / Adoption Risk None)。 -> -> **対処案**: `docs/dev-conventions.md` に 2 点を追記する。① **ユーザーの行動を要求する nudge は systemMessage (ユーザー可視) と additionalContext (モデル可視) の 2 チャネルで返す** (ADR-059 の可視化チャネル分離)、② **戻り値が複数の意味役割を持つ場合は tuple/多値 flag ではなく struct 化して役割を命名する** (`WeeklyReviewNudge { additional_context, system_message }` の先例)。 -> -> **参照**: `.claude/feedback-reports/299.md` Tier3 #1、[ADR-059](adr/adr-059-hook-system-message-visibility.md)、`src/hooks-session-start/src/weekly_review.rs` (`WeeklyReviewNudge`)、`docs/dev-conventions.md`。 -> -> **実行優先度**: 💎 Tier 3 — Severity Medium / Frequency Medium / Effort XS (dev-conventions への 1 節追記のみ、ADR-059 第2弾展開で再利用見込み)。 - -#### 作業計画 - -- [ ] `docs/dev-conventions.md` に上記 2 点の convention を追記。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 行動要求 nudge を実装する運用者が、2 チャネル返却と多義的戻り値の struct 化を dev-conventions で確認できること。 - ---- - -### hooks-session-start に systemMessage を含む JSON 出力の exe-spawn E2E テストを追加 (#299 post-merge feedback 採用) - -> **動機**: PR-N1 (#299) で systemMessage 可視化 (ADR-059) を追加したが、テストは `build_session_start_json` の pure function レベルに留まり、**実 config パースを含む exe 実駆動レベルの検証がない** (`src/hooks-session-start/tests/` 自体が未作成)。ADR-059 の第2弾展開で同型の 2 チャネル JSON contract が複製される見込みで、JSON contract の regression を exe レベルで seal する価値がある。#299 の post-merge feedback が採用候補と判定 (Effort S / Adoption Risk None)。 -> -> **対処案**: `src/hooks-session-start/tests/e2e.rs` (新設) に、SessionStart 入力 JSON を stdin で渡して exe を駆動し、`systemMessage` を含む出力 JSON の形状 (systemMessage 有り/無し・additionalContext の nudge 併載) を assert する E2E を追加する。既存の exe-spawn bounded-wait convention ([ADR-049](adr/adr-049-incident-eval-regression-suite.md) `incident_eval.rs`) を踏襲。**注記**: 本 E2E は JSON contract の regression 防止に留まり、Claude Code クライアント UI 側の実描画確認 (ADR-059 削除条件2 / 判定期限 2026-08-16) は代替できないため dogfood 目視は別途必要。 -> -> **参照**: `.claude/feedback-reports/299.md` Tier2 #1、[ADR-059](adr/adr-059-hook-system-message-visibility.md)、[ADR-049](adr/adr-049-incident-eval-regression-suite.md) (exe-spawn E2E 先例)、`src/hooks-session-start/src/main.rs` (`build_session_start_json`)。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Medium / Frequency Medium / Effort S (既存 exe-spawn E2E convention を流用可能、tests/ 新設)。 - -#### 作業計画 - -- [ ] `src/hooks-session-start/tests/e2e.rs` を新設し、実 config + stdin 入力で exe を駆動して systemMessage 有り/無しの JSON 形状を assert。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- 実 config パース込みの exe 駆動で systemMessage を含む JSON contract が regression テストで seal されること (UI 実描画確認は別途 dogfood)。 - ---- - -### `pnpm build:all` 前に git usr/bin (cp.exe) の PATH 未設定を自動検出・追加 (#301 post-merge feedback 採用) - -> **動機**: `pnpm build:all` (及び per-crate `build:*`) は `cp target/release/X.exe .claude/X.exe` で Unix `cp` を使うが、pnpm は Windows で `cmd.exe` 経由で script を実行するため `cp` が解決できず copy step が失敗する (`'cp' is not recognized`)。memory `windows-build-cp-path-gotcha.md` に既記録だが、PR-N3 (#301) の実装でも**再度手動で PATH 追加が必要になった (再発 2 回目)**。ビルド阻害という Severity Medium と再発 Frequency Medium が揃う。#301 の post-merge feedback が採用候補と判定。 -> -> **対処案**: `package.json` の `build:all` (または各 `build:*`) で、Windows のとき git の `usr/bin` (cp.exe 提供) を PATH に前置してから cargo/cp を実行する。Windows 限定の additive な分岐 (他 OS は非該当) とし既存の Unix 動作を変えない。あるいは `cp` を Node の cross-platform copy (`node -e` / `shx` 等) に置換する案も検討。あわせて setup ドキュメントへの明記を補助的に実施。 -> -> **参照**: `.claude/feedback-reports/301.md` Tier1 #2、`package.json` (`build:all` / `build:*` scripts)、memory `windows-build-cp-path-gotcha.md` (既記録・再発)。 -> -> **実行優先度**: 🔧 Tier 2 — Severity Medium (ビルド阻害) / Frequency Medium (再発 2 回目) / Effort S (Windows 限定 if 分岐、他 OS 非影響、Adoption Risk は OS 依存分岐のみ)。 - -#### 作業計画 - -- [ ] `package.json` の build script を Windows で cp.exe を解決できるよう修正: `git.exe` の場所を自動検出 (非標準インストールにも対応) → `usr/bin/cp.exe` の存在確認 → 既存 PATH を保持したまま前置。未検出時は cross-platform copy (`node -e` / `shx` 等) へ fallback するか明確なエラーを出す (silent 失敗にしない)。 -- [ ] setup ドキュメントに前提を明記 (補助)。 -- [ ] 本エントリ削除 + todo-summary.md 行削除。 - -#### 完了基準 - -- クリーンな Windows 環境で `pnpm build:all` が手動 PATH 調整なしに exe を `.claude/` へ配布できること。 -- Git が非標準の場所にインストールされている / `cp.exe` が不在の環境でも、cross-platform copy への fallback か診断可能な明確なエラーで失敗すること (silent 失敗・意味不明な `'cp' is not recognized` で止まらない)。 - ---- - -## 既知課題 (記録のみ、本セッションで未対応) - -(現時点で本ファイルへの既知課題は無し。docs/todo10.md / todo9.md 末尾を参照。) diff --git a/docs/todo14.md b/docs/todo14.md index d9c73c57..b19e8b61 100644 --- a/docs/todo14.md +++ b/docs/todo14.md @@ -2,7 +2,7 @@ > **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイルの位置付け**: docs/todo13.md がファイルサイズ約 171KB (50KB 安定読み取り閾値の約 3.4 倍) に到達したため、新規エントリは本ファイルに記録する (2026-07-19 週次レビュー WR-2026-07-19-T02 採用)。**新規エントリの追加先は本ファイル**。todo.md / todo2.md 〜 todo13.md の既存エントリは引き続き有効、相互に独立。 +> **本ファイルの位置付け**: docs/todo13.md がファイルサイズ約 171KB (50KB 安定読み取り閾値の約 3.4 倍) に到達したため、新規エントリは本ファイルに記録する (2026-07-19 週次レビュー WR-2026-07-19-T02 採用)。**新規エントリの追加先は本ファイル**。todo.md / todo2.md 〜 todo19.md の既存エントリは引き続き有効、相互に独立 (2026-07-20 に todo13.md→todo15/16/17・todo10.md→todo18/19 の物理分割で todo15-19 を新設)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 @@ -25,7 +25,7 @@ - [ ] ターミナル CLI 版 Claude Code で新セッションを起動し systemMessage の描画を確認 (last-run を stale にするか failed marker を置いて reminder を発火させる) - [ ] VSCode 拡張での描画有無・スタイルを確認し CLI との差を切り分け - [ ] 結果を ADR-059 § Dogfood 観測 (2026-07-19) に追記 + 削除条件 2 の可否を判定 -- [ ] 本エントリ削除 + todo-summary.md 行削除 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 #### 完了基準 @@ -47,7 +47,7 @@ - [ ] `.claude/custom-lint-rules.toml` に `docs/todo*.md` 本文の順位番号表記を検出する regex rule を追加 (table 行を除外) - [ ] 既存本文の違反を洗い出し修正 (ADR-033 の grep を流用) -- [ ] 本エントリ削除 + todo-summary.md 行削除 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 #### 完了基準 @@ -69,7 +69,7 @@ - [ ] cli-merge-pipeline の Phase 0 で transcript summary index を生成 (timestamp / message_type / tool_name / outcome) - [ ] session-analysis facet の入力を index に切替 + token 消費が threshold 内に収まることを確認 -- [ ] 本エントリ削除 + todo-summary.md 行削除 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 #### 完了基準 diff --git a/docs/todo15.md b/docs/todo15.md new file mode 100644 index 00000000..1a492393 --- /dev/null +++ b/docs/todo15.md @@ -0,0 +1,595 @@ +# TODO (Part 15) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo13.md がファイルサイズ約 171KB (50KB 安定読み取り閾値の約 3.4 倍) に達したため、順位 248〜296 のエントリを本ファイルに分離した (2026-07-20 docs 50KB 超過解消の物理分割)。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md 〜 todo19.md の既存エントリは引き続き有効、相互に独立。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- +### Gate Function Design Checklist を新規 guide として追加 (fail-closed パターン集) (PR #234 post-merge-feedback T3-1 採用) + +> **動機**: fail-closed 実装の失敗パターンと推奨パターンが複数の ADR / memory に分散しており、新規 gate 実装者が再発させるリスクが高い。PR #234 で `collect_oversize_files` の初版が `.ok()?` で読み取り失敗を握り潰す fail-open bug を含み CodeRabbit Major #234-1 で指摘された。gate 実装の失敗/推奨パターンを 1 箇所に集約する。 +> +> **本タスクの位置づけ**: PR #234 post-merge-feedback Tier 3 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。同 feedback の T1-1 (`filter_map + .ok()?` の linter 化) / T1-2 (TOCTOU linter 化) は false positive 多発リスクで却下推奨となったため、その補完としてドキュメント化が必須。 +> +> **参照**: `.claude/feedback-reports/234.md` Tier 3 #1、`docs/adr/adr-043-security-gates-fail-closed.md` (fail-closed 原則)、順位 249 (ADR-043 コード例追記、相補)、custom lint ⑫ `no-hardcoded-jj-revset-range`。 +> +> **実行優先度**: 💎 **Tier 3** — Effort S。 + +#### 作業計画 + +- [ ] Gate Function Design Checklist を `CLAUDE.md` patterns section または `docs/guides/gate-functions.md` に新設: (1) 判定不能状態は fail-closed、(2) gate 関数内で `filter_map + .ok()?` 禁止、(3) single-pass file access で TOCTOU 回避、(4) iterator chain + `Result::?` idiom で nesting depth 抑制、(5) エラーパスを明示的にテスト +- [ ] ADR-043 (順位 249) との相互リンク +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- fail-closed gate の失敗/推奨パターンが 1 箇所に集約され、新規 gate 実装者が参照して再発を防げる。 + +--- + +### ADR-043 に fail-open vs fail-closed の具体コード例を追記 (PR #234 post-merge-feedback T3-2 採用) + +> **動機**: ADR-043 は security-critical だが具体的なコード例が未記載で、解釈の分散が PR #234 の `.ok()?` fail-open bug を生んだ。`.ok()?` anti-pattern / single-read + `ErrorKind` inspection idiom / multi-step vs 単一操作の比較を ADR 本文に追記し、レビュー時の一貫した判断基準を提供する。 +> +> **本タスクの位置づけ**: PR #234 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。順位 248 (運用チェックリスト) と相補的な決定記録。 +> +> **参照**: `.claude/feedback-reports/234.md` Tier 3 #2、`docs/adr/adr-043-security-gates-fail-closed.md` (追記先)、順位 248 (Gate Function Design Checklist)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort S。 + +#### 作業計画 + +- [ ] ADR-043 に具体コード例 section を追加 (`.ok()?` anti-pattern / single-read + `ErrorKind` idiom / TOCTOU 回避の単一操作) +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- レビュー時に fail-open / fail-closed の判断基準が具体コードで参照でき、解釈の分散が解消される。 + +--- + +### ADR-021 に「jj revset の base branch は config/arg 化 (hardcode 禁止)」を明文化 (PR #234 post-merge-feedback T3-3 採用) + +> **動機**: PR #234 で `[file_length_gate] base` を config 引数化する ADR-021 準拠パターンを実装した (default `master`、`format!("{}..@", base)`)。custom lint ⑫ `no-hardcoded-jj-revset-range` は `.rs` の `master..@` literal を捕捉するが、TOML config / docs / 他ツールへの原則適用は明文化されていない。base branch hardcode 禁止の原則を明文化する。 +> +> **本タスクの位置づけ**: PR #234 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。jj change detection は複数ツールで多用されるため原則の明文化価値がある。 +> +> **参照**: `.claude/feedback-reports/234.md` Tier 3 #3、`docs/adr/adr-021-jj-change-detection-principles.md` (追記先)、custom lint ⑫ `no-hardcoded-jj-revset-range`。 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。 + +#### 作業計画 + +- [ ] ADR-021 (または `CLAUDE.md`) に「jj revset の base branch は config / arg 化し hardcode 禁止」の原則を明文化 (`.rs` / TOML config / docs / 他ツール横断) +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- base branch hardcode 禁止の原則が明文化され、新規 jj 変更検出実装で参照できる。 + +--- + +### ADR-NNN (採番未確定、land 時に確定): 部分効果 env var anti-pattern の文書化 (PR #239 post-merge-feedback T3-1 採用) + +> **動機**: サブコマンドによって効果が異なる env var は「一部のコマンドが成功する」ことで全体が動いていると誤認させ、silent 部分故障を招く。実例 = `GH_REPO` は `gh pr create/merge` には効くが引数なし `gh repo view` には効かず、PR #238 で「マージ成功 / post-merge feedback silent 消失」の部分故障が発生した。`gh-repo-env-guard` preset (PR #239) が GH_REPO 個別には機械防御するが、「なぜ partial coverage が危険か」の原則が未文書化で、同型のショートカット提案 (例: `GH_HOST` 系 env var) を reviewer / implementer が即認識できない。 +> +> **参照**: PR #238 (実害) / PR #239 (preset 実装 + feedback 提案 #1)、ADR-045 § PR 運用時の追加設定、`.claude/hooks-config.toml` gh-repo-env-guard preset。 +> +> **実行優先度**: 💎 Tier 3 — Effort S。Severity Medium + Frequency Medium + Adoption Risk None (PR #239 post-merge-feedback T3-1、ユーザー採用 2026-07-03)。 + +#### 作業計画 + +- [ ] 新 ADR (順位 135 placeholder policy 適用) に「部分効果 env var」anti-pattern を codify: 定義 / PR #238 実例 / 判定基準 (env var による回避策採用時は対象コマンド全系統でのカバレッジ確認を必須化) / 推奨代替 (全系統に効く機構 = GIT_DIR 自動注入型、または明示フラグ) +- [ ] CLAUDE.md の ADR 一覧にリンク追加 (ADR-022 の「CLAUDE.md はリンクに留める」方針に従い本文は ADR 側へ) +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 将来の env var ベースの回避策提案に対し、reviewer / implementer がカバレッジ確認を求める根拠文書が ADR として存在し、CLAUDE.md から辿れること。 + +#### 詰まっている箇所 + +- なし。 + +--- + +### ADR-030 に PR #239 の feedback silent skip 実装記録を追記 (PR #239 post-merge-feedback T3-2 採用) + +> **動機**: 非 colocated jj workspace での owner_repo 検出失敗 → `.failed` marker 未書込 → L2 recovery 未発動という silent skip シナリオ (PR #238 実観測、feedback が recovery 不能なまま消失) と、その対処 (`AiStepContext` enum 化 + `SkipWithMarker` variant + `skip_with_failed_marker()`) を ADR-030 に実装記録として残し、次回同類問題の参照点にする。 +> +> **参照**: PR #238 (実害) / PR #239 (`src/cli-merge-pipeline/src/pipeline.rs` の `AiStepContext::SkipWithMarker`)、ADR-030 (失敗マーカーによる recovery)。 +> +> **実行優先度**: 💎 Tier 3 — Effort XS。Severity Low (既修正) + Frequency Low (PR #239 post-merge-feedback T3-2、ユーザー採用 2026-07-03)。次回 ADR-030 を参照・編集する PR への同乗で消化可。 + +#### 作業計画 + +- [ ] ADR-030 に「owner_repo 検出失敗などの実行前 skip も marker 付き skip とし L2 recovery 対象にする (`AiStepContext::SkipWithMarker`)」の実装記録 sub-section を数行追記 (PR #238 シナリオを inline cite) +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- ADR-030 を読んだ実装者が「feedback の skip 経路はすべて marker を残す」規約を実装記録から把握できること。 + +#### 詰まっている箇所 + +- なし。 + +--- + +### pr_size_check の base を remote tracking ref に変更 — 並列 workspace のローカル master 遅延による誤計測解消 (順位242 push で実観測) + +> **動機**: `push-runner-config.toml` `[pr_size_check]` の `default_branch = "master"` が revset `master..@` のローカル bookmark 基準のため、ADR-045 並列 workspace 運用でローカル `master` (workspace 間共有) が誰にも advance されず遅延していると、過去の merge 済み PR 分を合算して誤計測する。順位 242 の push で実害: 実 diff +123/-35 (~160 行) が「1604 行 > block_threshold 1500」と誤 block され、直前の PR #239/#240 push でも warning 閾値 (800) を静かに誤超過していた。ADR-013 では `sync_local` が「remote tracking ref (`master@origin`) を使い bare local bookmark を使わない」を test で固定済みで、同じ原則を pr_size_check にも適用すべき。 +> +> **参照**: `push-runner-config.toml` `[pr_size_check]`、`src/cli-push-runner` の pr_size_check stage、ADR-013 (sync_local の master@origin 原則 + 固定 test)、ADR-021 / 順位 250 (base branch config/arg 化の明文化、相補)、ADR-045 調整ポイント 2 (ローカル master 共有と遅延の前提)。 +> +> **実行優先度**: 🔧 Tier 2 — Effort XS-S。並列 workspace 運用が続く限り再発する (今回は手動 `jj bookmark set master -r master@origin` で復旧)。 + +#### 作業計画 + +- [ ] `[pr_size_check] default_branch` を `master@origin` に変更 (config 1 行) または pr_size_check 側で remote tracking ref を優先解決する fallback を実装 (着手時に判断、`[file_length_gate] base` も同点検) +- [ ] ローカル master 遅延状態を模した test (revset 解決の単体レベル) を検討 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- ローカル `master` が遅延していても pr_size_check が「master@origin 以降の実 diff」だけを計測すること。 + +#### 詰まっている箇所 + +- なし (根因・復旧手順・実測値あり)。 + +--- + +### ADR-040 の実測値を新 GPU (RTX PRO 5000 48GB) で再 calibration (ADR-046 WP-01 スパイクで陳腐化を観測) + +> **動機**: ADR-038 / ADR-040 は Local LLM の実行環境を **RTX 3070 8GB** として実測値を固定しているが、実機は **NVIDIA RTX PRO 5000 Blackwell 48GB** に更新済み (2026-07-04 に `nvidia-smi` で確認)。この結果、(1) ADR-040 の VRAM/latency trade-off 表 (例: mistral:7b ~2GB at 32K ctx) と (2)「VRAM scarcity → 同時起動不可 / model swap 制約 / KV cache budgeting」という framing が陳腐化した。27-31B Q4 モデルが 100% GPU で動き (qwen3-coder:30b ~21.8GB / gemma4:31b ~20.9GB / gemma4:26b ~17.6GB at num_ctx 32768)、VRAM ではなく latency が実効制約になった。 +> +> **参照**: ADR-040 (Local LLM Context Size、実測値元)、ADR-046 (WP-01 スパイク、4 モデルの VRAM・latency 実測を保持)、ADR-038 (現行 classifier、RTX 3070 前提の記述)、memory `gpu-upgrade-rtx-pro-5000`。 +> +> **実行優先度**: 💎 Tier 3 — Effort S。実装変更を伴わず ADR amendment 中心。分類層 (ADR-038) の運用に直接の不具合はないが、num_ctx 再選定や派生プロジェクト porting 時に誤った RTX 3070 前提を引き継ぐリスクを解消する。 + +#### 作業計画 + +- [ ] ADR-040 に amendment: RTX 3070 8GB の実測表は「旧環境 (historical)」と明示し、新 GPU での再測定値 (ADR-046 の VRAM 実測 + 代表 diff の latency) を追記 +- [ ] 「Context 選定の判断 flow」の memory 軸 (同時起動可否 / swap) を latency 軸へ再重み付け +- [ ] ADR-038 の RTX 3070 前提記述 (§コンテキスト / §帰結の VRAM 8GB 制約) に更新環境への参照を付す +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- ADR-040 を読んだ実装者が、現行 GPU では VRAM が制約でなく latency が実効制約であることを把握でき、RTX 3070 8GB の数値を現行前提と誤認しないこと。 + +#### 詰まっている箇所 + +- なし (GPU 更新の事実・ADR-046 の実測値あり)。 + +--- + +### classifier FP 検出強化プロンプトで格上げ候補を再評価 (WP-04 見送りの follow-up、ADR-038 amendment 由来) + +> **動機**: WP-04 (classifier モデル格上げ) の実測で、mistral:7b からの格上げ候補 (gemma4:12b/26b/31b, qwen3-coder:30b) は **いずれも `false_positive_likely` 検出を改善しなかった** (gold FP 6 件中、正検出は最良 qwen3-coder でも 1 件、全モデルが 3〜4 件を有害な auto_fix に誤分類)。ただし eval で使った `classify.txt` は mistral:7b 向けに tune 済みのため、「FP 検出が能力限界なのか、プロンプト不適合なのか」が未分離。FP 検出を明示的に強化したプロンプト版で候補を再測し、切り分ける。 +> +> **参照**: ADR-038 § classify モデル格上げの評価と見送り (2026-07-05 追記、WP-04)、`src/cli-finding-classifier/prompts/classify.txt`、`src/cli-finding-classifier/src/main.rs` (`--prompt-file` で差し替え可)、WP-04 scratchpad の eval セット (Opus gold 35 件) + ハーネス。ADR-019 § 既知 CodeRabbit FP パターン (キュレート FP 例の出典)。 +> +> **実行優先度**: ⏳ Tier 5 — Effort M。現行 mistral:7b は安全軸完璧・最軽量で運用に支障なく、優先度は低い。materially better な新 local モデル出現時も再評価トリガー。 + +#### 作業計画 + +- [ ] FP 検出強化版 `classify.txt` を作成 (false_positive_likely の positive signal をより明示、Windows 専用/test mock/合成 fixture 等の既知 FP パターンを few-shot 化) +- [ ] WP-04 の Opus gold eval セット (35 件) で qwen3-coder:30b 等を再測、FP recall と human_review 安全軸を確認 +- [ ] 能力限界と確認できれば恒久見送りとして本 entry 削除。プロンプト不適合なら該当モデル + 専用プロンプトで格上げ (ADR-038 の model default 変更 + amendment) +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- FP 検出が「モデル能力限界」か「プロンプト不適合」かが実測で切り分けられ、格上げ採否が結論付けられていること。 + +#### 詰まっている箇所 + +- なし (WP-04 の eval 資産・gold セットあり、プロンプト改訂のみ)。 + +--- + +### push pipeline の `cargo test` を cargo-nextest 化 (WP-05 で Stop hook には無効と判明、push 側 follow-up) + +> **動機**: WP-05 (Stop hook 高速化) の実測で、当初計画の nextest 案は **Stop hook には無効**と判明した (Stop hook は cargo test を実行せず、真因は 7 ステップの逐次実行 → 並列化で解決済、ADR-004 amendment)。一方、**push pipeline (cli-push-runner の quality_gate) は `cargo test -- --ignored --test-threads=1` を実行**しており、実測で ~80s を要する (WP-03 push で観測)。ここは nextest による並列テスト実行で高速化の余地がある。push は Stop hook より低頻度だが、fix→push サイクルの待ち時間に直結する。 +> +> **参照**: `push-runner-config.toml` の `[[quality_gate.groups]]` name=`rust-lint-test`、`src/cli-push-runner` の quality_gate stage、ADR-004 § ステップ並列実行による高速化 (2026-07-05 追記) の scope 外 note、ADR-017 (takt バージョン固定哲学 = nextest 固定の根拠)。 +> +> **実行優先度**: ⏳ Tier 5 — Effort S-M。現行 push は機能上支障なく、優先度は低い。ツール依存追加の費用対効果を要評価。 + +#### 作業計画 + +- [ ] cargo-nextest の導入判断: ツール依存追加 (ADR-017 pinning + `pnpm deploy:hooks` 派生プロジェクト配布) のコスト vs push 高速化の便益を評価 +- [ ] 採用時: `push-runner-config.toml` の `cargo test` step を `cargo nextest run` に置換。**nextest は doctest を実行しないため `cargo test --doc` を併走**させる (doctest 有無を確認: `///` の ` ``` ` を持つ crate) +- [ ] `--ignored` 統合テスト (repush 等) が nextest で正しく実行されることを確認 (nextest の `--run-ignored` フラグ) +- [ ] before/after 実測で push pipeline 時間短縮を確認 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- push pipeline の test 実行時間が短縮され、doctest / `--ignored` 統合テストの網羅性が維持されていること。または費用対効果が見合わないと判断し見送りが記録されていること。 + +#### 詰まっている箇所 + +- なし (WP-05 で Stop 側は完了、push 側の nextest 適用余地とコスト構造は明確)。 + +--- + +### pre-push review-diff.txt の生成形式を jj diff --git に切替 — LLM レビュアーの add/delete 誤読解消 (PR #256 post-merge-feedback Tier1 #1 採用) + +> **動機**: `push-runner-config.toml:113` の `[diff] command = "jj diff -r @"`(jj デフォルト形式)で生成される `.takt/review-diff.txt` は、追加/削除を色 + 行番号2列(`NNN :` = 削除 / ` NNN:` = 追加)で表現する。ファイル化で色が落ちると `-`/`+` マーカーが無くなり、削除が「左列のみ行番号」でしか区別できず、pre-push の LLM レビュアー(simplicity-review 等)が削除ブロックを「追加」と誤読しうる。`--git`(標準 unified diff)は色非依存で `+`/`-` を明示するため誤読しない。PR #256(ADR-051 起票 PR)で todo エントリ25行の**削除**を simplicity-review が「追加」と誤読し stale-tracking-entry として false positive REJECT を出し、レビュー約19分を浪費した実害が発生した。 +> +> **本タスクの位置づけ**: PR #256 post-merge-feedback Tier1 #1 で採用(他6提案は over-engineering として却下)。fix ステップの「hunk-polarity bug」という診断は不正確で、真因は色を落とした平文 diff の LLM 可読性問題。 +> +> **参照**: `push-runner-config.toml:113`(`command = "jj diff -r @"` → `"jj diff --git -r @"`、修正対象)、`templates/push-runner-config.toml:52`(同様の変更、`pnpm deploy:hooks` で派生プロジェクトに配布されるため**両方修正必須**)、memory `prepush-review-diff-plain-format-misread.md`、PR #256 feedback report (`.claude/feedback-reports/256.md`) Tier1 #1 +> +> **実行優先度**: 🔧 Tier 2 — Effort S。false positive で約19分浪費した実害が既に発生しており、config + template 各1箇所の軽微な修正で再発を防止できる。 + +#### 設計決定 (案) + +- `[diff] command` を `jj diff --git -r @` に変更。本番 config と template の2箇所を同一 PR で修正(template 未修正だと派生プロジェクトに同じ false positive が横展開)。 +- review-diff.txt を format-sensitive に parse する `.rs` 箇所は存在せず(LLM facet が読むのみ)、Adoption Risk None。 + +#### 作業計画 + +- [ ] `push-runner-config.toml:113` を `command = "jj diff --git -r @"` に変更 +- [ ] `templates/push-runner-config.toml:52` も同様に変更 +- [ ] review-diff.txt を参照する箇所(facet instruction / `.rs`)が `--git` 形式で問題ないか確認 +- [ ] dogfood: 削除を含む diff で pre-push review が正しく削除を認識することを確認 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- pre-push review が削除ブロックを「追加」と誤読しなくなり、config + template 両方が `--git` 形式、派生プロジェクトへの横展開も解消。 + +#### 詰まっている箇所 + +- なし(変更箇所・影響範囲とも確定済み、PR #256 feedback report で cross-validation 済み)。 + +--- + +### cli-docs-lint に ADR 重複採番 + CLAUDE.md 索引整合チェック追加 (PR #261 post-merge-feedback T1-#2 採用) + +> **動機**: PR #261 で当方が ADR-052 として起草した ADR が、並行 land した PR #260 の ADR-052 (自律実行境界) と採番衝突し、rebase 時にファイル名 + 本文タイトル + ソース内参照 10+ 箇所の置換が発生した実例。ADR は既に 53 件、並行 PR 開発が常態化しており再発頻度 Medium。現状この衝突を機械検知する層が存在しない (発見は rebase 時の CLAUDE.md conflict 頼み)。 +> +> **チェック内容 (案)**: (a) `docs/adr/adr-NNN-*.md` の同一 NNN 重複検出、(b) CLAUDE.md 索引 ⇔ 実ファイルの対応検証 (索引にあるファイルの存在 / 実ファイルの索引掲載)、(c) ファイル名の NNN ⇔ 本文 H1 タイトル番号の一致。 +> +> **参照**: `.claude/feedback-reports/261.md` Tier 1 #2、`src/cli-docs-lint/src/main.rs` (CheckMode 拡張、preamble / cross-ref / priority-inversion の既存 check-mode dispatch と kill-switch 骨格を流用)、ADR-007 (層の線引き)、ADR-039。 +> +> **関連 (重複ではない)**: 順位 135 (todo8.md、ADR-NNN placeholder policy) は todo entry 側の採番 hardcode を防ぐ「ルール」であり、本 entry は land 済みファイル群の衝突を検知する「仕組み」(ADR-042 の役割分担で相補)。feedback report Tier 2 #2 (ADR sanity テスト新設) は本 entry と目的重複のため却下済み。 +> +> **実行優先度**: 🚀 **Tier 1** — Effort S。既存 cli-docs-lint 骨格の流用で新規 module 1 つ + fixture テスト。 + +#### 作業計画 + +- [ ] `src/cli-docs-lint/src/` に adr_consistency validator module を新設 (check 内容 a/b/c) +- [ ] 既存 CheckMode dispatch / kill-switch 設定に統合 (ADR-039 パターン) +- [ ] fixture テスト: 重複採番 / 索引欠落 / 番号不一致の bad fixture + clean fixture +- [ ] push-runner quality_gate (`pnpm lint:docs`) 経由で発火することを確認 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- ADR 採番衝突・索引不整合・ファイル名/タイトル番号不一致が push 前に決定論的に検出され、PR #261 型の rebase 時大量置換が再発しない構造になっていること。 + +--- + +### 層別テストテンプレート (StubOllama パターン・integration 独立性) の共有化 (PR #265 post-merge-feedback T2-1 採用) + +> **動機**: WP-11 (PR #265、ADR-054) の多層防御実装で、層別テスト戦略の設計に時間を要した。具体的には (a) 空 responses の `StubOllama` で「LLM が呼ばれていないこと」を証明する短絡検証パターン、(b) tempdir + `jj git init` + CwdRestore で実 jj repo を立てる integration テストの独立性パターン、の 2 つを都度設計した。WP-17 (自律化) で classifier / scope guard 層を拡張する際に同種の設計判断が再発する見込み。 +> +> **参照**: `.claude/feedback-reports/265.md` Tier 2 #1、`src/cli-finding-classifier/src/lib.rs` (StubOllama)、`src/cli-pr-monitor/src/stages/scope_guard.rs` (integration パターン)、ADR-041 (test isolation patterns)、ADR-025 (CwdRestore)、ADR-044 (共通化と分離の線引き — shared crate 化の境界判定に適用) +> +> **実行優先度**: 🔧 Tier 2 — Effort M。WP-17 着手前の実施が効果的。 + +#### 作業計画 + +- [ ] 対象パターンの棚卸し (StubOllama / tempdir+jj init+CwdRestore / 層別テストの構成方針) +- [ ] ADR-044 の境界判定で shared test crate 化 or fixture + doc 化を判断 +- [ ] 切り出し + 既存呼び出し側 (cli-finding-classifier / cli-pr-monitor) の移行 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 新しい LLM 系 / jj 統合系のテストが共有テンプレートを参照して層別テストを組める状態になっていること。 + +--- + +### ADR-007 に「コメント配置の意思決定フロー」を追加 (PR #265 post-merge-feedback T3-2 採用) + +> **動機**: PR #265 実装中に `classify_one` (cli-finding-classifier) と `config.rs` (cli-pr-monitor) の 2 箇所で非 doc コメントを書き、Bundle Z comment-lint (#B-α) に block された (同種ミス 2 回 = パターン化の価値あり)。「この説明は doc コメント (`///`) に書くべきか、識別子名 / 関数分割で表現して削除すべきか」の判断フローが未文書化。linter 自動化 (feedback Tier 1 #2) は意味論的判定 = NLP が必要なため却下済みで、本エントリは人間 / AI の判断補助ドキュメントとしての補完。 +> +> **参照**: `.claude/feedback-reports/265.md` Tier 3 #2、`docs/adr/adr-007-custom-linter-layer-boundary.md` (既存 Q1-Q3 判断フロー形式で拡張)、`src/hooks-post-tool-comment-lint-rust` (Bundle Z #B-α) +> +> **実行優先度**: 💎 Tier 3 — Effort S。doc のみ、バッチ PR で消化可。 + +#### 作業計画 + +- [ ] ADR-007 に Q 形式の「コメントを書きたくなったときの配置判断フロー」を追記 (doc コメント / 識別子名 / マーカー付き Why コメントの 3 分岐) +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- コメント配置の判断が ADR-007 の判断フローで一意に決まり、Bundle Z block の手戻りが減ること。 + +--- + +### PR body 配置タイミング規約を dev-conventions に明記 (PR #265 post-merge-feedback T3-3 採用) + +> **動機**: PR #265 の push パイプライン実行中に working copy へ `__pr-body.md` を作成し、jj snapshot 直前の退避で commit 混入をかろうじて回避したヒヤリハットが実発生。混入すると repo 履歴に残る。「PR body は push 完了後に scratchpad で準備し、`pnpm create-pr -- --body-file` に絶対パスで渡す (push 実行中の working copy に置かない)」というタイミング規約が未文書化。 +> +> **参照**: `.claude/feedback-reports/265.md` Tier 3 #3、`docs/dev-conventions.md` (追記先)、ADR-028 (external-output 実行フロー)、`src/cli-pr-monitor/src/stages/create_pr.rs` (--body-file パススルー実装) +> +> **実行優先度**: 💎 Tier 3 — Effort XS。doc のみ、バッチ PR で消化可 (並列安全化 PR の docs への相乗りも可)。 + +#### 作業計画 + +- [ ] dev-conventions.md に PR body 配置タイミング規約を追記 (scratchpad + 絶対パス推奨 / repo 直下 `__` ファイルは push 完了後のみ) +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- PR body ファイルが push パイプラインの snapshot に混入しない手順が規約として参照可能になっていること。 + +--- + + +### config-reading hook の `current_dir()` 解決を検出する lint rule (PR #267 post-merge-feedback T1-1 採用) + +> **動機**: PR #267 で新規 hook (jj-op-verify) が既存 3 hook と異なる `current_dir()` ベースの config 解決を実装し、pre-push simplicity-review が REJECT (`SIM-NEW-jjopverify-cwd-config-L179`、High) → fix step が `current_exe().parent()` へ修正した実例。Bash の cwd drift による silent fail-open (`enabled=false` 扱い) は新規 hook 追加のたびに再発しうる。 +> +> **参照**: `.claude/feedback-reports/267.md` Tier 1 #1、`.claude/custom-lint-rules.toml` (新規ルール)、順位 287 (convention 明文化、同一 PR bundle 推奨) +> +> **実行優先度**: 🚀 Tier 1 — Severity High / Effort S。 + +#### 作業計画 + +- [ ] custom-lint-rules.toml に「hooks-* の .rs で `current_dir()` + `hooks-config.toml` の組合せ」を検出するルール追加 (bad/good fixture + incident 構造) +- [ ] 順位 287 (convention 明文化) を同一 PR で bundle +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- config を cwd 基準で解決する新規 hook が push 前に決定論的に検出されること。 + +--- + +### jj-op-verify の変更系 verb 網羅拡大 (PR #267 post-merge-feedback T1-2 採用) + +> **動機**: 現行の検出対象 (new/describe/abandon/rebase/squash/bookmark 変更系) に `undo` / `restore` / `split` / `bookmark move` / `bookmark track` / `bookmark untrack` が含まれない。特に `jj undo` の検出漏れは lost-update 再発リスクが高く、Operation Verification Checklist 自動化の対象を狭める。 +> +> **参照**: `.claude/feedback-reports/267.md` Tier 1 #2、`src/hooks-post-tool-jj-op-verify/src/main.rs` (match 文)。**拡張時は `expected_op_keyword` を実際の `jj op log` 出力と要照合** +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort M。 + +#### 作業計画 + +- [ ] 各 verb の実際の op description を jj 0.42 実機で確認し keyword map に追加 + テスト +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 変更系 jj 操作の検出網羅率が上がり、`jj undo` 等の op 記録検証が機能すること。 + +--- + +### jj-op-verify の verb 検出を command-boundary に anchor (PR #267 post-merge-feedback T1-3 採用) + +> **動機**: `split_whitespace()` の非 anchored 検出は、commit message 引用符内の `"jj new"` 等で false positive「operation not recorded」を誘発しうる。実装時に accepted risk として一度見送った経緯あり (実害観測 0 件)。採用は「advisory 層の UX 劣化」防止目的で、着手時に実観測状況を再確認すること。 +> +> **参照**: `.claude/feedback-reports/267.md` Tier 1 #3、`src/hooks-post-tool-jj-op-verify/src/main.rs:detect_last_mutating_jj_op`、順位 285 (edge-case テスト、表裏の関係) +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort S。 + +#### 作業計画 + +- [ ] verb 検出をコマンド境界 (`&&` / `;` / `|` / 文頭) anchor に変更 + 引用符内の誤検出テスト +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- commit message 内の jj キーワードで警告が誤発火しないこと。 + +--- + +### stale_check_enabled の TOML パーステスト追加 (PR #267 post-merge-feedback T2-1 採用) + +> **動機**: PR #267 で追加した `StalenessConfig.stale_check_enabled` のパース経路にテストがなく、silent degrade (機能が黙って無効化) のリスク。既存テストへの数行追加で完備できる。 +> +> **参照**: `.claude/feedback-reports/267.md` Tier 2 #1、`src/hooks-session-start/src/hooks_config.rs` の既存パーステスト +> +> **実行優先度**: 🔧 Tier 2 — Effort XS。 + +#### 作業計画 + +- [ ] 既存 fixture に `stale_check_enabled = true` + assert を追加 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 新フィールドのパースが regression test で固定されていること。 + +--- + +### jj keyword を含む commit message の tokenization edge-case テスト (PR #267 post-merge-feedback T2-2 採用) + +> **動機**: 順位 283 (anchor 修正) と表裏。283 の着手有無に関わらず、現行挙動 (既知の限界) を regression test で明示的に固定する価値が独立して残る。 +> +> **参照**: `.claude/feedback-reports/267.md` Tier 2 #2、`src/hooks-post-tool-jj-op-verify/src/main.rs` の tests module +> +> **実行優先度**: 🔧 Tier 2 — Effort S。283 と同一 PR での消化が効率的。 + +#### 作業計画 + +- [ ] `token_detection_ignores_jj_in_message_quotes` 等の edge-case テスト追加 (283 実施後は新挙動を固定) +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- tokenization の既知の限界/修正後挙動がテストで明文化されていること。 + +--- + +### config path 解決の cwd 跨ぎ integration test (PR #267 post-merge-feedback T2-3 採用) + +> **動機**: PR #267 で FIXED 済の `SIM-NEW-jjopverify-cwd-config-L179` は、既存テストが pure parser のみで file-lookup 経路を未カバーだったため混入した。非 repo-root cwd から hook を起動して config が読み込まれることを検証する統合テストは、cwd drift シナリオ (ADR-045 の核心リスク) の re-incident 検知網になる。 +> +> **参照**: `.claude/feedback-reports/267.md` Tier 2 #3、`hooks-post-tool-jj-op-verify` test suite。Adoption Risk: OS 依存 (temp dir / path 形式) +> +> **実行優先度**: 🔧 Tier 2 — Severity High / Effort M。 + +#### 作業計画 + +- [ ] 実 exe spawn + 非 repo-root cwd で config 読込を assert する `#[ignore]` integration test +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- exe-relative 解決の退行が統合テストで検出されること。 + +--- + +### 「config 読み hook は exe-relative 解決必須」convention の明文化 (PR #267 post-merge-feedback T3-1 採用) + +> **動機**: 順位 281 (lint rule) の文書層の補完。ADR-045 (または dev-conventions) と該当 hook の inline comment に規約として明文化する。 +> +> **参照**: `.claude/feedback-reports/267.md` Tier 3 #1。**順位 281 と同一 PR での bundle 実装を推奨** (別作業に切り出す価値は低い) +> +> **実行優先度**: 💎 Tier 3 — Effort XS。 + +#### 作業計画 + +- [ ] 順位 281 の PR に同乗して convention を明文化 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 新規 hook 作成時に参照できる規約が存在し、lint rule (281) と 2 層で防御されていること。 + +--- + +### post-merge feedback の pre-push reports を対象 PR の全 run 集約に拡張 (PR #268 post-merge-feedback T2-1 採用) + +> **動機**: `find_latest_prepush_reports_dir()` は「最新 1 run」のみを feedback の分析ソースにするため、複数回 push した PR では最後の push 分に分析が偏る。PR #267 の feedback でも「参照した pre-push run は WP-11 status 更新 (docs-only の最終 push) のみが対象」という evidence-scope 注記が付いた実観測あり。対象 PR の commit 範囲内の全 pre-push-review run を集約し、`post-merge-feedback-context.json` の `prepush_reports_dir` を配列化、`analyze-prepush-reports.md` facet も複数 dir 対応に更新する。 +> +> **再発・優先度見直し (2026-07-19、#300/#301 feedback)**: PR-N2 (#300) / PR-N3 (#301) の feedback で同型 gap が Severity High で再発。根因は本エントリの集約範囲より上流の **push-runner `[diff]` stage** (`push-runner-config.toml` の `[diff] command = "jj diff -r @"`) が **tip コミットのみ**を AI レビュー用 diff に書き出す点。複数コミットを 1 回の `pnpm push` でまとめて送ると、tip 以外の祖先コミット (例 #300 の `resolve_main_workspace_root()` 実装、#301 の `Cargo.toml`/`main.rs` 変更) が local security/simplicity レビューを一度も経ずに merge される (security-review.md が実 diff と矛盾して "docs-only / No dependency changes" と記載)。**単一 push では pre-push run 自体が 1 回のみ**のため、本エントリの「全 run 集約」だけでは救えない。よって本エントリの実装時に、(a) `[diff]` stage の diff 範囲を `docs_only_routing` と同様に `..@` (PR 範囲) へ拡張し、(b) `bookmark_check.rs` の `@` 非 trunk 祖先が未レビューのまま push される穴 (T8 / PR #280 と同クラス) の検証を併せて行う。`docs_only_routing.rs` の skip 判定は既に `..@` に修正済みだが `[diff]` stage 自体は未修正で非対称。ADR-027 (push-time review を diff-local に限定し範囲外は CodeRabbit backstop) の trade-off 射程が security-review にも及ぶかはユーザー判断待ち。 +> +> **参照**: `.claude/feedback-reports/268.md` Tier 2 #1 / `.claude/feedback-reports/300.md` Tier1 #1 / `.claude/feedback-reports/301.md` Tier1 #1、`src/cli-merge-pipeline/src/feedback/context.rs` (`find_latest_prepush_reports_dir`)、`push-runner-config.toml` (`[diff]` section)、`src/cli-push-runner/src/stages/diff.rs`・`src/cli-push-runner/src/stages/bookmark_check.rs`、`src/cli-push-runner/src/config/docs_only_routing.rs` (既に PR 範囲へ修正済の対照)、`.takt/facets/instructions/analyze-prepush-reports.md`、[ADR-027](adr/adr-027-push-review-simplicity-focus.md) +> +> **実行優先度**: 🚀 Tier 1 — Severity High (review gate の silent 覆域縮小が 3 PR 連続で再発) / Frequency Medium (複数コミットを 1 push する運用で恒常発生) / Effort M。context スキーマ変更 + facet 更新 + `[diff]` stage 修正 + テストを伴うため独立 PR 推奨 (旧 Tier 2 から昇格)。 + +#### 作業計画 + +- [ ] **`[diff]` stage の diff 範囲を `..@` (PR 範囲) に拡張** — 祖先コミットの code 変更も AI レビュー用 diff に含める (`docs_only_routing` の skip 判定と同基準に揃える)。 +- [ ] `bookmark_check.rs` で `@` 非 trunk 祖先が未レビューのまま push される穴を検証・塞ぐ (T8 / PR #280 と同クラス)。 +- [ ] 対象 PR の pre-push run dir を列挙する関数に拡張。時刻範囲のみでの絞り込みは対象外 run の混入・対象 run の欠落を招くため、対象 PR のコミット範囲や関連 bookmark 名など複数の識別根拠を突き合わせて対象 run を判定すること (`.takt/runs/*-pre-push-review`) +- [ ] context json の `prepush_reports_dir` を配列化 + facet instruction を複数 dir 対応に (スキーマ契約変更のため: 全 reader の列挙 + 旧 string 形式との後方互換 or schema versioning + 空配列時の挙動を明記) +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 複数 push した PR の feedback が、時刻範囲だけでなく対象 PR のコミット範囲等の追加の識別根拠に基づいて集約された、全 pre-push run のレポートを分析対象にすること。 +- 複数コミットを 1 回で push した PR でも、tip 以外の祖先コミットの code 変更が pre-push AI レビュー (security/simplicity) の diff に含まれること (#300/#301 の "docs-only 誤認" が起きないこと)。 +- `bookmark_check` が `..@` の各祖先コミットと pre-push review 証跡を対応付け、いずれかが未レビューなら **fail-closed** で push を拒否すること ([ADR-043](adr/adr-043-security-gates-fail-closed.md))。レビュー済み・未レビュー祖先の両ケースを回帰テストで seal。 + +--- + +### cli-pr-monitor の lock.rs を token 方式の所有権検証へ統一 + +> **動機**: PR #271 で `pipeline_lock.rs` の `Drop` に token ベース所有権検証を追加した (CodeRabbit Major 対応、stale takeover 後に旧プロセスの Drop が新プロセスの lock を誤削除するバグの修正)。`src/cli-pr-monitor/src/lock.rs` の `MonitorLock` の `Drop` (`lock.rs:41-50`) も無条件 `remove_file` で、同型の所有権未検証バグを抱えている。 +> +> **参照**: `src/lib-jj-helpers/src/pipeline_lock.rs` (token 方式の参照実装)、`src/cli-pr-monitor/src/lock.rs:41-50` +> +> **実行優先度**: 🔧 Tier 2 — Effort S-M。 + +#### 作業計画 + +- [ ] `MonitorLock` に token フィールドを追加し、`Drop` を token 一致確認付き削除に変更 (`pipeline_lock.rs` の実装を踏襲) +- [ ] takeover 後に旧 guard の Drop が新 lock を消さないことを確認する regression test 追加 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- `cli-pr-monitor` の lock も stale takeover 後の誤削除が起きないことがテストで保証されていること。 + +--- + +### push-runner の stack push モード (opt-in、YAGNI につき見送り継続) + +> **動機**: `bookmark_check.rs` の `OWN_WORKSPACE_BOOKMARKS_REVSET = "@"` (厳密一致) は、stacked bookmark 運用 (`feature/base` → `feature/api` → `feature/ui` を `@` 先頭で一括 push) では `@` の bookmark だけでは不足するというトレードオフを持つ。現状その運用実績はなく、必要になった時点で明示オプトインの stack push モード (`[push] stack_push` 等) を追加する拡張余地として記録する。 +> +> **参照**: `src/cli-push-runner/src/stages/bookmark_check.rs:39-43` (トレードオフの記述箇所、本エントリを指して「todo 登録済み」と既に言及している) +> +> **実行優先度**: ⏳ Tier 5 (YAGNI、実運用実績なし) — Effort M。 + +#### 作業計画 + +- [ ] stacked bookmark 運用が実際に必要になった時点で `[push] stack_push` config を設計 +- [ ] 実績が出ないまま長期化する場合は close 判断も検討 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- (着手判断待ち) 次のいずれかに至ること: (a) stacked bookmark 運用の実需が生じ opt-in モードが設計・実装される、または (b) 実績が出ないまま長期化し close 判断がなされる。 + +--- + +### jj-op-verify hook の位置づけ再整理 — 並列 workspace 安全化ではなく混線緩和層として再分類 + +> **動機**: `hooks-post-tool-jj-op-verify` は PR #267 / ADR-045 上「並列 workspace 安全化」の一部として位置づけられているが、検知対象 (「op が記録されない」症状) は jj の公式並行モデルでは説明できない (並列操作なら stale working copy エラーか divergent operation heads として op log に残るはず)。実体は出力混線 (Opus 4.8 / Fable 5 モデル起源のシリアライズ不具合、ADR-053 が上流バグと断定済み) の症状検出器であり、並列 workspace 運用の有無とは独立に価値を持つ。「並列対策が完了したので撤去可能」という将来の誤判断を防ぐため、ADR-045 ではなく ADR-053 の枠組みに紐付け直す。 +> +> **参照**: `docs/adr/adr-045-jj-workspace-parallel-sessions.md` § Known operational risks、`docs/adr/adr-053-stop-tool-call-leak-detection.md`、`src/hooks-post-tool-jj-op-verify/src/main.rs` +> +> **実行優先度**: 💎 Tier 3 — Effort S (ドキュメント再整理のみ、hook 実装は変更不要)。 + +#### 作業計画 + +- [ ] ADR-053 に「jj-op-verify hook は tool 実行はされたが結果表示の信頼性が疑わしい型の混線を検知する」旨を追記し、当該 hook への参照を追加 +- [ ] ADR-045 の該当 hook の記述を「並列 workspace 対策」から「混線検知 (副次的に並列 workspace 由来の stale 検出にも有効)」に改める +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 将来のセッションが「並列運用をやめたので jj-op-verify は不要」と誤判断しないよう、ADR 上の位置づけが混線緩和層として明記されていること。 + +--- + +### ADR-045 にコミット消失事故の「並列原因」診断が未検証である旨の注記追加 + +> **動機**: WP-11 作業中に発生した「コミット 2 つ消失」事故は「並列 jj workspace の同時操作が原因」と診断され ADR-045 に記録されたが、この診断は当時の一次証拠 (`jj op log` の実データ) ではなく、post-merge-feedback の `analyze-session` facet による事後の自己分析 (未検証) に依拠している。「op が一切記録されない」という症状は jj の公式並行モデルでは説明できず、混線 (モデル起源のシリアライズ不具合) による状態誤認が真因である可能性の方が技術的に整合する。confirmation bias の記録として、この診断の不確実性を ADR-045 に注記する。 +> +> **参照**: `docs/adr/adr-045-jj-workspace-parallel-sessions.md` § Known operational risks、本セッションの調査 (transcript `ed897a3e-85b5-44d1-a78c-ff23973f207e.jsonl` 系列、独立 subagent 検証) +> +> **実行優先度**: 💎 Tier 3 — Effort XS。 + +#### 作業計画 + +- [ ] ADR-045 の該当事故記述に「並列 workspace 原因説は事後分析による推定であり、一次証拠 (当時の jj op log) には未到達。混線 (モデル起源) が真因である可能性も残る」旨を注記 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- ADR-045 を読む将来のセッションが、この診断を「確定事実」ではなく「未検証の有力仮説」として扱えること。 + +--- + +### Lock stale takeover + Drop の concurrency scenario 拡張テスト (271.md T2-2 採用) + +> **動機**: PR #271 が導入した token-based ownership Drop の前提 (「fresh lock は takeover されない」) を、既存 `concurrent_stale_takeover_only_one_wins` に加え、takeover 後の旧 guard drop までの full cycle を長い operation chain で検証する価値が高い。PR #267 (concurrent checkout 事故) の再発防止網としても機能する。 +> +> **参照**: `.claude/feedback-reports/271.md` Tier 2 #2、`src/lib-jj-helpers/src/pipeline_lock.rs` の tests モジュール +> +> **実行優先度**: 🔧 Tier 2 — Effort M。 + +#### 作業計画 + +- [ ] takeover → 旧 guard drop → 新 guard drop の full cycle を検証するテストを既存テストファイルに追加 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- takeover 後の旧 guard drop が新 lock を誤削除しないことが、長い operation chain のシナリオでも保証されていること。 + diff --git a/docs/todo16.md b/docs/todo16.md new file mode 100644 index 00000000..c2f2fa9d --- /dev/null +++ b/docs/todo16.md @@ -0,0 +1,493 @@ +# TODO (Part 16) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo13.md がファイルサイズ約 171KB (50KB 安定読み取り閾値の約 3.4 倍) に達したため、順位 297〜318 のエントリを本ファイルに分離した (2026-07-20 docs 50KB 超過解消の物理分割)。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md 〜 todo19.md の既存エントリは引き続き有効、相互に独立。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- +### Pipeline 段階間の状態遷移 E2E テスト (271.md T2-3 採用) + +> **動機**: PR #271 で bookmark 検出の revset 厳密化 (`@` 限定) が push-runner の後続 stage の前提と衝突した実例 (simplicity reviewer が `SIM-NEW-bookmark_check-L43` として検出) があった。Stage -1〜Stage 3 の各段階終了後状態と次段階の前提を突合するテストを追加し、bookmark が `@` に遅延した状態遷移を明示的にカバーする。 +> +> **参照**: `.claude/feedback-reports/271.md` Tier 2 #3、`src/cli-push-runner/tests/pipeline_integration_test.rs` (新設) +> +> **実行優先度**: 🔧 Tier 2 — Effort M。 + +#### 作業計画 + +- [ ] `pipeline_integration_test.rs` を新設し、Stage -1〜Stage 3 の状態遷移契約を突合するテストを追加 +- [ ] 既存 `cargo test` 実行に組み込み、独立 CI step は新設しない +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- pipeline stage 間の hidden coupling が regression test で検出可能になっていること。 + +--- + +### token ベース ownership check の convention 化 (271.md T3-1 採用) + +> **動機**: PR #271 で CodeRabbit Major が指摘した「PID は OS によって再利用されうる」という知見は、`lib-jj-helpers` 以外の multi-process coordination コード追加時にも再発しうる pattern。dev-conventions.md に一般化して記載する価値がある。 +> +> **参照**: `.claude/feedback-reports/271.md` Tier 3 #1、`docs/dev-conventions.md` +> +> **実行優先度**: 💎 Tier 3 — Effort S。 + +#### 作業計画 + +- [ ] token ベース ownership check (PID/start_unix 回避) の convention を `docs/dev-conventions.md` に追記 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 将来 multi-process coordination コードを書く際に参照できる convention が存在すること。 + +--- + +### revset で workspace 所有権を判定できない旨の convention 明記 (271.md T3-2 採用) + +> **動機**: `bookmark_check.rs` の `@` 厳密一致方式 (revset による所有権推定を諦める設計判断) は、将来の jj 運用で参照価値が高い negative result。「共有履歴上の bookmark は他 workspace のものが混ざりうる」旨を project-specific convention として `CLAUDE.md` に追記する。 +> +> **参照**: `.claude/feedback-reports/271.md` Tier 3 #2、`CLAUDE.md` +> +> **実行優先度**: 💎 Tier 3 — Effort XS。 + +#### 作業計画 + +- [ ] `CLAUDE.md` に「revset だけでは workspace 所有権を判定できない」旨と `@` 厳密一致の設計判断を追記 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 将来のセッションが同種の revset ベース所有権判定を再提案しないよう、negative result が明文化されていること。 + +--- + +### Push pipeline 段階間依存性チェック項目の追加 (271.md T3-3 採用) + +> **動機**: PR #271 の hidden coupling incident (revset 厳密化が Stage 3 の前提と衝突) から得た教訓を恒久化する。Pipeline stage 修正時に「この stage の変更が後続 stage の前提を破らないか」を確認する convention を明文化する。 +> +> **参照**: `.claude/feedback-reports/271.md` Tier 3 #3、`CLAUDE.md` / `docs/dev-conventions.md` +> +> **実行優先度**: 💎 Tier 3 — Effort S。 + +#### 作業計画 + +- [ ] `CLAUDE.md` または `docs/dev-conventions.md` に pipeline stage 修正時の段階間依存性チェック項目を追加 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- Pipeline stage 修正時のレビュー観点として、段階間依存性チェックが明文化されていること。 + +--- + +### TOCTOU (remove+create_new) パターン検出 lint rule — exclusive lock 実装限定 (273.md T1-1 採用) + +> **動機**: PR #273 の二重 Acquired バグ (`remove_file` 直前の状態再検証欠落) は data integrity violation の根本原因だった。`remove_file` の直前に安全性を示す justification コメントが無い exclusive lock 実装を検出する custom lint rule (rule⑩ `no-write-result-discard` と同型の comment-presence 検出) を追加する。 +> +> **重要な scope 限定**: `cli-pr-monitor/src/lock.rs` の `MonitorLock` は `std::fs::write` overwrite 方式 + 「stale takeover の race は benign」という設計判断をコメントで既に明示済みであり、本 rule の対象外とすべき (混同すると誤検出になる)。paths を `pipeline_lock.rs` 等の exclusive-lock 実装ファイルに限定して実装すること。 +> +> **既知の限界と過去の関連判断**: 271.md Tier 1 #1 (「Concurrent guard (Drop) の無条件リソース削除検出」regex 検出) は「regex では検証済み/未検証を区別できず ADR-007 の regex 層限界に抵触する」という理由で**既に却下済み**。本エントリの単純な comment-presence 検出も同じ限界 (justification コメントさえあれば実際の再検証コードが無くても通過してしまう) を抱える。CodeRabbit re-review (PR #274) 指摘によりこの限界が具体化したため、下記のとおり検出粒度を「コメント有無」から「再読込→比較→remove_file という 3 ステップの出現順序」の regex/pattern 検出へ強化する (AST 層への格上げは Effort M 相当となり本エントリの Effort S を超えるため、まずは pattern 検出の強化で対応し、それでも false negative が実運用で頻発する場合に AST 層格上げを再検討する)。 +> +> **参照**: `.claude/feedback-reports/273.md` Tier 1 #1、`.claude/feedback-reports/271.md` Tier 1 #1 (関連する過去の却下判断)、`src/lib-jj-helpers/src/pipeline_lock.rs` (今回の fix)、`.claude/custom-lint-rules.toml` +> +> **実行優先度**: 🚀 Tier 1 — Severity High / Effort S。 + +#### 作業計画 + +- [ ] `.claude/custom-lint-rules.toml` に「`remove_file` 呼び出し directly 手前の N 行以内に、読込 (`read_to_string` 等) → 比較 (`==`/`if let` 等) の出現順序があること」を要求する pattern 検出ルールを追加 (単純な comment-presence ではなく構造的な出現順序を見る、paths を exclusive-lock 実装限定) +- [ ] `cli-pr-monitor/src/lock.rs` を誤検出しないことを確認する negative fixture 追加 +- [ ] 「justification コメントはあるが再読込・比較コードが無い」ケースが lint により検出される (= コメントのみでは通過しない) ことを示す negative fixture を追加 +- [ ] lint 検出時に CODE REVIEW で「lock safety pattern verified」を人手確認する運用を `docs/dev-conventions.md` に明文化し、本 rule の false negative となりうるケース (カバレッジ限界) を rule 定義コメントに記録 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 「読込→比較→remove_file」という構造そのものを欠く新規 exclusive lock 実装が、lint rule (pattern 検出) により push 前に検出されること。 +- 「justification コメントのみで再検証コードを欠く」実装が、コメントの存在にかかわらず lint で検出される (= 通過しない) ことが negative fixture で証明されていること。 +- 上記 pattern 検出にも false negative となりうるケースが残るため、lint 検出時に CODE REVIEW で「lock safety pattern verified」であることを人手確認する運用が明文化されていること、かつ本 rule のカバレッジ限界が記録されていること。 + +--- + +### `takeover_stale_lock_skips_remove_when_snapshot_is_stale` パターンを deterministic concurrency test テンプレートとして記録 (273.md T2-3 採用) + +> **動機**: PR #273 で追加した決定論的 regression test (`stale_snapshot` を意図的に不一致にして takeover レースを注入的に再現するパターン) は、実スレッドタイミングに依存する flaky test (`concurrent_stale_takeover_only_one_wins`) より再現性が高い。次の並行処理系 PR で同型テストが必要になった際のテンプレートとして記録する。 +> +> **参照**: `.claude/feedback-reports/273.md` Tier 2 #3、`src/lib-jj-helpers/src/pipeline_lock.rs` の `takeover_stale_lock_skips_remove_when_snapshot_is_stale` +> +> **実行優先度**: 💎 Tier 3 — Effort XS。 + +#### 作業計画 + +- [ ] `docs/dev-conventions.md` に「並行処理の regression test は実スレッドレースより、内部関数を直接呼び状態不一致を注入する決定論的パターンを優先する」旨とコード例を追記 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 次の並行処理系バグ修正で、決定論的テストパターンが参照可能な形で存在すること。 + +--- + +### Advisory lock (fail-open) の TOCTOU window 許容可否を明示コメントで残す設計チェックリスト (273.md T3-1 採用) + +> **動機**: `cli-pr-monitor/src/lock.rs` の `MonitorLock` は「stale takeover の race は benign」という判断を既にコメントで明示済みだが、これは実践のみでチェックリスト化されていない。既に実践されている practice を明文化すれば、将来の advisory lock 実装での判断ミス (許容可否を検討せず TOCTOU を放置する、あるいは過剰に厳格化する) を構造的に防止できる。 +> +> **参照**: `.claude/feedback-reports/273.md` Tier 3 #1、`src/cli-pr-monitor/src/lock.rs`、`src/lib-jj-helpers/src/pipeline_lock.rs` (takeover_stale_lock の doc comment) +> +> **実行優先度**: 💎 Tier 3 — Effort XS。 + +#### 作業計画 + +- [ ] `docs/dev-conventions.md` に「advisory lock の TOCTOU window に触れる実装は、許容可否の判断根拠を doc comment に残す」チェックリストを追加 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- advisory lock 実装時に参照できるチェックリストが存在すること。 + +--- + +### quality gate 実行中に発見したバグ修正が別 PR に混入した際の `jj split` + `jj rebase` 復旧パターンを記録 (273.md T3-3 採用) + +> **動機**: PR #272 (docs-only) の push 中に quality gate が実行した `cargo test --workspace` で PR #273 相当のバグを発見し、その場で修正した結果 docs コミットに混入した。`jj split` + `jj rebase` で低コストに復旧できた実務パターンを記録する。ADR-045 の並列 workspace リスクとは別種の事故 (単一 session 内の混入) であり、区別して記録する価値がある。 +> +> **参照**: `.claude/feedback-reports/273.md` Tier 3 #3、本セッションの復旧手順 (`jj split -m ... ` → `jj rebase -s -d ` → `jj rebase -s -d master`) +> +> **実行優先度**: 💎 Tier 3 — Effort XS。 + +#### 作業計画 + +- [ ] `docs/dev-conventions.md` に「push/merge パイプライン実行中に無関係なバグを発見・修正した場合、`jj split` で分離し、それぞれ独立した bookmark/PR にする」復旧手順を追記 +- [ ] `jj split`/`jj rebase` は**混入後の事後対応**であり、混在した変更に対して既に実行された quality gate / pre-push review の結果は汚染されている (予防はできていない) ため、分離後は当該結果を破棄し、分離後の各コミット/PR で quality gate / pre-push review を個別に再実行する手順を追記 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 同種の混入が今後発生した際に、参照できる復旧手順が存在すること。 +- 復旧手順に「混在した変更に対する gate 実行結果は無効であり、分離後に各 PR で個別に再実行する」ことが明記されていること (CodeRabbit 指摘: 復旧は予防の代替ではなく、汚染された gate 結果をそのまま信頼してはならない)。 + +--- + +### Metrics violation の pre-existing 判定基準の明文化 (273.md T3-4 採用) + +> **動機**: metrics 系 gate (`file_size_check` / `file_length_gate` 等) が複数稼働中の本リポジトリでは、violation が先行 PR/feature 由来の pre-existing なものか、今回の変更に起因するものかを判定して override する場面が繰り返し発生する。PR #273 では 4 件の violation が PR #271 由来の pre-existing として人手判断で正しく override されたが、判定基準 (対象 revset の選び方・feature 境界の見極め方) が曖昧なまま自動化すると誤判定リスクがある。判定基準の明文化は Tier 2 #5 (自動 exemption 機構) の検討の前提を整える。 +> +> **参照**: `.claude/feedback-reports/273.md` Tier 3 #4、Tier 2 #5、`docs/dev-conventions.md` +> +> **実行優先度**: 💎 Tier 3 — Effort XS。 + +#### 作業計画 + +- [ ] `docs/dev-conventions.md` に「metrics violation が pre-existing と判断する際の判定基準 (対象 revset の選び方、feature 境界の見極め方など)」チェックリストを追加 (基準時点/現時点の計測結果・差分、判定理由、判定者・判定日時、レビュー承認者を記録する audit trail 要件を含み、証跡が揃わない場合は override 不可とする) +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- metrics 系 gate の violation を pre-existing として override する際に、判断根拠として参照できる基準が存在すること。 +- 上記基準に加え、override 判定時に「基準時点と現時点の計測結果・差分」「pre-existing と判断した理由」「判定者・判定日時」「レビュー承認者」を PR/MR コメントまたは `docs/override-log.md` に記録し、これらの証跡が揃わない限り override できないチェックリストになっていること (同一メトリクスの反復 violation を将来 anomaly として検知できるようにするため)。 + +--- + +### quality gate isolation 機構を見送り、recovery による risk acceptance とした判断の記録 (negative result) (273.md T3-5 採用) + +> **動機**: PR #273 の post-merge-feedback は「quality gate 実行を commit group ごとに isolated working copy で行う構造的防止機構」(Tier 2 #4) を提案したが、Effort L・runner 複雑化という Adoption Risk に見合わず却下した。spike 見送り (negative result) 永続化 convention に従い、この却下判断を記録する。 +> +> **CodeRabbit 指摘 (PR #274) による訂正**: **recovery (`jj split`/`jj rebase` 復旧パターン) は isolation (予防) の代替にはならない。** isolation は「混入自体を未然に防ぐ」機構であり、recovery は「混入が起きたことを検知した後に事後対応する」機構であって、両者は異なるリスク層に属する。isolation を見送った真の判断は「recovery で同等の予防効果が得られる」ではなく、「混入は今後も起こりうるが、発生時の recovery コストが低いため、isolation 実装コスト (Effort L) をかけてまで予防する必要はないと risk acceptance した」という判断である。 +> +> **参照**: `.claude/feedback-reports/273.md` Tier 2 #4 (却下 recommendation)、Tier 3 #5、docs/dev-conventions.md § spike 見送り (negative result) 永続化 convention、`jj split`/`jj rebase` 復旧パターンを記録するタスク (本ファイル内) +> +> **実行優先度**: 💎 Tier 3 — Effort S。 + +#### 作業計画 + +- [ ] 関連 ADR (ADR-045 または新規 amendment) に、isolation 機構を見送り、recovery コストの低さを理由に risk acceptance した判断を negative result として記録する。「recovery が isolation の代替になる」という表現は用いない +- [ ] 記録には「isolation を見送ったことで残る予防機能の欠如 (混在した変更に対して quality gate / pre-push review が誤って green 判定を出しうる残存リスク)」を明記する +- [ ] 記録には再検討条件 (例: 同種の混入事故が反復する、isolation の実装コストが下がる、等) を明記する +- [ ] `docs/todo-summary.md` の本エントリ行の説明も「代替」ではなく「recovery コストの低さによる risk acceptance」と表現する +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 将来の再検討時に、この見送り判断の根拠が参照可能であること。 +- 記録が「recovery は isolation の代替である」という誤解を招く表現になっておらず、予防機能の欠如という残存リスクと、再検討条件が明記されていること。 + +--- + + + + +### WP-12 step 2: 発火テレメトリ ROI 棚卸し pre-step (28 日 warm-up 後着手) + +> **動機**: WP-12 step 1 ([ADR-055](adr/adr-055-firing-telemetry-collection.md)) で `lib-telemetry` が `.claude/telemetry/firings-*.jsonl` に発火を収集し始めた。その実データを使って「直近 28 日で発火 0 の rule/preset/hook」を削除候補として機械抽出し、ハーネス複雑度の維持判断を発火実績で機械化する (WP-12 の本来目的)。 +> +> **本タスクの位置づけ**: WP-12 step 1 の後続 PR。**着手条件 = step 1 マージから 28 日経過** (warm-up。それ以前は全項目が発火 0 = データ無しになり削除候補判定が無意味)。 +> +> **参照**: [ADR-055](adr/adr-055-firing-telemetry-collection.md) (収集層)、[ADR-031](adr/adr-031-weekly-review-pipeline.md) (棚卸しの出力先 = weekly-review)、`.takt/facets/instructions/file-length-watchlist.md` (同型の「機械層」pre-step = takt facet + Bash パターン)、`.takt/facets/instructions/aggregate-weekly.md` (`### File Length Watchlist (機械的観測)` セクションの隣に発火統計セクションを追加)、[ADR-049](adr/adr-049-incident-eval-regression-suite.md) (incident 由来ルールは発火 0 でも維持推奨の区別)。 +> +> **実行優先度**: 🔧 Tier 2 — Effort M。step 1 の投資回収に必須だが warm-up 待ちのため即着手不可。 + +#### 設計決定 (案) + +- **集計は Rust exe** (ヒアリング確定)。`firings-*.jsonl` を glob 走査し、rule/preset/hook ごとに直近 28 日の発火数を集計する `cli-*` exe (または既存 crate のサブコマンド)。全 rule/preset/hook の一覧 (custom-lint-rules.toml / preset レジストリ / hook レジストリ) との差分で「発火 0 の項目」を導出する。 +- **takt facet + Bash で weekly-review に接続**。file-length-watchlist と同型で、facet の Bash step が集計 exe を呼び watchlist markdown を出力 → aggregate-weekly が `### 発火統計 (機械的観測)` セクションとして転載する。 +- **incident 由来ルールの区別**: `custom-lint-rules.toml` の `[rules.incident]` を持つルールは発火 0 でも「抑止力として維持推奨」とし、非 incident ルールのみ削除候補にする (ADR-049 の思想)。 +- **warm-up 表示**: 収集開始日から 28 日未満の項目は「観測期間中・判定保留」と出力し、誤って削除候補に出さない。 + +#### 作業計画 + +- [ ] 集計 Rust exe を実装 (28 日窓の発火数集計 + 全項目レジストリとの差分 + incident 区別 + warm-up 判定)。ユニットテストで固定 JSONL fixture から集計値を assert。 +- [ ] takt facet (`file-length-watchlist.md` 同型) を新設し weekly-review.yaml の reviewers parallel block に追加。 +- [ ] aggregate-weekly.md に `### 発火統計 (機械的観測)` セクション転載を追加。 +- [ ] dogfood: 週次レビューレポートに発火統計セクションが出力され、初回実行で削除候補 (または全維持の根拠) が特定されることを確認。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + [harness-improvement-plan.md](harness-improvement-plan.md) の WP-12 状態更新 (step 2 消化)。 + +#### 完了基準 + +- 週次レビューレポートに発火統計セクションが出力され、直近 28 日で発火 0 の rule/preset/hook が (incident 由来を除いて) 削除候補として、または全維持の根拠とともに特定されること。 + +--- + +### WP-12 step 3: ADR-039 bounded lifetime 判定の発火数機械化 (step 2 に依存) + +> **動機**: ADR-039 の試験運用機能の卒業/廃止判定は現状「手動で観測値を閾値照合」する方式で、機械集計機構が無い。WP-12 step 2 で発火数の集計基盤ができるので、これを使って「試験運用 ADR の機構が N 日発火 0 → 卒業 (廃止 or 本採用) の検討を promote」を機械化する。 +> +> **本タスクの位置づけ**: WP-12 step 3。**step 2 (集計基盤) に依存**。step 2 完了後に着手。 +> +> **参照**: [ADR-039](adr/adr-039-experimental-feature-standard-pattern.md) (§ 3 bounded lifetime、現状は手動 3 値判定)、[ADR-055](adr/adr-055-firing-telemetry-collection.md) (収集層)、WP-12 step 2 (集計基盤、本ファイル内)。 +> +> **実行優先度**: 💎 Tier 3 — Effort S。step 2 の集計結果に卒業/廃止判定ロジックを重ねる薄い層。 + +#### 作業計画 + +- [ ] step 2 の集計出力に「試験運用 ADR の機構ごとの発火数 + bounded lifetime 期限との照合」を追加し、卒業/廃止の検討を promote する判定を機械化する。 +- [ ] ADR-039 に「bounded lifetime 判定の発火数機械化」を amendment として記録。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除 + harness-improvement-plan.md の WP-12 状態更新 (step 3 消化 = WP-12 完了)。 + +#### 完了基準 + +- 試験運用機能の卒業/廃止検討が発火数に基づいて週次で自動 promote され、ADR-039 の手動閾値照合が機械化されること。 + +--- + +### telemetry の block 記録を実 quality 違反に限定(infra エラー混入の除外)(275.md T1-1 採用) + +> **動機**: CodeRabbit Major 指摘。`emit_block` / `record_*_firing` が品質違反だけでなく fail-closed の infra エラー(stdin 読込失敗 / JSON parse 失敗)でも発火を記録する。ADR-055 では「hook が block を emit した総数」として意図的にこの設計にしたが、WP-12 の ROI 棚卸し(発火数で hook 維持を判断)では infra エラー混入が発火数を歪めるため、実 quality 違反パス(`block_on_failures` 等)限定に絞り込む方が信号が正確になる。 +> +> **重要**: これは ADR-055 で「意図的」と記録した判断の見直しであり、実装時は ADR-055 の該当記述(emit 総数の定義)も併せて amendment する。3 hook 横断(hooks-stop-quality / hooks-stop-tool-call-leak / hooks-pre-tool-validate)のため実装は分割 PR 推奨。stop-tool-call-leak は実 leak でのみ emit_block を呼ぶため既に実質限定されている点も確認する。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 1 #1、`src/hooks-stop-quality/src/main.rs`(`emit_block` / `record_block_firing`)、[ADR-055](adr/adr-055-firing-telemetry-collection.md) § 計装スコープ、WP-12 step 2(順位 307、集計精度の前提)。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort M。 + +#### 作業計画 + +- [ ] 各 hook の記録呼び出しを実 quality 違反パス限定に移動(infra エラー経路では記録しない)。record 位置の見直し。 +- [ ] [ADR-055](adr/adr-055-firing-telemetry-collection.md) の「emit 総数」定義を amendment(実 violation 限定に方針変更した根拠を記録)。 +- [ ] 各 hook のユニットテストで「infra エラー経路では telemetry を記録しない」ことを検証。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- telemetry の block 記録が実 quality 違反に限定され、infra エラー(stdin/parse 失敗)では記録されないことがテストで保証され、ADR-055 の定義も整合していること。 + +--- + +### custom-regex preset の生 regex が telemetry id に流れる privacy footgun の是正(非ブロッキング follow-up 統合)(275.md T1-2 採用) + +> **動機**: PR #275 の pre-push simplicity review 非ブロッキング warning(= セッション中に検出された「非ブロッキング follow-up」)。`tag_source(name, ...)` の `name` が named preset 名でなく `blocked_patterns` の生正規表現文字列の場合、その regex テキストがそのまま telemetry の `id` フィールドに載り、ADR-055 の「コマンド本文・内容は非記録」プライバシー原則と緊張する。現行 `hooks-config.toml` は named preset のみのため**非発火**だが、派生プロジェクトが raw-regex エントリを足すと該当する latent footgun。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 1 #2、`src/hooks-pre-tool-validate/src/blocked_patterns.rs`(`tag_source`)、`src/hooks-pre-tool-validate/src/handlers.rs`(`record_preset_block`)、[ADR-055](adr/adr-055-firing-telemetry-collection.md) § プライバシー。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort S。 + +#### 作業計画 + +- [ ] custom-regex fallback branch では `source` を合成 id(例 `"custom-block"`)に正規化し、生 regex を telemetry id に載せない。 +- [ ] hooks-config パース時に raw-regex な `blocked_patterns` エントリを検出したら警告する config validation を追加(任意)。 +- [ ] [ADR-055](adr/adr-055-firing-telemetry-collection.md) に「Configuration-Driven Privacy Risks(custom config 変更時のプライバシー implications、派生プロジェクトの責務)」セクションを追記。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- custom-regex な `blocked_patterns` を設定しても生 regex 文字列が telemetry `id` に記録されず、ADR-055 のプライバシー原則が config 由来入力に対しても保たれること。 + +--- + +### 逐語的関数複製(3+ コピー)を pre-push 検出する DRY lint rule (275.md T1-3 採用) + +> **動機**: PR #275 で `is_truthy` が `lib-telemetry` / `hooks-post-tool-comment-lint-rust` / `hooks-stop-tool-call-leak` の 3 crate に逐語一致で存在していた(simplicity review が検出 → fix loop が `lib_telemetry::is_truthy` へ統一)。ADR-007 の regex 層に「同一関数コピーが threshold(3+)を超える」ことを検出するルールを追加すれば、次回同型の DRY を pre-push 段階で先回り検出できる。 +> +> **注意**: regex 層の限界(意味的同一性は検出できない)があるため、まず「逐語一致コピー」に限定した pattern 検出とし、false positive を避ける。より網羅的な依存グラフ型検出は様子見(275.md Tier 2 #2)。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 1 #3、`.claude/custom-lint-rules.toml`、[ADR-007](adr/adr-007-custom-linter-layer-boundary.md)。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium / Effort M。 + +#### 作業計画 + +- [ ] workspace 内で同一シグネチャ/本体の関数が 3+ 箇所に逐語一致で存在することを検出する仕組みを追加(custom lint rule または xtask)。 +- [ ] good/bad fixture 追加(順位 313 = ADR-049 incident fixture と抱き合わせ)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 同一関数が 3+ 箇所に逐語複製された状態が push 前に検出され、共有化を促すこと。 + +--- + +### `.claude/telemetry/` の per-pid×日次 partition ファイルの retention/cleanup (275.md T2-1 採用) + +> **動機**: WP-12 step 1 の Windows 並行安全性設計(per-pid × 日次 partition)は warm-up 期間中に小さな `firings-*.jsonl` を多数蓄積する。28 日超過分を削除する retention/cleanup を入れる。WP-12 step 2(集計 pre-step)の前提作業。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 2 #1、`src/lib-telemetry/src/lib.rs`、WP-12 step 2(順位 307)。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Medium / Effort M。**着手条件 = WP-12 step 2 と同時期(step 1 マージから 28 日後、2026-08-12 頃)**。 + +#### 作業計画 + +- [ ] `lib-telemetry` に retention ロジック(N 日超過の firings ファイル削除)を追加、ユニットテスト。 +- [ ] WP-12 step 2 の集計 pre-step と統合(順位 307 と同一 PR 消化が自然)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 28 日を超えた telemetry partition ファイルが自動削除され、warm-up 蓄積が bounded であること。 + +--- + +### `is_truthy` 三重複製を ADR-049 incident suite の fixture として記録 (275.md T2-4 採用) + +> **動機**: PR #275 の `is_truthy` 三重複製を [ADR-049](adr/adr-049-incident-eval-regression-suite.md) の「カスタムルールの由来 incident 再現テスト」convention に沿って fixture 化する。順位 311(DRY lint rule)実装時に good/bad fixture として抱き合わせるのが自然。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 2 #4、[ADR-049](adr/adr-049-incident-eval-regression-suite.md)、順位 311(DRY lint rule)。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Low / Effort XS。 + +#### 作業計画 + +- [ ] 順位 311 の DRY lint rule に対する bad fixture(3+ 逐語複製)と good fixture(共有化済み)を incident suite に追加。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- `is_truthy` 型の逐語複製 incident が回帰テストで再現・防止されること。 + +--- + +### bookmark 未作成での push 失敗(exit 7)のエラーメッセージ改善 (275.md T2-5 採用) + +> **動機**: PR #275 のセッションで、新規ブランチの bookmark を作らずに `pnpm push` して exit code 7 で失敗する process friction が実発生した(`jj bookmark create feat/firing-telemetry -r @` を手動実行して再試行)。push-runner の bookmark 自動作成は [ADR-011](adr/adr-011-jj-push-new-bookmark-strategy.md) の「明示的命名で ambiguity を避ける」設計意図と緊張するため対象外とし、**エラーメッセージの改善のみ**を行う(`jj bookmark create -r @` を命名規約とともに具体的に提示)。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 2 #5、`src/cli-push-runner`(bookmark 未検出時のエラー出力)、[ADR-011](adr/adr-011-jj-push-new-bookmark-strategy.md)。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Low / Effort S。 + +#### 作業計画 + +- [ ] push-runner の bookmark 未検出エラーに、推奨命名(`feat/...`)付きの `jj bookmark create -r @` を具体的に提示する。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 新規ブランチで bookmark 未作成のまま push した際、次に打つべきコマンドがエラーメッセージから即座に分かること。 + +--- + +### ADR-055 telemetry の bounded lifetime 期限を config コメントに明記 (275.md T3-1 採用) + +> **動機**: ADR-055 の telemetry は 28 日 warm-up 後に WP-12 step 2/3 で棚卸しする bounded lifetime 機能。運用者が期限を見落とさないよう、具体日付(step 1 マージ 2026-07-16 + 28 日 = 2026-08-12 頃)と todo-summary.md 順位 307/308 へのリンクを `.claude/hooks-config.toml` の `[telemetry]` section コメントに追記する。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 3 #1、`.claude/hooks-config.toml`(`[telemetry]` section)、順位 307/308。 +> +> **実行優先度**: 💎 Tier 3 — Severity Low / Effort XS。 + +#### 作業計画 + +- [ ] `[telemetry]` section コメントに warm-up 期限(2026-08-12 頃)と順位 307/308 を追記。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- config を読んだ運用者が telemetry の棚卸し期限と後続タスクを把握できること。 + +--- + +### ADR-044「2nd consumer で共通化」原則の明確化・判定基準の例示 (275.md T3-2 採用) + +> **動機**: PR #275 で UTC helper では ADR-044 の「2 番目の消費者」トリガを明示的に論じたのに `is_truthy` では同じ規律を見落とすという非対称性が実発生した(現在は統一済み)。「同一シグネチャ/logic の関数は 2nd consumer 時点で共有 crate に切り出す」という判定基準を明示化し、`is_truthy` を case study として記載する。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 3 #2、`CLAUDE.md`、[ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md)。 +> +> **実行優先度**: 💎 Tier 3 — Severity Low / Effort S。順位 317(チェックリスト)と対で実施すると効果的。 + +#### 作業計画 + +- [ ] [ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md) に「When to extract helper to shared crate」判定基準と `is_truthy` case study を追記。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 同一パターンの関数が複数箇所に現れた際の共有化判断基準が参照可能で、is_truthy 型の見落としが再発しにくくなること。 + +--- + +### utility 関数追加前のチェックリスト(workspace grep)(275.md T3-3 採用) + +> **動機**: 順位 316(ADR-044 明確化)と対で、新規 helper 追加時の実務チェックを `docs/dev-conventions.md` に追加する。「新 helper 追加前に workspace 内の類似パターンを grep し、2+ 箇所に既存すれば ADR-044 に従い共有化を検討する」。 +> +> **参照**: `.claude/feedback-reports/275.md` Tier 3 #3、`docs/dev-conventions.md`、順位 316。 +> +> **実行優先度**: 💎 Tier 3 — Severity Low / Effort XS。 + +#### 作業計画 + +- [ ] `docs/dev-conventions.md` のチェックリストに utility 追加前の grep 手順を追記。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 新規 utility 追加時に既存重複を事前確認する手順が明文化されていること。 + +--- + +### CR rate-limit 第3 format 未対応 + marker 一致/regex 不一致の silent 化 (PR #287 実観測) + +> **動機**: PR #287 で CodeRabbit がレビュー上限に達したが、**決定論層 (`check-ci-coderabbit`) が rate-limit を検知できず**、監視は「CodeRabbit: 新規指摘3件 / findings 0 件 / verdict approved」と報告した。ユーザーからは「レートリミットに引っかかっていることが表向き見えなかった」と観測された。 +> +> **根本原因 (実測で特定)**: CR の wait-time 文言が第3 format に変化していた。 +> +> | 判定 | 対象文字列 | 結果 | +> |---|---|---| +> | `is_rate_limit_comment` | `rate limited by coderabbit.ai` (HTML コメント内) | **TRUE** (marker は一致) | +> | `extract_old_format_wait_time` | `Please wait N minutes and M seconds` | 不一致 | +> | `extract_new_format_wait_time` | `More reviews will be available in N minutes` | 不一致 | +> | **実際の文言 (2026-07 観測)** | **`**Next review available in:** **32 minutes**`** | **どの parser も未対応** | +> +> `parse_rate_limit` は `let (minutes, seconds) = extract_wait_time(body)?;` で **None を返して静かに終了**する (`src/check-ci-coderabbit/src/rate_limit.rs`)。結果、rate-limit comment を検出しているのに「rate-limit 無し」と区別が付かない。 +> +> **ADR-034 の予測は当たっていた**: 同 ADR § 既知 CR rate-limit format 一覧 の「HTML マーカー優先 (CR は UI 文言を変えても internal marker は維持する傾向、本リポジトリ未検証)」は、今回 **marker 安定 / UI 文言変化** として実証された。予測は正しかったが、**wait-time regex 側の脆弱性は対策されていなかった**。 +> +> **ADR-034 の troubleshooting が想定する症状と違う**: 同 ADR § 検出 logic 更新手順 は「`is_rate_limit_comment` が常時 false を返す symptom (PR #182 実観測)」を前提に書かれている。今回は **marker 一致 / regex 不一致**という別の失敗モードで、既存の症状記述では発見できない。 +> +> **これは同一クラスの 3 世代目**: 旧 format (~2026 年初) → 新 format (2026-05 / PR #182・#184 で silent regression 実観測) → 第3 format (2026-07 / 本件)。marker は multi-variant 配列化されたが、regex は format 追従のたびに手当てが要る構造のまま。 +> +> **参照**: `src/check-ci-coderabbit/src/rate_limit.rs` (`extract_wait_time` / `parse_rate_limit`)、`src/check-ci-coderabbit/src/markers.rs` (`RATE_LIMIT_MARKERS`)、[ADR-034](adr/adr-034-coderabbit-auto-monitoring.md) § 既知 CR rate-limit format 一覧 / § 検出 logic 更新手順、[ADR-043](adr/adr-043-security-gates-fail-closed.md) (fail-closed)、PR #287。 +> +> **実行優先度**: 🚀 Tier 1 — Severity **High** (監視の false-green を生む) / Effort S。 + +#### 作業計画 + +- [ ] ADR-034 § 検出 logic 更新手順 の step 4: `extract_next_review_format_wait_time` を追加 (`Next review available in:?\**\s*\**(\d+) minutes?` + `and (\d+) seconds?` 併記 variant)。`extract_wait_time` の or_else 連鎖に追加する。 +- [ ] **silent 化の構造的解消 (本エントリの本丸)**: `is_rate_limit_comment == true` かつ `extract_wait_time == None` の組合せを **loud にする**。現状は「marker 一致だが wait time 不明」= 既知の未知 (known-unknown) を `None` に潰して「rate-limit 無し」と同一視している。最低限 warn ログ + 監視側で「rate-limit 検出・待ち時間不明」を報告し、ADR-043 に従い保守的な既定待ち時間 (例: 30 分) で park する案を検討する。**この修正が入れば第4 format が来ても silent regression にはならない** (regex 追加は追従作業に留まる)。 +- [ ] fixture 追加 (step 5): 第3 format の実 body を 2-3 variant。既存 fixture は backward compat のため維持。**回帰テストは「修正前に実際に落ちること」を確認する** (§2 原則 2 / ADR-049)。marker 一致・regex 不一致の silent ケースも 1 本固定する。 +- [ ] ADR-034 § 既知 CR rate-limit format 一覧 table に第3 format 行を append (step 6)。あわせて § 検出 logic 更新手順 の症状記述に「marker 一致 / regex 不一致 (= 常時 None、silent)」を追記する — 現在の記述は marker 失敗のみ想定で本件を発見できない。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 第3 format の rate-limit comment から待ち時間が抽出でき、監視が park 経路に乗ること (fixture + 実 body で確認)。 +- marker 一致 / wait-time 抽出失敗の組合せが silent に握り潰されず、ログまたは報告に現れること。 + diff --git a/docs/todo17.md b/docs/todo17.md new file mode 100644 index 00000000..5279c3cc --- /dev/null +++ b/docs/todo17.md @@ -0,0 +1,359 @@ +# TODO (Part 17) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo13.md がファイルサイズ約 171KB (50KB 安定読み取り閾値の約 3.4 倍) に達したため、順位 319〜332 のエントリを本ファイルに分離した (2026-07-20 docs 50KB 超過解消の物理分割)。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md 〜 todo19.md の既存エントリは引き続き有効、相互に独立。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- +### pr-monitor.yml バックストップの重複ガードが構造的に機能しない (PR #287 実観測) + +> **動機**: PR #287 で「🤖 PR Monitor 分析 (GitHub Actions バックストップ)」が **5 件**投稿された。ユーザーから「1 回投稿すれば十分な情報を、CodeRabbit の投稿に反応して毎回投稿する実装になっていないか」と指摘され、実測で裏付けられた。 +> +> **実測 (すべて CR 投稿の直後に発火)**: +> +> | CR 投稿 | → backstop | 遅延 | +> |---|---|---| +> | 12:42:31 | 12:44:13 | +1m42s | +> | 13:09:32/35 | 13:16:16 | — | +> | 13:16:36 (ack のみ) | 13:18:11 | +1m35s | +> | 13:45:03 (ack のみ) | 13:46:09 | +1m06s | +> | 13:46:25 | **13:49:06** | +2m41s (**マージ 13:48:12 の後**) | +> +> **根本原因**: 重複ガードは存在する (`.github/workflows/pr-monitor.yml` prompt 手順 2) が、**構造的トートロジー**になっている。ガードの skip 条件は「過去の分析コメント以降に**新しいコメント等の変化が無い**場合」。しかし本 workflow の起動トリガーは `issue_comment (created) by coderabbitai[bot]` であり、**発火した時点で必ず「新しいコメント」が存在する**。よって issue_comment 経路で skip 条件は永久に成立しない。 +> +> **証拠 (agent 自身が無価値と認識しつつ投稿している)**: 13:18:11 の投稿本文は「前回分析以降に生じたのは CodeRabbit による定型 acknowledgment コメント 1 件のみで、レビュー実体の追加は無し」と自ら述べている。ガードが「新規コメントの有無」を見ており「分析価値のある新情報か」を見ていないため、ack 1 件でも再分析・再投稿に進む。 +> +> **副次問題**: (a) PR が **MERGED/CLOSED でも投稿する** (13:49:06 はマージ後)。state ガードが無い。(b) 1 投稿あたり claude-code-action (sonnet / max-turns 30) が 1 run 走るため、**Max 枠を無駄に消費**する (workflow 冒頭コメントが挙げる「Max 枠の暴走ガード」の意図に反する)。 +> +> **設計上の含意**: ガードを LLM prompt 側 (助言層) に置いたことが原因。`concurrency` は同時実行を潰すが逐次の再投稿は防げない。ADR-042 (ルール vs 仕組み化の境界基準) の観点では、**決定論層 (workflow の `if:` 条件) に移すべき類**。 +> +> **参照**: `.github/workflows/pr-monitor.yml` (prompt 手順 2 / `on:` / `jobs.analyze.if:` / concurrency)、[ADR-022](adr/adr-022-automation-responsibility-separation.md) 原則 6、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md)、PR #287。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium (機能は壊れないが noise + Max 枠浪費) / Effort S。 + +#### 作業計画 + +- [ ] **決定論ガードを `if:` に追加** (LLM prompt に依存しない層へ移す): + - [ ] CR の **ack / 定型応答コメントを除外**する。`github.event.comment.body` に `` (= ack) が含まれる場合は起動しない。分析価値があるのは walkthrough (``) のみ。**本件の再投稿 5 件中 2 件はこの 1 条件で消える**。 + - [ ] PR が **CLOSED / MERGED なら起動しない** (`github.event.issue.state == 'open'`)。 +- [ ] prompt 手順 2 のガード条件を「**新規コメントの有無**」から「**分析価値のある新情報の有無**」へ書き換える (ack / rate-limit 通知 / 自身の分析コメントは新情報に数えない旨を明示)。決定論ガードを主、prompt ガードを従 (二層目) とする。 +- [ ] 起動条件を変えるため **workflow_dispatch でのスモークテスト**を行い、(a) ack で起動しないこと (b) walkthrough で起動すること (c) merged PR で起動しないこと を実測で確認する。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- CR の walkthrough 更新 1 回につき backstop の投稿が高々 1 件で、ack / マージ後には投稿されないこと (実 PR で確認)。 + +--- + +### CodeRabbit status check は実レビュー有無に関わらず `pass` (PR #287 実観測) + +> **動機**: PR #287 で `gh pr checks 287` が一貫して **`CodeRabbit pass`** を返し続けたが、実際にはレビューが 1 度も実行されていなかった (`pulls/287/reviews` = 0 件、インラインコメント = 0 件)。緑チェックが「レビュー済み」を意味しないことが実観測された。 +> +> **実測した表示の変遷 (いずれも `pass`)**: +> +> | 実態 | checks の表示 | +> |---|---| +> | 増分レビュー skip | `pass` — `Review skipped: incremental reviews are disabled` | +> | **rate limit で未実行** | `pass` — (同上のまま。**本文は `Review limit reached` に更新済みなのに check 行は追従しない**) | +> | レビュー完了 | `pass` — `Review completed` | +> +> **2 つの落とし穴**: +> +> 1. **`pass` は「レビューした」ではなく「CodeRabbit が異常終了しなかった」の意**。skip も rate-limit も pass。緑を根拠に「レビュー通過」と判断すると false-green になる。 +> 2. **check 行の summary は stale になる**。CR は**コメント本文を in-place 更新**する (本件では `updated_at` のみ 13:09:39 に更新) が、check の summary 文字列は更新されない。本セッションでは `Review skipped: incremental reviews are disabled` という古い表示のまま、実態は `Review limit reached` だった。**checks 行だけを見ると誤診する**。 +> +> **正しい判定 source (本件で有効だった順)**: (a) `gh pr view --json reviews` の件数、(b) CR walkthrough 本文の `Configuration used` (`Organization UI` = レビュー未開始の症状 / `Path: .coderabbit.yaml` = 実行された証拠)、(c) 本文の `No actionable comments were generated` / `Review limit reached`。**(b) は本件の診断で決定打になった**。 +> +> **参照**: PR #287 (`Configuration used` が `Organization UI` → `Path: .coderabbit.yaml` に変化)、順位 318 (決定論的 rate-limit 検知)、`.takt/facets/instructions/analyze-coderabbit.md`、`.github/workflows/pr-monitor.yml` prompt 手順 1。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Medium (誤診の温床) / Effort S。 + +#### 作業計画 + +- [ ] `analyze-coderabbit.md` と `pr-monitor.yml` prompt に「**CodeRabbit check の `pass` はレビュー実施の根拠にならない / summary 文字列は stale になり得る**」を明記し、判定 source を上記 (a)(b)(c) に固定する。 +- [ ] `check-ci-coderabbit` に「**レビュー実施の有無**」を `reviews` 件数 + walkthrough marker から判定する関数を追加し、`review_state: success` と実レビュー有無を分離して report する (現状 `review_state` が success でも実体ゼロがあり得る)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 監視の report で「CR check は pass だが実レビューは 0 件」の状態が判別でき、approved と誤って報告されないこと。 + +--- + +### ADR-019/WP-03 クォータ設計の前提 stale + 初回レビュー処理中 push のレビュー欠落穴 + +> **動機**: PR #287 の rate-limit 調査で、WP-03 (ADR-019 amendment) のクォータ設計に **2 つの前提ズレ**が判明した。 +> +> **(a) 前提が stale**: `.coderabbit.yaml` 冒頭は「**無料枠レートリミット (3〜4 レビュー/時)** の解除待ちを構造的に削減する」と書かれているが、CR の実際の応答は **`Plan: Pro`**。かつ課金プランのレート制限は固定値ではなく **adaptive per-developer limit** (CR docs: 直近の PR レビュー活動が全ユーザーの 95 パーセンタイル以上に達すると追加レビューの解放が緩やかになる)。**ADR-040 の GPU 前提が stale だった件と同型**で、設計根拠が現状と食い違っている。本件では #276〜#287 の **12 PR を約 24 時間**で投入したことが引き金と強く示唆される (CR 内部カウンタは外部から不可視のため断定はできない)。WP-03 は *PR あたり*のレビュー回数は減らせるが、*developer 単位の rolling window* 枯渇には効かない。 +> +> **(b) レビュー欠落穴**: `auto_incremental_review: false` と「初回レビュー処理中の push」が組み合わさると、**新 head が誰にもレビューされない**状態になる。PR #287 の実際の経緯: 12:44 時点で CR は初回レビューを処理中 (`Currently processing new changes... please wait`) → その直後に手動 push で head 差し替え → 新 head は増分レビュー対象外 (設定どおり) → 初回レビューは宙に浮く → 手動 `@coderabbitai review` が必要になり、そこで rate limit に到達。ADR-019 は「**手動 push 後は `@coderabbitai review` を手動投稿**」(§ 手動 fix push は手動トリガーが必要) と規定しているが、**規約 (人間の記憶) に依存**しており仕組み化されていない。 +> +> **参照**: `.coderabbit.yaml` 冒頭コメント、[ADR-019](adr/adr-019-coderabbit-review-hybrid-policy.md) § WP-03 / § 手動 fix push は手動トリガーが必要、[ADR-051](adr/adr-051-cross-system-config-coupling.md)、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md)、`docs/dev-conventions.md` 順位 262 (外部 SaaS 無料枠 / 制限の調査チェックリスト)、PR #287。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Medium / Effort S。 + +#### 作業計画 + +- [ ] **(a) 前提の是正**: 現行プラン (Pro) と adaptive limit の実態を調査し (`docs/dev-conventions.md` 順位 262 のチェックリストを適用)、`.coderabbit.yaml` 冒頭と ADR-019 § WP-03 の根拠記述を実態に合わせて更新する。**「無料枠 3〜4 レビュー/時」を前提にした設計判断が今も妥当かを再評価する** (adaptive limit なら「PR あたりの削減」より「PR 投入ペース」の方が支配的な可能性)。 +- [ ] **(b) 欠落穴の仕組み化を検討**: 手動 push 後の `@coderabbitai review` 投稿は現状「規約」。ADR-042 の境界基準で仕組み化の是非を判定する。候補: push-runner の push stage 後に「CR 再トリガーが必要」を**警告表示**する (助言層 / fail-open)、または `head_already_reviewed()` を使って未レビュー head を検出し警告する (`review_trigger.rs` に既存の照会ロジックあり)。**自動投稿はレート枠を消費するため慎重に** — ADR-019 § 同一 HEAD への再投稿はレート枠の無駄 と整合させること。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- `.coderabbit.yaml` / ADR-019 のクォータ設計根拠が実プラン・実制限と一致していること。 +- 手動 push で新 head が未レビューのまま放置される経路に、警告または仕組みによる検出があること。 + +--- + +### post-merge-feedback が repo root に scratch script を残し scratch guard をすり抜ける (near-miss 実観測) + +> **動機**: PR #287 のマージ直後 (2026-07-17 22:49)、post-merge-feedback の takt run が **repo root に `analyze_transcript.py` (3.2KB) を作成して残した**。`.takt/post-merge-feedback-transcript.jsonl` を読んで統計を出す一時解析スクリプトで、プロジェクト資産ではない。jj は auto-snapshot するため、**次のコミットに黙って混入する寸前だった** (本エントリを書くセッションで偶然発見。commit 前の `jj status` 確認で気付かなければ backlog PR に混入していた)。 +> +> **なぜ guard が効かないか (構造的問題)**: `push-runner-config.toml` の `[scratch_file_warning]` は `patterns = ["__*", "_tmp_*"]` という **deny-list (pattern 列挙)** で、`analyze_transcript.py` はどちらにも一致しない。PR #85 で実害が出た「scratch ファイル混入」と**同一クラス**だが、当時の対策が「観測された pattern を列挙する」形だったため、**新しい命名の scratch は素通りする**。順位 5 (AI 生成一時スクリプト pattern) で `_tmp_*` を追加した補完アプローチも同じ限界を持つ — **AI が付ける名前を列挙で先回りするのは原理的に不可能**。 +> +> **今回の生成元は自動化コンポーネント**: 人間や interactive Claude ではなく **post-merge-feedback の takt run** (ADR-030) が生成した。ADR-022 (自動化コンポーネントの責務分離) の観点で、**自動化コンポーネントが repo root を汚す**のは責務違反に近い。takt run の作業ファイルは `.takt/runs//` 配下か scratchpad に閉じるべき。 +> +> **検討の方向性 (実装前に判断が要る)**: +> +> - **(a) 生成側を直す (筋が良い)**: post-merge-feedback の instruction facet に「一時スクリプトは repo root に書かない」を明示。ただし instruction = 助言層のため確実性は低い (ADR-042 のルール vs 仕組み化)。 +> - **(b) allow-list 化**: repo root の**追跡外・新規ファイル**を既知の許容リスト以外すべて警告する (deny-list → allow-list の反転)。列挙の限界を構造的に解消できるが、誤検知の運用コストを見積もる必要がある。 +> - **(c) 拡張子/配置ベース**: repo root 直下の `*.py` は本 repo に存在しない (Rust + TS 構成) ため、root の未追跡 `*.py` は高確度で scratch と判定できる。安価だが (b) より弱い。 +> +> **参照**: `push-runner-config.toml` `[scratch_file_warning]`、`src/cli-push-runner/src/stages/scratch_file_warning.rs`、PR #85 (原初の実害)、順位 5 (`_tmp_*` 追加の補完アプローチ)、[ADR-022](adr/adr-022-automation-responsibility-separation.md)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md)、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md)。退避した実物: 本セッションの scratchpad (`analyze_transcript.py`、削除せず保全)。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium (実害は未発生だが near-miss。混入すると PR に無関係ファイルが載り、レビュー・履歴を汚す) / Effort S。 + +#### 作業計画 + +- [ ] **再現確認を先に行う** (§2 原則 2): post-merge-feedback を再実行し、scratch script が repo root に残ることを再現する。再現しない場合は「その run 固有の挙動」の可能性があるため、頻度を見極めてから着手する。 +- [ ] 方向性 (a)(b)(c) を評価して選択する。**(a) 単独は不可** — instruction は助言層で、AI が別の名前で別のファイルを書けば同じことが起きる。(a) + (b または c) の二層が要る。 +- [ ] `scratch_file_warning` の判定を選択した方式で拡張し、**回帰テストは `analyze_transcript.py` を実 fixture として使う** (ADR-049 の incident→eval 流儀。「今回すり抜けた実物」で固定すれば同型の再発を捕まえられる)。 +- [ ] deny-list の限界を `scratch_file_warning.rs` の module doc に記録する (「観測 pattern の列挙では AI 生成の新規命名を先回りできない」= 本件の教訓)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- post-merge-feedback / takt run が repo root に一時ファイルを残した場合に、push 前に検出されること (`analyze_transcript.py` fixture で確認)。 +- 検出方式が「pattern 列挙」に依存しない (新しい命名でも捕まる) こと。 + +--- + +### `lib-subprocess` `run_cmd_shell_*` の timeout が wall-clock を縛れない — 孫プロセス残存で join がブロック (push-pipeline-fix-plan §6 backlog 10 移管) + +> **動機**: T6 (PR #283、diff stage の timeout 追加) の実装中に発見された共有 lib 側の同種欠陥 (push-pipeline-fix-plan §6 backlog 10 から移管。計画ファイルは T99 で削除予定のため要点を本エントリに転記済)。`lib-subprocess` の `run_cmd_shell_with` (= `run_cmd_shell_capped` / `_capped_reporting` / `_unlimited` 3 variant の共通骨格) は timeout 検知後に `child.kill()` → reader thread join するが、`cmd /c ` の**孫プロセス (実際の `cargo` / `jj` 等) は kill 対象外**で pipe の書き込み端を保持し続けるため EOF が来ず、**join が孫の自然終了までブロック**する。実測: `run_cmd_shell_capped` に `timeout_secs = 1` を指定したテストが返るまで 9.23s (`ping -n 10` の自然終了待ち)。既存テストは経過時間を assert しないため素通りしている。 +> +> **影響**: cli-push-runner の quality_gate (`step_timeout = 300`) と push (`timeout = 300`)、cli-merge-pipeline の step 実行 — ハングした `cargo test` / `jj git push` を timeout で打ち切れない (gate のハング保護が実質無効 = ADR-043 fail-closed の空洞化)。**同じ「Windows の `child.kill()` はプロセスツリーを殺せない」根因の実害が 2026-07-17 の post-merge-feedback #286 で発生**: `feedback::run_takt_workflow` の timeout kill (1200s) も descendants を殺せず (`feedback/mod.rs` が PR #78 時点から明記)、orphan takt が kill の約 3 分後に report を完成させたが、reconciliation は kill 直後の 1 回のみのため `.failed` marker が stale に残留。marker 記載の復旧手順 (takt 再実行) は context が後続 PR に上書き済みで誤 PR 分析を誘発する状態だった (2026-07-18 に orphan report の手動 copy で復旧済)。 +> +> **対処案** (§6 backlog 10 の分析より): +> +> - **(a) T6 と同じ「失敗経路では join せず detach」**: 実績ある方式だが、`_capped` 系は表示用出力を捨てることになるためトレードオフの判断が要る (T6 の diff は timeout 時に出力不要だったので単純に採れた)。 +> - **(b) 孫まで殺す (`taskkill /T /F` or Job Object)**: orphan の発生自体を止められるため、post-merge-feedback の stale marker 問題 (上記) にも波及効果がある。Windows 固有実装の複雑さを見積もること。 +> - (b) を採らない場合、`feedback::reconcile_takt_output` の「reconciliation が kill 直後 1 回のみ」の穴 (orphan が後から report を完成させると marker が stale 残留し、以後誰も再チェックしない) への緩和策を別途検討する。 +> +> **参照**: `src/lib-subprocess/src/` (`run_cmd_shell_with`)、`src/cli-merge-pipeline/src/feedback/takt.rs` (`TAKT_TIMEOUT_SECS`) / `feedback/mod.rs` (reconciliation 設計)、T6 実施結果 = PR #283 (経過時間 assert の教訓)、#286 feedback report Tier1 #2 (「優先度を上げて todo 化」推奨)、[ADR-043](adr/adr-043-security-gates-fail-closed.md)、[ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md)。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium-High (ハング保護の実質無効化 + stale marker の実害 1 件観測済) / Effort S。 + +#### 作業計画 + +- [ ] **経過時間 assert 付きの再現テストを先に書く** (T6 の教訓: timeout の回帰テストは Err の内容だけでなく経過時間を assert する。無いと本件は再び素通りする)。 +- [ ] (a) detach vs (b) process-tree kill を評価して選択する。判断は `_capped` 系の出力保全要否と Windows 実装コストの比較で行い、選ばなかった側の理由を `run_cmd_shell_with` の doc に記録する。 +- [ ] 3 variant + 呼び出し元 (cli-push-runner quality_gate / push、cli-merge-pipeline) で回帰確認。サンドボックス実機 E2E は `ping -t` 差し替え + before/after 経過時間比較 (dev-conventions 記載の手法) で行う。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- `timeout_secs = 1` 指定時、孫プロセスが生存していても制御が 1s + ε で戻ること (経過時間 assert で seal)。 +- ハングするコマンド (`ping -t` stub) が quality_gate / push / merge-pipeline の timeout で実際に打ち切られること。 + +--- + +### `cli-pr-monitor::push_to_remote` に push 拒否検知が無く post-PR re-push が無言で失敗し得る (push-pipeline-fix-plan §6 backlog 9 移管) + +> **動機**: T5 (PR #282) の調査で発見された sibling bug (push-pipeline-fix-plan §6 backlog 9 から移管)。jj は新規 bookmark の push 拒否時に **exit 0** を返すことがある (ADR-011 の背景) が、`src/cli-pr-monitor/src/stages/push.rs` の `push_to_remote` は exit code のみで成否判定しており、post-PR の re-push (CodeRabbit 指摘修正後の再 push 等) が**リモート未反映のまま成功扱い**になり得る。T5 が cli-push-runner 側で塞いだ「silent-failure push」= ADR-043 が防ぐ事故そのものと同型の穴。 +> +> **対処**: 出力取得は既に `run_cmd_direct` (全量、truncate 無し) のため、**拒否判定の追加だけ**で済む (T5 と違い truncate 問題は無い)。判定ロジック `push_was_refused` は現在 `cli-push-runner/src/stages/push.rs` の private fn のため、共有化 (lib 移設) か複製かは [ADR-044](adr/adr-044-subprocess-utility-extraction-boundary.md) の境界基準 (2nd consumer 出現時の共通化判定) で決める。fail-closed 側に倒す `contains` 判定の根拠は同 fn の doc コメントに恒久化済みで、そのまま踏襲する。 +> +> **参照**: `src/cli-pr-monitor/src/stages/push.rs`、T5 実施結果 = PR #282 (`mod t5_truncated_refusal_detection` 回帰テスト 6 本が参考)、#286 feedback report Tier2 #3 (採用候補)、[ADR-011](adr/adr-011-jj-push-new-bookmark-strategy.md)、[ADR-043](adr/adr-043-security-gates-fail-closed.md)。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium (外部可視の push が無言で未反映になる silent failure。発生は re-push 経路のみ) / Effort XS。 + +#### 作業計画 + +- [ ] 再現テストを先に書く (拒否メッセージ + exit 0 の出力で失敗扱いになることを assert。T5 の回帰テスト群を参考にする)。 +- [ ] `push_was_refused` の共有化可否を ADR-044 基準で判定し、`push_to_remote` に拒否判定を追加する。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 拒否メッセージ + exit 0 の push が `push_to_remote` で失敗として報告されること (回帰テストで seal)。 + +--- + +### 並列設計レビュアー (design-fit reviewer) の実験起案 — 見落とし実績の事前調査付き (R4/ADR-047 却下分析の代替案) + +> **動機**: R4 の ADR-047 採否判定分析 (2026-07-19、[ADR-047](adr/adr-047-prepush-refute-facet.md) 「却下理由の補強」節) から。直列 refute (verify step) は同日導入の [ADR-056](adr/adr-056-review-policy-anomaly-shadow.md) anomaly policy が **inline 反証** (fact-check 義務) として上流で FP を枯らしたため、**26 run で却下 0 件・便益 0** となり却下推奨。これで precision 側 (FP 除去) は ADR-056 が担う体制になったが、**recall 側 (見落とし) は post-PR CodeRabbit 頼みのまま**。一方 reviewers step は並列実行であり、simplicity execute (実測 avg 203s / max 416s) を律速上限として **第 3 の並列レビュアーを wall-clock 追加ゼロで足せる**見込みがある (security execute avg 92s が simplicity の陰に収まっている実績)。観点は「実装内容」ではなく「**設計内容**」— 見落としやすいポイントの指摘・プロジェクト適合性 (ADR / dev-conventions との整合)。 +> +> **重要な区別**: これは反証 (precision フィルタ) の代替ではなく**多視点化 (recall 拡張)**。機能軸が逆であり、「refute の後継」ではなく独立の新実験として評価する。最大リスクは **fix loop 率の再上昇** (現行 8.3% は「finding が減った」直接効果。設計・適合性指摘は anomaly 指摘より主観的で FP を出しやすく、規律なしでは T10 以前の 20〜45% へ逆行し得る)。 +> +> **対処案 (2 phase 構成、Phase 0 必須先行)**: +> +> - **Phase 0 — 需要の実証 (ADR-042 の流儀)**: 「simplicity/security が APPROVE した後に、CodeRabbit または post-merge feedback 分析で初めて検出された**設計起因の見落とし**」の実績数を数える。データソースは実在する 3 系列 — (1) `.claude/feedback-reports/*.md` (post-merge-feedback 蓄積、`.takt/runs` に 54 run 分の生成履歴あり)、(2) merged PR の CodeRabbit resolved threads (`gh api` の reviewThreads で path/body 取得可、PR #294 で手順実証済)、(3) `docs/adr/` の「実害後に塞いだ」記録 (ADR-058 の PR #224 等)。**実績ゼロなら見送り** (negative result は dev-conventions 順位 261 convention で永続化)。あわせて weekly-review ([ADR-031](adr/adr-031-weekly-review-pipeline.md) architecture facet) / post-PR CodeRabbit との役割重複を確認し、並列レビュアーでしか埋まらない穴かを判定する。 +> - **Phase 1 — 実験導入 (Phase 0 で需要が実証された場合のみ、[ADR-039](adr/adr-039-experimental-feature-standard-pattern.md) 3 点セット)**: `pre-push-review.yaml` の reviewers step に design-review sub-step (sonnet) を**並列追加**。規律は ADR-056 と同一 + 追加 1 点 — (a) fact-check 義務 (実コード・実 ADR で検証してから raise)、(b) articulable 要件、(c) [ADR-048](adr/adr-048-facet-findings-handoff-markdown-contract.md) output contract、(d) **指摘には根拠ソース (対象 ADR / dev-conventions / 実コードの file:line) の引用を必須**とし、実データ・実ソースに基づかない speculation を禁止、(e) **blocking にできるのは実害を具体的に示せた場合のみ**、それ以外は non-blocking warning (fix loop 再上昇の抑止)。 +> +> **受け入れ基準 (Phase 1)**: ①採用された設計 finding ≥1 件/実験期間、②fix loop 率が現行 8.3% から有意に悪化しない、③wall-clock が simplicity 律速のまま (design execute ≤ simplicity execute を `scripts/analyze-takt-timings.ps1` で確認 — 別コミットの観測ツール)。計測は R3 の `push-runs-*.jsonl` (総時間・fix 発生) + step 別 timing 抽出で機械的に行う。 +> +> **参照**: [ADR-047](adr/adr-047-prepush-refute-facet.md) §却下理由の補強 (一般反証機構との構成差・本案の出自)、[ADR-056](adr/adr-056-review-policy-anomaly-shadow.md) (inline 反証 = 規律の移植元)、[ADR-042](adr/adr-042-rule-vs-mechanism-boundary.md) (Phase 0 需要調査の根拠)、`docs/takt-step-timings.md` (step 別実測、別コミット)、[push-pipeline-fix-plan2.md](push-pipeline-fix-plan2.md) R4。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Low〜Medium (現行に実害はない: recall 穴は post-PR CodeRabbit が受けている。改善余地の探索) / Effort: Phase 0 = S、Phase 1 = M (条件付き)。 + +#### 作業計画 + +- [ ] Phase 0: feedback-reports / CodeRabbit resolved threads / ADR 実害記録の 3 系列から「pre-push 通過後に検出された設計起因の見落とし」を集計し、需要の有無を判定する (ゼロなら見送り + negative result 永続化で本エントリ完了)。 +- [ ] Phase 0: weekly-review architecture facet / post-PR CodeRabbit との役割重複を確認し、並列レビュアー固有の担当領域を定義できるか判定する。 +- [ ] Phase 1 (条件付き): design-review facet 作成 + pre-push-review.yaml へ並列追加 (ADR-039 3 点セット、上記規律 (a)〜(e))。 +- [ ] Phase 1 (条件付き): 受け入れ基準 ①〜③ を dogfood で計測し、採否判定を ADR 化する。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- Phase 0 の需要調査結果 (実績数と判定) が記録されていること。見送りなら negative result が dev-conventions convention で永続化されていること。 +- Phase 1 に進んだ場合: design-review が並列で動き、受け入れ基準 ①〜③ の計測データに基づく採否判定が ADR に記録されていること。 + +--- + +### 多段コミットの ADR / observability 更新チェックリストを dev-conventions に追加 (#295/#296 post-merge feedback 採用) + +> **動機**: R4 (ADR-047 却下 / ADR-056 延長) を「判定ドラフト → 却下理由補強 → plan2.md 反映 → 却下確定・撤去 → 観測ツール」と複数コミット・複数 PR に分割して進めた際、齟齬が複数回発生した — (a) timing doc が ADR-047 を「却下」と断定したが該当ブランチの ADR status header は未確定だった (PR #295 の pre-push review が REJECT → fix step が訂正)、(b) timing doc の `docs/takt-step-timings.md` への参照を markdown link にすると中間コミットで cross-ref が壊れるため plain-text に統一する必要があった、(c) ADR status 行と「採否判定」セクションの同期。ADR 58 件超・活発な多段階判定運用の本 repo では同型の反復が見込まれる。#295 と #296 の post-merge feedback がいずれも採用候補と判定。 +> +> **対処案**: `docs/dev-conventions.md` に「多段コミット/多段 PR で ADR・観測 doc を更新するときのチェックリスト」を追加する。項目案: ① doc が外部 ADR の status (試験運用/却下等) に言及する場合は、参照先 ADR の**現行 status header と同期**しているか (未確定を「確定」と書かない)、② 別コミット/別 PR にまたがるファイルへの参照は **markdown link ではなく plain-text パス**にして中間コミットの cross-ref 破壊を避ける (docs-lint cross-ref は markdown link のみ検査)、③ ADR の status 行と「採否判定」セクションの記述を同時更新する。dev-conventions には WP-06/07/08 由来の同種 checklist 先例が複数あり同形式で追加可能。 +> +> **参照**: `.claude/feedback-reports/295.md` Tier3 #2 / `.claude/feedback-reports/296.md` Tier3 #2、`docs/dev-conventions.md`、[ADR-048](adr/adr-048-facet-findings-handoff-markdown-contract.md) (plain-text 参照統一の先例は本 R4 で ADR-047/056 に適用済)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md)。 +> +> **実行優先度**: 🔧 Tier 3 — Severity Low / Frequency Medium / Effort S (doc checklist の追加のみ、機械化はしない)。実害は未観測 (齟齬は各 PR の review / feedback で捕捉できている) のため、より重い自動化 (custom lint / pre-push facet checklist) は再発観測後にエスカレーション。 + +#### 作業計画 + +- [ ] `docs/dev-conventions.md` に上記 3 項目のチェックリストを追加 (WP-06/07/08 の既存 checklist と同形式)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 多段コミットで ADR/observability doc を更新する運用者が、status 同期・plain-text 参照・セクション同期の 3 点を dev-conventions のチェックリストで確認できること。 + +--- + +### post-merge feedback が成功後に `post-merge-feedback-context.json` を残し次マージの feedback を誤 bail させる (cleanup gap、#296 マージで実観測) + +> **動機**: 2026-07-19 の #296 マージで、post_merge_feedback step が「前回の feedback がまだ進行中の可能性 (context.json が 820s 前に書かれた)」と判定して bail し、`.claude/feedback-reports/296.md.failed` marker を残した ([ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) L2 recovery 経路)。原因は **#295 マージの post-merge feedback が正常完了 (295.md 生成) したにもかかわらず自身の `.takt/post-merge-feedback-context.json` を掃除せず残した**こと。約 25 分 (1500s threshold) 以内に次のマージを行うと、前回の leftover context.json を「進行中」と誤判定して feedback が走らない = **連続マージで後発の feedback が構造的に skip される**。今回は手動で context.json 削除 + `--feedback-only 296` で recovery したが、根治は context.json の cleanup。 +> +> **対処案**: post-merge feedback workflow (または cli-merge-pipeline) が feedback の**正常完了時に `post-merge-feedback-context.json` を削除**する。あわせて staleness 判定を「時刻ベース (820s < 1500s)」から「稼働中プロセスの実在確認」等に寄せるか、少なくとも成功時 cleanup で leftover を残さないようにする。fail 時は marker を残す現行 L2 recovery を維持 (真の中断と区別)。 +> +> **参照**: `src/cli-merge-pipeline/src/pipeline.rs` (post_merge_feedback step / context.json の書き出し・cleanup)、[ADR-030](adr/adr-030-deterministic-post-merge-feedback.md) (L1 floor / L2 recovery、marker 運用)、`.takt/post-merge-feedback-context.json`、#296 マージ実観測 (2026-07-19)。 +> +> **実行優先度**: 🚀 Tier 1 — Severity Medium (連続マージで後発 PR の再発防止分析が構造的に skip される。今回は手動 recovery で救済したが、気付かなければ feedback が静かに欠落) / Frequency Low〜Medium (連続マージ運用時) / Effort S (成功時 cleanup の追加)。 + +#### 作業計画 + +- [ ] 再現テスト: leftover context.json がある状態で 2 回目のマージ feedback が誤 bail することを固定 (base_dir 注入等)。 +- [ ] post-merge feedback の**正常完了時に context.json を削除**する (fail 時は marker を残す現行動作を維持)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 連続マージ (前回 feedback 成功後 25 分以内) でも 2 回目の post-merge feedback が leftover context.json で誤 bail せず実行されること (回帰テストで seal)。 + +--- + +### 新規 ADR 起案時の「判断根拠 × 既存 ADR 定義」矛盾チェックリストを追加 (#301 post-merge feedback 採用) + +> **動機**: PR-N3 (#301) で、ADR-055 初版が**自ら定義した `decision` 軸 (block/warn = 発火の重み)** と矛盾する除外根拠 (「nudge は block/warn に乗らない」) を採用しており、本 PR で Amendment を追加して除外根拠を撤回する手戻りが発生した。ADR は既に 59 件超を相互参照しており、新規 ADR が既存 ADR の定義・原則と衝突する見落としは他 ADR でも再発しうる。#301 の post-merge feedback が採用候補と判定 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。 +> +> **対処案**: `CLAUDE.md` または `docs/dev-conventions.md` に「新規 ADR 起案時のチェックリスト」を追加する。項目案: ① ADR が用いる用語・軸 (例 `decision` = 発火の重み) が**既存 ADR の定義と衝突していないか**、② 除外/非除外・採用/却下などの判断根拠が、参照先 ADR が既に定義した原則から**演繹的に導けるか** (別解釈を新設していないか)、③ 衝突が**新規 ADR 初版の誤り**由来なら起案時に初版で解消する。ただし既存 ADR が陳腐化した等で**方針を意図的に変更・supersede する**正当なケースは別扱いとし、Amendment / superseding ADR による明示的更新を妨げない (「初版の誤り」と「既存方針の意図的変更」を区別する項目を設ける)。#327 (多段コミットの ADR/observability 更新チェックリスト) と対をなす doc-only 対処で、同セクションにまとめると発見性が良い。 +> +> **参照**: `.claude/feedback-reports/301.md` Tier3 #1、[ADR-055](adr/adr-055-firing-telemetry-collection.md) (§計装スコープ の `decision` 軸定義と Amendment (2026-07-19) の除外根拠撤回)、`docs/dev-conventions.md`、#327 (関連 checklist)。 +> +> **実行優先度**: 💎 Tier 3 — Severity Medium / Frequency Medium / Effort S (doc checklist のみ、機械化はしない。ADR 相互参照数が多く同型見落としが再発しうるが、実害は各 PR review/feedback で捕捉できているため機械化は再発観測後にエスカレーション)。 + +#### 作業計画 + +- [ ] `CLAUDE.md` または `docs/dev-conventions.md` に上記 3 項目のチェックリストを追加 (#327 と同セクションにまとめる)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 新規 ADR 起案者が、用語・軸の既存 ADR 定義との整合と判断根拠の演繹可能性をチェックリストで確認でき、ADR-055 型の初版自己矛盾 → Amendment 撤回の手戻りを防げること。 + +--- + +### 「行動要求 nudge は 2 チャネル返却」+「多義的戻り値は struct 化」convention の明文化 (#299 post-merge feedback 採用) + +> **動機**: PR-N1 (#299) で、ユーザー行動を要求する nudge (weekly reminder) を `additionalContext` (モデル向け) だけでなく `systemMessage` (ユーザー向け) の 2 チャネルで返す設計 ([ADR-059](adr/adr-059-hook-system-message-visibility.md)) を確立し、その過程で `compute_weekly_review_reminder_nudge` の戻り値を「additional_context + system_message」の struct (`WeeklyReviewNudge`) に変更した。ADR-059 の第2弾展開 (PR monitor catch-up / post-merge recovery / failed marker) で同型パターンの再利用が見込まれる。weekly reminder が 4 週間気付かれなかった実害 (Severity Medium) の再発防止として設計原則を明文化する。#299 の post-merge feedback が採用候補と判定 (Effort XS / Adoption Risk None)。 +> +> **対処案**: `docs/dev-conventions.md` に 2 点を追記する。① **ユーザーの行動を要求する nudge は systemMessage (ユーザー可視) と additionalContext (モデル可視) の 2 チャネルで返す** (ADR-059 の可視化チャネル分離)、② **戻り値が複数の意味役割を持つ場合は tuple/多値 flag ではなく struct 化して役割を命名する** (`WeeklyReviewNudge { additional_context, system_message }` の先例)。 +> +> **参照**: `.claude/feedback-reports/299.md` Tier3 #1、[ADR-059](adr/adr-059-hook-system-message-visibility.md)、`src/hooks-session-start/src/weekly_review.rs` (`WeeklyReviewNudge`)、`docs/dev-conventions.md`。 +> +> **実行優先度**: 💎 Tier 3 — Severity Medium / Frequency Medium / Effort XS (dev-conventions への 1 節追記のみ、ADR-059 第2弾展開で再利用見込み)。 + +#### 作業計画 + +- [ ] `docs/dev-conventions.md` に上記 2 点の convention を追記。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 行動要求 nudge を実装する運用者が、2 チャネル返却と多義的戻り値の struct 化を dev-conventions で確認できること。 + +--- + +### hooks-session-start に systemMessage を含む JSON 出力の exe-spawn E2E テストを追加 (#299 post-merge feedback 採用) + +> **動機**: PR-N1 (#299) で systemMessage 可視化 (ADR-059) を追加したが、テストは `build_session_start_json` の pure function レベルに留まり、**実 config パースを含む exe 実駆動レベルの検証がない** (`src/hooks-session-start/tests/` 自体が未作成)。ADR-059 の第2弾展開で同型の 2 チャネル JSON contract が複製される見込みで、JSON contract の regression を exe レベルで seal する価値がある。#299 の post-merge feedback が採用候補と判定 (Effort S / Adoption Risk None)。 +> +> **対処案**: `src/hooks-session-start/tests/e2e.rs` (新設) に、SessionStart 入力 JSON を stdin で渡して exe を駆動し、`systemMessage` を含む出力 JSON の形状 (systemMessage 有り/無し・additionalContext の nudge 併載) を assert する E2E を追加する。既存の exe-spawn bounded-wait convention ([ADR-049](adr/adr-049-incident-eval-regression-suite.md) `incident_eval.rs`) を踏襲。**注記**: 本 E2E は JSON contract の regression 防止に留まり、Claude Code クライアント UI 側の実描画確認 (ADR-059 削除条件2 / 判定期限 2026-08-16) は代替できないため dogfood 目視は別途必要。 +> +> **参照**: `.claude/feedback-reports/299.md` Tier2 #1、[ADR-059](adr/adr-059-hook-system-message-visibility.md)、[ADR-049](adr/adr-049-incident-eval-regression-suite.md) (exe-spawn E2E 先例)、`src/hooks-session-start/src/main.rs` (`build_session_start_json`)。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Medium / Frequency Medium / Effort S (既存 exe-spawn E2E convention を流用可能、tests/ 新設)。 + +#### 作業計画 + +- [ ] `src/hooks-session-start/tests/e2e.rs` を新設し、実 config + stdin 入力で exe を駆動して systemMessage 有り/無しの JSON 形状を assert。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- 実 config パース込みの exe 駆動で systemMessage を含む JSON contract が regression テストで seal されること (UI 実描画確認は別途 dogfood)。 + +--- + +### `pnpm build:all` 前に git usr/bin (cp.exe) の PATH 未設定を自動検出・追加 (#301 post-merge feedback 採用) + +> **動機**: `pnpm build:all` (及び per-crate `build:*`) は `cp target/release/X.exe .claude/X.exe` で Unix `cp` を使うが、pnpm は Windows で `cmd.exe` 経由で script を実行するため `cp` が解決できず copy step が失敗する (`'cp' is not recognized`)。memory `windows-build-cp-path-gotcha.md` に既記録だが、PR-N3 (#301) の実装でも**再度手動で PATH 追加が必要になった (再発 2 回目)**。ビルド阻害という Severity Medium と再発 Frequency Medium が揃う。#301 の post-merge feedback が採用候補と判定。 +> +> **対処案**: `package.json` の `build:all` (または各 `build:*`) で、Windows のとき git の `usr/bin` (cp.exe 提供) を PATH に前置してから cargo/cp を実行する。Windows 限定の additive な分岐 (他 OS は非該当) とし既存の Unix 動作を変えない。あるいは `cp` を Node の cross-platform copy (`node -e` / `shx` 等) に置換する案も検討。あわせて setup ドキュメントへの明記を補助的に実施。 +> +> **参照**: `.claude/feedback-reports/301.md` Tier1 #2、`package.json` (`build:all` / `build:*` scripts)、memory `windows-build-cp-path-gotcha.md` (既記録・再発)。 +> +> **実行優先度**: 🔧 Tier 2 — Severity Medium (ビルド阻害) / Frequency Medium (再発 2 回目) / Effort S (Windows 限定 if 分岐、他 OS 非影響、Adoption Risk は OS 依存分岐のみ)。 + +#### 作業計画 + +- [ ] `package.json` の build script を Windows で cp.exe を解決できるよう修正: `git.exe` の場所を自動検出 (非標準インストールにも対応) → `usr/bin/cp.exe` の存在確認 → 既存 PATH を保持したまま前置。未検出時は cross-platform copy (`node -e` / `shx` 等) へ fallback するか明確なエラーを出す (silent 失敗にしない)。 +- [ ] setup ドキュメントに前提を明記 (補助)。 +- [ ] 本エントリ削除 + todo-summary2.md 行削除。 + +#### 完了基準 + +- クリーンな Windows 環境で `pnpm build:all` が手動 PATH 調整なしに exe を `.claude/` へ配布できること。 +- Git が非標準の場所にインストールされている / `cp.exe` が不在の環境でも、cross-platform copy への fallback か診断可能な明確なエラーで失敗すること (silent 失敗・意味不明な `'cp' is not recognized` で止まらない)。 + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +(現時点で本ファイルへの既知課題は無し。docs/todo10.md / todo9.md 末尾を参照。) diff --git a/docs/todo18.md b/docs/todo18.md new file mode 100644 index 00000000..4a0c3dfd --- /dev/null +++ b/docs/todo18.md @@ -0,0 +1,270 @@ +# TODO (Part 18) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo10.md がファイルサイズ約 95KB (50KB 安定読み取り閾値の約 1.9 倍) に達したため、順位 215〜219 のエントリを本ファイルに分離した (2026-07-20 docs 50KB 超過解消の物理分割)。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md 〜 todo19.md の既存エントリは引き続き有効、相互に独立。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- +### `~/.claude/rules/common/coding-style.md` に「Defensive State Reset in State Machines」section 追加 (PR #214 post-merge-feedback T3-1 採用) + +> **動機**: PR #214 round 2 で CR Major #4 (`既存 state 再利用時も現在の push 情報に更新してください`) の fix として `finalize_initial_review_park` 内で `read_state()` 後に `state.pr` / `state.repo` / `state.started_at` を `ctx` 値で **無条件上書き** する pattern を land した。この pattern は同 function 内の既存 reset と同型 (CR Major #1 fix で `head_commit` 上書き、CR Major #2 fix で `review_recheck_count = 0`) で、現時点で 3 field に適用済の確立された defensive pattern。 +> +> ただしこの「無条件上書き」は新規 reader / reviewer から見ると一見「冗長 (= `unwrap_or_else(|| ::new(...))` で既に同値を設定済だから不要)」に見える危険性がある。同型コードを future PR で reviewer (人間 / AI 両方) が「redundant resets は削除すべき」と誤判定して削除した場合、prior cycle の stale state (古い PR 番号 / repo / 開始時刻) が混入する silent bug を導入するリスクが顕在化する。 +> +> **本タスクの位置づけ**: PR #214 post-merge-feedback Tier 3 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-06-20 ユーザー承認)。analyzer rationale: 「PR #214 の `review_recheck.rs` で positive pattern として land (lines 185–187)。同型コード (`review_recheck_count`, `head_commit` 上書き) との一貫性がある確立されたパターン。Frequency Medium = cli-pr-monitor には複数の state machine があり再発確実。Effort S、Adoption Risk None → ✅ 採用候補と判定」。pre-push:simplicity + pre-push:security の独立 2 ソース検出。 +> +> **参照**: `.claude/feedback-reports/214.md` Tier 3 #1、[src/cli-pr-monitor/src/stages/poll/review_recheck.rs:177-193](../src/cli-pr-monitor/src/stages/poll/review_recheck.rs#L177-L193) (現行 `finalize_initial_review_park` の defensive reset block)、memory `feedback_no_unenforced_rules.md` (enforcement 要件)、memory `feedback_global_config_backup.md` (snapshot 必須)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort S。global rules への docs 追記 ~30 行で完結、`feedback_global_config_backup` snapshot を忘れない。 + +#### 設計決定 (案) + +- **追加先**: `~/.claude/rules/common/coding-style.md` の末尾 (`## Code Quality Checklist` の直前) または `## Error Handling` 直後に新 section「Defensive State Reset in State Machines」を追加 +- **rule 内容**: 「State machine 内で `read_state()` / `load_state()` 等の persisted state を再利用する場合、`new()` で設定される identity field と同等の **無条件上書き reset** を `read_state()` 後に明示的に書く。これは『冗長』に見えるが、prior cycle の stale state (古い PR 番号 / repo / session ID 等) が再利用 path で混入する silent bug を防ぐ defensive pattern。reviewer (人間 / AI) は redundant 削除を提案しないこと」 +- **anti-pattern 警告**: `let state = read_state().unwrap_or_else(|| State::new(id, repo, time));` だけで identity field を `ctx` で上書きしないと、prior cycle の値が残留する +- **good pattern 例**: PR #214 `review_recheck.rs:177-193` を inline cite (`state.pr` / `state.repo` / `state.started_at` / `state.review_recheck_count` / `state.head_commit` の 5 field reset) +- **由来 cite**: PR #214 の CR Major #4 が「既存 state 再利用時も現在の push 情報に更新してください」として独立検出した実証 +- **enforcement layer**: 機械 lint は困難 (`read_state` pattern の構文認識 + identity field 列挙が必要) だが、simplicity-review LLM が `coding-style.md` を読むため "enforced via review" として機能、memory `feedback_no_unenforced_rules` 例外を満たす +- **派生プロジェクト波及**: `~/.claude/rules/common/` 配下のため techbook-ledger / auto-review-fix-vc に自動 + +#### 作業計画 + +- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) +- [ ] `~/.claude/rules/common/coding-style.md` に新 section「Defensive State Reset in State Machines」追記 (anti-pattern + good pattern + PR #214 由来 cite、約 30 行) +- [ ] markdownlint clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `~/.claude/rules/common/coding-style.md` に「Defensive State Reset in State Machines」section が追加される +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 +- 由来 cite (PR #214 CR Major #4 + `review_recheck.rs:177-193`) で reviewer / Claude が rule 背景を理解可能 +- simplicity-review LLM が future PR で同型 `read_state()` を含む state machine 編集を review する際、本 section の anti-pattern 警告を参照可能 + +#### 詰まっている箇所 + +なし。Effort S、global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 + +--- + +### `no-workstream-seq-names-in-config` lint rule 追加 — config comment 内 `PR-[0-9]+` ephemeral workstream sequence 検出 (PR #216 post-merge-feedback T1-1 採用) + +> **動機**: PR #216 で `.claude/hooks-config.toml` の `weekly_review_reminder` section comment に `(2026-06-23、PR-1)` および `次 PR (PR-3) で移行予定` を書き込んだ。これは ephemeral workstream sequence names (= マルチ PR 計画のローカル連番、GitHub PR `#NNN` ではない) を permanent artifact (config file comments) に embed する違反であり、`coding-style.md` § Cross-File Reference Lifecycle の「permanent → ephemeral 禁止」原則と同根。 +> +> 既存の rule⑥ `no-ephemeral-todo-reference` は `docs/todo*.md` file path 直接参照を検出するが、本ケースのような workstream sequence names (`PR-N`) は対象外。PR シリーズ完了後に「PR-3 とは何だったか」が文脈喪失し dead pointer 化するリスクが構造的に残る。 +> +> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 1 #1 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-06-23 ユーザー承認)。順位 217 (文書層) と同根 = 1 PR bundle 推奨。analyzer rationale: 「config file comment は permanent artifact であり dead pointer 化の直接トリガ。pattern `(?i)PR-[0-9]+` の FP リスクは軽微 (config コメントで企業コード等との混同は稀)」。Prepush T1-1 + Session T1-1 + Session T1-2 の 3 ソース独立検出。 +> +> **Tier 列との不整合補足**: analyzer feedback report (`.claude/feedback-reports/216.md`) では `Tier 1: Hooks/Linter 改善` カテゴリに分類されているが、本 todo entry の Tier 列および「実行優先度」行では **🔧 Tier 2** に再分類している。memory `feedback_tier_classification` の re-classification rule (= analyzer の Tier 1/3 分類は鵜呑みにせず実体ベース ⟨mechanical enforcement = T1 / docs 修正 = T3⟩ で再分類) に従い、project tier 定義 (🚀 Tier 1 = high-impact urgent / 🔧 Tier 2 = tooling improvements) と整合させた意図的再分類。 +> +> **参照**: `.claude/feedback-reports/216.md` Tier 1 #1、PR #216 commit `65963197e6c0` の hooks-config.toml diff、既存 rule⑥ `no-ephemeral-todo-reference` (template)、rule⑫ `no-hardcoded-jj-revset-range` (TOML meta field test_coverage pattern の template)、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle、`.claude/custom-lint-rules.toml` (rule 配置先)。 +> +> **実行優先度**: 🔧 **Tier 2** (project 分類、上記 re-classification 後) — Effort S。rule 追加 (~30 行 TOML + meta field) + test 追加 (~50 行 main.rs) で約 80 行、順位 217 と bundle すれば 1 PR diff < 200 行見込み。 + +#### 設計決定 (案) + +- **rule id**: `no-workstream-seq-names-in-config` +- **pattern**: `(?i)\bPR-[0-9]+\b` +- **extensions**: `["toml", "yaml", "yml", "jsonc"]` (config formats、plain `json` は comment 構文を持たず rule 対象外なので除外) +- **検出範囲**: comment 行のみ (TOML `#`、YAML `#`、JSONC `//` 等)。**実装注**: 多くの project-local lint rule は file 全体に regex match している。本 rule は comment 行検出が本質だが、初期実装は file 全体マッチで MVP として開始し、false positive 観測後に comment 行限定への絞り込みを判断する (= 同 pattern の rule⑥/⑫ と整合的な段階導入) +- **exception**: GitHub PR number `#[0-9]+` 形式は対象外。実装上は positive pattern `(?i)\bPR-[0-9]+\b` が `#NNN` を match しない (`#` prefix 形式は別) ため exception 不要。ただし test で「`#216`」「`PR #216`」のようなケースが fire しないことを negative test で固定 +- **severity**: `warning` (block しない、author への hint 機能優先、rule⑫ と同 pattern) +- **block message**: 「Ephemeral workstream sequence name (`PR-N`) detected in config comment. Permanent artifacts (config files) must not reference ephemeral workstream sequences. Use GitHub PR `#NNN` for stable cite, or inline rationale instead of "PR-3 で移行予定". See coding-style.md § Cross-File Reference Lifecycle.」 +- **TOML meta field** (`test_coverage` schema、rule⑫ と同 pattern): + ```toml + [rules.test_coverage] + other_ext_tests = ["no_workstream_seq_detects_pr_dash_n_in_jsonc_comment"] + + [rules.test_coverage.main_ext_tests] + toml = ["no_workstream_seq_detects_pr_dash_n_in_toml_comment", "no_workstream_seq_skips_github_pr_number"] + yaml = ["no_workstream_seq_detects_pr_dash_n_in_yaml_comment"] + yml = ["no_workstream_seq_detects_pr_dash_n_in_yml_comment"] + ``` + +#### 作業計画 + +- [ ] `.claude/custom-lint-rules.toml` に `[[rules]]` entry 追加 (id / pattern / extensions / severity / message / test_coverage) +- [ ] `src/hooks-post-tool-linter/src/main.rs` の `mod tests` に positive test 4 件 (toml / yaml / yml / jsonc 各 1) + negative test 1 件 (`#216` / `PR #216` が fire しない) を追加 +- [ ] `cargo test -p hooks-post-tool-linter` で rule_test_coverage_check が pass することを確認 +- [ ] dogfood: 本 PR で `hooks-config.toml` から `PR-1` / `PR-3` 表記が削除 or `#216`/`#NNN` 表記に置換されることを確認 +- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 + +#### 完了基準 + +- `no-workstream-seq-names-in-config` rule が `.toml` / `.yaml` / `.yml` / `.jsonc` / `.json` comment 内の `PR-[0-9]+` を warning として検出 +- `#216` / `PR #216` のような GitHub PR number は fire しない (negative test pass) +- rule_test_coverage_check が main_ext_tests / other_ext_tests 整合性を強制 +- 順位 217 (文書層) と同 PR で land した場合、`coding-style.md` への具体例追加と機械強制の 2 層防御が確立される + +#### 詰まっている箇所 + +- comment 行限定 vs file 全体 match: MVP は file 全体 match で開始、false positive 観測後に絞り込み判断 (rule⑥/⑫ と同段階導入)。順位 217 の docs 追加で「config comment」の意図を明示化することで、author が non-comment context での意図的使用を回避できれば file 全体 match でも実用性高い +- `#NNN` vs `PR-NNN` 境界: regex `\bPR-[0-9]+\b` は `#` prefix を含まないため除外可能、ただし将来 `PR-#216` のような mixed 表記が登場した場合は pattern 拡張が必要 + +--- + +### `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に config file comments の permanent artifact 扱い明記 + workstream sequence 禁止例追加 (PR #216 post-merge-feedback T3-1 採用) + +> **動機**: 既存 `coding-style.md` § Cross-File Reference Lifecycle は markdown 内 cross-reference (docs/ADR/README 等) を主に想定して書かれており、**config file comments (`.toml`/`.json`/`.yaml`) も permanent artifact** であることが暗黙的にしか扱われていない。PR #216 で `hooks-config.toml` comment に "PR-1" / "PR-3" ephemeral workstream sequence を embed した違反は、author が「config の comment は注釈であって rule の対象外」と暗黙的に判断していた可能性が高い。 +> +> 順位 216 の lint rule が機械的に防止するが、author の理解を促す **文書層** として補完することで「なぜ config comment にも reference lifecycle が適用されるか」を理解可能にする。機械層 (216) + 文書層 (本 task) の 2 層防御は順位 200/202/205 と同 pattern。 +> +> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。順位 216 (機械層) と 1 PR bundle 推奨。analyzer rationale: 「既存ルールは markdown document 内の cross-reference を主に想定しており config file comments の permanent artifact としての扱いが暗黙的。Tier 1-1 の custom lint rule が機械的に防止するが、author の理解を促す文書層として補完。Frequency Medium (cross-file reference violations の systemic pattern と同根)」。Session T3-1 + PR-analysis T3-1 の独立 2 ソース収束。 +> +> **参照**: `.claude/feedback-reports/216.md` Tier 3 #1、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle (現行 section、編集対象)、順位 216 (機械層 = lint rule、本 task の機械強制対応)、memory `feedback_global_config_backup` (snapshot 必須)、PR #216 hooks-config.toml diff (違反実例として inline cite)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global rules への docs 追記 ~15 行で完結、`feedback_global_config_backup` snapshot を忘れない。 + +#### 設計決定 (案) + +- **追加先**: `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle の anti-pattern examples block (現状 Rust raw string / TOML コメント / JSONC ヘッダーコメント の 3 種を含む) の TOML コメント sub-section に「workstream sequence names も禁止」と明記 +- **追加内容案**: + + ```markdown + - **TOML コメント / config** (拡張): + - BAD: `# 由来: docs/todo.md "" 参照のため` + - BAD: `# 詳細: docs/local-llm-offload-analysis.md §A-2 を参照` (`*-analysis.md` は ephemeral 計画書、retire 時に dead pointer 化) + - BAD (workstream sequence): `# PR-3 で移行予定` / `# 次 PR (PR-1) で実装` (ephemeral workstream sequence、PR シリーズ完了後に文脈喪失で dead pointer 化) + - GOOD: `# 由来: PR #94 (docs lifecycle 整理)` または ADR 参照 + - GOOD: `# 詳細: docs/adr/adr-NNN-feature.md を参照` または config 設計意図を inline で 1-2 行記述 + - GOOD (workstream cite): `# 由来: PR #216` (GitHub PR number は永続 identifier) + ``` + +- **由来 cite**: PR #216 で `hooks-config.toml` の `weekly_review_reminder` comment に `(2026-06-23、PR-1)` / `次 PR (PR-3) で移行予定` を embed した実例を inline cite +- **enforcement layer**: 機械層は順位 216 lint rule で強制、本 task は author の理解促進と「なぜ workstream sequence も dead pointer になるか」の rationale 提供 +- **派生プロジェクト波及**: `~/.claude/rules/common/` 配下のため techbook-ledger / auto-review-fix-vc に自動 + +#### 作業計画 + +- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) +- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle の TOML コメント anti-pattern block に workstream sequence 禁止例を追加 (~5 行) +- [ ] 同 section 末尾近くの GOOD examples block に GitHub PR number 形式 (`# 由来: PR #NNN`) を明示 (~2 行) +- [ ] markdownlint clean +- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 + +#### 完了基準 + +- `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に「workstream sequence names (`PR-1`/`PR-3` 等) も config comment 内で禁止」が明文化される +- GOOD example として GitHub PR number 形式 (`# 由来: PR #NNN`) が提示される +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 +- 順位 216 (機械層) と同 PR で land した場合、機械強制 + 文書理解の 2 層防御が確立される + +#### 詰まっている箇所 + +なし。Effort XS、global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 + +--- + +### ADR-039 § Bounded Lifetime + `~/.claude/rules/common/patterns.md` に provisional `enabled` 変更時の todo entry 必須化を追加 (PR #216 post-merge-feedback T3-2 採用) + +> **動機**: PR #216 で `weekly_review_reminder.enabled = false → true` を「次 PR-3 (`[features].enabled` allow-list 移行) で真の opt-in 切り替えになるまでの暫定」として config comment に rationale を残したが、対応する `docs/todo*.md` の **移行 tracking entry を作成していなかった**。 +> +> このため: +> +> - 「いつ PR-3 で移行する予定か」が config comment にしか残らず、commit を辿らないと判らない +> - PR-3 が遅延または忘れられた場合、provisional state が silent に永続化する (= silent aging) +> - ADR-039 § Bounded Lifetime の「採否判定タイミングの明示」原則が config comment では弱く、todo entry で明示すべき +> +> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Low / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「provisional state を config comment のみで追跡する pattern が silent aging を招く。ADR-039 の bounded-lifetime checklist に『provisional enabled 変更 → todo entry 追加』を明示することで future PR での遵守を促進。Frequency Low (初観測) だが Adoption Risk None で早期 codify の費用対効果は高い」。Session T3-2 + PR-analysis T3-2 + Prepush T2-1 (ADR 側アプローチ統合) の 3 ソース独立収束。 +> +> **参照**: `.claude/feedback-reports/216.md` Tier 3 #2、`docs/adr/adr-039-experimental-feature-standard-pattern.md` § Bounded Lifetime (編集対象、6-point design checklist 拡張)、`~/.claude/rules/common/patterns.md` § Experimental Feature 設計時の参照必須 (補助編集対象、同旨 note 追加)、PR #216 hooks-config.toml comment (違反実例)、memory `feedback_global_config_backup` (snapshot 必須)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR + global rules への docs 追記 ~10 行で完結、`feedback_global_config_backup` snapshot を忘れない。 + +#### 設計決定 (案) + +- **ADR-039 編集**: § Bounded Lifetime の 6-point design checklist に新 checklist item 追加 (本 ADR は project-local のため snapshot 対象外): + + ```markdown + - [ ] **provisional state の todo tracking**: 試験運用中に config 値を一時的に変更する場合 (例: `enabled = false → true` を本採用判定前に試験的に有効化)、対応する `docs/todo*.md` entry を作成し、移行/採否判定タイミングを明示する。config comment のみで追跡すると silent aging を招く + ``` + +- **`~/.claude/rules/common/patterns.md` 編集** (global、波及対象): § Experimental Feature 設計時の参照必須 の末尾に同旨 note を追加 (~3 行): + + ```markdown + > **provisional state の追跡**: 試験運用中に config 値を一時的に変更する場合 (例: 試験運用元での明示 enable)、必ず `docs/todo*.md` に移行 tracking entry を作成し、採否判定タイミングを明示する。config comment のみの追跡は silent aging を招く (PR #216 で実観測、ADR-039 § Bounded Lifetime 参照)。 + ``` + +- **由来 cite**: PR #216 で `weekly_review_reminder.enabled` の provisional change を config comment のみで tracking した実例を inline cite +- **派生プロジェクト波及**: `~/.claude/rules/common/patterns.md` への追加で techbook-ledger / auto-review-fix-vc に自動波及 + +#### 作業計画 + +- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per、patterns.md 編集のため) +- [ ] `docs/adr/adr-039-experimental-feature-standard-pattern.md` § Bounded Lifetime 6-point checklist に provisional todo tracking item 追加 (~5 行) +- [ ] `~/.claude/rules/common/patterns.md` § Experimental Feature 設計時の参照必須 に同旨 note 追加 (~3 行) +- [ ] markdownlint clean (両 file) +- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 + +#### 完了基準 + +- ADR-039 § Bounded Lifetime に provisional state todo tracking checklist item が追加される +- `~/.claude/rules/common/patterns.md` に同旨 note が追加される +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 +- future PR で provisional state を導入する際、config comment のみで tracking せず todo entry も作成する慣行が確立される + +#### 詰まっている箇所 + +なし。Effort XS、ADR + global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 + +--- + +### `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に「commit description 言及 ≠ 実装完了」明文化 (PR #216 post-merge-feedback T3-3 採用) + +> **動機**: PR #216 cleanup 作業中、analyzer (Claude) が「PR #215 commit description で 順位 215 を言及している = 実装完了」と naïve に判断し、当初 6 entries (147/151/212/213/214/215) 削除計画を立てた。実際にはユーザーの修正 + grep `"Defensive State Reset" ~/.claude/rules/common/coding-style.md` による実体確認の結果、順位 215 は **todo entry が PR #215 で追加されただけ** で実装は未着手だった (5 entries 削除が正解)。 +> +> この naïve assumption は今後も analyzer / Claude が再発する可能性が高く、誤った削除を実施すると未実装タスクが docs から消える silent loss につながる。development-workflow.md に明文化することで、future Claude session 内で同 anti-pattern を構造的に防止する。 +> +> **本タスクの位置づけ**: PR #216 post-merge-feedback Tier 3 #3 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「本 PR で『commit description に順位 N 言及 = 実装完了』の naïve assumption から analyzer が誤った 6 entry 削除計画を立てた実観測。ユーザー修正で 5 entry に訂正。Effort XS、Severity Medium (analyzer の誤判定リスクが今後も継続)、Adoption Risk None」。Session T3-3 の単一ソースだが Severity Medium で採用条件成立。 +> +> **参照**: `.claude/feedback-reports/216.md` Tier 3 #3、`~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック (編集対象)、PR #216 cleanup session log (誤判定 → grep 救出の経緯)、memory `feedback_verify_task_not_already_done` (関連 memory、再確認 verb-noun rule の前提となる「verify」step)、memory `feedback_global_config_backup` (snapshot 必須)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global rules への docs 追記 ~8 行で完結、`feedback_global_config_backup` snapshot を忘れない。 + +#### 設計決定 (案) + +- **追加先**: `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック の末尾近く (関連 guideline と隣接配置) +- **追加内容案**: + + ```markdown + ### Commit description 言及は実装完了の証拠ではない + + PR commit description で「順位 N」「feature X 実装」「Y を追加」等を言及していても、**実際のファイル変更を `jj diff` / `grep` で確認するまで completion 判定してはならない**。 + + 特に多 commit PR (= 1 PR で複数の論理 unit を扱う場合): + - 「順位 N 削除」commit と「順位 N 実装」commit が分かれていることがある + - todo entry の追加 / docs 更新だけで実装本体が未着手な commit も存在する + + 検証手順: + + 1. commit description で言及されている feature / 順位 N を特定 + 2. `jj diff -r ` で実際のファイル変更を確認 + 3. 実装対象 file を `grep` で確認 (例: 「Defensive State Reset」section が `~/.claude/rules/common/coding-style.md` に実在するか) + 4. 実体確認後に「完了」判定 + + 由来: PR #216 で analyzer が「PR #215 commit description で 順位 215 を言及 = 実装完了」と naïve 判定し誤った削除計画を立てた実観測 (ユーザー修正 + grep 救出で訂正)。memory `feedback_verify_task_not_already_done` と相補的 (前者は task 着手前の verify、本 rule は task 完了判定前の verify)。 + ``` + +- **enforcement layer**: 機械 lint は困難 (commit description の意味解析 + ファイル diff の cross-check が必要) だが、Claude が development-workflow.md を読む文脈で「明示的に書かれた rule」として機能、memory `feedback_no_unenforced_rules` 例外 (= 既存実践の明文化) を満たす +- **派生プロジェクト波及**: `~/.claude/rules/common/development-workflow.md` 配下のため techbook-ledger / auto-review-fix-vc に自動 + +#### 作業計画 + +- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) +- [ ] `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に新 sub-section「Commit description 言及は実装完了の証拠ではない」を追加 (~25 行、設計決定の追加内容案 per) +- [ ] markdownlint clean +- [ ] 本エントリ削除 + docs/todo-summary.md 行削除 + +#### 完了基準 + +- `~/.claude/rules/common/development-workflow.md` § 設計 doc/実装の同期チェック に「commit description 言及 ≠ 実装完了」guideline が追加される +- 検証手順 (4 step) が明示される +- PR #216 事例が inline cite として記録される +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及 + +#### 詰まっている箇所 + +なし。Effort XS、global rules への docs 追記のみ、`feedback_global_config_backup` snapshot を忘れない。 + diff --git a/docs/todo19.md b/docs/todo19.md new file mode 100644 index 00000000..f6ebed02 --- /dev/null +++ b/docs/todo19.md @@ -0,0 +1,286 @@ +# TODO (Part 19) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo10.md がファイルサイズ約 95KB (50KB 安定読み取り閾値の約 1.9 倍) に達したため、順位 220〜224 のエントリを本ファイルに分離した (2026-07-20 docs 50KB 超過解消の物理分割)。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md 〜 todo19.md の既存エントリは引き続き有効、相互に独立。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- +### subprocess stress test (>64KB stdout) を ADR-031 weekly-review pipeline 経由で週次実行 (PR #217 post-merge-feedback T2-1 採用) + +> **動機**: PR #217 (refactor PR-3a) の post-pr-review iter 2 で 2 module (`hooks-session-start/src/jj_helpers.rs` + `hooks-pre-tool-validate/src/todo_staleness.rs`) に同型の subprocess deadlock 脆弱性が independent 観測された。具体的な脆弱性は、`Command::new("jj")` を `.stdout(Stdio::piped())` で spawn したあと parent process が `try_wait` ループで wait しつつ child の stdout を drain せず終了後にまとめて read するため、jj log の出力が pipe buffer (Linux default 64KB / Windows 4-64KB) を超えると child が write block → 親が wait block → deadlock。 +> +> CR Major fix として `spawn_stdout_drainer` + `poll_child_with_deadline` 関数を抽出して background drain に変更 (takt-fix iter 2)、さらに iter 3 で `lib_subprocess::drain_pipe_unlimited` + `wait_with_timeout_basic` の既存共通 helper への統合に refactor。本 fix で deadlock は構造的に防止されたが、**実際に >64KB を pipe させる regression test が存在しない** ため future refactor で再発する盲点が残る。 +> +> **本タスクの位置づけ**: PR #217 post-merge-feedback Tier 2 #1 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「2 モジュールで deadlock パターン確認、High severity + Medium frequency で M effort を正当化、deadlock は大 buffer 時のみ顕在化するため手動検証が困難でテスト化が最も確実な防止手段」。 +> +> **ユーザー判断 (2026-06-23)**: 「毎回走るタイプ (hooks など) のテストに組み込むのは適切ではない、週に 1 回程度に頻度を落として通常の開発速度に影響が出ない形で CI に組み込みたい」。Stop hook quality gate (`cargo test`) や pre-push pipeline (`cargo test`) は毎 push 実行のため stress test のような高コスト・低頻度検証は不適切。ADR-031 weekly-review pipeline (週次 cron / 手動 `/weekly-review`) で `cargo test -- --ignored --test-threads=1` 系の追加 step として実行する方針。 +> +> **参照**: `.claude/feedback-reports/217.md` Tier 2 #1、PR #217 takt-fix iter 2 / iter 3 (`lib-subprocess` 統合)、ADR-031 § Phase B (takt workflow + facets)、`#[ignore]` test 慣習 (例: cli-pr-monitor の integration test、ADR-021)、`docs/adr/adr-044-subprocess-utility-extraction-boundary.md` (lib-subprocess の extraction 境界判定)、順位 221 (ADR docs codification、bundle 推奨)。 +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。stress fixture 作成 (~50 行 × 2 module) + ADR-031 weekly workflow への step 追加 + `cargo test -- --ignored` 経由の動作確認。 + +#### 設計決定 (案) + +- **test 配置**: 各 module の既存 `mod tests` に `#[ignore = "stress test, requires explicit --ignored flag (PR #217 T2-1)"]` 付きで追加 +- **fixture 方針**: 実 `jj log` を呼び出すと環境依存になるため、`Command::new("yes")` 系 (Linux) や `Command::new("cmd").args(["/c", "for /L %i in (1,1,N) do @echo ..."])` (Windows) で >64KB の決定論的出力を生成。あるいは `jj log` を repo 内の真の commit history で呼ぶ場合は test 前提として大型 repo を必要とせず、std::process::Command 単体で test 可能な形に +- **検証項目**: + - `> 64KB` の stdout を吐く child を spawn し、`drain_pipe_unlimited` 経由で完全 read できる (`output.len() > 64 * 1024`) + - timeout 内に child が exit する (`child.wait().is_ok()` 系 assert) + - parent が wait 完了する (deadlock していたら test 自体がハングして CI timeout で fail) +- **CI 統合**: ADR-031 weekly-review workflow に新 step `rust-stress` を追加 (`cargo test --workspace -- --ignored --test-threads=1`)。既存 rust-test group (`cargo test --workspace`) とは分離 (前者は毎回、後者は週次) +- **派生プロジェクト transferability**: `lib-subprocess` を採用する他 crate (cli-merge-pipeline / cli-pr-monitor / cli-push-runner / hooks-post-tool-linter) へも同型 stress test を transfer 可能。本 task の MVP は 2 module 限定、3+ module で同 pattern 観測時に拡張判断 (cli-push-pipeline は 2026-07-17 に crate 削除済みのため対象外) +- **memory `feedback_test_dry_antipattern.md`** 適用: 各 module の test 内に独立 helper (`spawn_large_output_child` / `assert_no_deadlock_within`) を duplicate、共有 test module は抽出しない + +#### 作業計画 + +- [ ] hooks-session-start/src/jj_helpers.rs の `mod tests` に `stress_drain_large_stdout_does_not_deadlock` 追加 (~50 行、`#[ignore]` 付き) +- [ ] hooks-pre-tool-validate/src/todo_staleness.rs の `mod tests` に同型 test 追加 (~50 行) +- [ ] `cargo test -p hooks-session-start -- --ignored --test-threads=1` でローカル動作確認 +- [ ] `cargo test -p hooks-pre-tool-validate -- --ignored --test-threads=1` でローカル動作確認 +- [ ] ADR-031 weekly-review workflow (`.takt/workflows/weekly-review.yaml` 等) に rust-stress step 追加 +- [ ] 次回 `/weekly-review` で実発火確認、本 task entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 各 module で `>64KB stdout` を pipe する stress test が `#[ignore]` 付きで存在 +- `cargo test -- --ignored --test-threads=1` で test が pass、deadlock していないこと (timeout しないこと) を確認 +- ADR-031 weekly-review workflow に新 step が追加され、次回 weekly 実行で stress test が走る +- 順位 221 (ADR docs) と合わせ、test 層 (本 task) + docs 層 (221) の 2 層防御が確立 + +#### 詰まっている箇所 + +- Windows での大出力 fixture コマンド: `yes` は Windows に存在しない。`cmd /c for /L` で代替可能だが PowerShell / bash 等の環境差を test 内で吸収する設計が必要 (cross-platform test fixture) +- ADR-031 workflow への step 追加: 既存 weekly-review yaml の構造を確認、rust-stress step の独立 facet 化が必要か、aggregate-weekly facet の pre-step として組み込むかは実装時判断 + +--- + +### ADR-NNN (採番未確定、land 時に確定): Safe Subprocess Stdout Pattern を ADR-016 appendix or 新 ADR で codify (PR #217 post-merge-feedback T3-1 採用) + +> **動機**: PR #217 takt-fix iter 2 で 2 module 同型の subprocess deadlock を fix した実例 (順位 220 参照) から、`Stdio::piped()` を伴う child process の安全な扱い方を ADR で永続化する必要が判明した。同 pattern は本 PR 以前にも `lib-subprocess` 内部で `drain_pipe_unlimited` + `wait_with_timeout_basic` として codify されていたが、**新規 subprocess spawn を書く著者が pipe buffer 制約を知らない場合の防御層が欠落** していた。 +> +> ADR で pattern を明文化することで: +> +> - 機械検知 (T1-1 lint rule、🤔 様子見) より低 risk な代替防止層として機能 +> - 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability を確保 (ADR は global 参照可能) +> - reviewer (人間 / AI) が PR review 時に「Stdio::piped() を見たらこの ADR を確認」する mental check が成立 +> - ADR-025 (CwdRestore Drop guard pattern) の precedent と整合: 「pattern の codify は test/lint に先行する低コスト防止層」 +> +> **本タスクの位置づけ**: PR #217 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「2 モジュールで同一パターン違反、Medium frequency + S effort + None risk、pattern を明文化することで T1-1 の lint rule 化より低 risk な代替防止層として機能、ADR-025 の precedent あり」。 +> +> **参照**: `.claude/feedback-reports/217.md` Tier 3 #1、PR #217 takt-fix iter 2 (`spawn_stdout_drainer` + `poll_child_with_deadline` 初版抽出) / iter 3 (`lib-subprocess` 統合)、`docs/adr/adr-016-long-running-command-strategy.md` (append 候補)、`docs/adr/adr-025-cwd-restore-drop-guard.md` (precedent: pattern codify ADR)、`docs/adr/adr-044-subprocess-utility-extraction-boundary.md` (lib-subprocess 境界判定)、`src/lib-subprocess/src/lib.rs` (`drain_pipe_unlimited` / `wait_with_timeout_basic` 実装)、順位 220 (test 層、bundle 推奨)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort S。ADR appendix or 新 ADR 作成 (~150 行)、3 pattern (background drain / `Command::output()` / `Stdio::null()`) の説明 + lib-subprocess utility cite + anti-pattern 例 (本 PR の deadlock fix 経緯を inline cite)。 + +#### 設計決定 (案) + +- **配置選択**: 2 案あり、ADR 起案時にユーザー判断: + - **Option A** (append): `docs/adr/adr-016-long-running-command-strategy.md` に新 section「Safe Subprocess Stdout Pattern」を追加。ADR-016 が既に subprocess 戦略を扱うため整合的、ADR 数を増やさない + - **Option B** (new): `docs/adr/adr-NNN-safe-subprocess-stdout-pattern.md` として新規 ADR (採番は land 時に確定、順位 135 placeholder policy per)。pattern が ADR-016 の長時間コマンド扱いとは別関心 (= pipe buffer 制約は短時間 subprocess でも発生) のため scope 分離する根拠あり +- **本 task の MVP 推奨**: Option A (append) — ADR 数増加を抑え、ADR-016 § 長時間コマンド戦略 直後の new section として組み込む。実装時の dogfood で B 化判断 +- **記述項目** (3 pattern + anti-pattern): + 1. **Background drain pattern**: `spawn(...)` + `std::thread::spawn(move \|\| out.read_to_end(...))` で stdout を別 thread で drain、parent は `try_wait` ループ。本 PR で `lib_subprocess::drain_pipe_unlimited` + `wait_with_timeout_basic` として codify 済 + 2. **`Command::output()` pattern**: 短時間 subprocess で stdout/stderr を一括 capture する標準慣習。pipe buffer 問題を回避するが timeout 制御不可 + 3. **`Stdio::null()` pattern**: stdout を完全に捨てる場合 (= 副作用のみ目的)。pipe buffer 問題なし、最も simple + 4. **Anti-pattern**: `Stdio::piped()` + drain なしで `try_wait` ループ。pipe buffer 枯渇で deadlock (本 PR の修正前 state、inline cite) +- **由来 cite**: PR #217 takt-fix iter 2 の deadlock 修正経緯と iter 3 の lib-subprocess 統合 refactor を inline 引用 +- **派生プロジェクト波及**: ADR は global 参照可能、本 ADR を `~/.claude/rules/common/` に link することで techbook-ledger / auto-review-fix-vc 等に reference 提供 +- **enforcement layer**: 機械 lint (T1-1) は false positive リスクで 様子見、本 ADR が author 教育 + reviewer 確認の文書層、順位 220 (stress test) が test 層、3 層構成 (docs / test / lint defer) で防御 + +#### 作業計画 + +- [ ] ADR 配置の Option A/B 判断 (Option A = ADR-016 append が MVP 推奨) +- [ ] ADR section / 新 ADR を作成 (~150 行、3 pattern + anti-pattern + cite) +- [ ] CLAUDE.md ADR list 追記 (Option B の場合のみ) +- [ ] ADR-025 precedent との相補性を ADR 内で明示 +- [ ] `~/.claude/rules/common/coding-style.md` (or rust/patterns.md) から本 ADR への link を追加 (派生プロジェクト transferability) +- [ ] 本 task entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- ADR (appendix or new) が land、3 pattern + anti-pattern + 由来 cite を含む +- ADR-016 / ADR-025 / ADR-044 / lib-subprocess との関係性が明確 +- `~/.claude/rules/common/` から本 ADR への参照が追加され、派生プロジェクトで future PR 著者が `Stdio::piped()` を書く際の reference として機能 +- 順位 220 (stress test) と相補的に、docs + test の 2 層防御確立 + +#### 詰まっている箇所 + +- Option A vs B の判断: ADR-016 § 長時間コマンド戦略 が「長時間 = timeout 制御」に focus している場合、本 pattern (pipe buffer = 短時間でも発生) との scope mismatch で別 ADR が綺麗。実装着手時に既存 ADR-016 を read して判断 +- `~/.claude/rules/common/` への link 追加先: `coding-style.md` か `rust/patterns.md` かは Option A/B の結論と整合させる必要あり + +--- + +### `~/.claude/CLAUDE.md` に「複数セッション跨ぎの計画文書作成時は AI が先走らずユーザー確認後に方針報告し GO/NO-GO を得る」ルール追加 (PR #218 post-merge-feedback #5 採用) + +> **動機**: PR #218 (docs PR、ファイルサイズチェックフロー改善計画 + 順位 220/221 採用) のセッション内で、Plan file (`docs/file-length-enforcement-plan.md`) 作成完了報告後、AI (Claude) が **ユーザー承認なしに PR-W0 (weekly audit step 追加) の実装着手を開始** し、ユーザーが `[Request interrupted by user]` で停止 + 「勝手に作業を進めないでください」と明示的に course correction する事案が発生した。Auto mode 下でも「計画書 / planning doc 作成のような **大きな task 完了時** は GO/NO-GO の確認待ちが必須」という規範を CLAUDE.md に明文化することで、本セッション内の事例を後続セッションで再発防止する。 +> +> **本タスクの位置づけ**: PR #218 post-merge-feedback #5 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-23 ユーザー承認)。analyzer rationale: 「AI がユーザー確認なしに計画書作成を開始し `[Request interrupted by user]` で停止させた事例。Severity Medium (AI 暴走 = UX 劣化)・Effort XS・Adoption Risk None → ✅ 条件を満たす。Frequency Low だが Effort が極小なため採用コストが低い」。 +> +> **参照**: `.claude/feedback-reports/218.md` Tier 3 #5、PR #218 session transcript (Plan file 作成完了 → AI 先走り → ユーザー停止 → "勝手に作業を進めないでください" の course correction)、memory `feedback_no_unauthorized_reorder.md` (推奨実行順序の上位タスクが blocked された時点で停止し、ユーザーに pivot 可否を確認する、の補強)、memory `feedback_global_config_backup.md` (snapshot 必須)、`~/.claude/CLAUDE.md` (編集対象 global config)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global config への 1 段落追記で完結、`feedback_global_config_backup` snapshot を忘れない。 + +#### 設計決定 (案) + +- **追加先**: `~/.claude/CLAUDE.md` の `## Personal Preferences` section 直後 (もしくは `## Doing tasks` 配下の sub-section) +- **rule 内容**: + + ```markdown + ### AI 先走り防止 — 計画文書作成完了時の GO/NO-GO ゲート + + 複数セッション跨ぎの計画文書 (planning doc / 設計ドキュメント) の作成完了時は、 + Auto mode の最中であっても **次の実装着手を一時停止し、ユーザーに方針報告 + + GO/NO-GO 確認を待つ**。 + + 対象となる "大きな task" の例: + + - 新規 planning doc (`docs/-plan.md` / `docs/-analysis.md` 等) の作成完了 + - ADR 起案 + - 複数 PR にまたがる作業計画の決定 + - 既存 planning doc への大規模追記 (Tier 1/2 構成変更等) + + 対象外 (= 通常 task として継続して問題ない): + + - 単一 PR scope 内の段階的 commit + - 既存計画通りの逐次実装 step + + GO/NO-GO 確認のフォーマット例: + + > Plan file 作成完了。次の step は PR-W0 (...) への着手です。進めて OK か? + + Auto mode の「prefer action over planning」原則の例外として、planning doc + レベルの完了点では明示承認待ちが必須。 + ``` + +- **由来 cite**: PR #218 session transcript で実観測した「Plan file 完了報告 → AI が PR-W0 着手 → ユーザー停止 + 'AI 先走り' 指摘」の流れを inline cite +- **memory `feedback_no_unauthorized_reorder` との関係**: 既存 memory は「task が blocked された時点で停止」を扱うが、本 rule は「task 完了時 (= 自然な区切り) で停止」を扱う = lifecycle の異なる stage を扱う相補的 rule +- **派生プロジェクト波及**: `~/.claude/CLAUDE.md` 編集のため全 project に自動波及、planning doc の頻度が高い大型 refactor PR で効果を発揮 +- **Auto mode との関係**: Auto mode 仕様の「prefer action over planning」と本 rule の「planning 完了時は停止」は scope 分離 (前者は通常作業の AI 自律性、後者は planning doc レベルの mile stone 確認) で衝突しない + +#### 作業計画 + +- [ ] `~/.claude/` snapshot 取得 (memory `feedback_global_config_backup` per) +- [ ] `~/.claude/CLAUDE.md` に新 sub-section「AI 先走り防止 — 計画文書作成完了時の GO/NO-GO ゲート」を追加 (上記設計決定の rule 内容、~30 行) +- [ ] markdownlint clean +- [ ] 本エントリ削除 + docs/todo-summary2.md 行削除 + +#### 完了基準 + +- `~/.claude/CLAUDE.md` に新 sub-section が追加される (対象 task 例 / 対象外 / フォーマット例 含む) +- PR #218 事例が inline cite として記録される +- 全プロジェクト (techbook-ledger / auto-review-fix-vc 含む) に global rule として自動波及 +- Auto mode 下でも planning doc 完了時点で AI が明示承認待ちに転じることが、次回以降の planning task で確認可能 + +#### 詰まっている箇所 + +- 対象範囲の境界定義: 「計画文書」「設計ドキュメント」「大きな task」の判定基準が author に依存する余地あり。MVP は上記「対象 task の例」「対象外」リストで運用、3+ 回の dogfood で境界明確化を判断 (順位 207 mechanical lint scope 外 boundary case 追加の pattern と同様) +- Auto mode 仕様との関係明示: `~/.claude/CLAUDE.md` の Auto mode セクションが追加 or 改訂されている場合、本 rule の例外条項 (「prefer action over planning」との関係) を Auto mode セクション側にも cross-reference するか判断 + +--- + +### `ACTIVE_RUN_FRESH_THRESHOLD_SECS` と `ORPHAN_THRESHOLD_SECS` の compile-time 同期 (PR #222 post-merge-feedback T1-1 採用) + +> **動機**: PR #222 で hooks-stop-quality に追加した `ACTIVE_RUN_FRESH_THRESHOLD_SECS = 1500` は、hooks-session-start reaper の `ORPHAN_THRESHOLD_SECS = 1500` と **同値である必要がある** (Stop hook が「active」と判定する window と、reaper が「orphan」と判定する threshold が非対称になると、その隙間に挟まった run が両方の防御層から漏れる)。現状は `hooks-stop-quality/src/main.rs:67` のコメント (「reaper の `ORPHAN_THRESHOLD_SECS` (= 1500s) と同値」) で同期を「人間が読んで覚える」契約に留まり、片方を変更したときに他方を追従する mechanical enforcement が欠落している。 +> +> 同型の precedent として `cli-merge-pipeline/src/feedback.rs:60` の `pub const ORPHAN_THRESHOLD_SECS: u64 = TAKT_TIMEOUT_SECS + 300;` が存在し、derived value として上流定数 (`TAKT_TIMEOUT_SECS`) との関係を compile-time で保証している。本 task は同じ pattern を hooks-stop-quality / hooks-session-start の magic number 同期にも適用する。 +> +> **本タスクの位置づけ**: PR #222 post-merge-feedback Tier 1 #1 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None、2026-06-27 ユーザー承認)。analyzer rationale: 「3 reports 全てで threshold alignment を言及。`cli-merge-pipeline` の precedent (const + assert 方式) が参照実装として存在、実装コスト低。drift 発生時に orphan detection window と quality gate skip window が非対称になるリスクが明確。Effort M かつ Frequency Medium で採用候補」。`feedback_tier_classification` per analyzer Tier 1 (= mechanical enforcement) → project Tier 2 (🔧) に再分類。 +> +> **参照**: `.claude/feedback-reports/222.md` Tier 1 #1、`src/hooks-stop-quality/src/main.rs:67` (現状のコメント契約 + 定数定義)、`src/hooks-session-start/src/reaper.rs:29` (source of truth = `pub(crate) const ORPHAN_THRESHOLD_SECS: u64 = 1500`)、`src/cli-merge-pipeline/src/feedback.rs:60` (precedent: derived const + 上流定数 reference)、ADR-043 (Security/Quality Gate Fail-Closed) — fail-closed threshold の同期が崩れた場合のリスクを ADR で論じる経路、ADR-030 (決定論的 Post-Merge Feedback) § L2 reaper — `ORPHAN_THRESHOLD_SECS` の出処、順位 224 (ADR-043 amendment、bundle 推奨)。 +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。lib 抽出 (shared crate / lib module) vs cross-crate const re-export + compile-time assert の選択 + test 追加。 + +#### 設計決定 (案、land 時に判断) + +3 案を比較し、本 task 着手時に Option 選択: + +- **Option A** (shared lib crate 新設): `src/lib-takt-constants/` 等の新 crate を作成し `ORPHAN_THRESHOLD_SECS` / `ACTIVE_RUN_FRESH_THRESHOLD_SECS` を pub const として公開。reaper と stop-hook 双方が dep として import。**Pros**: 単一の source of truth、将来 takt 関連の magic number 追加に scale。**Cons**: 新 crate のため Cargo workspace への追加 + build graph 拡張、ADR-026 (Cargo workspace) との整合確認、過剰一般化のリスク (Effort M の上限) +- **Option B** (cross-crate const re-export): hooks-session-start の `reaper::ORPHAN_THRESHOLD_SECS` を `pub` に昇格、hooks-stop-quality が `[dependencies] hooks-session-start = { path = "..." }` で依存し `use hooks_session_start::reaper::ORPHAN_THRESHOLD_SECS;` で参照。**Pros**: 新 crate 不要、変更最小。**Cons**: hooks crate 間の依存方向が逆 (本来は SessionStart hook と Stop hook は独立だが、これで一方向 dependency が発生)、cargo workspace の循環依存リスク (現状は問題なくとも将来制約に) +- **Option C** (compile-time assert via `const _: () = assert!(...)`): 各 hook crate で独立に const を定義しつつ、片方の crate 内で `const _: () = assert!(REAPER_ORPHAN_THRESHOLD_SECS == ACTIVE_RUN_FRESH_THRESHOLD_SECS);` 系の compile-time 検証を入れる。**Pros**: dep 依存 0、各 hook crate の autonomy 維持。**Cons**: 検証側 crate に「他 crate の値を埋め込む」必要があり、結局参照経路が必要 (= Option B と同等の依存になる) +- **MVP 推奨**: **Option B と C の hybrid** で、stop-hook 内に `const _: () = assert!(...)` を追加して const 同期を保証 (C 側のメリット) しつつ、`hooks-session-start::reaper::ORPHAN_THRESHOLD_SECS` を pub 昇格して hooks-stop-quality が dep として参照 (B 側のメリット)。Option A (新 crate) は将来同型 magic number が 3+ 出てきた時に再評価 +- **`cli-merge-pipeline/src/feedback.rs:60` の precedent を inline cite**: 上流定数 (`TAKT_TIMEOUT_SECS`) + derived const + 同 crate 内 const equality assert の構成例。本 task は cross-crate 版に拡張 +- **test 追加**: compile-time assert は失敗時 compile error なので runtime test は不要、ただし「片方の const を変更したら compile error になる」ことを確認する手順を README / コメントに記録 (PR description で dogfood) +- **派生プロジェクト transferability**: 本 pattern (cross-crate const sync) は派生プロジェクト (techbook-ledger / auto-review-fix-vc) でも同型ニーズが発生しうるが、現状は本 repo 固有のため transferability は ADR-016 / ADR-043 等への documentation 経由 + +#### 作業計画 + +- [ ] Option A / B / C 判断 (MVP 推奨 = Option B+C hybrid: assert で同期保証 + pub 昇格して dep 参照) +- [ ] `hooks-session-start::reaper::ORPHAN_THRESHOLD_SECS` を `pub` 昇格 (現状 `pub(crate)`)、必要なら module path の整理 +- [ ] hooks-stop-quality の `Cargo.toml` に `hooks-session-start` dep を追加 (Option B 側のアプローチ) +- [ ] hooks-stop-quality `main.rs` に `const _: () = assert!(ACTIVE_RUN_FRESH_THRESHOLD_SECS == hooks_session_start::reaper::ORPHAN_THRESHOLD_SECS);` を追加 +- [ ] `cargo build --workspace` で compile-time assert が通ることを確認、片方を変更して compile error を観測 (PR description に貼付) +- [ ] hooks-stop-quality の既存コメント (line 67) を「compile-time assert で同期保証」 に更新 +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- 片方の const を変更すると `cargo build` が compile error で失敗する +- hooks-stop-quality / hooks-session-start の magic number 同期が compile-time 契約として codified +- `cli-merge-pipeline/src/feedback.rs:60` precedent と同 pattern が確立、将来同型 magic number 追加時の参照実装になる +- ADR-030 §L2 と本 task の関係性が ADR 内で明示される (順位 224 と相補 = T1 mechanical + T3 docs) + +#### 詰まっている箇所 + +- Option A/B/C 判断: 新 crate 追加 vs 既存 dep 追加 vs assert macro のいずれも trade-off あり、ADR-026 (Cargo workspace) との整合性を実装時に確認 +- hooks crate 間の依存方向: SessionStart と Stop は本来独立な lifecycle stage だが、const 共有のため一方向 dep が必要 (Option B/C)。将来 hooks 共通 lib (= 順位 224 関連で hook_stop_quality の `meta_is_fresh` 抽出が浮上した場合) が出てきた際に再整理判断 + +--- + +### ADR-043 (Security/Quality Gate Fail-Closed) に hooks-stop-quality の error handling を具体例として追記 (PR #222 post-merge-feedback T3-1 採用) + +> **動機**: PR #222 で hooks-stop-quality に追加した `meta_is_fresh()` / `meta_is_active_run()` / `takt_subsession_active()` は、すべての error path で `false` を返却することで「gate が effective (= skip しない)」状態に倒す **fail-closed pattern** を踏襲している。具体的には mtime 取得失敗 / system clock skew (future timestamp) / malformed JSON / file read error すべてが「active subsession ではないと判定」→「quality gate を skip しない」= 安全側に倒れる。 +> +> ADR-043 (Security/Quality Gate での Fail-Closed 原則) は **試験運用 ADR** として既に存在するが、現状は abstract な原則記述に留まる。PR #222 の `meta_is_fresh` 実装は ADR-043 の **concrete instantiation** として価値があり、ADR 内の具体例 list に追記することで: +> +> - ADR が「概念定義 + 具体例 list」型に進化、将来同型 fail-closed pattern を実装する author の参照実装になる +> - 派生プロジェクト (techbook-ledger / auto-review-fix-vc) で hook / lint / pipeline を fail-closed で書く際の transferability 向上 (ADR は global 参照可能) +> - 順位 223 (mechanical enforcement) と相補的に、docs 層で fail-closed pattern を author 教育として codify +> +> **本タスクの位置づけ**: PR #222 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-27 ユーザー承認)。analyzer rationale: 「ADR-043 は永続 artifact で既存。追記は XS Effort で ADR の具体例を充実。fail-closed pattern は本 PR 以外でも発生する (Frequency Medium)。Effort XS + None risk で採用候補」。 +> +> **参照**: `.claude/feedback-reports/222.md` Tier 3 #1、`docs/adr/adr-043-security-gates-fail-closed.md` (追記対象、試験運用 ADR)、`src/hooks-stop-quality/src/main.rs` の `meta_is_fresh()` / `meta_is_active_run()` (具体例として cite)、PR #222 (`b0b91978`) (由来 cite)、順位 223 (T1 mechanical、bundle 推奨)、`feedback_global_config_backup` 適用は本リポジトリ docs/ のため不要 (グローバル CLAUDE.md / rules は触らない)。 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR-043 の既存 § 「concrete examples」 or 末尾に新 sub-section を追加 (~30 行)、mtime 取得失敗 / clock skew / malformed JSON / read error の 4 error path を列挙し、各 path で `false` 返却 → gate effective 維持を inline 説明。 + +#### 設計決定 (案) + +- **追記位置**: ADR-043 に既存「concrete examples」section があればそこへ追加。無ければ末尾 (References 直前) に新 sub-section 「Concrete instantiation: hooks-stop-quality の subsession freshness check (PR #222)」を追加 +- **記述項目**: + - 4 error path 各々で何が起き `false` 返却に倒れるか + - **mtime 取得失敗** (`std::fs::metadata()` error / `metadata.modified()` error): `Err(_) => return false` + - **system clock skew (future timestamp)**: `mtime.elapsed()` が `Err` を返した場合 `Err(_) => false` で skip 不可、orphan 扱いになる + - **malformed JSON**: `serde_json::from_str::` が `Err` → `Ok(_)` 以外は `false` + - **file read error**: 同上、`fs::read_to_string` が `Err` → `false` + - 全ての error path が「subsession active ではない」= 「Stop hook の quality gate を skip しない」に倒れる構造 = fail-closed + - 反対 pattern (fail-open = error path で `true` 返却) の anti-example: orphan 1 件が残るだけで全 session の quality gate が永続 skip → ADR-004 §「freshness check の必要性」で詳細解説 +- **由来 cite**: PR #222 で CR Major 指摘 (orphan 永続 skip リスク) に対応した freshness check 実装、ADR-004 amendment と本 ADR-043 追記の 2 ADR を同時更新した経緯を inline 引用 +- **派生プロジェクト transferability**: ADR は global 参照可能、本 ADR を `~/.claude/rules/common/` から link することで techbook-ledger / auto-review-fix-vc 等に reference 提供 +- **順位 223 との bundle**: 1 PR でまとめて land 推奨 (T1 mechanical layer + T3 docs layer の 2 層防御を 1 PR で確立) + +#### 作業計画 + +- [ ] ADR-043 現状を read、追記位置 (既存 concrete examples or 新 sub-section) を判断 +- [ ] 「Concrete instantiation: hooks-stop-quality の subsession freshness check (PR #222)」sub-section を追加 (~30 行) +- [ ] 4 error path の inline 説明 + anti-example (fail-open) の論理対比 +- [ ] PR #222 + ADR-004 § freshness check との cross-reference 追加 +- [ ] markdownlint clean +- [ ] 本 entry 削除 + todo-summary2.md 行削除 + +#### 完了基準 + +- ADR-043 に hooks-stop-quality の error handling が concrete example として追記される +- 4 error path 各々の `false` 返却 logic と「gate effective」状態への倒し方が明示される +- PR #222 / ADR-004 / ADR-043 の 3 文書間の cross-reference が成立、reader が 1 example から原則 → 適用 → 反対例を辿れる +- 順位 223 と合わせ、mechanical (T2) + docs (T3) の 2 層防御確立 + +#### 詰まっている箇所 + +- ADR-043 が現時点で試験運用 (= ephemeral 性質を残す) のため、concrete example 追記が本採用昇格のトリガーになりうるかは現状 ADR 内容を read してから判断 +- ADR-043 と ADR-004 の責務境界: 「fail-closed 原則の汎用論」(043) vs 「freshness check の必要性」(004) を ambiguous にせず、043 が「why fail-closed」、004 が「how freshness check works」と明確に分業する記述 + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。) diff --git a/docs/todo3.md b/docs/todo3.md index 50fa21f7..b9190972 100644 --- a/docs/todo3.md +++ b/docs/todo3.md @@ -2,7 +2,7 @@ > **運用ルール** ([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-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo2.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #88 以降の新規エントリは本ファイルに記録した。本ファイルも PR #96 セッションで 50KB 接近のため、それ以降の新規エントリは [docs/todo4.md](todo4.md) へ。todo.md / todo2-19.md の既存エントリは引き続き有効、相互に独立。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo4.md b/docs/todo4.md index a5772713..0ef9ff01 100644 --- a/docs/todo4.md +++ b/docs/todo4.md @@ -2,7 +2,7 @@ > **運用ルール** ([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-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo3.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録していた。**本ファイルも 50KB に到達したため、PR #101 セッション以降の新規エントリは [docs/todo5.md](todo5.md) へ**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-19.md の既存エントリは引き続き有効、相互に独立。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo5.md b/docs/todo5.md index 6c2600b4..c1bd079e 100644 --- a/docs/todo5.md +++ b/docs/todo5.md @@ -2,7 +2,7 @@ > **運用ルール** ([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-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo4.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #101 セッション以降の新規エントリは本ファイルに記録していた。**本ファイルも 67KB に到達したため、2026-05-09 に PR #101〜#109 由来の古い半分を [docs/todo7.md](todo7.md) へ分離した**。本ファイル残存は PR #110 以降のエントリのみ。新規エントリは [docs/todo6.md](todo6.md) へ。todo.md / todo2-19.md の既存エントリは引き続き有効、相互に独立。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo6.md b/docs/todo6.md index 2608a122..c8d0be42 100644 --- a/docs/todo6.md +++ b/docs/todo6.md @@ -2,7 +2,7 @@ > **運用ルール** ([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-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo5.md / 本ファイルが 50KB に到達 (PR #143 T3-#1) のため **新規エントリは [docs/todo8.md](todo8.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-19.md の既存エントリは引き続き有効、相互に独立。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo7.md b/docs/todo7.md index a0fdc8f8..e1c64644 100644 --- a/docs/todo7.md +++ b/docs/todo7.md @@ -2,7 +2,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-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: 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-19.md の既存エントリは引き続き有効、相互に独立。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo8.md b/docs/todo8.md index fb0f8d3f..a6617fec 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -2,7 +2,7 @@ > **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 > -> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #143 T3-#1 採用時 = 2026-05-11 から新規エントリは本ファイルに記録していた。**本ファイルも 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-14.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #143 T3-#1 採用時 = 2026-05-11 から新規エントリは本ファイルに記録していた。**本ファイルも 60KB に到達したため、PR #172 仕組み化方針切替セッション = 2026-05-25 以降の新規エントリは [docs/todo9.md](todo9.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md / todo7.md / todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo9.md b/docs/todo9.md index 9c35904d..a625d87b 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 の既存エントリは引き続き有効、相互に独立。**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-14.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)。新セッションでは21つすべてを確認すること (todo.md / todo2-19.md / todo-summary.md / todo-summary2.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/src/cli-docs-lint/src/preamble.rs b/src/cli-docs-lint/src/preamble.rs index 6a9273d3..5a504dd5 100644 --- a/src/cli-docs-lint/src/preamble.rs +++ b/src/cli-docs-lint/src/preamble.rs @@ -11,18 +11,17 @@ use std::fs; use std::path::{Path, PathBuf}; const PREAMBLE_SCAN_LINES: usize = 12; -const TODO_SUMMARY_FILE: &str = "todo-summary.md"; +/// 分割された index の全 part (todo-summary.md / todo-summary2.md / ...) にマッチする prefix。 +/// `is_todo_summary` (ファイル分類) と `check_line` (preamble の summary 参照判定) の両方で使い、 +/// 判定基準を一致させる (Phase 3 simplicity-review: 完全一致と prefix-match の混在は landmine)。 +const TODO_SUMMARY_PREFIX: &str = "todo-summary"; /// `docs/` 配下の preamble 整合性を検査する。 pub fn check(docs_dir: &Path) -> Result, String> { let todo_files = list_todo_files(docs_dir)?; let expected_total = todo_files.len(); - let has_summary = todo_files.iter().any(|p| is_todo_summary(p)); - let expected_without_summary = if has_summary { - expected_total.saturating_sub(1) - } else { - expected_total - }; + let summary_count = todo_files.iter().filter(|p| is_todo_summary(p)).count(); + let expected_without_summary = expected_total.saturating_sub(summary_count); let mut violations = Vec::new(); for path in &todo_files { @@ -79,7 +78,7 @@ fn check_line( )); }; - let includes_summary = line.contains(TODO_SUMMARY_FILE); + let includes_summary = line.contains(TODO_SUMMARY_PREFIX); let expected = if includes_summary { expected_total } else { @@ -118,7 +117,7 @@ fn number_regex() -> Regex { fn is_todo_summary(path: &Path) -> bool { path.file_name() .and_then(|s| s.to_str()) - .map(|name| name == TODO_SUMMARY_FILE) + .map(|name| name.starts_with(TODO_SUMMARY_PREFIX) && name.ends_with(".md")) .unwrap_or(false) } @@ -298,4 +297,51 @@ mod tests { v ); } + + #[test] + fn is_todo_summary_recognizes_split_parts() { + assert!(is_todo_summary(Path::new("todo-summary.md"))); + assert!(is_todo_summary(Path::new("todo-summary2.md"))); + assert!(!is_todo_summary(Path::new("todo3.md"))); + assert!(!is_todo_summary(Path::new("todo.md"))); + } + + /// 分割された index (todo-summary.md + todo-summary2.md) を両方 summary 扱いで + /// preamble check から skip し、かつ両方を count する。summary 参照ありは + /// expected_total (=4)、参照なしは expected_without_summary (= 4 - summary 2 = 2) と照合。 + #[test] + fn check_counts_split_summary_parts_and_skips_both() { + let tmp = TempDir::new().unwrap(); + write(&tmp.path().join("todo-summary.md"), "# S\n\n> 百つ\n"); + write(&tmp.path().join("todo-summary2.md"), "# S2\n\n> 百つ\n"); + write( + &tmp.path().join("todo.md"), + "# TODO\n\n> stuff\n>\n> 新セッションでは四つすべてを確認すること (todo.md / todo2.md / todo-summary.md)。\n", + ); + write( + &tmp.path().join("todo2.md"), + "# TODO\n\n> stuff\n>\n> 各 entry を確認すること。二つすべてを確認すること。\n", + ); + let v = check(tmp.path()).unwrap(); + assert!(v.is_empty(), "expected no violations, got {:?}", v); + } + + /// preamble が todo-summary.md を含まず todo-summary2.md のみを参照する場合でも + /// prefix-match (`TODO_SUMMARY_PREFIX`) で summary 参照と判定し expected_total と + /// 照合することを保証する回帰テスト (Phase 3 simplicity-review 指摘の follow-up)。 + #[test] + fn check_line_detects_summary_via_prefix_when_only_todo_summary2_referenced() { + let re = number_regex(); + let path = Path::new("todo3.md"); + let referenced = "> 新セッションでは五つすべてを確認すること (todo.md / todo2.md / todo-summary2.md)。"; + assert!( + check_line(path, 1, referenced, &re, 5, 3).is_none(), + "todo-summary2.md 参照は summary 扱いで expected_total=5 と一致すべき" + ); + let mismatched = "> 新セッションでは三つすべてを確認すること (todo.md / todo2.md / todo-summary2.md)。"; + assert!( + check_line(path, 1, mismatched, &re, 5, 3).is_some(), + "todo-summary2.md 参照時は expected_total(5) と照合するため 三つ(3) は violation になるべき" + ); + } } diff --git a/src/cli-docs-lint/src/priority_inversion.rs b/src/cli-docs-lint/src/priority_inversion.rs index caa2d012..7cccf3dd 100644 --- a/src/cli-docs-lint/src/priority_inversion.rs +++ b/src/cli-docs-lint/src/priority_inversion.rs @@ -33,7 +33,9 @@ static TIER_REGEX: LazyLock = static RANK_REGEX: LazyLock = LazyLock::new(|| Regex::new(r"順位\s*(\d+)(?:/(\d+))?").expect("static rank regex must compile")); -const SUMMARY_FILE: &str = "todo-summary.md"; +/// 分割された index の全 part にマッチする name prefix。 +/// `todo-summary.md` / `todo-summary2.md` / 将来の `todo-summary3.md` を含む。 +const SUMMARY_FILE_PREFIX: &str = "todo-summary"; /// 依存記述近傍で「解決済」を示す substring。順位参照の **直後 RESOLUTION_WINDOW_CHARS /// 文字以内** にいずれかが含まれていれば、その順位参照は resolved 扱い (= inversion @@ -44,24 +46,54 @@ const RESOLVED_MARKERS: &[&str] = &["land 済", "完了", "retired", "retire 済 /// multi-byte 文字でも spec 通りの 80 文字 window を保証する。 const RESOLUTION_WINDOW_CHARS: usize = 80; -/// `docs/` 配下の todo-summary.md を読み inversion を検査する。 +/// `docs/` 配下の todo-summary*.md (分割された index の全 part) を読み inversion を検査する。 +/// +/// 複数 part にまたがる場合も **全 part の row を統合してから** tier_by_rank を構築するため、 +/// part をまたいだ cross-file 依存 (例: part1 の Tier1 が part2 の Tier2 に依存) も検査対象になる。 pub fn check(docs_dir: &Path) -> Result, String> { - let path: PathBuf = docs_dir.join(SUMMARY_FILE); - if !path.exists() { - return Ok(vec![]); + let mut rows: Vec = Vec::new(); + for path in list_summary_files(docs_dir)? { + let content = fs::read_to_string(&path) + .map_err(|e| format!("読み込み失敗 {}: {}", path.display(), e))?; + rows.extend(parse_table_rows(&content, &path)); } - let content = fs::read_to_string(&path) - .map_err(|e| format!("読み込み失敗 {}: {}", path.display(), e))?; - Ok(check_content(&path, &content)) + Ok(check_rows(&rows)) } -/// 与えられた markdown 内容から inversion violations を抽出する。 +/// `docs/todo-summary*.md` を name 順に列挙する (分割された index の全 part)。 +fn list_summary_files(docs_dir: &Path) -> Result, String> { + let entries = fs::read_dir(docs_dir) + .map_err(|e| format!("docs ディレクトリ読み込み失敗 {}: {}", docs_dir.display(), e))?; + let mut paths: Vec = Vec::new(); + for entry in entries.flatten() { + let path = entry.path(); + if !path.is_file() { + continue; + } + let Some(name) = path.file_name().and_then(|s| s.to_str()) else { + continue; + }; + if name.starts_with(SUMMARY_FILE_PREFIX) && name.ends_with(".md") { + paths.push(path); + } + } + paths.sort(); + Ok(paths) +} + +/// 与えられた単一ファイルの markdown 内容から inversion violations を抽出する。 pub fn check_content(path: &Path, content: &str) -> Vec { - let rows = parse_table_rows(content); + check_rows(&parse_table_rows(content, path)) +} + +/// 収集済みの全 row から inversion violations を抽出する。 +/// tier_by_rank は渡された row 全体 (= 全 part) から構築するため、分割された +/// summary 間の cross-file 依存も検査される。violation は各 row の出自 (file/line) に帰属する。 +fn check_rows(rows: &[TableRow]) -> Vec { let tier_by_rank: HashMap = rows.iter().map(|r| (r.rank, r.tier)).collect(); let mut violations = Vec::new(); - for row in &rows { + for row in rows { if has_no_dependency_prefix(&row.dependency) { continue; } @@ -78,7 +110,7 @@ pub fn check_content(path: &Path, content: &str) -> Vec { if is_rank_resolved(&row.dependency, dep_rank) { continue; } - violations.push(make_violation(path, row, dep_rank, dep_tier)); + violations.push(make_violation(row, dep_rank, dep_tier)); } } violations @@ -90,9 +122,11 @@ struct TableRow { tier: u32, dependency: String, line: usize, + /// row の出自ファイル。分割された summary で violation を正しい part に帰属させる。 + path: PathBuf, } -fn parse_table_rows(content: &str) -> Vec { +fn parse_table_rows(content: &str, path: &Path) -> Vec { content .lines() .enumerate() @@ -101,6 +135,7 @@ fn parse_table_rows(content: &str) -> Vec { tier, dependency: dep, line: idx + 1, + path: path.to_path_buf(), })) .collect() } @@ -193,9 +228,9 @@ fn has_resolved_marker_after(haystack: &str, needle: &str) -> bool { false } -fn make_violation(path: &Path, row: &TableRow, dep_rank: u32, dep_tier: u32) -> Violation { +fn make_violation(row: &TableRow, dep_rank: u32, dep_tier: u32) -> Violation { Violation { - file: path.display().to_string(), + file: row.path.display().to_string(), line: row.line, message: format!( "priority inversion 検出: 順位 {} (Tier {}) が 順位 {} (Tier {}) に依存しています。\ @@ -210,6 +245,7 @@ fn make_violation(path: &Path, row: &TableRow, dep_rank: u32, dep_tier: u32) -> mod tests { use super::*; use std::path::Path; + use tempfile::TempDir; fn fake_path() -> &'static Path { Path::new("docs/todo-summary.md") @@ -401,4 +437,72 @@ mod tests { assert!(violations[0].message.contains("順位 100")); assert!(violations[0].message.contains("順位 90")); } + + #[test] + fn list_summary_files_returns_all_parts_sorted() { + let tmp = TempDir::new().unwrap(); + fs::write(tmp.path().join("todo-summary.md"), "").unwrap(); + fs::write(tmp.path().join("todo-summary2.md"), "").unwrap(); + fs::write(tmp.path().join("todo.md"), "").unwrap(); + fs::write(tmp.path().join("README.md"), "").unwrap(); + let files = list_summary_files(tmp.path()).unwrap(); + let names: Vec = files + .iter() + .map(|p| p.file_name().unwrap().to_string_lossy().to_string()) + .collect(); + assert_eq!(names, vec!["todo-summary.md", "todo-summary2.md"]); + } + + /// 分割された index (todo-summary.md + todo-summary2.md) を跨ぐ inversion を + /// 統合 tier_by_rank で検出し、violation が part2 (出自ファイル) に帰属することを保証する。 + /// 分割で priority-inversion カバレッジが半減しないことの回帰テスト (Phase 3)。 + #[test] + fn check_detects_cross_part_inversion_attributed_to_source_part() { + let tmp = TempDir::new().unwrap(); + fs::write( + tmp.path().join("todo-summary.md"), + "| 順位 | Tier | タスク | ファイル | 工数 | 依存 |\n\ + |---|---|---|---|---|---|\n\ + | 19 | 🔧 Tier 2 | task | todo3.md | M | なし |\n", + ) + .unwrap(); + fs::write( + tmp.path().join("todo-summary2.md"), + "| 順位 | Tier | タスク | ファイル | 工数 | 依存 |\n\ + |---|---|---|---|---|---|\n\ + | 220 | 🚀 Tier 1 | task | todo14.md | M | 順位 19 land 後推奨 |\n", + ) + .unwrap(); + let violations = check(tmp.path()).unwrap(); + assert_eq!( + violations.len(), + 1, + "cross-part inversion should be detected, got {:#?}", + violations + ); + assert!( + violations[0].file.contains("todo-summary2.md"), + "violation は part2 (出自) に帰属すべき: {}", + violations[0].file + ); + assert!(violations[0].message.contains("順位 220")); + assert!(violations[0].message.contains("順位 19")); + } + + /// 単一 part のみ (todo-summary.md だけ) でも従来どおり動作する回帰テスト。 + #[test] + fn check_single_part_still_works() { + let tmp = TempDir::new().unwrap(); + fs::write( + tmp.path().join("todo-summary.md"), + "| 順位 | Tier | タスク | ファイル | 工数 | 依存 |\n\ + |---|---|---|---|---|---|\n\ + | 19 | 🔧 Tier 2 | task | todo3.md | M | なし |\n\ + | 34 | 🚀 Tier 1 | task | todo4.md | M | 順位 19 land 後推奨 |\n", + ) + .unwrap(); + let violations = check(tmp.path()).unwrap(); + assert_eq!(violations.len(), 1); + assert!(violations[0].file.contains("todo-summary.md")); + } }