From ebb166ef4d2b02b2fd8776020c8c43c19af5941f Mon Sep 17 00:00:00 2001 From: aloekun Date: Fri, 12 Jun 2026 12:27:02 +0900 Subject: [PATCH 1/5] =?UTF-8?q?docs(todo):=20=E9=A0=86=E4=BD=8D=20198=20?= =?UTF-8?q?=E3=82=92=20PR=20#203=20T3-1=20=E6=8E=A1=E7=94=A8=E3=81=A7=203?= =?UTF-8?q?=20=E8=A6=B3=E6=B8=AC=E7=9B=AE=E3=81=AB=E6=98=87=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #203 post-merge-feedback Tier 3 #1 (ADR-NNN: Timestamp invariant safety) を採用。 analyzer は新規 entry 提案だが、順位 198 が既に同 ADR 提案として登録済 (PR #199 T3-2) のため、新規追加ではなく既存 entry の data point 強化として merge した。 主な変更: - 動機: 2 件観測 (Medium) → 3 件観測 (High) に Frequency 昇格 - 本タスクの位置づけ: PR #203 T3-1 採用情報 + 既存 entry 強化の判断根拠を追記 - 参照: .claude/feedback-reports/203.md Tier 3 #1 + PR #203 を追加 - 設計決定 § 1 コンテキスト: PR #203 hooks-session-start port を観測実例に追加 - 派生プロジェクト適用: "順位 197 で実装予定" → "PR #203 で実装済" に更新 - 作業計画: PR #96 / #199 / #203 の 3 観測すべてを ADR 実装時に inline cite 順位 194 (task 着手前 grep 確認 rule、PR #196 採用) の初実践例となる。 analyzer の重複提案を運用層で吸収する明示的 pattern。 --- docs/todo-summary.md | 2 +- docs/todo10.md | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/todo-summary.md b/docs/todo-summary.md index f40b21cb..ac2ad33a 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -77,7 +77,7 @@ | 193 | 🔧 Tier 2 | **Companion helper group 署名整合 compile-time validation test (PR #196 T2-1 採用) ★ Bundle 195-FB follow-up** | todo10.md | S | なし (Bundle 195-FB で 3 関数目の signature drift が CR Major + pre-push F-1 で systemic 観測、rule⑫ は literal hardcode 層、本タスクは API signature 整合性層、関数ポインタ cast による compile-time witness で signature drift を test 不通過に。`code-review.md` § Review Checklist に reviewer 注意 1 項目追加で 3 層防御 = rule⑫ + compile-time test + reviewer 注意、`feedback_global_config_backup` 適用必須) | | 194 | 💎 Tier 3 | **`development-workflow.md` 「1. Plan First」に「task 着手前に grep で既存 section 確認」step 追記 (PR #196 T3-5 採用)** | todo10.md | XS | なし (PR #123 + #196 で「既実装 section の重複計画」事象を Frequency Medium で観測、`~/.claude/rules/common/development-workflow.md` "1. Plan First" に Codification 重複確認 step を 1-2 行追記、`grep -rn` 手順 + 由来 cite (PR #123, #196)、派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及、`feedback_global_config_backup` 適用必須) | -| 198 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用)** | todo10.md | M | なし (PR #96 Finding D + PR #199 Bundle W で同型 bug class 2 件観測 = Frequency Medium、PastTime newtype + proptest が実証した型層防御原則を ADR で永続化、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 確保、順位 135 placeholder policy 適用、CLAUDE.md ADR list 追記) | +| 198 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用、PR #203 T3-1 で 3 観測目に昇格)** | todo10.md | M | なし (PR #96 Finding D + PR #199 Bundle W + PR #203 hooks-session-start port で同型 bug class **3 件観測 = Frequency High**、PastTime newtype + proptest が実証した型層防御原則を ADR で永続化、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 確保、順位 135 placeholder policy 適用、CLAUDE.md ADR list 追記) | | 199 | 🔧 Tier 2 | **multi-byte 文字を含む string window test の標準 coverage requirement 化 (PR #200 post-merge-feedback T2-1 採用)** | todo10.md | S | なし (PR #199 byte 計算混乱 + PR #200 priority_inversion char window bug の 2 観測 = Frequency Medium、`is_resolved_detects_marker_across_multibyte_gap` style を testing.md に標準化、新 validator 追加時に CJK 40 文字 (= 120 bytes) gap 含む multi-byte test を必須化、MVP は docs/checklist、3-5 validator land 後に lint rule 化を再評価) | | 200 | 💎 Tier 3 | **`~/.claude/rules/rust/patterns.md` に「String Indexing with Multi-byte Characters」section 追加 (PR #200 post-merge-feedback T3-1 採用)** | todo10.md | XS | なし (PR #199 parse_age_secs + PR #200 priority_inversion の 2 観測 = Frequency Medium、`char_indices().nth(N)` canonical reference を global rules に追加して将来の lint rule 著者が同型 byte/char 混同 bug を再生産しないよう構造的予防、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へも自動波及、`feedback_global_config_backup` 適用必須) | | 201 | 💎 Tier 3 | **ADR-007 に「Regex は loop / repeated call 内で `LazyLock` 必須」guideline 追記 (PR #200 post-merge-feedback T3-2 採用)** | todo10.md | XS | なし (PR #200 priority_inversion で per-row `Regex::new()` 再 compile を `LazyLock` 化した F-2 fix を ADR-007 § 正規表現層 に guideline として追記、`TIER_REGEX` / `RANK_REGEX` を参照実装として cite、1000+ 行 table での累積コスト顕在化を予防) | diff --git a/docs/todo10.md b/docs/todo10.md index 127cb238..00778672 100644 --- a/docs/todo10.md +++ b/docs/todo10.md @@ -388,35 +388,36 @@ fn companion_helpers_share_default_branch_signature() { --- -### ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用) +### ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用、PR #203 T3-1 で 3 観測目に昇格) -> **動機**: PR #96 Finding D (`cli-pr-monitor::lock` の `parse_age_secs` で `saturating_sub` silent semantic mismatch) と PR #199 Bundle W (PastTime newtype + proptest で構造的予防) で同型 bug class が 2 件観測 (Frequency Medium)。本 ADR は「時刻計算における silent failure class と型レベル防御」を永続化し、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability を確保する。 +> **動機**: PR #96 Finding D (`cli-pr-monitor::lock` の `parse_age_secs` で `saturating_sub` silent semantic mismatch)、PR #199 Bundle W (`cli-pr-monitor::lock` に PastTime newtype + proptest で構造的予防)、PR #203 (`hooks-session-start` に PastTime + proptest 移植) で同型 bug class が **3 件観測 (Frequency High)**。本 ADR は「時刻計算における silent failure class と型レベル防御」を永続化し、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability を確保する。 > -> **本タスクの位置づけ**: PR #199 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None、2026-06-08 ユーザー承認)。順位 135 codified placeholder policy を適用し ADR 番号は land 時 PR で空き番号を確定する (本 entry 登録時点で ADR-038/039/040/041/042/043 占有済、044 が最有力候補だが land 時に再確認)。 +> **本タスクの位置づけ**: PR #199 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None、2026-06-08 ユーザー承認)。PR #203 post-merge-feedback Tier 3 #1 で 3 観測目として再確認、2026-06-11 ユーザー承認 (analyzer は新規 entry を提案したが既存 entry 強化として merge、`feedback_post_merge_feedback_adoption_requires_user_approval` + 順位 194「task 着手前に grep」適用)。順位 135 codified placeholder policy を適用し ADR 番号は land 時 PR で空き番号を確定する (本 entry 登録時点で ADR-038/039/040/041/042/043 占有済、044 が最有力候補だが land 時に再確認)。 > -> **参照**: `.claude/feedback-reports/199.md` Tier 3 #2、PR #96 Finding D、PR #199 Bundle W (PastTime newtype 実装 + proptest properties 5 件)、`~/.claude/rules/rust/patterns.md` § Newtype Pattern (extension 候補)、順位 135 (ADR 番号 hardcode 撤廃 policy)、順位 78 (旧 ADR-038 → 041 → NNN の 3 段振り直し実証) +> **参照**: `.claude/feedback-reports/199.md` Tier 3 #2、`.claude/feedback-reports/203.md` Tier 3 #1、PR #96 Finding D、PR #199 Bundle W (PastTime newtype 実装 + proptest properties 5 件)、PR #203 (hooks-session-start への port + integration test 追加)、`~/.claude/rules/rust/patterns.md` § Newtype Pattern (extension 候補)、順位 135 (ADR 番号 hardcode 撤廃 policy)、順位 78 (旧 ADR-038 → 041 → NNN の 3 段振り直し実証) > -> **実行優先度**: 💎 **Tier 3** — 工数 Medium。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記。 +> **実行優先度**: 💎 **Tier 3** — 工数 Medium。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記。Frequency High (3 PR) に昇格したため優先度内で着手順を引き上げる余地あり。 #### 背景 - **Bug class の定義**: `saturating_sub(now, then)` 等の silent fallback が dominate ドメイン的に誤った値 (age=0) を返し、後段の判定で「fresh」「young」等の誤判定を生む - **発生条件**: clock rewind (NTP 巻き戻し / VM snapshot restore) / 破損 future timestamp (corrupted lock file / 不正 input) / 時刻取得失敗 → silent fallback - **防御原則**: 業務ロジック的に不可能な状態 (future timestamp の存在) を型層で unrepresentable にする。construction 時に invariant 検証、`age_secs()` 等の derived 値は invariant により安全に計算 -- **実証パターン**: PR #199 Bundle W で `PastTime { epoch_secs, captured_now }` newtype + `from_iso8601_now` / `from_parts` 2 経路 + `age_secs()` non-negative invariant + proptest 5 properties で構造化 +- **実証パターン**: PR #199 Bundle W で `PastTime { epoch_secs, captured_now }` newtype + `from_iso8601_now` / `from_parts` 2 経路 + `age_secs()` non-negative invariant + proptest 5 properties で構造化、PR #203 で同 pattern を `hooks-session-start` の orphan reaper に展開 (`saturating_sub` 排除 + integration test `find_orphans_skips_future_start_time_without_silent_age_zero` 追加) #### 設計決定 (案) - **ADR title (案)**: 「Timestamp invariant safety — 時刻計算 silent failure class と型レベル防御」 - **ADR sections (案)**: - 1. **コンテキスト**: bug class 定義 + 観測実例 (PR #96 Finding D / PR #199 Bundle W) + 1. **コンテキスト**: bug class 定義 + 観測実例 (PR #96 Finding D / PR #199 Bundle W / PR #203 hooks-session-start port) 2. **決定**: - 原則 1: `saturating_sub` を時刻計算で使用しない (silent fallback 禁止) - 原則 2: 「過去性」を型で表現する (newtype + construction 時 invariant) - 原則 3: proptest properties で type invariant を executable contract として記述 3. **設計哲学**: 「業務ロジック的に impossible な状態を型層で unrepresentable にする」(parse, don't validate 派生) - 4. **派生プロジェクト適用**: cli-pr-monitor (実装済) / hooks-session-start (順位 197 で実装予定) / 派生プロジェクトの時刻計算箇所 (検出→展開計画) - 5. **完了状態 / 関連 ADR**: PR #199 (実証)、ADR-021 / ADR-024 等の参照 + 4. **派生プロジェクト適用**: cli-pr-monitor (PR #199 で実装済) / hooks-session-start (PR #203 で実装済、共通 lib 化は順位 T2-1 で別 task) / 派生プロジェクトの時刻計算箇所 (検出→展開計画) + 5. **完了状態 / 関連 ADR**: PR #199 (実証)、PR #203 (port 実証)、ADR-021 / ADR-024 等の参照 + - **CLAUDE.md ADR list**: 「ADR-NNN: Timestamp invariant safety + saturating_sub による silent fallback 禁止 *(試験運用)*」として追記 #### 作業計画 @@ -424,7 +425,7 @@ fn companion_helpers_share_default_branch_signature() { - [ ] land 時 PR で ADR 空き番号を確定 (現状最有力は ADR-044) - [ ] `docs/adr/adr-NNN-timestamp-invariant-safety.md` を新規作成 (試験運用) - [ ] CLAUDE.md ADR list に追記 -- [ ] PR #96 Finding D / PR #199 Bundle W を実例として inline cite +- [ ] PR #96 Finding D / PR #199 Bundle W / PR #203 hooks-session-start port を実例として inline cite - [ ] (任意) `~/.claude/rules/rust/patterns.md` § Newtype Pattern に link back を追記 (順位 T3-1 様子見と連動で判断) - [ ] 本 todo10.md エントリを削除 From a886cb5f79f0f83a5888a38d86c6313cf9704f59 Mon Sep 17 00:00:00 2001 From: aloekun Date: Fri, 12 Jun 2026 13:44:36 +0900 Subject: [PATCH 2/5] =?UTF-8?q?docs(adr-039):=20mechanical=20lint=20except?= =?UTF-8?q?ion=20=E3=82=92=20=C2=A7=201.b=20=E3=81=A8=E3=81=97=E3=81=A6?= =?UTF-8?q?=E6=98=8E=E8=A8=98=20+=20checklist=20=E4=B8=8A=E4=BD=8D?= =?UTF-8?q?=E5=88=A4=E5=AE=9A=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #203 post-merge-feedback で「順位 177 file_size_check が ADR-039 機械適用で default OFF にされ、user 期待と乖離した」事象を発見。順位 147 file_length lint (default ON 固定) と順位 177 file_size_check (default OFF) の asymmetry が 標準パターンの over-application を示した。 主な変更: § 1 (Config opt-in) の改訂 - 「適用対象を明示」する section に再構成 - 「behavior の妥当性が不確定な experimental feature」と適用範囲を限定 - 「採否判定 (採用 / 却下 / 継続) のフェーズが必要なもの」を判定基準として追加 § 1.b 新設 (mechanical lint default ON 許容) - 4 条件 (non-blocking / 決定論 / scope 限定 / recovery hint 明確) すべて満たす機能を § 1 対象外として default ON 配布を許容 - 該当する実装例: 順位 147 file_length lint / 順位 177 file_size_check - 該当しない例: post-merge-feedback (ADR-014/030) / weekly-review (ADR-031) / local-llm-finding-classification (ADR-038) - PR #197 順位 177 の誤適用を本 PR (PR #203 由来) で訂正と明記 § 新規 feature 追加時 checklist (4 点 → 5 点に拡張) - § 0 「上位判定」を最初に追加: 「そもそも § 1 適用対象か?」 - § 1.b 4 条件すべて満たす → default ON で配布、4 点 checklist は skip - 1 つでも欠ける → 従来通り 4 点 mechanical checklist 実施 - 判断に迷う場合は conservative default (default OFF) を選択 - 本判定を skip して機械適用すると order-application 発生 (PR #197 で実観測) 由来: PR #203 post-merge-feedback で発見された systemic 問題への対応。 派生プロジェクトへの自動波及はなし (本 ADR は本リポジトリ専用、`~/.claude/rules/` 配下ではないため)。 --- ...9-experimental-feature-standard-pattern.md | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/docs/adr/adr-039-experimental-feature-standard-pattern.md b/docs/adr/adr-039-experimental-feature-standard-pattern.md index 51d37646..f4e27a33 100644 --- a/docs/adr/adr-039-experimental-feature-standard-pattern.md +++ b/docs/adr/adr-039-experimental-feature-standard-pattern.md @@ -40,13 +40,43 @@ 試験運用 feature を導入する際の **標準パターン** として 3 点セットを以下の通り規定する。新規試験運用 ADR は本 ADR を **参照** し、3 点を満たすことを default とする。 -### 1. Config opt-in (デフォルト無効) +### 1. Config opt-in (デフォルト無効) — 適用対象を明示 + +本 § は **behavior の妥当性が不確定な** experimental feature に適用する。具体的には: + +- 挙動が後の dogfood で「失敗 / 却下 / 方向転換」されうるもの +- false positive 発生時に多数 user / session に影響するもの +- 採否判定 (採用 / 却下 / 継続) のフェーズが必要なもの + +該当する場合: - 設定ファイル (`*.toml`) または env var で `enabled = false` をデフォルトとする - 明示有効化 (`enabled = true`) で feature 発動 - env var / config 値での切り替えを必ず提供 (config-only より env override 可能な方が望ましい) - 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への deploy 時にも default OFF が継承されるよう、`[feature]` section の追加を必須化 +### 1.b 適用対象外: 決定論的 mechanical lint (default ON 許容、PR #203 post-merge-feedback 由来) + +以下条件をすべて満たす機能は § 1 (default OFF) の対象外とし、**default ON で配布してよい**: + +1. **失敗 mode が non-blocking**: block ではなく additionalContext / warning のみ (ユーザー操作を妨げない) +2. **判定が決定論的**: 閾値 (例: 50KB) / 文字列 match (例: regex) / metadata 演算で discretionary 判断を含まない +3. **影響範囲が宣言的に限定**: scope filter (`paths` glob / extension match 等) で適用箇所が config or const で限定済み +4. **recovery hint が明確**: 違反検出時に「次にやるべきこと」が message に含まれる + +該当する例 (本リポジトリで既に default ON 稼働中): + +- **順位 147 file_length lint** (`hooks-post-tool-comment-lint-rust`、Rust source 800 行 max): `const MAX_FILE_LINES = 800` で固定、config 不在 = ON 固定 +- **順位 177 file_size_check** (`hooks-post-tool-linter` § Layer 0.5、metadata-only 50KB threshold): touch-trigger ratchet で grandfather + paths glob で scope 限定 + +該当**しない**例 (default OFF が正しい): + +- post-merge-feedback (ADR-014/030): 挙動が dogfood で確定する experimental +- weekly-review (ADR-031): 採否判定要、reminder 頻度や observation rubric が dogfood で進化 +- local-llm-finding-classification (ADR-038): classification 精度が dogfood で判定 + +**過去の誤適用**: PR #197 で順位 177 file_size_check を ADR-039 § 1 機械適用で default OFF にしたが、本 PR (PR #203 post-merge-feedback 由来) で「決定論的 mechanical lint = § 1.b 例外で default ON」へ訂正。順位 147 と同様の扱いに統一。 + ### 2. Kill-switch (停止経路の事前明文化) - revert PR で `enabled = false` に戻す経路を **PR body / ADR で明文化** @@ -82,7 +112,20 @@ decision trigger は **config (TOML コメント) / code comment (module doc) / ### 新規 experimental feature 追加時の self-review checklist -新規 experimental feature を追加する PR では、push 前 self-review で以下 4 点の整合を **mechanical に** 確認する。各点は discretionary 判断を含まず、config / code / docs / test の差分を機械的に照合できる: +新規 feature を追加する PR では、push 前 self-review で以下 5 点 (上位 1 件 + mechanical 4 件) の整合を確認する。**上位判定で「§ 1.b 例外」に該当した場合は 4 点 checklist を skip し、default ON で配布**する: + +#### 0. 上位判定: そもそも § 1 適用対象か? (PR #203 post-merge-feedback 由来) + +§ 1.b の 4 条件 (non-blocking / 決定論 / scope 限定 / recovery hint 明確) をすべて満たすか self-check する: + +- **すべて満たす** → § 1.b 例外、default ON で配布 (順位 147 file_length lint / 順位 177 file_size_check と同 pattern) +- **1 つでも欠ける** → § 1 適用、以下 4 点 checklist を実施 + +判断に迷う場合は 4 点 checklist を実施する側 (default OFF) を選択 (= conservative default)。本判定を skip して機械的に 4 点 checklist を実施すると、決定論的 mechanical lint を誤って opt-in 化する over-application が発生する (PR #197 順位 177 で実観測、PR #203 で訂正)。 + +#### 1-4. § 1 適用時の mechanical 4 点 (config / code / docs / test) + +各点は discretionary 判断を含まず、config / code / docs / test の差分を機械的に照合できる: 1. **config schema**: 該当 hook / module の config struct (例: `WeeklyReviewReminderConfig`) が `enabled: Option` field を持つ 2. **feature flag default OFF**: 該当 config の `enabled` の default が **OFF** (= `unwrap_or(false)`) になっている。`unwrap_or(true)` は § 決定 1 (Config opt-in) 違反 From 233beb41d6cb8835534ed371f88419a59f27242d Mon Sep 17 00:00:00 2001 From: aloekun Date: Fri, 12 Jun 2026 13:46:23 +0900 Subject: [PATCH 3/5] =?UTF-8?q?docs(adr-007):=20Layer=200.5=20file=5Fsize?= =?UTF-8?q?=5Fcheck=20=E8=BF=BD=E8=A8=98=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 順位 177 file_size_check は ADR-007 で扱う「正規表現層 / AST 層」の判断フロー対象外で あり、metadata-only check (`std::fs::metadata.len()`) という性質上、独立した Layer 区分を設ける積極的理由がない。「Layer 0.5」概念を ADR に codify することで: - 後続の metadata-only check 追加時に Layer 0.5 への配置判断を毎回迫る - ADR-007 本体の Q1/Q2/Q3 判断フロー (regex / AST) との整合性が複雑化 - ADR-039 opt-in pattern 言及が「導入リスク」未定義のまま記載されている という systemic な over-abstraction の温床になっていた。本 PR で「順位 177 は単純な custom linter の一つとして扱う」方針 (ユーザー判断、2026-06-12) に従い、Layer 0.5 追記を削除する。今後 file_size_check 系の linter を追加する場合は ADR-007 の通常 判断フローに従い、必要なら都度 ADR 改訂で対応する。 --- docs/adr/adr-007-custom-linter-layer-boundary.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/adr/adr-007-custom-linter-layer-boundary.md b/docs/adr/adr-007-custom-linter-layer-boundary.md index 0bc283f8..a840f003 100644 --- a/docs/adr/adr-007-custom-linter-layer-boundary.md +++ b/docs/adr/adr-007-custom-linter-layer-boundary.md @@ -153,7 +153,3 @@ PR #98 (Bundle Y2) post-merge-feedback で `post-pr-review.yaml` supervise step - TOML rule コメントに field 拡張手順を 4 ステップで記述(grep → alternation 追加 → test helper 追加 → fixture test + TOML test 宣言追加) - 各 field について `_detects__violation` 命名規約で個別 fixture test を確保(一括 test では削除回帰が検知不可能) - `[rules.test_coverage.main_ext_tests]` 宣言で test 名を機械強制レイヤに接続する - -## Layer 0.5 追記: file_size_check (2026-06-07、順位 177 由来) - -`[post_tool_use.file_size_check]` (PR #197 land、`hooks-post-tool-linter` 統合) は本 ADR の Q1/Q2/Q3 判断フロー対象外。ファイル content を読まず metadata (`std::fs::metadata.len()`) のみで判定する **正規表現層未満の Layer 0.5** に位置し、Layer 0 (UTF-8 整合性) と Layer 1 (正規表現 custom-rules) の間で発火する。`paths` glob filter (順位 102 / Phase D D-3 と同 helper 共有) で対象を絞り、ADR-039 opt-in pattern (default OFF + bounded lifetime dogfood) で導入リスクを抑制する。同型 (metadata-only、content 非依存) の future check は同 Layer 0.5 に追加することで regex/AST 層との責務分離が維持される。 From 9be57378cf5a270867deae4c31bafeec3535e5c6 Mon Sep 17 00:00:00 2001 From: aloekun Date: Fri, 12 Jun 2026 13:47:29 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix(hooks-config):=20file=5Fsize=5Fcheck=20?= =?UTF-8?q?=E3=82=92=20default=20ON=20=E5=8C=96=20+=20ADR=20=E5=8F=82?= =?UTF-8?q?=E7=85=A7=E8=A1=A8=E8=A8=98=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADR-039 § 1.b (mechanical lint 例外、本 PR で同時 codify) に従い、順位 177 file_size_check を default ON で配布する。順位 147 file_length lint と同 pattern。 主な変更: enabled = false → enabled = true - 4 条件 (non-blocking / 決定論的閾値 / scope 限定 / recovery hint 明確) すべて満たすため - additionalContext warning のみで block しない (failure mode が無害) - paths glob で scope 宣言的に限定 - todo*.md / Rust source に明示的 recovery hint コメント修正: - "ADR-039 § 3 opt-in pattern" → "ADR-039 § 1.b mechanical lint 例外" (§ 3 は bounded lifetime、opt-in は § 1。元コメントは誤参照) - "Layer 0.5" → "custom linter" (ADR-007 Layer 0.5 追記削除に追従) - 4 条件 (1.b 適用根拠) を明示 - 順位 147 file_length lint を同類例として cite - bounded lifetime dogfood の記述を削除 (mechanical lint は dogfood phase 不要) 影響: - 既存 grandfather (>50KB 既存ファイル) は touch されるまで warning なし - 触られた >50KB ファイル (例: docs/todo10.md) は次の Edit/Write で warning が出る - 本 PR で todo10.md の split (Commit 5) を同時実施し、初回 dogfood も完了させる --- .claude/hooks-config.toml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.claude/hooks-config.toml b/.claude/hooks-config.toml index 41fd06e5..20498028 100644 --- a/.claude/hooks-config.toml +++ b/.claude/hooks-config.toml @@ -98,17 +98,23 @@ grep_recent_limit = 20 # jj log で参照する直近 commit 数 # 順位 177 (PR #197 で Tier 1 (優先実装) 格上げ) で実装。 # PostToolUse Edit/Write 直後にファイルサイズを確認し、threshold (50KB) 超過時に # additionalContext でファイル分割を促す。Claude Code 読み取り安定性閾値 (50KB) を -# 機械強制する Layer 0.5。 +# 機械強制する custom linter。 +# +# ADR-039 § 1.b mechanical lint 例外で default ON (PR #203 で訂正、本 PR で適用): +# - 失敗 mode が non-blocking (additionalContext warning のみ、ブロックしない) +# - 判定が決定論的 (50KB 固定閾値、discretionary 判断なし) +# - 適用 scope が宣言的に限定 (paths glob) +# - recovery hint が明確 (todo*.md なら新 todo.md を新設して移管) +# 同類例: 順位 147 file_length lint (hooks-post-tool-comment-lint-rust) も default ON 固定。 # -# ADR-039 § 3 opt-in pattern: default OFF (enabled = false)、明示有効化で発火。 # touch-trigger ratchet (default true): 触られたファイルのみチェック = 既存超過 # ファイルは未編集なら grandfather。strict mode (touch_trigger=false で全 enabled -# paths を scan) は MVP では受理のみ、3-5 PR の dogfood 後に判定 (bounded lifetime)。 +# paths を scan) は MVP では受理のみ。 # # Kill-switch: enabled = false で完全停止。 [post_tool_use.file_size_check] -enabled = false # opt-in (明示有効化で発火、ADR-039 § 3 bounded lifetime: 3-5 PR dogfood 後に default-ON 昇格判定) -threshold_bytes = 51200 # 50KB (= 50 * 1024) +enabled = true # ADR-039 § 1.b mechanical lint 例外 (non-blocking + 決定論 + scope 限定 + recovery hint 明確) +threshold_bytes = 51200 # 50KB (= 50 * 1024)、Claude Code 読み取り安定性閾値 paths = ["docs/**/*.md", "src/**/*.rs"] # default 対象 glob touch_trigger = true # 触られたファイルのみ check (ratchet) From f47e9adfbd435a12dc6720b1f463e06f02613935 Mon Sep 17 00:00:00 2001 From: aloekun Date: Fri, 12 Jun 2026 13:48:38 +0900 Subject: [PATCH 5/5] =?UTF-8?q?docs(todo):=20todo10.md=20=E3=82=92?= =?UTF-8?q?=E5=88=86=E5=89=B2=E3=81=97=E3=81=A6=20file=5Fsize=5Fcheck=2050?= =?UTF-8?q?KB=20threshold=20=E5=86=85=E3=81=AB=E5=8F=8E=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本 PR で順位 177 file_size_check を default ON 化したことにより、touched で 50KB 超のファイル (= 本 PR 着手時の docs/todo10.md = 57KB) に warning が出る状態になった。 本 commit で todo10.md から PR #185 〜 PR #196 era の 8 エントリを新規 docs/todo12.md に分離し、todo10.md を 27KB まで縮小して threshold 内に収める。同時に hook の dogfood としても機能 (順位 177 が想定する recovery flow = 新 todo.md 新設 + entry 移管 が実際に機能することを実観測)。 主な変更: docs/todo12.md (新規 158 行) - 順位 176 (PR #185 T2-#4): check-ci-coderabbit format variant fixture 追加 - 順位 178 (週次レビュー S02): state.rs behavioral invariant test - 順位 179 (週次レビュー S03): rate-limit retry decision boundary test - 順位 180 (週次レビュー C01): lib-report-formatter markdown pipe escape - 順位 181 (Phase D D-A): aggregate-weekly findings.json raw JSON - 順位 182 (Phase D D-B): /weekly-review skill 重複検出 (簡易 grep) - 順位 193 (PR #196 T2-1): Companion helper group 署名整合 compile-time test - 順位 194 (PR #196 T3-5): development-workflow.md grep step 追記 - 専用ファイル (新規追加先ではない)、todo11.md と同 role docs/todo10.md (-377 行、57KB → 27KB) - 上記 8 エントリを削除 - preamble に todo12.md 分離の経緯を記述 - 新セッション確認対象を「12 file」→「13 file」に更新 docs/todo-summary.md - preamble に todo12.md の説明を追記 - 8 行の「ファイル」列を todo10.md → todo12.md に変更 (sed 一括置換) 由来: 本 PR (PR #204) の hooks-config.toml 変更 (commit 4) で file_size_check default ON 化に伴う初回 dogfood。順位 177 設計の recovery flow が機能した実証 データとなる。 技術メモ: sed -i '13,390d' で 8 entries 削除、Edit tool で 380 行の old_string 構築は実用的でないため Bash 経路を選択 (ユーザーの「適切な粒度」要件と整合、 独立 commit に集約)。 --- docs/todo-summary.md | 182 ++++---- docs/todo10.md | 1054 ++++++++++++++---------------------------- docs/todo11.md | 2 +- docs/todo12.md | 389 ++++++++++++++++ docs/todo3.md | 366 +++++++-------- docs/todo4.md | 476 +++++++++---------- docs/todo5.md | 260 +++++------ docs/todo6.md | 442 +++++++++--------- docs/todo7.md | 484 +++++++++---------- docs/todo8.md | 624 ++++++++++++------------- docs/todo9.md | 2 +- 11 files changed, 2146 insertions(+), 2135 deletions(-) create mode 100644 docs/todo12.md diff --git a/docs/todo-summary.md b/docs/todo-summary.md index ac2ad33a..ee9f70c5 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -1,91 +1,91 @@ -# TODO 推奨実行順序サマリー - -> **本ファイルの位置付け**: `docs/todo.md` から「推奨実行順序サマリー」section を切り出した index 専用ファイル。各タスクの詳細は「ファイル」列に示された `docs/todoN.md` を参照する。`docs/todo.md` のサイズが 50KB を超え Claude Code 読み取り安定性に影響したため分離 (2026-05-09)。 -> -> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo10.md`、2026-05-29 PR #186 時点で新設、以降の新規エントリ受入先) に記録する。なお `docs/todo11.md` は 2026-06-06 todo9.md 分割で新設された専用ファイル (順位 157, 160-173 を収容) で、新規追加先ではない。 - - -## 推奨実行順序サマリー (2026-05-10 更新、ADR-033 採番管理簡素化 land 後) - -開発環境の作業効率への貢献度を基準にした推奨実行順序。詳細は各タスク冒頭の **「実行優先度」** 行を参照。 - -| 順位 | Tier | タスク | ファイル | 工数 | 依存 | -|---|---|---|---|---|---| -| 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | -| 10 | 🔧 Tier 2 | ADR-032 PR-broken-link: broken-link-check + 内部アンカー検査 統合 | todo2.md | Small-中 | なし (clean baseline 確立済) | -| 11 | 🔧 Tier 2 | `cli-pr-monitor` プロセス正常終了の integration test (PR #85 T2-2) | todo2.md | S | なし (Status update 2026-06-06: ADR-018 park モデル / ADR-030 短命プロセス移行後の再現確認が前段必要、未再現なら削除候補) | -| 16 | 🔧 Tier 2 | **`vitest` を devDependencies に固定 (PR #88 T2-3)** | todo3.md | Small | なし | -| 17 | 🔧 Tier 2 | **`pnpm create-pr` 必須引数ヘルプ改善 (PR #88 T2-5)** | todo3.md | Small | なし | -| 18 | 🔧 Tier 2 | **`.failed` marker への recovery 手順自己文書化 (PR #90 T2-2)** | todo3.md | S | なし | -| 20 | 💎 Tier 3 | ADR-032 PR-β: 実装 (enabled=false default) | todo2.md | 中-高 | 6, 8, 10 | -| 21 | 💎 Tier 3 | ADR-032 PR-γ: enablement (1 行 flip) | todo2.md | XS | ADR-031 dogfood (本採用済 2026-06-01) + 順位 20 | -| 22 | 💎 Tier 3 | ADR-032 PR-δ: dogfood + メトリクス検証 | todo2.md | (運用) | 順位 21 | -| 27 | 🧹 Tier 4 | ADR-030 Phase E/F: 旧機構廃止 + dogfood | todo.md | 中 | なし (cleanup、Status update 2026-06-06: Phase D-7 = PR #154 land 済、残 Phase E 旧機構廃止 + Phase F dogfood) | -| 28 | ⏳ Tier 5 | (追って) ADR-030 の takt-test-vc 反映 | todo.md | 中 | 順位 27 Phase F | -| 36 | 🔧 Tier 2 | **cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) ★ Bundle X** | todo4.md | M | Bundle W (順位 34/35) land 済 (2026-06-07) → 後付け検証層として着手可能、変更 crate + 1-hop 依存 scope | -| 37 | 🔧 Tier 2 | **pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) ★ Bundle X** | todo4.md | S | 順位 36 と同 PR (Bundle X、cli-push-runner に +~1 秒 step 追加) | -| 38 | 💎 Tier 3 | **L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky)** | todo4.md | S | ADR-031 採用昇格済 (PR #192) + Bundle W land 済 (2026-06-07) → Bundle X (順位 36/37) land のみ残依存、facet 追加 or aggregate 前 Rust pre-step として組込 | -| 40 | 🚀 Tier 1 | **prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2)** | todo4.md | XS | なし (Status update 2026-06-06: PR #175 で push-runner 側 `bookmark_check.rs` stage 実装済 → skill 側は二重防御 + 派生プロジェクト未 deploy 環境向け knowledge transfer に縮小) | -| 44 | 💎 Tier 3 | **PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25)** | todo4.md | M | なし (順位 144 hook 化 dogfood 成功事例を踏襲、3 BlockedPattern = 応答破棄漏れ POST / `--jq` なし GET / CR walkthrough state 混入 を `exception` field 付きで実装、`feedback_pipeline_over_rules.md` 適用で rule → hook 切替、session 毎の rule load コスト不要) | -| 49 | 🔧 Tier 2 | **`parse_findings` 系の error-path test infrastructure (PR #101 T2-1)** | todo7.md | M | なし (Status update 2026-06-06: 元 Bundle a Sub-PR 2 (順位 42/43/46) は段階 land 完了で消滅、本 task は単独で `unwrap_or_else(\|_\| empty)` silent fail 抑止 + cli-pr-monitor mock infra として独立着手可) | -| 51 | 🚀 Tier 1 | **`.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測)** | todo7.md | M | なし (Status update 2026-06-06: 採用案 C = `fix.md` instruction 追加は land 済、残作業 = dogfood 観測のみ、6-iter outlier 解消確認後に削除可) | -| 52 | 💎 Tier 3 | **comment-lint hook の MultiEdit 対応 (順位 50 follow-up)** | todo7.md | S | なし (順位 50 で v1 = Edit のみ実装、MultiEdit は whole-file fallback で no-regression、利用頻度低く優先度は低) | -| 60 | 💎 Tier 3 | **analyze-session の transcript filter 絞り込み (旧 #A-3)** | todo7.md | M | なし (旧 docs/pipeline-token-efficiency.md #A-3、ADR-036/037 化に伴い計画書削除、本 task のみ todo に移管。analyze-session の input range を PR 作成 commit〜merge に限定して input token 30-50% 削減見込み、dogfood で実測必要) | -| 61 | 🔧 Tier 2 | **`check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25)** | todo7.md | M | なし (Status update 2026-06-06: 旧依存 順位 45 = `--list-findings` Rust モードは PR #101 で land 済、本 task は `source: "inline" \| "review_body"` field 追加で同型 finding 化、手動 checklist (= 当初 rule 案) を programmatic 検出で置換、`feedback_pipeline_over_rules.md` 適用、analyze-coderabbit 連携で merge 前検出を構造化、即着手可能) | -| 78 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up** | todo5.md | S | なし (config が user-editable system boundary のとき `sanitize()` 値域検証を必須化し dependent arithmetic に `// SAFETY: により上限保証` コメントを要求するパターンを ADR + CLAUDE.md に codify、Rust 固有の checked_add + MAX_SAFE capping + time-dependent test の 3 層を明文化。2026-05-16 entry 登録時の旧予約 ADR-038 → ADR-041 振り直し → 順位 139 (PR #168 follow-up) ADR-041 取得に伴い 2026-05-22 再 placeholder 化、land 時 PR で空き番号確定 — 順位 135 codified placeholder policy の実例運用) | -| 79 | 💎 Tier 3 | **`docs-governance.md` § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用)** | todo5.md | XS | なし (PR #117 で順位 15 を Bb-3 で吸収済として削除した際、現 Step 2「残タスクを priority table に登録」が priority table から除外するケース = 完了/deprioritize/defer を未定義だった実証。除外時の commit/PR で 3 値のいずれかを明示する要件を追加して将来の同型 ambiguity を構造的に防ぐ) | -| 81 | 🚀 Tier 1 | **cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer)** | todo5.md | M | 1 観測のみで systemic 性未確認 (§A-2 P-5 PR で defer 判断、ADR-018 §追記 2026-05-08 で re-trigger 条件 = 2 件以上の同型観測を規定) | -| 92 | 🔧 Tier 2 | **scale-aware eval fixtures (200+ 行) — 大規模 diff dogfood 信頼性継続改善 (PR #132 T2-#5 採用)** | todo6.md | M | なし (Status update 2026-06-06: ADR-038 採用昇格済 (PR #156) で Phase d は運用入り、動機を「投入前 infrastructure」→「運用中の継続改善」に書き換え、優先度 must→should に若干低下するが大規模 diff の fallback rate 測定 infrastructure として継続価値あり) | -| 100 | 💎 Tier 3 | **`development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用)** | todo6.md | XS | なし (PR #119/#120/#121 sub-PR 分割 + PR #139 partial completion で systemic に観測された 2 暗黙知を `~/.claude/rules/common/development-workflow.md` に codify、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化のため非機械強制でも採用相当) | -| 105 | 💎 Tier 3 | **グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/CLAUDE.md` に `pattern` / `extensions` / `severity` (planned: `paths`) の field 一覧を表形式で追加、派生プロジェクト (techbook-ledger / auto-review-fix-vc) で rule porting 時の理解統一、順位 103 の code comment と相補) | -| 107 | 💎 Tier 3 | **`development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に「マージ後 N 日間 todo.md 残存 → 後続 phase で手動発見」事例を追記、memory `feedback_verify_task_not_already_done` を central rule にも反映、`feedback_todo_no_history` と合わせて「マージ → 即削除」サイクルを強調) | -| 108 | 💎 Tier 3 | **CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用)** | todo6.md | S | なし (`~/.claude/CLAUDE.md` に memory `feedback_no_unenforced_rules` の policy をユーザー可視 table として公開、Tier 2 と称した必須化ルール提案を新セッションでも一貫して却下できる構造、memory ファイル閉鎖を補完) | -| 110 | 💎 Tier 3 | **pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用)** | todo6.md | S | なし (Phase A の `overflow_hint()` をモデル例とし「境界値 / None / 閾値未満」3 パターンの test テンプレを `~/.claude/rules/common/testing.md` に追記、副作用分離の促進、Rust lib 全般で再利用) | -| 111 | 💎 Tier 3 | **`docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用)** | todo6.md | S | なし (Phase/bundle 関連 → todo6、global rules/lint → todo5 等の routing rule を `~/.claude/rules/common/docs-governance.md` に追記、PR #142 で実証された file pointer bifurcation の構造的予防、CR Minor #2 と同根) | -| 117 | 💎 Tier 3 | **`coding-style.md § Cross-File Reference Lifecycle` に ephemeral → permanent 知識移管 edit order 追記 (PR #145 T3-#3 採用)** | todo8.md | S | なし (PR #145 で lib.rs L128-139 → ADR-040 移管 + Phase C/D empirical data 移管の 2 観測。既存ルール (参照方向制約) と complementary な「① permanent target 先行作成・validate → ② 参照追加 → ③ 参照元削除」3 ステップ原則を `~/.claude/rules/common/coding-style.md` に codify、次回 ephemeral 計画書 retire 時の checklist として再利用) | -| 118 | 💎 Tier 3 | **rule⑧ への paths filter 適用範囲検討 (順位 102 land 時の意図的保留、follow-up)** | todo8.md | XS | 順位 102 (PR #148 land 済、Phase D D-3) で paths filter は実装済だが、rule⑧ への `paths = ["docs/**/*.md"]` migration は D-2 (PR #146、順位 101) で追加した root-level MD fire intent を壊すため保留。4 案 (保留継続 / broader glob / explicit list / rule split) の trade-off 評価を ADR-007 amendment (順位 104) と整合させて結論を出す | -| 128 | 💎 Tier 3 | **CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用)** | todo8.md | XS | なし (PR #133 (todo.md 分割) + PR #153 (analysis.md 分割) の successful pattern を明文化、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | -| 133 | 💎 Tier 3 | **docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = grep hit は実ファイル Read で確認」明記 (PR #156 T3 #1 採用)** | todo8.md | XS | なし (PR #156 で 5 件以上の false alarm 発生、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | -| 135 | 💎 Tier 3 | **todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来)** | todo8.md | XS | なし (順位 78 (旧 ADR-038 → ADR-041) で番号 conflict が顕在化、queue 滞留 entry の hardcode が後発 PR の採番と衝突する構造リスクを convention で予防、`~/.claude/rules/common/docs-governance.md` に 2-3 行追記。採番予約簿は管理コスト過剰のため見送り、land 時 PR で空き番号確定の軽量運用に統一) | -| 140 | 💎 Tier 3 | **順位 135「codified placeholder policy」を正式 ADR に昇格 (PR #169 T3-#2 採用)** | todo8.md | S | なし (順位 135 entry を retire し、ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy として永続化。PR #111/#132/#169 の 3+ PR で適用実証済 — PR #169 で「ADR-038 → 041 → NNN」3 段振り直し dogfood が land、ephemeral todo entry 限りでは派生プロジェクトへの transferability 不足、`feedback_no_unenforced_rules.md` 例外 = 既存実践 (3 PR で実証) の明文化 + 後続 entry が同 policy を参照する際の永続 reference 確保) | -| 143 | 🔧 Tier 2 | **複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171** | todo8.md | S | なし (PR #151/#171 の 2 PR 横断で multi-byte fixture 手動組み立てコストが Frequency Medium で観測、Japanese / emoji / combining chars helper 3 関数を標準化して新規 string-processing 関数追加時の boundary test コスト削減 + silent regression early detection、順位 142 + 144 と同 PR で land 推奨) | -| 145 | 🔧 Tier 2 | **preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用)** | todo8.md | M | なし (PR #172 Phase 3 で `jj-message-required` が opt-in preset であることを前提とせず test を書き rewrite が必要になった経緯、preset architecture の implicit assumption (always-enabled vs config-selectable) を classification 表として test レベルで codify、新 preset 追加時に matrix 更新を強制する mechanical enforcement で design misalignment を構造的検出、target は main.rs (feedback report の lib.rs 記載は誤り)) | -| 147 | 🔧 Tier 2 | **File length lint (800 行 max) 追加 — `coding-style.md` § File Organization 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`~/.claude/rules/common/coding-style.md` § File Organization の 800 行 max を `hooks-post-tool-comment-lint-rust` に追加、順位 48 関数長と同 touch-trigger ratchet pattern で grandfather 適用、Rust 限定 MVP、順位 57 truncate contract 整合、rule docs から具体閾値削除で縮小) | -| 148 | 🔧 Tier 2 | **Test coverage 80% CI gate 追加 — `testing.md` § Minimum Test Coverage 80% 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S-M | なし (`~/.claude/rules/common/testing.md` § 80% coverage ガイドラインを実行時 gate に変換、`cargo llvm-cov --fail-under-lines 80` を push-runner-config.toml [quality_gate] に integration 推奨、現状未測定のため段階導入計画必要、rule docs § 80% coverage を実行時 gate 参照に縮小) | -| 149 | 🔧 Tier 2 | **Long-running subprocess pipe truncate hook 拡張 — `development-workflow.md` § subprocess pipe truncate 禁止 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (既存 `exe-help-block` preset を `cli-*.exe ... \| (head\|tail\|awk)` 等の副作用ある subprocess 出力 truncate にも拡張 or 新 `subprocess-pipe-truncate-block` preset 追加、PR #109 SIGPIPE 事故 root cause の構造化、順位 44 (gh-token-efficiency) との scope 境界整理必要、development-workflow.md § 該当 section 縮小) | -| 150 | 🔧 Tier 2 | **Magic number lint 追加 — `coding-style.md` § Magic Numbers 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = source folder 限定) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`.claude/custom-lint-rules.toml` に `no-magic-number` rule 追加、source folder paths filter で test/config 除外、時間定数 / リトライ回数 / threshold の 3 category MVP、severity warning で reviewer 判断補助、順位 102 paths filter + 順位 118 適用範囲検討と整合、coding-style.md § Magic Numbers 削除可否は dogfood 後判断) | -| 151 | 🔧 Tier 2 | **PR diff lines check 追加 — `git-workflow.md` § Multi-PR chaining 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = 条件付き block 3 段階) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`src/cli-push-runner/src/stages/pr_size_check.rs` 新 stage 追加、`push-runner-config.toml` `[pr_size_check]` section で threshold 設定可能化 (default: block 1500 / warning 800)、jj diff stat 計測、大型 refactoring 時の override は config 編集、git-workflow.md § Multi-PR chaining 縮小) | -| 152 | 🔧 Tier 2 | **todo entry 削除時の事前 land 確認手順 — 順位 136 hook 拡張 or 独立 follow-up (PR #173 T2-1 採用、2026-05-26)** | todo9.md | XS-S | 順位 136 (working copy staleness + 既実装 grep) と同型機械強制、lifecycle 補完 = 順位 136 (add/edit 時) + 本タスク (delete 時)。PreToolUse hook で `docs/todo*.md` 削除時に対応 land commit を `jj log` で grep 検証、land 確認なら allow + 証跡出力、未確認なら warning (block しない)。順位 136 hook 統合 (~+15 行) or 独立 (~40 行) のいずれか、ADR-042 § Decision matrix 適用 (mechanizable + FP 低 + Adoption Risk None) | -| 153 | 🔧 Tier 2 | **`review-harness-whole` facet 追加 — 観点 ① 独立 facet 化 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | S | ADR-031 本採用後 (2026-06-01) の Phase B+1 拡張、extract 不要と判明したら close、順位 146-151 Bundle 既存ルール仕組み化の継続的発見源、architecture-whole から ① 観点を extract して context 圧迫回避 | -| 154 | 🔧 Tier 2 | **`review-todo-whole` facet + aggregate 前 file size pre-step — 観点 ⑤ ⑦ 拡張 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | M | 順位 136 land + ADR-031 本採用 (2026-06-01) 後着手、cli-docs-lint (preamble) / 順位 147 (file length) と scope 整理必要 (CI 即時 vs 週次 batch)、ADR-031 3 層分離原則で file size は LLM 不要の Rust pre-step に分離 | -| 157 | 🔧 Tier 2 | **Bundle 1 dogfood checklist 実行 — `__test.ps1` block + override env 確認 (PR #174 T2-#2 採用、ADR-039 bounded lifetime data point #1)** | todo11.md | XS | なし (PR #174 PR body の未消化 dogfood、Bundle 2 PR merge 前の前提条件として消化、結果は Bundle 2 PR body に記録) | -| 160 | 💎 Tier 3 | **`docs-governance.md` に「ADR multi-variant pattern section 追加時の checklist」codify (PR #176 T3-#1 採用)** | todo11.md | XS | なし (PR #175 Minor + PR #176 Nitpick の 2 連続観測 = Frequency Medium で採用条件成立、ADR 拡張時の variant 網羅性 + 擬似コード vs 実コード齟齬を reviewer / Claude 視点で防止する checklist、global file `~/.claude/rules/common/docs-governance.md` 編集のため本リポジトリ外で実施、`feedback_global_config_backup` 適用) | -| 161 | 🔧 Tier 2 | **Subprocess timeout+kill lifecycle 検証テスト追加 (PR #177 T2-#1 採用)** | todo11.md | M | なし (PR #177 Major #2 「jj kill on timeout 漏れ」fix の回帰テスト、`Child::is_finished` で 2 hook の `run_jj_with_timeout` lifecycle 検証、Severity High + Frequency Medium、ADR-024 shared lib 統合候補との関係明示) | -| 162 | 🔧 Tier 2 | **fail-closed error path (Option::None) 個別テスト追加 (PR #177 T2-#2 採用)** | todo11.md | S | なし (PR #177 Major #1 「`behind.unwrap_or(0)` fail-closed 漏れ」fix の回帰テスト、`check_todo_staleness` / `build_todo_staleness_message` の None ケース独立検証、Severity High + Frequency Medium、security gate + Option return pattern の reference) | -| 163 | 🔧 Tier 2 | **Cross-ref edge case test coverage 追加 — percent-encode / GFM heading slug / relative path normalize (PR #179 T2-#1 採用)** | todo11.md | S | なし (PR #179 で cli-docs-lint の cross_ref validator を新規実装したが、percent-encode (`%20` / `%23`) / heading slug / `../` resolve の edge case が fixture テストで明示的に保護されていない silent regression リスク回避) | -| 165 | 🔧 Tier 2 | **`pnpm create-pr` PR body truncation 回避を検証する e2e/integration test 追加 (PR #181 T2-#1 採用)** | todo11.md | S | なし (PR #134 + #181 の 2 回観測で Medium frequency に昇格、memory `feedback_pnpm_create_pr_body` の `--body-file` workaround を自動 regression gate 化、shell argument truncation の境界 (行数/バイト数) を fixture で測定、silent UX 劣化の早期検出、cli-pr-monitor の argv 組み立て層を test 対象、順位 166 と相補 = test 層 vs docs 層) | -| 170 | 💎 Tier 3 | **`git-workflow.md § Multi-PR chaining` を「1 PR 内 multi-commit + intent 明記」パターンに拡張 (PR #183 T3-#1 採用)** | todo11.md | S | なし (PR #119/#120/#121 + #183 の 4 観測で Frequency High、commit 分割判断 + intent 記述ガイドを既存 section に追記、`~/.claude/rules/common/git-workflow.md` 編集、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須) | -| 171 | 💎 Tier 3 | **`docs-governance.md` に「Operational reference vs Pointer reference」区別 section を追加 (PR #183 T3-#2 採用) ★ Bundle DG-RULES** | todo11.md | S | 順位 172 と同 PR 推奨、PR #183 A01 修正で実適用した判定ロジック (operational = workflow 動作記述 = 保持可 / pointer = section 名・順位番号参照 = 置換必要) を `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section として codify、ADR-031 lines 79-302 中 line 270 のみが真の pointer だった実例を inline cite、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須 | -| 172 | 💎 Tier 3 | **CR ephemeral artifact Nitpick の統一 skip 基準を memory に codify (PR #183 T3-#3 採用) ★ Bundle DG-RULES** | todo11.md | XS | 順位 171 と同 PR 推奨、CR が `docs/todo*.md` 系 ephemeral artifact 内の行番号参照を Nitpick 指摘した場合は skip 推奨という判断基準を新 memory `feedback_coderabbit_ephemeral_nitpick.md` に codify、既存 memory `feedback_coderabbit_no_actionable_merge_signal` の補完、本リポジトリ専用 (派生プロジェクトには波及しない)、`feedback_global_config_backup` 適用推奨 | -| 173 | 🔧 Tier 2 | **`combine_output` 5 crate 重複を `lib-runner-utils` (or 既存 lib-*) に extract (PR #182 dry-run S01 採用)** | todo11.md | S-M | なし (`src/cli-pr-monitor/src/runner.rs:80-89` の `combine_output` 8 行関数が `#[allow(dead_code)]` 付与で生産未使用、同関数が 4 他 crate (cli-push-runner, cli-push-pipeline, cli-merge-pipeline, hooks-post-tool-linter) にも複製 = 5 crate 横断 systemic duplication、ADR-026 Cargo workspace + ADR-012 lib-* naming で解決、Phase B dogfood の最初の実体ベース finding (A01 と並ぶ)、A01 は PR #183 で fix 済) | -| 176 | 🔧 Tier 2 | **check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用)** | todo10.md | M | なし (順位 167-169 Bundle CR-RL の follow-up、bold-wrapper variant (`**More reviews will be available**`) / 短形態 (secs のみ) / 複数 separator / wait time なし graceful failure の 4 fixture 追加、PR #182 + #185 の 2 PR 連続観測で CR format 多様性 systemic、`extract_old_format_wait_time` / `extract_new_format_wait_time` の coverage gap 補填、regex 拡張 vs fixture 先行の 2 アプローチを着手時判断、analyzer rationale の「Edit 集中 = test gap signal」は incidental で採用根拠から除外、true 採用根拠は format 多様性 + 防御的 variant) | -| 178 | 🔧 Tier 2 | **`state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/cli-pr-monitor/src/state.rs:226-510` の test が JSON round-trip のみ、`rate_limit=Some` 時 CI 更新 skip 等の behavioral invariant 未検証、ADR-041 sentinel 事前投入 + mutation 不在 assert pattern で 3-5 test 追加、memory `feedback_test_dry_antipattern` 適用、Effort S で high value catches state regression) | -| 179 | 🔧 Tier 2 | **rate-limit retry decision boundary test を rstest parameterized で追加 (週次レビュー 2026-05-30 S03 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/cli-pr-monitor/src/config.rs:94-122` + `stages/poll.rs` の `max_retries=3` 固定 test のみで boundary (0/1/3/off-by-one) 未検証、rstest parameterized で 3-4 case 追加 ~15 行、rstest 既存使用 + Bundle CR-RL = 順位 167-169 隣接領域 follow-up、off-by-one regression が test で検出可能化) | -| 180 | 🔧 Tier 2 | **`lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用)** | todo10.md | S | なし (Phase D dogfood で発見、`src/lib-report-formatter/src/lib.rs:51-79` の `format_table()` が PR title / commit message の `|` / `\n` を escape せず markdown table 構造を破壊 → downstream AI facet で prompt injection リスク、`escape_markdown_pipe()` 5 行 utility + call site escape + 5 variant test で defense-in-depth 確立、本セッション 5 PR chain で AI facet 連鎖が systemic 化したため継続価値高) | -| 181 | 🔧 Tier 2 | **`aggregate-weekly` facet の `findings.json` 出力を raw JSON にする (Phase D dogfood D-A 採用)** | todo10.md | XS-S | なし (本セッション 2026-05-30 Phase D dogfood で実観測した facet 出力 bug、`aggregate-weekly.md` instruction が「raw JSON 出力必須、markdown code fence で囲まない」を明示せず facet LLM が ` \`\`\`json...\`\`\` ` で wrap してしまう、skill 側の手動 fence strip workaround を不要化、修正後の次 `/weekly-review` で raw JSON 出力を dogfood 観測、Phase E 試験運用前の整備) | -| 182 | 🔧 Tier 2 | **`/weekly-review` skill に重複検出 (簡易 grep) を Phase 4 で追加 (Phase D dogfood D-B 採用)** | todo10.md | XS-S | なし (本セッション 2026-05-30 Phase D dogfood で WR-2026-05-30-S05 と既存 順位 173 が完全重複していた実観測、ADR-031 § Phase 4 「重複検出は MVP では実装しない」を「MVP+1 (簡易 grep + 3 択 AskUserQuestion: augment/新規/skip)」相当に格上げ、自動 merge なし原則は維持、description 先頭 40 chars の grep ヒット警告 → user 判断、`feedback_global_config_backup` 適用必須 (~/.claude/skills/ 編集前 snapshot)) | - -| 193 | 🔧 Tier 2 | **Companion helper group 署名整合 compile-time validation test (PR #196 T2-1 採用) ★ Bundle 195-FB follow-up** | todo10.md | S | なし (Bundle 195-FB で 3 関数目の signature drift が CR Major + pre-push F-1 で systemic 観測、rule⑫ は literal hardcode 層、本タスクは API signature 整合性層、関数ポインタ cast による compile-time witness で signature drift を test 不通過に。`code-review.md` § Review Checklist に reviewer 注意 1 項目追加で 3 層防御 = rule⑫ + compile-time test + reviewer 注意、`feedback_global_config_backup` 適用必須) | -| 194 | 💎 Tier 3 | **`development-workflow.md` 「1. Plan First」に「task 着手前に grep で既存 section 確認」step 追記 (PR #196 T3-5 採用)** | todo10.md | XS | なし (PR #123 + #196 で「既実装 section の重複計画」事象を Frequency Medium で観測、`~/.claude/rules/common/development-workflow.md` "1. Plan First" に Codification 重複確認 step を 1-2 行追記、`grep -rn` 手順 + 由来 cite (PR #123, #196)、派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及、`feedback_global_config_backup` 適用必須) | -| 198 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用、PR #203 T3-1 で 3 観測目に昇格)** | todo10.md | M | なし (PR #96 Finding D + PR #199 Bundle W + PR #203 hooks-session-start port で同型 bug class **3 件観測 = Frequency High**、PastTime newtype + proptest が実証した型層防御原則を ADR で永続化、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 確保、順位 135 placeholder policy 適用、CLAUDE.md ADR list 追記) | -| 199 | 🔧 Tier 2 | **multi-byte 文字を含む string window test の標準 coverage requirement 化 (PR #200 post-merge-feedback T2-1 採用)** | todo10.md | S | なし (PR #199 byte 計算混乱 + PR #200 priority_inversion char window bug の 2 観測 = Frequency Medium、`is_resolved_detects_marker_across_multibyte_gap` style を testing.md に標準化、新 validator 追加時に CJK 40 文字 (= 120 bytes) gap 含む multi-byte test を必須化、MVP は docs/checklist、3-5 validator land 後に lint rule 化を再評価) | -| 200 | 💎 Tier 3 | **`~/.claude/rules/rust/patterns.md` に「String Indexing with Multi-byte Characters」section 追加 (PR #200 post-merge-feedback T3-1 採用)** | todo10.md | XS | なし (PR #199 parse_age_secs + PR #200 priority_inversion の 2 観測 = Frequency Medium、`char_indices().nth(N)` canonical reference を global rules に追加して将来の lint rule 著者が同型 byte/char 混同 bug を再生産しないよう構造的予防、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へも自動波及、`feedback_global_config_backup` 適用必須) | -| 201 | 💎 Tier 3 | **ADR-007 に「Regex は loop / repeated call 内で `LazyLock` 必須」guideline 追記 (PR #200 post-merge-feedback T3-2 採用)** | todo10.md | XS | なし (PR #200 priority_inversion で per-row `Regex::new()` 再 compile を `LazyLock` 化した F-2 fix を ADR-007 § 正規表現層 に guideline として追記、`TIER_REGEX` / `RANK_REGEX` を参照実装として cite、1000+ 行 table での累積コスト顕在化を予防) | -| 202 | 💎 Tier 3 | **`~/.claude/rules/common/testing.md` に「multi-path test fixture isolation」section 追記 (PR #200 post-merge-feedback T3-3 採用)** | todo10.md | XS | なし (PR #200 F-3 fix で実証した「Path A を exercise する fixture には Path B トリガー条件を明示除外」 pattern を sentinel section 直下に追加、silent path-shift fragility を構造的に防ぐ、sentinel pattern (mutation 不在 assert) と相補的な test robustness 手法、派生プロジェクトへ global rules 経由で自動波及、`feedback_global_config_backup` 適用必須) | -| 203 | 🔧 Tier 2 | **GitHub token alternation の variant test 完成 — `ghu_` / `ghr_` (PR #201 post-merge-feedback T2-1 採用)** | todo10.md | XS | なし (PR #201 で `(gho\|ghs\|ghu\|ghr)_` alternation のうち `ghu_` user-to-server / `ghr_` refresh の専用 test が欠落、3 ソース PR diff + pre-push NB-2 + CR NB-2 が独立検出、`secret_detection_blocks_github_oauth_token` / `_server_token` と同パターンで 2 test 追加 〜10 行、Frequency Medium、Bundle-201-FB-A 候補も単独 land 可) | -| 204 | 💎 Tier 3 | **ADR-007 に exception field + 専用 pattern の設計方針 codify (PR #201 post-merge-feedback T3-2 採用)** | todo10.md | XS | なし (Rust regex の negative lookahead 非対応を回避する `BlockedPattern.exception` field + 専用 pattern の 2 段判定が PR #171 順位 144 で導入 + PR #201 順位 146 で再利用 = Frequency Medium、ADR-007「正規表現層」section に新 sub-section 追加、defense in depth で除外側を専用 pattern で別途検出、順位 201 LazyLock guideline と相補) | -| 205 | 💎 Tier 3 | **`~/.claude/rules/common/git-workflow.md` に jj auto-snapshot onboarding rule 追記 (PR #201 post-merge-feedback T3-4 採用)** | todo10.md | XS | なし (PR #201 で prior session の docs commit 199-202 と本セッションの impl 146 が auto-snapshot で混入し bundle 化に収束した実観測、jj Operations section に「Auto-snapshot の理解と logical separation」sub-section 追加、`jj new -m` を **作業開始時** に実行する正しいフロー明文化、派生プロジェクトへ global 経由で自動波及、`feedback_global_config_backup` 適用必須) | - -**戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 - -**Bundle 履歴**: 完了済 Bundle / post-merge-feedback 反映の経緯詳細は [docs/bundle-history.md](bundle-history.md) を参照 (2026-05-25 分離、本ファイルの index 責務集中のため)。 +# TODO 推奨実行順序サマリー + +> **本ファイルの位置付け**: `docs/todo.md` から「推奨実行順序サマリー」section を切り出した index 専用ファイル。各タスクの詳細は「ファイル」列に示された `docs/todoN.md` を参照する。`docs/todo.md` のサイズが 50KB を超え Claude Code 読み取り安定性に影響したため分離 (2026-05-09)。 +> +> **更新方針**: table への新規行追加・既存行の削除・順位の再採番はすべて本ファイルで実施する。詳細エントリは現行の追加先ファイル (= `docs/todo10.md`、2026-05-29 PR #186 時点で新設、以降の新規エントリ受入先) に記録する。なお `docs/todo11.md` は 2026-06-06 todo9.md 分割で新設された専用ファイル (順位 157, 160-173 を収容)、`docs/todo12.md` は 2026-06-12 PR #204 で todo10.md 分割により新設された専用ファイル (順位 176/178/179/180/181/182/193/194 = PR #185 〜 PR #196 era を収容) で、いずれも新規追加先ではない。 + + +## 推奨実行順序サマリー (2026-05-10 更新、ADR-033 採番管理簡素化 land 後) + +開発環境の作業効率への貢献度を基準にした推奨実行順序。詳細は各タスク冒頭の **「実行優先度」** 行を参照。 + +| 順位 | Tier | タスク | ファイル | 工数 | 依存 | +|---|---|---|---|---|---| +| 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | +| 10 | 🔧 Tier 2 | ADR-032 PR-broken-link: broken-link-check + 内部アンカー検査 統合 | todo2.md | Small-中 | なし (clean baseline 確立済) | +| 11 | 🔧 Tier 2 | `cli-pr-monitor` プロセス正常終了の integration test (PR #85 T2-2) | todo2.md | S | なし (Status update 2026-06-06: ADR-018 park モデル / ADR-030 短命プロセス移行後の再現確認が前段必要、未再現なら削除候補) | +| 16 | 🔧 Tier 2 | **`vitest` を devDependencies に固定 (PR #88 T2-3)** | todo3.md | Small | なし | +| 17 | 🔧 Tier 2 | **`pnpm create-pr` 必須引数ヘルプ改善 (PR #88 T2-5)** | todo3.md | Small | なし | +| 18 | 🔧 Tier 2 | **`.failed` marker への recovery 手順自己文書化 (PR #90 T2-2)** | todo3.md | S | なし | +| 20 | 💎 Tier 3 | ADR-032 PR-β: 実装 (enabled=false default) | todo2.md | 中-高 | 6, 8, 10 | +| 21 | 💎 Tier 3 | ADR-032 PR-γ: enablement (1 行 flip) | todo2.md | XS | ADR-031 dogfood (本採用済 2026-06-01) + 順位 20 | +| 22 | 💎 Tier 3 | ADR-032 PR-δ: dogfood + メトリクス検証 | todo2.md | (運用) | 順位 21 | +| 27 | 🧹 Tier 4 | ADR-030 Phase E/F: 旧機構廃止 + dogfood | todo.md | 中 | なし (cleanup、Status update 2026-06-06: Phase D-7 = PR #154 land 済、残 Phase E 旧機構廃止 + Phase F dogfood) | +| 28 | ⏳ Tier 5 | (追って) ADR-030 の takt-test-vc 反映 | todo.md | 中 | 順位 27 Phase F | +| 36 | 🔧 Tier 2 | **cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) ★ Bundle X** | todo4.md | M | Bundle W (順位 34/35) land 済 (2026-06-07) → 後付け検証層として着手可能、変更 crate + 1-hop 依存 scope | +| 37 | 🔧 Tier 2 | **pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) ★ Bundle X** | todo4.md | S | 順位 36 と同 PR (Bundle X、cli-push-runner に +~1 秒 step 追加) | +| 38 | 💎 Tier 3 | **L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky)** | todo4.md | S | ADR-031 採用昇格済 (PR #192) + Bundle W land 済 (2026-06-07) → Bundle X (順位 36/37) land のみ残依存、facet 追加 or aggregate 前 Rust pre-step として組込 | +| 40 | 🚀 Tier 1 | **prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2)** | todo4.md | XS | なし (Status update 2026-06-06: PR #175 で push-runner 側 `bookmark_check.rs` stage 実装済 → skill 側は二重防御 + 派生プロジェクト未 deploy 環境向け knowledge transfer に縮小) | +| 44 | 💎 Tier 3 | **PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25)** | todo4.md | M | なし (順位 144 hook 化 dogfood 成功事例を踏襲、3 BlockedPattern = 応答破棄漏れ POST / `--jq` なし GET / CR walkthrough state 混入 を `exception` field 付きで実装、`feedback_pipeline_over_rules.md` 適用で rule → hook 切替、session 毎の rule load コスト不要) | +| 49 | 🔧 Tier 2 | **`parse_findings` 系の error-path test infrastructure (PR #101 T2-1)** | todo7.md | M | なし (Status update 2026-06-06: 元 Bundle a Sub-PR 2 (順位 42/43/46) は段階 land 完了で消滅、本 task は単独で `unwrap_or_else(\|_\| empty)` silent fail 抑止 + cli-pr-monitor mock infra として独立着手可) | +| 51 | 🚀 Tier 1 | **`.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測)** | todo7.md | M | なし (Status update 2026-06-06: 採用案 C = `fix.md` instruction 追加は land 済、残作業 = dogfood 観測のみ、6-iter outlier 解消確認後に削除可) | +| 52 | 💎 Tier 3 | **comment-lint hook の MultiEdit 対応 (順位 50 follow-up)** | todo7.md | S | なし (順位 50 で v1 = Edit のみ実装、MultiEdit は whole-file fallback で no-regression、利用頻度低く優先度は低) | +| 60 | 💎 Tier 3 | **analyze-session の transcript filter 絞り込み (旧 #A-3)** | todo7.md | M | なし (旧 docs/pipeline-token-efficiency.md #A-3、ADR-036/037 化に伴い計画書削除、本 task のみ todo に移管。analyze-session の input range を PR 作成 commit〜merge に限定して input token 30-50% 削減見込み、dogfood で実測必要) | +| 61 | 🔧 Tier 2 | **`check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25)** | todo7.md | M | なし (Status update 2026-06-06: 旧依存 順位 45 = `--list-findings` Rust モードは PR #101 で land 済、本 task は `source: "inline" \| "review_body"` field 追加で同型 finding 化、手動 checklist (= 当初 rule 案) を programmatic 検出で置換、`feedback_pipeline_over_rules.md` 適用、analyze-coderabbit 連携で merge 前検出を構造化、即着手可能) | +| 78 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up** | todo5.md | S | なし (config が user-editable system boundary のとき `sanitize()` 値域検証を必須化し dependent arithmetic に `// SAFETY: により上限保証` コメントを要求するパターンを ADR + CLAUDE.md に codify、Rust 固有の checked_add + MAX_SAFE capping + time-dependent test の 3 層を明文化。2026-05-16 entry 登録時の旧予約 ADR-038 → ADR-041 振り直し → 順位 139 (PR #168 follow-up) ADR-041 取得に伴い 2026-05-22 再 placeholder 化、land 時 PR で空き番号確定 — 順位 135 codified placeholder policy の実例運用) | +| 79 | 💎 Tier 3 | **`docs-governance.md` § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用)** | todo5.md | XS | なし (PR #117 で順位 15 を Bb-3 で吸収済として削除した際、現 Step 2「残タスクを priority table に登録」が priority table から除外するケース = 完了/deprioritize/defer を未定義だった実証。除外時の commit/PR で 3 値のいずれかを明示する要件を追加して将来の同型 ambiguity を構造的に防ぐ) | +| 81 | 🚀 Tier 1 | **cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer)** | todo5.md | M | 1 観測のみで systemic 性未確認 (§A-2 P-5 PR で defer 判断、ADR-018 §追記 2026-05-08 で re-trigger 条件 = 2 件以上の同型観測を規定) | +| 92 | 🔧 Tier 2 | **scale-aware eval fixtures (200+ 行) — 大規模 diff dogfood 信頼性継続改善 (PR #132 T2-#5 採用)** | todo6.md | M | なし (Status update 2026-06-06: ADR-038 採用昇格済 (PR #156) で Phase d は運用入り、動機を「投入前 infrastructure」→「運用中の継続改善」に書き換え、優先度 must→should に若干低下するが大規模 diff の fallback rate 測定 infrastructure として継続価値あり) | +| 100 | 💎 Tier 3 | **`development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用)** | todo6.md | XS | なし (PR #119/#120/#121 sub-PR 分割 + PR #139 partial completion で systemic に観測された 2 暗黙知を `~/.claude/rules/common/development-workflow.md` に codify、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化のため非機械強制でも採用相当) | +| 105 | 💎 Tier 3 | **グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/CLAUDE.md` に `pattern` / `extensions` / `severity` (planned: `paths`) の field 一覧を表形式で追加、派生プロジェクト (techbook-ledger / auto-review-fix-vc) で rule porting 時の理解統一、順位 103 の code comment と相補) | +| 107 | 💎 Tier 3 | **`development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用)** | todo6.md | XS | なし (`~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に「マージ後 N 日間 todo.md 残存 → 後続 phase で手動発見」事例を追記、memory `feedback_verify_task_not_already_done` を central rule にも反映、`feedback_todo_no_history` と合わせて「マージ → 即削除」サイクルを強調) | +| 108 | 💎 Tier 3 | **CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用)** | todo6.md | S | なし (`~/.claude/CLAUDE.md` に memory `feedback_no_unenforced_rules` の policy をユーザー可視 table として公開、Tier 2 と称した必須化ルール提案を新セッションでも一貫して却下できる構造、memory ファイル閉鎖を補完) | +| 110 | 💎 Tier 3 | **pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用)** | todo6.md | S | なし (Phase A の `overflow_hint()` をモデル例とし「境界値 / None / 閾値未満」3 パターンの test テンプレを `~/.claude/rules/common/testing.md` に追記、副作用分離の促進、Rust lib 全般で再利用) | +| 111 | 💎 Tier 3 | **`docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用)** | todo6.md | S | なし (Phase/bundle 関連 → todo6、global rules/lint → todo5 等の routing rule を `~/.claude/rules/common/docs-governance.md` に追記、PR #142 で実証された file pointer bifurcation の構造的予防、CR Minor #2 と同根) | +| 117 | 💎 Tier 3 | **`coding-style.md § Cross-File Reference Lifecycle` に ephemeral → permanent 知識移管 edit order 追記 (PR #145 T3-#3 採用)** | todo8.md | S | なし (PR #145 で lib.rs L128-139 → ADR-040 移管 + Phase C/D empirical data 移管の 2 観測。既存ルール (参照方向制約) と complementary な「① permanent target 先行作成・validate → ② 参照追加 → ③ 参照元削除」3 ステップ原則を `~/.claude/rules/common/coding-style.md` に codify、次回 ephemeral 計画書 retire 時の checklist として再利用) | +| 118 | 💎 Tier 3 | **rule⑧ への paths filter 適用範囲検討 (順位 102 land 時の意図的保留、follow-up)** | todo8.md | XS | 順位 102 (PR #148 land 済、Phase D D-3) で paths filter は実装済だが、rule⑧ への `paths = ["docs/**/*.md"]` migration は D-2 (PR #146、順位 101) で追加した root-level MD fire intent を壊すため保留。4 案 (保留継続 / broader glob / explicit list / rule split) の trade-off 評価を ADR-007 amendment (順位 104) と整合させて結論を出す | +| 128 | 💎 Tier 3 | **CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用)** | todo8.md | XS | なし (PR #133 (todo.md 分割) + PR #153 (analysis.md 分割) の successful pattern を明文化、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | +| 133 | 💎 Tier 3 | **docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = grep hit は実ファイル Read で確認」明記 (PR #156 T3 #1 採用)** | todo8.md | XS | なし (PR #156 で 5 件以上の false alarm 発生、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | +| 135 | 💎 Tier 3 | **todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来)** | todo8.md | XS | なし (順位 78 (旧 ADR-038 → ADR-041) で番号 conflict が顕在化、queue 滞留 entry の hardcode が後発 PR の採番と衝突する構造リスクを convention で予防、`~/.claude/rules/common/docs-governance.md` に 2-3 行追記。採番予約簿は管理コスト過剰のため見送り、land 時 PR で空き番号確定の軽量運用に統一) | +| 140 | 💎 Tier 3 | **順位 135「codified placeholder policy」を正式 ADR に昇格 (PR #169 T3-#2 採用)** | todo8.md | S | なし (順位 135 entry を retire し、ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy として永続化。PR #111/#132/#169 の 3+ PR で適用実証済 — PR #169 で「ADR-038 → 041 → NNN」3 段振り直し dogfood が land、ephemeral todo entry 限りでは派生プロジェクトへの transferability 不足、`feedback_no_unenforced_rules.md` 例外 = 既存実践 (3 PR で実証) の明文化 + 後続 entry が同 policy を参照する際の永続 reference 確保) | +| 143 | 🔧 Tier 2 | **複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171** | todo8.md | S | なし (PR #151/#171 の 2 PR 横断で multi-byte fixture 手動組み立てコストが Frequency Medium で観測、Japanese / emoji / combining chars helper 3 関数を標準化して新規 string-processing 関数追加時の boundary test コスト削減 + silent regression early detection、順位 142 + 144 と同 PR で land 推奨) | +| 145 | 🔧 Tier 2 | **preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用)** | todo8.md | M | なし (PR #172 Phase 3 で `jj-message-required` が opt-in preset であることを前提とせず test を書き rewrite が必要になった経緯、preset architecture の implicit assumption (always-enabled vs config-selectable) を classification 表として test レベルで codify、新 preset 追加時に matrix 更新を強制する mechanical enforcement で design misalignment を構造的検出、target は main.rs (feedback report の lib.rs 記載は誤り)) | +| 147 | 🔧 Tier 2 | **File length lint (800 行 max) 追加 — `coding-style.md` § File Organization 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`~/.claude/rules/common/coding-style.md` § File Organization の 800 行 max を `hooks-post-tool-comment-lint-rust` に追加、順位 48 関数長と同 touch-trigger ratchet pattern で grandfather 適用、Rust 限定 MVP、順位 57 truncate contract 整合、rule docs から具体閾値削除で縮小) | +| 148 | 🔧 Tier 2 | **Test coverage 80% CI gate 追加 — `testing.md` § Minimum Test Coverage 80% 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S-M | なし (`~/.claude/rules/common/testing.md` § 80% coverage ガイドラインを実行時 gate に変換、`cargo llvm-cov --fail-under-lines 80` を push-runner-config.toml [quality_gate] に integration 推奨、現状未測定のため段階導入計画必要、rule docs § 80% coverage を実行時 gate 参照に縮小) | +| 149 | 🔧 Tier 2 | **Long-running subprocess pipe truncate hook 拡張 — `development-workflow.md` § subprocess pipe truncate 禁止 移管 (PR #172 仕組み化方針切替由来) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (既存 `exe-help-block` preset を `cli-*.exe ... \| (head\|tail\|awk)` 等の副作用ある subprocess 出力 truncate にも拡張 or 新 `subprocess-pipe-truncate-block` preset 追加、PR #109 SIGPIPE 事故 root cause の構造化、順位 44 (gh-token-efficiency) との scope 境界整理必要、development-workflow.md § 該当 section 縮小) | +| 150 | 🔧 Tier 2 | **Magic number lint 追加 — `coding-style.md` § Magic Numbers 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = source folder 限定) ★ Bundle 既存ルール仕組み化** | todo9.md | M | なし (`.claude/custom-lint-rules.toml` に `no-magic-number` rule 追加、source folder paths filter で test/config 除外、時間定数 / リトライ回数 / threshold の 3 category MVP、severity warning で reviewer 判断補助、順位 102 paths filter + 順位 118 適用範囲検討と整合、coding-style.md § Magic Numbers 削除可否は dogfood 後判断) | +| 151 | 🔧 Tier 2 | **PR diff lines check 追加 — `git-workflow.md` § Multi-PR chaining 移管 (PR #172 仕組み化方針切替由来、ユーザー判断 2026-05-25 = 条件付き block 3 段階) ★ Bundle 既存ルール仕組み化** | todo9.md | S | なし (`src/cli-push-runner/src/stages/pr_size_check.rs` 新 stage 追加、`push-runner-config.toml` `[pr_size_check]` section で threshold 設定可能化 (default: block 1500 / warning 800)、jj diff stat 計測、大型 refactoring 時の override は config 編集、git-workflow.md § Multi-PR chaining 縮小) | +| 152 | 🔧 Tier 2 | **todo entry 削除時の事前 land 確認手順 — 順位 136 hook 拡張 or 独立 follow-up (PR #173 T2-1 採用、2026-05-26)** | todo9.md | XS-S | 順位 136 (working copy staleness + 既実装 grep) と同型機械強制、lifecycle 補完 = 順位 136 (add/edit 時) + 本タスク (delete 時)。PreToolUse hook で `docs/todo*.md` 削除時に対応 land commit を `jj log` で grep 検証、land 確認なら allow + 証跡出力、未確認なら warning (block しない)。順位 136 hook 統合 (~+15 行) or 独立 (~40 行) のいずれか、ADR-042 § Decision matrix 適用 (mechanizable + FP 低 + Adoption Risk None) | +| 153 | 🔧 Tier 2 | **`review-harness-whole` facet 追加 — 観点 ① 独立 facet 化 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | S | ADR-031 本採用後 (2026-06-01) の Phase B+1 拡張、extract 不要と判明したら close、順位 146-151 Bundle 既存ルール仕組み化の継続的発見源、architecture-whole から ① 観点を extract して context 圧迫回避 | +| 154 | 🔧 Tier 2 | **`review-todo-whole` facet + aggregate 前 file size pre-step — 観点 ⑤ ⑦ 拡張 (ADR-031 weekly-review 拡張、2026-05-26 ユーザー合意) ★ 週次拡張** | todo9.md | M | 順位 136 land + ADR-031 本採用 (2026-06-01) 後着手、cli-docs-lint (preamble) / 順位 147 (file length) と scope 整理必要 (CI 即時 vs 週次 batch)、ADR-031 3 層分離原則で file size は LLM 不要の Rust pre-step に分離 | +| 157 | 🔧 Tier 2 | **Bundle 1 dogfood checklist 実行 — `__test.ps1` block + override env 確認 (PR #174 T2-#2 採用、ADR-039 bounded lifetime data point #1)** | todo11.md | XS | なし (PR #174 PR body の未消化 dogfood、Bundle 2 PR merge 前の前提条件として消化、結果は Bundle 2 PR body に記録) | +| 160 | 💎 Tier 3 | **`docs-governance.md` に「ADR multi-variant pattern section 追加時の checklist」codify (PR #176 T3-#1 採用)** | todo11.md | XS | なし (PR #175 Minor + PR #176 Nitpick の 2 連続観測 = Frequency Medium で採用条件成立、ADR 拡張時の variant 網羅性 + 擬似コード vs 実コード齟齬を reviewer / Claude 視点で防止する checklist、global file `~/.claude/rules/common/docs-governance.md` 編集のため本リポジトリ外で実施、`feedback_global_config_backup` 適用) | +| 161 | 🔧 Tier 2 | **Subprocess timeout+kill lifecycle 検証テスト追加 (PR #177 T2-#1 採用)** | todo11.md | M | なし (PR #177 Major #2 「jj kill on timeout 漏れ」fix の回帰テスト、`Child::is_finished` で 2 hook の `run_jj_with_timeout` lifecycle 検証、Severity High + Frequency Medium、ADR-024 shared lib 統合候補との関係明示) | +| 162 | 🔧 Tier 2 | **fail-closed error path (Option::None) 個別テスト追加 (PR #177 T2-#2 採用)** | todo11.md | S | なし (PR #177 Major #1 「`behind.unwrap_or(0)` fail-closed 漏れ」fix の回帰テスト、`check_todo_staleness` / `build_todo_staleness_message` の None ケース独立検証、Severity High + Frequency Medium、security gate + Option return pattern の reference) | +| 163 | 🔧 Tier 2 | **Cross-ref edge case test coverage 追加 — percent-encode / GFM heading slug / relative path normalize (PR #179 T2-#1 採用)** | todo11.md | S | なし (PR #179 で cli-docs-lint の cross_ref validator を新規実装したが、percent-encode (`%20` / `%23`) / heading slug / `../` resolve の edge case が fixture テストで明示的に保護されていない silent regression リスク回避) | +| 165 | 🔧 Tier 2 | **`pnpm create-pr` PR body truncation 回避を検証する e2e/integration test 追加 (PR #181 T2-#1 採用)** | todo11.md | S | なし (PR #134 + #181 の 2 回観測で Medium frequency に昇格、memory `feedback_pnpm_create_pr_body` の `--body-file` workaround を自動 regression gate 化、shell argument truncation の境界 (行数/バイト数) を fixture で測定、silent UX 劣化の早期検出、cli-pr-monitor の argv 組み立て層を test 対象、順位 166 と相補 = test 層 vs docs 層) | +| 170 | 💎 Tier 3 | **`git-workflow.md § Multi-PR chaining` を「1 PR 内 multi-commit + intent 明記」パターンに拡張 (PR #183 T3-#1 採用)** | todo11.md | S | なし (PR #119/#120/#121 + #183 の 4 観測で Frequency High、commit 分割判断 + intent 記述ガイドを既存 section に追記、`~/.claude/rules/common/git-workflow.md` 編集、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須) | +| 171 | 💎 Tier 3 | **`docs-governance.md` に「Operational reference vs Pointer reference」区別 section を追加 (PR #183 T3-#2 採用) ★ Bundle DG-RULES** | todo11.md | S | 順位 172 と同 PR 推奨、PR #183 A01 修正で実適用した判定ロジック (operational = workflow 動作記述 = 保持可 / pointer = section 名・順位番号参照 = 置換必要) を `~/.claude/rules/common/docs-governance.md` § Cross-File Reference Lifecycle に新 sub-section として codify、ADR-031 lines 79-302 中 line 270 のみが真の pointer だった実例を inline cite、派生プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須 | +| 172 | 💎 Tier 3 | **CR ephemeral artifact Nitpick の統一 skip 基準を memory に codify (PR #183 T3-#3 採用) ★ Bundle DG-RULES** | todo11.md | XS | 順位 171 と同 PR 推奨、CR が `docs/todo*.md` 系 ephemeral artifact 内の行番号参照を Nitpick 指摘した場合は skip 推奨という判断基準を新 memory `feedback_coderabbit_ephemeral_nitpick.md` に codify、既存 memory `feedback_coderabbit_no_actionable_merge_signal` の補完、本リポジトリ専用 (派生プロジェクトには波及しない)、`feedback_global_config_backup` 適用推奨 | +| 173 | 🔧 Tier 2 | **`combine_output` 5 crate 重複を `lib-runner-utils` (or 既存 lib-*) に extract (PR #182 dry-run S01 採用)** | todo11.md | S-M | なし (`src/cli-pr-monitor/src/runner.rs:80-89` の `combine_output` 8 行関数が `#[allow(dead_code)]` 付与で生産未使用、同関数が 4 他 crate (cli-push-runner, cli-push-pipeline, cli-merge-pipeline, hooks-post-tool-linter) にも複製 = 5 crate 横断 systemic duplication、ADR-026 Cargo workspace + ADR-012 lib-* naming で解決、Phase B dogfood の最初の実体ベース finding (A01 と並ぶ)、A01 は PR #183 で fix 済) | +| 176 | 🔧 Tier 2 | **check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用)** | 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 試験運用前の整備) | +| 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` 適用必須) | +| 194 | 💎 Tier 3 | **`development-workflow.md` 「1. Plan First」に「task 着手前に grep で既存 section 確認」step 追記 (PR #196 T3-5 採用)** | todo12.md | XS | なし (PR #123 + #196 で「既実装 section の重複計画」事象を Frequency Medium で観測、`~/.claude/rules/common/development-workflow.md` "1. Plan First" に Codification 重複確認 step を 1-2 行追記、`grep -rn` 手順 + 由来 cite (PR #123, #196)、派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及、`feedback_global_config_backup` 適用必須) | +| 198 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用、PR #203 T3-1 で 3 観測目に昇格)** | todo10.md | M | なし (PR #96 Finding D + PR #199 Bundle W + PR #203 hooks-session-start port で同型 bug class **3 件観測 = Frequency High**、PastTime newtype + proptest が実証した型層防御原則を ADR で永続化、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 確保、順位 135 placeholder policy 適用、CLAUDE.md ADR list 追記) | +| 199 | 🔧 Tier 2 | **multi-byte 文字を含む string window test の標準 coverage requirement 化 (PR #200 post-merge-feedback T2-1 採用)** | todo10.md | S | なし (PR #199 byte 計算混乱 + PR #200 priority_inversion char window bug の 2 観測 = Frequency Medium、`is_resolved_detects_marker_across_multibyte_gap` style を testing.md に標準化、新 validator 追加時に CJK 40 文字 (= 120 bytes) gap 含む multi-byte test を必須化、MVP は docs/checklist、3-5 validator land 後に lint rule 化を再評価) | +| 200 | 💎 Tier 3 | **`~/.claude/rules/rust/patterns.md` に「String Indexing with Multi-byte Characters」section 追加 (PR #200 post-merge-feedback T3-1 採用)** | todo10.md | XS | なし (PR #199 parse_age_secs + PR #200 priority_inversion の 2 観測 = Frequency Medium、`char_indices().nth(N)` canonical reference を global rules に追加して将来の lint rule 著者が同型 byte/char 混同 bug を再生産しないよう構造的予防、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へも自動波及、`feedback_global_config_backup` 適用必須) | +| 201 | 💎 Tier 3 | **ADR-007 に「Regex は loop / repeated call 内で `LazyLock` 必須」guideline 追記 (PR #200 post-merge-feedback T3-2 採用)** | todo10.md | XS | なし (PR #200 priority_inversion で per-row `Regex::new()` 再 compile を `LazyLock` 化した F-2 fix を ADR-007 § 正規表現層 に guideline として追記、`TIER_REGEX` / `RANK_REGEX` を参照実装として cite、1000+ 行 table での累積コスト顕在化を予防) | +| 202 | 💎 Tier 3 | **`~/.claude/rules/common/testing.md` に「multi-path test fixture isolation」section 追記 (PR #200 post-merge-feedback T3-3 採用)** | todo10.md | XS | なし (PR #200 F-3 fix で実証した「Path A を exercise する fixture には Path B トリガー条件を明示除外」 pattern を sentinel section 直下に追加、silent path-shift fragility を構造的に防ぐ、sentinel pattern (mutation 不在 assert) と相補的な test robustness 手法、派生プロジェクトへ global rules 経由で自動波及、`feedback_global_config_backup` 適用必須) | +| 203 | 🔧 Tier 2 | **GitHub token alternation の variant test 完成 — `ghu_` / `ghr_` (PR #201 post-merge-feedback T2-1 採用)** | todo10.md | XS | なし (PR #201 で `(gho\|ghs\|ghu\|ghr)_` alternation のうち `ghu_` user-to-server / `ghr_` refresh の専用 test が欠落、3 ソース PR diff + pre-push NB-2 + CR NB-2 が独立検出、`secret_detection_blocks_github_oauth_token` / `_server_token` と同パターンで 2 test 追加 〜10 行、Frequency Medium、Bundle-201-FB-A 候補も単独 land 可) | +| 204 | 💎 Tier 3 | **ADR-007 に exception field + 専用 pattern の設計方針 codify (PR #201 post-merge-feedback T3-2 採用)** | todo10.md | XS | なし (Rust regex の negative lookahead 非対応を回避する `BlockedPattern.exception` field + 専用 pattern の 2 段判定が PR #171 順位 144 で導入 + PR #201 順位 146 で再利用 = Frequency Medium、ADR-007「正規表現層」section に新 sub-section 追加、defense in depth で除外側を専用 pattern で別途検出、順位 201 LazyLock guideline と相補) | +| 205 | 💎 Tier 3 | **`~/.claude/rules/common/git-workflow.md` に jj auto-snapshot onboarding rule 追記 (PR #201 post-merge-feedback T3-4 採用)** | todo10.md | XS | なし (PR #201 で prior session の docs commit 199-202 と本セッションの impl 146 が auto-snapshot で混入し bundle 化に収束した実観測、jj Operations section に「Auto-snapshot の理解と logical separation」sub-section 追加、`jj new -m` を **作業開始時** に実行する正しいフロー明文化、派生プロジェクトへ global 経由で自動波及、`feedback_global_config_backup` 適用必須) | + +**戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 + +**Bundle 履歴**: 完了済 Bundle / post-merge-feedback 反映の経緯詳細は [docs/bundle-history.md](bundle-history.md) を参照 (2026-05-25 分離、本ファイルの index 責務集中のため)。 diff --git a/docs/todo10.md b/docs/todo10.md index 00778672..d3904d16 100644 --- a/docs/todo10.md +++ b/docs/todo10.md @@ -1,716 +1,338 @@ -# TODO (Part 10) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo9.md がファイルサイズ 50KB を超え行数 1100+ 行に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #185 = Bundle CR-RL land 後、2026-05-29 ユーザー判断)。todo.md / todo2.md 〜 todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用) - -> **動機**: PR #185 (Bundle CR-RL) で `extract_old_format_wait_time` / `extract_new_format_wait_time` の 2 helper 関数に分離し 3 新規 fixture (full / minutes-only / 旧新混在) を追加したが、analyzer (post-merge-feedback) は **bold-wrapper variant** (例: `**More reviews will be available in N minutes and S seconds**`) や **その他の組合せ variant** の coverage gap を指摘。PR #182 (30+ 分 polling 浪費の実観測) + PR #185 (format 多様性対応) の 2 PR 連続観測で、CR の format は引き続き variants を生む可能性が高く、防御的 fixture coverage 追加が systemic 価値あり。 -> -> **本タスクの位置づけ**: PR #185 post-merge-feedback Tier 2 #4 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None、2026-05-29 ユーザー承認)。順位 167-169 (Bundle CR-RL) の follow-up として next format drift での silent regression 防止網を厚くする。 -> -> **参照**: `.claude/feedback-reports/185.md` Tier 2 #4、`src/check-ci-coderabbit/src/main.rs` の `#[cfg(test)]` mod (既存 9 fixture = 6 旧 format + 3 新 format)、`extract_old_format_wait_time` / `extract_new_format_wait_time` の regex (現状 markdown bold `\*?\*?` は旧 format のみ対応、新 format は bold 想定なし) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。fixture 追加のみで runtime 影響なし。 -> -> **注意 (analyzer rationale の一部に弱点)**: post-merge-feedback report は「PR #185 で 6 回の Edit が同一ファイルに集中した incremental development パターンは test coverage gap の兆候」と述べているが、これは incidental development pattern であり test coverage の真の signal ではない。採用根拠は **CR format 多様性 (PR #182 + #185 の 2 PR 連続観測) + bold-wrapper 等の防御的 variant 追加の妥当性** であり、Edit 集中は無関係。 - -#### 設計決定 (案) - -追加候補 fixture (memory `feedback_test_dry_antipattern`: 各 variant 独立 setup): - -- **bold-wrapper 新 format**: `**More reviews will be available in 15 minutes and 30 seconds**` — CR が markdown bold を新 format に追加した場合の検出 - - 現 `extract_new_format_wait_time` の regex はこの場合 fail する (旧 format の `\*?\*?` 相当を新 format regex にも追加する必要あり) - - もし fail を assertion で確認するなら fixture は「現状の振る舞いを pin」、もし regex を pre-emptively 拡張するなら「拡張後の動作 verify」 -- **secs だけ provided 新 format**: `More reviews will be available in 45 seconds` (minutes 0 + seconds N の variant、CR が短時間 rate-limit を表現する場合) -- **複数 separator 旧 format**: `Please wait 5 minutes, 13 seconds` (`and` ではなく `,` 使用、観測例なしだが defensive) -- **HTML マーカーのみで wait time 文言なし**: ` ## Review limit reached` のみ → wait time 抽出失敗 = `parse_rate_limit` が None を返すことを assert (graceful failure verify) - -#### 設計判断 (regex 拡張 vs fixture のみ追加) - -2 つのアプローチ: - -1. **regex 拡張先行**: `extract_new_format_wait_time` の regex に `\*?\*?` 等を pre-emptively 追加し、それを fixture で verify する (= 想定 variant への先回り対応) -2. **fixture 先行 + 観測後 regex 拡張**: 現状の regex で fixture を書き、bold-wrapper variant では fail することを assert (= 現状の振る舞いを pin、観測ベース対応に倣う) - -どちらを採るかは本タスク着手時に判断。memory `feedback_no_unenforced_rules` の「未観測の preventive over-engineering を避ける」原則からは 2 が一貫性あり。1 を採るならその根拠 (=「regex 拡張は trivial で false positive リスクなし」) を commit description に明示する。 - -#### 作業計画 - -- [ ] 既存 9 fixture (`#[cfg(test)]` mod) を Read で全件確認、coverage gap を整理 -- [ ] 追加 4 fixture を独立 `#[test]` 関数として追加 (helper 共通化なし、memory `feedback_test_dry_antipattern` 適用) -- [ ] `cargo test -p check-ci-coderabbit` で全 fixture pass を確認 (新 + 既存 backward compat 維持) -- [ ] regex 拡張アプローチを採る場合は `extract_*_format_wait_time` の regex を更新、対応する `--release` test 確認 -- [ ] ADR-034 § 既知 CR rate-limit format 一覧 table に新 variant を 1 行 append (発見時期 = 「2026-05-29 防御的追加 (順位 176 land 時)」) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 4 新規 fixture が `cargo test -p check-ci-coderabbit` で全 pass -- bold-wrapper / 短形態 / graceful failure 等の variant coverage 確立 -- silent regression を test で 1 件以上検出できる構造 (= regex を意図的に元に戻すと新 fixture test が落ちる) -- ADR-034 § 既知 format 一覧 table の append による永続 reference 整合 - -#### 詰まっている箇所 - -regex 拡張アプローチ (#1) vs fixture のみ追加 (#2) の選択。本タスク着手時に bold-wrapper の CR 実観測例が増えていれば #1、increase なしなら #2 を採る判断が memory `feedback_no_unenforced_rules` の原則に整合する。 - ---- - -### `state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用) - -> **動機**: 週次レビュー WR-2026-05-30-S02 で検出。`src/cli-pr-monitor/src/state.rs:226-510` の test は JSON round-trip (serde 直列化 / 逆直列化) のみを検証し、**behavioral invariant** (例: `rate_limit` が `Some` の場合に `update_state_from_check_result()` が `ci` field を populate しない) を test していない。状態遷移 regression が test suite を通り抜ける構造的リスク。ADR-041 (Test Isolation Patterns for Multi-Condition Guards) で確立された「sentinel 事前投入 + mutation 不在を assert」pattern が本リポジトリの canonical 対策。 -> -> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。analyzer rationale: "Concrete, low-effort (add 3-5 tests), high value (catches state regression bugs). ADR-041 is already the project's documented pattern for this exact problem type." -> -> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/state.rs:226-510` (既存 test、JSON round-trip のみ)、`docs/adr/adr-041-test-isolation-patterns.md` (適用 pattern source) -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。3-5 test 追加で済む、既存 ADR-041 pattern 流用。 - -#### 設計決定 (案) - -- **対象 invariant 候補** (analyzer 提案 + 派生): - 1. `rate_limit` が `Some` 時、`update_state_from_check_result()` は `ci` field を更新しない - 2. `rate_limit.until_unix_secs` が過去時刻になった場合、次回 update で `rate_limit` が `None` に reset される (timer expiry) - 3. `notified` flag が `true` の場合、再度 `update_state_*` を呼んでも `notified` は維持される (idempotency) - 4. (実装側で発見し次第追加) -- **ADR-041 pattern 適用**: - - 各 test variant は独立 setup (`memory feedback_test_dry_antipattern`) - - sentinel value を事前投入 (`ci.overall = "MUTATION_CHECK_SENTINEL"` 等)、mutation が起こったか否かを明示的に assert - - guard condition を partial に偽にする setup で「他 guard が真でも mutation が起こらないこと」を保証 - -#### 作業計画 - -- [ ] `src/cli-pr-monitor/src/state.rs:226-510` を Read で全件確認、現状の test スコープと不足 invariant を整理 -- [ ] ADR-041 § Test Isolation Patterns を Read で再確認 -- [ ] 3-5 behavioral invariant test を `#[cfg(test)]` mod に追加 (memory `feedback_test_dry_antipattern` 適用、各 variant 独立 setup) -- [ ] cargo test -p cli-pr-monitor で全 pass 確認 -- [ ] mutation regression check: 意図的に invariant を破る変更 (例: rate_limit check を削除) を local で適用して新 test が落ちるか手動検証 -- [ ] cargo clippy clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 3-5 behavioral invariant test が追加され全 pass -- silent regression を test で 1 件以上検出できる構造 (意図破壊で新 test 落ちる確認済) -- ADR-041 pattern の rationale を test コメントで cite (sentinel 事前投入 + mutation 不在 assert) - -#### 詰まっている箇所 - -なし。Effort S、既存 pattern + 既存 test 構造への追加で完結。 - ---- - -### rate-limit retry decision boundary test を rstest parameterized で追加 (週次レビュー 2026-05-30 S03 採用) - -> **動機**: 週次レビュー WR-2026-05-30-S03 で検出。`src/cli-pr-monitor/src/config.rs:94-122` の rate-limit retry logic + `stages/poll.rs` 周辺で、`max_retries=3` (固定値) のみが test されており **decision boundary** (`max_retries=0` で retry されない / `max_retries=1` で 1 回だけ retry / `max_retries=3` で boundary 通過後 `action_required` 遷移) が未検証。off-by-one error (`<` vs `<=`) が silent regression として通る構造的リスク。rstest crate は既に本リポジトリで使用済のため新 dep 不要。 -> -> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。Bundle CR-RL (順位 167-169) と隣接領域 (= rate-limit detection の周辺 logic) のため follow-up 価値高。analyzer rationale: "Low effort (rstest parameterized test, ~15 lines). rstest is already in use in the codebase. High value: catches the exact off-by-one class that single-value tests miss." -> -> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/config.rs:94-122` (RateLimitConfig + max_retries field)、`src/cli-pr-monitor/src/stages/poll.rs` (retry 適用 site)、Bundle CR-RL (順位 167-169) の隣接 context、`feedback_test_dry_antipattern` 適用 - -#### 設計決定 (案) - -- **rstest parameterized test 構造**: - - ```rust - #[rstest] - #[case(0, vec![])] // max_retries=0: retry なし - #[case(1, vec![true, false])] // max_retries=1: 1 retry 後 stop - #[case(3, vec![true, true, true, false])] // max_retries=3: full boundary coverage - fn rate_limit_retry_boundary(#[case] max_retries: u32, #[case] expected_continues: Vec) { - // setup + execution + assert - } - ``` - -- **boundary 観点**: - - 0 retry: 最初の attempt の後 `action_required` 遷移を確認 - - max_retries 到達: 連続 retry 後の最終 attempt で `action_required` に遷移 - - off-by-one: `< max_retries` か `<= max_retries` かを test 経由で pin (実装の `<` を `<=` に変えると新 test が落ちる) - -#### 作業計画 - -- [ ] `src/cli-pr-monitor/src/config.rs` の `RateLimitConfig::max_retries` 周辺 + `stages/poll.rs` の retry decision logic を Read で確認 -- [ ] 既存 rstest 使用箇所を grep で確認、import / pattern を踏襲 -- [ ] `#[cfg(test)]` mod に `rate_limit_retry_boundary` parameterized test を追加 (3-4 case) -- [ ] cargo test -p cli-pr-monitor で全 pass 確認 -- [ ] off-by-one regression check: `<` を `<=` に意図的変更で test が落ちることを手動検証 -- [ ] cargo clippy clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 3-4 parameterized case が全 pass -- off-by-one error が test で検出可能 (`<` ↔ `<=` mutation で test 落ちる) -- 既存単一値 test は維持 (backward compat) - -#### 詰まっている箇所 - -なし。Effort S、rstest pattern 既存使用 + 約 15 行で完結。 - ---- - -### `lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用) - -> **動機**: 週次レビュー WR-2026-05-30-C01 で検出。`src/lib-report-formatter/src/lib.rs:51-79` の `format_table()` が PR title / commit message を markdown table 行に直接埋め込むが、`|` / `\n` を escape していない。「`Fix | Critical | src/main.rs`」のような PR title が markdown table 構造を破壊し、**downstream AI facet が malformed row を Read 時に misinterpret する prompt injection リスク** が存在。PR title は外部 actor (= PR 作成者) が制御可能な input source のため defense-in-depth 重要。 -> -> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=security, category=prompt-injection、2026-05-30 ユーザー承認)。本セッションの 5 PR chain で AI facet 連鎖が systemic 化したため、prompt injection 防御層は今後の facet 拡張 (順位 153 / 154 等) でも継続価値あり。 -> -> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/lib-report-formatter/src/lib.rs:51-79` (format_table 実装)、`src/cli-merge-pipeline/src/feedback.rs:114-123` (PR title データ source)、ADR-022 (責務分離) との整合 (= utility は lib-* に集約) - -#### 設計決定 (案) - -- **`escape_markdown_pipe(s: &str) -> String`** ユーティリティを `lib-report-formatter` に追加: - - ```rust - pub fn escape_markdown_pipe(input: &str) -> String { - input.replace('|', "\\|").replace('\n', " ") - } - ``` - -- **call site 修正**: `format_table()` で user-controlled field (PR title / commit message / author) を embed する箇所に `escape_markdown_pipe()` を適用 -- **test 追加** (memory `feedback_test_dry_antipattern` 適用、各 variant 独立): - - 通常 ASCII (pipe / newline なし) → 変更なし - - pipe 単独 (`a | b`) → `a \| b` - - newline 単独 (`a\nb`) → `a b` - - pipe + newline 混合 - - empty string - -#### 作業計画 - -- [ ] `src/lib-report-formatter/src/lib.rs:51-79` を Read で `format_table()` 全体確認、user-controlled embed 箇所を特定 -- [ ] `escape_markdown_pipe()` を lib に追加、pub export -- [ ] `format_table()` の embed call site を escape 経由に書き換え -- [ ] `#[cfg(test)]` に 5 variant test を独立 setup で追加 -- [ ] cargo test + cargo clippy clean -- [ ] 受け先 (cli-merge-pipeline 等) で test がまだ pass することを cargo test --workspace で確認 (call signature 変更なしのため backward compat 維持) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `escape_markdown_pipe()` が `lib-report-formatter` に pub function として追加される -- 5 variant test が独立 pass -- `format_table()` の user-controlled embed が escape 経由になる -- markdown table 構造破壊 PR title (`Fix | Critical`) を fixture で渡しても table 整合維持を assert - -#### 詰まっている箇所 - -なし。Effort S、5 行 utility + call site 修正 + 5 test で完結。 - ---- - -### `aggregate-weekly` facet の `findings.json` 出力を raw JSON にする (Phase D dogfood D-A 採用) - -> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で検出した skill 統合 bug。`aggregate-weekly` facet が write する `findings.json` が ` ```json ... ``` ` の markdown code fence で wrap されており、Phase C skill (`/weekly-review`) が JSON parser に直接渡せない。本 dogfood では skill 内で fence を手動 strip して pending JSON を構築したが、**facet 出力を raw JSON にすれば skill 側の workaround が不要**になる。 -> -> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) の skill flow 実観測で発見、本 PR の dogfood 観測点 (D-A) として user 承認 (2026-05-30)。週次レビュー (ADR-031) facet 出力の整合性確保。 -> -> **参照**: `.takt/facets/instructions/aggregate-weekly.md` (修正対象)、`.takt/runs/20260529-150611-weekly-review-2026-05-30/reports/findings.json` (Phase D dogfood で実観測した fence 付き出力)、`~/.claude/skills/weekly-review/SKILL.md` Phase 2 (現 skill が手動 fence strip した workaround) - -#### 設計決定 (案) - -- **`aggregate-weekly.md` の output 指示を明確化**: - - 現状: instruction が「JSON は ... `findings.json` というファイル名で write する」と書いてあるが、facet LLM が markdown 出力癖 (` ```json...``` ` 自動 wrap) で fence 付きで write してしまう - - 修正: instruction で「**raw JSON のみ** (markdown code fence なし) で write する。先頭は `{` で始まり、末尾は `}` で終わる必要がある」を明示 - - test 文言例: `{"run_date": "...", ...}` から始まる、` ```json` で始まらない、を強調 -- **alternative**: skill 側で fence 検出 + strip を実装する (但し source-of-truth が facet 側であるべき) - -#### 作業計画 - -- [ ] `.takt/facets/instructions/aggregate-weekly.md` の `## Phase 3` (= JSON 生成 section) に「**raw JSON 出力必須、markdown code fence で囲まない**」warning を追加 -- [ ] JSON 出力例の前後 context を Edit で明確化 -- [ ] dogfood: 修正後に次の `/weekly-review` 実行で `findings.json` が raw JSON で出力されることを実観測 (Phase E で確認) -- [ ] (option) Phase C skill SKILL.md にも「fence wrap された場合の defensive strip 手順」を補足追記 (= belt-and-suspenders) -- [ ] markdownlint clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `aggregate-weekly.md` instruction で raw JSON 出力要件が明示される -- 次回 `/weekly-review` 実行で `findings.json` が raw JSON (= ` ```` ` で wrap されない) で出力される dogfood 観測 - -#### 詰まっている箇所 - -facet 側の文言修正のみで facet LLM の出力 habit を矯正できるかは未確定。修正後の dogfood 結果次第で alternative (= skill 側 strip) に切り替える判断あり。Effort XS-S。 - ---- - -### `/weekly-review` skill に重複検出 (簡易 grep) を Phase 4 で追加 (Phase D dogfood D-B 採用) - -> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で **WR-2026-05-30-S05 (`combine_output` dead-code) が既存 順位 173 (PR #182 dry-run S01 採用) と完全重複**であることを実観測。ADR-031 § Phase 4 で「**重複検出は MVP では実装しない**」と明示済だが、本 dogfood で「2 PR で同じ finding が出る」を実証したため、最低限の grep ベース簡易検出を後追い追加する妥当性が確立。MVP は description 先頭 40 chars の grep ヒットを警告表示するのみで、自動 merge は行わない (user 判断に委ねる ADR-031 原則維持)。 -> -> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) で observability gain (= 重複が見える) を実証、user 承認 (2026-05-30) で skill 拡張採用。Phase E 試験運用 dogfood の前に整備しておくと user 判断負荷を圧縮。 -> -> **参照**: `~/.claude/skills/weekly-review/SKILL.md` Phase 4 (修正対象)、ADR-031 § todo.md 反映ルール (「重複検出は MVP では実装しない」記述、本タスクで「MVP+1」相当に拡張)、Phase D dogfood の実観測 (WR-2026-05-30-S05 ↔ 順位 173 重複) - -#### 設計決定 (案) - -- **簡易 grep 重複検出 in Phase 4**: - - ```bash - # finding を docs/todo.md 系列に書き込む前に実行 - TITLE_PREFIX=$(echo "$finding_description" | head -c 40) - HITS=$(grep -li "$TITLE_PREFIX" docs/todo.md docs/todo*.md 2>/dev/null) - if [ -n "$HITS" ]; then - # AskUserQuestion で「augment / 新規 / skip」を聞く - fi - ``` - -- **3 択 AskUserQuestion**: - 1. **augment**: 既存 entry に補足追記 (= 「重複 observation を別 dogfood で再確認、優先度上昇」記録) - 2. **新規**: 重複と認識した上で別 entry 化 (= scope or角度 が異なる場合) - 3. **skip**: 重複と認識して書き込まない (= 既存 entry で十分) -- **自動 merge は行わない**: ADR-031 原則の「重複検出は MVP では実装しない」(自動 merge は MVP 超過、observability のみ提供) は維持 -- **grep target**: `docs/todo.md docs/todo2-11.md` 全件 (= 現在の todo file 集合、新 todoN+1.md 追加時は SKILL.md update が必要) - -#### 作業計画 - -- [ ] `~/.claude/skills/weekly-review/SKILL.md` Phase 4 § 重複検出 (簡易) を expansion: 現状の grep + 警告のみ → 警告 + 3 択 AskUserQuestion に変更 -- [ ] grep target file 列を docs/todo*.md glob 化、追加ファイル時の自動追従 (固定 list 回避) -- [ ] dogfood 観測の cite を skill 内 inline で明示 (= Phase D 2026-05-30 で WR-2026-05-30-S05 ↔ 順位 173 重複検出済、本 logic が機能した実例) -- [ ] **`feedback_global_config_backup` 適用**: ~/.claude/skills/ 編集前 snapshot 取得 -- [ ] markdownlint clean -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への skill 配布判断は別タスク (本 skill は global 配置だが ADR-031 自体は本リポジトリ ADR、派生展開は要検討) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- skill Phase 4 で grep 重複検出 → 3 択 AskUserQuestion → user 判断 経路が実装される -- 次回 `/weekly-review` 実行で重複候補が user 提示される dogfood 観測 -- ADR-031 「重複検出 MVP 未実装」を「MVP+1 (簡易 grep)」相当に格上げ、但し自動 merge なし原則は維持 -- skill 編集前後の ~/.claude snapshot が backup される - -#### 詰まっている箇所 - -なし。Effort XS-S、SKILL.md の Phase 4 section 拡張 + Bash snippet 追加で完結。 - ---- - -### Companion helper group 署名整合 compile-time validation test (PR #196 T2-1 採用) - -> **動機**: Bundle 195-FB (PR #196) で `count_empty_in_pr_range` だけ `default_branch` 引数化が漏れていた問題 (CR Major + pre-push F-1) を rule⑫ で **literal hardcode 層** では機械検出するようになったが、companion helper group (`assert_descriptions_absent/present_in_pr_range` / `count_empty_in_pr_range` / 将来追加される helper) の **API signature 整合性** は lint rule では catch できない (= AST レベル complexity)。4 番目以降の helper 追加時に signature drift が発生しても rule⑫ は fire しない silent regression リスク。 -> -> **本タスクの位置づけ**: PR #196 post-merge-feedback Tier 2 #2 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-06-05 ユーザー承認)。test-level validation で構造強制、Bundle 195-FB Layer 1 (rule⑫) + Layer 2 (parameterize) の seal 層として位置付け。analyzer は Tier 1 lint rule (item 1) を ROI 不釣合いとして却下推奨済、本 test approach は Tier 2 内 alternative。 -> -> **参照**: `.claude/feedback-reports/196.md` Tier 2 #2、`src/cli-pr-monitor/src/fix_commit.rs` (test module 内 companion helper group)、PR #195 commit `9663dd68` (前 2 関数の修正)、PR #196 commit `qntnzyxt` (Layer 2 = 3 関数目の整合) -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。compile-time witness (関数ポインタキャスト) で signature drift を test 不通過にする構造。 - -#### 設計決定 (案) - -Rust の compile-time check で signature drift を検出する pattern: - -```rust -#[test] -fn companion_helpers_share_default_branch_signature() { - // Compile-time witness: 各 helper が (&Path, &str, ...) signature を取ることを強制。 - // 新 helper を group に追加した際は本 test の末尾に同型 cast を追加して compile-time - // 整合性を seal する。signature が drift すると本 test が compile error で落ちる。 - let _: fn(&std::path::Path, &str, &[&str]) = assert_descriptions_absent_in_pr_range; - let _: fn(&std::path::Path, &str, &[&str]) = assert_descriptions_present_in_pr_range; - let _: fn(&std::path::Path, &str) -> usize = count_empty_in_pr_range; -} -``` - -- 関数ポインタへの cast は compile-time check (= test 関数 body 内の statement だが実行時 cost ≒ 0) -- signature drift → compile error → cargo test 不通過 -- 新 helper 追加時の運用: companion group の prefix (`*_in_pr_range` 等) で命名一致するなら本 test に 1 行追加を **`code-review.md` § Review Checklist** で reviewer 注意喚起 (rule⑫ + 本 test + Reviewer 注意の 3 層防御) - -#### 作業計画 - -- [ ] `src/cli-pr-monitor/src/fix_commit.rs` の `#[cfg(test)] mod tests` 内に `companion_helpers_share_default_branch_signature` test を追加 -- [ ] `cargo test --bin cli-pr-monitor fix_commit::tests::companion_helpers_share_default_branch_signature` で pass 確認 -- [ ] mutation regression check: 意図的に 1 関数の signature を変更 (例: `count_empty_in_pr_range(&Path) -> usize`) して compile error で落ちることを手動確認 -- [ ] `~/.claude/rules/common/code-review.md` § Review Checklist の末尾に「companion helper group の signature 整合は compile-time witness test で seal、新 helper 追加時は test に 1 行追加」を 1 項目追加 (3 層防御の reviewer 喚起層) -- [ ] cargo clippy clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- compile-time witness test が `fix_commit.rs` test module に追加され pass -- signature 意図変更で compile error 観測 (dogfood) -- code-review.md § Review Checklist に reviewer 注意項目追加 (global rule、派生プロジェクト波及) - -#### 詰まっている箇所 - -なし。Effort S、3-5 行 test 追加 + code-review.md 1 行追加で完結。 - ---- - -### development-workflow.md 「1. Plan First」に「task 着手前に grep で既存 section 確認」step 追記 (PR #196 T3-5 採用) - -> **動機**: PR #196 pre-push reviewer OBS-1 で「tasks 191/192 が既実装 sections を再度計画対象としていた」と指摘 (実態は cleanup diff の誤読だが、similar pattern は PR #123 でも観測済で Frequency Medium)。task 計画段階で「対象 section が既に global rules / ADR に存在するか `grep` で確認する」step を `~/.claude/rules/common/development-workflow.md` "1. Plan First" に追記し、後続 task 計画時の redundant 提案を構造的に予防する。 -> -> **本タスクの位置づけ**: PR #196 post-merge-feedback Tier 3 #5 採用 (Severity Medium / Frequency Medium / Effort XS / Adoption Risk None、2026-06-05 ユーザー承認)。development-workflow.md への 1-2 行追記のみ、派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及。 -> -> **参照**: `.claude/feedback-reports/196.md` Tier 3 #5、PR #196 pre-push OBS-1 (`.takt/runs/20260605-054100-pre-push-review/`)、PR #123 同型事象 (analyzer report 内 cite)、memory `feedback_global_config_backup` (snapshot 必須) -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule への 1-2 行追記。 - -#### 設計決定 (案) - -`~/.claude/rules/common/development-workflow.md` の **Feature Implementation Workflow** "1. Plan First" sub-step に以下を追記: - -```markdown -- **Codification 重複の事前確認**: 計画段階で「対象 section が既に global rules (`~/.claude/rules/common/*.md`) / ADR (`docs/adr/*.md`) / 既存 docs に存在するか」を `grep -n` で必ず確認する。重複追加は reviewer 混乱 + global rule の冗長化を招く。確認手順: - - `grep -rn "
" ~/.claude/rules/common/ docs/adr/ docs/` - - hit があれば既存 codification を読み、追記 vs 新規 vs skip を判断 - - 由来: PR #123 / PR #196 で同型「既実装 section の重複計画」事象を観測 -``` - -- **適用範囲**: 「ADR/global rule への新規 section codify」を含む全 task 計画 -- **派生プロジェクト波及**: `~/.claude/rules/common/` 配下のため techbook-ledger / auto-review-fix-vc に自動 - -#### 作業計画 - -- [ ] `~/.claude` snapshot 取得 (memory `feedback_global_config_backup` per) -- [ ] `~/.claude/rules/common/development-workflow.md` Feature Implementation Workflow "1. Plan First" sub-step に上記項目を追加 -- [ ] PR #123 + #196 を実例として inline cite -- [ ] markdownlint clean -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- development-workflow.md "1. Plan First" に Codification 重複確認 step が追記 -- 派生プロジェクトに global rule として波及 -- 由来 cite (PR #123, #196) で reviewer / Claude が rule 背景を理解可能 - -#### 詰まっている箇所 - -なし。Effort XS、docs 編集のみ。 - ---- - -### ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用、PR #203 T3-1 で 3 観測目に昇格) - -> **動機**: PR #96 Finding D (`cli-pr-monitor::lock` の `parse_age_secs` で `saturating_sub` silent semantic mismatch)、PR #199 Bundle W (`cli-pr-monitor::lock` に PastTime newtype + proptest で構造的予防)、PR #203 (`hooks-session-start` に PastTime + proptest 移植) で同型 bug class が **3 件観測 (Frequency High)**。本 ADR は「時刻計算における silent failure class と型レベル防御」を永続化し、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability を確保する。 -> -> **本タスクの位置づけ**: PR #199 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None、2026-06-08 ユーザー承認)。PR #203 post-merge-feedback Tier 3 #1 で 3 観測目として再確認、2026-06-11 ユーザー承認 (analyzer は新規 entry を提案したが既存 entry 強化として merge、`feedback_post_merge_feedback_adoption_requires_user_approval` + 順位 194「task 着手前に grep」適用)。順位 135 codified placeholder policy を適用し ADR 番号は land 時 PR で空き番号を確定する (本 entry 登録時点で ADR-038/039/040/041/042/043 占有済、044 が最有力候補だが land 時に再確認)。 -> -> **参照**: `.claude/feedback-reports/199.md` Tier 3 #2、`.claude/feedback-reports/203.md` Tier 3 #1、PR #96 Finding D、PR #199 Bundle W (PastTime newtype 実装 + proptest properties 5 件)、PR #203 (hooks-session-start への port + integration test 追加)、`~/.claude/rules/rust/patterns.md` § Newtype Pattern (extension 候補)、順位 135 (ADR 番号 hardcode 撤廃 policy)、順位 78 (旧 ADR-038 → 041 → NNN の 3 段振り直し実証) -> -> **実行優先度**: 💎 **Tier 3** — 工数 Medium。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記。Frequency High (3 PR) に昇格したため優先度内で着手順を引き上げる余地あり。 - -#### 背景 - -- **Bug class の定義**: `saturating_sub(now, then)` 等の silent fallback が dominate ドメイン的に誤った値 (age=0) を返し、後段の判定で「fresh」「young」等の誤判定を生む -- **発生条件**: clock rewind (NTP 巻き戻し / VM snapshot restore) / 破損 future timestamp (corrupted lock file / 不正 input) / 時刻取得失敗 → silent fallback -- **防御原則**: 業務ロジック的に不可能な状態 (future timestamp の存在) を型層で unrepresentable にする。construction 時に invariant 検証、`age_secs()` 等の derived 値は invariant により安全に計算 -- **実証パターン**: PR #199 Bundle W で `PastTime { epoch_secs, captured_now }` newtype + `from_iso8601_now` / `from_parts` 2 経路 + `age_secs()` non-negative invariant + proptest 5 properties で構造化、PR #203 で同 pattern を `hooks-session-start` の orphan reaper に展開 (`saturating_sub` 排除 + integration test `find_orphans_skips_future_start_time_without_silent_age_zero` 追加) - -#### 設計決定 (案) - -- **ADR title (案)**: 「Timestamp invariant safety — 時刻計算 silent failure class と型レベル防御」 -- **ADR sections (案)**: - 1. **コンテキスト**: bug class 定義 + 観測実例 (PR #96 Finding D / PR #199 Bundle W / PR #203 hooks-session-start port) - 2. **決定**: - - 原則 1: `saturating_sub` を時刻計算で使用しない (silent fallback 禁止) - - 原則 2: 「過去性」を型で表現する (newtype + construction 時 invariant) - - 原則 3: proptest properties で type invariant を executable contract として記述 - 3. **設計哲学**: 「業務ロジック的に impossible な状態を型層で unrepresentable にする」(parse, don't validate 派生) - 4. **派生プロジェクト適用**: cli-pr-monitor (PR #199 で実装済) / hooks-session-start (PR #203 で実装済、共通 lib 化は順位 T2-1 で別 task) / 派生プロジェクトの時刻計算箇所 (検出→展開計画) - 5. **完了状態 / 関連 ADR**: PR #199 (実証)、PR #203 (port 実証)、ADR-021 / ADR-024 等の参照 - -- **CLAUDE.md ADR list**: 「ADR-NNN: Timestamp invariant safety + saturating_sub による silent fallback 禁止 *(試験運用)*」として追記 - -#### 作業計画 - -- [ ] land 時 PR で ADR 空き番号を確定 (現状最有力は ADR-044) -- [ ] `docs/adr/adr-NNN-timestamp-invariant-safety.md` を新規作成 (試験運用) -- [ ] CLAUDE.md ADR list に追記 -- [ ] PR #96 Finding D / PR #199 Bundle W / PR #203 hooks-session-start port を実例として inline cite -- [ ] (任意) `~/.claude/rules/rust/patterns.md` § Newtype Pattern に link back を追記 (順位 T3-1 様子見と連動で判断) -- [ ] 本 todo10.md エントリを削除 - -#### 完了基準 - -- ADR-NNN が docs/adr/ に存在し試験運用 status で 1 PR で land -- CLAUDE.md ADR list に追記され ADR タイトル + 試験運用 marker が表示される -- bug class が以降の reviewer (人間 / CodeRabbit / takt facet) から ADR 参照で言及可能になる - -#### 詰まっている箇所 - -- ADR 番号確定タイミング (land 時 PR) と他並走 entry (順位 78 等) の競合可能性。順位 135 placeholder policy に従い land 時 PR で grep 確認すれば構造的に解決 -- `~/.claude/rules/rust/patterns.md` への展開 (順位 T3-1 が 様子見) との順序関係。本 ADR が land してから patterns.md 拡張を再評価する流れで矛盾なし - ---- - -### multi-byte 文字を含む string window test の標準 coverage requirement 化 (PR #200 post-merge-feedback T2-1 採用) - -> **動機**: PR #200 で `priority_inversion::has_resolved_marker_after` の window 計算が **byte 演算** で、日本語 1 文字 = 3 bytes のため「80 文字」のつもりが実質 ~27 文字に縮退する Major bug が発生 (CR が指摘、char-based に修正済)。PR #199 でも `parse_age_secs` 周辺で byte/char 混乱があり、Frequency Medium (2 観測) で systemic。char-based fix と regression test (`is_resolved_detects_marker_across_multibyte_gap`) は PR #200 で完了済だが、**将来の新規 validator が同パターンで実装されたとき multi-byte test が無指定で欠落するリスク** を構造的に塞ぐ。 -> -> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 2 #1 採用 (Severity High / Frequency Medium / Effort S / Adoption Risk None、2026-06-09 ユーザー承認)。`is_resolved_detects_marker_across_multibyte_gap` スタイルを **coverage requirement** として位置付け、新規 validator 追加 PR で同パターンの test を必須化する。 -> -> **参照**: `.claude/feedback-reports/200.md` Tier 2 #1、`src/cli-docs-lint/src/priority_inversion.rs:469-473` (char-based window fix)、`is_resolved_detects_marker_across_multibyte_gap` test (regression)、PR #199 PastTime newtype + proptest (parse_age_secs 周辺の byte 演算)。 -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Small。Coverage requirement 化のみで実装作業は新 validator 追加時の test 追記 (チェックリスト + テストテンプレート)。 - -#### 設計決定 (案) - -- **配置**: `~/.claude/rules/common/testing.md` (multi-path test fixture 拡張と同じ section) または `src/cli-docs-lint/README.md` (validator 追加 checklist) -- **要求項目**: - - 文字列 window 演算 (`str::find` + byte offset / `[start..end]` slice) を行う validator は、**30 bytes 超 multi-byte 文字を含む regression test を 1 件以上保持** する - - 推奨 fixture: CJK 40 文字 (= 120 bytes) gap + 末尾に marker - - assertion で window 内検出を verify -- **enforcement layer**: - - 案 A: docs (manual checklist、reviewer に頼る) - - 案 B: custom-lint-rules.toml で `str::find` + `[..]` slice 使用 file に対応 multi-byte test の存在を grep ベースで弱検出 (FP リスク高、要検討) -- **MVP**: 案 A (docs/checklist) で開始、3-5 validator land 後に案 B 化を再評価 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/testing.md` の sentinel pattern section 末尾に「multi-byte string window test 必須」を追記 -- [ ] `src/cli-docs-lint/README.md` (or 該当 doc) に validator 追加 checklist として記載 -- [ ] PR #200 の `is_resolved_detects_marker_across_multibyte_gap` を参照テンプレートとして cite -- [ ] 派生プロジェクト deploy 計画 (techbook-ledger / auto-review-fix-vc) を別 task として todo 登録 -- [ ] 本 todo10.md エントリを削除 - -#### 完了基準 - -- testing.md に「multi-byte string window test 必須」requirement が追記され、参照テンプレートとして PR #200 test が cite される -- 派生プロジェクトでも同 rule が global 配下から自動波及 - -#### 詰まっている箇所 - -- 案 B (mechanical enforcement) は FP リスクが見えるため MVP では docs のみで開始。dogfood で test 漏れ実例が観測されたら案 B を再検討。 - ---- - -### `~/.claude/rules/rust/patterns.md` に「String Indexing with Multi-byte Characters」section 追加 (PR #200 post-merge-feedback T3-1 採用) - -> **動機**: PR #200 で `priority_inversion::has_resolved_marker_after` の byte/char 混同 Major bug を fix した際、`char_indices().nth(N)` パターンが Rust の canonical solution として有効と判明。同パターンは現在 `~/.claude/rules/rust/` に未記述で、将来の lint rule 著者が同型 bug を再生産するリスクあり。PR #199 (parse_age_secs 周辺) + PR #200 (priority_inversion) で 2 観測 = Frequency Medium。 -> -> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-09 ユーザー承認)。global `~/.claude/rules/rust/patterns.md` への section 追加で、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へも自動波及。 -> -> **参照**: `.claude/feedback-reports/200.md` Tier 3 #1、`src/cli-docs-lint/src/priority_inversion.rs:178-184` (char_indices() pattern)、PR #199 (parse_age_secs byte/char 観測)。 -> -> **実行優先度**: 💎 **Tier 3** — 工数 XS。`~/.claude/rules/rust/patterns.md` に 1 section (10-20 行) 追加のみ。 - -#### 設計決定 (案) - -- **配置**: `~/.claude/rules/rust/patterns.md` の Newtype Pattern section 近傍に新 section「String Indexing with Multi-byte Characters」を追加 -- **記述内容**: - - **BAD**: `&haystack[start..start + N]` で N が byte offset の場合 → multi-byte で off-by-N bytes - - **GOOD**: `haystack[start..].char_indices().nth(N).map(|(i, _)| start + i).unwrap_or(haystack.len())` で N 文字目の byte offset を取得 - - **由来**: PR #200 priority_inversion `has_resolved_marker_after` (cite 必須) - - **関連**: rust/security.md § Input Validation の「Parse, don't validate」原則と相補 - -#### 作業計画 - -- [ ] `~/.claude/rules/rust/patterns.md` を Read で確認 (現状の section 構成) -- [ ] 新 section「String Indexing with Multi-byte Characters」を Newtype Pattern 近傍に追加 -- [ ] BAD/GOOD code sample + PR #200 引用 + 関連参照を記述 -- [ ] `feedback_global_config_backup` を適用して snapshot 取得 -- [ ] 本 todo10.md エントリを削除 - -#### 完了基準 - -- `~/.claude/rules/rust/patterns.md` に新 section が追加され、char_indices().nth() pattern が canonical reference として記述される -- PR #200 の修正箇所 (src/cli-docs-lint/src/priority_inversion.rs:178-184) が cite される - -#### 詰まっている箇所 - -なし。Effort XS、global rules への docs 追記のみ。 - ---- - -### ADR-007 に「Regex は loop 内で `LazyLock` 必須」guideline 追記 (PR #200 post-merge-feedback T3-2 採用) - -> **動機**: PR #200 で `priority_inversion::parse_tier` / `extract_referenced_ranks` が per-row `Regex::new()` 再 compile していた問題を `LazyLock` で module 初期化時の 1 回 compile に修正 (F-2)。同パターンの guideline は ADR-007 (custom linter regex/AST 層の線引き) に未記述で、将来の custom lint rule 著者が同型 bug を再生産するリスクあり。小規模 table では無害だが 1000+ 行 table では顕著な遅延。 -> -> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-09 ユーザー承認)。ADR-007 への guideline 追記で、本リポジトリの lint runner サポートと整合。 -> -> **参照**: `.claude/feedback-reports/200.md` Tier 3 #2、`src/cli-docs-lint/src/priority_inversion.rs:29-34` (TIER_REGEX / RANK_REGEX の LazyLock 定義)、ADR-007 (custom-linter-layer-boundary)。 -> -> **実行優先度**: 💎 **Tier 3** — 工数 XS。ADR-007 に 1 guideline (5-10 行) 追記のみ。 - -#### 設計決定 (案) - -- **配置**: `docs/adr/adr-007-custom-linter-layer-boundary.md` の「正規表現層」section に新 guideline 「Regex は loop / repeated call 内では `LazyLock` 必須」を追記 -- **記述内容**: - - **原則**: `Regex::new()` は重い処理 (regex compilation)。loop 内 / per-row call で繰り返すと累積コストが顕在化 - - **GOOD**: `static MY_REGEX: LazyLock = LazyLock::new(|| Regex::new(r"...").unwrap());` - - **由来**: PR #200 priority_inversion の `TIER_REGEX` / `RANK_REGEX` (cite 必須) - - **関連**: `~/.claude/rules/rust/coding-style.md` § Iterators Over Loops と相補 - -#### 作業計画 - -- [ ] `docs/adr/adr-007-custom-linter-layer-boundary.md` を Read で確認 (現状の section 構成) -- [ ] 「正規表現層」section に新 guideline を追記 -- [ ] LazyLock 利用例 + PR #200 引用を記述 -- [ ] 本 todo10.md エントリを削除 - -#### 完了基準 - -- ADR-007 に「Regex は loop / repeated call 内で LazyLock 必須」guideline が追記される -- PR #200 の TIER_REGEX / RANK_REGEX が参照実装として cite される - -#### 詰まっている箇所 - -なし。Effort XS、ADR への docs 追記のみ。 - ---- - -### `~/.claude/rules/common/testing.md` に「multi-path test fixture isolation」section 追記 (PR #200 post-merge-feedback T3-3 採用) - -> **動機**: PR #200 pre-push reviewer non-blocking finding F-3 で、test fixture が **意図せず複数 path をカバー** していると、将来 fixture 変更時に test 経路が silent shift する fragility が指摘された。修正は fixture を resolved-marker 非含有に変更し missing-rank 経路を厳密に exercise する形にした。この設計手法は sentinel pattern (`feedback_test_dry_antipattern` 起源、testing.md 既記述) と独立な「Path A を exercise する場合は Path B トリガー条件を意図的に除外」 pattern として汎用化できる。 -> -> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 3 #3 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-09 ユーザー承認)。sentinel section 直下に「multi-path test fixture isolation」変種として追加することで、test robustness パターンを補完。 -> -> **参照**: `.claude/feedback-reports/200.md` Tier 3 #3、`src/cli-docs-lint/src/priority_inversion.rs:633-637` (F-3 fix のテストコメント、fixture 設計意図)、PR #200 pre-push reviewer F-3 finding。 -> -> **実行優先度**: 💎 **Tier 3** — 工数 XS。`~/.claude/rules/common/testing.md` の sentinel section に 1 sub-section (10-15 行) 追記のみ。 - -#### 設計決定 (案) - -- **配置**: `~/.claude/rules/common/testing.md` の sentinel 事前投入 section 直下 -- **記述内容**: - - **原則**: 複数 path をカバーしうる fixture では、Path A を exercise する意図なら Path B トリガー条件を fixture から **明示除外** する。silent shift (= 将来 fixture 変更で test 経路が無告知に変わる) を防ぐ - - **BAD**: missing-rank 経路を exercise する test で fixture に resolved-marker (`(retire 済)`) を含める → 別経路でも skip するため意図 path が test されない - - **GOOD**: missing-rank 経路には resolved-marker 非含有 fixture (`順位 19 land 後推奨`) を使う → 純粋に missing-rank skip のみが exercise される - - **由来**: PR #200 F-3 fix (`is_rank_resolved` test fixture redesign) - - **関連**: sentinel 事前投入 (mutation 不在 assert) と相補的 — sentinel は「mutation が起こらないことを観測可能化」、本パターンは「意図 path を path-shift から保護」 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/testing.md` を Read で確認 (sentinel section の現状) -- [ ] sentinel section 直下に新 sub-section「multi-path test fixture isolation」を追加 -- [ ] BAD/GOOD example + PR #200 F-3 cite を記述 -- [ ] `feedback_global_config_backup` を適用して snapshot 取得 -- [ ] 本 todo10.md エントリを削除 - -#### 完了基準 - -- testing.md に新 sub-section が追加され、PR #200 F-3 fix が参照例として cite される -- sentinel pattern と相補的な独立パターンとして区別が明示される -- 派生プロジェクトでも同 rule が global 配下から自動波及 - -#### 詰まっている箇所 - -なし。Effort XS、global rules への docs 追記のみ。 - ---- - -### GitHub token alternation の variant test 完成 — `ghu_` / `ghr_` (PR #201 post-merge-feedback T2-1 採用) - -> **動機**: PR #201 で `(gho|ghs|ghu|ghr)_[A-Za-z0-9]{36}` の regex alternation に `ghu_` (user-to-server) / `ghr_` (refresh) の専用テストが欠落していることを 3 ソース (PR diff + pre-push NB-2 + CR NB-2) が独立検出。alternation グループは全 variant に 1+ test が原則で、将来 regex 簡略化時の silent drop regression を防止する。 -> -> **本タスクの位置づけ**: PR #201 post-merge-feedback Tier 2 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-10 ユーザー承認)。順位 145 preset matrix test と同根の test matrix mechanical 強化。Bundle-201-FB-A 候補 (T3-1 と同 PR で land 可能だが T3-1 は今回未採用のため単独 land でも可)。 -> -> **参照**: `.claude/feedback-reports/201.md` Tier 2 #1、`src/hooks-pre-tool-validate/src/main.rs` の `secret_detection_blocks_github_oauth_token` (gho_) / `secret_detection_blocks_github_server_token` (ghs_) test (既存テンプレート) -> -> **実行優先度**: 🔧 **Tier 2** — Effort XS。2 テストケース追加のみ (~10 行)。 - -#### 設計決定 (案) - -- 既存 `secret_detection_blocks_github_oauth_token` (gho_) / `secret_detection_blocks_github_server_token` (ghs_) と同パターンで `ghu_` / `ghr_` 用 test を追加 -- `is_blocked_with("let token = \"ghu_<36 chars>\";", SECRET_DETECT)` 形式 -- helper 共通化なし (memory `feedback_test_dry_antipattern` 適用)、independent setup - -#### 作業計画 - -- [ ] `secret_detection_blocks_github_user_to_server_token` test 関数追加 (ghu_ + 36 chars fixture) -- [ ] `secret_detection_blocks_github_refresh_token` test 関数追加 (ghr_ + 36 chars fixture) -- [ ] `cargo test -p hooks-pre-tool-validate` で全 pass 確認 (現 202 + 2 = 204) -- [ ] 本 todo10.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 4 variant (`gho_` / `ghs_` / `ghu_` / `ghr_`) すべてが専用 test で block 検証される -- 将来の regex 簡略化時の silent drop が test で検出される - -#### 詰まっている箇所 - -なし。Effort XS、test 追加のみ。 - ---- - -### ADR-007 に exception field + 専用 pattern の設計方針 codify (PR #201 post-merge-feedback T3-2 採用) - -> **動機**: Rust 標準 regex crate は negative lookahead 非対応のため、相互排他的な regex pattern を扱う際は `BlockedPattern.exception` field + 専用 pattern の 2 段判定が canonical solution。順位 144 `jj-message-required` (PR #171) で導入され、順位 146 `secret-detection` (PR #201) で Anthropic `sk-ant-` を OpenAI `sk-` から除外するのに再利用。2 PR で再利用 = Frequency Medium で ADR codify 妥当。将来の custom linter 実装者が negative lookahead を試みて iteration を浪費するのを防ぐ。 -> -> **本タスクの位置づけ**: PR #201 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-10 ユーザー承認)。ADR-007 への section 追加で、本リポジトリの lint runner サポートと整合。 -> -> **参照**: `.claude/feedback-reports/201.md` Tier 3 #2、[docs/adr/adr-007-custom-linter-layer-boundary.md](adr/adr-007-custom-linter-layer-boundary.md) (拡張先)、`src/hooks-pre-tool-validate/src/main.rs` の `preset_jj_message_required` / `preset_secret_detection` (参照実装) -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR-007 に 1 sub-section (10-15 行) 追記のみ。 - -#### 設計決定 (案) - -- **配置**: `docs/adr/adr-007-custom-linter-layer-boundary.md` の「正規表現層」section に新 sub-section「Mutual exclusion via `exception` field + dedicated pattern」を追加 -- **記述内容**: - - **原則**: 相互排他的な regex pattern (例: OpenAI `sk-` ⊃ Anthropic `sk-ant-`) を扱う際は negative lookahead ではなく `exception` field を使う - - **canonical pattern**: BlockedPattern { pattern: ..., exception: Some(...), message: ... } の 2 段判定 - - **defense in depth**: exception で除外した側を専用 pattern で別途検出 (Anthropic 専用 `\bsk-ant-[A-Za-z0-9_-]{20,}\b`) - - **由来**: PR #171 順位 144 (`jj-message-required` 導入) + PR #201 順位 146 (`secret-detection` 再利用) - - **関連**: 順位 201 ADR-007 LazyLock guideline と相補的に「正規表現層」section 内で 2 つの canonical pattern として共存 - -#### 作業計画 - -- [ ] `docs/adr/adr-007-custom-linter-layer-boundary.md` を Read で確認 (現状の section 構成) -- [ ] 「正規表現層」section に新 sub-section を追加 -- [ ] BAD (negative lookahead を試みる anti-pattern) / GOOD (exception field + 専用 pattern) code sample + PR #171 / #201 引用を記述 -- [ ] 本 todo10.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- ADR-007 に exception field + 専用 pattern 設計方針が codify される -- 順位 144 / 146 の実装が参照実装として cite される - -#### 詰まっている箇所 - -なし。Effort XS、ADR への docs 追記のみ。 - ---- - -### `~/.claude/rules/common/git-workflow.md` に jj auto-snapshot onboarding rule 追記 (PR #201 post-merge-feedback T3-4 採用) - -> **動機**: jj は git の staging-area モデルと異なり working tree 全体を即座に @ commit に取り込む (auto-snapshot)。この挙動を知らない agent / ユーザーが「prior session の docs commit (順位 199-202)」と「本セッションの impl 変更 (順位 146 secret-detection)」を同 @ commit に混入させ、結果として bundle PR にせざるを得ない事象が PR #201 で発生 (advisor 助言で bundle 化に収束)。 -> -> **本タスクの位置づけ**: PR #201 post-merge-feedback Tier 3 #4 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-10 ユーザー承認)。global `~/.claude/rules/common/git-workflow.md` への追記で派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ自動波及。`feedback_global_config_backup` 適用必須。 -> -> **参照**: `.claude/feedback-reports/201.md` Tier 3 #4、`~/.claude/rules/common/git-workflow.md` (拡張先、既存「jj Operations」section に追記)、PR #201 session log (auto-snapshot 由来の bundle 化事例、advisor consult) -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。`~/.claude/rules/common/git-workflow.md` に 1 sub-section (10-15 行) 追記のみ。 - -#### 設計決定 (案) - -- **配置**: `~/.claude/rules/common/git-workflow.md` の「jj Operations」section 直下に新 sub-section「Auto-snapshot の理解と logical separation」を追加 -- **記述内容**: - - **原則**: jj は staging area を持たず、working tree 全体を即座に @ commit に取り込む (auto-snapshot) - - **anti-pattern**: 異なる論理ユニットの作業を同 @ commit に混在させる (prior session commit に impl を後追いで足す等) - - **正しいフロー**: 新しい論理作業を始める前に必ず `jj new -m ""` で空の @ を作る (memory `feedback_no_empty_change_before_push` の補完: push 直前ではなく **作業開始時** に作る、これにより auto-snapshot で混入しても commit 説明と整合) - - **トラブル時**: bundle 化が唯一の分離手段 (multi-unit same-file edit は jj path-level split で分離不能、本リポジトリ PR #201 実証) - - **由来**: PR #201 session で順位 199-202 docs と順位 146 impl の auto-snapshot 混入事象を実観測、advisor 助言で redescribe + bundle 化に収束 - - **関連**: 既存「todo.md 完了タスク削除手順 (jj 環境)」と相補 - -#### 作業計画 - -- [ ] `~/.claude/` snapshot 取得 (`feedback_global_config_backup` 適用) -- [ ] `~/.claude/rules/common/git-workflow.md` の「jj Operations」section を Read で確認 -- [ ] 新 sub-section「Auto-snapshot の理解と logical separation」を追加 -- [ ] 「正しいフロー」記述 + PR #201 cite を記述 -- [ ] 本 todo10.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `~/.claude/rules/common/git-workflow.md` に auto-snapshot section が追加される -- PR #201 の bundle 化事例が cite される -- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) で同 rule が global 配下から自動波及 - -#### 詰まっている箇所 - -なし。Effort XS、global rules への docs 追記のみ。 - ---- - -## 既知課題 (記録のみ、本セッションで未対応) - -(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。) +# TODO (Part 10) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo9.md がファイルサイズ 50KB を超え行数 1100+ 行に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #185 = Bundle CR-RL land 後、2026-05-29 ユーザー判断)。**新規エントリの追加先は引き続き本ファイル** (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-12.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### ADR-NNN (採番未確定、land 時に確定): Timestamp invariant safety — 時刻計算 silent failure class の codify (PR #199 post-merge-feedback T3-2 採用、PR #203 T3-1 で 3 観測目に昇格) + +> **動機**: PR #96 Finding D (`cli-pr-monitor::lock` の `parse_age_secs` で `saturating_sub` silent semantic mismatch)、PR #199 Bundle W (`cli-pr-monitor::lock` に PastTime newtype + proptest で構造的予防)、PR #203 (`hooks-session-start` に PastTime + proptest 移植) で同型 bug class が **3 件観測 (Frequency High)**。本 ADR は「時刻計算における silent failure class と型レベル防御」を永続化し、派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability を確保する。 +> +> **本タスクの位置づけ**: PR #199 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None、2026-06-08 ユーザー承認)。PR #203 post-merge-feedback Tier 3 #1 で 3 観測目として再確認、2026-06-11 ユーザー承認 (analyzer は新規 entry を提案したが既存 entry 強化として merge、`feedback_post_merge_feedback_adoption_requires_user_approval` + 順位 194「task 着手前に grep」適用)。順位 135 codified placeholder policy を適用し ADR 番号は land 時 PR で空き番号を確定する (本 entry 登録時点で ADR-038/039/040/041/042/043 占有済、044 が最有力候補だが land 時に再確認)。 +> +> **参照**: `.claude/feedback-reports/199.md` Tier 3 #2、`.claude/feedback-reports/203.md` Tier 3 #1、PR #96 Finding D、PR #199 Bundle W (PastTime newtype 実装 + proptest properties 5 件)、PR #203 (hooks-session-start への port + integration test 追加)、`~/.claude/rules/rust/patterns.md` § Newtype Pattern (extension 候補)、順位 135 (ADR 番号 hardcode 撤廃 policy)、順位 78 (旧 ADR-038 → 041 → NNN の 3 段振り直し実証) +> +> **実行優先度**: 💎 **Tier 3** — 工数 Medium。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記。Frequency High (3 PR) に昇格したため優先度内で着手順を引き上げる余地あり。 + +#### 背景 + +- **Bug class の定義**: `saturating_sub(now, then)` 等の silent fallback が dominate ドメイン的に誤った値 (age=0) を返し、後段の判定で「fresh」「young」等の誤判定を生む +- **発生条件**: clock rewind (NTP 巻き戻し / VM snapshot restore) / 破損 future timestamp (corrupted lock file / 不正 input) / 時刻取得失敗 → silent fallback +- **防御原則**: 業務ロジック的に不可能な状態 (future timestamp の存在) を型層で unrepresentable にする。construction 時に invariant 検証、`age_secs()` 等の derived 値は invariant により安全に計算 +- **実証パターン**: PR #199 Bundle W で `PastTime { epoch_secs, captured_now }` newtype + `from_iso8601_now` / `from_parts` 2 経路 + `age_secs()` non-negative invariant + proptest 5 properties で構造化、PR #203 で同 pattern を `hooks-session-start` の orphan reaper に展開 (`saturating_sub` 排除 + integration test `find_orphans_skips_future_start_time_without_silent_age_zero` 追加) + +#### 設計決定 (案) + +- **ADR title (案)**: 「Timestamp invariant safety — 時刻計算 silent failure class と型レベル防御」 +- **ADR sections (案)**: + 1. **コンテキスト**: bug class 定義 + 観測実例 (PR #96 Finding D / PR #199 Bundle W / PR #203 hooks-session-start port) + 2. **決定**: + - 原則 1: `saturating_sub` を時刻計算で使用しない (silent fallback 禁止) + - 原則 2: 「過去性」を型で表現する (newtype + construction 時 invariant) + - 原則 3: proptest properties で type invariant を executable contract として記述 + 3. **設計哲学**: 「業務ロジック的に impossible な状態を型層で unrepresentable にする」(parse, don't validate 派生) + 4. **派生プロジェクト適用**: cli-pr-monitor (PR #199 で実装済) / hooks-session-start (PR #203 で実装済、共通 lib 化は順位 T2-1 で別 task) / 派生プロジェクトの時刻計算箇所 (検出→展開計画) + 5. **完了状態 / 関連 ADR**: PR #199 (実証)、PR #203 (port 実証)、ADR-021 / ADR-024 等の参照 + +- **CLAUDE.md ADR list**: 「ADR-NNN: Timestamp invariant safety + saturating_sub による silent fallback 禁止 *(試験運用)*」として追記 + +#### 作業計画 + +- [ ] land 時 PR で ADR 空き番号を確定 (現状最有力は ADR-044) +- [ ] `docs/adr/adr-NNN-timestamp-invariant-safety.md` を新規作成 (試験運用) +- [ ] CLAUDE.md ADR list に追記 +- [ ] PR #96 Finding D / PR #199 Bundle W / PR #203 hooks-session-start port を実例として inline cite +- [ ] (任意) `~/.claude/rules/rust/patterns.md` § Newtype Pattern に link back を追記 (順位 T3-1 様子見と連動で判断) +- [ ] 本 todo10.md エントリを削除 + +#### 完了基準 + +- ADR-NNN が docs/adr/ に存在し試験運用 status で 1 PR で land +- CLAUDE.md ADR list に追記され ADR タイトル + 試験運用 marker が表示される +- bug class が以降の reviewer (人間 / CodeRabbit / takt facet) から ADR 参照で言及可能になる + +#### 詰まっている箇所 + +- ADR 番号確定タイミング (land 時 PR) と他並走 entry (順位 78 等) の競合可能性。順位 135 placeholder policy に従い land 時 PR で grep 確認すれば構造的に解決 +- `~/.claude/rules/rust/patterns.md` への展開 (順位 T3-1 が 様子見) との順序関係。本 ADR が land してから patterns.md 拡張を再評価する流れで矛盾なし + +--- + +### multi-byte 文字を含む string window test の標準 coverage requirement 化 (PR #200 post-merge-feedback T2-1 採用) + +> **動機**: PR #200 で `priority_inversion::has_resolved_marker_after` の window 計算が **byte 演算** で、日本語 1 文字 = 3 bytes のため「80 文字」のつもりが実質 ~27 文字に縮退する Major bug が発生 (CR が指摘、char-based に修正済)。PR #199 でも `parse_age_secs` 周辺で byte/char 混乱があり、Frequency Medium (2 観測) で systemic。char-based fix と regression test (`is_resolved_detects_marker_across_multibyte_gap`) は PR #200 で完了済だが、**将来の新規 validator が同パターンで実装されたとき multi-byte test が無指定で欠落するリスク** を構造的に塞ぐ。 +> +> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 2 #1 採用 (Severity High / Frequency Medium / Effort S / Adoption Risk None、2026-06-09 ユーザー承認)。`is_resolved_detects_marker_across_multibyte_gap` スタイルを **coverage requirement** として位置付け、新規 validator 追加 PR で同パターンの test を必須化する。 +> +> **参照**: `.claude/feedback-reports/200.md` Tier 2 #1、`src/cli-docs-lint/src/priority_inversion.rs:469-473` (char-based window fix)、`is_resolved_detects_marker_across_multibyte_gap` test (regression)、PR #199 PastTime newtype + proptest (parse_age_secs 周辺の byte 演算)。 +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Small。Coverage requirement 化のみで実装作業は新 validator 追加時の test 追記 (チェックリスト + テストテンプレート)。 + +#### 設計決定 (案) + +- **配置**: `~/.claude/rules/common/testing.md` (multi-path test fixture 拡張と同じ section) または `src/cli-docs-lint/README.md` (validator 追加 checklist) +- **要求項目**: + - 文字列 window 演算 (`str::find` + byte offset / `[start..end]` slice) を行う validator は、**30 bytes 超 multi-byte 文字を含む regression test を 1 件以上保持** する + - 推奨 fixture: CJK 40 文字 (= 120 bytes) gap + 末尾に marker + - assertion で window 内検出を verify +- **enforcement layer**: + - 案 A: docs (manual checklist、reviewer に頼る) + - 案 B: custom-lint-rules.toml で `str::find` + `[..]` slice 使用 file に対応 multi-byte test の存在を grep ベースで弱検出 (FP リスク高、要検討) +- **MVP**: 案 A (docs/checklist) で開始、3-5 validator land 後に案 B 化を再評価 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/testing.md` の sentinel pattern section 末尾に「multi-byte string window test 必須」を追記 +- [ ] `src/cli-docs-lint/README.md` (or 該当 doc) に validator 追加 checklist として記載 +- [ ] PR #200 の `is_resolved_detects_marker_across_multibyte_gap` を参照テンプレートとして cite +- [ ] 派生プロジェクト deploy 計画 (techbook-ledger / auto-review-fix-vc) を別 task として todo 登録 +- [ ] 本 todo10.md エントリを削除 + +#### 完了基準 + +- testing.md に「multi-byte string window test 必須」requirement が追記され、参照テンプレートとして PR #200 test が cite される +- 派生プロジェクトでも同 rule が global 配下から自動波及 + +#### 詰まっている箇所 + +- 案 B (mechanical enforcement) は FP リスクが見えるため MVP では docs のみで開始。dogfood で test 漏れ実例が観測されたら案 B を再検討。 + +--- + +### `~/.claude/rules/rust/patterns.md` に「String Indexing with Multi-byte Characters」section 追加 (PR #200 post-merge-feedback T3-1 採用) + +> **動機**: PR #200 で `priority_inversion::has_resolved_marker_after` の byte/char 混同 Major bug を fix した際、`char_indices().nth(N)` パターンが Rust の canonical solution として有効と判明。同パターンは現在 `~/.claude/rules/rust/` に未記述で、将来の lint rule 著者が同型 bug を再生産するリスクあり。PR #199 (parse_age_secs 周辺) + PR #200 (priority_inversion) で 2 観測 = Frequency Medium。 +> +> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-09 ユーザー承認)。global `~/.claude/rules/rust/patterns.md` への section 追加で、派生プロジェクト (techbook-ledger / auto-review-fix-vc) へも自動波及。 +> +> **参照**: `.claude/feedback-reports/200.md` Tier 3 #1、`src/cli-docs-lint/src/priority_inversion.rs:178-184` (char_indices() pattern)、PR #199 (parse_age_secs byte/char 観測)。 +> +> **実行優先度**: 💎 **Tier 3** — 工数 XS。`~/.claude/rules/rust/patterns.md` に 1 section (10-20 行) 追加のみ。 + +#### 設計決定 (案) + +- **配置**: `~/.claude/rules/rust/patterns.md` の Newtype Pattern section 近傍に新 section「String Indexing with Multi-byte Characters」を追加 +- **記述内容**: + - **BAD**: `&haystack[start..start + N]` で N が byte offset の場合 → multi-byte で off-by-N bytes + - **GOOD**: `haystack[start..].char_indices().nth(N).map(|(i, _)| start + i).unwrap_or(haystack.len())` で N 文字目の byte offset を取得 + - **由来**: PR #200 priority_inversion `has_resolved_marker_after` (cite 必須) + - **関連**: rust/security.md § Input Validation の「Parse, don't validate」原則と相補 + +#### 作業計画 + +- [ ] `~/.claude/rules/rust/patterns.md` を Read で確認 (現状の section 構成) +- [ ] 新 section「String Indexing with Multi-byte Characters」を Newtype Pattern 近傍に追加 +- [ ] BAD/GOOD code sample + PR #200 引用 + 関連参照を記述 +- [ ] `feedback_global_config_backup` を適用して snapshot 取得 +- [ ] 本 todo10.md エントリを削除 + +#### 完了基準 + +- `~/.claude/rules/rust/patterns.md` に新 section が追加され、char_indices().nth() pattern が canonical reference として記述される +- PR #200 の修正箇所 (src/cli-docs-lint/src/priority_inversion.rs:178-184) が cite される + +#### 詰まっている箇所 + +なし。Effort XS、global rules への docs 追記のみ。 + +--- + +### ADR-007 に「Regex は loop 内で `LazyLock` 必須」guideline 追記 (PR #200 post-merge-feedback T3-2 採用) + +> **動機**: PR #200 で `priority_inversion::parse_tier` / `extract_referenced_ranks` が per-row `Regex::new()` 再 compile していた問題を `LazyLock` で module 初期化時の 1 回 compile に修正 (F-2)。同パターンの guideline は ADR-007 (custom linter regex/AST 層の線引き) に未記述で、将来の custom lint rule 著者が同型 bug を再生産するリスクあり。小規模 table では無害だが 1000+ 行 table では顕著な遅延。 +> +> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 3 #2 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-09 ユーザー承認)。ADR-007 への guideline 追記で、本リポジトリの lint runner サポートと整合。 +> +> **参照**: `.claude/feedback-reports/200.md` Tier 3 #2、`src/cli-docs-lint/src/priority_inversion.rs:29-34` (TIER_REGEX / RANK_REGEX の LazyLock 定義)、ADR-007 (custom-linter-layer-boundary)。 +> +> **実行優先度**: 💎 **Tier 3** — 工数 XS。ADR-007 に 1 guideline (5-10 行) 追記のみ。 + +#### 設計決定 (案) + +- **配置**: `docs/adr/adr-007-custom-linter-layer-boundary.md` の「正規表現層」section に新 guideline 「Regex は loop / repeated call 内では `LazyLock` 必須」を追記 +- **記述内容**: + - **原則**: `Regex::new()` は重い処理 (regex compilation)。loop 内 / per-row call で繰り返すと累積コストが顕在化 + - **GOOD**: `static MY_REGEX: LazyLock = LazyLock::new(|| Regex::new(r"...").unwrap());` + - **由来**: PR #200 priority_inversion の `TIER_REGEX` / `RANK_REGEX` (cite 必須) + - **関連**: `~/.claude/rules/rust/coding-style.md` § Iterators Over Loops と相補 + +#### 作業計画 + +- [ ] `docs/adr/adr-007-custom-linter-layer-boundary.md` を Read で確認 (現状の section 構成) +- [ ] 「正規表現層」section に新 guideline を追記 +- [ ] LazyLock 利用例 + PR #200 引用を記述 +- [ ] 本 todo10.md エントリを削除 + +#### 完了基準 + +- ADR-007 に「Regex は loop / repeated call 内で LazyLock 必須」guideline が追記される +- PR #200 の TIER_REGEX / RANK_REGEX が参照実装として cite される + +#### 詰まっている箇所 + +なし。Effort XS、ADR への docs 追記のみ。 + +--- + +### `~/.claude/rules/common/testing.md` に「multi-path test fixture isolation」section 追記 (PR #200 post-merge-feedback T3-3 採用) + +> **動機**: PR #200 pre-push reviewer non-blocking finding F-3 で、test fixture が **意図せず複数 path をカバー** していると、将来 fixture 変更時に test 経路が silent shift する fragility が指摘された。修正は fixture を resolved-marker 非含有に変更し missing-rank 経路を厳密に exercise する形にした。この設計手法は sentinel pattern (`feedback_test_dry_antipattern` 起源、testing.md 既記述) と独立な「Path A を exercise する場合は Path B トリガー条件を意図的に除外」 pattern として汎用化できる。 +> +> **本タスクの位置づけ**: PR #200 post-merge-feedback Tier 3 #3 採用 (Severity Medium / Frequency Low / Effort XS / Adoption Risk None、2026-06-09 ユーザー承認)。sentinel section 直下に「multi-path test fixture isolation」変種として追加することで、test robustness パターンを補完。 +> +> **参照**: `.claude/feedback-reports/200.md` Tier 3 #3、`src/cli-docs-lint/src/priority_inversion.rs:633-637` (F-3 fix のテストコメント、fixture 設計意図)、PR #200 pre-push reviewer F-3 finding。 +> +> **実行優先度**: 💎 **Tier 3** — 工数 XS。`~/.claude/rules/common/testing.md` の sentinel section に 1 sub-section (10-15 行) 追記のみ。 + +#### 設計決定 (案) + +- **配置**: `~/.claude/rules/common/testing.md` の sentinel 事前投入 section 直下 +- **記述内容**: + - **原則**: 複数 path をカバーしうる fixture では、Path A を exercise する意図なら Path B トリガー条件を fixture から **明示除外** する。silent shift (= 将来 fixture 変更で test 経路が無告知に変わる) を防ぐ + - **BAD**: missing-rank 経路を exercise する test で fixture に resolved-marker (`(retire 済)`) を含める → 別経路でも skip するため意図 path が test されない + - **GOOD**: missing-rank 経路には resolved-marker 非含有 fixture (`順位 19 land 後推奨`) を使う → 純粋に missing-rank skip のみが exercise される + - **由来**: PR #200 F-3 fix (`is_rank_resolved` test fixture redesign) + - **関連**: sentinel 事前投入 (mutation 不在 assert) と相補的 — sentinel は「mutation が起こらないことを観測可能化」、本パターンは「意図 path を path-shift から保護」 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/testing.md` を Read で確認 (sentinel section の現状) +- [ ] sentinel section 直下に新 sub-section「multi-path test fixture isolation」を追加 +- [ ] BAD/GOOD example + PR #200 F-3 cite を記述 +- [ ] `feedback_global_config_backup` を適用して snapshot 取得 +- [ ] 本 todo10.md エントリを削除 + +#### 完了基準 + +- testing.md に新 sub-section が追加され、PR #200 F-3 fix が参照例として cite される +- sentinel pattern と相補的な独立パターンとして区別が明示される +- 派生プロジェクトでも同 rule が global 配下から自動波及 + +#### 詰まっている箇所 + +なし。Effort XS、global rules への docs 追記のみ。 + +--- + +### GitHub token alternation の variant test 完成 — `ghu_` / `ghr_` (PR #201 post-merge-feedback T2-1 採用) + +> **動機**: PR #201 で `(gho|ghs|ghu|ghr)_[A-Za-z0-9]{36}` の regex alternation に `ghu_` (user-to-server) / `ghr_` (refresh) の専用テストが欠落していることを 3 ソース (PR diff + pre-push NB-2 + CR NB-2) が独立検出。alternation グループは全 variant に 1+ test が原則で、将来 regex 簡略化時の silent drop regression を防止する。 +> +> **本タスクの位置づけ**: PR #201 post-merge-feedback Tier 2 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-10 ユーザー承認)。順位 145 preset matrix test と同根の test matrix mechanical 強化。Bundle-201-FB-A 候補 (T3-1 と同 PR で land 可能だが T3-1 は今回未採用のため単独 land でも可)。 +> +> **参照**: `.claude/feedback-reports/201.md` Tier 2 #1、`src/hooks-pre-tool-validate/src/main.rs` の `secret_detection_blocks_github_oauth_token` (gho_) / `secret_detection_blocks_github_server_token` (ghs_) test (既存テンプレート) +> +> **実行優先度**: 🔧 **Tier 2** — Effort XS。2 テストケース追加のみ (~10 行)。 + +#### 設計決定 (案) + +- 既存 `secret_detection_blocks_github_oauth_token` (gho_) / `secret_detection_blocks_github_server_token` (ghs_) と同パターンで `ghu_` / `ghr_` 用 test を追加 +- `is_blocked_with("let token = \"ghu_<36 chars>\";", SECRET_DETECT)` 形式 +- helper 共通化なし (memory `feedback_test_dry_antipattern` 適用)、independent setup + +#### 作業計画 + +- [ ] `secret_detection_blocks_github_user_to_server_token` test 関数追加 (ghu_ + 36 chars fixture) +- [ ] `secret_detection_blocks_github_refresh_token` test 関数追加 (ghr_ + 36 chars fixture) +- [ ] `cargo test -p hooks-pre-tool-validate` で全 pass 確認 (現 202 + 2 = 204) +- [ ] 本 todo10.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 4 variant (`gho_` / `ghs_` / `ghu_` / `ghr_`) すべてが専用 test で block 検証される +- 将来の regex 簡略化時の silent drop が test で検出される + +#### 詰まっている箇所 + +なし。Effort XS、test 追加のみ。 + +--- + +### ADR-007 に exception field + 専用 pattern の設計方針 codify (PR #201 post-merge-feedback T3-2 採用) + +> **動機**: Rust 標準 regex crate は negative lookahead 非対応のため、相互排他的な regex pattern を扱う際は `BlockedPattern.exception` field + 専用 pattern の 2 段判定が canonical solution。順位 144 `jj-message-required` (PR #171) で導入され、順位 146 `secret-detection` (PR #201) で Anthropic `sk-ant-` を OpenAI `sk-` から除外するのに再利用。2 PR で再利用 = Frequency Medium で ADR codify 妥当。将来の custom linter 実装者が negative lookahead を試みて iteration を浪費するのを防ぐ。 +> +> **本タスクの位置づけ**: PR #201 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-10 ユーザー承認)。ADR-007 への section 追加で、本リポジトリの lint runner サポートと整合。 +> +> **参照**: `.claude/feedback-reports/201.md` Tier 3 #2、[docs/adr/adr-007-custom-linter-layer-boundary.md](adr/adr-007-custom-linter-layer-boundary.md) (拡張先)、`src/hooks-pre-tool-validate/src/main.rs` の `preset_jj_message_required` / `preset_secret_detection` (参照実装) +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR-007 に 1 sub-section (10-15 行) 追記のみ。 + +#### 設計決定 (案) + +- **配置**: `docs/adr/adr-007-custom-linter-layer-boundary.md` の「正規表現層」section に新 sub-section「Mutual exclusion via `exception` field + dedicated pattern」を追加 +- **記述内容**: + - **原則**: 相互排他的な regex pattern (例: OpenAI `sk-` ⊃ Anthropic `sk-ant-`) を扱う際は negative lookahead ではなく `exception` field を使う + - **canonical pattern**: BlockedPattern { pattern: ..., exception: Some(...), message: ... } の 2 段判定 + - **defense in depth**: exception で除外した側を専用 pattern で別途検出 (Anthropic 専用 `\bsk-ant-[A-Za-z0-9_-]{20,}\b`) + - **由来**: PR #171 順位 144 (`jj-message-required` 導入) + PR #201 順位 146 (`secret-detection` 再利用) + - **関連**: 順位 201 ADR-007 LazyLock guideline と相補的に「正規表現層」section 内で 2 つの canonical pattern として共存 + +#### 作業計画 + +- [ ] `docs/adr/adr-007-custom-linter-layer-boundary.md` を Read で確認 (現状の section 構成) +- [ ] 「正規表現層」section に新 sub-section を追加 +- [ ] BAD (negative lookahead を試みる anti-pattern) / GOOD (exception field + 専用 pattern) code sample + PR #171 / #201 引用を記述 +- [ ] 本 todo10.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- ADR-007 に exception field + 専用 pattern 設計方針が codify される +- 順位 144 / 146 の実装が参照実装として cite される + +#### 詰まっている箇所 + +なし。Effort XS、ADR への docs 追記のみ。 + +--- + +### `~/.claude/rules/common/git-workflow.md` に jj auto-snapshot onboarding rule 追記 (PR #201 post-merge-feedback T3-4 採用) + +> **動機**: jj は git の staging-area モデルと異なり working tree 全体を即座に @ commit に取り込む (auto-snapshot)。この挙動を知らない agent / ユーザーが「prior session の docs commit (順位 199-202)」と「本セッションの impl 変更 (順位 146 secret-detection)」を同 @ commit に混入させ、結果として bundle PR にせざるを得ない事象が PR #201 で発生 (advisor 助言で bundle 化に収束)。 +> +> **本タスクの位置づけ**: PR #201 post-merge-feedback Tier 3 #4 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-10 ユーザー承認)。global `~/.claude/rules/common/git-workflow.md` への追記で派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ自動波及。`feedback_global_config_backup` 適用必須。 +> +> **参照**: `.claude/feedback-reports/201.md` Tier 3 #4、`~/.claude/rules/common/git-workflow.md` (拡張先、既存「jj Operations」section に追記)、PR #201 session log (auto-snapshot 由来の bundle 化事例、advisor consult) +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。`~/.claude/rules/common/git-workflow.md` に 1 sub-section (10-15 行) 追記のみ。 + +#### 設計決定 (案) + +- **配置**: `~/.claude/rules/common/git-workflow.md` の「jj Operations」section 直下に新 sub-section「Auto-snapshot の理解と logical separation」を追加 +- **記述内容**: + - **原則**: jj は staging area を持たず、working tree 全体を即座に @ commit に取り込む (auto-snapshot) + - **anti-pattern**: 異なる論理ユニットの作業を同 @ commit に混在させる (prior session commit に impl を後追いで足す等) + - **正しいフロー**: 新しい論理作業を始める前に必ず `jj new -m ""` で空の @ を作る (memory `feedback_no_empty_change_before_push` の補完: push 直前ではなく **作業開始時** に作る、これにより auto-snapshot で混入しても commit 説明と整合) + - **トラブル時**: bundle 化が唯一の分離手段 (multi-unit same-file edit は jj path-level split で分離不能、本リポジトリ PR #201 実証) + - **由来**: PR #201 session で順位 199-202 docs と順位 146 impl の auto-snapshot 混入事象を実観測、advisor 助言で redescribe + bundle 化に収束 + - **関連**: 既存「todo.md 完了タスク削除手順 (jj 環境)」と相補 + +#### 作業計画 + +- [ ] `~/.claude/` snapshot 取得 (`feedback_global_config_backup` 適用) +- [ ] `~/.claude/rules/common/git-workflow.md` の「jj Operations」section を Read で確認 +- [ ] 新 sub-section「Auto-snapshot の理解と logical separation」を追加 +- [ ] 「正しいフロー」記述 + PR #201 cite を記述 +- [ ] 本 todo10.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `~/.claude/rules/common/git-workflow.md` に auto-snapshot section が追加される +- PR #201 の bundle 化事例が cite される +- 派生プロジェクト (techbook-ledger / auto-review-fix-vc) で同 rule が global 配下から自動波及 + +#### 詰まっている箇所 + +なし。Effort XS、global rules への docs 追記のみ。 + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。) diff --git a/docs/todo11.md b/docs/todo11.md index bbc4748b..f7bfa968 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-11.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 の既存エントリは引き続き有効、相互に独立。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 diff --git a/docs/todo12.md b/docs/todo12.md new file mode 100644 index 00000000..e1d7f5cc --- /dev/null +++ b/docs/todo12.md @@ -0,0 +1,389 @@ +# TODO (Part 12) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: 2026-06-12 PR #204 で `docs/todo10.md` がファイルサイズ 50KB を超え、順位 177 `file_size_check` (PR #197 で実装、本 PR で default ON 化) が触られたファイルに warning を出す状態になったため、PR #185 〜 PR #196 era (= 順位 176/178/179/180/181/182/193/194) の active entries を本ファイルに分離した専用ファイル。**新規追加先ではない** (新規エントリは引き続き [docs/todo10.md](todo10.md) に記録)。todo10.md / todo11.md の既存エントリと同じく相互に独立。新セッションでは todo*.md と todo-summary.md をすべて確認すること。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### check-ci-coderabbit format extraction 関数への variant fixture 追加 (PR #185 T2-#4 採用) + +> **動機**: PR #185 (Bundle CR-RL) で `extract_old_format_wait_time` / `extract_new_format_wait_time` の 2 helper 関数に分離し 3 新規 fixture (full / minutes-only / 旧新混在) を追加したが、analyzer (post-merge-feedback) は **bold-wrapper variant** (例: `**More reviews will be available in N minutes and S seconds**`) や **その他の組合せ variant** の coverage gap を指摘。PR #182 (30+ 分 polling 浪費の実観測) + PR #185 (format 多様性対応) の 2 PR 連続観測で、CR の format は引き続き variants を生む可能性が高く、防御的 fixture coverage 追加が systemic 価値あり。 +> +> **本タスクの位置づけ**: PR #185 post-merge-feedback Tier 2 #4 採用 (Severity High / Frequency Medium / Effort M / Adoption Risk None、2026-05-29 ユーザー承認)。順位 167-169 (Bundle CR-RL) の follow-up として next format drift での silent regression 防止網を厚くする。 +> +> **参照**: `.claude/feedback-reports/185.md` Tier 2 #4、`src/check-ci-coderabbit/src/main.rs` の `#[cfg(test)]` mod (既存 9 fixture = 6 旧 format + 3 新 format)、`extract_old_format_wait_time` / `extract_new_format_wait_time` の regex (現状 markdown bold `\*?\*?` は旧 format のみ対応、新 format は bold 想定なし) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。fixture 追加のみで runtime 影響なし。 +> +> **注意 (analyzer rationale の一部に弱点)**: post-merge-feedback report は「PR #185 で 6 回の Edit が同一ファイルに集中した incremental development パターンは test coverage gap の兆候」と述べているが、これは incidental development pattern であり test coverage の真の signal ではない。採用根拠は **CR format 多様性 (PR #182 + #185 の 2 PR 連続観測) + bold-wrapper 等の防御的 variant 追加の妥当性** であり、Edit 集中は無関係。 + +#### 設計決定 (案) + +追加候補 fixture (memory `feedback_test_dry_antipattern`: 各 variant 独立 setup): + +- **bold-wrapper 新 format**: `**More reviews will be available in 15 minutes and 30 seconds**` — CR が markdown bold を新 format に追加した場合の検出 + - 現 `extract_new_format_wait_time` の regex はこの場合 fail する (旧 format の `\*?\*?` 相当を新 format regex にも追加する必要あり) + - もし fail を assertion で確認するなら fixture は「現状の振る舞いを pin」、もし regex を pre-emptively 拡張するなら「拡張後の動作 verify」 +- **secs だけ provided 新 format**: `More reviews will be available in 45 seconds` (minutes 0 + seconds N の variant、CR が短時間 rate-limit を表現する場合) +- **複数 separator 旧 format**: `Please wait 5 minutes, 13 seconds` (`and` ではなく `,` 使用、観測例なしだが defensive) +- **HTML マーカーのみで wait time 文言なし**: ` ## Review limit reached` のみ → wait time 抽出失敗 = `parse_rate_limit` が None を返すことを assert (graceful failure verify) + +#### 設計判断 (regex 拡張 vs fixture のみ追加) + +2 つのアプローチ: + +1. **regex 拡張先行**: `extract_new_format_wait_time` の regex に `\*?\*?` 等を pre-emptively 追加し、それを fixture で verify する (= 想定 variant への先回り対応) +2. **fixture 先行 + 観測後 regex 拡張**: 現状の regex で fixture を書き、bold-wrapper variant では fail することを assert (= 現状の振る舞いを pin、観測ベース対応に倣う) + +どちらを採るかは本タスク着手時に判断。memory `feedback_no_unenforced_rules` の「未観測の preventive over-engineering を避ける」原則からは 2 が一貫性あり。1 を採るならその根拠 (=「regex 拡張は trivial で false positive リスクなし」) を commit description に明示する。 + +#### 作業計画 + +- [ ] 既存 9 fixture (`#[cfg(test)]` mod) を Read で全件確認、coverage gap を整理 +- [ ] 追加 4 fixture を独立 `#[test]` 関数として追加 (helper 共通化なし、memory `feedback_test_dry_antipattern` 適用) +- [ ] `cargo test -p check-ci-coderabbit` で全 fixture pass を確認 (新 + 既存 backward compat 維持) +- [ ] regex 拡張アプローチを採る場合は `extract_*_format_wait_time` の regex を更新、対応する `--release` test 確認 +- [ ] ADR-034 § 既知 CR rate-limit format 一覧 table に新 variant を 1 行 append (発見時期 = 「2026-05-29 防御的追加 (順位 176 land 時)」) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 4 新規 fixture が `cargo test -p check-ci-coderabbit` で全 pass +- bold-wrapper / 短形態 / graceful failure 等の variant coverage 確立 +- silent regression を test で 1 件以上検出できる構造 (= regex を意図的に元に戻すと新 fixture test が落ちる) +- ADR-034 § 既知 format 一覧 table の append による永続 reference 整合 + +#### 詰まっている箇所 + +regex 拡張アプローチ (#1) vs fixture のみ追加 (#2) の選択。本タスク着手時に bold-wrapper の CR 実観測例が増えていれば #1、increase なしなら #2 を採る判断が memory `feedback_no_unenforced_rules` の原則に整合する。 + +--- + +### `state.rs` の behavioral invariant test を ADR-041 pattern で追加 (週次レビュー 2026-05-30 S02 採用) + +> **動機**: 週次レビュー WR-2026-05-30-S02 で検出。`src/cli-pr-monitor/src/state.rs:226-510` の test は JSON round-trip (serde 直列化 / 逆直列化) のみを検証し、**behavioral invariant** (例: `rate_limit` が `Some` の場合に `update_state_from_check_result()` が `ci` field を populate しない) を test していない。状態遷移 regression が test suite を通り抜ける構造的リスク。ADR-041 (Test Isolation Patterns for Multi-Condition Guards) で確立された「sentinel 事前投入 + mutation 不在を assert」pattern が本リポジトリの canonical 対策。 +> +> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。analyzer rationale: "Concrete, low-effort (add 3-5 tests), high value (catches state regression bugs). ADR-041 is already the project's documented pattern for this exact problem type." +> +> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/state.rs:226-510` (既存 test、JSON round-trip のみ)、`docs/adr/adr-041-test-isolation-patterns.md` (適用 pattern source) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。3-5 test 追加で済む、既存 ADR-041 pattern 流用。 + +#### 設計決定 (案) + +- **対象 invariant 候補** (analyzer 提案 + 派生): + 1. `rate_limit` が `Some` 時、`update_state_from_check_result()` は `ci` field を更新しない + 2. `rate_limit.until_unix_secs` が過去時刻になった場合、次回 update で `rate_limit` が `None` に reset される (timer expiry) + 3. `notified` flag が `true` の場合、再度 `update_state_*` を呼んでも `notified` は維持される (idempotency) + 4. (実装側で発見し次第追加) +- **ADR-041 pattern 適用**: + - 各 test variant は独立 setup (`memory feedback_test_dry_antipattern`) + - sentinel value を事前投入 (`ci.overall = "MUTATION_CHECK_SENTINEL"` 等)、mutation が起こったか否かを明示的に assert + - guard condition を partial に偽にする setup で「他 guard が真でも mutation が起こらないこと」を保証 + +#### 作業計画 + +- [ ] `src/cli-pr-monitor/src/state.rs:226-510` を Read で全件確認、現状の test スコープと不足 invariant を整理 +- [ ] ADR-041 § Test Isolation Patterns を Read で再確認 +- [ ] 3-5 behavioral invariant test を `#[cfg(test)]` mod に追加 (memory `feedback_test_dry_antipattern` 適用、各 variant 独立 setup) +- [ ] cargo test -p cli-pr-monitor で全 pass 確認 +- [ ] mutation regression check: 意図的に invariant を破る変更 (例: rate_limit check を削除) を local で適用して新 test が落ちるか手動検証 +- [ ] cargo clippy clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 3-5 behavioral invariant test が追加され全 pass +- silent regression を test で 1 件以上検出できる構造 (意図破壊で新 test 落ちる確認済) +- ADR-041 pattern の rationale を test コメントで cite (sentinel 事前投入 + mutation 不在 assert) + +#### 詰まっている箇所 + +なし。Effort S、既存 pattern + 既存 test 構造への追加で完結。 + +--- + +### rate-limit retry decision boundary test を rstest parameterized で追加 (週次レビュー 2026-05-30 S03 採用) + +> **動機**: 週次レビュー WR-2026-05-30-S03 で検出。`src/cli-pr-monitor/src/config.rs:94-122` の rate-limit retry logic + `stages/poll.rs` 周辺で、`max_retries=3` (固定値) のみが test されており **decision boundary** (`max_retries=0` で retry されない / `max_retries=1` で 1 回だけ retry / `max_retries=3` で boundary 通過後 `action_required` 遷移) が未検証。off-by-one error (`<` vs `<=`) が silent regression として通る構造的リスク。rstest crate は既に本リポジトリで使用済のため新 dep 不要。 +> +> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=simplicity, category=test-anti-pattern、2026-05-30 ユーザー承認)。Bundle CR-RL (順位 167-169) と隣接領域 (= rate-limit detection の周辺 logic) のため follow-up 価値高。analyzer rationale: "Low effort (rstest parameterized test, ~15 lines). rstest is already in use in the codebase. High value: catches the exact off-by-one class that single-value tests miss." +> +> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/cli-pr-monitor/src/config.rs:94-122` (RateLimitConfig + max_retries field)、`src/cli-pr-monitor/src/stages/poll.rs` (retry 適用 site)、Bundle CR-RL (順位 167-169) の隣接 context、`feedback_test_dry_antipattern` 適用 + +#### 設計決定 (案) + +- **rstest parameterized test 構造**: + + ```rust + #[rstest] + #[case(0, vec![])] // max_retries=0: retry なし + #[case(1, vec![true, false])] // max_retries=1: 1 retry 後 stop + #[case(3, vec![true, true, true, false])] // max_retries=3: full boundary coverage + fn rate_limit_retry_boundary(#[case] max_retries: u32, #[case] expected_continues: Vec) { + // setup + execution + assert + } + ``` + +- **boundary 観点**: + - 0 retry: 最初の attempt の後 `action_required` 遷移を確認 + - max_retries 到達: 連続 retry 後の最終 attempt で `action_required` に遷移 + - off-by-one: `< max_retries` か `<= max_retries` かを test 経由で pin (実装の `<` を `<=` に変えると新 test が落ちる) + +#### 作業計画 + +- [ ] `src/cli-pr-monitor/src/config.rs` の `RateLimitConfig::max_retries` 周辺 + `stages/poll.rs` の retry decision logic を Read で確認 +- [ ] 既存 rstest 使用箇所を grep で確認、import / pattern を踏襲 +- [ ] `#[cfg(test)]` mod に `rate_limit_retry_boundary` parameterized test を追加 (3-4 case) +- [ ] cargo test -p cli-pr-monitor で全 pass 確認 +- [ ] off-by-one regression check: `<` を `<=` に意図的変更で test が落ちることを手動検証 +- [ ] cargo clippy clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 3-4 parameterized case が全 pass +- off-by-one error が test で検出可能 (`<` ↔ `<=` mutation で test 落ちる) +- 既存単一値 test は維持 (backward compat) + +#### 詰まっている箇所 + +なし。Effort S、rstest pattern 既存使用 + 約 15 行で完結。 + +--- + +### `lib-report-formatter` に markdown pipe / newline escape を追加 (週次レビュー 2026-05-30 C01 採用) + +> **動機**: 週次レビュー WR-2026-05-30-C01 で検出。`src/lib-report-formatter/src/lib.rs:51-79` の `format_table()` が PR title / commit message を markdown table 行に直接埋め込むが、`|` / `\n` を escape していない。「`Fix | Critical | src/main.rs`」のような PR title が markdown table 構造を破壊し、**downstream AI facet が malformed row を Read 時に misinterpret する prompt injection リスク** が存在。PR title は外部 actor (= PR 作成者) が制御可能な input source のため defense-in-depth 重要。 +> +> **本タスクの位置づけ**: 週次レビュー (ADR-031) 2026-05-30 dogfood で採用 (severity=medium, facet=security, category=prompt-injection、2026-05-30 ユーザー承認)。本セッションの 5 PR chain で AI facet 連鎖が systemic 化したため、prompt injection 防御層は今後の facet 拡張 (順位 153 / 154 等) でも継続価値あり。 +> +> **参照**: `.claude/weekly-reviews/2026-05-30.md` § Findings、`src/lib-report-formatter/src/lib.rs:51-79` (format_table 実装)、`src/cli-merge-pipeline/src/feedback.rs:114-123` (PR title データ source)、ADR-022 (責務分離) との整合 (= utility は lib-* に集約) + +#### 設計決定 (案) + +- **`escape_markdown_pipe(s: &str) -> String`** ユーティリティを `lib-report-formatter` に追加: + + ```rust + pub fn escape_markdown_pipe(input: &str) -> String { + input.replace('|', "\\|").replace('\n', " ") + } + ``` + +- **call site 修正**: `format_table()` で user-controlled field (PR title / commit message / author) を embed する箇所に `escape_markdown_pipe()` を適用 +- **test 追加** (memory `feedback_test_dry_antipattern` 適用、各 variant 独立): + - 通常 ASCII (pipe / newline なし) → 変更なし + - pipe 単独 (`a | b`) → `a \| b` + - newline 単独 (`a\nb`) → `a b` + - pipe + newline 混合 + - empty string + +#### 作業計画 + +- [ ] `src/lib-report-formatter/src/lib.rs:51-79` を Read で `format_table()` 全体確認、user-controlled embed 箇所を特定 +- [ ] `escape_markdown_pipe()` を lib に追加、pub export +- [ ] `format_table()` の embed call site を escape 経由に書き換え +- [ ] `#[cfg(test)]` に 5 variant test を独立 setup で追加 +- [ ] cargo test + cargo clippy clean +- [ ] 受け先 (cli-merge-pipeline 等) で test がまだ pass することを cargo test --workspace で確認 (call signature 変更なしのため backward compat 維持) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `escape_markdown_pipe()` が `lib-report-formatter` に pub function として追加される +- 5 variant test が独立 pass +- `format_table()` の user-controlled embed が escape 経由になる +- markdown table 構造破壊 PR title (`Fix | Critical`) を fixture で渡しても table 整合維持を assert + +#### 詰まっている箇所 + +なし。Effort S、5 行 utility + call site 修正 + 5 test で完結。 + +--- + +### `aggregate-weekly` facet の `findings.json` 出力を raw JSON にする (Phase D dogfood D-A 採用) + +> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で検出した skill 統合 bug。`aggregate-weekly` facet が write する `findings.json` が ` ```json ... ``` ` の markdown code fence で wrap されており、Phase C skill (`/weekly-review`) が JSON parser に直接渡せない。本 dogfood では skill 内で fence を手動 strip して pending JSON を構築したが、**facet 出力を raw JSON にすれば skill 側の workaround が不要**になる。 +> +> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) の skill flow 実観測で発見、本 PR の dogfood 観測点 (D-A) として user 承認 (2026-05-30)。週次レビュー (ADR-031) facet 出力の整合性確保。 +> +> **参照**: `.takt/facets/instructions/aggregate-weekly.md` (修正対象)、`.takt/runs/20260529-150611-weekly-review-2026-05-30/reports/findings.json` (Phase D dogfood で実観測した fence 付き出力)、`~/.claude/skills/weekly-review/SKILL.md` Phase 2 (現 skill が手動 fence strip した workaround) + +#### 設計決定 (案) + +- **`aggregate-weekly.md` の output 指示を明確化**: + - 現状: instruction が「JSON は ... `findings.json` というファイル名で write する」と書いてあるが、facet LLM が markdown 出力癖 (` ```json...``` ` 自動 wrap) で fence 付きで write してしまう + - 修正: instruction で「**raw JSON のみ** (markdown code fence なし) で write する。先頭は `{` で始まり、末尾は `}` で終わる必要がある」を明示 + - test 文言例: `{"run_date": "...", ...}` から始まる、` ```json` で始まらない、を強調 +- **alternative**: skill 側で fence 検出 + strip を実装する (但し source-of-truth が facet 側であるべき) + +#### 作業計画 + +- [ ] `.takt/facets/instructions/aggregate-weekly.md` の `## Phase 3` (= JSON 生成 section) に「**raw JSON 出力必須、markdown code fence で囲まない**」warning を追加 +- [ ] JSON 出力例の前後 context を Edit で明確化 +- [ ] dogfood: 修正後に次の `/weekly-review` 実行で `findings.json` が raw JSON で出力されることを実観測 (Phase E で確認) +- [ ] (option) Phase C skill SKILL.md にも「fence wrap された場合の defensive strip 手順」を補足追記 (= belt-and-suspenders) +- [ ] markdownlint clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `aggregate-weekly.md` instruction で raw JSON 出力要件が明示される +- 次回 `/weekly-review` 実行で `findings.json` が raw JSON (= ` ```` ` で wrap されない) で出力される dogfood 観測 + +#### 詰まっている箇所 + +facet 側の文言修正のみで facet LLM の出力 habit を矯正できるかは未確定。修正後の dogfood 結果次第で alternative (= skill 側 strip) に切り替える判断あり。Effort XS-S。 + +--- + +### `/weekly-review` skill に重複検出 (簡易 grep) を Phase 4 で追加 (Phase D dogfood D-B 採用) + +> **動機**: Phase D dogfood (週次レビュー 2026-05-30 実行) で **WR-2026-05-30-S05 (`combine_output` dead-code) が既存 順位 173 (PR #182 dry-run S01 採用) と完全重複**であることを実観測。ADR-031 § Phase 4 で「**重複検出は MVP では実装しない**」と明示済だが、本 dogfood で「2 PR で同じ finding が出る」を実証したため、最低限の grep ベース簡易検出を後追い追加する妥当性が確立。MVP は description 先頭 40 chars の grep ヒットを警告表示するのみで、自動 merge は行わない (user 判断に委ねる ADR-031 原則維持)。 +> +> **本タスクの位置づけ**: Phase D dogfood (本セッション 2026-05-30 実施) で observability gain (= 重複が見える) を実証、user 承認 (2026-05-30) で skill 拡張採用。Phase E 試験運用 dogfood の前に整備しておくと user 判断負荷を圧縮。 +> +> **参照**: `~/.claude/skills/weekly-review/SKILL.md` Phase 4 (修正対象)、ADR-031 § todo.md 反映ルール (「重複検出は MVP では実装しない」記述、本タスクで「MVP+1」相当に拡張)、Phase D dogfood の実観測 (WR-2026-05-30-S05 ↔ 順位 173 重複) + +#### 設計決定 (案) + +- **簡易 grep 重複検出 in Phase 4**: + + ```bash + # finding を docs/todo.md 系列に書き込む前に実行 + TITLE_PREFIX=$(echo "$finding_description" | head -c 40) + HITS=$(grep -li "$TITLE_PREFIX" docs/todo.md docs/todo*.md 2>/dev/null) + if [ -n "$HITS" ]; then + # AskUserQuestion で「augment / 新規 / skip」を聞く + fi + ``` + +- **3 択 AskUserQuestion**: + 1. **augment**: 既存 entry に補足追記 (= 「重複 observation を別 dogfood で再確認、優先度上昇」記録) + 2. **新規**: 重複と認識した上で別 entry 化 (= scope or角度 が異なる場合) + 3. **skip**: 重複と認識して書き込まない (= 既存 entry で十分) +- **自動 merge は行わない**: ADR-031 原則の「重複検出は MVP では実装しない」(自動 merge は MVP 超過、observability のみ提供) は維持 +- **grep target**: `docs/todo.md docs/todo2-11.md` 全件 (= 現在の todo file 集合、新 todoN+1.md 追加時は SKILL.md update が必要) + +#### 作業計画 + +- [ ] `~/.claude/skills/weekly-review/SKILL.md` Phase 4 § 重複検出 (簡易) を expansion: 現状の grep + 警告のみ → 警告 + 3 択 AskUserQuestion に変更 +- [ ] grep target file 列を docs/todo*.md glob 化、追加ファイル時の自動追従 (固定 list 回避) +- [ ] dogfood 観測の cite を skill 内 inline で明示 (= Phase D 2026-05-30 で WR-2026-05-30-S05 ↔ 順位 173 重複検出済、本 logic が機能した実例) +- [ ] **`feedback_global_config_backup` 適用**: ~/.claude/skills/ 編集前 snapshot 取得 +- [ ] markdownlint clean +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への skill 配布判断は別タスク (本 skill は global 配置だが ADR-031 自体は本リポジトリ ADR、派生展開は要検討) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- skill Phase 4 で grep 重複検出 → 3 択 AskUserQuestion → user 判断 経路が実装される +- 次回 `/weekly-review` 実行で重複候補が user 提示される dogfood 観測 +- ADR-031 「重複検出 MVP 未実装」を「MVP+1 (簡易 grep)」相当に格上げ、但し自動 merge なし原則は維持 +- skill 編集前後の ~/.claude snapshot が backup される + +#### 詰まっている箇所 + +なし。Effort XS-S、SKILL.md の Phase 4 section 拡張 + Bash snippet 追加で完結。 + +--- + +### Companion helper group 署名整合 compile-time validation test (PR #196 T2-1 採用) + +> **動機**: Bundle 195-FB (PR #196) で `count_empty_in_pr_range` だけ `default_branch` 引数化が漏れていた問題 (CR Major + pre-push F-1) を rule⑫ で **literal hardcode 層** では機械検出するようになったが、companion helper group (`assert_descriptions_absent/present_in_pr_range` / `count_empty_in_pr_range` / 将来追加される helper) の **API signature 整合性** は lint rule では catch できない (= AST レベル complexity)。4 番目以降の helper 追加時に signature drift が発生しても rule⑫ は fire しない silent regression リスク。 +> +> **本タスクの位置づけ**: PR #196 post-merge-feedback Tier 2 #2 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None、2026-06-05 ユーザー承認)。test-level validation で構造強制、Bundle 195-FB Layer 1 (rule⑫) + Layer 2 (parameterize) の seal 層として位置付け。analyzer は Tier 1 lint rule (item 1) を ROI 不釣合いとして却下推奨済、本 test approach は Tier 2 内 alternative。 +> +> **参照**: `.claude/feedback-reports/196.md` Tier 2 #2、`src/cli-pr-monitor/src/fix_commit.rs` (test module 内 companion helper group)、PR #195 commit `9663dd68` (前 2 関数の修正)、PR #196 commit `qntnzyxt` (Layer 2 = 3 関数目の整合) +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。compile-time witness (関数ポインタキャスト) で signature drift を test 不通過にする構造。 + +#### 設計決定 (案) + +Rust の compile-time check で signature drift を検出する pattern: + +```rust +#[test] +fn companion_helpers_share_default_branch_signature() { + // Compile-time witness: 各 helper が (&Path, &str, ...) signature を取ることを強制。 + // 新 helper を group に追加した際は本 test の末尾に同型 cast を追加して compile-time + // 整合性を seal する。signature が drift すると本 test が compile error で落ちる。 + let _: fn(&std::path::Path, &str, &[&str]) = assert_descriptions_absent_in_pr_range; + let _: fn(&std::path::Path, &str, &[&str]) = assert_descriptions_present_in_pr_range; + let _: fn(&std::path::Path, &str) -> usize = count_empty_in_pr_range; +} +``` + +- 関数ポインタへの cast は compile-time check (= test 関数 body 内の statement だが実行時 cost ≒ 0) +- signature drift → compile error → cargo test 不通過 +- 新 helper 追加時の運用: companion group の prefix (`*_in_pr_range` 等) で命名一致するなら本 test に 1 行追加を **`code-review.md` § Review Checklist** で reviewer 注意喚起 (rule⑫ + 本 test + Reviewer 注意の 3 層防御) + +#### 作業計画 + +- [ ] `src/cli-pr-monitor/src/fix_commit.rs` の `#[cfg(test)] mod tests` 内に `companion_helpers_share_default_branch_signature` test を追加 +- [ ] `cargo test --bin cli-pr-monitor fix_commit::tests::companion_helpers_share_default_branch_signature` で pass 確認 +- [ ] mutation regression check: 意図的に 1 関数の signature を変更 (例: `count_empty_in_pr_range(&Path) -> usize`) して compile error で落ちることを手動確認 +- [ ] `~/.claude/rules/common/code-review.md` § Review Checklist の末尾に「companion helper group の signature 整合は compile-time witness test で seal、新 helper 追加時は test に 1 行追加」を 1 項目追加 (3 層防御の reviewer 喚起層) +- [ ] cargo clippy clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- compile-time witness test が `fix_commit.rs` test module に追加され pass +- signature 意図変更で compile error 観測 (dogfood) +- code-review.md § Review Checklist に reviewer 注意項目追加 (global rule、派生プロジェクト波及) + +#### 詰まっている箇所 + +なし。Effort S、3-5 行 test 追加 + code-review.md 1 行追加で完結。 + +--- + +### development-workflow.md 「1. Plan First」に「task 着手前に grep で既存 section 確認」step 追記 (PR #196 T3-5 採用) + +> **動機**: PR #196 pre-push reviewer OBS-1 で「tasks 191/192 が既実装 sections を再度計画対象としていた」と指摘 (実態は cleanup diff の誤読だが、similar pattern は PR #123 でも観測済で Frequency Medium)。task 計画段階で「対象 section が既に global rules / ADR に存在するか `grep` で確認する」step を `~/.claude/rules/common/development-workflow.md` "1. Plan First" に追記し、後続 task 計画時の redundant 提案を構造的に予防する。 +> +> **本タスクの位置づけ**: PR #196 post-merge-feedback Tier 3 #5 採用 (Severity Medium / Frequency Medium / Effort XS / Adoption Risk None、2026-06-05 ユーザー承認)。development-workflow.md への 1-2 行追記のみ、派生プロジェクト (techbook-ledger / auto-review-fix-vc) に global rule として自動波及。 +> +> **参照**: `.claude/feedback-reports/196.md` Tier 3 #5、PR #196 pre-push OBS-1 (`.takt/runs/20260605-054100-pre-push-review/`)、PR #123 同型事象 (analyzer report 内 cite)、memory `feedback_global_config_backup` (snapshot 必須) +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule への 1-2 行追記。 + +#### 設計決定 (案) + +`~/.claude/rules/common/development-workflow.md` の **Feature Implementation Workflow** "1. Plan First" sub-step に以下を追記: + +```markdown +- **Codification 重複の事前確認**: 計画段階で「対象 section が既に global rules (`~/.claude/rules/common/*.md`) / ADR (`docs/adr/*.md`) / 既存 docs に存在するか」を `grep -n` で必ず確認する。重複追加は reviewer 混乱 + global rule の冗長化を招く。確認手順: + - `grep -rn "
" ~/.claude/rules/common/ docs/adr/ docs/` + - hit があれば既存 codification を読み、追記 vs 新規 vs skip を判断 + - 由来: PR #123 / PR #196 で同型「既実装 section の重複計画」事象を観測 +``` + +- **適用範囲**: 「ADR/global rule への新規 section codify」を含む全 task 計画 +- **派生プロジェクト波及**: `~/.claude/rules/common/` 配下のため techbook-ledger / auto-review-fix-vc に自動 + +#### 作業計画 + +- [ ] `~/.claude` snapshot 取得 (memory `feedback_global_config_backup` per) +- [ ] `~/.claude/rules/common/development-workflow.md` Feature Implementation Workflow "1. Plan First" sub-step に上記項目を追加 +- [ ] PR #123 + #196 を実例として inline cite +- [ ] markdownlint clean +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- development-workflow.md "1. Plan First" に Codification 重複確認 step が追記 +- 派生プロジェクトに global rule として波及 +- 由来 cite (PR #123, #196) で reviewer / Claude が rule 背景を理解可能 + +#### 詰まっている箇所 + +なし。Effort XS、docs 編集のみ。 + +--- diff --git a/docs/todo3.md b/docs/todo3.md index 6f80780b..cd8e31af 100644 --- a/docs/todo3.md +++ b/docs/todo3.md @@ -1,183 +1,183 @@ -# TODO (Part 3) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo2.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #88 以降の新規エントリは本ファイルに記録した。本ファイルも PR #96 セッションで 50KB 接近のため、それ以降の新規エントリは [docs/todo4.md](todo4.md) へ。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### `vitest` を devDependencies に固定 (PR #88 T2-3) - -> **動機**: Stop hook の `pnpm test` → `npx vitest run` が `pnpm-lock.yaml` に vitest なしのため npx がネット DL を試みて偽陽性 FAIL する事象を観測。ネット環境・キャッシュ依存の不確実性を排除し、Stop gate を deterministic にする。 -> -> **本タスクの位置づけ**: PR #88 で markdownlint-cli2 を `--no-install` で安定化させたのと同じ思想。テスト実行が外部 DL なしで完結する状態を維持する。 -> -> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #3 finding -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Small。Stop gate の偽陽性 FAIL を排除する効果は中-高 (毎回の Stop で発生する潜在リスクの解消)。 - -#### 背景 - -- `package.json` の `"test": "npx vitest run"` は vitest がローカルにあれば走るが、なければ npx が DL を試みる -- ネット未接続環境やプロキシ環境で偽陽性 FAIL → 開発体験悪化 -- markdownlint-cli2 は PR #88 で `--no-install` を付けて DL を抑止、devDependencies で版固定済 → 同じパターンを vitest にも適用 - -#### 設計決定 (案) - -- 案 A: `vitest` を devDependencies に追加し `pnpm-lock.yaml` に固定。`pnpm test` script は変更不要 (`npx --no-install vitest run` とするか `vitest run` 直呼びにするかは実装時判断) -- 案 B: `pnpm test` script を `npx --no-install vitest run` に変更し、明示的にローカル参照を強制 -- 推奨: 案 A + script 側を `--no-install` 付きに変更 (二重防御) -- 既存テストが現行通り動作することを確認 (既存の vitest 設定は不変、依存固定のみ) - -#### 作業計画 - -- [ ] `vitest` の現行バージョン確認 (`npx vitest --version` 等) -- [ ] `pnpm add -D vitest` (またはインスタンス化済バージョンで固定) -- [ ] `package.json` の test script を `npx --no-install vitest run` に更新 -- [ ] `pnpm test` 動作確認 -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- `pnpm test` がローカルの vitest のみで動作 (ネット切断状態で実行可) -- Stop hook の偽陽性 FAIL が発生しなくなる -- `pnpm-lock.yaml` に vitest が固定されている - -#### 詰まっている箇所 - -なし (Effort Small、devDep 追加 + script 修正のみ) - ---- - -### `pnpm create-pr` 必須引数未指定時のヘルプ改善 (PR #88 T2-5) - -> **動機**: 引数なしで `pnpm create-pr` を実行すると `gh pr create` が `must provide --title and --body (or --fill or fill-first or --fillverbose)` エラーのみ出力し、使用例が示されない。今回 PR 作成時に手動ワークアラウンド (`pnpm prepare-pr-body` で `.tmp-pr-body.md` 生成 → `pnpm create-pr -- --title "..." --body-file .tmp-pr-body.md`) が必要になった。`gh` のエラーをそのまま流す現設計だと、Claude や人間が次の手を察するのに余計な往復が発生する。 -> -> **本タスクの位置づけ**: cli-pr-monitor の UX 改善。現実装は `gh pr create` への薄い wrapper だが、必須引数チェックを wrapper 側で実施することで使用例付きエラーを返せる。 -> -> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #5 finding -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Small。daily efficiency への影響中 (PR 作成は頻繁ではないが、エラー時の摩擦が高い)。 - -#### 背景 - -- 現実装: `cli-pr-monitor.exe` (PR 作成モード) は受け取った args をそのまま `gh pr create` に forwarding -- `gh` のエラーは英語かつ汎用的。プロジェクト固有の推奨 (prepare-pr-body スクリプトを使う等) は反映されない -- Claude / 人間の双方が「`pnpm prepare-pr-body` を先に呼ぶ」運用を覚える必要がある - -#### 設計決定 (案) - -- cli-pr-monitor の PR 作成モード入口で `--title` / `--body` / `--body-file` / `--fill*` 系のいずれかが指定されているかチェック -- 未指定なら使用例付きエラーを stderr に出力して非 0 で exit: - -```text -Error: PR title and body are required. -Usage: - pnpm create-pr -- --title "feat: ..." --body-file .tmp-pr-body.md - pnpm create-pr -- --title "feat: ..." --fill-verbose -Hint: - Run `pnpm prepare-pr-body` first to generate `.tmp-pr-body.md` from stdin. -``` - -- gh の実行は引数チェック後にのみ進む - -#### 作業計画 - -- [ ] cli-pr-monitor の PR 作成モード入口で arg validation 追加 -- [ ] エラーメッセージ作成 (上記の使用例ベース) -- [ ] dogfood: 引数なしで `pnpm create-pr` 実行 → 改善されたエラーが出ることを確認 -- [ ] 既存の正常系 (--title --body-file 指定時) が変わらず動作することを確認 -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- 引数なし実行でプロジェクト固有の使用例 + Hint がエラーに含まれる -- `--title` + `--body-file` または `--fill*` 指定時は従来通り PR 作成が走る - -#### 詰まっている箇所 - -なし (Effort Small、cli-pr-monitor 入口の arg parser 拡張のみ) - ---- - -### `.failed` marker への recovery 手順自己文書化 (PR #90 T2-2) - -> **動機**: ADR-030 で確立した soft-fail 機構 (`.md.failed` marker + L2 recovery) は PR #89 セッションで実際に発火し、UserPromptSubmit hook 経由で recovery が機能することが実証された。しかし現状の marker file は識別子のみで、recovery に必要な手順 (再実行コマンド、必要な引数、想定所要時間、よくある失敗原因) が外部 (ADR-030 / skill SKILL.md) を参照しないと分からない。marker 自体に手順を埋め込めば、将来 (ドキュメント所在を忘れた時 / ADR-030 が改訂された時 / 派生プロジェクトでの再現時) の recovery が省力化される。 -> -> **本タスクの位置づけ**: ADR-030 の運用負荷削減。soft-fail 機構そのものは正しく動作しているため、UX 改善カテゴリ。marker file の content をテンプレート化し、生成側 (cli-merge-pipeline) で recovery 手順 + コマンド例 + ADR-030 への参照を含める。 -> -> **参照**: `.claude/feedback-reports/90.md` の Tier 2 #2 finding -> -> **実行優先度**: 🔧 **Tier 2** — 工数 S。daily efficiency への影響中 (recovery 発生頻度は低いが、発生時の摩擦を低減)。rate-limit 系 task (cli-pr-monitor ポーリング延長 PR #88 T2-4、完了済 / post-pr-review rate-limit 自動検出) ほど critical ではないが、ADR-030 の long-term 運用品質に寄与。 - -#### 背景 - -- ADR-030 の L1 (cli-merge-pipeline → takt workflow 同期実行) が失敗した場合、`.claude/feedback-reports/.md.failed` marker が残存する設計 -- L2 recovery (UserPromptSubmit hook) が次セッションで marker を検出し additionalContext で再実行を促す -- PR #89 セッションで実際に soft-fail が発火し、recovery 経路が機能した実証あり -- 課題: marker file の content が空 or 識別用の最小情報のみで、再実行手順は外部ドキュメント (ADR-030 / skill SKILL.md) を参照する必要がある -- 将来リスク: ADR-030 改訂・派生プロジェクト展開・時間経過による参照先不明化により、recovery が高摩擦化する可能性 - -#### 設計決定 (案) - -- cli-merge-pipeline (or takt workflow 失敗時の marker 書込み箇所) で marker content をテンプレート化 -- テンプレート例: - -~~~markdown -# Post-Merge Feedback Failed: PR # - -This marker indicates the post-merge feedback workflow failed for PR #. -The L2 recovery hook (UserPromptSubmit) will detect this file on the next -prompt and prompt Claude to re-run the workflow. - -## Manual Recovery (if L2 hook does not fire) - -1. Check the takt run logs at `.takt/runs//` for the failure reason. -2. Re-run the workflow: - - ```sh - takt run post-merge-feedback.yaml --input pr= - ``` - -3. On success this marker will be replaced by `.claude/feedback-reports/.md`. - -## Failure Context - -- Failed at: -- takt run id: -- Last error (truncated to 500 chars): - -## Reference - -- ADR-030: docs/adr/adr-030-deterministic-post-merge-feedback.md -~~~ - -- marker 内容は ADR 改訂耐性のため「ADR-030 への参照リンク + 当時の手順」を共存させる -- 失敗の context (timestamp / run-id / stderr tail) を含めることで、再実行前に原因切り分けがしやすくなる -- 本タスク完了後、L2 hook の additionalContext からも marker content を読ませる構成にすれば自己完結度が上がる (本タスクの拡張、必須ではない) - -#### 作業計画 - -- [ ] cli-merge-pipeline の `.failed` marker 書込みロジックを確認 (現状 content がどう生成されているか) -- [ ] テンプレート文字列を crate 内 const として定義 or 外部 template ファイル化を判定 -- [ ] timestamp / run-id / stderr tail を marker に埋め込む実装 -- [ ] L2 hook (`hooks-user-prompt-feedback-recovery` 等) の additionalContext 出力で marker content を流用するか判定 (本タスクの scope 内 or 別タスク化) -- [ ] dogfood: 意図的に takt fail を inject し、marker に手順 + context が含まれることを確認 -- [ ] ADR-030 を更新 (marker format の section を追記) -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- `.failed` marker file に recovery 手順 + コマンド例 + ADR-030 参照 + failure context が含まれる -- ADR-030 の本文に marker format が明文化される -- 派生プロジェクトでも同じ template が機能する (ADR-030 が外部 reference として読める前提) - -#### 詰まっている箇所 - -なし (Effort S、cli-merge-pipeline の marker 書込み箇所のテンプレート化のみ) - - +# TODO (Part 3) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo2.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #88 以降の新規エントリは本ファイルに記録した。本ファイルも PR #96 セッションで 50KB 接近のため、それ以降の新規エントリは [docs/todo4.md](todo4.md) へ。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### `vitest` を devDependencies に固定 (PR #88 T2-3) + +> **動機**: Stop hook の `pnpm test` → `npx vitest run` が `pnpm-lock.yaml` に vitest なしのため npx がネット DL を試みて偽陽性 FAIL する事象を観測。ネット環境・キャッシュ依存の不確実性を排除し、Stop gate を deterministic にする。 +> +> **本タスクの位置づけ**: PR #88 で markdownlint-cli2 を `--no-install` で安定化させたのと同じ思想。テスト実行が外部 DL なしで完結する状態を維持する。 +> +> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #3 finding +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Small。Stop gate の偽陽性 FAIL を排除する効果は中-高 (毎回の Stop で発生する潜在リスクの解消)。 + +#### 背景 + +- `package.json` の `"test": "npx vitest run"` は vitest がローカルにあれば走るが、なければ npx が DL を試みる +- ネット未接続環境やプロキシ環境で偽陽性 FAIL → 開発体験悪化 +- markdownlint-cli2 は PR #88 で `--no-install` を付けて DL を抑止、devDependencies で版固定済 → 同じパターンを vitest にも適用 + +#### 設計決定 (案) + +- 案 A: `vitest` を devDependencies に追加し `pnpm-lock.yaml` に固定。`pnpm test` script は変更不要 (`npx --no-install vitest run` とするか `vitest run` 直呼びにするかは実装時判断) +- 案 B: `pnpm test` script を `npx --no-install vitest run` に変更し、明示的にローカル参照を強制 +- 推奨: 案 A + script 側を `--no-install` 付きに変更 (二重防御) +- 既存テストが現行通り動作することを確認 (既存の vitest 設定は不変、依存固定のみ) + +#### 作業計画 + +- [ ] `vitest` の現行バージョン確認 (`npx vitest --version` 等) +- [ ] `pnpm add -D vitest` (またはインスタンス化済バージョンで固定) +- [ ] `package.json` の test script を `npx --no-install vitest run` に更新 +- [ ] `pnpm test` 動作確認 +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- `pnpm test` がローカルの vitest のみで動作 (ネット切断状態で実行可) +- Stop hook の偽陽性 FAIL が発生しなくなる +- `pnpm-lock.yaml` に vitest が固定されている + +#### 詰まっている箇所 + +なし (Effort Small、devDep 追加 + script 修正のみ) + +--- + +### `pnpm create-pr` 必須引数未指定時のヘルプ改善 (PR #88 T2-5) + +> **動機**: 引数なしで `pnpm create-pr` を実行すると `gh pr create` が `must provide --title and --body (or --fill or fill-first or --fillverbose)` エラーのみ出力し、使用例が示されない。今回 PR 作成時に手動ワークアラウンド (`pnpm prepare-pr-body` で `.tmp-pr-body.md` 生成 → `pnpm create-pr -- --title "..." --body-file .tmp-pr-body.md`) が必要になった。`gh` のエラーをそのまま流す現設計だと、Claude や人間が次の手を察するのに余計な往復が発生する。 +> +> **本タスクの位置づけ**: cli-pr-monitor の UX 改善。現実装は `gh pr create` への薄い wrapper だが、必須引数チェックを wrapper 側で実施することで使用例付きエラーを返せる。 +> +> **参照**: `.claude/feedback-reports/88.md` の Tier 2 #5 finding +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Small。daily efficiency への影響中 (PR 作成は頻繁ではないが、エラー時の摩擦が高い)。 + +#### 背景 + +- 現実装: `cli-pr-monitor.exe` (PR 作成モード) は受け取った args をそのまま `gh pr create` に forwarding +- `gh` のエラーは英語かつ汎用的。プロジェクト固有の推奨 (prepare-pr-body スクリプトを使う等) は反映されない +- Claude / 人間の双方が「`pnpm prepare-pr-body` を先に呼ぶ」運用を覚える必要がある + +#### 設計決定 (案) + +- cli-pr-monitor の PR 作成モード入口で `--title` / `--body` / `--body-file` / `--fill*` 系のいずれかが指定されているかチェック +- 未指定なら使用例付きエラーを stderr に出力して非 0 で exit: + +```text +Error: PR title and body are required. +Usage: + pnpm create-pr -- --title "feat: ..." --body-file .tmp-pr-body.md + pnpm create-pr -- --title "feat: ..." --fill-verbose +Hint: + Run `pnpm prepare-pr-body` first to generate `.tmp-pr-body.md` from stdin. +``` + +- gh の実行は引数チェック後にのみ進む + +#### 作業計画 + +- [ ] cli-pr-monitor の PR 作成モード入口で arg validation 追加 +- [ ] エラーメッセージ作成 (上記の使用例ベース) +- [ ] dogfood: 引数なしで `pnpm create-pr` 実行 → 改善されたエラーが出ることを確認 +- [ ] 既存の正常系 (--title --body-file 指定時) が変わらず動作することを確認 +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- 引数なし実行でプロジェクト固有の使用例 + Hint がエラーに含まれる +- `--title` + `--body-file` または `--fill*` 指定時は従来通り PR 作成が走る + +#### 詰まっている箇所 + +なし (Effort Small、cli-pr-monitor 入口の arg parser 拡張のみ) + +--- + +### `.failed` marker への recovery 手順自己文書化 (PR #90 T2-2) + +> **動機**: ADR-030 で確立した soft-fail 機構 (`.md.failed` marker + L2 recovery) は PR #89 セッションで実際に発火し、UserPromptSubmit hook 経由で recovery が機能することが実証された。しかし現状の marker file は識別子のみで、recovery に必要な手順 (再実行コマンド、必要な引数、想定所要時間、よくある失敗原因) が外部 (ADR-030 / skill SKILL.md) を参照しないと分からない。marker 自体に手順を埋め込めば、将来 (ドキュメント所在を忘れた時 / ADR-030 が改訂された時 / 派生プロジェクトでの再現時) の recovery が省力化される。 +> +> **本タスクの位置づけ**: ADR-030 の運用負荷削減。soft-fail 機構そのものは正しく動作しているため、UX 改善カテゴリ。marker file の content をテンプレート化し、生成側 (cli-merge-pipeline) で recovery 手順 + コマンド例 + ADR-030 への参照を含める。 +> +> **参照**: `.claude/feedback-reports/90.md` の Tier 2 #2 finding +> +> **実行優先度**: 🔧 **Tier 2** — 工数 S。daily efficiency への影響中 (recovery 発生頻度は低いが、発生時の摩擦を低減)。rate-limit 系 task (cli-pr-monitor ポーリング延長 PR #88 T2-4、完了済 / post-pr-review rate-limit 自動検出) ほど critical ではないが、ADR-030 の long-term 運用品質に寄与。 + +#### 背景 + +- ADR-030 の L1 (cli-merge-pipeline → takt workflow 同期実行) が失敗した場合、`.claude/feedback-reports/.md.failed` marker が残存する設計 +- L2 recovery (UserPromptSubmit hook) が次セッションで marker を検出し additionalContext で再実行を促す +- PR #89 セッションで実際に soft-fail が発火し、recovery 経路が機能した実証あり +- 課題: marker file の content が空 or 識別用の最小情報のみで、再実行手順は外部ドキュメント (ADR-030 / skill SKILL.md) を参照する必要がある +- 将来リスク: ADR-030 改訂・派生プロジェクト展開・時間経過による参照先不明化により、recovery が高摩擦化する可能性 + +#### 設計決定 (案) + +- cli-merge-pipeline (or takt workflow 失敗時の marker 書込み箇所) で marker content をテンプレート化 +- テンプレート例: + +~~~markdown +# Post-Merge Feedback Failed: PR # + +This marker indicates the post-merge feedback workflow failed for PR #. +The L2 recovery hook (UserPromptSubmit) will detect this file on the next +prompt and prompt Claude to re-run the workflow. + +## Manual Recovery (if L2 hook does not fire) + +1. Check the takt run logs at `.takt/runs//` for the failure reason. +2. Re-run the workflow: + + ```sh + takt run post-merge-feedback.yaml --input pr= + ``` + +3. On success this marker will be replaced by `.claude/feedback-reports/.md`. + +## Failure Context + +- Failed at: +- takt run id: +- Last error (truncated to 500 chars): + +## Reference + +- ADR-030: docs/adr/adr-030-deterministic-post-merge-feedback.md +~~~ + +- marker 内容は ADR 改訂耐性のため「ADR-030 への参照リンク + 当時の手順」を共存させる +- 失敗の context (timestamp / run-id / stderr tail) を含めることで、再実行前に原因切り分けがしやすくなる +- 本タスク完了後、L2 hook の additionalContext からも marker content を読ませる構成にすれば自己完結度が上がる (本タスクの拡張、必須ではない) + +#### 作業計画 + +- [ ] cli-merge-pipeline の `.failed` marker 書込みロジックを確認 (現状 content がどう生成されているか) +- [ ] テンプレート文字列を crate 内 const として定義 or 外部 template ファイル化を判定 +- [ ] timestamp / run-id / stderr tail を marker に埋め込む実装 +- [ ] L2 hook (`hooks-user-prompt-feedback-recovery` 等) の additionalContext 出力で marker content を流用するか判定 (本タスクの scope 内 or 別タスク化) +- [ ] dogfood: 意図的に takt fail を inject し、marker に手順 + context が含まれることを確認 +- [ ] ADR-030 を更新 (marker format の section を追記) +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- `.failed` marker file に recovery 手順 + コマンド例 + ADR-030 参照 + failure context が含まれる +- ADR-030 の本文に marker format が明文化される +- 派生プロジェクトでも同じ template が機能する (ADR-030 が外部 reference として読める前提) + +#### 詰まっている箇所 + +なし (Effort S、cli-merge-pipeline の marker 書込み箇所のテンプレート化のみ) + + diff --git a/docs/todo4.md b/docs/todo4.md index bc47ceaa..389a7b14 100644 --- a/docs/todo4.md +++ b/docs/todo4.md @@ -1,238 +1,238 @@ -# TODO (Part 4) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo3.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録していた。**本ファイルも 50KB に到達したため、PR #101 セッション以降の新規エントリは [docs/todo5.md](todo5.md) へ**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) - -> **動機**: Bundle W (PBT + 型) で書かれた properties が「実装を本当に制約しているか」を後段で機械的に測定する layer。`cargo mutants` は production code に微小変異を注入し、全 mutant が少なくとも 1 つの test で fail することを要求する。survivor mutant は「test がこのコードを制約していない」の直接的証拠で、PBT の弱さや coverage gap を mechanical に暴く。Bundle W で「仕様を articulate」、Bundle X で「articulate された仕様の強さを測定」の二層構造を完成させる。 -> -> **本タスクの位置づけ**: Bundle X の **L2 layer (post-PR)**。順位 37 (pre-push stress runner) と同 PR で land 推奨。Bundle W land 済 (2026-06-07、PR で `cli-pr-monitor::lock` の PastTime newtype + proptest properties 5 件 land) → mutants 投入の前提整備完了。 -> -> **参照**: PR #96 セッション内議論、ユーザーフィードバック「mutation scope を 変更ファイル + 依存モジュール 1 層 に拡大」。 -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Medium。post-PR pipeline (post-pr-monitor の前後) に組み込み、PR 単位で 1-5 分追加。user 待機 0 (async)。 - -#### 背景 - -- 試算: cli-pr-monitor (4724 LoC) で 150-500 mutants → 5-17 分 -- 変更 crate のみ + 1-hop 依存に scope 限定: 50-150 mutants → 1-5 分 -- 既存 cli-pr-monitor で実測しないと正確な数字は出ない (試算の桁ずれリスクあり) - -#### 設計決定 (案) - -- **scope 戦略**: 変更 file + `cargo metadata` で抽出した 1-hop 依存 module -- **配置先**: post-pr-review takt workflow の analyze step 前後に新 step として追加 (analyze → fix → **mutate** → conclude) -- **survivor 報告 format**: CR-style table (severity/file/mutant variant/原因仮説) として state file に書き出し、Claude が「test を強化」または「実装を簡素化」を判断 -- **失敗ポリシー**: survivor mutant が 1 件でも残ったら post-pr-review で warning。PR は block しない (false positive 多発を考慮) -- **CI 環境**: pnpm push 時の post-PR 経路で実行。手元 push のみで CI 環境 fork なし - -#### 作業計画 - -- [ ] `cargo install cargo-mutants` を develop 環境で確認 -- [ ] cli-pr-monitor で実測: 全 crate / 変更 file のみ / +1-hop での mutants 数と所要時間 -- [ ] post-pr-monitor の Rust 実装に mutate step を組み込み (`runner::run_cmd_direct` を流用) -- [ ] survivor を `.takt/mutation-report.md` に書き出す -- [ ] takt facet (analyze-mutation.md 新規) で survivor の人間可読 summary を生成 -- [ ] dogfood: 既知の弱い test を意図的に書いて mutate が survivor を検出することを確認 -- [ ] 派生プロジェクトへ deploy -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- post-PR pipeline で cargo-mutants が変更 crate + 1-hop 依存に対して走る -- survivor mutant が 0 ⇔ test が impl を制約している (Bundle W の properties が機能している) ことの相関を 3 PR 以上で確認 -- pipeline 追加時間が PR 単位で 5 分以内 - -#### 詰まっている箇所 - -- 1-hop 依存 scope の自動算出ロジックが未調査。`cargo metadata --format-version=1` の dependencies graph を解析する Rust util が必要。 -- false positive (test では catch する意義のない mutant) の filter 戦略を着手時に検討する。 - ---- - -### pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) - -> **動機**: PR #96 Finding E (concurrency test の guard 即 drop) は scheduling 空間の race を逐次実行で誤魔化していた。`#[stress] N=100` で同 test を 100 回回すと、scheduler の偶然性で flaky window が露出する確率が劇的に向上する。pre-push に組み込めば AI が flaky concurrency test を書いた瞬間に push が止まる。 -> -> **本タスクの位置づけ**: Bundle X の **L1 layer (pre-push)**。順位 36 (cargo-mutants post-PR) と同 PR で land 推奨。Bundle W (PBT + 型) で記述された concurrency contract を、pre-push の最終防衛として deterministic に検証する補完層。 -> -> **参照**: PR #96 セッション内議論、ユーザーフィードバック「stress test は scheduling 空間の探索」。 -> -> **実行優先度**: 🔧 **Tier 2** — 工数 Small。cli-push-runner に +~1 秒 step として追加。Bundle W で書かれた loom test と相補的 (loom は in-memory 限定、stress は filesystem も含む実環境 race)。 - -#### 背景 - -- 実測: `concurrent_acquire_only_one_wins` 単発 ~10 ms、N=100 で ~1 秒 -- 1000 倍 (N=1000) は long-tail flake catch には有用だが pre-push に毎回は過剰 (順位 38 の L3 weekly に配置) - -#### 設計決定 (案) - -- **タグ方式**: `#[stress]` cfg attribute or test name suffix で stress test を識別 -- **実行**: cli-push-runner の Rust pipeline に `cargo test --release stress::` step を追加 -- **N=100 設定**: テストコード内で `for _ in 0..100 { ... }` (proptest macro と独立、tunable) -- **失敗時挙動**: 1 度でも失敗したら push 全体を fail (skip 不可) - -#### 作業計画 - -- [ ] stress test 命名規約決定 (`#[stress]` cfg vs `_stress_` prefix) -- [ ] cli-push-runner に stress runner step 追加 -- [ ] 既存 `concurrent_acquire_only_one_wins` を stress 化し N=100 ループで実行 -- [ ] dogfood: 意図的に flaky な test を書いて stress runner が検出することを確認 -- [ ] 派生プロジェクトへ deploy -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- pre-push pipeline で stress test が N=100 回実行される -- pipeline 追加時間が +2 秒以内 -- Finding E 相当の bug を stress runner が pre-push で catch することを再現実験で確認 - -#### 詰まっている箇所 - -- なし (Effort Small、cli-push-runner の Rust step に 1 つ追加するのみ)。 - ---- - -### L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky) - -> **動機**: Bundle W (PBT + 型) と Bundle X (mutants + stress) は per-PR / per-push の防御層だが、long-tail flake (N=100 では catch されないが N=1000 で出る) と workspace 全体の coverage gap (PR で触らない crate の test 弱さ) は別途 audit が必要。ADR-031 (週次レビュー、本採用 2026-06-01) に facet 拡張 / aggregate 前 pre-step として組込むことで、週次の人間不在時間に 30-60 分の audit を回す。 -> -> **本タスクの位置づけ**: Bundle W / X の **L3 layer (weekly)**。ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 Rust pre-step として組込。daily efficiency への直接効果は小さいが、long-term の test debt 蓄積を防ぐ。 -> -> **Status update (2026-06-07)**: ADR-031 は **2026-06-01 本採用昇格済 (PR #192)** で weekly-review pipeline は安定運用入り。**Bundle W (順位 34/35) は 2026-06-07 land 済** (`cli-pr-monitor::lock` の PastTime newtype + proptest properties 5 件)。本タスクの依存は **Bundle X (順位 36/37) の land のみ** に減縮。 -> -> **参照**: PR #96 セッション内議論、ADR-031 (週次レビューパイプライン、本採用 2026-06-01、PR #192)。 -> -> **実行優先度**: 💎 **Tier 3** — 工数 Small (ADR-031 への追加扱い)。Bundle X land 後に着手。 - -#### 背景 - -- ADR-031 (本採用 2026-06-01) は weekly-review 本体が land 済、本タスクは facet 拡張 / pre-step 追加として独立着手可能 -- L3 を独立 task にせず、ADR-031 facet 拡張として load すれば pipeline duplication なし - -#### 設計決定 (案) - -- **scope**: workspace 全体 (`cargo mutants -p '*'` 相当) -- **stress runner**: N=1000 で全 stress test を回す -- **配置**: ADR-031 で予定されている週次 cron / GitHub Actions schedule に追加 step -- **報告**: survivor mutant + stress flake を週次レビュー report に統合 (既存 weekly report format に追記) -- **action 連携**: 検出された問題を post-merge-feedback と同型の Tier 分類で todo 登録 - -#### 作業計画 - -- [ ] ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 pre-step として設計書作成 -- [ ] 週次 schedule に cargo-mutants workspace 全体 + stress N=1000 を追加 -- [ ] survivor / flake の自動 todo 登録ロジック (post-merge-feedback と同型 takt workflow) -- [ ] dogfood: 1 週間運用して week 1/2/3 の survivor 数推移を観察 -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- 週次 cron で workspace 全体 mutants + stress N=1000 が走る -- survivor / flake が検出されたら自動で todo 登録される -- ADR-031 weekly report に mutation / stress 結果が含まれる - -#### 詰まっている箇所 - -- ADR-031 (本採用 2026-06-01) は land 済、Bundle W (順位 34/35) は 2026-06-07 land 済。本 task は独立着手可能 (残依存 = Bundle X 順位 36/37 land 完了)。 - ---- - -### prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2) - -> **動機**: PR #98 セッションで、Bundle Y2 commit の `jj describe` 後の `pnpm push` がローカル bookmark 未作成のまま実行され、`jj git push` の default revset (`remote_bookmarks(remote=origin)..@`) で対象 0 件 → "Nothing changed" warning となり実質 push 失敗。push-runner は bookmark 自動採番ロジックを持たず、prepare-pr skill の Step 1 fallback (bookmark `/` 自動採番) でリカバリしたが、Step 1 の state 確認コマンド一覧に `jj bookmark list` の output 確認が明示されておらず、検出が「Step 1 fallback 表の `local_bookmarks` 空判定」に依存していた。 -> -> **本タスクの位置づけ**: prepare-pr skill Step 1 の state 確認フローに bookmark 存在チェックを明示追加し、push 失敗を事前検出。skill 自体は global (`~/.claude/skills/prepare-pr/`) なので本リポジトリの patch ではなく skill repository (`E:\work\claude-code-skills`) で更新する。 -> -> **Status update (2026-06-06)**: 本リポジトリ側で **PR #175 (Bundle 2) で `src/cli-push-runner/src/stages/bookmark_check.rs` stage が land 済**。push-runner 自体が bookmark 不在を mechanical 検出するため、skill 側の primary 検出責務は機械化済。本タスクは「skill 側 (派生プロジェクト未 deploy 環境向け二重防御 + skill SKILL.md 教育)」として scope 縮小可能。当初予定の Step 1 state 確認コマンド追加 + fallback 表強化は、push-runner 側仕様に追従して docs 同期する位置付けに変更。 -> -> **参照**: `.claude/feedback-reports/98.md` Tier 1 #2、PR #175 Bundle 2 (push-runner bookmark_check stage 実装) -> -> **実行優先度**: 🚀 **Tier 1** — Effort XS。SKILL.md Step 1 に確認コマンド 1 行 + fallback 表への明示マッピング追加のみ。Status update により push-runner との二重防御 / 派生プロジェクト向け knowledge transfer として位置付け。 - -#### 設計決定 (案) - -- **追加場所**: `~/.claude/skills/prepare-pr/SKILL.md` Step 1 「現状確認 + 前提工程 fallback」セクション -- **追加内容**: state コマンド一覧に `jj bookmark list 2>&1 | head -20` を追加し、output に `:` 行が含まれない場合を fallback 表「local bookmark なし」行に明示マッピング -- **既存 fallback 表との関係**: `local_bookmarks` template での判定は引き続き primary signal。本タスクは「読み手 (Claude / 人間) の state 確認 step で見落とさない」ための明示化 -- **evals 補強**: 「bookmark 未作成 → fallback で bookmark 作成 → push 成功」の Scenario を `evals/evals.json` に追加 (feedback-report Tier 2 #1 相当、同 PR で land 推奨) - -#### 作業計画 - -- [ ] `E:\work\claude-code-skills\prepare-pr\SKILL.md` の Step 1 を編集 (state コマンド + fallback 表強化) -- [ ] `~/.claude/skills/prepare-pr/SKILL.md` に sync (claude-code-skills repo の deploy 経路に従う) -- [ ] `~/.claude/skills/prepare-pr/evals/evals.json` に新 Scenario 追加 (bookmark 未作成正常 path) -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- prepare-pr skill Step 1 の state 確認コマンドに bookmark 存在チェックが明示 -- 新 Scenario が evals.json に追加され、bookmark 未作成 fallback の正常動作が検証される -- 本セッション類似の push 失敗が再現した場合、Step 1 で fallback 実行が即時発火 - -#### 詰まっている箇所 - -- skill repository (`E:\work\claude-code-skills`) の deploy / sync 経路の確認が必要 (本リポジトリの `deploy:hooks` とは別経路)。 - ---- - -### PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25) - -> **動機**: PR #97 / #99 セッションで観測された gh tool_result の token bloat (POST 応答 24KB / GET 過剰 metadata 44KB) を、当初 rule 追加 (`~/.claude/rules/common/git-workflow.md`) で抑制する計画だった。しかし PR #172 で 順位 144 (`jj-message-required` preset) の dogfood が成功し、「rule 化は session 毎に読み込みコストがかかり、別セッションでも結果が一定にならない」課題が顕在化。仕組み化 (PreToolUse hook) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。 -> -> 抑制対象 3 パターン (rule 設計時点で確定済): -> -> 1. **POST 操作 (作成・更新)** の応答破棄漏れ: `gh api .../replies` 等で `> /dev/null 2>&1` がない → 24KB の reply body が context 汚染 -> 2. **GET 操作 (取得)** で `--jq` filter 不使用: `gh api .../comments` 等で生 JSON 全取得 → 44KB の不要 metadata 流入 -> 3. **CR walkthrough internal state 混入**: `gh pr view --json comments` で CR walkthrough の base64 encoded state が含まれる (1 PR で 30KB+) → 確認時は `--jq 'del(.comments[].body)'` 等で除外必須 -> -> **本タスクの位置づけ**: 順位 144 (jj-message-required hook) の同型実装パターン。`feedback_pipeline_over_rules.md` 適用 = パイプライン側機械的修正で Claude 判断介入を排除、session 毎の rule load コスト不要、別セッションでも結果が一定。Bundle a の **Sub-PR 1 token 削減層** だが docs 化 → hook 化への切替に伴い Bundle a との結合は緩む。 -> -> **参照**: ADR-034 (CodeRabbit 監視・対話の自動化戦略)、PR #99 / #97 session log (token bloat 実観測)、PR #172 (順位 144 = `jj-message-required` preset 実装事例)、`src/hooks-pre-tool-validate/src/main.rs` の `preset_jj_message_required` を template に追加 -> -> **実行優先度**: 💎 **Tier 3** — Effort M (順位 144 と同型実装で工数把握済、~90 分見込み)。Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) でも `gh api` を使うため Sub-PR 1 で先行 land 推奨。 - -#### 設計決定 (案、順位 144 hook 実装を template に踏襲) - -- **配置**: `src/hooks-pre-tool-validate/src/main.rs` に新 preset `gh-token-efficiency` 追加 -- **`BlockedPattern.exception` を活用** (順位 144 で導入済、再利用) -- **block 対象 3 種類** (個別 BlockedPattern として実装): - - (1) **POST 応答破棄漏れ**: pattern = `gh\s+(api\s+-X\s+POST|api\s+(?!.*-X\s+GET)[^|]*-f\s+)`、exception = `>\s*/dev/null|>\s*NUL`、message = 「`> /dev/null 2>&1` で応答 body 破棄を推奨 (24KB context 汚染防止)」 - - (2) **`gh api` の `--jq` 不使用**: pattern = `gh\s+api\s+[^|]*`、exception = `--jq\b|\|\s*jq\b|>\s*/dev/null`、message = 「`--jq` で必要 field のみ抽出を推奨 (生 JSON 過剰流入防止)」 - - (3) **CR walkthrough state 混入**: pattern = `gh\s+pr\s+view\s+[^|]*--json\s+[^|]*comments`、exception = `del\(\.comments|--jq.*comments.*\|\s*map`、message = 「CR walkthrough base64 internal state を含むため `--jq 'del(.comments[].body)'` 等で除外を推奨」 -- **hooks-config.toml**: `blocked_patterns` に `"gh-token-efficiency"` を追加 (opt-in preset、派生プロジェクト breaking change リスク軽減) -- **opt-in 設計**: `default_preset_names()` の fallback には含めない (`gh-pr-create-guard` 等と同じ classification) - -#### 作業計画 (順位 144 と同 phase 構造) - -- [ ] **Phase 1**: 既存 preset 構造を理解し、`preset_gh_token_efficiency()` 関数を実装 (3 BlockedPattern を vec で返す) -- [ ] **Phase 2**: `build_blocked_patterns` の `resolve_preset_or_custom` dispatch に登録 + `.claude/hooks-config.toml` の `blocked_patterns` に `"gh-token-efficiency"` 追加 + コメント section に説明追加 -- [ ] **Phase 3**: test 拡充 — block ケース (応答破棄漏れ POST / `--jq` なし GET / walkthrough exclusion なし) × 3 + allow ケース (3 規則すべて遵守) × 3 + non-regression (既存 preset との干渉なし) -- [ ] **Phase 4**: `pnpm build:hooks-pre-tool-validate` で exe deploy + dogfood (本 todo を読んだ後の `gh api` 呼び出しで block 動作確認) -- [ ] **Phase 5**: `pnpm push` (AI review) + `pnpm create-pr` -- [ ] **post-merge**: 本リポジトリ 1-2 PR の dogfood で false positive 観測 → 派生プロジェクト deploy 判断 -- [ ] 本 todo4.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `jj-message-required` と同型の `gh-token-efficiency` preset が稼働 (3 BlockedPattern が block + exception 機能で正規パターン allow) -- `gh api .../replies -f body='...'` (応答破棄なし) → block + 修正手順 feedback -- `gh api .../comments` (`--jq` なし) → block + 修正手順 feedback -- `gh pr view 171 --json comments` (walkthrough 除外なし) → block + 修正手順 feedback -- 規則遵守版 (`> /dev/null 2>&1` 付き POST / `--jq` 抽出 / `del(.comments[].body)` 除外) は通過 -- 既存 preset との non-regression (jj-main-guard / git push block 等は継続動作) -- `cargo test -p hooks-pre-tool-validate` pass - -#### 詰まっている箇所 - -- 順位 144 実装パターンを踏襲することで設計判断は最小化される -- false positive リスク: `gh api ... | jq` のような piped jq は exception regex で吸収可能 (`\|\s*jq\b` を含める) -- 派生プロジェクト deploy timing: 本リポジトリ先行 dogfood (1-2 PR) → 観測後判断 (`feedback_dogfood_evals_two_phase.md` 適用) +# TODO (Part 4) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo3.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録していた。**本ファイルも 50KB に到達したため、PR #101 セッション以降の新規エントリは [docs/todo5.md](todo5.md) へ**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) + +> **動機**: Bundle W (PBT + 型) で書かれた properties が「実装を本当に制約しているか」を後段で機械的に測定する layer。`cargo mutants` は production code に微小変異を注入し、全 mutant が少なくとも 1 つの test で fail することを要求する。survivor mutant は「test がこのコードを制約していない」の直接的証拠で、PBT の弱さや coverage gap を mechanical に暴く。Bundle W で「仕様を articulate」、Bundle X で「articulate された仕様の強さを測定」の二層構造を完成させる。 +> +> **本タスクの位置づけ**: Bundle X の **L2 layer (post-PR)**。順位 37 (pre-push stress runner) と同 PR で land 推奨。Bundle W land 済 (2026-06-07、PR で `cli-pr-monitor::lock` の PastTime newtype + proptest properties 5 件 land) → mutants 投入の前提整備完了。 +> +> **参照**: PR #96 セッション内議論、ユーザーフィードバック「mutation scope を 変更ファイル + 依存モジュール 1 層 に拡大」。 +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Medium。post-PR pipeline (post-pr-monitor の前後) に組み込み、PR 単位で 1-5 分追加。user 待機 0 (async)。 + +#### 背景 + +- 試算: cli-pr-monitor (4724 LoC) で 150-500 mutants → 5-17 分 +- 変更 crate のみ + 1-hop 依存に scope 限定: 50-150 mutants → 1-5 分 +- 既存 cli-pr-monitor で実測しないと正確な数字は出ない (試算の桁ずれリスクあり) + +#### 設計決定 (案) + +- **scope 戦略**: 変更 file + `cargo metadata` で抽出した 1-hop 依存 module +- **配置先**: post-pr-review takt workflow の analyze step 前後に新 step として追加 (analyze → fix → **mutate** → conclude) +- **survivor 報告 format**: CR-style table (severity/file/mutant variant/原因仮説) として state file に書き出し、Claude が「test を強化」または「実装を簡素化」を判断 +- **失敗ポリシー**: survivor mutant が 1 件でも残ったら post-pr-review で warning。PR は block しない (false positive 多発を考慮) +- **CI 環境**: pnpm push 時の post-PR 経路で実行。手元 push のみで CI 環境 fork なし + +#### 作業計画 + +- [ ] `cargo install cargo-mutants` を develop 環境で確認 +- [ ] cli-pr-monitor で実測: 全 crate / 変更 file のみ / +1-hop での mutants 数と所要時間 +- [ ] post-pr-monitor の Rust 実装に mutate step を組み込み (`runner::run_cmd_direct` を流用) +- [ ] survivor を `.takt/mutation-report.md` に書き出す +- [ ] takt facet (analyze-mutation.md 新規) で survivor の人間可読 summary を生成 +- [ ] dogfood: 既知の弱い test を意図的に書いて mutate が survivor を検出することを確認 +- [ ] 派生プロジェクトへ deploy +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- post-PR pipeline で cargo-mutants が変更 crate + 1-hop 依存に対して走る +- survivor mutant が 0 ⇔ test が impl を制約している (Bundle W の properties が機能している) ことの相関を 3 PR 以上で確認 +- pipeline 追加時間が PR 単位で 5 分以内 + +#### 詰まっている箇所 + +- 1-hop 依存 scope の自動算出ロジックが未調査。`cargo metadata --format-version=1` の dependencies graph を解析する Rust util が必要。 +- false positive (test では catch する意義のない mutant) の filter 戦略を着手時に検討する。 + +--- + +### pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) + +> **動機**: PR #96 Finding E (concurrency test の guard 即 drop) は scheduling 空間の race を逐次実行で誤魔化していた。`#[stress] N=100` で同 test を 100 回回すと、scheduler の偶然性で flaky window が露出する確率が劇的に向上する。pre-push に組み込めば AI が flaky concurrency test を書いた瞬間に push が止まる。 +> +> **本タスクの位置づけ**: Bundle X の **L1 layer (pre-push)**。順位 36 (cargo-mutants post-PR) と同 PR で land 推奨。Bundle W (PBT + 型) で記述された concurrency contract を、pre-push の最終防衛として deterministic に検証する補完層。 +> +> **参照**: PR #96 セッション内議論、ユーザーフィードバック「stress test は scheduling 空間の探索」。 +> +> **実行優先度**: 🔧 **Tier 2** — 工数 Small。cli-push-runner に +~1 秒 step として追加。Bundle W で書かれた loom test と相補的 (loom は in-memory 限定、stress は filesystem も含む実環境 race)。 + +#### 背景 + +- 実測: `concurrent_acquire_only_one_wins` 単発 ~10 ms、N=100 で ~1 秒 +- 1000 倍 (N=1000) は long-tail flake catch には有用だが pre-push に毎回は過剰 (順位 38 の L3 weekly に配置) + +#### 設計決定 (案) + +- **タグ方式**: `#[stress]` cfg attribute or test name suffix で stress test を識別 +- **実行**: cli-push-runner の Rust pipeline に `cargo test --release stress::` step を追加 +- **N=100 設定**: テストコード内で `for _ in 0..100 { ... }` (proptest macro と独立、tunable) +- **失敗時挙動**: 1 度でも失敗したら push 全体を fail (skip 不可) + +#### 作業計画 + +- [ ] stress test 命名規約決定 (`#[stress]` cfg vs `_stress_` prefix) +- [ ] cli-push-runner に stress runner step 追加 +- [ ] 既存 `concurrent_acquire_only_one_wins` を stress 化し N=100 ループで実行 +- [ ] dogfood: 意図的に flaky な test を書いて stress runner が検出することを確認 +- [ ] 派生プロジェクトへ deploy +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- pre-push pipeline で stress test が N=100 回実行される +- pipeline 追加時間が +2 秒以内 +- Finding E 相当の bug を stress runner が pre-push で catch することを再現実験で確認 + +#### 詰まっている箇所 + +- なし (Effort Small、cli-push-runner の Rust step に 1 つ追加するのみ)。 + +--- + +### L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky) + +> **動機**: Bundle W (PBT + 型) と Bundle X (mutants + stress) は per-PR / per-push の防御層だが、long-tail flake (N=100 では catch されないが N=1000 で出る) と workspace 全体の coverage gap (PR で触らない crate の test 弱さ) は別途 audit が必要。ADR-031 (週次レビュー、本採用 2026-06-01) に facet 拡張 / aggregate 前 pre-step として組込むことで、週次の人間不在時間に 30-60 分の audit を回す。 +> +> **本タスクの位置づけ**: Bundle W / X の **L3 layer (weekly)**。ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 Rust pre-step として組込。daily efficiency への直接効果は小さいが、long-term の test debt 蓄積を防ぐ。 +> +> **Status update (2026-06-07)**: ADR-031 は **2026-06-01 本採用昇格済 (PR #192)** で weekly-review pipeline は安定運用入り。**Bundle W (順位 34/35) は 2026-06-07 land 済** (`cli-pr-monitor::lock` の PastTime newtype + proptest properties 5 件)。本タスクの依存は **Bundle X (順位 36/37) の land のみ** に減縮。 +> +> **参照**: PR #96 セッション内議論、ADR-031 (週次レビューパイプライン、本採用 2026-06-01、PR #192)。 +> +> **実行優先度**: 💎 **Tier 3** — 工数 Small (ADR-031 への追加扱い)。Bundle X land 後に着手。 + +#### 背景 + +- ADR-031 (本採用 2026-06-01) は weekly-review 本体が land 済、本タスクは facet 拡張 / pre-step 追加として独立着手可能 +- L3 を独立 task にせず、ADR-031 facet 拡張として load すれば pipeline duplication なし + +#### 設計決定 (案) + +- **scope**: workspace 全体 (`cargo mutants -p '*'` 相当) +- **stress runner**: N=1000 で全 stress test を回す +- **配置**: ADR-031 で予定されている週次 cron / GitHub Actions schedule に追加 step +- **報告**: survivor mutant + stress flake を週次レビュー report に統合 (既存 weekly report format に追記) +- **action 連携**: 検出された問題を post-merge-feedback と同型の Tier 分類で todo 登録 + +#### 作業計画 + +- [ ] ADR-031 (本採用 2026-06-01) の facet 拡張 / aggregate 前 pre-step として設計書作成 +- [ ] 週次 schedule に cargo-mutants workspace 全体 + stress N=1000 を追加 +- [ ] survivor / flake の自動 todo 登録ロジック (post-merge-feedback と同型 takt workflow) +- [ ] dogfood: 1 週間運用して week 1/2/3 の survivor 数推移を観察 +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- 週次 cron で workspace 全体 mutants + stress N=1000 が走る +- survivor / flake が検出されたら自動で todo 登録される +- ADR-031 weekly report に mutation / stress 結果が含まれる + +#### 詰まっている箇所 + +- ADR-031 (本採用 2026-06-01) は land 済、Bundle W (順位 34/35) は 2026-06-07 land 済。本 task は独立着手可能 (残依存 = Bundle X 順位 36/37 land 完了)。 + +--- + +### prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2) + +> **動機**: PR #98 セッションで、Bundle Y2 commit の `jj describe` 後の `pnpm push` がローカル bookmark 未作成のまま実行され、`jj git push` の default revset (`remote_bookmarks(remote=origin)..@`) で対象 0 件 → "Nothing changed" warning となり実質 push 失敗。push-runner は bookmark 自動採番ロジックを持たず、prepare-pr skill の Step 1 fallback (bookmark `/` 自動採番) でリカバリしたが、Step 1 の state 確認コマンド一覧に `jj bookmark list` の output 確認が明示されておらず、検出が「Step 1 fallback 表の `local_bookmarks` 空判定」に依存していた。 +> +> **本タスクの位置づけ**: prepare-pr skill Step 1 の state 確認フローに bookmark 存在チェックを明示追加し、push 失敗を事前検出。skill 自体は global (`~/.claude/skills/prepare-pr/`) なので本リポジトリの patch ではなく skill repository (`E:\work\claude-code-skills`) で更新する。 +> +> **Status update (2026-06-06)**: 本リポジトリ側で **PR #175 (Bundle 2) で `src/cli-push-runner/src/stages/bookmark_check.rs` stage が land 済**。push-runner 自体が bookmark 不在を mechanical 検出するため、skill 側の primary 検出責務は機械化済。本タスクは「skill 側 (派生プロジェクト未 deploy 環境向け二重防御 + skill SKILL.md 教育)」として scope 縮小可能。当初予定の Step 1 state 確認コマンド追加 + fallback 表強化は、push-runner 側仕様に追従して docs 同期する位置付けに変更。 +> +> **参照**: `.claude/feedback-reports/98.md` Tier 1 #2、PR #175 Bundle 2 (push-runner bookmark_check stage 実装) +> +> **実行優先度**: 🚀 **Tier 1** — Effort XS。SKILL.md Step 1 に確認コマンド 1 行 + fallback 表への明示マッピング追加のみ。Status update により push-runner との二重防御 / 派生プロジェクト向け knowledge transfer として位置付け。 + +#### 設計決定 (案) + +- **追加場所**: `~/.claude/skills/prepare-pr/SKILL.md` Step 1 「現状確認 + 前提工程 fallback」セクション +- **追加内容**: state コマンド一覧に `jj bookmark list 2>&1 | head -20` を追加し、output に `:` 行が含まれない場合を fallback 表「local bookmark なし」行に明示マッピング +- **既存 fallback 表との関係**: `local_bookmarks` template での判定は引き続き primary signal。本タスクは「読み手 (Claude / 人間) の state 確認 step で見落とさない」ための明示化 +- **evals 補強**: 「bookmark 未作成 → fallback で bookmark 作成 → push 成功」の Scenario を `evals/evals.json` に追加 (feedback-report Tier 2 #1 相当、同 PR で land 推奨) + +#### 作業計画 + +- [ ] `E:\work\claude-code-skills\prepare-pr\SKILL.md` の Step 1 を編集 (state コマンド + fallback 表強化) +- [ ] `~/.claude/skills/prepare-pr/SKILL.md` に sync (claude-code-skills repo の deploy 経路に従う) +- [ ] `~/.claude/skills/prepare-pr/evals/evals.json` に新 Scenario 追加 (bookmark 未作成正常 path) +- [ ] 本 todo4.md エントリを削除 + +#### 完了基準 + +- prepare-pr skill Step 1 の state 確認コマンドに bookmark 存在チェックが明示 +- 新 Scenario が evals.json に追加され、bookmark 未作成 fallback の正常動作が検証される +- 本セッション類似の push 失敗が再現した場合、Step 1 で fallback 実行が即時発火 + +#### 詰まっている箇所 + +- skill repository (`E:\work\claude-code-skills`) の deploy / sync 経路の確認が必要 (本リポジトリの `deploy:hooks` とは別経路)。 + +--- + +### PreToolUse hook で `gh` CLI の token-bloat パターンを検出する `gh-token-efficiency` preset 追加 (計画書 #D-1、PR #172 仕組み化方針切替 2026-05-25) + +> **動機**: PR #97 / #99 セッションで観測された gh tool_result の token bloat (POST 応答 24KB / GET 過剰 metadata 44KB) を、当初 rule 追加 (`~/.claude/rules/common/git-workflow.md`) で抑制する計画だった。しかし PR #172 で 順位 144 (`jj-message-required` preset) の dogfood が成功し、「rule 化は session 毎に読み込みコストがかかり、別セッションでも結果が一定にならない」課題が顕在化。仕組み化 (PreToolUse hook) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。 +> +> 抑制対象 3 パターン (rule 設計時点で確定済): +> +> 1. **POST 操作 (作成・更新)** の応答破棄漏れ: `gh api .../replies` 等で `> /dev/null 2>&1` がない → 24KB の reply body が context 汚染 +> 2. **GET 操作 (取得)** で `--jq` filter 不使用: `gh api .../comments` 等で生 JSON 全取得 → 44KB の不要 metadata 流入 +> 3. **CR walkthrough internal state 混入**: `gh pr view --json comments` で CR walkthrough の base64 encoded state が含まれる (1 PR で 30KB+) → 確認時は `--jq 'del(.comments[].body)'` 等で除外必須 +> +> **本タスクの位置づけ**: 順位 144 (jj-message-required hook) の同型実装パターン。`feedback_pipeline_over_rules.md` 適用 = パイプライン側機械的修正で Claude 判断介入を排除、session 毎の rule load コスト不要、別セッションでも結果が一定。Bundle a の **Sub-PR 1 token 削減層** だが docs 化 → hook 化への切替に伴い Bundle a との結合は緩む。 +> +> **参照**: ADR-034 (CodeRabbit 監視・対話の自動化戦略)、PR #99 / #97 session log (token bloat 実観測)、PR #172 (順位 144 = `jj-message-required` preset 実装事例)、`src/hooks-pre-tool-validate/src/main.rs` の `preset_jj_message_required` を template に追加 +> +> **実行優先度**: 💎 **Tier 3** — Effort M (順位 144 と同型実装で工数把握済、~90 分見込み)。Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) でも `gh api` を使うため Sub-PR 1 で先行 land 推奨。 + +#### 設計決定 (案、順位 144 hook 実装を template に踏襲) + +- **配置**: `src/hooks-pre-tool-validate/src/main.rs` に新 preset `gh-token-efficiency` 追加 +- **`BlockedPattern.exception` を活用** (順位 144 で導入済、再利用) +- **block 対象 3 種類** (個別 BlockedPattern として実装): + - (1) **POST 応答破棄漏れ**: pattern = `gh\s+(api\s+-X\s+POST|api\s+(?!.*-X\s+GET)[^|]*-f\s+)`、exception = `>\s*/dev/null|>\s*NUL`、message = 「`> /dev/null 2>&1` で応答 body 破棄を推奨 (24KB context 汚染防止)」 + - (2) **`gh api` の `--jq` 不使用**: pattern = `gh\s+api\s+[^|]*`、exception = `--jq\b|\|\s*jq\b|>\s*/dev/null`、message = 「`--jq` で必要 field のみ抽出を推奨 (生 JSON 過剰流入防止)」 + - (3) **CR walkthrough state 混入**: pattern = `gh\s+pr\s+view\s+[^|]*--json\s+[^|]*comments`、exception = `del\(\.comments|--jq.*comments.*\|\s*map`、message = 「CR walkthrough base64 internal state を含むため `--jq 'del(.comments[].body)'` 等で除外を推奨」 +- **hooks-config.toml**: `blocked_patterns` に `"gh-token-efficiency"` を追加 (opt-in preset、派生プロジェクト breaking change リスク軽減) +- **opt-in 設計**: `default_preset_names()` の fallback には含めない (`gh-pr-create-guard` 等と同じ classification) + +#### 作業計画 (順位 144 と同 phase 構造) + +- [ ] **Phase 1**: 既存 preset 構造を理解し、`preset_gh_token_efficiency()` 関数を実装 (3 BlockedPattern を vec で返す) +- [ ] **Phase 2**: `build_blocked_patterns` の `resolve_preset_or_custom` dispatch に登録 + `.claude/hooks-config.toml` の `blocked_patterns` に `"gh-token-efficiency"` 追加 + コメント section に説明追加 +- [ ] **Phase 3**: test 拡充 — block ケース (応答破棄漏れ POST / `--jq` なし GET / walkthrough exclusion なし) × 3 + allow ケース (3 規則すべて遵守) × 3 + non-regression (既存 preset との干渉なし) +- [ ] **Phase 4**: `pnpm build:hooks-pre-tool-validate` で exe deploy + dogfood (本 todo を読んだ後の `gh api` 呼び出しで block 動作確認) +- [ ] **Phase 5**: `pnpm push` (AI review) + `pnpm create-pr` +- [ ] **post-merge**: 本リポジトリ 1-2 PR の dogfood で false positive 観測 → 派生プロジェクト deploy 判断 +- [ ] 本 todo4.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `jj-message-required` と同型の `gh-token-efficiency` preset が稼働 (3 BlockedPattern が block + exception 機能で正規パターン allow) +- `gh api .../replies -f body='...'` (応答破棄なし) → block + 修正手順 feedback +- `gh api .../comments` (`--jq` なし) → block + 修正手順 feedback +- `gh pr view 171 --json comments` (walkthrough 除外なし) → block + 修正手順 feedback +- 規則遵守版 (`> /dev/null 2>&1` 付き POST / `--jq` 抽出 / `del(.comments[].body)` 除外) は通過 +- 既存 preset との non-regression (jj-main-guard / git push block 等は継続動作) +- `cargo test -p hooks-pre-tool-validate` pass + +#### 詰まっている箇所 + +- 順位 144 実装パターンを踏襲することで設計判断は最小化される +- false positive リスク: `gh api ... | jq` のような piped jq は exception regex で吸収可能 (`\|\s*jq\b` を含める) +- 派生プロジェクト deploy timing: 本リポジトリ先行 dogfood (1-2 PR) → 観測後判断 (`feedback_dogfood_evals_two_phase.md` 適用) diff --git a/docs/todo5.md b/docs/todo5.md index b9d667dc..5a7f4b59 100644 --- a/docs/todo5.md +++ b/docs/todo5.md @@ -1,130 +1,130 @@ -# TODO (Part 5) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo4.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #101 セッション以降の新規エントリは本ファイルに記録していた。**本ファイルも 67KB に到達したため、2026-05-09 に PR #101〜#109 由来の古い半分を [docs/todo7.md](todo7.md) へ分離した**。本ファイル残存は PR #110 以降のエントリのみ。新規エントリは [docs/todo6.md](todo6.md) へ。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up - - - -> **動機**: PR #115 で「config が user-editable system boundary のとき、sanitize() で値域検証 + 下流 arithmetic で安全範囲保証」というパターンが実証された (CR Major #1 + #2 が両方とも同型の「config 値→arithmetic 入力」cross-layer integrity 問題)。同型の bug class は今後も Rust + config 駆動の component で発生しうるため、組織的 learning として codify。 -> -> **本タスクの位置づけ**: 順位 76 / 77 (test 層) の補完層 = ドキュメント / ADR 層。3 つを別 PR で land すると依存関係が読みやすい (test 層先 → 後で ADR が test を参照)。post-merge-feedback Tier 3 #1 採用。 -> -> **参照**: PR #115 CR Major #1+#2 解消経緯、`.claude/feedback-reports/115.md` Tier 3 #1、CLAUDE.md `security.md` (input validation)、ADR-022 (責務分離原則) の延長 -> -> **実行優先度**: 💎 **Tier 3** — Effort S。順位 76 / 77 が land した後の codification PR。 - -#### 設計決定 (案) - -- **ADR-NNN (新規)**: `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を作成 (番号は land 時 PR で確定) - - **タイトル**: Rust timestamp arithmetic の overflow safety pattern - - **Context**: PR #115 で sanitize() が `i64::MAX as u64` を valid として通したが downstream の `now_unix + wait as i64` で overflow した CR Major #2 を引用 - - **Decision**: 以下 3 層で overflow を構造的に防ぐ - 1. **Sanitize layer**: config に `MAX_SAFE_WAIT_SECS` 等の上限を設定し、`sanitize()` で値域違反を default fallback - 2. **Arithmetic layer**: `now_unix + wait as i64` のような cast point に `// SAFETY: が 以下を保証` コメント (人間レビュー時の手がかり) - 3. **Test layer**: `now + sanitize 後の値 < i64::MAX` invariant を `checked_add` で machine-enforce (順位 76/77 で実装) - - **Consequences**: cross-module overflow を test layer で構造的に検知。`MAX_SAFE_WAIT_SECS` の根拠が future-proof (2100 年でも safe) -- **CLAUDE.md `security.md` (`~/.claude/rules/common/security.md`) 拡充**: 「config は user-editable system boundary、必ず sanitize() で値域検証」+ 「Rust の `as` cast は overflow check しない、`checked_add` を併用」を追加。global rule なので全 Rust project に適用される -- **本 PR の効果**: ADR + CLAUDE.md で codified 後、将来同型 bug が発生したら「本 ADR (採番後の実番号) 違反」として一発で指摘可能 - -#### 作業計画 - -- [ ] `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を新規作成 (Context / Decision / Consequences、番号は land 時 PR で確定) -- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 -- [ ] `~/.claude/rules/common/security.md` に「config sanitize + Rust arithmetic safety」セクション追加 -- [ ] (任意) `~/.claude/rules/rust/coding-style.md` に `// SAFETY:` コメント pattern を補足 -- [ ] 順位 76/77 が land 済の前提で「Test layer で検証する」を ADR で言及 (前後関係を明示) -- [ ] 派生プロジェクト deploy には影響なし (docs / global rule のみ) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- 該当 ADR (land 時 PR で番号確定) が land し、CLAUDE.md からリンクされる -- `~/.claude/rules/common/security.md` に Rust arithmetic safety pattern が追加される -- 将来「config 値が arithmetic で overflow」という形の bug が出たら、本 ADR (採番後の実番号) を引用して一発で指摘できる - -#### 詰まっている箇所 - -- 順位 76/77 land 前後の順番: ADR で test layer に言及するため、test 実装が先のほうが自然。ただし ADR を先 land して「test を本 ADR (採番後の実番号) に従って実装する」流れも可能。実装時に ROI で判断 (test PR と ADR PR を分けるか、まとめるか) -- `~/.claude/` 配下の global rule 編集は本 repo 外への影響あり、慎重に (memory `feedback_no_unenforced_rules.md` 「強制力のないルール追加は却下」原則を踏まえる必要あり = 機械検知できないルールは却下されうる)。本 task は ADR + 既存 rule 拡充で「機械検知の根拠」を提供する形なので OK だが、CLAUDE.md security.md の追記内容が「ルールだけ増やす」と評価されないよう、順位 76/77 の test との連携を明示する - ---- - -### docs-governance.md § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用) - -> **動機**: PR #117 (`docs/coderabbit-monitoring-efficiency.md` retirement) で順位 15 (cli-pr-monitor 通知 Recovery 経路) を「Bb-3 SessionStart catch-up nudge で吸収済」として priority table から削除した際、現 `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2「残タスクを priority table に登録」は **priority table から除外するケース (= 完了/意図的 deprioritize/defer) を未定義**。reviewer (post-merge-feedback agent) は私の commit message に「Bb-3 で吸収済」と書かれていることは認識したが、rule として 3 値分類が明文化されていない点を指摘。 -> -> **本タスクの位置づけ**: PR #117 post-merge-feedback Tier 3 #1 採用。retirement workflow 自体を強化する meta-task で、将来の同型 ambiguity を構造的に防止。 -> -> **参照**: PR #117 retirement の経緯 (`docs/coderabbit-monitoring-efficiency.md` 削除)、`.claude/feedback-reports/117.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。1 セクションに 5-10 行追記。 - -#### 設計決定 (案) - -- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Retirement Workflow (planning markdowns)` セクション内、Step 2「Migrate residual tasks」を拡充 -- **追記内容案** (Step 2 改訂): - - 現状: 「Migrate residual tasks — register any remaining work to `docs/todo*.md` priority table」 - - 改訂: priority table から除外する場合は commit/PR description で 3 値のいずれかを明示する要件を追加 - - **完了 (subsumed)**: 別タスクで実質達成済 (例: 順位 15 → Bb-3 で吸収)。subsuming task / PR を引用 - - **意図的 deprioritize**: 優先度を下げて当面着手しない。理由を引用 - - **defer**: 後続 bundle で扱う。次の bundle context を引用 - - 「分類なしの単純削除は禁止」と明記し、`grep` 等での検証可能性を担保 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件を追記 (5-10 行) -- [ ] PR #117 を retroactive example として引用 (順位 15 = subsumed by Bb-3 のケース) -- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) -- [ ] 本 todo5.md エントリを削除 - -#### 完了基準 - -- `docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件が明記される -- 将来の retirement PR で「priority table 削除時の理由を 3 値のどれか明示」が rule として参照可能になる -- 順位 15 のような subsumed なタスクが「単純削除」として誤解されないよう、convention で守られる - -#### 詰まっている箇所 - -- ルール追加自体は機械検知不可だが、本 task は **既存の retirement workflow の Step 2 を拡充するもの** (新規 rule の追加ではなく既存 rule の精緻化) なので、memory `feedback_no_unenforced_rules.md` の「強制力のないルール追加は却下」原則とは性質が異なる。retirement workflow を実行する commit/PR で `grep -E "完了|deprioritize|defer"` 等の機械検知を後付け可能 (ただし本 task の scope 外) -- 3 値分類が実用的な粒度か、より細かい分類が必要か (例: `subsumed` を `merged into bundle` / `replaced by ADR` 等に分割) は実装時に dogfood で判断 - ---- - -### cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer) - -> **動機**: PR #120 dogfood で CR walkthrough overlay が `Failed to post review comments` (rate-limit ではない transient failure) を表示するも `parse_rate_limit_status` が detected せず、auto-retry が発火しなかった。1 観測だが auto-retry の silent failure として機能不全。 -> -> **参照**: PR #120 walkthrough comment (16:41Z 投稿)、`.claude/feedback-reports/120.md` Tier 1 #2、[ADR-018 §追記 2026-05-08](adr/adr-018-pr-monitor-takt-migration.md) -> -> **実行優先度**: 🚀 **Tier 1 (defer)** — §A-2 P-5 PR (2026-05-08) で Defer 判定。1 観測のみで systemic 性未確認のため、ユーザー方針 `feedback_no_unenforced_rules` (機械検知不可なら何もしない方がマシ) と整合させて 3 PR 観測閾値到達まで待つ。 -> -> **Re-trigger 条件**: `Failed to post review comments` (またはそれに類する rate-limit 以外の CR transient failure) が他の PR で 1 件以上追加観測 (合計 2 件以上) されたら本タスクを再活性化、実装に着手。 - -#### 作業計画 (defer 中、参考) - -- [ ] `Review failed` / `Failed to post review comments` 等の transient failure pattern を detection に追加 -- [ ] rate-limit 系と統合する場合は state field を `transient_failure: Option` に一般化検討 -- [ ] ADR-018 §追記 2026-05-08 の「対象 transient failure 分類」表を「⏳ 未実装」→「✅ 実装済」に更新 - -#### 完了基準 - -- `Failed to post review comments` を含む walkthrough overlay 検出時に auto-retry が発火する -- regression test (failure pattern 注入 → auto-retry 発火) が green -- ADR-018 §追記 2026-05-08 と整合 - ---- - +# TODO (Part 5) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo4.md がファイルサイズ約 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #101 セッション以降の新規エントリは本ファイルに記録していた。**本ファイルも 67KB に到達したため、2026-05-09 に PR #101〜#109 由来の古い半分を [docs/todo7.md](todo7.md) へ分離した**。本ファイル残存は PR #110 以降のエントリのみ。新規エントリは [docs/todo6.md](todo6.md) へ。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### ADR-NNN (採番未確定、land 時に確定): Rust timestamp arithmetic safety + CLAUDE.md security 拡充 (PR #115 T3-1 採用) ★ Bb-3 follow-up + + + +> **動機**: PR #115 で「config が user-editable system boundary のとき、sanitize() で値域検証 + 下流 arithmetic で安全範囲保証」というパターンが実証された (CR Major #1 + #2 が両方とも同型の「config 値→arithmetic 入力」cross-layer integrity 問題)。同型の bug class は今後も Rust + config 駆動の component で発生しうるため、組織的 learning として codify。 +> +> **本タスクの位置づけ**: 順位 76 / 77 (test 層) の補完層 = ドキュメント / ADR 層。3 つを別 PR で land すると依存関係が読みやすい (test 層先 → 後で ADR が test を参照)。post-merge-feedback Tier 3 #1 採用。 +> +> **参照**: PR #115 CR Major #1+#2 解消経緯、`.claude/feedback-reports/115.md` Tier 3 #1、CLAUDE.md `security.md` (input validation)、ADR-022 (責務分離原則) の延長 +> +> **実行優先度**: 💎 **Tier 3** — Effort S。順位 76 / 77 が land した後の codification PR。 + +#### 設計決定 (案) + +- **ADR-NNN (新規)**: `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を作成 (番号は land 時 PR で確定) + - **タイトル**: Rust timestamp arithmetic の overflow safety pattern + - **Context**: PR #115 で sanitize() が `i64::MAX as u64` を valid として通したが downstream の `now_unix + wait as i64` で overflow した CR Major #2 を引用 + - **Decision**: 以下 3 層で overflow を構造的に防ぐ + 1. **Sanitize layer**: config に `MAX_SAFE_WAIT_SECS` 等の上限を設定し、`sanitize()` で値域違反を default fallback + 2. **Arithmetic layer**: `now_unix + wait as i64` のような cast point に `// SAFETY: が 以下を保証` コメント (人間レビュー時の手がかり) + 3. **Test layer**: `now + sanitize 後の値 < i64::MAX` invariant を `checked_add` で machine-enforce (順位 76/77 で実装) + - **Consequences**: cross-module overflow を test layer で構造的に検知。`MAX_SAFE_WAIT_SECS` の根拠が future-proof (2100 年でも safe) +- **CLAUDE.md `security.md` (`~/.claude/rules/common/security.md`) 拡充**: 「config は user-editable system boundary、必ず sanitize() で値域検証」+ 「Rust の `as` cast は overflow check しない、`checked_add` を併用」を追加。global rule なので全 Rust project に適用される +- **本 PR の効果**: ADR + CLAUDE.md で codified 後、将来同型 bug が発生したら「本 ADR (採番後の実番号) 違反」として一発で指摘可能 + +#### 作業計画 + +- [ ] `docs/adr/adr-NNN-timestamp-arithmetic-safety.md` を新規作成 (Context / Decision / Consequences、番号は land 時 PR で確定) +- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 +- [ ] `~/.claude/rules/common/security.md` に「config sanitize + Rust arithmetic safety」セクション追加 +- [ ] (任意) `~/.claude/rules/rust/coding-style.md` に `// SAFETY:` コメント pattern を補足 +- [ ] 順位 76/77 が land 済の前提で「Test layer で検証する」を ADR で言及 (前後関係を明示) +- [ ] 派生プロジェクト deploy には影響なし (docs / global rule のみ) +- [ ] 本 todo5.md エントリを削除 + +#### 完了基準 + +- 該当 ADR (land 時 PR で番号確定) が land し、CLAUDE.md からリンクされる +- `~/.claude/rules/common/security.md` に Rust arithmetic safety pattern が追加される +- 将来「config 値が arithmetic で overflow」という形の bug が出たら、本 ADR (採番後の実番号) を引用して一発で指摘できる + +#### 詰まっている箇所 + +- 順位 76/77 land 前後の順番: ADR で test layer に言及するため、test 実装が先のほうが自然。ただし ADR を先 land して「test を本 ADR (採番後の実番号) に従って実装する」流れも可能。実装時に ROI で判断 (test PR と ADR PR を分けるか、まとめるか) +- `~/.claude/` 配下の global rule 編集は本 repo 外への影響あり、慎重に (memory `feedback_no_unenforced_rules.md` 「強制力のないルール追加は却下」原則を踏まえる必要あり = 機械検知できないルールは却下されうる)。本 task は ADR + 既存 rule 拡充で「機械検知の根拠」を提供する形なので OK だが、CLAUDE.md security.md の追記内容が「ルールだけ増やす」と評価されないよう、順位 76/77 の test との連携を明示する + +--- + +### docs-governance.md § Retirement Workflow に「残タスクの lifecycle 整合」要件明記 (PR #117 T3-1 採用) + +> **動機**: PR #117 (`docs/coderabbit-monitoring-efficiency.md` retirement) で順位 15 (cli-pr-monitor 通知 Recovery 経路) を「Bb-3 SessionStart catch-up nudge で吸収済」として priority table から削除した際、現 `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2「残タスクを priority table に登録」は **priority table から除外するケース (= 完了/意図的 deprioritize/defer) を未定義**。reviewer (post-merge-feedback agent) は私の commit message に「Bb-3 で吸収済」と書かれていることは認識したが、rule として 3 値分類が明文化されていない点を指摘。 +> +> **本タスクの位置づけ**: PR #117 post-merge-feedback Tier 3 #1 採用。retirement workflow 自体を強化する meta-task で、将来の同型 ambiguity を構造的に防止。 +> +> **参照**: PR #117 retirement の経緯 (`docs/coderabbit-monitoring-efficiency.md` 削除)、`.claude/feedback-reports/117.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。1 セクションに 5-10 行追記。 + +#### 設計決定 (案) + +- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Retirement Workflow (planning markdowns)` セクション内、Step 2「Migrate residual tasks」を拡充 +- **追記内容案** (Step 2 改訂): + - 現状: 「Migrate residual tasks — register any remaining work to `docs/todo*.md` priority table」 + - 改訂: priority table から除外する場合は commit/PR description で 3 値のいずれかを明示する要件を追加 + - **完了 (subsumed)**: 別タスクで実質達成済 (例: 順位 15 → Bb-3 で吸収)。subsuming task / PR を引用 + - **意図的 deprioritize**: 優先度を下げて当面着手しない。理由を引用 + - **defer**: 後続 bundle で扱う。次の bundle context を引用 + - 「分類なしの単純削除は禁止」と明記し、`grep` 等での検証可能性を担保 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件を追記 (5-10 行) +- [ ] PR #117 を retroactive example として引用 (順位 15 = subsumed by Bb-3 のケース) +- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) +- [ ] 本 todo5.md エントリを削除 + +#### 完了基準 + +- `docs-governance.md` § Retirement Workflow Step 2 に 3 値分類要件が明記される +- 将来の retirement PR で「priority table 削除時の理由を 3 値のどれか明示」が rule として参照可能になる +- 順位 15 のような subsumed なタスクが「単純削除」として誤解されないよう、convention で守られる + +#### 詰まっている箇所 + +- ルール追加自体は機械検知不可だが、本 task は **既存の retirement workflow の Step 2 を拡充するもの** (新規 rule の追加ではなく既存 rule の精緻化) なので、memory `feedback_no_unenforced_rules.md` の「強制力のないルール追加は却下」原則とは性質が異なる。retirement workflow を実行する commit/PR で `grep -E "完了|deprioritize|defer"` 等の機械検知を後付け可能 (ただし本 task の scope 外) +- 3 値分類が実用的な粒度か、より細かい分類が必要か (例: `subsumed` を `merged into bundle` / `replaced by ADR` 等に分割) は実装時に dogfood で判断 + +--- + +### cli-pr-monitor: CR 投稿エラー (`Failed to post review comments`) auto-retry 拡張 (PR #120 T1-2 採用) ★ Bundle f (defer) + +> **動機**: PR #120 dogfood で CR walkthrough overlay が `Failed to post review comments` (rate-limit ではない transient failure) を表示するも `parse_rate_limit_status` が detected せず、auto-retry が発火しなかった。1 観測だが auto-retry の silent failure として機能不全。 +> +> **参照**: PR #120 walkthrough comment (16:41Z 投稿)、`.claude/feedback-reports/120.md` Tier 1 #2、[ADR-018 §追記 2026-05-08](adr/adr-018-pr-monitor-takt-migration.md) +> +> **実行優先度**: 🚀 **Tier 1 (defer)** — §A-2 P-5 PR (2026-05-08) で Defer 判定。1 観測のみで systemic 性未確認のため、ユーザー方針 `feedback_no_unenforced_rules` (機械検知不可なら何もしない方がマシ) と整合させて 3 PR 観測閾値到達まで待つ。 +> +> **Re-trigger 条件**: `Failed to post review comments` (またはそれに類する rate-limit 以外の CR transient failure) が他の PR で 1 件以上追加観測 (合計 2 件以上) されたら本タスクを再活性化、実装に着手。 + +#### 作業計画 (defer 中、参考) + +- [ ] `Review failed` / `Failed to post review comments` 等の transient failure pattern を detection に追加 +- [ ] rate-limit 系と統合する場合は state field を `transient_failure: Option` に一般化検討 +- [ ] ADR-018 §追記 2026-05-08 の「対象 transient failure 分類」表を「⏳ 未実装」→「✅ 実装済」に更新 + +#### 完了基準 + +- `Failed to post review comments` を含む walkthrough overlay 検出時に auto-retry が発火する +- regression test (failure pattern 注入 → auto-retry 発火) が green +- ADR-018 §追記 2026-05-08 と整合 + +--- + diff --git a/docs/todo6.md b/docs/todo6.md index a8a4c911..d9086dfc 100644 --- a/docs/todo6.md +++ b/docs/todo6.md @@ -1,221 +1,221 @@ -# TODO (Part 6) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo5.md / 本ファイルが 50KB に到達 (PR #143 T3-#1) のため **新規エントリは [docs/todo8.md](todo8.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### scale-aware eval fixtures (200+ 行) — 大規模 diff dogfood 信頼性継続改善 (PR #132 T2-#5 採用) ★ Bundle i - -> **動機**: PR #132 smoke dogfood で 868 行の現実 PR diff を mistral:7b に流したところ、JSON 出力が不完全 (`missing field 'screen_decision'`) になり fallback path が作動した。Phase b' eval fixtures (10-30 行/件) では出ない failure mode で、本番 PR 投入時に頻発するリスクが顕在化していた。fixture 化することで再現可能化し、§8.D prompt v3 / v4 改善ループの reference point として固定する。 -> -> **本タスクの位置づけ**: PR #132 post-merge-feedback Tier 2 #5 採用 (Frequency Medium / Effort M / Adoption Risk None)。 -> -> **Status update (2026-06-06)**: 当初動機は「Phase d 投入前の必須 infrastructure」だったが、**ADR-038 (Local LLM finding classification) は PR #156 で採用昇格済**、関連 ephemeral 計画書も retire 済で **Phase d は既に運用入り**。動機は「Phase d 着手前」→「**採用昇格後の大規模 diff dogfood 信頼性向上 (継続改善)**」に書き換え。優先度は若干低下 (must → should) するが、リアル PR で 200+ 行 diff の fallback rate を測定する infrastructure はまだ価値あり (週次レビュー Phase D dogfood で fallback 観測継続中)。 -> -> **参照**: `.claude/feedback-reports/132.md` Tier 2 #5、`src/cli-finding-classifier/evals/lint-screen-evals.json` (eval セット)、`src/cli-finding-classifier/tests/lint_screen_evals.rs` (compare ロジック)、PR #132 PR body §smoke dogfood 結果 (868 行 diff の fallback 観測)、ADR-038 (採用昇格 PR #156) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。順位 91 land 済のため独立着手可。Phase d 運用中の継続改善として位置付け。 - -#### 追加する fixture 案 (3 件以上) - -| # | 名前 | 規模 | 検証目的 | -|---|---|---|---| -| 13 | eval13-large-refactor-real | ~300 行 / 5 file | mistral:7b の context 限界、fallback 頻度 | -| 14 | eval14-mid-mixed | ~150 行 / 3 file | scale 中域での recall 安定性 | -| 15 | eval15-syntax-stress | ~200 行 / 1 file | 単 file の long diff、JSON 完全性 | - -baseline は Phase a/b' と同じく Claude Code 一次起案 → ユーザー確認。期待結果 (`screen_decision`) は **agreement 75% 維持** が目標、未達なら §8.D v4 prompt 改訂ループ。 - -#### 作業計画 - -- [ ] 200-300 行 diff fixture を 3 件以上作成 (実 PR から抽出 or 合成) -- [ ] 各 fixture に SYNTHETIC FIXTURE comment header (ADR-038 規約) を付与 -- [ ] `lint-screen-evals.json` に baseline + expectations 追加 -- [ ] `eval_set_loads_and_has_phase_b_prime_twelve_entries` test を 15+ 件期待に更新 -- [ ] cargo test --ignored 再走、agreement rate と fallback rate を記録 -- [ ] agreement < 75% なら §8.D v4 prompt 改訂で対処 - -#### 完了基準 - -- 200+ 行 fixture 3 件以上が `evals/files/` に追加 -- cargo test --ignored が pass -- 大規模 diff の fallback rate が記録される (Phase d 改善ループの baseline) -- agreement 75% 以上が維持されているか、未達理由が文書化される - -#### 詰まっている箇所 - -なし。Phase d 本番 PR 投入前の必須 infra。 - ---- - -### `development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用) - -> **動機**: PR #139 (Bundle h+g-2 land) の post-merge-feedback で 2 つの暗黙知が systemic に観測された: -> -> 1. **同一ファイル複数編集の 1 task 統合**: PR #119/#120/#121 の sub-PR 分割では同一ファイル (`~/.claude/rules/common/*`) の複数編集を 1 task に統合した方が review 重複を回避できた。明文化されていないため次回類似 sub-PR で再発する余地 -> 2. **partial completion + 後続 PR 追補明記**: PR #139 で Bundle g-2 (順位 87+88) を land したが Bundle g-1 (順位 85+86) は未着手という partial completion を PR body / analysis.md で明記する pattern。Bundle h でも同様 (8 試験運用 ADR への back-link は本 PR 範囲外と明示)。明文化されていないと「全部やった」誤認や曖昧 review が生じる -> -> **本タスクの位置づけ**: PR #139 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 方針との整合: 本提案は「既存実践の明文化」であり機械検知不可なルール追加ではない (review/PR body 記述で人間の意識付けに用いる目安) ため例外的に採用相当。 -> -> **参照**: `.claude/feedback-reports/139.md` Tier 3 #1、`~/.claude/rules/common/development-workflow.md`、PR #119/#120/#121 (sub-PR 分割実例)、PR #139 (partial completion 実例) - -#### 作業計画 - -- [ ] `~/.claude/rules/common/development-workflow.md` の Feature Implementation Workflow 直後 (現 § Edge case 観測頻度の前後 etc.) に新 section を追加 - - **(a) 同一ファイル複数編集の 1 task 統合**: 「sub-PR 分割時、同一ファイルへの複数 task 編集は 1 commit / 1 task に統合する。理由: review 重複回避 + diff の局所化」 - - **(b) partial completion + 後続 PR 追補明記**: 「bundle / scope を全消化できない場合、PR body の "Out of scope" や planning doc に未消化分を明示。理由: 「全部やった」誤認の防止 + 後続 PR の起点として trackable」 -- [ ] 既存 § Edge case 観測頻度との接続 (相互参照 or 配置順序検討) -- [ ] markdownlint clean 確認 -- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 上記 2 pattern が rule として codify される -- 次回 sub-PR 分割時 / partial completion 時に reviewer/Claude が rule から逆引き可能になる -- markdownlint clean - -#### 詰まっている箇所 - -なし。Effort XS、global rule への追記のみで副作用最小。配置先 (Feature Implementation Workflow 直後 vs 別 § で独立) は実装時の判断。 - ---- - -### グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用) - -> **動機**: 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) で hooks を porting する際、lint runner がサポートするフィールド (`pattern` / `extensions` / `severity` / `message` / `why`、planned: `paths`) を一目で把握できる reference が グローバル CLAUDE.md に存在しない。順位 103 (code comment) と相補的で、cross-project 可視性を即時向上。 -> -> **本タスクの位置づけ**: PR #140 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/140.md` Tier 3 #2、`~/.claude/CLAUDE.md` (global、リンクのみ方針 = `feedback_claude_md_link_only.md`)、`src/hooks-post-tool-linter/src/main.rs` `CustomRule` struct - -#### 設計決定の余地 - -- **`feedback_claude_md_link_only.md` との整合**: グローバル CLAUDE.md は「リンクのみ」方針。table 形式で field 一覧を inline すると memory rule に違反する可能性 -- **代替案 1**: グローバル CLAUDE.md には「lint runner field reference は `~/.claude/rules/...` 配下に独立 doc」とリンクのみ書き、本体 doc は `~/.claude/rules//lint-runner-fields.md` 等に配置 -- **代替案 2**: project 内 ADR-007 amendment (順位 104) で field 一覧を含めて、グローバル CLAUDE.md は ADR-007 へのリンクのみ -- **判断**: 順位 104 land 後に決定。重複が無いように lifecycle 整合性を取る - -#### 作業計画 - -- [ ] 順位 104 (ADR-007 amendment) の land 後、配置案 1 / 2 / 別案を決定 -- [ ] `feedback_claude_md_link_only.md` 方針を再確認 -- [ ] 配置先に table 追加 (現サポート field + planned + 派生プロジェクト porting 時の参照点) -- [ ] グローバル CLAUDE.md にリンク追加 (memory rule 遵守) -- [ ] 派生プロジェクト 2 つ (techbook-ledger / auto-review-fix-vc) に本変更を伝播する deploy step を確認 -- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 派生プロジェクトの rule porting 時に field reference を 1 hop で参照可能 -- `feedback_claude_md_link_only.md` 違反なし - -#### 詰まっている箇所 - -- 配置先決定が順位 104 (ADR-007 amendment) の land と依存。順位 104 で field 一覧を inline するなら本タスクはリンク追加のみで済むが、ADR は判断基準中心であれば独立 reference doc が必要 - ---- - -### `development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用) - -> **動機**: memory `feedback_verify_task_not_already_done.md` (PR #141 セッションで追加) は session-scoped で「PR #125 → #141 で 4 日間 stale todo 残存 → P-3 起動時に手動発見」事例を含むが、`~/.claude/rules/common/development-workflow.md` の central rule 側には反映されていない。`feedback_todo_no_history.md` と合わせて central 化することで、memory file 閉鎖の structural risk を軽減する。 -> -> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium = 2 観測 / Effort XS / Adoption Risk None)。memory rule の central reference への昇格パターン。 -> -> **参照**: `.claude/feedback-reports/141.md` Tier 3 #2、`~/.claude/rules/common/development-workflow.md`、memory `feedback_verify_task_not_already_done.md` / `feedback_todo_no_history.md`、PR #125 / PR #141 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に 2-3 行追記: - - 「マージ後 N 日間 stale entry 残存 → 後続 phase で手動発見」anti-pattern 事例 (PR #125 → #141) - - 「マージ → 即削除」サイクル強調 (memory `feedback_todo_no_history` central 化) - - 「task 着手時に jj log + 既存 test で land 済確認」recovery layer (memory `feedback_verify_task_not_already_done` central 化) -- [ ] central rule から両 memory file への双方向参照を追加 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- central rule に PR #125→#141 anti-pattern が anchor として記録される -- 新セッションでも両 memory rule の趣旨を central から逆引き可能になる - ---- - -### CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用) - -> **動機**: PR #140 / PR #141 で post-merge-feedback agent が Tier 2 (テスト/自動化) と称した提案を出したが、中身は ルール追加 / checklist 必須化 等の **unenforced rule** で、ユーザー判断で却下相当 (memory `feedback_no_unenforced_rules.md` で codify 済)。memory ファイルは session-scoped で新セッション AI からは見えにくく「Tier 2 = 採用必須」と誤解する構造的リスクがある。グローバル CLAUDE.md に signal + 却下パターン table を可視化し、policy をユーザー可視 + 新セッション AI からも逆引き可能にする。 -> -> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium = 複数 session 観測 / Effort S / Adoption Risk None)。memory policy の central reference への昇格パターン。 -> -> **参照**: `.claude/feedback-reports/141.md` Tier 3 #3、`~/.claude/CLAUDE.md`、memory `feedback_no_unenforced_rules.md` (PR #140 / #141 で追記済) - -#### 設計決定 - -- **`feedback_claude_md_link_only.md` との整合**: CLAUDE.md は「リンクのみ」方針。table を inline すると memory rule に違反するため、別 stable doc (`~/.claude/rules/common/post-merge-feedback-policy.md` 等) に table を移し、CLAUDE.md からリンクする運用を推奨 - -#### 検知 signal table 案 - -| Signal | 例 | 判定 | -|---|---|---| -| target field に `*.md` / `test convention` 等 **文書 path** | "lint rule テスト checklist に <条件> を必須化" | ⚠️ Tier 2 偽装疑い | -| description に「**必須化**」「**標準化**」「**チェックリスト追加**」 | "lint rule テストで大文字バリアント必須化" | ⚠️ unenforced rule 強い signal | -| 機械強制 (CI / lint / test 存在検証) なし | "verbal checklist", "guideline 追記" | ❌ 却下相当 | - -#### 作業計画 - -- [ ] 配置先 (新 doc / 既存 doc) を決定 -- [ ] 上記 signal table を新 doc or 既存 doc に追加 -- [ ] CLAUDE.md に link 追加 (memory rule 遵守) -- [ ] 派生プロジェクトへの伝播も検討 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 新セッション AI が CLAUDE.md → link → table の動線で Tier 2 偽装判定を逆引き可能になる -- `feedback_claude_md_link_only` 違反なし - ---- - - -### pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用) - -> **動機**: Phase A (PR #142) の `overflow_hint()` は副作用なしの純粋関数で、境界値 (90%) / None (metadata 欠落) / 閾値未満 (90% 未満) の 3 パターンで test 化できる構造になっていた。このパターンを `~/.knee/rules/common/testing.md` にテンプレ化することで、Rust lib 全般で副作用分離と test 容易性が促進される。 -> -> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 2 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/142.md` Tier 2 #3、`~/.claude/rules/common/testing.md`、`src/lib-ollama-client/src/lib.rs` の `overflow_hint()` (PR #142) - -#### 作業計画 - -- [ ] `~/.claude/rules/common/testing.md` に「Pure function test pattern」section を追加 (境界値 / None / 閾値未満 の 3 パターン例) -- [ ] `overflow_hint()` (PR #142) をモデル例として cite -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- testing.md に template が記載され、次回 Rust lib で副作用分離する局面で参照可能になる - ---- - -### `docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用) - -> **動機**: PR #142 で CR Minor #2 として「todo-summary.md 順位 106-108 が todo5.md を指すが intro policy は todo6.md」の bifurcation 指摘あり、本 PR 内で修正済。しかし routing rule が文書化されておらず次回も同型 bifurcation の再発リスクがある。docs-governance.md に「新規詳細は todo6.md」routing rule + 50KB 超過時の対応方針を明文化することで構造的予防。 -> -> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/142.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md`、PR #142 CR Minor #2 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` に「todo*.md 新規詳細 routing rule」section を追加: 新規詳細は最新の todoN.md (現在 = todo6.md)、50KB 超過時は todo(N+1).md を新設 -- [ ] todo*.md 既存 file の preamble との整合確認 (todo6.md / todo7.md の冒頭文と矛盾しないか) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回 todo*.md 50KB 超過時に routing 判断が明確になり、CR Minor #2 と同型の bifurcation が再発しない - +# TODO (Part 6) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo5.md / 本ファイルが 50KB に到達 (PR #143 T3-#1) のため **新規エントリは [docs/todo8.md](todo8.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### scale-aware eval fixtures (200+ 行) — 大規模 diff dogfood 信頼性継続改善 (PR #132 T2-#5 採用) ★ Bundle i + +> **動機**: PR #132 smoke dogfood で 868 行の現実 PR diff を mistral:7b に流したところ、JSON 出力が不完全 (`missing field 'screen_decision'`) になり fallback path が作動した。Phase b' eval fixtures (10-30 行/件) では出ない failure mode で、本番 PR 投入時に頻発するリスクが顕在化していた。fixture 化することで再現可能化し、§8.D prompt v3 / v4 改善ループの reference point として固定する。 +> +> **本タスクの位置づけ**: PR #132 post-merge-feedback Tier 2 #5 採用 (Frequency Medium / Effort M / Adoption Risk None)。 +> +> **Status update (2026-06-06)**: 当初動機は「Phase d 投入前の必須 infrastructure」だったが、**ADR-038 (Local LLM finding classification) は PR #156 で採用昇格済**、関連 ephemeral 計画書も retire 済で **Phase d は既に運用入り**。動機は「Phase d 着手前」→「**採用昇格後の大規模 diff dogfood 信頼性向上 (継続改善)**」に書き換え。優先度は若干低下 (must → should) するが、リアル PR で 200+ 行 diff の fallback rate を測定する infrastructure はまだ価値あり (週次レビュー Phase D dogfood で fallback 観測継続中)。 +> +> **参照**: `.claude/feedback-reports/132.md` Tier 2 #5、`src/cli-finding-classifier/evals/lint-screen-evals.json` (eval セット)、`src/cli-finding-classifier/tests/lint_screen_evals.rs` (compare ロジック)、PR #132 PR body §smoke dogfood 結果 (868 行 diff の fallback 観測)、ADR-038 (採用昇格 PR #156) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。順位 91 land 済のため独立着手可。Phase d 運用中の継続改善として位置付け。 + +#### 追加する fixture 案 (3 件以上) + +| # | 名前 | 規模 | 検証目的 | +|---|---|---|---| +| 13 | eval13-large-refactor-real | ~300 行 / 5 file | mistral:7b の context 限界、fallback 頻度 | +| 14 | eval14-mid-mixed | ~150 行 / 3 file | scale 中域での recall 安定性 | +| 15 | eval15-syntax-stress | ~200 行 / 1 file | 単 file の long diff、JSON 完全性 | + +baseline は Phase a/b' と同じく Claude Code 一次起案 → ユーザー確認。期待結果 (`screen_decision`) は **agreement 75% 維持** が目標、未達なら §8.D v4 prompt 改訂ループ。 + +#### 作業計画 + +- [ ] 200-300 行 diff fixture を 3 件以上作成 (実 PR から抽出 or 合成) +- [ ] 各 fixture に SYNTHETIC FIXTURE comment header (ADR-038 規約) を付与 +- [ ] `lint-screen-evals.json` に baseline + expectations 追加 +- [ ] `eval_set_loads_and_has_phase_b_prime_twelve_entries` test を 15+ 件期待に更新 +- [ ] cargo test --ignored 再走、agreement rate と fallback rate を記録 +- [ ] agreement < 75% なら §8.D v4 prompt 改訂で対処 + +#### 完了基準 + +- 200+ 行 fixture 3 件以上が `evals/files/` に追加 +- cargo test --ignored が pass +- 大規模 diff の fallback rate が記録される (Phase d 改善ループの baseline) +- agreement 75% 以上が維持されているか、未達理由が文書化される + +#### 詰まっている箇所 + +なし。Phase d 本番 PR 投入前の必須 infra。 + +--- + +### `development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用) + +> **動機**: PR #139 (Bundle h+g-2 land) の post-merge-feedback で 2 つの暗黙知が systemic に観測された: +> +> 1. **同一ファイル複数編集の 1 task 統合**: PR #119/#120/#121 の sub-PR 分割では同一ファイル (`~/.claude/rules/common/*`) の複数編集を 1 task に統合した方が review 重複を回避できた。明文化されていないため次回類似 sub-PR で再発する余地 +> 2. **partial completion + 後続 PR 追補明記**: PR #139 で Bundle g-2 (順位 87+88) を land したが Bundle g-1 (順位 85+86) は未着手という partial completion を PR body / analysis.md で明記する pattern。Bundle h でも同様 (8 試験運用 ADR への back-link は本 PR 範囲外と明示)。明文化されていないと「全部やった」誤認や曖昧 review が生じる +> +> **本タスクの位置づけ**: PR #139 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 方針との整合: 本提案は「既存実践の明文化」であり機械検知不可なルール追加ではない (review/PR body 記述で人間の意識付けに用いる目安) ため例外的に採用相当。 +> +> **参照**: `.claude/feedback-reports/139.md` Tier 3 #1、`~/.claude/rules/common/development-workflow.md`、PR #119/#120/#121 (sub-PR 分割実例)、PR #139 (partial completion 実例) + +#### 作業計画 + +- [ ] `~/.claude/rules/common/development-workflow.md` の Feature Implementation Workflow 直後 (現 § Edge case 観測頻度の前後 etc.) に新 section を追加 + - **(a) 同一ファイル複数編集の 1 task 統合**: 「sub-PR 分割時、同一ファイルへの複数 task 編集は 1 commit / 1 task に統合する。理由: review 重複回避 + diff の局所化」 + - **(b) partial completion + 後続 PR 追補明記**: 「bundle / scope を全消化できない場合、PR body の "Out of scope" や planning doc に未消化分を明示。理由: 「全部やった」誤認の防止 + 後続 PR の起点として trackable」 +- [ ] 既存 § Edge case 観測頻度との接続 (相互参照 or 配置順序検討) +- [ ] markdownlint clean 確認 +- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 上記 2 pattern が rule として codify される +- 次回 sub-PR 分割時 / partial completion 時に reviewer/Claude が rule から逆引き可能になる +- markdownlint clean + +#### 詰まっている箇所 + +なし。Effort XS、global rule への追記のみで副作用最小。配置先 (Feature Implementation Workflow 直後 vs 別 § で独立) は実装時の判断。 + +--- + +### グローバル CLAUDE.md に lint runner サポートフィールド一覧表 (PR #140 T3-#2 採用) + +> **動機**: 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) で hooks を porting する際、lint runner がサポートするフィールド (`pattern` / `extensions` / `severity` / `message` / `why`、planned: `paths`) を一目で把握できる reference が グローバル CLAUDE.md に存在しない。順位 103 (code comment) と相補的で、cross-project 可視性を即時向上。 +> +> **本タスクの位置づけ**: PR #140 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/140.md` Tier 3 #2、`~/.claude/CLAUDE.md` (global、リンクのみ方針 = `feedback_claude_md_link_only.md`)、`src/hooks-post-tool-linter/src/main.rs` `CustomRule` struct + +#### 設計決定の余地 + +- **`feedback_claude_md_link_only.md` との整合**: グローバル CLAUDE.md は「リンクのみ」方針。table 形式で field 一覧を inline すると memory rule に違反する可能性 +- **代替案 1**: グローバル CLAUDE.md には「lint runner field reference は `~/.claude/rules/...` 配下に独立 doc」とリンクのみ書き、本体 doc は `~/.claude/rules//lint-runner-fields.md` 等に配置 +- **代替案 2**: project 内 ADR-007 amendment (順位 104) で field 一覧を含めて、グローバル CLAUDE.md は ADR-007 へのリンクのみ +- **判断**: 順位 104 land 後に決定。重複が無いように lifecycle 整合性を取る + +#### 作業計画 + +- [ ] 順位 104 (ADR-007 amendment) の land 後、配置案 1 / 2 / 別案を決定 +- [ ] `feedback_claude_md_link_only.md` 方針を再確認 +- [ ] 配置先に table 追加 (現サポート field + planned + 派生プロジェクト porting 時の参照点) +- [ ] グローバル CLAUDE.md にリンク追加 (memory rule 遵守) +- [ ] 派生プロジェクト 2 つ (techbook-ledger / auto-review-fix-vc) に本変更を伝播する deploy step を確認 +- [ ] 本 todo6.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 派生プロジェクトの rule porting 時に field reference を 1 hop で参照可能 +- `feedback_claude_md_link_only.md` 違反なし + +#### 詰まっている箇所 + +- 配置先決定が順位 104 (ADR-007 amendment) の land と依存。順位 104 で field 一覧を inline するなら本タスクはリンク追加のみで済むが、ADR は判断基準中心であれば独立 reference doc が必要 + +--- + +### `development-workflow.md` に PR #125→#141 anti-pattern 事例補強 (PR #141 T3-#2 採用) + +> **動機**: memory `feedback_verify_task_not_already_done.md` (PR #141 セッションで追加) は session-scoped で「PR #125 → #141 で 4 日間 stale todo 残存 → P-3 起動時に手動発見」事例を含むが、`~/.claude/rules/common/development-workflow.md` の central rule 側には反映されていない。`feedback_todo_no_history.md` と合わせて central 化することで、memory file 閉鎖の structural risk を軽減する。 +> +> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium = 2 観測 / Effort XS / Adoption Risk None)。memory rule の central reference への昇格パターン。 +> +> **参照**: `.claude/feedback-reports/141.md` Tier 3 #2、`~/.claude/rules/common/development-workflow.md`、memory `feedback_verify_task_not_already_done.md` / `feedback_todo_no_history.md`、PR #125 / PR #141 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/development-workflow.md` の「タスク完了削除手順」に 2-3 行追記: + - 「マージ後 N 日間 stale entry 残存 → 後続 phase で手動発見」anti-pattern 事例 (PR #125 → #141) + - 「マージ → 即削除」サイクル強調 (memory `feedback_todo_no_history` central 化) + - 「task 着手時に jj log + 既存 test で land 済確認」recovery layer (memory `feedback_verify_task_not_already_done` central 化) +- [ ] central rule から両 memory file への双方向参照を追加 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- central rule に PR #125→#141 anti-pattern が anchor として記録される +- 新セッションでも両 memory rule の趣旨を central から逆引き可能になる + +--- + +### CLAUDE.md に「Tier 2 偽装検知 + 却下パターン」table (PR #141 T3-#3 採用) + +> **動機**: PR #140 / PR #141 で post-merge-feedback agent が Tier 2 (テスト/自動化) と称した提案を出したが、中身は ルール追加 / checklist 必須化 等の **unenforced rule** で、ユーザー判断で却下相当 (memory `feedback_no_unenforced_rules.md` で codify 済)。memory ファイルは session-scoped で新セッション AI からは見えにくく「Tier 2 = 採用必須」と誤解する構造的リスクがある。グローバル CLAUDE.md に signal + 却下パターン table を可視化し、policy をユーザー可視 + 新セッション AI からも逆引き可能にする。 +> +> **本タスクの位置づけ**: PR #141 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium = 複数 session 観測 / Effort S / Adoption Risk None)。memory policy の central reference への昇格パターン。 +> +> **参照**: `.claude/feedback-reports/141.md` Tier 3 #3、`~/.claude/CLAUDE.md`、memory `feedback_no_unenforced_rules.md` (PR #140 / #141 で追記済) + +#### 設計決定 + +- **`feedback_claude_md_link_only.md` との整合**: CLAUDE.md は「リンクのみ」方針。table を inline すると memory rule に違反するため、別 stable doc (`~/.claude/rules/common/post-merge-feedback-policy.md` 等) に table を移し、CLAUDE.md からリンクする運用を推奨 + +#### 検知 signal table 案 + +| Signal | 例 | 判定 | +|---|---|---| +| target field に `*.md` / `test convention` 等 **文書 path** | "lint rule テスト checklist に <条件> を必須化" | ⚠️ Tier 2 偽装疑い | +| description に「**必須化**」「**標準化**」「**チェックリスト追加**」 | "lint rule テストで大文字バリアント必須化" | ⚠️ unenforced rule 強い signal | +| 機械強制 (CI / lint / test 存在検証) なし | "verbal checklist", "guideline 追記" | ❌ 却下相当 | + +#### 作業計画 + +- [ ] 配置先 (新 doc / 既存 doc) を決定 +- [ ] 上記 signal table を新 doc or 既存 doc に追加 +- [ ] CLAUDE.md に link 追加 (memory rule 遵守) +- [ ] 派生プロジェクトへの伝播も検討 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 新セッション AI が CLAUDE.md → link → table の動線で Tier 2 偽装判定を逆引き可能になる +- `feedback_claude_md_link_only` 違反なし + +--- + + +### pure function test pattern template を `testing.md` に追記 (PR #142 T2-#3 採用) + +> **動機**: Phase A (PR #142) の `overflow_hint()` は副作用なしの純粋関数で、境界値 (90%) / None (metadata 欠落) / 閾値未満 (90% 未満) の 3 パターンで test 化できる構造になっていた。このパターンを `~/.knee/rules/common/testing.md` にテンプレ化することで、Rust lib 全般で副作用分離と test 容易性が促進される。 +> +> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 2 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/142.md` Tier 2 #3、`~/.claude/rules/common/testing.md`、`src/lib-ollama-client/src/lib.rs` の `overflow_hint()` (PR #142) + +#### 作業計画 + +- [ ] `~/.claude/rules/common/testing.md` に「Pure function test pattern」section を追加 (境界値 / None / 閾値未満 の 3 パターン例) +- [ ] `overflow_hint()` (PR #142) をモデル例として cite +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- testing.md に template が記載され、次回 Rust lib で副作用分離する局面で参照可能になる + +--- + +### `docs-governance.md` に todo5/todo6 routing rule 明文化 (PR #142 T3-#1 採用) + +> **動機**: PR #142 で CR Minor #2 として「todo-summary.md 順位 106-108 が todo5.md を指すが intro policy は todo6.md」の bifurcation 指摘あり、本 PR 内で修正済。しかし routing rule が文書化されておらず次回も同型 bifurcation の再発リスクがある。docs-governance.md に「新規詳細は todo6.md」routing rule + 50KB 超過時の対応方針を明文化することで構造的予防。 +> +> **本タスクの位置づけ**: PR #142 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/142.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md`、PR #142 CR Minor #2 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` に「todo*.md 新規詳細 routing rule」section を追加: 新規詳細は最新の todoN.md (現在 = todo6.md)、50KB 超過時は todo(N+1).md を新設 +- [ ] todo*.md 既存 file の preamble との整合確認 (todo6.md / todo7.md の冒頭文と矛盾しないか) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回 todo*.md 50KB 超過時に routing 判断が明確になり、CR Minor #2 と同型の bifurcation が再発しない + diff --git a/docs/todo7.md b/docs/todo7.md index 93e2c830..3b4b9044 100644 --- a/docs/todo7.md +++ b/docs/todo7.md @@ -1,242 +1,242 @@ -# TODO (Part 7) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo5.md がファイルサイズ 67KB に到達して Claude Code の読み取り安定性 (50KB 超で不安定化) を損なったため、2026-05-09 に **PR #101〜#109 由来の古い半分のタスクを本ファイルへ分離** した。todo5.md には PR #110 以降のタスクが残存。本ファイルは既存タスクの編集・完了削除専用、新規タスクは追加しない (新規エントリは [docs/todo6.md](todo6.md) へ)。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### `parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2 - -> **動機**: PR #101 で `run_list_findings` が `unwrap_or_else(|_| "[]")` で gh api 失敗を `[]` に潰していて CR Major finding を受けた。99.md でも `silent fail` (Windows path mismatch で early return) として類似言及あり。**`unwrap_or_else(|_| empty)` の anti-pattern が複数 PR で再発**。test 層で機械検証することで未然に塞ぐ。本タスクは Bundle a Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) で同 API を消費するので、同一 PR land で test 二重投資なし。 -> -> **本タスクの位置づけ**: PR #101 post-merge-feedback Tier 2 #1 採用 (高頻度 anti-pattern finding)。Bundle a Sub-PR 2 (順位 42 / 43 / 46) と同 PR で land 推奨。CLAUDE.md `coding-style.md` "Never silently swallow errors" 原則の test 層実装。 -> -> **参照**: `.claude/feedback-reports/101.md` Tier 2 #1、`.claude/feedback-reports/99.md`、`~/.claude/rules/common/coding-style.md` "Never silently swallow errors" -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。新 test ファイル + gh API モック。Sub-PR 2 と一体実装。 - -#### 設計決定 (案) - -- **配置先**: `src/check-ci-coderabbit/tests/parse_error_handling_test.rs` (integration test、既存 unit test と分離) -- **テスト対象シナリオ**: - - **gh API HTTP error 返却時**: `run_list_findings` がエラーを propagate するか verify (現状 PR #101 fix で `.map_err(...)?` 化済 → regression 防止) - - **JSON 不正形式入力**: `serde_json::from_str` 失敗時の挙動 (現状 `unwrap_or_else(|e| { eprintln!(...); vec![] })` で warn は出すが空配列返却 = silent fall) — 望ましい設計を test で固定 - - **空 JSON `[]`**: 正常 path (空 findings 返却) の境界条件 -- **モック戦略**: - - gh API 直接モックは不要 (parse 関数は JSON string を受け取る純関数) - - `run_gh` を trait 化して mock injection or `mockito` HTTP mock — Sub-PR 2 の cli-pr-monitor 実装方針と整合 -- **既存 unit test との関係**: 既存 16 件は normal path 中心。本 task は error path 専用 - -#### 作業計画 - -- [ ] `src/check-ci-coderabbit/tests/` ディレクトリ作成 (現在 unit test only) -- [ ] gh API モック戦略の選定 (trait injection or shell wrapper stub) — Sub-PR 2 の cli-pr-monitor 実装方針と整合 -- [ ] error-path シナリオ 3 件 (HTTP error / 不正 JSON / 空 JSON) を実装 -- [ ] `cargo test --workspace` で pass 確認 -- [ ] dogfood: 実 PR で `unwrap_or_else(|_| empty)` を一時的に書き戻して test が fail するか sensitivity 検証 -- [ ] 本 todo7.md エントリを削除 - -#### 完了基準 - -- `parse_listed_findings` / `parse_findings` の error-path 3 シナリオ test が pass -- `unwrap_or_else(|_| empty)` の silent fallback パターンが test で fail 検出される -- Sub-PR 2 の cli-pr-monitor 実装で同 mock infrastructure を流用できる - -#### 詰まっている箇所 - -- gh API モック戦略の選定: HTTP mock library `mockito` vs `run_gh` の trait injection — 単純さ優先なら後者、real API 結合に近づけたいなら前者。 -- `eprintln!` (stderr) を assert する仕組みが Rust 標準にないため、`gag::BufferRedirect` や custom logger 注入が必要 — 着手時に評価。 - ---- - -### `.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測) - -> **動機**: PR #103 push の実観測で takt pre-push-review が **6-iter outlier (22m 50s)** を発生させ、うち iter 3+4 の ~10 分が wasted。原因は `.takt/review-diff.txt` が push-runner 起動時 snapshot として固定され、fix step の変更が反映されないこと。reviewer は古い diff を読んで「fix されていない」と機械的 false positive (`persists`) を出し、max iter まで escalate して supervise の live Read で打開する以外に経路がない。supervisor 自身が "structural limit" として診断済 (`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md`)。 -> -> **本タスクの位置づけ**: PR #103 セッション知見 (post-merge-feedback の Tier 3 #1 = ADR 化提案を skip し、機構で塞ぐ実装層対策を採用)。Bundle Z 3 層 (#B-α / #B-β / #B-γ) では完全に塞げない独立改善。reviewer の判定精度を構造的に改善することで 6-iter outlier の発生率を 0% 近くに抑える。 -> -> **Status update (2026-06-06)**: **採用案 C (`.takt/facets/instructions/fix.md` に refresh section 追加) は既に land 済** — entry 内 checklist `[x]` で完了表示 + `fix.md` に「Pre-completion diff refresh (REQUIRED)」section 確認。残るは **dogfood 観測** (PR D-6 merge + 1-2 PR の 6-iter outlier 非再発確認 + AI 実行率 > 90%) のみ。継続観測なら本 entry は **削除候補に近接**。次セッションで dogfood log を確認後、6-iter outlier が解消していれば即削除可。 -> -> **参照**: `.claude/feedback-reports/103.md` (Tier 3 #1 で同根因に別アプローチ提案、本 task で代替)、`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md` (false positive 構造診断)、[ADR-036: Bundle Z 3 層アーキテクチャ](adr/adr-036-bundle-z-three-layer-review.md) (PR #97 ベースライン observation を含む、本 task は Bundle Z 3 層では塞げない独立改善) -> -> **実行優先度**: 🚀 **Tier 1** — Effort M。takt 設定 / pre-push-review.yaml への hook 追加。Status update により実装は完了、残作業は dogfood 観測のみ。 - -#### 設計決定 (D-6 セッションで確定、2026-05-13) - -- **refresh タイミング**: fix step が `convergence_verdict` を emit する直前に refresh (= 次 reviewer iteration が読み始める時点で post-fix 状態) -- **実装方針 (3 案を評価)**: - - **案 A: takt workflow の reviewer step に precondition step を挟む** — ❌ **不可**。takt v0.35.3 schema (`PieceMovement` / `PieceConfig`) を確認した結果、per-step `before:` / `pre-step:` / `hooks:` field は存在しない。piece レベルの `runtime.prepare` は workflow 開始時 1 回のみ実行され、step 間に挟まらない (`node_modules/.pnpm/takt@0.35.3/node_modules/takt/dist/core/models/piece-types.d.ts` Line 74-98 / `runtime-environment.js` Line 171-191) - - **案 B: cli-push-runner 側で fix step の終了を検出して diff を更新** — ❌ **scope 不適合**。`stages/takt.rs` は `run_cmd_inherit` で takt を spawn-and-wait するのみ。filesystem watcher で `.takt/runs//reports/*.md` の生成を監視する案は ~100-200 行の Rust + race condition 対応が必要で、AI-driven 案で塞げる範囲を超える複雑度 - - **案 C: fix.md instruction に "Pre-completion diff refresh" section を追加** — ✅ **採用**。既存の Bundle Z #B-β `Pre-completion deterministic check (Bundle Z Phase 2 / #B-β)` と同形の precedent あり (`scripts/fix-metrics-check.ps1` を Bash 呼び出しする pattern)。失敗 mode (= AI が refresh を skip) は現状と同等 (no regression) -- **採用案 C の実装**: `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 (advisor 推奨)。`jj diff -r @ > .takt/review-diff.txt` を `convergence_verdict` emit 直前に必須実行 -- **共有 instruction の影響**: `fix.md` は pre-push-review.yaml と post-pr-review.yaml の両方で使用される。post-pr-review は `.takt/review-diff.txt` を読まないが、refresh は冪等で副作用なし (~1s 程度の `jj diff` invocation cost のみ) -- **派生プロジェクト deploy**: `scripts/deploy-hooks.ts` は exe + `settings.local.json` のみ転送し、`.takt/facets/instructions/*` は派生 (techbook-ledger / auto-review-fix-vc) 各自が管理。よって本変更の自動 propagate は不要 (手動 port が必要だが scope 外、follow-up task) - -#### 作業計画 - -- [x] takt workflow の hook 仕様を確認 → 案 A 不可と確定 -- [x] cli-push-runner の takt invocation 構造を確認 → 案 B も scope 不適合と確定 -- [x] advisor に方針相談 → 案 C (instruction-level) 採用 + 共有 instruction 影響 / deploy 経路を検証 -- [x] `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 -- [ ] dogfood: D-6 PR push 自体で本 instruction が機能するかを観察 (fix step が refresh を実行 → 次 reviewer iter が post-fix 状態を読むか) -- [ ] dogfood 1〜2 PR で実 6-iter outlier scenario が再発しないことを観測 -- [x] Bundle Z #B-β との競合確認: `fix-metrics-check.ps1` invocation は fix step 内部の Bash 実行で完結し、本 task の diff refresh は同 fix step の最終段 Bash 実行で独立。両者は時系列で順序通り走り競合なし -- [ ] 本 todo7.md エントリを削除 (PR D-6 merge + 1-2 PR の dogfood 完了後) - -#### 完了基準 - -- fix step 完了後の review iteration で `.takt/review-diff.txt` が最新状態を反映 -- 6-iter outlier の発生率が **0%** に近づく (PR #103 のような scenario が 3-iter で収束) -- supervisor の live Read 救済が不要になる (= supervisor step は workflow に残るが、false positive 救済責務が消える) - -#### 残課題 / dogfood リスク - -- AI-driven 案の弱点: fix step の AI が refresh 命令を skip する可能性。Bundle Z #B-β `metrics_check` invocation の実行率を baseline として比較し、refresh 実行率 > 90% を初期目標とする。dogfood で実行率 < 90% なら **案 D (PostToolUse hook ベースの決定論層)** へ escalate を検討 -- 派生プロジェクト port: `~/.takt/facets/instructions/fix.md` (global) や techbook-ledger / auto-review-fix-vc の同等ファイルへの転載が follow-up task (本 task scope 外) - ---- - -### comment-lint hook の MultiEdit 対応 (順位 50 follow-up) - -> **動機**: 順位 50 で comment-lint hook の scope を変更行に限定する v1 実装を完了した。v1 は Edit (single new_string) のみフィルタ対象とし、MultiEdit は whole-file lint にフォールバックする (no-regression)。MultiEdit が頻繁に使われる場合、複数 edit の `edits[].new_string` を順次適用して累積 range を計算する拡張が望ましい。 -> -> **本タスクの位置づけ**: 順位 50 follow-up。MultiEdit 利用頻度が低いため優先度は Tier 3。MultiEdit 由来の 12.6KB 出力が無視できない頻度になった場合、または Bundle Z Phase 3 (#B-γ) で MultiEdit ベースの大規模リファクタが日常化した場合に着手。 -> -> **参照**: 順位 50 PR (`src/hooks-post-tool-comment-lint-rust/src/main.rs` の `compute_changed_lines`)、Claude Code MultiEdit tool spec -> -> **実行優先度**: 💎 **Tier 3** — Effort S。`compute_changed_lines` に MultiEdit branch を追加。 - -#### 設計決定 (案) - -- **MultiEdit input schema**: `tool_input.edits: Vec<{old_string, new_string, replace_all?}>` を順次適用 -- **行 range 計算**: 各 edit の `new_string` を post-edit source 内で全件検索 → 全 edit の match 行 range の union を filter として使用 -- **空 new_string の扱い**: 個別の edit が純削除の場合、その edit はスキップ。全 edit が純削除なら filter は空 = lint skip -- **fallback 条件**: ある edit の `new_string` が見つからない場合 → 安全側に倒し whole-file lint (現 Edit 実装と同じ動作) - -#### 作業計画 - -- [ ] `ToolInput` struct に `edits: Option>` を追加 -- [ ] `compute_changed_lines` に `Some("MultiEdit")` branch を追加 (各 edit の new_string を locate して union) -- [ ] 単体テスト: 複数 edit の union が正しく計算されることを確認 -- [ ] 単体テスト: 一部 edit が純削除の場合の挙動確認 -- [ ] dogfood: MultiEdit を使った PR で hook 出力が変更行のみに絞られることを確認 -- [ ] 派生プロジェクト deploy -- [ ] 本 todo7.md エントリを削除 - -#### 完了基準 - -- MultiEdit でも変更行外の pre-existing violations が flag されない -- v1 (Edit) の挙動は不変 -- Phase 3 (#B-γ) で reviewer の役割が「異常検知」に縮小されると本 task の効果も部分的に縮む可能性 (criterion-based finding がそもそも reviewer から消えるため)。ただし Phase 3 完了前の中間期間 + Phase 3 後も「異常検知」自体は diff を読むので効果は残る。 - ---- - -### analyze-session の transcript filter 絞り込み (旧 #A-3) - -> **動機**: `cli-merge-pipeline` が生成する `.takt/post-merge-feedback-transcript.jsonl` は **session 全履歴** を含むため、analyze-session step が読み込む input token が大きい。当該 PR に直接関連する範囲のみ filter すれば input token 削減 = post-merge-feedback の cache_read 削減。 -> -> **本タスクの位置づけ**: 旧 `docs/pipeline-token-efficiency.md` の #A-3 entry。同計画書は ADR-036 (Bundle Z 3 層) / ADR-037 (fix-trust shortcut) に主要決定を移し終了予定で、残作業として本 task のみ todo に移管。Bundle 化対象なし、独立 PR 推奨。 -> -> **参照**: (削除済) `docs/pipeline-token-efficiency.md` #A-3 セクション、`src/cli-merge-pipeline/` の transcript 生成ロジック -> -> **実行優先度**: 💎 **Tier 3** — Effort M。ROI ★★★ で優先度中程度、dogfood 実測が必要。 - -#### 設計決定 (案) - -- **filter 範囲**: 当該 PR の作成 commit (= cli-pr-monitor が PR を最初に検出した時刻、または `pnpm create-pr` 完了時刻) から merge 完了時刻までの jsonl 行のみ -- **時刻判定**: jsonl の `timestamp` field を使用 (各エントリに ISO 8601 形式で記録あり) -- **境界の扱い**: - - 開始時刻 *以降*: PR 作業中の Claude 対話 + tool 実行履歴 - - 終了時刻 *まで*: merge 完了 (= post-merge-feedback 起動の直前まで) - - 境界外 (PR 作成前 / merge 後): 除外 -- **既存挙動との互換**: 開始時刻取得失敗時 (state file なし等) は全 session フォールバック (no-regression) - -#### 作業計画 - -- [ ] `cli-merge-pipeline` の transcript 生成ロジックを特定 -- [ ] PR 作成時刻 / merge 時刻の取得経路を確定 (`.claude/cli-pr-monitor-state.json` or `gh pr view --json mergedAt` 等) -- [ ] timestamp 比較で jsonl 行を filter する logic を実装 -- [ ] 開始時刻取得失敗時のフォールバック (全 session) を保持 -- [ ] dogfood 1-2 PR で input token 削減量を実測 (analyze-session の billable input tokens で比較) -- [ ] 削減効果が想定 30-50% に届くか確認、届かない場合は filter 設計を見直し -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy -- [ ] 本 todo7.md エントリを削除 - -#### 完了基準 - -- analyze-session の input token が PR 作業範囲のみに絞り込まれる -- dogfood で 30-50% 削減を実測 (削減未達なら filter 設計を見直し) -- 開始時刻取得失敗時のフォールバックが機能 (regression なし) - -#### 詰まっている箇所 - -- 「PR 作成前の議論 (設計判断、却下されたアイデア)」が落ちる可能性 → post-merge-feedback の知見質に影響しうる。dogfood で「重要 finding が拾えなくなった」事象が出たら filter 範囲を広げる (例: PR 作成 commit から 2 時間前まで遡る等) -- transcript jsonl の structure 変更時に filter logic が壊れる risk → field name (`timestamp`) を assert する unit test を追加 - ---- - -### `check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25) - -> **動機**: PR #108 で CodeRabbit が `Outside diff range comment` として review body 内に投稿した Minor finding (`docs/todo4.md` line 371/378 の retire 済前提と旧フロー混在) を、takt の `analyze-coderabbit` step が検出漏れした。`analyze-coderabbit` は `pulls/N/comments` (= inline review comment) ベースで動作するため、review.body 内のコメントは parse 対象外。結果、PR #108 で line 371/378 の修正が merge 後 follow-up commit (`vokyspww`) になった。 -> -> 当初計画では暫定緩和策として **手動 checklist** (post-PR フローに目視確認 step) を追加する rule 化方針だったが、PR #172 で「rule 化は session 毎に読み込みコストがかかり、人間が忘れる」課題が顕在化。仕組み化 (`check-ci-coderabbit` 拡張で programmatic 検出) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。当初 Tier 1 として位置づけていた analyzer 拡張を本 task で先行実施する形。 -> -> **本タスクの位置づけ**: PR #108 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。手動 checklist の根本解決 = 検出漏れを programmatic に消滅させる。手動 step が持続性低い (= 人間が忘れる) ため、CLI 拡張で session 跨いだ品質一定化が確保される。 -> -> **参照**: `.claude/feedback-reports/108.md` Tier 2 #1、PR #108 review (`Outside diff range comments` セクション、reviewer comment id 4217897113)、`src/check-ci-coderabbit/src/main.rs` (`parse_findings` 系 + `--list-findings` mode = 順位 45)、`.takt/facets/instructions/analyze-coderabbit.md`、PR #172 (順位 144 hook 化の dogfood 成功事例) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。`check-ci-coderabbit` 既存 crate への parse 機能追加 + analyze-coderabbit 連携。 - -#### 設計決定 (案) - -- **対象 source**: `gh api repos/{owner}/{repo}/pulls/{N}/reviews --jq '.[].body'` で取得する review.body markdown 文字列 -- **parse 対象セクション** (CR の出力フォーマットに準拠): - - `## Outside diff range comments` セクション内の bullet list (file:line 参照 + comment body) - - `## Caution` / `## Warning` セクション内の bullet (severity-marked findings) - - 行番号参照のある generic comment (regex: `\b(file|line)\s*[:=]\s*\d+|`L\d+`|`:`) -- **JSON schema 拡張**: 既存 `--list-findings` mode (順位 45) の出力に `source: "inline" | "review_body"` field を追加して同型 findings として扱う: - - ```json - { - "findings": [ - {"severity": "minor", "file": "docs/todo4.md", "line": 371, "summary": "...", "source": "review_body"} - ] - } - ``` - -- **analyze-coderabbit 連携**: 既存 `analyze-coderabbit` step が `--list-findings` 出力を取得する形になっていれば、source field を追加するだけで本 task の出力が自動的に下流に流れる -- **検出時の挙動**: inline findings と同じく severity 評価 → fix commit 追加 → resolve reply の通常 flow に乗る (本 task で flow 自体は変更しない) - -#### 作業計画 - -- [ ] `check-ci-coderabbit` 現状確認 (`--list-findings` mode が 順位 45 として実装済か、未実装なら本 task 着手前に 順位 45 を land) -- [ ] review.body 取得 API (`gh api .../pulls/{N}/reviews`) wrapper 実装 (既存の gh CLI wrapper が `src/check-ci-coderabbit/src/` にあれば再利用) -- [ ] markdown parser: `## Outside diff range comments` / `## Caution` / `## Warning` セクション抽出 + bullet 毎の file:line + body 抽出 -- [ ] JSON schema 拡張: `source` field 追加 (既存 schema は inline 想定なので default 値 `"inline"` で後方互換) -- [ ] test 拡充: 実 PR #108 の review.body を fixture 化 + parse 結果が期待 finding を返す test -- [ ] `analyze-coderabbit` 連携検証: source 別の handling が必要か (`outside-diff-range` の重み付けは inline と同等で進める想定) -- [ ] dogfood: 次 1-2 PR の post-pr-review で review.body finding が自動検出されることを観測 -- [ ] 派生プロジェクト deploy 検討 (`check-ci-coderabbit.exe` は本リポジトリ exe なので deploy で配布、scope 内) -- [ ] 本 todo7.md エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `check-ci-coderabbit --list-findings --pr 108` が PR #108 の outside-diff-range finding (line 371/378) を構造化 JSON で返す -- `source` field で inline vs review_body の区別が可能 -- `analyze-coderabbit` 連携で merge 前に outside-diff-range finding が actionable として扱われる -- 既存 inline finding 検出に regression なし -- `cargo test -p check-ci-coderabbit` pass - -#### 詰まっている箇所 - -- 順位 45 (`check-ci-coderabbit --list-findings` Rust モード) の land 状況確認が前提。未 land なら本 task 着手前に 順位 45 を先に進める -- CR 側 review.body フォーマットの変更耐性: section header (`## Outside diff range comments`) が CR の出力変更で変わる可能性がある。fail-soft 設計 (parse 失敗時は空 findings で続行 + warn log) で運用継続性を確保 -- false positive リスク: 行番号らしき文字列 (`L42` 等) が誤検出される可能性。CR 公式フォーマット section に限定した parse でリスク軽減 - ---- - +# TODO (Part 7) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo5.md がファイルサイズ 67KB に到達して Claude Code の読み取り安定性 (50KB 超で不安定化) を損なったため、2026-05-09 に **PR #101〜#109 由来の古い半分のタスクを本ファイルへ分離** した。todo5.md には PR #110 以降のタスクが残存。本ファイルは既存タスクの編集・完了削除専用、新規タスクは追加しない (新規エントリは [docs/todo6.md](todo6.md) へ)。todo.md / todo2-9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### `parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2 + +> **動機**: PR #101 で `run_list_findings` が `unwrap_or_else(|_| "[]")` で gh api 失敗を `[]` に潰していて CR Major finding を受けた。99.md でも `silent fail` (Windows path mismatch で early return) として類似言及あり。**`unwrap_or_else(|_| empty)` の anti-pattern が複数 PR で再発**。test 層で機械検証することで未然に塞ぐ。本タスクは Bundle a Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) で同 API を消費するので、同一 PR land で test 二重投資なし。 +> +> **本タスクの位置づけ**: PR #101 post-merge-feedback Tier 2 #1 採用 (高頻度 anti-pattern finding)。Bundle a Sub-PR 2 (順位 42 / 43 / 46) と同 PR で land 推奨。CLAUDE.md `coding-style.md` "Never silently swallow errors" 原則の test 層実装。 +> +> **参照**: `.claude/feedback-reports/101.md` Tier 2 #1、`.claude/feedback-reports/99.md`、`~/.claude/rules/common/coding-style.md` "Never silently swallow errors" +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。新 test ファイル + gh API モック。Sub-PR 2 と一体実装。 + +#### 設計決定 (案) + +- **配置先**: `src/check-ci-coderabbit/tests/parse_error_handling_test.rs` (integration test、既存 unit test と分離) +- **テスト対象シナリオ**: + - **gh API HTTP error 返却時**: `run_list_findings` がエラーを propagate するか verify (現状 PR #101 fix で `.map_err(...)?` 化済 → regression 防止) + - **JSON 不正形式入力**: `serde_json::from_str` 失敗時の挙動 (現状 `unwrap_or_else(|e| { eprintln!(...); vec![] })` で warn は出すが空配列返却 = silent fall) — 望ましい設計を test で固定 + - **空 JSON `[]`**: 正常 path (空 findings 返却) の境界条件 +- **モック戦略**: + - gh API 直接モックは不要 (parse 関数は JSON string を受け取る純関数) + - `run_gh` を trait 化して mock injection or `mockito` HTTP mock — Sub-PR 2 の cli-pr-monitor 実装方針と整合 +- **既存 unit test との関係**: 既存 16 件は normal path 中心。本 task は error path 専用 + +#### 作業計画 + +- [ ] `src/check-ci-coderabbit/tests/` ディレクトリ作成 (現在 unit test only) +- [ ] gh API モック戦略の選定 (trait injection or shell wrapper stub) — Sub-PR 2 の cli-pr-monitor 実装方針と整合 +- [ ] error-path シナリオ 3 件 (HTTP error / 不正 JSON / 空 JSON) を実装 +- [ ] `cargo test --workspace` で pass 確認 +- [ ] dogfood: 実 PR で `unwrap_or_else(|_| empty)` を一時的に書き戻して test が fail するか sensitivity 検証 +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- `parse_listed_findings` / `parse_findings` の error-path 3 シナリオ test が pass +- `unwrap_or_else(|_| empty)` の silent fallback パターンが test で fail 検出される +- Sub-PR 2 の cli-pr-monitor 実装で同 mock infrastructure を流用できる + +#### 詰まっている箇所 + +- gh API モック戦略の選定: HTTP mock library `mockito` vs `run_gh` の trait injection — 単純さ優先なら後者、real API 結合に近づけたいなら前者。 +- `eprintln!` (stderr) を assert する仕組みが Rust 標準にないため、`gag::BufferRedirect` や custom logger 注入が必要 — 着手時に評価。 + +--- + +### `.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測) + +> **動機**: PR #103 push の実観測で takt pre-push-review が **6-iter outlier (22m 50s)** を発生させ、うち iter 3+4 の ~10 分が wasted。原因は `.takt/review-diff.txt` が push-runner 起動時 snapshot として固定され、fix step の変更が反映されないこと。reviewer は古い diff を読んで「fix されていない」と機械的 false positive (`persists`) を出し、max iter まで escalate して supervise の live Read で打開する以外に経路がない。supervisor 自身が "structural limit" として診断済 (`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md`)。 +> +> **本タスクの位置づけ**: PR #103 セッション知見 (post-merge-feedback の Tier 3 #1 = ADR 化提案を skip し、機構で塞ぐ実装層対策を採用)。Bundle Z 3 層 (#B-α / #B-β / #B-γ) では完全に塞げない独立改善。reviewer の判定精度を構造的に改善することで 6-iter outlier の発生率を 0% 近くに抑える。 +> +> **Status update (2026-06-06)**: **採用案 C (`.takt/facets/instructions/fix.md` に refresh section 追加) は既に land 済** — entry 内 checklist `[x]` で完了表示 + `fix.md` に「Pre-completion diff refresh (REQUIRED)」section 確認。残るは **dogfood 観測** (PR D-6 merge + 1-2 PR の 6-iter outlier 非再発確認 + AI 実行率 > 90%) のみ。継続観測なら本 entry は **削除候補に近接**。次セッションで dogfood log を確認後、6-iter outlier が解消していれば即削除可。 +> +> **参照**: `.claude/feedback-reports/103.md` (Tier 3 #1 で同根因に別アプローチ提案、本 task で代替)、`.takt/runs/20260503-113700-pre-push-review/reports/supervisor-validation.md` (false positive 構造診断)、[ADR-036: Bundle Z 3 層アーキテクチャ](adr/adr-036-bundle-z-three-layer-review.md) (PR #97 ベースライン observation を含む、本 task は Bundle Z 3 層では塞げない独立改善) +> +> **実行優先度**: 🚀 **Tier 1** — Effort M。takt 設定 / pre-push-review.yaml への hook 追加。Status update により実装は完了、残作業は dogfood 観測のみ。 + +#### 設計決定 (D-6 セッションで確定、2026-05-13) + +- **refresh タイミング**: fix step が `convergence_verdict` を emit する直前に refresh (= 次 reviewer iteration が読み始める時点で post-fix 状態) +- **実装方針 (3 案を評価)**: + - **案 A: takt workflow の reviewer step に precondition step を挟む** — ❌ **不可**。takt v0.35.3 schema (`PieceMovement` / `PieceConfig`) を確認した結果、per-step `before:` / `pre-step:` / `hooks:` field は存在しない。piece レベルの `runtime.prepare` は workflow 開始時 1 回のみ実行され、step 間に挟まらない (`node_modules/.pnpm/takt@0.35.3/node_modules/takt/dist/core/models/piece-types.d.ts` Line 74-98 / `runtime-environment.js` Line 171-191) + - **案 B: cli-push-runner 側で fix step の終了を検出して diff を更新** — ❌ **scope 不適合**。`stages/takt.rs` は `run_cmd_inherit` で takt を spawn-and-wait するのみ。filesystem watcher で `.takt/runs//reports/*.md` の生成を監視する案は ~100-200 行の Rust + race condition 対応が必要で、AI-driven 案で塞げる範囲を超える複雑度 + - **案 C: fix.md instruction に "Pre-completion diff refresh" section を追加** — ✅ **採用**。既存の Bundle Z #B-β `Pre-completion deterministic check (Bundle Z Phase 2 / #B-β)` と同形の precedent あり (`scripts/fix-metrics-check.ps1` を Bash 呼び出しする pattern)。失敗 mode (= AI が refresh を skip) は現状と同等 (no regression) +- **採用案 C の実装**: `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 (advisor 推奨)。`jj diff -r @ > .takt/review-diff.txt` を `convergence_verdict` emit 直前に必須実行 +- **共有 instruction の影響**: `fix.md` は pre-push-review.yaml と post-pr-review.yaml の両方で使用される。post-pr-review は `.takt/review-diff.txt` を読まないが、refresh は冪等で副作用なし (~1s 程度の `jj diff` invocation cost のみ) +- **派生プロジェクト deploy**: `scripts/deploy-hooks.ts` は exe + `settings.local.json` のみ転送し、`.takt/facets/instructions/*` は派生 (techbook-ledger / auto-review-fix-vc) 各自が管理。よって本変更の自動 propagate は不要 (手動 port が必要だが scope 外、follow-up task) + +#### 作業計画 + +- [x] takt workflow の hook 仕様を確認 → 案 A 不可と確定 +- [x] cli-push-runner の takt invocation 構造を確認 → 案 B も scope 不適合と確定 +- [x] advisor に方針相談 → 案 C (instruction-level) 採用 + 共有 instruction 影響 / deploy 経路を検証 +- [x] `.takt/facets/instructions/fix.md` に「Pre-completion diff refresh (REQUIRED)」section を追加 +- [ ] dogfood: D-6 PR push 自体で本 instruction が機能するかを観察 (fix step が refresh を実行 → 次 reviewer iter が post-fix 状態を読むか) +- [ ] dogfood 1〜2 PR で実 6-iter outlier scenario が再発しないことを観測 +- [x] Bundle Z #B-β との競合確認: `fix-metrics-check.ps1` invocation は fix step 内部の Bash 実行で完結し、本 task の diff refresh は同 fix step の最終段 Bash 実行で独立。両者は時系列で順序通り走り競合なし +- [ ] 本 todo7.md エントリを削除 (PR D-6 merge + 1-2 PR の dogfood 完了後) + +#### 完了基準 + +- fix step 完了後の review iteration で `.takt/review-diff.txt` が最新状態を反映 +- 6-iter outlier の発生率が **0%** に近づく (PR #103 のような scenario が 3-iter で収束) +- supervisor の live Read 救済が不要になる (= supervisor step は workflow に残るが、false positive 救済責務が消える) + +#### 残課題 / dogfood リスク + +- AI-driven 案の弱点: fix step の AI が refresh 命令を skip する可能性。Bundle Z #B-β `metrics_check` invocation の実行率を baseline として比較し、refresh 実行率 > 90% を初期目標とする。dogfood で実行率 < 90% なら **案 D (PostToolUse hook ベースの決定論層)** へ escalate を検討 +- 派生プロジェクト port: `~/.takt/facets/instructions/fix.md` (global) や techbook-ledger / auto-review-fix-vc の同等ファイルへの転載が follow-up task (本 task scope 外) + +--- + +### comment-lint hook の MultiEdit 対応 (順位 50 follow-up) + +> **動機**: 順位 50 で comment-lint hook の scope を変更行に限定する v1 実装を完了した。v1 は Edit (single new_string) のみフィルタ対象とし、MultiEdit は whole-file lint にフォールバックする (no-regression)。MultiEdit が頻繁に使われる場合、複数 edit の `edits[].new_string` を順次適用して累積 range を計算する拡張が望ましい。 +> +> **本タスクの位置づけ**: 順位 50 follow-up。MultiEdit 利用頻度が低いため優先度は Tier 3。MultiEdit 由来の 12.6KB 出力が無視できない頻度になった場合、または Bundle Z Phase 3 (#B-γ) で MultiEdit ベースの大規模リファクタが日常化した場合に着手。 +> +> **参照**: 順位 50 PR (`src/hooks-post-tool-comment-lint-rust/src/main.rs` の `compute_changed_lines`)、Claude Code MultiEdit tool spec +> +> **実行優先度**: 💎 **Tier 3** — Effort S。`compute_changed_lines` に MultiEdit branch を追加。 + +#### 設計決定 (案) + +- **MultiEdit input schema**: `tool_input.edits: Vec<{old_string, new_string, replace_all?}>` を順次適用 +- **行 range 計算**: 各 edit の `new_string` を post-edit source 内で全件検索 → 全 edit の match 行 range の union を filter として使用 +- **空 new_string の扱い**: 個別の edit が純削除の場合、その edit はスキップ。全 edit が純削除なら filter は空 = lint skip +- **fallback 条件**: ある edit の `new_string` が見つからない場合 → 安全側に倒し whole-file lint (現 Edit 実装と同じ動作) + +#### 作業計画 + +- [ ] `ToolInput` struct に `edits: Option>` を追加 +- [ ] `compute_changed_lines` に `Some("MultiEdit")` branch を追加 (各 edit の new_string を locate して union) +- [ ] 単体テスト: 複数 edit の union が正しく計算されることを確認 +- [ ] 単体テスト: 一部 edit が純削除の場合の挙動確認 +- [ ] dogfood: MultiEdit を使った PR で hook 出力が変更行のみに絞られることを確認 +- [ ] 派生プロジェクト deploy +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- MultiEdit でも変更行外の pre-existing violations が flag されない +- v1 (Edit) の挙動は不変 +- Phase 3 (#B-γ) で reviewer の役割が「異常検知」に縮小されると本 task の効果も部分的に縮む可能性 (criterion-based finding がそもそも reviewer から消えるため)。ただし Phase 3 完了前の中間期間 + Phase 3 後も「異常検知」自体は diff を読むので効果は残る。 + +--- + +### analyze-session の transcript filter 絞り込み (旧 #A-3) + +> **動機**: `cli-merge-pipeline` が生成する `.takt/post-merge-feedback-transcript.jsonl` は **session 全履歴** を含むため、analyze-session step が読み込む input token が大きい。当該 PR に直接関連する範囲のみ filter すれば input token 削減 = post-merge-feedback の cache_read 削減。 +> +> **本タスクの位置づけ**: 旧 `docs/pipeline-token-efficiency.md` の #A-3 entry。同計画書は ADR-036 (Bundle Z 3 層) / ADR-037 (fix-trust shortcut) に主要決定を移し終了予定で、残作業として本 task のみ todo に移管。Bundle 化対象なし、独立 PR 推奨。 +> +> **参照**: (削除済) `docs/pipeline-token-efficiency.md` #A-3 セクション、`src/cli-merge-pipeline/` の transcript 生成ロジック +> +> **実行優先度**: 💎 **Tier 3** — Effort M。ROI ★★★ で優先度中程度、dogfood 実測が必要。 + +#### 設計決定 (案) + +- **filter 範囲**: 当該 PR の作成 commit (= cli-pr-monitor が PR を最初に検出した時刻、または `pnpm create-pr` 完了時刻) から merge 完了時刻までの jsonl 行のみ +- **時刻判定**: jsonl の `timestamp` field を使用 (各エントリに ISO 8601 形式で記録あり) +- **境界の扱い**: + - 開始時刻 *以降*: PR 作業中の Claude 対話 + tool 実行履歴 + - 終了時刻 *まで*: merge 完了 (= post-merge-feedback 起動の直前まで) + - 境界外 (PR 作成前 / merge 後): 除外 +- **既存挙動との互換**: 開始時刻取得失敗時 (state file なし等) は全 session フォールバック (no-regression) + +#### 作業計画 + +- [ ] `cli-merge-pipeline` の transcript 生成ロジックを特定 +- [ ] PR 作成時刻 / merge 時刻の取得経路を確定 (`.claude/cli-pr-monitor-state.json` or `gh pr view --json mergedAt` 等) +- [ ] timestamp 比較で jsonl 行を filter する logic を実装 +- [ ] 開始時刻取得失敗時のフォールバック (全 session) を保持 +- [ ] dogfood 1-2 PR で input token 削減量を実測 (analyze-session の billable input tokens で比較) +- [ ] 削減効果が想定 30-50% に届くか確認、届かない場合は filter 設計を見直し +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy +- [ ] 本 todo7.md エントリを削除 + +#### 完了基準 + +- analyze-session の input token が PR 作業範囲のみに絞り込まれる +- dogfood で 30-50% 削減を実測 (削減未達なら filter 設計を見直し) +- 開始時刻取得失敗時のフォールバックが機能 (regression なし) + +#### 詰まっている箇所 + +- 「PR 作成前の議論 (設計判断、却下されたアイデア)」が落ちる可能性 → post-merge-feedback の知見質に影響しうる。dogfood で「重要 finding が拾えなくなった」事象が出たら filter 範囲を広げる (例: PR 作成 commit から 2 時間前まで遡る等) +- transcript jsonl の structure 変更時に filter logic が壊れる risk → field name (`timestamp`) を assert する unit test を追加 + +--- + +### `check-ci-coderabbit` に CR review.body parse 機能追加 — outside-diff-range finding の programmatic 検出 (PR #108 T2-1 採用、PR #172 仕組み化方針切替 2026-05-25) + +> **動機**: PR #108 で CodeRabbit が `Outside diff range comment` として review body 内に投稿した Minor finding (`docs/todo4.md` line 371/378 の retire 済前提と旧フロー混在) を、takt の `analyze-coderabbit` step が検出漏れした。`analyze-coderabbit` は `pulls/N/comments` (= inline review comment) ベースで動作するため、review.body 内のコメントは parse 対象外。結果、PR #108 で line 371/378 の修正が merge 後 follow-up commit (`vokyspww`) になった。 +> +> 当初計画では暫定緩和策として **手動 checklist** (post-PR フローに目視確認 step) を追加する rule 化方針だったが、PR #172 で「rule 化は session 毎に読み込みコストがかかり、人間が忘れる」課題が顕在化。仕組み化 (`check-ci-coderabbit` 拡張で programmatic 検出) に方針切替する (`feedback_pipeline_over_rules.md` 適用)。当初 Tier 1 として位置づけていた analyzer 拡張を本 task で先行実施する形。 +> +> **本タスクの位置づけ**: PR #108 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。手動 checklist の根本解決 = 検出漏れを programmatic に消滅させる。手動 step が持続性低い (= 人間が忘れる) ため、CLI 拡張で session 跨いだ品質一定化が確保される。 +> +> **参照**: `.claude/feedback-reports/108.md` Tier 2 #1、PR #108 review (`Outside diff range comments` セクション、reviewer comment id 4217897113)、`src/check-ci-coderabbit/src/main.rs` (`parse_findings` 系 + `--list-findings` mode = 順位 45)、`.takt/facets/instructions/analyze-coderabbit.md`、PR #172 (順位 144 hook 化の dogfood 成功事例) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。`check-ci-coderabbit` 既存 crate への parse 機能追加 + analyze-coderabbit 連携。 + +#### 設計決定 (案) + +- **対象 source**: `gh api repos/{owner}/{repo}/pulls/{N}/reviews --jq '.[].body'` で取得する review.body markdown 文字列 +- **parse 対象セクション** (CR の出力フォーマットに準拠): + - `## Outside diff range comments` セクション内の bullet list (file:line 参照 + comment body) + - `## Caution` / `## Warning` セクション内の bullet (severity-marked findings) + - 行番号参照のある generic comment (regex: `\b(file|line)\s*[:=]\s*\d+|`L\d+`|`:`) +- **JSON schema 拡張**: 既存 `--list-findings` mode (順位 45) の出力に `source: "inline" | "review_body"` field を追加して同型 findings として扱う: + + ```json + { + "findings": [ + {"severity": "minor", "file": "docs/todo4.md", "line": 371, "summary": "...", "source": "review_body"} + ] + } + ``` + +- **analyze-coderabbit 連携**: 既存 `analyze-coderabbit` step が `--list-findings` 出力を取得する形になっていれば、source field を追加するだけで本 task の出力が自動的に下流に流れる +- **検出時の挙動**: inline findings と同じく severity 評価 → fix commit 追加 → resolve reply の通常 flow に乗る (本 task で flow 自体は変更しない) + +#### 作業計画 + +- [ ] `check-ci-coderabbit` 現状確認 (`--list-findings` mode が 順位 45 として実装済か、未実装なら本 task 着手前に 順位 45 を land) +- [ ] review.body 取得 API (`gh api .../pulls/{N}/reviews`) wrapper 実装 (既存の gh CLI wrapper が `src/check-ci-coderabbit/src/` にあれば再利用) +- [ ] markdown parser: `## Outside diff range comments` / `## Caution` / `## Warning` セクション抽出 + bullet 毎の file:line + body 抽出 +- [ ] JSON schema 拡張: `source` field 追加 (既存 schema は inline 想定なので default 値 `"inline"` で後方互換) +- [ ] test 拡充: 実 PR #108 の review.body を fixture 化 + parse 結果が期待 finding を返す test +- [ ] `analyze-coderabbit` 連携検証: source 別の handling が必要か (`outside-diff-range` の重み付けは inline と同等で進める想定) +- [ ] dogfood: 次 1-2 PR の post-pr-review で review.body finding が自動検出されることを観測 +- [ ] 派生プロジェクト deploy 検討 (`check-ci-coderabbit.exe` は本リポジトリ exe なので deploy で配布、scope 内) +- [ ] 本 todo7.md エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `check-ci-coderabbit --list-findings --pr 108` が PR #108 の outside-diff-range finding (line 371/378) を構造化 JSON で返す +- `source` field で inline vs review_body の区別が可能 +- `analyze-coderabbit` 連携で merge 前に outside-diff-range finding が actionable として扱われる +- 既存 inline finding 検出に regression なし +- `cargo test -p check-ci-coderabbit` pass + +#### 詰まっている箇所 + +- 順位 45 (`check-ci-coderabbit --list-findings` Rust モード) の land 状況確認が前提。未 land なら本 task 着手前に 順位 45 を先に進める +- CR 側 review.body フォーマットの変更耐性: section header (`## Outside diff range comments`) が CR の出力変更で変わる可能性がある。fail-soft 設計 (parse 失敗時は空 findings で続行 + warn log) で運用継続性を確保 +- false positive リスク: 行番号らしき文字列 (`L42` 等) が誤検出される可能性。CR 公式フォーマット section に限定した parse でリスク軽減 + +--- + diff --git a/docs/todo8.md b/docs/todo8.md index 3a4bab9c..0bcc59fc 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -1,312 +1,312 @@ -# TODO (Part 8) - -> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 -> -> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #143 T3-#1 採用時 = 2026-05-11 から新規エントリは本ファイルに記録していた。**本ファイルも 60KB に到達したため、PR #172 仕組み化方針切替セッション = 2026-05-25 以降の新規エントリは [docs/todo9.md](todo9.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md / todo7.md / todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十二つすべてを確認すること (todo.md / todo2-11.md / todo-summary.md)。 -> -> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 - ---- - -## 現在進行中 - -### rule⑧ への paths filter 適用範囲検討 (順位 102 land 時に意図的保留、follow-up) - -> **動機**: 順位 102 (PR #148 想定で land 中、Phase D D-3) で paths filter が lint runner に実装されたが、当初計画した rule⑧ への `paths = ["docs/**/*.md"]` migration は **意図的に保留**。理由: D-2 (PR #146、順位 101) で追加した「root-level MD (CLAUDE.md / README.md) からの `../docs/` 参照を fire = true positive で扱う」design intent が、`paths = ["docs/**/*.md"]` 適用で scope narrow されて壊れる (root-level MD の実 path が docs/ 配下ではないため rule 対象外になり、broken link 検出を失う)。本タスクで以下のいずれを採用するか検討する: -> -> 1. **保留継続** (現状維持): rule⑧ は `extensions = ["md"]` のみで run、root-level fire を保護 -> 2. **broader glob**: `paths = ["**/*.md"]` で全 .md 受容 (= extensions filter と機能的同等、demonstration 用途) -> 3. **explicit list**: `paths = ["docs/**/*.md", "*.md", ".claude/**/*.md"]` で docs/ + root + .claude/ をカバー -> 4. **rule split**: rule⑧-docs (docs/ scope) + rule⑧-root (root scope) に分割 -> -> **本タスクの位置づけ**: 順位 102 follow-up (Severity Low / Frequency Low = 1 観測 / Effort XS / Adoption Risk None)。実 production lint behavior に影響しない range で trade-off 評価。 -> -> **参照**: PR #148 (順位 102 land) の TOML rule⑧ コメント、PR #146 (D-2、順位 101) の `md_no_docs_relative_detects_root_*` tests - -#### 作業計画 - -- [ ] 4 案の trade-off を ADR-007 amendment (順位 104) と整合させて評価 -- [ ] 採用案を `.claude/custom-lint-rules.toml` rule⑧ に適用 (案 1 保留継続なら no-op だが、本エントリ削除で結論明示) -- [ ] 既存 test (`md_no_docs_relative_*` group) との整合性確認 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- rule⑧ scope の設計判断が ADR-007 amendment と本タスク entry で明確化される -- 同型 trade-off (filter scope narrow vs coverage 保持) を将来 rule 追加時に逆引きできる - ---- - -### `coding-style.md § Cross-File Reference Lifecycle` に「ephemeral → permanent 知識移管 edit order」追記 (PR #145 T3-#3 採用) - -> **動機**: PR #145 で lib.rs L128-139 dogfood evolution コメントを ADR-040 に migrate した際、edit 順序が曖昧だった (ADR-040 を先に作るべきか、lib.rs 側の参照削除を先にすべきか)。同パターンが (1) lib.rs コメント → ADR-040、(2) Phase C/D empirical data → ADR-040 で 2 回観測。既存の Cross-File Reference Lifecycle ルール は「参照方向の制約」(permanent → ephemeral 禁止) に特化しており、移管作業の edit order checklist は complementary で重複なし。次回同型の永続化作業 (ephemeral 計画書 retire 時の permanent value 移管 等) で再発防止策として codify する。 -> -> **本タスクの位置づけ**: PR #145 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 -> -> **参照**: `.claude/feedback-reports/145.md` Tier 3 #3、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle - -#### 提案する 3 ステップ原則 - -1. **permanent target 先行作成・validate**: 移管先の permanent artifact (ADR / stable docs) を先に作成し、内容の正確性 (cross-reference の妥当性 / 数値整合性 / markdownlint pass) を確認 -2. **参照追加**: ephemeral 側 (lib.rs コメント / config コメント / scratch markdown 等) から permanent への参照 link を追加 (1-2 行) -3. **参照元削除**: ephemeral 側の冗長な内容を削除し、参照 link のみ残す。同一 commit で 3 step すべてを実施 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle 末尾に「ephemeral → permanent 知識移管 edit order」 subsection を追加 -- [ ] 3 ステップ原則を inline で記述、PR #145 (lib.rs L128-139 → ADR-040) を実例として cite -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 計画も検討 -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回 permanent 化作業時に edit order が決定論的に決まる -- ephemeral 計画書 retire 時の permanent value 移管プロセスが checklist 化される - ---- - -### CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用) - -> **動機**: PR #153 で旧 `docs/local-llm-offload-analysis.md` を `phase-d-outcomes.md` に分割した際 (3 ファイルは Phase E 採用昇格 = 2026-05-15 に retire 済)、retirement clause を **3 ファイル (analysis.md / history.md / phase-d-outcomes.md) 同時削除** に統一する作業が developer/AI の手動 review でしか担保されていなかった。advisor 指摘で明示的に「3 ファイルすべてに同じ retirement clause を書く」ステップを踏んだが、これは structural pattern として再利用可能 (今後の docs/* 50KB 分割でも同じ checklist が必要)。同パターンが drift すると ephemeral artifact の lifecycle 整合が崩れ、stale pointer が増殖するリスクあり。 -> -> **本タスクの位置づけ**: PR #153 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。**既存実践 (PR #133 todo.md 分割 + PR #153 analysis.md 分割) の明文化 + 機械強制ではなく guide 効果** のため、`feedback_no_unenforced_rules.md` の例外条件 (順位 122 / 127 と同じロジック) を満たす。 -> -> **参照**: `.claude/feedback-reports/153.md` Tier 3 #2、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow - -#### 作業計画 - -- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に「多ファイル同時削除時の retirement condition consistency checklist」section を追加 (3-5 項目程度の bullet list) - - 「N ファイルを同時削除する設計の場合、全 N ファイルの header に同一の retirement clause が記載されているか」 - - 「retirement workflow の Step 3 (参照更新) で `grep -rn ''` を全ファイル分実施したか」 - - 「新ファイル追加時に既存ファイルの retirement clause にも追記したか」 - - 「参照先 (ADR / docs-governance.md) が permanent artifact であることを確認」 -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 -- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回多ファイル分割 (例: history.md 50KB 接近時) で同 checklist を踏むことで drift が構造的に防止される -- PR #133 (todo.md 分割) / PR #153 (analysis.md 分割) の successful pattern が明文化され、3 例目以降の reproducibility が確保される - ---- - -### docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = 必ず grep で実ファイル確認」を明記 (PR #156 T3 #1 採用) - -> **動機**: PR #156 で ephemeral 4 ファイル retire を実施した際、`grep` 結果に含まれる **diff context 行が実ファイルの最新内容ではなく PR 直前の状態を反映する** ため、削除対象ファイルへの参照が「残存」と誤検出される false alarm が 5 件以上発生。fact-check の grep 実行に時間を要した。XS の文言追加で将来セッションの reviewer / Claude が同一の確認コストを繰り返すことを防止できる。ephemeral 退役ワークフローは今後も繰り返されるため Frequency Medium。 -> -> **本タスクの位置づけ**: PR #156 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 例外条件 = 既存実践の明文化 + guide 効果のため採用 (順位 122 / 127 と同じロジック)。 -> -> **参照**: `.claude/feedback-reports/156.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` §Retirement Workflow - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` §Retirement Workflow の Step 3 (参照更新) に「diff context 由来 false alarm 防止」note 追加 (2-3 行) - - 「`grep -rn ''` で hit した参照は **必ず該当ファイルを Read で開き、最新内容に対象参照が実在することを確認** する。diff context は PR 直前の旧状態を反映するため、retire 対象ファイルへの参照が context として残存しているように見えても、現行 working copy では既に削除されている場合がある」 - - 具体例: PR #156 (4 ファイル同時 retire) で 5 件以上の false alarm が発生 -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 -- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 次回 ephemeral 退役 workflow で同 false alarm が発生しても、明文化された手順により fact-check の認知コストが低減する -- guide として PR review / Claude session 双方で参照可能 - -#### 詰まっている箇所 - -なし。Effort XS、global rule への追記のみで副作用最小。 - ---- - -### todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来) - -> **動機**: 順位 78 (旧 ADR-038 Rust timestamp arithmetic safety、PR #115 T3-1) は entry 登録時 (2026 年序盤) に新規 ADR として ADR-038 を予約のつもりで hardcode していたが、queue 滞留中に Bundle Z 系列の連続採用で `ADR-037 / 038 / 039 / 040` がすべて占有され、2026-05-16 セッションで番号 conflict が顕在化 (ADR-041 へ振り直し)。さらに 2026-05-22 に順位 139 (PR #168 follow-up) が ADR-041 を取得したため順位 78 を再 placeholder 化 = **同一 entry が 3 回 (038 → 041 → NNN) 番号変更を経た実証ベース**で、queue 深度と滞留期間の積に比例して同型 conflict が再発する構造リスクを convention で予防する必要がある。 -> -> **本タスクの位置づけ**: 順位 78 振り直し対応の **再発防止 convention**。採番予約簿 (`docs/adr/RESERVED.md` 等) は管理コストが過剰なため見送り、entry 登録時は placeholder で済ませて land 時の PR で空き番号を確定する運用に統一する (作業着手時に採番するだけの軽量運用、ユーザー判断 2026-05-16)。 -> -> **参照**: 順位 78 entry ([docs/todo5.md](todo5.md) § ADR-NNN Rust timestamp arithmetic safety + CLAUDE.md security 拡充)、`~/.claude/rules/common/docs-governance.md` -> -> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule に 2-3 行追記。 - -#### 設計決定 (案) - -- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Document Lifecycle Classification` 周辺、もしくは新規 `## ADR 採番の運用` section -- **追記内容案** (2-3 行): - - todo entry / planning markdown で新規 ADR を予告する際は、番号を hardcode せず **`ADR-NNN (採番未確定、land 時に確定)`** placeholder で記述する - - land 時の PR で `docs/adr/` を確認し空き番号を確定。同時に当該 entry / markdown / table 内の placeholder を実番号に置換 - - 採番予約簿の運用は行わない (queue 滞留 entry の管理コストが回収可能性に見合わない) -- **本タスクの効果**: queue 滞留 entry が後発 PR の採番と衝突する構造リスクを convention で予防、作業着手時の軽量採番で十分運用可能 - -#### 作業計画 - -- [ ] `~/.claude/rules/common/docs-governance.md` に上記 placeholder 採用方針を 2-3 行追記 -- [ ] 既存 todo entries 内に他の hardcode された ADR 予告番号が残っていないか `grep -rn 'ADR-[0-9]\+ (新規)' docs/` 等で確認 (順位 78 振り直し後の漏れ検出) -- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- `docs-governance.md` に ADR 番号 hardcode 撤廃方針が明記される -- 将来 todo entry で新規 ADR を予告する際に placeholder 形式が convention として参照可能 -- 既存 todo に他の hardcode 予告番号が残っていないことが grep で確認される - -#### 詰まっている箇所 - -- ルール追加自体は機械検知不可だが、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + 簡素な代替手順を提示。grep ベースの後付け検証も容易 (`grep -nE 'ADR-[0-9]+ \(新規\)' docs/`) - ---- - -### ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment (PR #169 T3-#2 採用) - -> **動機**: 順位 135 で codify された「ADR 番号は entry 登録時に hardcode せず `ADR-NNN (採番未確定)` placeholder で記述し、land 時 PR で空き番号を確定する」運用が、PR #111 / PR #132 / PR #169 の **3+ PR で適用実証済**になった。特に PR #169 では同一 entry (順位 78) が `ADR-038 → 041 → NNN` の **3 段振り直し** を経た live dogfood が完了し、queue 滞留 entry と後発 PR の採番衝突を convention 層で完全予防できる状態が確立された。現在 policy は `~/.claude/rules/common/docs-governance.md` の 2-3 行追記として ephemeral todo (順位 135) 内で codify されているが、ephemeral artifact 限りでは派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への transferability に欠ける。正式 ADR に昇格して永続化する。 -> -> **本タスクの位置づけ**: PR #169 post-merge-feedback Tier 3 #2 採用。`feedback_no_unenforced_rules.md` の例外 = 既存実践 (3 PR で実証済) の明文化 + multi-PR race-freedom rationale + history の codify。Severity Low / **Frequency Medium (PR #111/#132/#169 の 3+ PR で適用実証)** / Effort S / Adoption Risk None。 -> -> **参照**: `.claude/feedback-reports/169.md` Tier 3 #2、順位 135 entry (`docs/todo8.md` 内、本 ADR 昇格後に retire 候補)、`~/.claude/rules/common/docs-governance.md` (現状 codify 先)、PR #111 / PR #132 / PR #169 history -> -> **実行優先度**: 💎 **Tier 3** — Effort S。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記 + 順位 135 entry retire (= todo8.md から削除)。 - -#### ADR 番号 - -順位 135 codified policy 自身に従い、本 entry では番号を `ADR-NNN (採番未確定)` placeholder とする (= dogfood 自己適用)。**land 時 PR で空き番号を確定**する (現時点既存: ADR-041 まで確定、ADR-NNN slot は順位 78 で「Rust timestamp arithmetic safety」用に予約中)。本 entry が順位 78 より先に land する場合は次の空き番号を本件に割り当て、順位 78 の placeholder は維持。 - -#### 設計決定 (案) - -- **ADR タイトル候補**: `ADR-NNN: ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment` (内容を反映、派生プロジェクトでも理解可能な英文タイトル) -- **内容構成**: - - **コンテキスト**: queue 滞留 entry の ADR 番号 hardcode が後発 PR の採番と衝突する構造リスク。PR #111/#132/#169 の history (順位 78 が `ADR-038 → 041 → NNN` の 3 段振り直しを経た live dogfood) - - **決定**: ① entry 登録時は `ADR-NNN (採番未確定、land 時に確定)` placeholder で記述、② land 時 PR で `docs/adr/` の空き番号を確定、③ 同一 PR で当該 entry / markdown / table 内 placeholder を実番号に同時置換、④ 採番予約簿 (`RESERVED.md` 等) は導入しない (queue 滞留 entry の管理コストが回収可能性に見合わない) - - **帰結**: queue 滞留期間と queue 深度の積に比例する番号衝突リスクが convention 層で予防される。派生プロジェクトでも同 policy を採用すれば multi-PR race-freedom が確保される。コスト: entry 著者は placeholder を維持する規律が必要、land 時 PR では multi-point sync (todo + ADR + CLAUDE.md) を同 commit で揃える必要 - - **適用範囲**: 全 ADR (試験運用 / 永続採用問わず)。既存 ADR (ADR-001〜ADR-041) には遡及適用しない - - **既存資料との関係**: `~/.claude/rules/common/docs-governance.md` の 2-3 行追記 (順位 135 で codified 予定) を ADR で補完する layer。global rule は entry author への 1-line guidance、ADR は派生プロジェクトを含む reference layer -- **CLAUDE.md ADR list 追加**: project-local の Architecture Decisions list に link 追記 -- **順位 135 entry retire**: 本 ADR で内容を完全 codify した時点で順位 135 を todo8.md から削除 (ephemeral → permanent への migration、`feedback_todo_no_history` 適用) - -#### 作業計画 - -- [ ] `docs/adr/adr-NNN-adr-numbering-strategy.md` を新規作成 (番号は land 時 PR で確定) -- [ ] 内容構成 (上記 5 項目) を記述 -- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 (番号確定時) -- [ ] 順位 135 entry を todo8.md から削除 (本 ADR が retire 先になる) -- [ ] PR description で `docs/adr/adr-NNN-adr-numbering-strategy.md` への link と「順位 135 内容を permanent ADR に migrate、派生プロジェクト transferability 確保」要約を明記 (PR 作成時) - -#### 完了基準 - -- ADR ファイルが新規作成され、PR #111/#132/#169 の history + placeholder policy + multi-PR race-freedom rationale が記述される -- CLAUDE.md の ADR リストに該当 entry が追加される -- 順位 135 entry が todo8.md から削除される -- 次回 ADR 採番が必要な entry を書く際の reference として global rule (docs-governance.md) から本 ADR にリンク可能になる - -#### 詰まっている箇所 - -なし。記述のみで実装変更不要。順位 135 と内容重複しないよう「global rule = 1-line entry author guidance / ADR = full rationale + history + transferability」で役割分離を明示する。 - ---- - - -### 複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171 - -> **動機**: PR #151 (`byte_offset_to_line` char-boundary panic 発見) + PR #171 (`build_violation_json` defensive test 追加) の 2 PR 横断で multi-byte content fixture を手動で組み立てるコストが顕在化。Japanese / emoji / combining chars の各 sample を helper として標準化することで、新規 string-processing 関数追加時の boundary test 実装コストを低減し silent regression を early detection できる。 -> -> **本タスクの位置づけ**: PR #171 post-merge-feedback Tier 2 #4 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。Bundle 171 のコア (順位 142 ADR-041 補強 + 順位 144 jj hook と同 PR で land 推奨)。 -> -> **参照**: `.claude/feedback-reports/171.md` Tier 2 #4、`src/hooks-post-tool-linter/src/main.rs` (`run_custom_rules_line_number_correct_with_multibyte_content` を helper 化対象)、PR #151 / PR #171 -> -> **実行優先度**: 🔧 **Tier 2** — Effort S。Bundle 171 ペアタスク。 - -#### 設計決定 (案) - -- **helper API** (3 関数): - - `multibyte_fixture_japanese() -> &'static str` — 3 bytes/char (例: `// 日本語コメント`) - - `multibyte_fixture_emoji() -> &'static str` — 4 bytes/char (例: `// 🦀 rust`) - - `multibyte_fixture_combining() -> &'static str` — e + U+0301 結合文字 (例: `// caf\u{00e9}`) -- **配置先候補**: `src/hooks-post-tool-linter/src/main.rs` の test mod 内 (in-crate) vs 共有 test util crate (cross-crate 再利用)。本タスクでは前者を採用し、再利用ニーズが顕在化したタイミングで後者へ migrate -- **既存 test refactor**: PR #171 で追加した `run_custom_rules_line_number_correct_with_multibyte_content` を helper を呼ぶ形に書き換え - -#### 作業計画 - -- [ ] helper 配置先決定 (in-crate test mod を優先採用) -- [ ] 3 helper 関数を実装 (Japanese / emoji / combining) -- [ ] PR #171 で追加した既存 test を helper を使う形に refactor -- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 考慮 (in-crate なら porting 容易) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- 3 helper 関数が公開され、test mod 内から呼べる -- 既存 test の refactor 完了 (動作不変、`cargo test` pass) -- 新規 string-processing 関数追加時に 1 行で multi-byte boundary test を書ける状態になる - -#### 詰まっている箇所 - -なし。Effort S、Bundle 171 内で 順位 142 + 順位 144 と並列実施可能。 - ---- - -### preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用) - -> **動機**: PR #172 で `jj-message-required` preset 実装の Phase 3 において、当初 `is_blocked("jj new")` (default config 使用) で block を assert する test を書いたが、`jj-message-required` が `default_preset_names()` の fallback list に含まれない opt-in preset であることを前提とせず、test rewrite が必要になった。preset architecture の implicit assumption (always-enabled vs config-selectable) を test 設計レベルで codify することで、将来の新 preset 追加時の design misalignment を構造的に防止する。 -> -> **本タスクの位置づけ**: PR #172 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。matrix test で preset 分類を明示する mechanical enforcement 層を追加。 -> -> **参照**: `.claude/feedback-reports/172.md` Tier 2 #1、`src/hooks-pre-tool-validate/src/main.rs` の `default_preset_names()` + test module、PR #172 Phase 3 (test rewrite 経緯) -> -> **実行優先度**: 🔧 **Tier 2** — Effort M。Bundle 171 残タスク (順位 142 + 143) との並列実施可能。 - -#### 設計決定 (案) - -- **配置先**: `src/hooks-pre-tool-validate/src/main.rs` の test module (feedback report は lib.rs と記載するが本 crate は binary crate のため main.rs を採用) -- **matrix 構成** (2 軸): - - axis 1: `default fallback (always-enabled)` vs `config-selectable (opt-in)` - - axis 2: 各 preset 名 -- **classification 期待値** (本セッション時点): - - always-enabled (`default_preset_names()` 内): `default` / `git` / `jj-immutable` / `jj-main-guard` / `jj-push-guard` / `electron` - - config-selectable: `gh-pr-create-guard` / `gh-pr-merge-guard` / `polling-anti-pattern` / `exe-help-block` / `jj-message-required` -- **test 案**: - - `preset_default_fallback_classification`: 各 always-enabled preset 名が `default_preset_names()` の return に含まれることを assert - - `preset_config_selectable_opt_in_classification`: 各 config-selectable preset 名が `default_preset_names()` に含まれないことを assert - - `preset_matrix_full_coverage`: 既知 preset 名の全集合が classification 表 (always-enabled ∪ config-selectable) と一致することを assert (= 新 preset 追加時に matrix 更新を強制) - -#### 作業計画 - -- [ ] preset 分類表を const として定義 (`ALWAYS_ENABLED_PRESETS` + `CONFIG_SELECTABLE_PRESETS`) -- [ ] matrix test 関数 3 件追加 (default fallback / config-selectable / full coverage) -- [ ] 既存 test (`default_config_enables_all_presets` / `jj_message_required_not_in_default_fallback_is_opt_in` 等) との重複整理 (削除 or matrix への移行) -- [ ] `resolve_preset_or_custom` の dispatch arm 列挙との整合性確認 (matrix の preset 名 = dispatch arm 名) -- [ ] 派生プロジェクト transferability 考慮 (porting 時に preset 分類を即把握できる) -- [ ] 本エントリ削除 + todo-summary.md 行削除 - -#### 完了基準 - -- preset の分類 (always-enabled vs config-selectable) が test レベルで codify される -- 将来の新 preset 追加時に classification 表を更新せざるを得ない構造になり、design misalignment が構造的に検出される -- 既存 test (158 件) との regression なし -- `resolve_preset_or_custom` の arm 列挙との不整合 (preset 追加忘れ等) が test で catch される - -#### 詰まっている箇所 - -- feedback report は target を `src/hooks-pre-tool-validate/src/lib.rs` と記載するが、本 crate は binary crate (main.rs のみ) で lib.rs は存在しない → main.rs を採用 (target 是正) -- 「config-selectable preset 名が default に含まれない」test は `jj_message_required_not_in_default_fallback_is_opt_in` で 1 件既存。matrix 化で全 5 preset に拡張する - ---- - -## 既知課題 (記録のみ、本セッションで未対応) - -### post-merge-feedback workflow が長時間 stale marker を残す問題 (PR #119 marker observed 2026-05-15) - -> **観測**: 2026-05-15 セッション開始時、`.claude/feedback-reports/119.md.failed` marker が **606,269 秒 (約 7 日)** 経過した状態で UserPromptSubmit hook により検出。PR #119 (ADR-038 Phase 5: cli-finding-classifier 統合) のマージ後に起動した post-merge-feedback workflow (run id `20260506-141736-post-merge-feedback-for-119`) が abrupt 終了 (kill -9 / SIGKILL / power loss / OOM 等) で中断され、Drop guard 経路を経由せず orphan reaper の 1500 秒閾値も大幅に超過した state で marker が残存。 -> -> **解釈**: 単発事象として記録のみ留め、即時手動 recovery (`pnpm exec takt -w post-merge-feedback -t 'post-merge-feedback for #119'`) は実施しない (PR #119 は 7 日前 land 済で、対応するレビュー知見は後続 PR で既に消化済の可能性が高い)。次回 stale marker の自然 cleanup 機構 (ADR-030 §L2 orphan reaper / D-7 / 順位 64) の dogfood で本 marker も同時に reap されるかを観察する材料として残す。 -> -> **本タスクの位置づけ**: **既知課題のみ、todo 着手は予定なし**。merge pipeline の長期化 / abrupt 終了が原因と推定されるが、systemic な再発 (Frequency Medium 以上) を確認するまで実装側の改修は scope 外。Bundle c-1 (PR #154、L1 Drop guard + L2 reaper) で recovery 機構自体は実装済のため、本 marker は単に「reaper 投入前に取り残された artifact」として扱う。 -> -> **参照**: `.claude/feedback-reports/119.md.failed`、ADR-030 §L1/L2 spec、Bundle c-1 (PR #154、L2 orphan reaper の本セッションでの初回完全 dogfood) - -#### 想定される追加観察項目 (Frequency が上がった場合に着手) - -- abrupt 終了 (Drop guard 不発) の root cause: takt subprocess 階層のどこで SIGKILL が起きたか (cli-merge-pipeline / takt 本体 / Claude Code session 終了 etc.) の事後 forensic -- L2 orphan reaper が古い marker をどう扱うか (immediate cleanup vs warn-only vs leave alone) の policy 評価 -- 7 日経過 marker を Claude Code セッション開始時に毎回提示するべきか (UserPromptSubmit hook の signal-to-noise) の検討 - ---- +# TODO (Part 8) + +> **運用ルール** ([docs/todo.md](todo.md) と同一): 各タスクには **やろうとしたこと / 現在地 / 詰まっている箇所** を必ず書く。完了タスクは ADR か仕組みに反映後、このファイルから削除する。過去の経緯は git log で追跡可能。 +> +> **本ファイルの位置付け**: docs/todo6.md がファイルサイズ 50KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して PR #143 T3-#1 採用時 = 2026-05-11 から新規エントリは本ファイルに記録していた。**本ファイルも 60KB に到達したため、PR #172 仕組み化方針切替セッション = 2026-05-25 以降の新規エントリは [docs/todo9.md](todo9.md) へ移行**。本ファイルは既存タスクの編集・完了削除専用。todo.md / todo2.md / todo3.md / todo4.md / todo5.md / todo6.md / todo7.md / todo9.md の既存エントリは引き続き有効、相互に独立。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 +> +> **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。 + +--- + +## 現在進行中 + +### rule⑧ への paths filter 適用範囲検討 (順位 102 land 時に意図的保留、follow-up) + +> **動機**: 順位 102 (PR #148 想定で land 中、Phase D D-3) で paths filter が lint runner に実装されたが、当初計画した rule⑧ への `paths = ["docs/**/*.md"]` migration は **意図的に保留**。理由: D-2 (PR #146、順位 101) で追加した「root-level MD (CLAUDE.md / README.md) からの `../docs/` 参照を fire = true positive で扱う」design intent が、`paths = ["docs/**/*.md"]` 適用で scope narrow されて壊れる (root-level MD の実 path が docs/ 配下ではないため rule 対象外になり、broken link 検出を失う)。本タスクで以下のいずれを採用するか検討する: +> +> 1. **保留継続** (現状維持): rule⑧ は `extensions = ["md"]` のみで run、root-level fire を保護 +> 2. **broader glob**: `paths = ["**/*.md"]` で全 .md 受容 (= extensions filter と機能的同等、demonstration 用途) +> 3. **explicit list**: `paths = ["docs/**/*.md", "*.md", ".claude/**/*.md"]` で docs/ + root + .claude/ をカバー +> 4. **rule split**: rule⑧-docs (docs/ scope) + rule⑧-root (root scope) に分割 +> +> **本タスクの位置づけ**: 順位 102 follow-up (Severity Low / Frequency Low = 1 観測 / Effort XS / Adoption Risk None)。実 production lint behavior に影響しない range で trade-off 評価。 +> +> **参照**: PR #148 (順位 102 land) の TOML rule⑧ コメント、PR #146 (D-2、順位 101) の `md_no_docs_relative_detects_root_*` tests + +#### 作業計画 + +- [ ] 4 案の trade-off を ADR-007 amendment (順位 104) と整合させて評価 +- [ ] 採用案を `.claude/custom-lint-rules.toml` rule⑧ に適用 (案 1 保留継続なら no-op だが、本エントリ削除で結論明示) +- [ ] 既存 test (`md_no_docs_relative_*` group) との整合性確認 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- rule⑧ scope の設計判断が ADR-007 amendment と本タスク entry で明確化される +- 同型 trade-off (filter scope narrow vs coverage 保持) を将来 rule 追加時に逆引きできる + +--- + +### `coding-style.md § Cross-File Reference Lifecycle` に「ephemeral → permanent 知識移管 edit order」追記 (PR #145 T3-#3 採用) + +> **動機**: PR #145 で lib.rs L128-139 dogfood evolution コメントを ADR-040 に migrate した際、edit 順序が曖昧だった (ADR-040 を先に作るべきか、lib.rs 側の参照削除を先にすべきか)。同パターンが (1) lib.rs コメント → ADR-040、(2) Phase C/D empirical data → ADR-040 で 2 回観測。既存の Cross-File Reference Lifecycle ルール は「参照方向の制約」(permanent → ephemeral 禁止) に特化しており、移管作業の edit order checklist は complementary で重複なし。次回同型の永続化作業 (ephemeral 計画書 retire 時の permanent value 移管 等) で再発防止策として codify する。 +> +> **本タスクの位置づけ**: PR #145 post-merge-feedback Tier 3 #3 採用 (Severity Low / Frequency Medium / Effort S / Adoption Risk None)。 +> +> **参照**: `.claude/feedback-reports/145.md` Tier 3 #3、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle + +#### 提案する 3 ステップ原則 + +1. **permanent target 先行作成・validate**: 移管先の permanent artifact (ADR / stable docs) を先に作成し、内容の正確性 (cross-reference の妥当性 / 数値整合性 / markdownlint pass) を確認 +2. **参照追加**: ephemeral 側 (lib.rs コメント / config コメント / scratch markdown 等) から permanent への参照 link を追加 (1-2 行) +3. **参照元削除**: ephemeral 側の冗長な内容を削除し、参照 link のみ残す。同一 commit で 3 step すべてを実施 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle 末尾に「ephemeral → permanent 知識移管 edit order」 subsection を追加 +- [ ] 3 ステップ原則を inline で記述、PR #145 (lib.rs L128-139 → ADR-040) を実例として cite +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 計画も検討 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回 permanent 化作業時に edit order が決定論的に決まる +- ephemeral 計画書 retire 時の permanent value 移管プロセスが checklist 化される + +--- + +### CLAUDE.md § Cross-File Reference Lifecycle に多ファイル同時削除 retirement condition checklist を追加 (PR #153 T3-#2 採用) + +> **動機**: PR #153 で旧 `docs/local-llm-offload-analysis.md` を `phase-d-outcomes.md` に分割した際 (3 ファイルは Phase E 採用昇格 = 2026-05-15 に retire 済)、retirement clause を **3 ファイル (analysis.md / history.md / phase-d-outcomes.md) 同時削除** に統一する作業が developer/AI の手動 review でしか担保されていなかった。advisor 指摘で明示的に「3 ファイルすべてに同じ retirement clause を書く」ステップを踏んだが、これは structural pattern として再利用可能 (今後の docs/* 50KB 分割でも同じ checklist が必要)。同パターンが drift すると ephemeral artifact の lifecycle 整合が崩れ、stale pointer が増殖するリスクあり。 +> +> **本タスクの位置づけ**: PR #153 post-merge-feedback Tier 3 #2 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。**既存実践 (PR #133 todo.md 分割 + PR #153 analysis.md 分割) の明文化 + 機械強制ではなく guide 効果** のため、`feedback_no_unenforced_rules.md` の例外条件 (順位 122 / 127 と同じロジック) を満たす。 +> +> **参照**: `.claude/feedback-reports/153.md` Tier 3 #2、`~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle、`~/.claude/rules/common/docs-governance.md` § Retirement Workflow + +#### 作業計画 + +- [ ] `~/.claude/rules/common/coding-style.md` § Cross-File Reference Lifecycle に「多ファイル同時削除時の retirement condition consistency checklist」section を追加 (3-5 項目程度の bullet list) + - 「N ファイルを同時削除する設計の場合、全 N ファイルの header に同一の retirement clause が記載されているか」 + - 「retirement workflow の Step 3 (参照更新) で `grep -rn ''` を全ファイル分実施したか」 + - 「新ファイル追加時に既存ファイルの retirement clause にも追記したか」 + - 「参照先 (ADR / docs-governance.md) が permanent artifact であることを確認」 +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 +- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回多ファイル分割 (例: history.md 50KB 接近時) で同 checklist を踏むことで drift が構造的に防止される +- PR #133 (todo.md 分割) / PR #153 (analysis.md 分割) の successful pattern が明文化され、3 例目以降の reproducibility が確保される + +--- + +### docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = 必ず grep で実ファイル確認」を明記 (PR #156 T3 #1 採用) + +> **動機**: PR #156 で ephemeral 4 ファイル retire を実施した際、`grep` 結果に含まれる **diff context 行が実ファイルの最新内容ではなく PR 直前の状態を反映する** ため、削除対象ファイルへの参照が「残存」と誤検出される false alarm が 5 件以上発生。fact-check の grep 実行に時間を要した。XS の文言追加で将来セッションの reviewer / Claude が同一の確認コストを繰り返すことを防止できる。ephemeral 退役ワークフローは今後も繰り返されるため Frequency Medium。 +> +> **本タスクの位置づけ**: PR #156 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。`feedback_no_unenforced_rules.md` 例外条件 = 既存実践の明文化 + guide 効果のため採用 (順位 122 / 127 と同じロジック)。 +> +> **参照**: `.claude/feedback-reports/156.md` Tier 3 #1、`~/.claude/rules/common/docs-governance.md` §Retirement Workflow + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` §Retirement Workflow の Step 3 (参照更新) に「diff context 由来 false alarm 防止」note 追加 (2-3 行) + - 「`grep -rn ''` で hit した参照は **必ず該当ファイルを Read で開き、最新内容に対象参照が実在することを確認** する。diff context は PR 直前の旧状態を反映するため、retire 対象ファイルへの参照が context として残存しているように見えても、現行 working copy では既に削除されている場合がある」 + - 具体例: PR #156 (4 ファイル同時 retire) で 5 件以上の false alarm が発生 +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) は `~/.claude/` global 配下なので自動波及 +- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 次回 ephemeral 退役 workflow で同 false alarm が発生しても、明文化された手順により fact-check の認知コストが低減する +- guide として PR review / Claude session 双方で参照可能 + +#### 詰まっている箇所 + +なし。Effort XS、global rule への追記のみで副作用最小。 + +--- + +### todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来) + +> **動機**: 順位 78 (旧 ADR-038 Rust timestamp arithmetic safety、PR #115 T3-1) は entry 登録時 (2026 年序盤) に新規 ADR として ADR-038 を予約のつもりで hardcode していたが、queue 滞留中に Bundle Z 系列の連続採用で `ADR-037 / 038 / 039 / 040` がすべて占有され、2026-05-16 セッションで番号 conflict が顕在化 (ADR-041 へ振り直し)。さらに 2026-05-22 に順位 139 (PR #168 follow-up) が ADR-041 を取得したため順位 78 を再 placeholder 化 = **同一 entry が 3 回 (038 → 041 → NNN) 番号変更を経た実証ベース**で、queue 深度と滞留期間の積に比例して同型 conflict が再発する構造リスクを convention で予防する必要がある。 +> +> **本タスクの位置づけ**: 順位 78 振り直し対応の **再発防止 convention**。採番予約簿 (`docs/adr/RESERVED.md` 等) は管理コストが過剰なため見送り、entry 登録時は placeholder で済ませて land 時の PR で空き番号を確定する運用に統一する (作業着手時に採番するだけの軽量運用、ユーザー判断 2026-05-16)。 +> +> **参照**: 順位 78 entry ([docs/todo5.md](todo5.md) § ADR-NNN Rust timestamp arithmetic safety + CLAUDE.md security 拡充)、`~/.claude/rules/common/docs-governance.md` +> +> **実行優先度**: 💎 **Tier 3** — Effort XS。global rule に 2-3 行追記。 + +#### 設計決定 (案) + +- **配置先**: `~/.claude/rules/common/docs-governance.md` の `## Document Lifecycle Classification` 周辺、もしくは新規 `## ADR 採番の運用` section +- **追記内容案** (2-3 行): + - todo entry / planning markdown で新規 ADR を予告する際は、番号を hardcode せず **`ADR-NNN (採番未確定、land 時に確定)`** placeholder で記述する + - land 時の PR で `docs/adr/` を確認し空き番号を確定。同時に当該 entry / markdown / table 内の placeholder を実番号に置換 + - 採番予約簿の運用は行わない (queue 滞留 entry の管理コストが回収可能性に見合わない) +- **本タスクの効果**: queue 滞留 entry が後発 PR の採番と衝突する構造リスクを convention で予防、作業着手時の軽量採番で十分運用可能 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/docs-governance.md` に上記 placeholder 採用方針を 2-3 行追記 +- [ ] 既存 todo entries 内に他の hardcode された ADR 予告番号が残っていないか `grep -rn 'ADR-[0-9]\+ (新規)' docs/` 等で確認 (順位 78 振り直し後の漏れ検出) +- [ ] 派生プロジェクト deploy には影響なし (global rule のみ) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `docs-governance.md` に ADR 番号 hardcode 撤廃方針が明記される +- 将来 todo entry で新規 ADR を予告する際に placeholder 形式が convention として参照可能 +- 既存 todo に他の hardcode 予告番号が残っていないことが grep で確認される + +#### 詰まっている箇所 + +- ルール追加自体は機械検知不可だが、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + 簡素な代替手順を提示。grep ベースの後付け検証も容易 (`grep -nE 'ADR-[0-9]+ \(新規\)' docs/`) + +--- + +### ADR-NNN (採番未確定、land 時に確定): ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment (PR #169 T3-#2 採用) + +> **動機**: 順位 135 で codify された「ADR 番号は entry 登録時に hardcode せず `ADR-NNN (採番未確定)` placeholder で記述し、land 時 PR で空き番号を確定する」運用が、PR #111 / PR #132 / PR #169 の **3+ PR で適用実証済**になった。特に PR #169 では同一 entry (順位 78) が `ADR-038 → 041 → NNN` の **3 段振り直し** を経た live dogfood が完了し、queue 滞留 entry と後発 PR の採番衝突を convention 層で完全予防できる状態が確立された。現在 policy は `~/.claude/rules/common/docs-governance.md` の 2-3 行追記として ephemeral todo (順位 135) 内で codify されているが、ephemeral artifact 限りでは派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への transferability に欠ける。正式 ADR に昇格して永続化する。 +> +> **本タスクの位置づけ**: PR #169 post-merge-feedback Tier 3 #2 採用。`feedback_no_unenforced_rules.md` の例外 = 既存実践 (3 PR で実証済) の明文化 + multi-PR race-freedom rationale + history の codify。Severity Low / **Frequency Medium (PR #111/#132/#169 の 3+ PR で適用実証)** / Effort S / Adoption Risk None。 +> +> **参照**: `.claude/feedback-reports/169.md` Tier 3 #2、順位 135 entry (`docs/todo8.md` 内、本 ADR 昇格後に retire 候補)、`~/.claude/rules/common/docs-governance.md` (現状 codify 先)、PR #111 / PR #132 / PR #169 history +> +> **実行優先度**: 💎 **Tier 3** — Effort S。新規 ADR 1 件作成 (記述のみ、コード変更なし) + CLAUDE.md ADR list 追記 + 順位 135 entry retire (= todo8.md から削除)。 + +#### ADR 番号 + +順位 135 codified policy 自身に従い、本 entry では番号を `ADR-NNN (採番未確定)` placeholder とする (= dogfood 自己適用)。**land 時 PR で空き番号を確定**する (現時点既存: ADR-041 まで確定、ADR-NNN slot は順位 78 で「Rust timestamp arithmetic safety」用に予約中)。本 entry が順位 78 より先に land する場合は次の空き番号を本件に割り当て、順位 78 の placeholder は維持。 + +#### 設計決定 (案) + +- **ADR タイトル候補**: `ADR-NNN: ADR Numbering Strategy — Placeholder Policy for Multi-PR Race-Free Assignment` (内容を反映、派生プロジェクトでも理解可能な英文タイトル) +- **内容構成**: + - **コンテキスト**: queue 滞留 entry の ADR 番号 hardcode が後発 PR の採番と衝突する構造リスク。PR #111/#132/#169 の history (順位 78 が `ADR-038 → 041 → NNN` の 3 段振り直しを経た live dogfood) + - **決定**: ① entry 登録時は `ADR-NNN (採番未確定、land 時に確定)` placeholder で記述、② land 時 PR で `docs/adr/` の空き番号を確定、③ 同一 PR で当該 entry / markdown / table 内 placeholder を実番号に同時置換、④ 採番予約簿 (`RESERVED.md` 等) は導入しない (queue 滞留 entry の管理コストが回収可能性に見合わない) + - **帰結**: queue 滞留期間と queue 深度の積に比例する番号衝突リスクが convention 層で予防される。派生プロジェクトでも同 policy を採用すれば multi-PR race-freedom が確保される。コスト: entry 著者は placeholder を維持する規律が必要、land 時 PR では multi-point sync (todo + ADR + CLAUDE.md) を同 commit で揃える必要 + - **適用範囲**: 全 ADR (試験運用 / 永続採用問わず)。既存 ADR (ADR-001〜ADR-041) には遡及適用しない + - **既存資料との関係**: `~/.claude/rules/common/docs-governance.md` の 2-3 行追記 (順位 135 で codified 予定) を ADR で補完する layer。global rule は entry author への 1-line guidance、ADR は派生プロジェクトを含む reference layer +- **CLAUDE.md ADR list 追加**: project-local の Architecture Decisions list に link 追記 +- **順位 135 entry retire**: 本 ADR で内容を完全 codify した時点で順位 135 を todo8.md から削除 (ephemeral → permanent への migration、`feedback_todo_no_history` 適用) + +#### 作業計画 + +- [ ] `docs/adr/adr-NNN-adr-numbering-strategy.md` を新規作成 (番号は land 時 PR で確定) +- [ ] 内容構成 (上記 5 項目) を記述 +- [ ] CLAUDE.md (project) Architecture Decisions リストに該当 ADR を追加 (番号確定時) +- [ ] 順位 135 entry を todo8.md から削除 (本 ADR が retire 先になる) +- [ ] PR description で `docs/adr/adr-NNN-adr-numbering-strategy.md` への link と「順位 135 内容を permanent ADR に migrate、派生プロジェクト transferability 確保」要約を明記 (PR 作成時) + +#### 完了基準 + +- ADR ファイルが新規作成され、PR #111/#132/#169 の history + placeholder policy + multi-PR race-freedom rationale が記述される +- CLAUDE.md の ADR リストに該当 entry が追加される +- 順位 135 entry が todo8.md から削除される +- 次回 ADR 採番が必要な entry を書く際の reference として global rule (docs-governance.md) から本 ADR にリンク可能になる + +#### 詰まっている箇所 + +なし。記述のみで実装変更不要。順位 135 と内容重複しないよう「global rule = 1-line entry author guidance / ADR = full rationale + history + transferability」で役割分離を明示する。 + +--- + + +### 複言語 fixture helper 標準化 (hooks-post-tool-linter-tests) (PR #171 T2-#4 採用) ★ Bundle 171 + +> **動機**: PR #151 (`byte_offset_to_line` char-boundary panic 発見) + PR #171 (`build_violation_json` defensive test 追加) の 2 PR 横断で multi-byte content fixture を手動で組み立てるコストが顕在化。Japanese / emoji / combining chars の各 sample を helper として標準化することで、新規 string-processing 関数追加時の boundary test 実装コストを低減し silent regression を early detection できる。 +> +> **本タスクの位置づけ**: PR #171 post-merge-feedback Tier 2 #4 採用 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。Bundle 171 のコア (順位 142 ADR-041 補強 + 順位 144 jj hook と同 PR で land 推奨)。 +> +> **参照**: `.claude/feedback-reports/171.md` Tier 2 #4、`src/hooks-post-tool-linter/src/main.rs` (`run_custom_rules_line_number_correct_with_multibyte_content` を helper 化対象)、PR #151 / PR #171 +> +> **実行優先度**: 🔧 **Tier 2** — Effort S。Bundle 171 ペアタスク。 + +#### 設計決定 (案) + +- **helper API** (3 関数): + - `multibyte_fixture_japanese() -> &'static str` — 3 bytes/char (例: `// 日本語コメント`) + - `multibyte_fixture_emoji() -> &'static str` — 4 bytes/char (例: `// 🦀 rust`) + - `multibyte_fixture_combining() -> &'static str` — e + U+0301 結合文字 (例: `// caf\u{00e9}`) +- **配置先候補**: `src/hooks-post-tool-linter/src/main.rs` の test mod 内 (in-crate) vs 共有 test util crate (cross-crate 再利用)。本タスクでは前者を採用し、再利用ニーズが顕在化したタイミングで後者へ migrate +- **既存 test refactor**: PR #171 で追加した `run_custom_rules_line_number_correct_with_multibyte_content` を helper を呼ぶ形に書き換え + +#### 作業計画 + +- [ ] helper 配置先決定 (in-crate test mod を優先採用) +- [ ] 3 helper 関数を実装 (Japanese / emoji / combining) +- [ ] PR #171 で追加した既存 test を helper を使う形に refactor +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への transferability 考慮 (in-crate なら porting 容易) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- 3 helper 関数が公開され、test mod 内から呼べる +- 既存 test の refactor 完了 (動作不変、`cargo test` pass) +- 新規 string-processing 関数追加時に 1 行で multi-byte boundary test を書ける状態になる + +#### 詰まっている箇所 + +なし。Effort S、Bundle 171 内で 順位 142 + 順位 144 と並列実施可能。 + +--- + +### preset matrix test 追加 — default fallback vs config-selectable の 2 軸 classification 検証 (PR #172 T2-#1 採用) + +> **動機**: PR #172 で `jj-message-required` preset 実装の Phase 3 において、当初 `is_blocked("jj new")` (default config 使用) で block を assert する test を書いたが、`jj-message-required` が `default_preset_names()` の fallback list に含まれない opt-in preset であることを前提とせず、test rewrite が必要になった。preset architecture の implicit assumption (always-enabled vs config-selectable) を test 設計レベルで codify することで、将来の新 preset 追加時の design misalignment を構造的に防止する。 +> +> **本タスクの位置づけ**: PR #172 post-merge-feedback Tier 2 #1 採用 (Severity Medium / Frequency Low / Effort M / Adoption Risk None)。matrix test で preset 分類を明示する mechanical enforcement 層を追加。 +> +> **参照**: `.claude/feedback-reports/172.md` Tier 2 #1、`src/hooks-pre-tool-validate/src/main.rs` の `default_preset_names()` + test module、PR #172 Phase 3 (test rewrite 経緯) +> +> **実行優先度**: 🔧 **Tier 2** — Effort M。Bundle 171 残タスク (順位 142 + 143) との並列実施可能。 + +#### 設計決定 (案) + +- **配置先**: `src/hooks-pre-tool-validate/src/main.rs` の test module (feedback report は lib.rs と記載するが本 crate は binary crate のため main.rs を採用) +- **matrix 構成** (2 軸): + - axis 1: `default fallback (always-enabled)` vs `config-selectable (opt-in)` + - axis 2: 各 preset 名 +- **classification 期待値** (本セッション時点): + - always-enabled (`default_preset_names()` 内): `default` / `git` / `jj-immutable` / `jj-main-guard` / `jj-push-guard` / `electron` + - config-selectable: `gh-pr-create-guard` / `gh-pr-merge-guard` / `polling-anti-pattern` / `exe-help-block` / `jj-message-required` +- **test 案**: + - `preset_default_fallback_classification`: 各 always-enabled preset 名が `default_preset_names()` の return に含まれることを assert + - `preset_config_selectable_opt_in_classification`: 各 config-selectable preset 名が `default_preset_names()` に含まれないことを assert + - `preset_matrix_full_coverage`: 既知 preset 名の全集合が classification 表 (always-enabled ∪ config-selectable) と一致することを assert (= 新 preset 追加時に matrix 更新を強制) + +#### 作業計画 + +- [ ] preset 分類表を const として定義 (`ALWAYS_ENABLED_PRESETS` + `CONFIG_SELECTABLE_PRESETS`) +- [ ] matrix test 関数 3 件追加 (default fallback / config-selectable / full coverage) +- [ ] 既存 test (`default_config_enables_all_presets` / `jj_message_required_not_in_default_fallback_is_opt_in` 等) との重複整理 (削除 or matrix への移行) +- [ ] `resolve_preset_or_custom` の dispatch arm 列挙との整合性確認 (matrix の preset 名 = dispatch arm 名) +- [ ] 派生プロジェクト transferability 考慮 (porting 時に preset 分類を即把握できる) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- preset の分類 (always-enabled vs config-selectable) が test レベルで codify される +- 将来の新 preset 追加時に classification 表を更新せざるを得ない構造になり、design misalignment が構造的に検出される +- 既存 test (158 件) との regression なし +- `resolve_preset_or_custom` の arm 列挙との不整合 (preset 追加忘れ等) が test で catch される + +#### 詰まっている箇所 + +- feedback report は target を `src/hooks-pre-tool-validate/src/lib.rs` と記載するが、本 crate は binary crate (main.rs のみ) で lib.rs は存在しない → main.rs を採用 (target 是正) +- 「config-selectable preset 名が default に含まれない」test は `jj_message_required_not_in_default_fallback_is_opt_in` で 1 件既存。matrix 化で全 5 preset に拡張する + +--- + +## 既知課題 (記録のみ、本セッションで未対応) + +### post-merge-feedback workflow が長時間 stale marker を残す問題 (PR #119 marker observed 2026-05-15) + +> **観測**: 2026-05-15 セッション開始時、`.claude/feedback-reports/119.md.failed` marker が **606,269 秒 (約 7 日)** 経過した状態で UserPromptSubmit hook により検出。PR #119 (ADR-038 Phase 5: cli-finding-classifier 統合) のマージ後に起動した post-merge-feedback workflow (run id `20260506-141736-post-merge-feedback-for-119`) が abrupt 終了 (kill -9 / SIGKILL / power loss / OOM 等) で中断され、Drop guard 経路を経由せず orphan reaper の 1500 秒閾値も大幅に超過した state で marker が残存。 +> +> **解釈**: 単発事象として記録のみ留め、即時手動 recovery (`pnpm exec takt -w post-merge-feedback -t 'post-merge-feedback for #119'`) は実施しない (PR #119 は 7 日前 land 済で、対応するレビュー知見は後続 PR で既に消化済の可能性が高い)。次回 stale marker の自然 cleanup 機構 (ADR-030 §L2 orphan reaper / D-7 / 順位 64) の dogfood で本 marker も同時に reap されるかを観察する材料として残す。 +> +> **本タスクの位置づけ**: **既知課題のみ、todo 着手は予定なし**。merge pipeline の長期化 / abrupt 終了が原因と推定されるが、systemic な再発 (Frequency Medium 以上) を確認するまで実装側の改修は scope 外。Bundle c-1 (PR #154、L1 Drop guard + L2 reaper) で recovery 機構自体は実装済のため、本 marker は単に「reaper 投入前に取り残された artifact」として扱う。 +> +> **参照**: `.claude/feedback-reports/119.md.failed`、ADR-030 §L1/L2 spec、Bundle c-1 (PR #154、L2 orphan reaper の本セッションでの初回完全 dogfood) + +#### 想定される追加観察項目 (Frequency が上がった場合に着手) + +- abrupt 終了 (Drop guard 不発) の root cause: takt subprocess 階層のどこで SIGKILL が起きたか (cli-merge-pipeline / takt 本体 / Claude Code session 終了 etc.) の事後 forensic +- L2 orphan reaper が古い marker をどう扱うか (immediate cleanup vs warn-only vs leave alone) の policy 評価 +- 7 日経過 marker を Claude Code セッション開始時に毎回提示するべきか (UserPromptSubmit hook の signal-to-noise) の検討 + +--- diff --git a/docs/todo9.md b/docs/todo9.md index 74d59a29..d4606b09 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-11.md / todo-summary.md)。 +> **本ファイルの位置付け**: docs/todo8.md がファイルサイズ 60KB に到達したため、Claude Code の読み取り安定性 (50KB 超で不安定化) を考慮して新規エントリは本ファイルに記録する (PR #172 仕組み化方針切替セッション = 2026-05-25)。todo.md / todo2.md 〜 todo8.md の既存エントリは引き続き有効、相互に独立。**2026-06-06 分割**: 本ファイルが 75KB / 890 行に到達したため、PR-specific follow-up entries (順位 157, 160-173) を [docs/todo11.md](todo11.md) に分離。残置: 既存ルール仕組み化バンドル (順位 146-151) + 週次レビュー拡張 (順位 152-154)。新セッションでは十三つすべてを確認すること (todo.md / todo2-12.md / todo-summary.md)。 > > **推奨実行順序**: 全タスク横断のサマリーは [docs/todo-summary.md](todo-summary.md#recommended-order-summary) を参照。