Skip to content

feat(lint-screen): Bundle k-1 (順位 123) — Markdown ハンク除外フィルター + docs Phase D Round 2 完遂反映#155

Merged
aloekun merged 3 commits into
masterfrom
bundle-k-1-md-filter
May 15, 2026
Merged

feat(lint-screen): Bundle k-1 (順位 123) — Markdown ハンク除外フィルター + docs Phase D Round 2 完遂反映#155
aloekun merged 3 commits into
masterfrom
bundle-k-1-md-filter

Conversation

@aloekun
Copy link
Copy Markdown
Owner

@aloekun aloekun commented May 14, 2026

Summary

Phase D dogfood で 5 PR 連続観測された false positive (mistral:7b が docs-only diff や .md ファイルに対して Rust の unused-import を hallucinate) を 拡張子ベースの mechanical filter で構造的に解消する。Phase E 採否判定前に systemic FP root cause を消す位置付け。

  • src/cli-push-runner/src/stages/lint_screen.rsfilter_excluded_hunks 関数 + EXCLUDED_EXTENSIONS = ["md", "markdown"] (case-insensitive) を追加。diff --git 行を file-diff 境界として分割、各 chunk の +++ b/<path> (なければ --- a/<path>) から拡張子判定。全ハンク除外時は FilterResult::AllExcluded で invoke を skip + screen_decision: skipped 説明付き skip-report を書き出す short-circuit。
  • docs alignment (commit 1) — analysis.md L216 を 🚧 進行中✅ 完遂outcomes.mdD-7 outcome section (PR feat(post-merge-feedback): Bundle c-1 (D-7) — L1 Drop guard + L2 orphan reaper + ADR-030 spec #154 結果) を追加、Phase E 判定材料を 7 data points / 5 PR に更新。Phase D Round 2 完遂状態を文書化。

このPRの2コミット構成

  • commit 1 (vnwzzzyw): docs(llm-offload): Phase D Round 2 完遂状況を analysis.md / outcomes.md に反映 (D-7 #154 結果込み) — docs-only、PR scope に混ぜることをユーザー許可済
  • commit 2 (plytvxno): feat(lint-screen): Bundle k-1 (順位 123) — Markdown ハンク除外フィルターを追加 — 本 PR の主旨

Bundle k-1 self-dogfood 結果 (Phase D data point #8 = 累積 9 dp / 6 PR)

LINT_SCREEN_ENABLED=true で push 実行、本 PR 自身が filter のテストケースに:

指標
screen_decision auto_fix
findings 1
finding 内容 unused-import on lint_screen.rs:305 (const EXCLUDED_EXTENSIONS: &[&str] = &[)
fallback なし
## Diagnostic 不在 (num_ctx overflow なし)
lint_screen latency 41s
pre-push pipeline 合計 884s (2 iterations / 8m 59s)

観察の意義:

  1. filter は機能した — diff 内の docs/*.md ハンクは mistral:7b に渡らず、findings は Rust ファイル (lint_screen.rs) のみが対象。D-3〜D-6 で観測した use std::io::Write; hallucinate は本 PR で再現しなかった。
  2. 新 FP class が露出 — mistral:7b は const EXCLUDED_EXTENSIONS: &[&str] = &[...]unused-import と誤分類。これは Markdown 軸ではなく Rust const 構文の misclassification で、5 観測した「context 外 hallucinate」とは別 root cause。
  3. reviewer cross-check の構造的成功 — simplicity-review が EXCLUDED_EXTENSIONS を line 374 で実使用していることを直接読み取って FP と判定 + 「自己実証 PR」とコメント。

takt-fix iteration outcome (2 iterations / 8m 59s)

initial review で simplicity-review が REJECT を出した 2 件の BLOCKING:

  1. let _ = write_skip_report(...) 経路で I/O エラーを silent dropwrite_report 経路 (line 108-117) の if let Err(e) { log_stage(...) } pattern と不一致
  2. run_lint_screen の nesting depth 増加 — fix のための if let Err をインラインで書くと深くなる

takt-fix の解決: write_skip_report_logged helper を新規切り出し (既存の invoke_and_write_report extraction pattern と同形)。1 fix で両 finding を同時解消、iteration 2 で APPROVE。

累積 FP rate への効果

Phase D 観測 filter 前 filter 後 (本 PR + 推定)
docs-only diff .md 系 FP (D-5 ×2 / D-6) 3 件 構造的消滅 (0 件)
Rust scope hallucinate (D-3) 1 件 残存 (filter scope 外)
TOML hallucinate (D-4 CR fix) 1 件 残存 (filter scope 外)
新規露出: Rust const 構文 misclassification (Bundle k-1 self-dogfood) 1 件観測

累積: 5 件 (filter 前) → 2-3 件 (filter 後の推定)。Phase E 採否判定の精度が向上する位置付け。

テストカバレッジ (10 件新規)

  • Rust-only / mixed (Rust + .md) / pure .md / pure .markdown
  • 大文字 (.MD / .Markdown) の case-insensitive 判定
  • something.mdxyz.rs の中途 .md 判定 (= 除外しない)
  • /dev/null create / delete 片側 path の処理
  • 3-file mixed diff で hunk 境界が正しく保たれる
  • skip-report 本文に "skipped" / "docs-only diff" / "Bundle k 順位 123" を含む

Test plan

  • cargo test -p cli-push-runner stages::lint_screen 24 件 pass
  • cargo test --workspace 901+ 件 pass (regression なし)
  • cargo clippy -p cli-push-runner clean
  • release exe build + .claude/cli-push-runner.exe deploy
  • markdown lint clean (4 files)
  • Phase D dogfood data point feat(hooks): push 前パイプラインハーネスの実装 #8 取得 (LINT_SCREEN_ENABLED=true)
  • post-merge-feedback で Phase E 移行可能性の再評価

Refs

🤖 Self-dogfood meta-pattern: 本 PR の filter 実装が本 PR 自身の lint_screen で機能していることが finding 内容から直接観測可能。

Summary by CodeRabbit

  • New Features

    • lintスクリーンがMarkdownを自動除外し、対象外時はスキップ報告を出力して処理を短絡するようになりました。
  • Documentation

    • Phase D の進捗・集計を更新し、Phase E 判定材料を整理しました。
    • タスクリストから完了した項目を削除して一覧を更新しました。
  • Tests

    • Markdown除外やスキップ報告の振る舞いを検証するユニットテストを追加しました。

Review Change Stack

aloekun added 2 commits May 15, 2026 00:52
Phase D dogfood で 5 PR 連続観測された false positive (mistral:7b が docs-only
diff や `.md` ファイルに対して Rust の `unused-import` を hallucinate) を
拡張子ベースの mechanical filter で構造的に解消する。

## 設計

- `src/cli-push-runner/src/stages/lint_screen.rs` に `filter_excluded_hunks` 関数を追加
- `EXCLUDED_EXTENSIONS = ["md", "markdown"]` を hardcode (大文字小文字無視)
- `diff --git ` 行を file-diff 境界として 1 ハンク = 1 chunk に分割、各 chunk の
  `+++ b/<path>` (または `--- a/<path>`) から拡張子を抽出して判定
- 全ハンクが対象外拡張子 (= docs-only diff) の場合は `FilterResult::AllExcluded` を
  返し、invoke を完全に skip + skip-report (`screen_decision: skipped` + 理由)
  を書き出す short-circuit path に分岐

## なぜ filter 適用箇所を (b) lint_screen stage 内にしたか

- (a) `.takt/review-diff.txt` 生成時に drop すると review 全体の汎用性を壊す
- (c) prompt 内で「.md は無視せよ」と instruct は LLM 信頼で危険
- (b) lint_screen stage 限定で副作用最小、Bundle k 順位 123 計画通り

## なぜ `run_lint_screen` を `invoke_and_write_report` に分割したか

filter 経路追加で 50 行ガイドラインを超過 (58 行)。invoke + write_report の
2 step を `invoke_and_write_report` ヘルパーに切り出して 30 行台に収めた。

## テストカバレッジ (10 件新規)

- Rust-only / mixed (Rust + .md) / pure .md / pure .markdown
- 大文字 (.MD / .Markdown) も除外対象に含む
- `something.mdxyz.rs` のような中途 `.md` を含む path は除外しない
- `/dev/null` create / delete の片側 path 判定
- 3-file mixed diff で hunk 境界が正しく保たれる
- skip-report 本文に "skipped" / "docs-only diff" / "Bundle k 順位 123" を含む

## 累積 false positive への効果見積

5 観測のうち:
- D-4 CR fix (TOML) — scope 外 (TOML は除外対象に含まない) = 残存
- D-5 ×2 + D-6 (Markdown / docs-only) — **構造的解消** (3 件消滅)
- D-5 初回 (Rust + docs mixed) — Rust 部分は依然 mistral:7b に渡る = scope 内 Rust FP が残る可能性

期待: Phase E 採否判定前の FP rate を 5/7 → ~2/7 に低減。残 2 件は別 root cause
(Rust scope hallucinate / TOML hallucinate) のため別途分析が必要。

Refs: Bundle k 順位 123 (todo8.md 削除済)、ADR-038 Known failure mode、
docs/local-llm-offload-phase-d-outcomes.md L162 (false positive 累積観測)
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 70ba43c7-d486-4c7a-9919-b9bec6aa000e

📥 Commits

Reviewing files that changed from the base of the PR and between 85461e4 and bc3a4f2.

📒 Files selected for processing (1)
  • src/cli-push-runner/src/stages/lint_screen.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/cli-push-runner/src/stages/lint_screen.rs

📝 Walkthrough

Walkthrough

lint_screen ステージに Markdown(.md/.markdown)差分をハンク単位で除外し、除外時は classifier を起動せず説明付きの skip-report を出力する短絡経路を追加。関連ドキュメントで Phase D の D-7 完了反映と todo 項目の削除を行い、網羅的な単体テストを追加した。

Changes

Markdown フィルター実装と Phase D ドキュメント更新

Layer / File(s) Summary
差分読み込みと早期短絡(skip-report)
src/cli-push-runner/src/stages/lint_screen.rs
run_lint_screen が diff を読み込んだ後に output_path を確定し、filter_excluded_hunks の結果が全ハンク除外(.md/.markdown のみ)なら classifier を起動せず write_skip_report_logged で説明的な skip-report を書き出して即 return する短絡経路を追加。
Classifier 呼び出し経路の整理
src/cli-push-runner/src/stages/lint_screen.rs
classifier 実行〜レポート書き出し部分を invoke_and_write_report に分離。invoke_classifier 失敗時の短絡戻りと、成功時の stdout/stderr を write_report に渡す流れに整理。
拡張子判定と diff チャンク分割ロジック
src/cli-push-runner/src/stages/lint_screen.rs
EXCLUDED_EXTENSIONS/FilterResult を導入し、split_into_file_diffschunk_has_excluded_extensiondiff --git 境界を基にファイル差分チャンクを分割、+++ b/<path>(無ければ --- a/<path>)から拡張子を抽出して大小無視で除外判定する実装を追加。全チャンク除外で FilterResult::AllExcluded を返す。
skip-report 書き出しの実装とログ対応
src/cli-push-runner/src/stages/lint_screen.rs
説明的な Summary/Findings を含む skip-report を write_skip_report/write_skip_report_logged でファイルへ出力し、書き込み失敗時はステージログへ記録する処理を追加。
単体テストと diff 生成ヘルパ
src/cli-push-runner/src/stages/lint_screen.rs
unified diff 生成ヘルパ(rust_chunk/md_chunk)と多数のユニットテストを追加。テストは Rust/MD 混在、MD 全除外、拡張子大小無視、パス中に拡張子文字列が含まれるケース、/dev/null 作成削除、rename 時の新旧パス優先、非 diff 入力のパススルー、skip-report 本文検証などを網羅。
Phase D ドキュメント更新
docs/local-llm-offload-analysis.md, docs/local-llm-offload-phase-d-outcomes.md
D-7(PR #154)を「完遂」に更新し、D-7 の dogfood 結果(human_review、Ollama HTTP timeout による fallback、## Diagnostic 不在など)を追加。Phase E 判定材料(完走数、fallback rate、false positive 累積、verdict variance、累積 PR data)を D-7 反映後の値へ更新。
todo からのタスク削除
docs/todo-summary.md, docs/todo8.md
「lint-screen の Markdown ファイル除外フィルター追加(PR #151 T1-#2)」に対応するタスク記述を docs/todo-summary.md の順位 123 行および docs/todo8.md の該当セクションから削除。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • aloekun/claude-code-hook-test#144: run_lint_screen 周辺のレポート生成経路に影響する変更が含まれており、同一コードパスとの衝突や相互依存の可能性がある。
  • aloekun/claude-code-hook-test#132: 既存の run_lint_screen ステージ実装を拡張した PR で、本 PR がその実装に対する機能追加(Markdown 除外)を行っているため直接関連している。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PRタイトルは主要な変更内容を明確に要約している。Markdown ハンク除外フィルターの実装と Phase D Round 2 完遂の反映という2つの重要な変更を適切に示している。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cli-push-runner/src/stages/lint_screen.rs`:
- Around line 360-375: The function chunk_has_excluded_extension currently takes
the first header line found (using find_map) which can pick the "--- a/..." old
path and miss renames; change it to prefer the new-path header "+++ b/" across
the entire chunk and only fall back to "--- a/" if no "+++ b/" is present:
search lines for a "+++ b/" prefix first, set path to that if found, otherwise
search for "--- a/"; then extract the extension and check EXCLUDED_EXTENSIONS as
before. Ensure you update the logic inside chunk_has_excluded_extension
(referencing the function name and EXCLUDED_EXTENSIONS) so renames like *.rs ->
*.md correctly use the new-path extension.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59b2dfc7-e68e-4e69-8c65-38c8810db0b4

📥 Commits

Reviewing files that changed from the base of the PR and between c872da2 and 85461e4.

📒 Files selected for processing (5)
  • docs/local-llm-offload-analysis.md
  • docs/local-llm-offload-phase-d-outcomes.md
  • docs/todo-summary.md
  • docs/todo8.md
  • src/cli-push-runner/src/stages/lint_screen.rs
💤 Files with no reviewable changes (2)
  • docs/todo8.md
  • docs/todo-summary.md

Comment thread src/cli-push-runner/src/stages/lint_screen.rs Outdated
…b/ (new path) を優先

CodeRabbit Major 指摘の rename 時除外漏れ bug を解消する。unified diff の慣例で
`--- a/<path>` が `+++ b/<path>` より先に出現するため、find_map の旧実装では
両者を OR で取ると常に旧パスが優先されてしまう問題があった。

## 修正前の bug

```rust
let path = chunk.lines().find_map(|line| {
    line.strip_prefix("+++ b/")
        .or_else(|| line.strip_prefix("--- a/"))
}).unwrap_or("");
```

`*.rs → *.md` の rename で:
- `--- a/src/a.rs` を先に処理 → `find_map` が "src/a.rs" を返す
- `+++ b/docs/a.md` に到達せず
- 拡張子 = "rs" → EXCLUDED_EXTENSIONS に含まれず → mistral:7b が `.md` 内容を見る
- = Bundle k-1 の filter contract (新パス優先) に違反

## 修正後

```rust
let new_path = chunk.lines().find_map(|line| line.strip_prefix("+++ b/"));
let old_path = chunk.lines().find_map(|line| line.strip_prefix("--- a/"));
let path = new_path.or(old_path).unwrap_or("");
```

new_path を chunk 全体から先に探す → rename でも新拡張子で判定。new_path が無い
場合 (= `+++ /dev/null` の delete) のみ old_path にフォールバック。

## テスト追加 (2 件)

- `filter_excluded_hunks_prefers_b_path_on_rename_to_markdown`: `*.rs → *.md`
  rename が AllExcluded になることを assert
- `filter_excluded_hunks_keeps_rename_from_md_to_rust`: 逆方向 (`*.md → *.rs`)
  rename が Kept になることを assert (symmetric 検証)

## 累積テスト

cli-push-runner stages::lint_screen 24 → 26 件 pass、clippy clean、release exe deploy 済

Refs: PR #155 CR review コメント (Major 🟠 Quick win)、Bundle k-1 順位 123、ADR-038
@aloekun aloekun merged commit 31bb7cd into master May 15, 2026
1 check passed
@aloekun aloekun deleted the bundle-k-1-md-filter branch May 15, 2026 03:26
aloekun added a commit that referenced this pull request May 17, 2026
… diff metadata strip + silent failure baseline cleanup (#159)

Bundle l 3 サブ変更を bundled で land (順位 129 + 131 + 132、todo-summary.md table 4 行整理含む)。
共通テーマ: cli-push-runner lint-screen stage の堅牢化 + I/O write 関数の silent failure 構造的防止。

順位 132 (Tier 1 / S): cli-push-runner/src/stages/lint_screen.rs に strip_diff_metadata_lines
前処理関数を追加し、similarity index NN% / index <hex> / file mode / rename 系の
diff metadata 行を LLM 入力前に決定論的に除去。PR #155-#156 で 5 観測された mistral:7b の
magic-number FP を構造的に解消。unit test 7 件 (各 metadata 系列 + content 保持 + substring 誤検出回避)。
順位 130 (prompt 改修 or 前処理 filter のいずれか) を本実装で前処理 filter に確定して supersede、
table から 130 行も削除。

順位 129 (Tier 1 / S): .claude/custom-lint-rules.toml に rule⑩ (no-write-result-discard、
pattern let\s+_\s*=\s+write_\w+\(、extensions=["rs"]、severity=error) を追加。
hooks-post-tool-linter に 8 件 unit test を追加 (positive x3 / negative x4 / dogfood x1)。
dogfood test (deployed_src_rust_passes_no_write_result_discard_rule) は src/**/*.rs を再帰走査して
clean baseline を強制。本 PR の completeness criteria に合わせて既存違反 5 件を fix:
  - cli-pr-monitor/src/stages/poll.rs: 3 箇所の let _ = write_state(...) を
    if let Err(e) = ... { log_info(...) } に置換 (非 fatal 進行 + 観測可能性回復)
  - cli-merge-pipeline/src/feedback.rs: FailedMarkerGuard::drop 内の write_failed_marker と
    feedback::run の write_pending_marker を log 化、後者は write_pending_marker_logged helper
    に抽出して fn run の 50 行ガイドライン超過を回避 (lint_screen.rs の write_skip_report_logged と同 pattern)

順位 131 (Tier 2 / M): write_skip_report_logged の error path regression test を 3 件追加。
parent が regular file な path に書込を試みて create_dir_all 失敗を確定的に誘発する方式 (Unix/Windows
両方で reliable、追加 dep 不要)。write_skip_report の Err 返却 + write_skip_report_logged の
no-panic + writable path success の 3 段で seal、将来 refactor での silent drop 回帰を機械検出。

副次: src/cli-push-runner/Cargo.toml に tempfile dev-dep を追加 (順位 131 test 用)、
todo8.md から 129/130/131/132 detail entry を削除 (Cross-File Reference Lifecycle 整合)。

検証: cargo test 全 workspace pass / pnpm build:all 成功 / 変更 crate 3 つ
(cli-push-runner / hooks-post-tool-linter / cli-pr-monitor) で cargo clippy --all-targets -- -D warnings clean。
aloekun added a commit that referenced this pull request May 19, 2026
…ule-test coverage check + global testing.md 明文化)

PR #163 (Bundle k-2) merge 後の post-merge-feedback で 2 件採用された follow-up
task を todo 系列に登録。

## 順位 137 (Tier 1, M, Frequency High)

Rule-Test Coverage Check Cargo test。
`.claude/custom-lint-rules.toml` の各 rule の extensions ⇔
`src/hooks-post-tool-linter/src/main.rs` の test 関数名を mechanical に検証
する Cargo test step を追加する。

由来: PR #110/#151/#152/#155 の 4 PR 観測 (Frequency High)、PR #163 で順位 127
として passive reminder comment を追加したが、analyzer が「passive reminder
では PR #152 同根再発を防止できなかった実証ベース → mechanical enforcement
が必要」と判定。

必須カバレッジ scope (CodeRabbit Minor 指摘で確定): 主要 ext rs/toml/yaml/yml ×
全 rule に対応 test 必須、その他 ext (jsonc/json/ts/tsx/js/jsx/py/ps1) は
rule あたり positive single test 1 件以上で代替。完了基準と詰まっている箇所
の scope drift を fix。

## 順位 138 (Tier 3, XS, Frequency High)

Rule Extension Test Pattern を `~/.claude/rules/common/testing.md` に明文化。
順位 137 (mechanical Cargo test) と 2 層構成。`~/.claude/` global 配下のため
派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ自動波及。

## land 順序の推奨

順位 137 + 138 は同 PR で land 推奨 (命名規約 + 必須 ext scope 決定が
atomic に整う、cross-reference が同 commit で完結)。

## 補正事項

analyzer report は target を `src/cli-custom-linter/src/main.rs` と記載
していたが、実際の crate 名は `hooks-post-tool-linter` のため詳細 entry
で補正済。

## CodeRabbit review 反映

PR review (PR #164 round 1) で順位 137 の「完了基準」(全 (rule, ext) ペア必須)
と「詰まっている箇所」(主要 ext に絞った coverage 推奨) の scope drift を
🟡 Minor で指摘。修正方針:

- 完了基準を 主要 ext (rs/toml/yaml/yml) × 全 rule 必須 + その他 ext は
  rule あたり single positive test で代替、と明示
- 設計決定 section に必須カバレッジ scope を追加 (順位 138 testing.md と
  同一 commit で codify することで cross-reference の atomicity 確保)
- 詰まっている箇所 から該当議論を削除、TOML meta field vs 命名規約方式の
  trade-off のみ残す (= 順位 138 実装時に確定する補助 design 議論)

## docs only

実装は別 PR で着手予定。
aloekun added a commit that referenced this pull request May 19, 2026
…ule-test coverage check + global testing.md 明文化) (#164)

PR #163 (Bundle k-2) merge 後の post-merge-feedback で 2 件採用された follow-up
task を todo 系列に登録。

## 順位 137 (Tier 1, M, Frequency High)

Rule-Test Coverage Check Cargo test。
`.claude/custom-lint-rules.toml` の各 rule の extensions ⇔
`src/hooks-post-tool-linter/src/main.rs` の test 関数名を mechanical に検証
する Cargo test step を追加する。

由来: PR #110/#151/#152/#155 の 4 PR 観測 (Frequency High)、PR #163 で順位 127
として passive reminder comment を追加したが、analyzer が「passive reminder
では PR #152 同根再発を防止できなかった実証ベース → mechanical enforcement
が必要」と判定。

必須カバレッジ scope (CodeRabbit Minor 指摘で確定): 主要 ext rs/toml/yaml/yml ×
全 rule に対応 test 必須、その他 ext (jsonc/json/ts/tsx/js/jsx/py/ps1) は
rule あたり positive single test 1 件以上で代替。完了基準と詰まっている箇所
の scope drift を fix。

## 順位 138 (Tier 3, XS, Frequency High)

Rule Extension Test Pattern を `~/.claude/rules/common/testing.md` に明文化。
順位 137 (mechanical Cargo test) と 2 層構成。`~/.claude/` global 配下のため
派生プロジェクト (techbook-ledger / auto-review-fix-vc) へ自動波及。

## land 順序の推奨

順位 137 + 138 は同 PR で land 推奨 (命名規約 + 必須 ext scope 決定が
atomic に整う、cross-reference が同 commit で完結)。

## 補正事項

analyzer report は target を `src/cli-custom-linter/src/main.rs` と記載
していたが、実際の crate 名は `hooks-post-tool-linter` のため詳細 entry
で補正済。

## CodeRabbit review 反映

PR review (PR #164 round 1) で順位 137 の「完了基準」(全 (rule, ext) ペア必須)
と「詰まっている箇所」(主要 ext に絞った coverage 推奨) の scope drift を
🟡 Minor で指摘。修正方針:

- 完了基準を 主要 ext (rs/toml/yaml/yml) × 全 rule 必須 + その他 ext は
  rule あたり single positive test で代替、と明示
- 設計決定 section に必須カバレッジ scope を追加 (順位 138 testing.md と
  同一 commit で codify することで cross-reference の atomicity 確保)
- 詰まっている箇所 から該当議論を削除、TOML meta field vs 命名規約方式の
  trade-off のみ残す (= 順位 138 実装時に確定する補助 design 議論)

## docs only

実装は別 PR で着手予定。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant