Skip to content

refactor(hooks): 3 hook の main.rs を module 分割 (PR-3a、file_length lint 違反解消) - #217

Merged
aloekun merged 4 commits into
masterfrom
pr3a-hooks-module-split
Jun 23, 2026
Merged

refactor(hooks): 3 hook の main.rs を module 分割 (PR-3a、file_length lint 違反解消)#217
aloekun merged 4 commits into
masterfrom
pr3a-hooks-module-split

Conversation

@aloekun

@aloekun aloekun commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

PR-3 (layered config refactor) の前置 PR。3 hook の main.rs を coding-style.md § File Organization (800 行 max) 内に収まる module 構成に分割。behavior 不変 な mechanical refactor で関数 signature・公開 API・field 名・default 値はすべて保持。

順位 147 (file_length lint、PR #202 で land) が touch-trigger ratchet 違反として検出した 3 hook の触れない技術債務を解消し、PR-3b (layered config) を clean state で進められるようにする。

分割結果

crate 旧 main.rs 行数 新構成 最大 file 行数 tests
hooks-session-start 1611 行 7 modules (+ 既存 past_time.rs) 572 行 (reaper.rs) 71 件
hooks-pre-tool-validate 2914 行 14 modules (presets/ + presets/safety/ sub-tree) 461 行 (todo_staleness.rs) 221 件
hooks-post-tool-linter 3316 行 14 modules (custom_rules/ sub-tree) 575 行 (rule_tests.rs) 145 件

全 file ≤ 575 行 (800 行制限の 72% 以下)。tests 計 437 件、変動なし。

分割方針

hooks-session-start

  • reaper.rs — TaktMeta + OrphanRun + orphan scan / mark / reap (ADR-030 §L2)
  • pr_monitor.rs — ParkedStatePartial + catch-up nudge
  • staleness.rs — working copy staleness 検出 (順位 136 案 A)
  • weekly_review.rs — ADR-031 Phase C reminder
  • hooks_config.rs — Config 構造体 + load_config
  • jj_helpers.rs — run_jj_with_timeout / count_commits_in_revset / fetch_head_is_recent
  • main.rs — entry + dispatch (339 行)

hooks-pre-tool-validate

  • presets/{basic,jj,gh}.rs + presets/safety/{polling_exe,powershell,secret}.rs — 13 BlockedPattern preset 関数
  • blocked_patterns.rs — BlockedPattern 構造体 + validate_command + build_blocked_patterns
  • protected_files.rs — PROTECTED_CONFIG_FILES + is_protected_config
  • todo_staleness.rs — TodoStalenessConfig + check_todo_staleness + jj log helpers
  • handlers.rs — Bash/Edit/Write/PowerShell handlers
  • config.rs / main.rs — entry + dispatch

hooks-post-tool-linter

  • custom_rules/{engine,types,coverage,deployed_tests,engine_tests,rule_tests,rule_tests_extras}.rs — regex rule engine + per-rule positive/negative tests
  • pipeline_runner.rs — lint pipeline 実行 (Biome / oxlint / ruff / markdownlint)
  • file_size_check.rs — 50KB threshold check
  • utf8_integrity.rs — UTF-8 整合性 check
  • violation.rs — Violation 構造体 + emit_feedback
  • config.rs / main.rs — entry + dispatch

behavior 不変性の保証

  • 関数 signature 変更なし、struct field rename なし、default 値変更なし
  • 公開 API (cross-module で参照される関数) は pub(crate) 付与のみ、export 経路は同等
  • cargo test --workspace: 全 crate pass (本 PR 関連の 437 件含む)
  • cargo clippy --workspace -- -D warnings: clean
  • cargo fmt: clean

非機能的な変更点

  • comment policy 準拠: 各 hook の関数 body 内に存在した // foo 形式の非 doc コメント (見出し / inline rationale / セクション banner 等) を削除。comment-lint-rust hook の Bundle Z #B-α rule に従い識別子名 / 関数名 / doc comment に意図を集約。Pre-existing の grandfather 状態だったが、Write tool で新規 file 作成すると新規コメント扱いで block されるため、移動時に整理した。
  • test 内 helper の per-module 複製: unique_temp_root / write_meta / parked_state / patterns_with_presets / is_blocked / build_todo_path / make_test_rule / compile_test_rules / write_file 等の test helper は memory feedback_test_dry_antipattern に従い各 test module に独立コピー (合計 ~4 重複)。共有 test util module の抽出は anti-pattern。
  • test fixture の secret pattern 表現: hooks-pre-tool-validate の secret-detection test で format!("{}{}", "AKIA", "...") 形式を採用 (literal AWS / GitHub / OpenAI key を Edit/Write tool 経由で書き込むと secret-detection hook (順位 146) 自身が発火するため、test fixture を dogfood 経由で書く必要があり)。runtime 上は regex match と等価。
  • hooks-post-tool-linter の rule_test_coverage_check 適応: 元実装は src/main.rs 1 file の test 関数名を抽出していたが、split 後は test が複数 module に分散するため src/**/*.rs を recursive walk するように rewrite。TOML main_ext_tests / other_ext_tests の宣言と実 test 関数名の整合性 check は引き続き機能。
  • extract_existing_test_fn_names の false-green guard: 関数自身が coverage.rs に居るため、coverage check が間違って空 set を返した場合に自分自身を含まない結果になる guard は維持。

pr_size_check override の理由

本 PR の jj diff は 15636 行 (= 削除 ~8000 行 + 追加 ~8000 行) で push-runner の pr_size_check block_threshold 1500 を超過したが、これは「mechanical refactor で同じ code を別 file に移動」した結果で、pr_size_check の想定する「実装 work が大きすぎる」case ではない。PR_SIZE_CHECK_OVERRIDE=1 で override (= 順位 151 の override 想定 use case「大型 refactoring 等で意図的な場合」)。

case A2 (hook 単位 3 PR に分割) も検討したが、3 hook 同時 split で workspace-wide 整合性を確認できるメリットを優先して 1 PR で進めた (ユーザー判断、2026-06-23)。

Test plan

  • cargo build --workspace: SUCCESS
  • cargo test --workspace: 全 crate pass (本 PR 関連 437 件含む)
  • cargo clippy --workspace -- -D warnings: clean
  • cargo fmt: clean
  • 全 file ≤ 800 行 (最大 575 行)
  • rule_test_coverage_check pass (post-tool-linter の TOML meta field 整合性、split 対応 rewrite 後)
  • takt pre-push-review approved (1 iteration、15m 16s)

PR 計画における位置

PR-1 (順位 147/151/212-214 削除 + weekly enable、merged #216) → 本 PR (PR-3a) → PR-3b (layered config + lib-hooks-config + ADR-039 amendment) → PR-2 (Stop hook todo cleanup check)

PR-3a の land 後に PR-3b で [features].enabled allow-list pattern に移行し、各 hook の enabled: Option<bool> field を削除する。本 PR で clean state を確立したことで、PR-3b の diff は logical な refactor のみに focus できる。

Summary by CodeRabbit

リリースノート

  • New Features
    • カスタムリントルールの自動検証(カバレッジ確認含む)と、UTF-8整合性・検証パイプライン実行、ファイルサイズ閾値チェックを追加。
    • 事前バリデーションを強化(危険コマンド/秘密情報/ドキュメント鮮度などを検知してブロック)。
    • セッション開始時のリマインド、オーファン回収、再開案内、鮮度/週次案内を追加。
  • Documentation
    • 推奨実行順序サマリーを更新。
  • Bug Fixes
    • ISO8601解析の厳密な扱いを調整。

aloekun added 2 commits June 23, 2026 12:16
…/T3-3)

PR #216 (cleanup-stale-todo-weekly-enable) の post-merge-feedback で 6 提案中
4 件 (T1-1 / T3-1 / T3-2 / T3-3) をユーザー承認 (2026-06-23) し
docs/todo-summary.md + docs/todo10.md に entry 化:

- 順位 216 (🔧 Tier 2、Bundle 216-217): `no-workstream-seq-names-in-config`
  lint rule 追加 — config comment 内 `PR-[0-9]+` ephemeral workstream
  sequence の機械的検出。analyzer Tier 1 分類は memory
  feedback_tier_classification に従い project Tier 2 (mechanical = T2) に再分類。

- 順位 217 (💎 Tier 3、Bundle 216-217): coding-style.md § Cross-File
  Reference Lifecycle に config file comments の permanent artifact 扱い明記 +
  workstream sequence 禁止例追加 (順位 216 の文書層補完、2 層防御)。

- 順位 218 (💎 Tier 3): ADR-039 § Bounded Lifetime + patterns.md に
  provisional `enabled` 変更時の todo entry 必須化を追加
  (config comment-only tracking の silent aging 防止)。

- 順位 219 (💎 Tier 3): development-workflow.md § 設計 doc/実装の同期チェック
  に「commit description 言及 ≠ 実装完了」明文化 (PR #216 cleanup での
  順位 215 救出事例を inline cite、analyzer naïve assumption の構造的予防)。

採用されなかった T2-1 / T2-2 (analyzer cross-check / provisional auto-detect) は
🤔 様子見継続。Frequency Low 初観測 + Effort M + takt test infra 未調査のため、
2 PR 以上の再観測後に Tier 1 昇格を再評価する方針。

ファイル変更:
- docs/todo-summary.md: table に 4 rows 追加 (順位 215 直後、lines 89-92)
- docs/todo10.md: 詳細 entry 4 件追加 ("## 既知課題" 直前、lines 512/568/620/674)
…s-post-tool-linter を module 分割

3 hook crate の main.rs を coding-style.md § File Organization (800 行 max) 内に収まる module 構成に分割。behavior 不変な mechanical refactor で、各関数の signature / export 関係は維持し、test も co-located mod tests として各 module に分散する。

PR-3 (layered config refactor) の前置 PR (PR-3a)。順位 147 (file_length lint) が PR #202 で land、本 PR-3a で 3 hook の touch-trigger ratchet 違反を解消することで PR-3b (layered config) を clean state で進められる。

対象:
- src/hooks-session-start/src/main.rs (1611 行) → 6-7 module
- src/hooks-pre-tool-validate/src/main.rs (2914 行) → 5-7 module
- src/hooks-post-tool-linter/src/main.rs (3316 行) → 6-8 module

完了基準:
- 全 module ファイルが 800 行以下
- cargo clippy --workspace -- -D warnings clean
- cargo test --workspace pass (behavior 不変)
- PostToolUse comment-lint-rust の file_length lint 0 件
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

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: fa776d39-6eaa-422a-a78e-bfd77a631572

📥 Commits

Reviewing files that changed from the base of the PR and between 4384d82 and f39f0b0.

📒 Files selected for processing (1)
  • docs/todo10.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/todo10.md

📝 Walkthrough

Walkthrough

3つの Claude フックバイナリ(hooks-post-tool-linter、hooks-pre-tool-validate、hooks-session-start)を大規模に新規実装・リファクタリング。post-tool-linter にカスタムルールエンジン・UTF-8 整合性・ファイルサイズ・パイプライン lint を追加し、pre-tool-validate にブロックパターンプリセットライブラリと todo staleness 検知を追加し、session-start の nudge 生成ロジックをサブモジュールへ分離。docs の todo バックログに4件の新規タスクを追記。

Changes

hooks-post-tool-linter: カスタムルールエンジン・lint レイヤ新規実装

Layer / File(s) Summary
違反出力型・Config・カスタムルール型定義
src/hooks-post-tool-linter/src/violation.rs, src/hooks-post-tool-linter/src/config.rs, src/hooks-post-tool-linter/src/custom_rules/types.rs, src/hooks-post-tool-linter/src/custom_rules/mod.rs
LintViolation/HookOutput/emit_feedback の共通出力型と Config/PipelineConfig/default_pipelines/load_config を定義し、CustomRule/CompiledRule/CustomRuleTestCoverage など TOML デシリアライズ型を追加する。
カスタムルールエンジン(compile・match・run)
src/hooks-post-tool-linter/src/custom_rules/engine.rs, src/hooks-post-tool-linter/src/custom_rules/engine_tests.rs
custom-lint-rules.toml を読み込み、regex と glob を CompiledRule にプリコンパイルし、ファイル走査・行番号算出・MAX_CUSTOM_VIOLATIONS 打ち切り・emit_feedback 発火を行う一連のエンジンを実装し、拡張子/paths フィルタ・行番号・上限・マルチバイトを網羅テストする。
デプロイ済みルール回帰テストとテストカバレッジ強制
src/hooks-post-tool-linter/src/custom_rules/deployed_tests.rs, src/hooks-post-tool-linter/src/custom_rules/coverage.rs
デプロイ済み custom-lint-rules.toml の自己トリガ不在・PowerShell (?i) フラグ・write 結果破棄・takt workflow persona 回帰を広域テストし、各ルールの test_coverage フィールドの実在性・関数名整合性を CI で強制する。
ルール別ユニットテスト
src/hooks-post-tool-linter/src/custom_rules/rule_tests.rs, src/hooks-post-tool-linter/src/custom_rules/rule_tests_extras.rs
no-personal-paths / no-empty-powershell-catch / no-silent-error-action / no-mutable-anchor / no-time-field-strict-greater / no-docs-relative-back-to-docs / no-ephemeral-todo-reference / takt-workflow-persona-without-model / no-write-result-discard / no-jj-template-first-line / no-hardcoded-jj-revset-range の positive/negative テストを追加する。
UTF-8 整合性・ファイルサイズ閾値・パイプラインランナー
src/hooks-post-tool-linter/src/utf8_integrity.rs, src/hooks-post-tool-linter/src/file_size_check.rs, src/hooks-post-tool-linter/src/pipeline_runner.rs
U+FFFD 行検出、glob+閾値超過時の回復ヒント付きフィードバック、拡張子一致パイプラインを選択して biome/oxlint/ruff ステップを順次実行する3つの独立した lint レイヤを追加する。

hooks-pre-tool-validate: プリセット・保護ファイル・staleness 実装

Layer / File(s) Summary
Config・ToolInput 公開化・BlockedPattern 型と validate_command
src/hooks-pre-tool-validate/src/config.rs, src/hooks-pre-tool-validate/src/main.rs, src/hooks-pre-tool-validate/src/blocked_patterns.rs
ToolInputpub(crate) 化して main.rs を配線専用に整理し、BlockedPattern(pattern + exception + message)と build_blocked_patterns/validate_command を追加する。Config/TodoStalenessConfig の TOML 読込も提供する。
プリセットライブラリ: basic / gh / jj + mod dispatcher
src/hooks-pre-tool-validate/src/presets/basic.rs, src/hooks-pre-tool-validate/src/presets/gh.rs, src/hooks-pre-tool-validate/src/presets/jj.rs, src/hooks-pre-tool-validate/src/presets/mod.rs
rm -rf/cd /d/git/electron/gh pr create・merge/jj-immutable/main-guard/push-guard/message-required の各プリセットを定義し、default_preset_namesresolve_preset_or_custom でディスパッチする。jj-message-required は -m/--message 例外の2段判定を実装する。
safety プリセット: polling / exe-help / powershell / secret
src/hooks-pre-tool-validate/src/presets/safety/...
ポーリングループ・--help 単独実行・PowerShell 破壊的書き込み(__ scratch 例外付き)・AWS/OpenAI/GitHub/Anthropic API キーの各ブロックプリセットと網羅テストを追加する。
保護ファイル判定・todo staleness 検知・ハンドラ実装
src/hooks-pre-tool-validate/src/protected_files.rs, src/hooks-pre-tool-validate/src/todo_staleness.rs, src/hooks-pre-tool-validate/src/handlers.rs
PROTECTED_CONFIG_FILESis_protected_config、jj サブプロセスで ahead 計測と commit ログパースを行う fail-closed staleness 検知、Bash/PowerShell/Write-Edit の3ハンドラ(保護→secret→staleness 順で検査)を実装する。

hooks-session-start: nudge 生成ロジックをサブモジュール分離

Layer / File(s) Summary
HooksConfig・jj helpers
src/hooks-session-start/src/hooks_config.rs, src/hooks-session-start/src/jj_helpers.rs
TOML の [session_start] セクションを fail-open デシリアライズする HooksConfig/read_hooks_config と、FETCH_HEAD 鮮度判定・タイムアウト付き jj 実行・revset commit カウントの3ユーティリティを追加する。
PR monitor catch-up nudge・orphan reaper
src/hooks-session-start/src/pr_monitor.rs, src/hooks-session-start/src/reaper.rs, src/hooks-session-start/src/past_time.rs
pr-monitor-state.jsonparked_* 判定で catch-up nudge を生成し、.takt/runs の orphan PMF run を検出して .failed マーカー作成・meta 更新・reaper nudge を返す。parse_iso8601_to_unix を reaper モジュールへ移管する。
staleness nudge・weekly review reminder
src/hooks-session-start/src/staleness.rs, src/hooks-session-start/src/weekly_review.rs
fetch 鮮度チェック後に @-..default_branch の ahead 数で staleness nudge を生成し、weekly-review-last-run.json mtime と .md.failed マーカー存在から weekly-review スキル起動 reminder を生成する。
main.rs リファクタ: session_id 伝播・nudge 委譲
src/hooks-session-start/src/main.rs
main.rs を session_id 読み取り・CLAUDE_ENV_FILE 伝播・.session-id 冪等的永続化に絞り込み、nudge 生成を各サブモジュールの imported 関数へ委譲する。大量のハンドラ実装・テストが削除されてサブモジュールへ移動。

docs・その他: todo バックログ追記・ISO8601 厳密化

Layer / File(s) Summary
todo-summary・todo10 へのバックログ追記
docs/todo-summary.md, docs/todo10.md
todo-summary.md に順位 216〜219 の4行を追加し、todo10.mdno-workstream-seq-names-in-config lint 追加・coding-style.md 更新・ADR-039 追記・development-workflow.md ガイド追記の詳細 todo ブロックを追加する。
rate_limit.rs: ISO8601 末尾 Z 処理の厳密化
src/check-ci-coderabbit/src/rate_limit.rs
ISO 8601 文字列末尾の Z 削除が trim_end_matches から strip_suffix に変更され、末尾に厳密に Z がない入力は parse 失敗になる。

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • aloekun/claude-code-hook-test#165: test_coverage フィールドのルールカバレッジ機構を導入した PR であり、本 PR の coverage.rs が同機構の検証強制を実装するため直接関連する。
  • aloekun/claude-code-hook-test#162: 本 PR の src/hooks-pre-tool-validate/src/todo_staleness.rs による docs/todo*.md の staleness 検知実装と、retrieved PR の同スキーム doc 記述(todo-summary 順位136)が直結している。
  • aloekun/claude-code-hook-test#204: FileSizeCheckConfig/check_file_size_threshold/run_file_size_layer の同一コンポーネントを実装・拡張する PR であり、本 PR と機能レベルで直接重複する。
🚥 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 タイトルは main.rs モジュール分割によるファイル長違反の解消という main 変更をカバーしており、関連内容と一致しています。
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.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hooks-session-start/src/main.rs (1)

163-175: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

env file の重複判定を exact export 行にしてください。

Line 164 の contains(marker) だとコメントや OLD_CLAUDE_CODE_SESSION_ID でも skip し、別 session の古い export も更新されません。Line 221-235 の test も stale 値を許す期待値になっています。

修正案
 fn write_to_env_file(env_file: &str, session_id: &str) {
     let marker = "CLAUDE_CODE_SESSION_ID";
+    let export_line = format!("export {}={}", marker, shell_quote(session_id));
 
     if let Ok(content) = std::fs::read_to_string(env_file) {
-        if content.contains(marker) {
+        if content
+            .lines()
+            .any(|line| line.trim() == export_line.as_str())
+        {
             return;
         }
     }
 
     use std::io::Write;
@@
         .append(true)
         .open(env_file)
     {
-        let _ = writeln!(f, "export {}={}", marker, shell_quote(session_id));
+        let _ = writeln!(f, "{export_line}");
     }
 }
🤖 Prompt for 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.

In `@src/hooks-session-start/src/main.rs` around lines 163 - 175, The current
duplication check using contains(marker) on the file content is too broad and
will match the marker string anywhere including in comments or variable names
like OLD_CLAUDE_CODE_SESSION_ID, preventing proper updates of stale session
values. Instead of checking if the marker exists anywhere in the content, check
for the exact export line pattern (the complete export statement with the
marker) to properly detect and skip re-adding the exact same export while
allowing old stale session exports to be updated with new ones.
🧹 Nitpick comments (8)
docs/todo10.md (2)

549-550: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Task 216 の作業計画: rule_test_coverage_check 通過の確認手順が明記されている。

Line 550 で「cargo test -p hooks-post-tool-linter で rule_test_coverage_check が pass することを確認」と明示されており、前述の test_coverage 不整合を catch する CI gate が機能することが前提とされている(good)。ただし、上記 critical issue (#1 comment で指摘) を修正してから実行する必要があることを明確にするため、作業計画の実行順序を以下に修正すると robustness が上がる:

修正案:

- [ ] extension/test_coverage の不整合を fix (jsonc/json 削除 OR negative test の other_ext_tests 移動)
- [ ] `.claude/custom-lint-rules.toml` に `[[rules]]` entry 追加
- [ ] `src/hooks-post-tool-linter/src/main.rs` の tests に positive/negative test 追加
- [ ] `cargo test -p hooks-post-tool-linter` で rule_test_coverage_check が pass することを確認
🤖 Prompt for 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.

In `@docs/todo10.md` around lines 549 - 550, The task plan in the TODO list does
not explicitly clarify the required execution order for fixing the test coverage
issue. Reorder the items in the list to ensure that the extension/test_coverage
inconsistency fix (either removing jsonc/json or moving negative test's
other_ext_tests) appears BEFORE the steps to add tests in main.rs and BEFORE the
final cargo test verification. This ensures that the rule_test_coverage_check CI
gate will pass once all preceding fixes are completed, making the task sequence
more robust and easier to follow.

512-567: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Task 216 の実装可能性: comment 行限定の段階導入。

Line 531 で「MVP は file 全体 match で開始、false positive 観測後に comment 行限定への絞り込みを判断」と明記されており、段階導入の方針は適切。ただし comment 行 only 検出の技術的課題 (TOML/YAML/JSON の comment syntax が異なる、regex では単純な ^# では充分でない) を追加で注記するとより clear。

例えば:

  • TOML: # で行が始まる(シンプル)
  • YAML: # で行が始まる(同様)
  • JSON/JSONC: comment は // または /* */ (regex 複雑化)
  • config comment 限定を後で実装する場合、config parser (e.g., toml crate の comment node 分別) に依存する必要が出てくる可能性

Line 563-564 の「詰まっている箇所」で既に言及されているため、実装前の留意点としては十分だが、初期 MVP の「file 全体 match」が jsonc/json に対して FP を大量生成するリスク(コード内コメント、git diff, markdown 等の埋め込みで誤検出)も併記するとより helpful。

🤖 Prompt for 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.

In `@docs/todo10.md` around lines 512 - 567, Add technical implementation caveats
to the "詰まっている箇所" section of the design decision to clarify the challenges of
transitioning from file-wide match to comment-only detection. Specifically note
that TOML and YAML use `#` for comments (simple regex), but JSONC and JSON use
`//` or `/* */` (complex regex), and that comment-line-only filtering may
require config parser support rather than regex alone. Additionally, document
that the MVP file-wide match approach carries significant false positive risk
for JSONC and JSON formats due to code comments, embedded diffs, and markdown
blocks that could accidentally trigger the `PR-[0-9]+` pattern, and this risk
should inform the decision to narrow scope after initial false positive
observations.
src/hooks-post-tool-linter/src/config.rs (2)

94-149: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

デフォルトパイプラインのツール依存性を文書化してください。

TypeScript パイプラインは biomeoxlint を、Python パイプラインは ruff を前提としていますが、これらのツールがインストールされていない場合の動作は未定義です。npx --no-install は既存インストールを要求します。

実行時にツールが見つからない場合のエラーハンドリングは pipeline_runner.rs で行われていると思われますが、README または設定ファイルのコメントでこれらの前提条件を文書化することを推奨します。

🤖 Prompt for 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.

In `@src/hooks-post-tool-linter/src/config.rs` around lines 94 - 149, The
default_ts_pipeline() and default_py_pipeline() functions have undocumented tool
dependencies that will cause runtime failures if the required tools are not
installed. Add documentation comments to both functions clearly stating the
required external tools: biome and oxlint for the TypeScript pipeline, and ruff
for the Python pipeline. These comments should explain that npx --no-install
requires tools to be pre-installed, and optionally reference that error handling
for missing tools is handled in pipeline_runner.rs.

153-158: 📐 Maintainability & Code Quality | 🔵 Trivial

current_exe() 失敗時の明示的なログ出力を追加してください。

current_exe() が失敗した場合、エラーログなしでカレントディレクトリ (".") にフォールバックします。設定ファイルが見つからない時のデバッグを容易にするため、失敗時に警告ログを出力することを検討してください。例えば、config_path() 内で失敗時に eprintln!() で通知すると、設定ファイルの解決経路がより明確になります。

🤖 Prompt for 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.

In `@src/hooks-post-tool-linter/src/config.rs` around lines 153 - 158, The
config_path() function silently falls back to the current directory when
current_exe() fails, without any notification or logging to help with debugging.
Add explicit logging using eprintln!() or a similar mechanism to warn the user
when current_exe() fails and the function is falling back to the default path.
This will make the configuration file resolution path more transparent and aid
in troubleshooting when config files cannot be found.
src/hooks-post-tool-linter/src/violation.rs (1)

64-66: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

シリアライゼーション失敗時のサイレントエラーに対処してください。

serde_json::to_string(&output)Err を返した場合、フィードバックが出力されず、エラーログも記録されません。本番環境でこの状況が発生すると、違反が検出されたにもかかわらずユーザーに通知されない可能性があります。

Err 時に stderr へログを出力することを推奨します。

📝 提案する修正
-    if let Ok(json) = serde_json::to_string(&output) {
-        println!("{}", json);
+    match serde_json::to_string(&output) {
+        Ok(json) => println!("{}", json),
+        Err(e) => eprintln!("[post-tool-linter] Warning: Failed to serialize feedback: {}", e),
     }
🤖 Prompt for 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.

In `@src/hooks-post-tool-linter/src/violation.rs` around lines 64 - 66, The code
block handling the serialization of output to JSON currently only handles the
successful case with the Ok branch, but silently ignores any serialization
errors when serde_json::to_string(&output) returns Err. Add an else branch or
convert the if let to a match statement to handle the Err case, and log the
error details to stderr using eprintln! or similar error logging mechanism so
that serialization failures are visible to the user instead of being silently
ignored.
src/hooks-post-tool-linter/src/custom_rules/engine.rs (2)

105-114: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

PowerShell の大文字小文字非区別フラグ検出ロジックを強化してください。

現在の実装は単純な部分文字列マッチ (pattern.contains("(?i)")) を使用しています。これは (?im)(?is) などの複合フラグを持つパターンを検出しません。

より堅牢な検出のため、正規表現の先頭で (? から始まる flags グループ内に i が含まれているかを確認することを推奨します。

♻️ 提案する改善
 pub(crate) fn find_powershell_rules_missing_case_insensitive_flag(
     rules: &[CustomRule],
 ) -> Vec<String> {
     rules
         .iter()
         .filter(|r| r.extensions.iter().any(|e| e.eq_ignore_ascii_case("ps1")))
-        .filter(|r| !r.pattern.contains("(?i)"))
+        .filter(|r| {
+            // Check for (?i) or (?im) or (?is) etc. at start of pattern
+            !r.pattern.starts_with("(?i") && !r.pattern.contains("(?")
+                .then(|| r.pattern.split("(?").nth(1))
+                .flatten()
+                .and_then(|flags| flags.split(')').next())
+                .map_or(true, |flags| !flags.contains('i'))
+        })
         .map(|r| r.id.clone())
         .collect()
 }

または、シンプルに正規表現を使用:

use regex::Regex;
let flag_pattern = Regex::new(r"\(\?[a-z]*i[a-z]*\)").unwrap();
.filter(|r| !flag_pattern.is_match(&r.pattern))
🤖 Prompt for 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.

In `@src/hooks-post-tool-linter/src/custom_rules/engine.rs` around lines 105 -
114, The filter condition in the
find_powershell_rules_missing_case_insensitive_flag function currently checks
only for the exact substring "(?i)" using pattern.contains(), which misses
case-insensitive flags combined with other flags like "(?im)" or "(?is)".
Replace the simple substring check with a regex pattern that matches any flag
group starting with "(?", containing the letter 'i' anywhere within that group,
and ending with ")" to properly detect all variations of case-insensitive flags.
This ensures the function correctly identifies PowerShell rules that have
case-insensitive matching enabled regardless of what other flags are present.

174-174: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

シリアライゼーション失敗時のログ出力を検討してください。

serde_json::to_string(&violation).ok() は失敗時に None を返しますが、エラーはログに記録されません。これは violation.rsemit_feedback と同じパターンですが、デバッグ時に問題の特定が困難になる可能性があります。

失敗ケースは稀ですが、一貫性のため emit_feedback と同様のエラーログを追加することを検討してください。

🤖 Prompt for 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.

In `@src/hooks-post-tool-linter/src/custom_rules/engine.rs` at line 174, The
`serde_json::to_string(&violation).ok()` call silently discards serialization
errors without logging them, making debugging difficult. Instead of using
`.ok()`, handle the error case explicitly and add logging similar to the pattern
used in `emit_feedback` from violation.rs. When serialization fails, log the
error before returning None to maintain consistency across the codebase and aid
in troubleshooting.
src/hooks-post-tool-linter/src/pipeline_runner.rs (1)

72-72: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Config を参照渡しにすることを検討してください。

現在、run_pipeline_layerconfig: Config を値渡しで受け取っていますが、Config 構造体のサイズによっては非効率な可能性があります。&Config に変更することで不要なコピーやムーブを回避できます。

♻️ 提案される修正
-pub(crate) fn run_pipeline_layer(file: &str, config: Config) {
+pub(crate) fn run_pipeline_layer(file: &str, config: &Config) {
     let pipelines = config
         .post_tool_linter
+        .as_ref()
-        .and_then(|c| c.pipelines)
+        .and_then(|c| c.pipelines.as_ref())
         .unwrap_or_else(default_pipelines);

注: default_pipelines() の戻り値型によっては追加の調整が必要になる場合があります。

🤖 Prompt for 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.

In `@src/hooks-post-tool-linter/src/pipeline_runner.rs` at line 72, The
`run_pipeline_layer` function receives `config: Config` by value, which can be
inefficient if the Config struct is large. Change the parameter in the
`run_pipeline_layer` function signature from `config: Config` to `config:
&Config` to use a reference instead. Then update all usages of `config` within
the function body to work with the reference (adding dereferences where needed),
and update all call sites of `run_pipeline_layer` to pass a reference to the
config argument instead of moving the value. Check that any function calls
within `run_pipeline_layer` that receive config as an argument are compatible
with the reference type.
🤖 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 `@docs/todo10.md`:
- Line 532: In the docs/todo10.md file around line 532, there is a markdown
formatting inconsistency where the second quoted text has mismatched backticks.
The text currently shows 「PR `#216``」 with a closing backtick but no opening
backtick. Fix this by either adding the missing opening backtick to make it 「`PR
`#216``」 to match the formatting of 「`#216`」, or alternatively remove both
backticks entirely and use just 「PR `#216`」 to maintain consistency. Choose
whichever formatting style is more appropriate for the document's conventions.
- Line 530: The extensions list in the `extensions` declaration at line 530
includes `jsonc` and `json`, but the test coverage section in
`[rules.test_coverage.main_ext_tests]` (lines 541-543) only covers `toml`,
`yaml`, and `yml`. This mismatch will cause `check_main_ext_keys_sanity()` in
`src/hooks-post-tool-linter/src/custom_rules/coverage.rs` to fail during CI.
Additionally, the `no_workstream_seq_skips_github_pr_number` test at line 541 is
a negative test (based on `skips_*` naming convention) but is incorrectly placed
in `main_ext_tests` which expects positive tests. Either remove `jsonc` and
`json` from the extensions list to match the current test coverage, or add
corresponding positive test declarations for these formats in the
`main_ext_tests` section, and move the negative test
`no_workstream_seq_skips_github_pr_number` from `main_ext_tests` to an
`other_ext_tests` section while adding the appropriate positive tests.

In `@src/hooks-pre-tool-validate/src/config.rs`:
- Line 32: The constant TODO_STALENESS_DEFAULT_BRANCH is set to "master", but
the repository branch strategy uses "main" as the default branch (as evidenced
by jj.rs preset messages). When staleness checking is enabled without an
explicit default_branch configuration, this constant is used as the fallback
value, causing count_commits_branch_ahead to return None for the non-existent
"master" branch, which results in all todo file edits being incorrectly blocked.
Change the value of TODO_STALENESS_DEFAULT_BRANCH from "master" to "main" to
align with the actual repository branch strategy.

In `@src/hooks-pre-tool-validate/src/todo_staleness.rs`:
- Around line 53-83: The `run_jj_with_timeout` function has a deadlock risk
because it calls `try_wait()` to wait for process completion before reading
stdout with `read_to_end()`. If the `jj` command produces output exceeding the
OS pipe buffer capacity (approximately 64KB on Linux), the child process will
block on write and never exit, causing the timeout loop to reach the deadline,
kill the process, and always return None. Fix this by reading stdout
concurrently in a separate thread while the process is running, rather than
reading it after waiting for the process to exit. Alternatively, switch to using
`Command::output()` which handles concurrent reading internally.

In `@src/hooks-session-start/src/jj_helpers.rs`:
- Around line 32-58: The issue is that stdout is piped from the child process
but not read until after the process completes (in the Ok(Some(status)) branch),
which can cause a deadlock if the jj output exceeds the pipe buffer size. The
child process will block trying to write to stdout while the parent waits on
try_wait(), preventing progress. To fix this, spawn a separate thread to drain
the piped stdout in the background while the main thread continues polling with
try_wait(). Move the stdout reading logic that currently happens after
child.stdout.take() into a dedicated thread that starts immediately after
Command::new("jj") spawns, so the pipe buffer is continuously drained regardless
of when the process completes.

In `@src/hooks-session-start/src/reaper.rs`:
- Around line 58-60: The parse_iso8601_to_unix function does not properly
validate ISO 8601 timestamps before parsing them. Currently, it unconditionally
discards content after the first dot and removes the trailing 'Z', which allows
invalid timestamps like "2026-05-13T12:33:23.bad" or strings with timezone
offsets to be treated as valid UTC times, causing false positives in orphan
detection. To fix this, validate that the input string is a valid UTC ISO 8601
timestamp by confirming it ends with the 'Z' suffix and that any fractional
seconds portion (between the dot and 'Z') contains only numeric digits before
removing these parts. Reject any timestamps that have timezone offsets or
invalid fractional parts instead of silently discarding them.
- Around line 232-240: The code has a race condition (TOCTOU issue) between the
existence check on marker and success_report and the subsequent write operation.
Between the check and the std::fs::write call, another process could create the
success_report or marker, leading to false `.failed` markers on successful runs.
Fix this by writing the marker atomically: first write the body returned by
build_reaper_failed_marker_body to a temporary file in the parent directory,
then use atomic rename (std::fs::rename) to move it to the final marker path.
This ensures the marker creation is atomic and prevents race conditions where
concurrent processes could interfere with marker state.

---

Outside diff comments:
In `@src/hooks-session-start/src/main.rs`:
- Around line 163-175: The current duplication check using contains(marker) on
the file content is too broad and will match the marker string anywhere
including in comments or variable names like OLD_CLAUDE_CODE_SESSION_ID,
preventing proper updates of stale session values. Instead of checking if the
marker exists anywhere in the content, check for the exact export line pattern
(the complete export statement with the marker) to properly detect and skip
re-adding the exact same export while allowing old stale session exports to be
updated with new ones.

---

Nitpick comments:
In `@docs/todo10.md`:
- Around line 549-550: The task plan in the TODO list does not explicitly
clarify the required execution order for fixing the test coverage issue. Reorder
the items in the list to ensure that the extension/test_coverage inconsistency
fix (either removing jsonc/json or moving negative test's other_ext_tests)
appears BEFORE the steps to add tests in main.rs and BEFORE the final cargo test
verification. This ensures that the rule_test_coverage_check CI gate will pass
once all preceding fixes are completed, making the task sequence more robust and
easier to follow.
- Around line 512-567: Add technical implementation caveats to the "詰まっている箇所"
section of the design decision to clarify the challenges of transitioning from
file-wide match to comment-only detection. Specifically note that TOML and YAML
use `#` for comments (simple regex), but JSONC and JSON use `//` or `/* */`
(complex regex), and that comment-line-only filtering may require config parser
support rather than regex alone. Additionally, document that the MVP file-wide
match approach carries significant false positive risk for JSONC and JSON
formats due to code comments, embedded diffs, and markdown blocks that could
accidentally trigger the `PR-[0-9]+` pattern, and this risk should inform the
decision to narrow scope after initial false positive observations.

In `@src/hooks-post-tool-linter/src/config.rs`:
- Around line 94-149: The default_ts_pipeline() and default_py_pipeline()
functions have undocumented tool dependencies that will cause runtime failures
if the required tools are not installed. Add documentation comments to both
functions clearly stating the required external tools: biome and oxlint for the
TypeScript pipeline, and ruff for the Python pipeline. These comments should
explain that npx --no-install requires tools to be pre-installed, and optionally
reference that error handling for missing tools is handled in
pipeline_runner.rs.
- Around line 153-158: The config_path() function silently falls back to the
current directory when current_exe() fails, without any notification or logging
to help with debugging. Add explicit logging using eprintln!() or a similar
mechanism to warn the user when current_exe() fails and the function is falling
back to the default path. This will make the configuration file resolution path
more transparent and aid in troubleshooting when config files cannot be found.

In `@src/hooks-post-tool-linter/src/custom_rules/engine.rs`:
- Around line 105-114: The filter condition in the
find_powershell_rules_missing_case_insensitive_flag function currently checks
only for the exact substring "(?i)" using pattern.contains(), which misses
case-insensitive flags combined with other flags like "(?im)" or "(?is)".
Replace the simple substring check with a regex pattern that matches any flag
group starting with "(?", containing the letter 'i' anywhere within that group,
and ending with ")" to properly detect all variations of case-insensitive flags.
This ensures the function correctly identifies PowerShell rules that have
case-insensitive matching enabled regardless of what other flags are present.
- Line 174: The `serde_json::to_string(&violation).ok()` call silently discards
serialization errors without logging them, making debugging difficult. Instead
of using `.ok()`, handle the error case explicitly and add logging similar to
the pattern used in `emit_feedback` from violation.rs. When serialization fails,
log the error before returning None to maintain consistency across the codebase
and aid in troubleshooting.

In `@src/hooks-post-tool-linter/src/pipeline_runner.rs`:
- Line 72: The `run_pipeline_layer` function receives `config: Config` by value,
which can be inefficient if the Config struct is large. Change the parameter in
the `run_pipeline_layer` function signature from `config: Config` to `config:
&Config` to use a reference instead. Then update all usages of `config` within
the function body to work with the reference (adding dereferences where needed),
and update all call sites of `run_pipeline_layer` to pass a reference to the
config argument instead of moving the value. Check that any function calls
within `run_pipeline_layer` that receive config as an argument are compatible
with the reference type.

In `@src/hooks-post-tool-linter/src/violation.rs`:
- Around line 64-66: The code block handling the serialization of output to JSON
currently only handles the successful case with the Ok branch, but silently
ignores any serialization errors when serde_json::to_string(&output) returns
Err. Add an else branch or convert the if let to a match statement to handle the
Err case, and log the error details to stderr using eprintln! or similar error
logging mechanism so that serialization failures are visible to the user instead
of being silently ignored.
🪄 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: f6590c8e-78a5-4c32-ac5f-20fb0de728aa

📥 Commits

Reviewing files that changed from the base of the PR and between e74fd72 and 13e0a86.

📒 Files selected for processing (38)
  • docs/todo-summary.md
  • docs/todo10.md
  • src/hooks-post-tool-linter/src/config.rs
  • src/hooks-post-tool-linter/src/custom_rules/coverage.rs
  • src/hooks-post-tool-linter/src/custom_rules/deployed_tests.rs
  • src/hooks-post-tool-linter/src/custom_rules/engine.rs
  • src/hooks-post-tool-linter/src/custom_rules/engine_tests.rs
  • src/hooks-post-tool-linter/src/custom_rules/mod.rs
  • src/hooks-post-tool-linter/src/custom_rules/rule_tests.rs
  • src/hooks-post-tool-linter/src/custom_rules/rule_tests_extras.rs
  • src/hooks-post-tool-linter/src/custom_rules/types.rs
  • src/hooks-post-tool-linter/src/file_size_check.rs
  • src/hooks-post-tool-linter/src/main.rs
  • src/hooks-post-tool-linter/src/pipeline_runner.rs
  • src/hooks-post-tool-linter/src/utf8_integrity.rs
  • src/hooks-post-tool-linter/src/violation.rs
  • src/hooks-pre-tool-validate/src/blocked_patterns.rs
  • src/hooks-pre-tool-validate/src/config.rs
  • src/hooks-pre-tool-validate/src/handlers.rs
  • src/hooks-pre-tool-validate/src/main.rs
  • src/hooks-pre-tool-validate/src/presets/basic.rs
  • src/hooks-pre-tool-validate/src/presets/gh.rs
  • src/hooks-pre-tool-validate/src/presets/jj.rs
  • src/hooks-pre-tool-validate/src/presets/mod.rs
  • src/hooks-pre-tool-validate/src/presets/safety/mod.rs
  • src/hooks-pre-tool-validate/src/presets/safety/polling_exe.rs
  • src/hooks-pre-tool-validate/src/presets/safety/powershell.rs
  • src/hooks-pre-tool-validate/src/presets/safety/secret.rs
  • src/hooks-pre-tool-validate/src/protected_files.rs
  • src/hooks-pre-tool-validate/src/todo_staleness.rs
  • src/hooks-session-start/src/hooks_config.rs
  • src/hooks-session-start/src/jj_helpers.rs
  • src/hooks-session-start/src/main.rs
  • src/hooks-session-start/src/past_time.rs
  • src/hooks-session-start/src/pr_monitor.rs
  • src/hooks-session-start/src/reaper.rs
  • src/hooks-session-start/src/staleness.rs
  • src/hooks-session-start/src/weekly_review.rs

Comment thread docs/todo10.md Outdated
Comment thread docs/todo10.md Outdated
Comment thread src/hooks-pre-tool-validate/src/config.rs
Comment thread src/hooks-pre-tool-validate/src/todo_staleness.rs Outdated
Comment thread src/hooks-session-start/src/jj_helpers.rs Outdated
Comment thread src/hooks-session-start/src/reaper.rs
Comment thread src/hooks-session-start/src/reaper.rs
…llow-up)

PR #217 (pr3a-hooks-module-split) の CodeRabbit review で検出された
Critical / Major / Minor findings を takt post-pr-review の 3 iter fix で
解消した変更を land。

## 修正内容 (CR severity 別)

### Critical (1 件 / 採用)
- docs/todo10.md: 順位 216 (no-workstream-seq-names-in-config rule) の
  test_coverage 宣言で拡張子カバレッジ欠落と test 命名不一致を修正
  (other_ext_tests に jsonc test を追加、main_ext_tests の test 名を
  TOML schema 規約と整合)

### Major (3 件 / 採用)
- src/hooks-pre-tool-validate/src/todo_staleness.rs: run_jj_with_timeout
  で child stdout をブロッキング待機していたパイプバッファ枯渇デッド
  ロックを修正。spawn_stdout_drainer + poll_child_with_deadline 関数を
  抽出してバックグラウンド drain に変更 (ADR-016 subprocess safety pattern)
- src/hooks-session-start/src/jj_helpers.rs: 同型の deadlock 修正
  (spawn_stdout_drainer + poll_child_with_deadline 抽出)。両 module で
  identical pattern を共有
- src/hooks-session-start/src/reaper.rs: .failed marker の atomic file
  creation を File::create_new() で保証 (TOCTOU window 解消)

### Minor (2 件 / 採用)
- docs/todo10.md: line 532 markdown 引用符の閉じ括弧不一致を修正
- src/check-ci-coderabbit/src/rate_limit.rs + src/hooks-session-start/
  src/reaper.rs: parse_iso8601_to_unix で Z suffix を strip_suffix で
  validate (trim_end_matches では invalid timestamp も accept していた)

### Minor (1 件 / 却下)
- src/hooks-pre-tool-validate/src/config.rs: TODO_STALENESS_DEFAULT_BRANCH
  を "master" → "main" 提案。本リポジトリは master を default branch
  として運用しているため却下。他 module の "main" 参照は aspirational /
  transitional な記述で、本 module の "master" が正しい。

## 検証

- cargo test --workspace: 437 tests pass (本 PR 関連: 71 + 221 + 145、
  rate_limit.rs 周辺は別 crate test で cover)
- cargo clippy --workspace -- -D warnings: clean
- takt post-pr-review: 3 iterations / 39m 32s / approved (structured_output)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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/hooks-session-start/Cargo.toml`:
- Line 10: The lib-subprocess dependency in hooks-session-start Cargo.toml is
using a path-based dependency instead of workspace dependency management as
required by ADR-026. Replace the path dependency syntax `{ path =
"../lib-subprocess" }` with `{ workspace = true }` for the lib-subprocess entry
to align with the workspace-based dependency management guidelines.
🪄 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: fccccd84-96c8-4ecf-9540-f3290b2df5e2

📥 Commits

Reviewing files that changed from the base of the PR and between 13e0a86 and 4384d82.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • docs/todo10.md
  • src/check-ci-coderabbit/src/rate_limit.rs
  • src/hooks-pre-tool-validate/Cargo.toml
  • src/hooks-pre-tool-validate/src/todo_staleness.rs
  • src/hooks-session-start/Cargo.toml
  • src/hooks-session-start/src/jj_helpers.rs
  • src/hooks-session-start/src/main.rs
  • src/hooks-session-start/src/pr_monitor.rs
  • src/hooks-session-start/src/reaper.rs
  • src/hooks-session-start/src/weekly_review.rs
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/hooks-session-start/src/jj_helpers.rs
  • src/hooks-session-start/src/weekly_review.rs
  • src/hooks-session-start/src/pr_monitor.rs
  • docs/todo10.md
  • src/hooks-session-start/src/main.rs
  • src/hooks-pre-tool-validate/src/todo_staleness.rs
  • src/hooks-session-start/src/reaper.rs

Comment thread src/hooks-session-start/Cargo.toml
…L530 採用)

CR Critical L530 で「Task 216 の test_coverage 宣言に拡張子カバレッジ欠落」
として指摘された不整合を解消:

- extensions = ["toml", "yaml", "yml", "jsonc", "json"] のうち plain
  `json` は comment 構文を持たず本 rule (`no-workstream-seq-names-in-config`)
  の対象外 = test 未定義状態だった
- jsonc が JSON-with-comments を cover するため json は rule scope から除外
- extensions = ["toml", "yaml", "yml", "jsonc"] に縮小

なお同 thread 内で指摘された「`no_workstream_seq_skips_github_pr_number` が
main_ext_tests.toml に配置されている」点は coverage.rs の実装 (positive/negative
semantic を強制しない、宣言 test 名の存在のみ check) と rule⑫ 既存 pattern
との整合により現状維持。CR Major (path → workspace dep) と CR Minor
(master → main) は rejection 理由を thread reply で記録済。
@aloekun

aloekun commented Jun 23, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@aloekun
aloekun merged commit 862eb1e into master Jun 23, 2026
1 check passed
@aloekun
aloekun deleted the pr3a-hooks-module-split branch June 23, 2026 10:49
aloekun added a commit that referenced this pull request Jun 23, 2026
PR-3a (#217) の post-merge-feedback で採用された 2 件と、調査の結果判明した
800 行超 file 累積問題への改善計画を documents として land。

## 順位 220/221 (PR #217 post-merge-feedback 採用)

- 順位 220 (🔧 Tier 2): subprocess stress test (>64KB stdout) を ADR-031
  weekly-review pipeline 経由で週次実行
  - ユーザー判断 (2026-06-23): hooks/pre-push には組み込まず週次に分離
  - `#[ignore]` 付き cargo test + ADR-031 workflow に rust-stress step 追加

- 順位 221 (💎 Tier 3): ADR-NNN (採番未確定): Safe Subprocess Stdout Pattern
  を ADR-016 appendix or 新 ADR で codify
  - 順位 220 (test 層) と 1 PR bundle 推奨
  - ADR-025 CwdRestore guard pattern を precedent として cite

## ファイルサイズチェックフロー改善計画 (新規 docs/file-length-enforcement-plan.md)

PR-3a 完了時に判明: 800 行超 file が 7 件存在 (lint hook 本体 1606 行を含む)。
現状の file_length lint (順位 147) は soft-nag のみで decision: block しない設計、
Stop hook quality_gate / pre-push quality_gate にも file_length check が無く、
ratchet 累積を防ぐ機構が欠落していた。

ユーザー判断 (2026-06-23): C (Stop hook gate) + E (weekly audit) の二段組を導入、
clean state 到達後に C → B (PostToolUse block) 移行を将来検討。

planning doc として docs/file-length-enforcement-plan.md を新設、6 PR (W0-W5)
の作業計画 + 削除条件 (全 PR land + 0 件確認 + dogfood 通過) を明文化。
並列セッションから状況を把握できる ephemeral 計画書 (試験運用、完了で削除)。
aloekun added a commit that referenced this pull request Jun 24, 2026
…順位 222 採用 (#219)

* docs(todo): 順位 222 採用 (PR #218 post-merge-feedback #5)

PR #218 (docs PR、ファイルサイズチェックフロー改善計画 + 順位 220/221 採用)
の post-merge-feedback で承認された #5 を採用:

順位 222 (💎 Tier 3、Effort XS):
`~/.claude/CLAUDE.md` に「複数セッション跨ぎの計画文書作成時は AI が
先走らずユーザー確認後に方針報告し GO/NO-GO を得る」ルール追加

由来: PR #218 session 内で Plan file 作成完了報告後、AI がユーザー承認
なしに PR-W0 着手しようとして `[Request interrupted by user]` で停止
された実観測 (Severity Medium、Frequency Low 初観測、Effort XS、
Adoption Risk None)。memory `feedback_no_unauthorized_reorder` の補強
として「planning doc 作成のような大きな task 完了時は GO/NO-GO 確認待ち」
を明文化、派生プロジェクトへ `~/.claude/CLAUDE.md` 経由で自動波及。

採用しなかった項目:
- #1 (weekly audit を feedback entry にも明示): 計画書 PR-W0 で既に管理
- #3 (lib-subprocess stress test): 順位 220 と完全重複
- #4 (Agent template PMF entry): 計画書 Appendix A で既に capture、却下
- #2/#6/#7: 様子見継続

* feat(weekly-review): file_length scan を pre-LLM step として追加 (PR-W0)

ADR-031 weekly-review pipeline に deterministic Rust pre-step として
800 行超 file の scan を追加。LLM facet 不要、純機械測定。

順位 147 (file_length lint) は touch-trigger ratchet で「触られた file の
編集時のみ警告」設計のため、未触り state の violation を可視化できない。
本 step は毎週 1 回 master HEAD に対して 800 行超 file を全件列挙し、
aggregate-weekly facet の input に注入して watchlist として report 化する。

PR-3a (PR #217) で 7 件の 800 行超 file が判明した経緯から、Phase 1
(file split work、PR-W1 〜 W4) の進捗 dashboard としても機能する。
全 file ≤ 800 行に到達後も恒久的に監視継続。

由来: docs/file-length-enforcement-plan.md PR-W0 (PR #218 で land)、
severity = warning (block しない、健康診断目的)。
aloekun added a commit that referenced this pull request Jun 24, 2026
…PR-W1、self-host irony 解消) (#220)

* docs(plan): PR-W0 を [x] #219 (merged at 2026-06-24T16:07:42Z) に更新

PR #219 (PR-W0、weekly-review に file_length scan facet 追加) が
2026-06-24T16:07:42Z に master へ land したことを受けて、
docs/file-length-enforcement-plan.md の進捗追跡 table の PR-W0 status を
`[in progress]` → `[x] #219` に更新する。

* refactor(hooks-post-tool-comment-lint-rust): main.rs を module 分割 (PR-W1)

docs/file-length-enforcement-plan.md PR-W1 を実装。
lint hook 本体 (1606 行) を coding-style.md § File Organization (800 行 max)
内に収まる module 構成に分割。behavior 不変な mechanical refactor で
関数 signature・公開 API・field 名・default 値はすべて保持。

順位 147 (file_length lint、PR #202 land) を自分自身に適用した self-host
の整合性を確立。本 PR が land すれば 7 files 中 1 件 (1606 行) を 800 行
以下に解消、weekly-review file_length watchlist の件数が 7 → 6 に減少。

分割計画は計画書 PR-W1 section + Appendix A Agent prompt template 参照。
PR-3a (#217) の hooks-session-start 分割と同型 procedure を Agent 委譲で
実装、behavior 不変性は test count 不変 + cargo clippy clean で verify。
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