diff --git a/docs/todo-summary.md b/docs/todo-summary.md index 2d0d73a..0de6da9 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -76,6 +76,8 @@ | 134 | 💎 Tier 3 | **ADR-035 に docs-only PR 評価の適用外基準リスト追加 (mutation / error handling / DRY / YAGNI / function length / test coverage / magic-number 等) (PR #156 T3 #2 採用)** | todo8.md | S | なし (Severity Medium = reviewer の criteria 誤適用による unnecessary review overhead / 開発体験劣化、ADR-035 は分類基準のみ定義済で適用外基準が未明示、`feedback_no_unenforced_rules.md` 例外 = ADR への追加で機械強制ではなく reviewer / Claude の judgment 補助) | | 135 | 💎 Tier 3 | **todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来)** | todo8.md | XS | なし (順位 78 (旧 ADR-038 → ADR-041) で番号 conflict が顕在化、queue 滞留 entry の hardcode が後発 PR の採番と衝突する構造リスクを convention で予防、`~/.claude/rules/common/docs-governance.md` に 2-3 行追記。採番予約簿は管理コスト過剰のため見送り、land 時 PR で空き番号確定の軽量運用に統一) | | 136 | 🚀 Tier 1 | **working copy staleness 検出 hook 2 段構え: SessionStart (jj git fetch + lineage 報告) + PreToolUse (stale 時 docs/todo*.md edit block) — 本セッション cleanup-stale-rank-39 由来** | todo8.md | M | なし (本セッションで実証された「stale parent で docs/todo*.md 読込 → 既削除 entry を再度削除提案」failure mode の structural enforcement。Claude Code Web 並列セッション運用前提下で再発確実。`feedback_no_unenforced_rules.md` 例外 = 2 つの hook で機械強制可能、案 A 予防層 + 案 B 最終 backstop の二段構え、ADR-039 experimental pattern 適用) | +| 137 | 🚀 Tier 1 | **Rule-Test Coverage Check Cargo test — `.claude/custom-lint-rules.toml` の extensions ⇔ `src/hooks-post-tool-linter/src/main.rs` test 関数名 mechanical 検証 (PR #163 T1-#1 採用)** | todo8.md | M | なし (PR #110/#151/#152/#155 4 PR 観測 = Frequency High、PR #163 順位 127 で passive reminder comment を追加したが analyzer が「PR #152 同根再発を防止できなかった実証ベース → mechanical enforcement が必要」と判定、`feedback_no_unenforced_rules.md` 原則 = 機械検知なら active enforcement layer のみが防止層として有効) | +| 138 | 💎 Tier 3 | **Rule Extension Test Pattern を `~/.claude/rules/common/testing.md` に明文化 (PR #163 T3-#1 採用)** | todo8.md | XS | なし (PR #151/#152/#163 で確立した pattern の canonical 文書化、`~/.claude/` global 配下のため派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ自動波及、順位 137 = mechanical layer の 2 層構成として運用、Frequency High = 4 PR 観測で ROI 確認済) | **戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 diff --git a/docs/todo8.md b/docs/todo8.md index b608f0d..a58d11b 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -388,6 +388,94 @@ --- +### Rule-Test Coverage Check Cargo test — extensions ⇔ test 関数名 mechanical 検証 (PR #163 T1-#1 採用) + +> **動機**: PR #110 (yaml/yml 追加 → test gap) / PR #151 (toml 検出力 test gap) / PR #152 (.md FP 再現) / PR #155 (Bundle k-1 で structural fix) の 4 PR で「extensions 変更時に対応 test が追加されない」pattern が累積観測 (Frequency High = 3 PR 連続観測閾値超過)。 +> +> PR #163 で順位 127 として passive reminder comment (`.claude/custom-lint-rules.toml` rule⑥ 上に「extensions 変更時 test 追加義務」記載) を追加したが、本 PR の post-merge-feedback analyzer は「passive reminder では PR #152 同根再発を防止できなかった実証ベース → mechanical enforcement が必要」と判定。`feedback_no_unenforced_rules.md` 原則 (機械検知できなければ何もしない方がマシ) を analyzer 自身が私の comment 追加に対して適用した形。 +> +> **本タスクの位置づけ**: PR #163 post-merge-feedback Tier 1 #1 採用 (Severity Medium / Frequency High / Effort M / Adoption Risk None)。順位 127 (PR #163 で land 済の passive reminder) との相補関係: comment は point-of-edit reminder、本 cargo test は CI 層での mechanical check。順位 138 (testing.md 明文化) と同 PR land 推奨 (命名規約決定が atomic に整う)。 +> +> **参照**: `.claude/feedback-reports/163.md` Tier 1 #1、`src/hooks-post-tool-linter/src/main.rs` test module、`.claude/custom-lint-rules.toml` rule⑥ コメント + +#### 設計決定 (案) + +- **配置**: `src/hooks-post-tool-linter/src/main.rs` test module (analyzer report は `src/cli-custom-linter/src/main.rs` と記載しているが、実際の crate 名は `hooks-post-tool-linter`) +- **検証ロジック**: + 1. `.claude/custom-lint-rules.toml` を `toml::from_str` で parse + 2. 各 rule の `id` + `extensions` 配列を列挙 + 3. main.rs の test 関数名 (`fn no__detects__*` または `fn no___*` 等の規約に沿う) を静的解析または build script で抽出 + 4. 対応 test 不在の (rule, ext) ペアを列挙、空でなければ `panic!` で fail +- **検出 pattern 選択肢**: + - **案 a (命名規約方式)**: rule_id を kebab-case → snake_case 変換 (`no-ephemeral-todo-reference` → `no_ephemeral_todo_reference`)、ext を test 関数名内の suffix or prefix で確認。規約遵守に依存するが TOML schema 拡張不要 + - **案 b (TOML meta field 方式)**: rule に `[rules.test_names]` メタ field を追加して explicit 対応関係を記述。明示的だが schema 拡張あり +- **段階的導入**: 初期は warning として既存 rule 全てに対する test gap を報告のみ (ratchet 方式)、ベースライン到達後に hard fail に切り替え +- **必須カバレッジ scope**: 主要 ext = **`rs` / `toml` / `yaml`** (および `yml`) の 3+1 ext × 全 rule に対応 test 関数が存在することを必須化。その他 ext (`jsonc` / `json` / `ts` / `tsx` / `js` / `jsx` / `py` / `ps1`) は rule あたり positive single test 1 件以上で代替 (= test 関数爆発を抑制)。**この scope 決定は順位 138 (testing.md) と同一 commit で codify** することで cross-reference の atomicity を確保 + +#### 作業計画 + +- [ ] 既存 rule × 主要 ext (rs/toml/yaml) の test カバレッジを実測 (現状の test gap 把握、ベースライン確定) +- [ ] 命名規約 vs TOML meta field の trade-off 決定 (順位 138 と同 PR で確定推奨) +- [ ] Cargo test として `rule_test_coverage_check` 等の名前で実装 +- [ ] 既存 rule の test gap を test fail で発見した場合は本 PR で同時補填 (もしくは別 PR で test 追加) +- [ ] 順位 138 (`testing.md` への明文化) と命名規約 + 必須 ext scope を整合 +- [ ] 派生プロジェクト deploy 検討 (test 実装は global pattern として共有可能) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `cargo test -p hooks-post-tool-linter rule_test_coverage_check` が green = **主要 ext (`rs` / `toml` / `yaml` / `yml`) × 全 rule に対応 test 関数が存在**、その他 ext は rule あたり positive single test 1 件以上 +- 将来 extensions に新拡張子を追加した PR で、その拡張子が主要 ext かつ対応 test 不在なら pre-push の cargo test step で fail +- 順位 138 (testing.md) との cross-reference が機能 (本実装 → testing.md の規約参照、testing.md → 本実装の機械強制参照、必須 ext scope は同一 commit で codify) +- 派生プロジェクトでの動作確認 (deploy 後) + +#### 詰まっている箇所 + +- TOML meta field 方式 vs 命名規約方式 の trade-off (前者は明示的だが TOML schema 拡張、後者は規約遵守に依存) — 順位 138 と同 PR 実装時に確定推奨 + +--- + +### Rule Extension Test Pattern を `~/.claude/rules/common/testing.md` に明文化 (PR #163 T3-#1 採用) + +> **動機**: PR #151 / #152 / #163 で確立された「custom lint rule に extensions を追加 / 削除する際は同 PR で対応する positive test + negative test を追加する」pattern を、project 個別の reminder comment (`.claude/custom-lint-rules.toml` rule⑥ コメント、PR #163 順位 127 で追加済) から **global rules への canonical 文書化** に昇格する。 +> +> **本タスクの位置づけ**: PR #163 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency High = 4 PR 観測 / Effort XS / Adoption Risk None)。順位 137 (mechanical Cargo test) と 2 層構成: 本 entry は canonical 文書化 (= 規約と思想)、137 は CI 層の機械強制 (= 規約違反を fail で検出)。 +> +> 派生プロジェクト (techbook-ledger / auto-review-fix-vc) へは `~/.claude/` global 配下のため自動波及。Frequency High でドキュメント化 ROI 確認済。 +> +> **参照**: `.claude/feedback-reports/163.md` Tier 3 #1、`~/.claude/rules/common/testing.md`、`.claude/custom-lint-rules.toml` (rule⑥ コメント、PR #163 で追加済) + +#### 設計決定 (案) + +- **配置先**: `~/.claude/rules/common/testing.md` に新 section "Custom Lint Rule Test Coverage" 等を追加 +- **記述内容案** (3-5 段落): + 1. 原則: rule の extensions を変更する場合、同 PR で positive test (新拡張子で fire) と negative test (新拡張子で non-violation は fire しない) を追加 + 2. 命名規約: `no__detects__*` (positive) / `no__skips_*` (negative) — 順位 137 の mechanical check と整合 + 3. self-exclusion パターンへの注意: test fixture が rule の対象になる meta-case を回避するため `build_*_fixture` helper を介して format! interpolation で fixture を構築 (PR #163 で実証された anti-pattern 経験ベース) + 4. mechanical enforcement の参照: 順位 137 (cargo test step) と 2 層構成であること明記 +- **派生プロジェクト deploy**: グローバル `~/.claude/rules/` 配下のため自動波及。techbook-ledger / auto-review-fix-vc 等で custom lint rule を porting する際にも同 pattern が伝播 + +#### 作業計画 + +- [ ] グローバル設定変更前に `~/.claude/` snapshot 取得 (memory rule `feedback_global_config_backup.md` 適用) +- [ ] 既存 `~/.claude/rules/common/testing.md` 構造を確認 (新 section 挿入位置) +- [ ] 新 section "Custom Lint Rule Test Coverage" を追加 +- [ ] 順位 137 (mechanical check) との cross-reference を相互記載 (本 section から 137 へ、137 実装時に testing.md への逆参照を追加) +- [ ] 派生プロジェクト動作確認 (`~/.claude/` 自動波及で deploy 不要) +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- `~/.claude/rules/common/testing.md` に新 section が canonical pattern として記述される +- 派生プロジェクトで custom lint rule を追加する際に同 pattern が prior として参照可能 +- 順位 137 実装時に testing.md への cross-reference が機能 + +#### 詰まっている箇所 + +- 順位 137 の命名規約決定 (`no__detects__*` vs TOML meta field) と整合させる必要があり、137 着手時に同 PR で書くと cross-reference が atomic に整う (= 本 entry は単独 land せず 137 と bundled が efficient) + +--- + ## 既知課題 (記録のみ、本セッションで未対応) ### post-merge-feedback workflow が長時間 stale marker を残す問題 (PR #119 marker observed 2026-05-15)