Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .claude/custom-lint-rules.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ good = 'See [推奨実行順序](todo-summary.md#recommended-order-summary) <!-
# - PR #110 で yaml/yml を追加: takt workflow yaml / GitHub Actions yaml 等の
# YAML config も permanent artifact として ephemeral 参照を含み得るため
#
# ⚠️ extensions 変更時の test 追加義務 (順位 127, PR #151/#152 で観測の test gap 対策):
# extensions に新規拡張子を追加 / 削除する場合、同 PR で対応する positive test
# (= 新拡張子ファイルで rule が fire することの assertion) と negative test (= 同
# 拡張子で permanent 参照は fire しないこと) を
# `src/hooks-post-tool-linter/src/main.rs` テストモジュールの
# `no_ephemeral_todo_detects_*` / `no_ephemeral_todo_skips_*` / `no_ephemeral_todo_<ext>_*`
# 系列に追加すること。test 不在のまま extensions を変更すると検出力 regression が
# silent に発生する (yaml/yml = PR #110、toml = PR #151 で実観測の gap)。
#
# Self-exclusion 設計:
# Rust regex は lookbehind 非対応のため負 lookahead は使用不可。本ファイル自身は
# .toml 拡張子で対象内だが、message / why / example 内に concrete `docs/todoN.md`
Expand Down
2 changes: 0 additions & 2 deletions docs/todo-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@
| 120 | 💎 Tier 3 | **`takt-workflow-persona-without-model` rule コメント拡張 + ADR-007 case study 追記 (PR #150 T1-#1 採用、実体 Tier 3 — analyzer 誤分類)** | todo8.md | XS | なし (実体は docs/comment 修正のみで mechanical enforcement なし → Tier 3 reclassify。次回 takt yaml schema 拡張時の rule 更新フロー文書化 + enumeration-based pattern の case study 記録、Tier 1 #2 ADR case study と同 PR で land 効率的) |
| 121 | 🔧 Tier 2 | **`takt_workflow_persona_detects_required_permission_mode_violation` doc 修正 + 残り 3 fields 個別 fixture test 追加 (PR #150 T2-#1 採用)** | todo8.md | S | なし (4 fields のうち 3 fields は個別 fixture test 不在、doc comment と実態乖離。pass_previous_response / output_contracts / parallel の individual test を追加して将来 regex 変更時の regression 検知を担保) |
| 122 | 💎 Tier 3 | **`development-workflow.md` Step 0 に「新 todo 着手前の既実装確認」チェックステップ追加 (PR #150 T3-#1 採用)** | todo8.md | XS | なし (memory rule `feedback_verify_task_not_already_done.md` を canonical workflow へ昇格。`jj log --limit 20 <keyword>` は決定的コマンドのため `feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + 機械実行可能で採用、グローバル設定変更前に `~/.claude/` バックアップ取得必須) |
| 124 | 🚀 Tier 1 | **`no-ephemeral-todo-reference` rule の TOML positive test 追加 (PR #151 T1-#1 採用、PR #152 で再観測)** | todo8.md | S | なし (extensions 拡張が複数 PR にわたり反復する pattern (yaml/yml = PR #110、toml 等)、test gap 累積を構造的に防ぐ。Frequency Medium で採用基準を満たす) |
| 125 | 🔧 Tier 2 | **UTF-8 マルチバイト boundary test を他の string-processing hooks に横展開 (PR #151 T2-#1 採用)** | todo8.md | M | なし (PR #151 で `byte_offset_to_line` char-boundary panic bug を test 拡充で発見、同型関数を持つ他 hooks に systemic 防御を確保。test 拡充が production fault detection に直結する事例の横展開) |
| 127 | 💎 Tier 3 | **extensions 拡張時の test 追加 pattern をコード comment で明文化 (PR #151 T3-#2 採用、順位 124 と同 PR 推奨、PR #152 で再観測)** | todo8.md | XS | なし (`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + 機械強制ではなく guide 効果。順位 124 と同 PR で test location を正確に参照、順位 122 と同じロジック) |
| 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 配下で派生プロジェクトに自動波及) |
| 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 補助) |
Expand Down
44 changes: 0 additions & 44 deletions docs/todo8.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,28 +160,6 @@

---

### `no-ephemeral-todo-reference` rule の TOML positive test 追加 (PR #151 T1-#1 採用、**PR #152 で再観測**)

> **動機**: PR #151 の CodeRabbit nitpick (および本 PR で発見されなかった latent gap) で、`no-ephemeral-todo-reference` rule が TOML ファイルを extensions に持つ場合の positive test (= 実際に violation を検出することの assertion) が不在と判明。既存テスト `no_ephemeral_todo_self_exclusion_invariant_holds_on_deployed_toml` は self-exclusion 確認のみで、検出力の test ではない。
>
> **本タスクの位置づけ**: PR #151 post-merge-feedback Tier 1 #1 採用 → PR #152 post-merge-feedback で再確認 (Severity Medium / Frequency Medium / Effort S / Adoption Risk None)。extensions 拡張が複数 PR にわたって反復する pattern (yaml/yml = PR #110、toml = PR #129?) があり、test gap が累積するリスクを構造的に防ぐ。PR #152 post-merge-feedback でも「yaml/yml test gap (PR #110) + TOML test gap (PR #151) の 2 PR 連続観測」と同根の指摘あり。
>
> **参照**: `.claude/feedback-reports/151.md` Tier 1 #1、`src/hooks-post-tool-linter/src/main.rs` test module

#### 作業計画

- [ ] test fixture: `.toml` 拡張子ファイルに `docs/todo3.md` 等の ephemeral 参照を含む 2-3 行 fixture を作成
- [ ] test ケース: `run_custom_rules` が 1 件以上の violation を返し、`type == "NO_EPHEMERAL_TODO_REFERENCE"` を確認
- [ ] negative test: 同じ TOML fixture で `docs/adr/adr-007.md` 等の permanent 参照は violation 0 件であることを確認
- [ ] 本エントリ削除 + todo-summary.md 行削除

#### 完了基準

- TOML 拡張子で rule が機能することが explicit test で seal される
- 将来 extensions から TOML を誤削除した場合に test fail で検出される

---

### UTF-8 マルチバイト boundary test を他の string-processing hooks に横展開 (PR #151 T2-#1 採用)

> **動機**: PR #151 で `byte_offset_to_line` の char-boundary panic bug を test 拡充 (UTF-8 漢字単独 needle) で発見した。同型関数 (byte offset から行番号変換 / needle 検索 + slice 操作) は他の string-processing hooks にも存在する可能性が高く、横展開 test で systemic 防御を確保すべき。
Expand All @@ -205,28 +183,6 @@

---

### extensions 拡張時の test 追加 pattern をコード comment で明文化 (PR #151 T3-#2 採用、順位 124 と同 PR 推奨、**PR #152 で再観測**)

> **動機**: 順位 124 (TOML positive test) の根因である「extensions 配列を変更しても対応する test が追加されない」pattern を、`custom-lint-rules.toml` または `no_ephemeral_todo_reference_rule()` 関数の近傍コメントに明記。「extensions を変更した際は対応する positive/negative test を追加すること」のリマインダを次回 rule 変更時に目に入る位置に置く。
>
> **本タスクの位置づけ**: PR #151 post-merge-feedback Tier 3 #2 採用 → PR #152 post-merge-feedback で再確認 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None)。memory rule `feedback_no_unenforced_rules.md` に抵触するように見えるが、本 case は **既存実践の明文化 + 機械強制ではなく guide 効果** のため例外採用 (順位 122 と同じロジック)。PR #152 post-merge-feedback でも「point-of-edit reminder は enforcement ゼロでも omission 抑止効果あり」と同様の判断で再採用された。
>
> **参照**: `.claude/feedback-reports/151.md` Tier 3 #2、`.claude/custom-lint-rules.toml`、`src/hooks-post-tool-linter/src/main.rs`

#### 作業計画

- [ ] `.claude/custom-lint-rules.toml` の `no-ephemeral-todo-reference` rule entry の上に 2-3 行 comment 追加: 「⚠️ extensions を変更する場合: 同 PR で positive + negative test を `src/hooks-post-tool-linter/src/main.rs` に追加すること」
- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 要否を検討 (`.claude/custom-lint-rules.toml` は project 個別なので deploy 不要)
- [ ] 順位 124 (TOML test 追加) の作業中に test の location を確認して、comment 内の path 参照を正確に書く
- [ ] 本エントリ削除 + todo-summary.md 行削除

#### 完了基準

- 次回 extensions 変更時に rule 編集者が test 追加を忘れにくくなる
- comment が機械強制ではなく guide として機能する (PR review 時の 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 が増殖するリスクあり。
Expand Down
41 changes: 41 additions & 0 deletions src/hooks-post-tool-linter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,47 @@ extensions = ["ts", "js"]
assert!(violations.is_empty());
}

/// 順位 124 (PR #151 T1-#1 採用、PR #152 で再観測): TOML 拡張子で rule⑥ が機能することを
/// explicit に seal する positive test。既存の self-exclusion invariant test
/// (`no_ephemeral_todo_self_exclusion_invariant_holds_on_deployed_toml`) は
/// "self-trigger しない" 方向の test であり、検出力の test ではない。本 test は将来
/// extensions から "toml" を誤削除した場合に test fail で検出する safety net。
#[test]
fn no_ephemeral_todo_detects_toml_ephemeral_reference() {
let dir = tempfile::tempdir().unwrap();
let file = write_file(
dir.path(),
"config.toml",
&build_concrete_digit_fixture(3),
);
let rules = compile_test_rules(vec![no_ephemeral_todo_reference_rule()]);
let violations = run_custom_rules(file.to_str().unwrap(), &rules);
assert_eq!(
violations.len(),
1,
"rule⑥ should fire on TOML file with ephemeral todo reference"
);
}

/// 順位 124 補完: TOML 拡張子でも `docs/adr/...` 等の permanent 参照は fire しないことを
/// assert する negative test。拡張子だけでなく pattern の正確性も seal する。
#[test]
fn no_ephemeral_todo_toml_skips_permanent_adr_reference() {
let dir = tempfile::tempdir().unwrap();
let file = write_file(
dir.path(),
"config.toml",
"doc_link = \"see docs/adr/adr-007-foo.md for context\"\n",
);
let rules = compile_test_rules(vec![no_ephemeral_todo_reference_rule()]);
let violations = run_custom_rules(file.to_str().unwrap(), &rules);
assert!(
violations.is_empty(),
"rule⑥ should NOT fire on TOML file with permanent ADR reference (got {} violations)",
violations.len()
);
}

#[test]
fn no_ephemeral_todo_self_exclusion_invariant_holds_on_deployed_toml() {
let path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
Expand Down