Skip to content

feat(lint): rule⑧ no-docs-relative-back-to-docs (Phase d P-2 / Bundle j-1 / 順位 94)#140

Merged
aloekun merged 2 commits into
masterfrom
feature/lint-rule-no-docs-relative
May 10, 2026
Merged

feat(lint): rule⑧ no-docs-relative-back-to-docs (Phase d P-2 / Bundle j-1 / 順位 94)#140
aloekun merged 2 commits into
masterfrom
feature/lint-rule-no-docs-relative

Conversation

@aloekun
Copy link
Copy Markdown
Owner

@aloekun aloekun commented May 10, 2026

Summary

docs/ 配下から ../docs/ への back-link を検出する custom lint rule⑧ (no-docs-relative-back-to-docs) を追加。Phase d roster の P-2 (Bundle j-1 / 順位 94) に該当。

変更内容

Commit 1 (前 PR carry-over): 順位 100 登録 + analysis.md P-1 完了反映

PR #139 (Bundle h+g-2) merge 後の post-merge-feedback で採用された Tier 3 #1 (development-workflow.md に「同一ファイル複数編集の 1 task 統合」+「partial completion + 後続 PR 追補明記」 の 2 pattern 追補) を 順位 100 として docs/todo6.md + docs/todo-summary.md に登録、analysis.md §4 #2 の P-1 行を ✅ 完了化 + dogfood outcome (classifier preview metrics + post-merge-feedback 結果) を記載。

本 commit は前 PR からの「フィードバック層」carry-over で、本 PR の P-2 implementation とは独立。

Commit 2: rule⑧ 追加 + linter test + 順位 94 cleanup

.claude/custom-lint-rules.toml

ルール⑧ no-docs-relative-back-to-docs を追加 (severity = error):

field
pattern (?i)\]\(\.\./docs/
extensions ["md"]
severity error

自己限定設計: paths filter は lint runner 未実装 (extensions のみサポート)。pattern semantics で自己限定可: ](../docs/ は parent-dir 経由で docs/ を再参照する形で、root-level README / docs 外の Markdown では自然な link 形式 ](docs/...) (相対なし) と区別される。grep 確認で false positive 影響範囲は todo6.md の説明文 1 件のみ (本 PR で削除)。

src/hooks-post-tool-linter/src/main.rs

5 件の synthetic test:

  1. md_no_docs_relative_detects_pr133_pattern: PR docs(todo): split summary and todo5.md tasks to keep files under 50KB #133 で混入した [ADR-036](../docs/adr/adr-036-...) 形式の検出を確認
  2. md_no_docs_relative_detects_uppercase_path: ../DOCS/... 大文字バリアント (case-insensitive) の検出
  3. md_no_docs_relative_skips_same_directory_link: 同階層 [text](adr/foo.md) (相対参照なし) は skip
  4. md_no_docs_relative_skips_parent_to_other_dir: ../README.md / ../src/main.rs 等 docs 以外への parent-dir 参照は skip
  5. md_no_docs_relative_only_targets_md: .toml 等の他拡張子は対象外 (extensions = ["md"] 確認)

全 87 test pass、新規 5 test 含む。

todo cleanup

  • docs/todo6.md: 順位 94 (docs/ 内 Markdown の ../docs/ 相対パストラップ検出 lint rule) 詳細削除
  • docs/todo-summary.md: priority table から 順位 94 行削除、Bundle j 解説で j-1 land 済を明記

Phase d P-2 dogfood signal (classifier preview のみ、real pipeline 未実行)

P-1 と同じ方針 (feedback_global_config_backup を踏まえた commit pollution 回避):

Metric P-1 (337-line / docs-only) P-2 (203-line / Rust+TOML+MD mixed)
Latency 23s 46s
Findings 0 0
screen_decision human_review (fallback) human_review (fallback)
fallback_reason JSON parse error: missing field screen_decision 同 (line 94 column 1)

観測:

  • Fallback rate 2/2 = 100% (kill-switch criteria の 50% を超過、ただし Phase d guide §3 は 3/5 PR で停止 = まだ trend 内。real pipeline 経由なら kill-switch に厳密該当する)
  • Latency 増加 (P-1 23s → P-2 46s): 短い diff (203 < 337) でも倍増 = 入力依存性 + mistral 内部状態の variance (cold/warm context) の両方が候補
  • Mixed diff (Rust + TOML + MD) でも崩壊: 順位 98 (num_ctx overflow detection) の必要性が再々確認、P-3 着手前の優先実装を推奨

real pipeline 経由の P-2 metric は未取得。P-3 移行時に再判断。

Test plan

  • cargo test -p hooks-post-tool-linter — 87/87 pass (新規 5 test 含む)
  • pnpm deploy:hooks でビルド・デプロイ確認
  • takt pre-push-review APPROVE (1 iter / 4m 6s)
  • markdownlint clean (PostToolUse hook 確認)
  • PostToolUse lint で rule⑧ 自体が rule⑥ (no-ephemeral-todo-reference) に当たって fix 済 (lint dogfood 成功)
  • サイズチェック: todo6.md (~30KB) / todo-summary.md (~35KB) 50KB 内

Out of scope

  • paths filter の lint runner 実装: 現状 extensions のみ。多数の false positive 観測時は別 PR で実装検討
  • 順位 98 (num_ctx overflow detection): P-2 fallback で再確認したが本 PR scope 外、別 PR で実施
  • real pipeline 経由 Phase d metric: P-3 移行時の trade-off 再判断
  • 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 確認: 各 repo の docs/ 構造確認が必要、別タイミングで実施

Summary by CodeRabbit

リリースノート

  • New Features

    • Markdown ファイル内の不適切な相対リンクパターンを検出するカスタムリントルールを追加しました。
  • Documentation

    • フェーズ進捗情報と実装ワークフロー推奨事項を更新しました。
  • Tests

    • 新しいリントルール検証用のテストケースを追加しました。

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 10, 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: 802ff5fb-8a08-4c68-aa23-3fc1a35d735c

📥 Commits

Reviewing files that changed from the base of the PR and between d5a3af2 and 9cdfc8c.

📒 Files selected for processing (5)
  • .claude/custom-lint-rules.toml
  • docs/local-llm-offload-analysis.md
  • docs/todo-summary.md
  • docs/todo6.md
  • src/hooks-post-tool-linter/src/main.rs

📝 Walkthrough

Walkthrough

新しいカスタムリントルールno-docs-relative-back-to-docsを定義し、Markdownの../docs/形式の相対リンク検出機能を実装。テストケースで動作を検証し、dogfood実行結果をドキュメントに記録。開発ワークフロー改善タスクも追加。

Changes

MD相対リンク検出ルール実装・テスト・ドキュメント更新

Layer / File(s) Summary
ルール定義
.claude/custom-lint-rules.toml
新規ルール⑧no-docs-relative-back-to-docsを追加。Markdown対象で](../docs/パターンをエラーとして検出。修正手順(相対パス置換)と違反/非違反例を定義。
テスト実装
src/hooks-post-tool-linter/src/main.rs
ルール検証用ヘルパー関数と6つのテストケース追加。../docs/検出、大文字小文字対応、同一ディレクトリ除外、別ディレクトリ除外、md以外拡張子除外を確認。
Dogfood実行結果
docs/local-llm-offload-analysis.md
Phase d P-1を完了(PR #139, 2026-05-10)と記載。classifier-previewメトリクス、検出フォールバック理由、post-merge feedback結果(10findings → 1accepted)、num_ctx overflow診断重要性を記録。P-2移行時の実パイプラン測定再評価計画を注記。
タスク進捗更新
docs/todo-summary.md
推奨実行順序テーブルで順位94の相対リンク検出ルールを削除、順位100のdevelopment-workflow.md追補タスク追加。Bundle j説明文でSub-PR j-1 land済(Phase d P-2)を明示。
開発ワークフロー追補
docs/todo6.md
PR #133 T1-1ルール作成タスク削除。PR #139フィードバック受けた``development-workflow.md追補新タスク追加:同一ファイル複数編集の1task統合、partial completion時の後続PR追補明記の運用ルール化。

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • aloekun/claude-code-hook-test#6: カスタムリントエンジンの同じファイルとカスタム規約ファイルを対象として、新規ルール実装とテストを追加しているため関連。
  • aloekun/claude-code-hook-test#134: ../docs/相対リンク検出ルール実装に関連。本PR実装一方、当該PRではタスク/todoドキュメントに追記。
  • aloekun/claude-code-hook-test#91: カスタムリント規約設定とsrc/hooks-post-tool-linter/src/main.rsテストコード追加で共通。Markdownリント機能拡張の関連実装。
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトルは、新しいカスタムリントルール(rule⑧ no-docs-relative-back-to-docs)の追加という主要な変更を明確に要約しており、変更セットの主要な目的を的確に反映しています。
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

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.

@aloekun aloekun merged commit b6b61dd into master May 10, 2026
1 check passed
@aloekun aloekun deleted the feature/lint-rule-no-docs-relative branch May 10, 2026 14:25
aloekun added a commit that referenced this pull request May 11, 2026
…nup (Phase d P-3 繰上げ) (#141)

* docs: 順位 101-105 (PR #140 T1-#1/#2/#3 + T3-#1/#2 採用) 登録 + analysis.md P-2 完了反映 (classifier preview metrics + fallback rate 100% trend signal)

* docs(todo): 順位 85+86 (Bundle g-1) は PR #125 で land 済を反映 — stale todo entries 削除 + analysis.md P-3 完了反映

* test(custom-lint): rule⑥ no-ephemeral-todo-reference self-exclusion 回帰テスト追加 + analysis.md P-3 完了反映 (順位 68 / Bundle d / Phase d P-3 繰上げ)
aloekun added a commit that referenced this pull request May 12, 2026
…1/103/106) (#146)

* docs(todo,analysis): post-merge-feedback PR #145 採用 2 件登録 + Phase D D-1 完了反映

PR #145 (D-1) merge 後の post-merge-feedback で採用された 2 件 (Tier 3 #1 + #3) を todo 系列に登録し、analysis.md の Phase D section に D-1 land 状況と副産物を反映する。

順位 116 (Tier 3 XS、PR #145 T3-#1):
  - ADR-040 step_timeout 説明に sublinear / KV cache locality clarification 追記
  - 実測値 600s 採択 / 保守上限 720s / sublinear 性の KV cache 根拠

順位 117 (Tier 3 S、PR #145 T3-#3):
  - coding-style.md § Cross-File Reference Lifecycle に ephemeral → permanent 知識移管 edit order を追記
  - 3 ステップ原則 (① permanent target 先行作成・validate → ② 参照追加 → ③ 参照元削除)

analysis.md Phase D section 更新:
  - D-1 land 状況 (PR #145、298 行、ZERO findings APPROVE) を table の状態列に反映
  - 順位 115 を D-2 前 critical path として明示
  - D-1 dogfood outcome として 4 項目記録 (skip 理由 / workflow gap 発見 / ADR-040 fix / migration codify)

順位 115 (Tier 1) の rationale に「post-merge-feedback Tier 1 #1 で再 validate 済」を追記。

* feat(hooks-post-tool-linter): D-2 lint rule code touch (順位 101/103/106)

Phase D dogfood の 2 本目 (D-2)。lint rule の test gap + struct doc + self-exclusion guards を bundled。

順位 101 (PR #140 T1-#1 採用): rule⑧ depth-1 root MD edge case test 2 件追加
  - md_no_docs_relative_detects_root_level_back_reference (CLAUDE.md fixture)
  - md_no_docs_relative_detects_root_readme_back_reference (README.md fixture)
  - 「fire = true positive」整理を doc comment と test 名で明示
  - root-level MD からの ../docs/ 参照は repo 外を指す broken link で真陽性が正しい挙動

順位 103 (PR #140 T1-#3 採用): CustomRule struct に lint runner field reference doc comment 追加
  - サポート field 一覧 (id/pattern/severity/message/extensions/why/fix/example) を /// で記述
  - planned field (paths、順位 102) も併記し設計-実装 gap を構造的に予防
  - custom-lint-rules.toml 冒頭コメントに main.rs CustomRule struct への動線追加

順位 106 (PR #141 T2-#1 採用): self-exclusion invariant test に 2 false-green guards 追加
  - assert!(path.exists()) — deployed TOML 削除 / 移動時の silent pass 抑止
  - assert!(extensions contains "toml") — rule scope 変更時の silent degradation 抑止
  - 各 assertion message に silent degradation のリスクと由来 (順位 106 / PR #141 T2-#1) を inline で記述

cargo test pass: hooks-post-tool-linter 95 tests (新規 2 + 既存 +1 強化、ZERO regression)。

PR #145 = D-1 と同様、lint_screen dogfood は順位 115 (env var override) land 前のため skip。
aloekun added a commit that referenced this pull request May 12, 2026
…hase D D-3)

PR #140 post-merge-feedback Tier 1 #2 採用。lint runner に glob ベースの paths filter
を追加し、path-sensitive な lint rule を explicit filter で表現可能にする。

実装 (src/hooks-post-tool-linter/src/main.rs + Cargo.toml):
  - globset = 0.4 を依存追加 (BurntSushi 製、ripgrep の依存と同じ)
  - CustomRule::paths: Option<Vec<String>> field 追加 (optional、既存 rule に影響なし)
  - CompiledRule に paths_glob: Option<GlobSet> を cache (lint 実行時の repeated compile を回避)
  - compile_paths_glob() helper: None / Some(empty) → None (filter なし)、glob valid → Some(GlobSet)、invalid → Err (rule drop)
  - rule_matches_path() helper: paths_glob None なら全 path 受容、Some なら GlobSet match で判定
  - Windows-style backslash path も  に normalize して match
  - run_custom_rules で extensions × paths を AND 結合 (両方マッチで rule 対象)
  - 関数長 50 行制限維持のため build_violation_json / collect_violations_for_rule に切り出し
  - CustomRule doc comment の planned: paths → supported: paths に更新

unit test 7 件追加:
  - paths_filter_none_accepts_any_path
  - paths_filter_empty_vec_accepts_any_path
  - paths_filter_recursive_glob_matches_docs_only
  - paths_filter_normalizes_windows_separators
  - paths_filter_multiple_globs_or_semantics
  - paths_filter_invalid_glob_drops_rule
  - run_custom_rules_extensions_and_paths_are_anded (AND 結合 E2E)

意図的保留 (順位 118 として todo 化):
  - rule⑧ への paths = ["docs/**/*.md"] migration は当初計画していたが、D-2 (順位 101)
    で追加した root-level MD (CLAUDE.md / README.md) からの ../docs/ fire 挙動が
    scope narrow で壊れるため保留。trade-off 検討は別 PR に分離。

cargo test pass: hooks-post-tool-linter 102 tests (新規 7 + 既存 95、ZERO regression)。

Phase D D-3: 順位 115 (PR #147) land 後の **初の real lint_screen dogfood**。
LINT_SCREEN_ENABLED=true 経路で push pipeline 経由 lint_screen を実行し、metrics
(screen_decision / findings / fallback_reason / Diagnostic section / latency) を観測。
aloekun added a commit that referenced this pull request May 12, 2026
…hase D D-3) (#148)

PR #140 post-merge-feedback Tier 1 #2 採用。lint runner に glob ベースの paths filter
を追加し、path-sensitive な lint rule を explicit filter で表現可能にする。

実装 (src/hooks-post-tool-linter/src/main.rs + Cargo.toml):
  - globset = 0.4 を依存追加 (BurntSushi 製、ripgrep の依存と同じ)
  - CustomRule::paths: Option<Vec<String>> field 追加 (optional、既存 rule に影響なし)
  - CompiledRule に paths_glob: Option<GlobSet> を cache (lint 実行時の repeated compile を回避)
  - compile_paths_glob() helper: None / Some(empty) → None (filter なし)、glob valid → Some(GlobSet)、invalid → Err (rule drop)
  - rule_matches_path() helper: paths_glob None なら全 path 受容、Some なら GlobSet match で判定
  - Windows-style backslash path も  に normalize して match
  - run_custom_rules で extensions × paths を AND 結合 (両方マッチで rule 対象)
  - 関数長 50 行制限維持のため build_violation_json / collect_violations_for_rule に切り出し
  - CustomRule doc comment の planned: paths → supported: paths に更新

unit test 7 件追加:
  - paths_filter_none_accepts_any_path
  - paths_filter_empty_vec_accepts_any_path
  - paths_filter_recursive_glob_matches_docs_only
  - paths_filter_normalizes_windows_separators
  - paths_filter_multiple_globs_or_semantics
  - paths_filter_invalid_glob_drops_rule
  - run_custom_rules_extensions_and_paths_are_anded (AND 結合 E2E)

意図的保留 (順位 118 として todo 化):
  - rule⑧ への paths = ["docs/**/*.md"] migration は当初計画していたが、D-2 (順位 101)
    で追加した root-level MD (CLAUDE.md / README.md) からの ../docs/ fire 挙動が
    scope narrow で壊れるため保留。trade-off 検討は別 PR に分離。

cargo test pass: hooks-post-tool-linter 102 tests (新規 7 + 既存 95、ZERO regression)。

Phase D D-3: 順位 115 (PR #147) land 後の **初の real lint_screen dogfood**。
LINT_SCREEN_ENABLED=true 経路で push pipeline 経由 lint_screen を実行し、metrics
(screen_decision / findings / fallback_reason / Diagnostic section / latency) を観測。
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