feat(hooks-post-tool-linter): no-time-field-strict-greater rule (順位 47 / §A-2 P-2)#126
Merged
Merged
Conversation
…7 / §A-2 P-2) §A-2 Phase 5 dogfood P-2。PR #101 で実証された latent drift (parse_findings 系 3 関数で created_at > push_time vs >= の混在) を構造的に防止する custom lint rule を追加。Bundle Z #B-α と同じ「決定論的防止層」哲学。 ルール仕様: - pattern: \b(created_at|submitted_at|updated_at|comment_event_time| event_time|comment_created_at|published_at|posted_at|commented_at) \s*>\s*[a-zA-Z_] - direction: `>` のみ flag (`<` は is_stale 等で意図的 exclusive 境界 の正しい用途があるため scope 外) - target: .rs files only 検証: - 11 unit tests (4 detect 系 + 7 skip 系) + 1 helper 関数 で transition matrix を網羅 - 全 75 tests passed - 既存 codebase で 0 violations (created_at >= は doc コメントのみ、 is_stale の created_at < は `<` で対象外) build + deploy 済 (.claude/hooks-post-tool-linter.exe)。
📝 Walkthrough🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/hooks-post-tool-linter/src/main.rs (1)
1360-1366: ⚡ Quick win9 フィールドのうち 5 フィールドに検出テストがありません。
TOML の交代パターンには 9 フィールドが列挙されていますが、陽性検出テスト (violations.len() == 1 を assert するもの) は
created_at、submitted_at、updated_at、comment_event_timeの 4 フィールドのみです。以下の 5 フィールドには検出テストがなく、TOML の交代式への誤字があってもテストスイートでは捕捉できません。
event_timecomment_created_atpublished_atposted_atcommented_at🧪 追加テストの例 (残り 5 フィールド)
+ #[test] + fn rs_time_field_strict_greater_detects_event_time() { + let dir = tempfile::tempdir().unwrap(); + let file = write_file( + dir.path(), + "parse.rs", + &build_rs_source_with_op("event_time", ">", "cutoff"), + ); + let rules = compile_test_rules(vec![rs_time_field_strict_greater_rule()]); + let violations = run_custom_rules(file.to_str().unwrap(), &rules); + assert_eq!(violations.len(), 1); + } + + #[test] + fn rs_time_field_strict_greater_detects_comment_created_at() { + let dir = tempfile::tempdir().unwrap(); + let file = write_file( + dir.path(), + "parse.rs", + &build_rs_source_with_op("comment_created_at", ">", "since"), + ); + let rules = compile_test_rules(vec![rs_time_field_strict_greater_rule()]); + let violations = run_custom_rules(file.to_str().unwrap(), &rules); + assert_eq!(violations.len(), 1); + } + + #[test] + fn rs_time_field_strict_greater_detects_published_at() { + let dir = tempfile::tempdir().unwrap(); + let file = write_file( + dir.path(), + "parse.rs", + &build_rs_source_with_op("published_at", ">", "threshold"), + ); + let rules = compile_test_rules(vec![rs_time_field_strict_greater_rule()]); + let violations = run_custom_rules(file.to_str().unwrap(), &rules); + assert_eq!(violations.len(), 1); + } + + #[test] + fn rs_time_field_strict_greater_detects_posted_at() { + let dir = tempfile::tempdir().unwrap(); + let file = write_file( + dir.path(), + "parse.rs", + &build_rs_source_with_op("posted_at", ">", "now"), + ); + let rules = compile_test_rules(vec![rs_time_field_strict_greater_rule()]); + let violations = run_custom_rules(file.to_str().unwrap(), &rules); + assert_eq!(violations.len(), 1); + } + + #[test] + fn rs_time_field_strict_greater_detects_commented_at() { + let dir = tempfile::tempdir().unwrap(); + let file = write_file( + dir.path(), + "parse.rs", + &build_rs_source_with_op("commented_at", ">", "boundary"), + ); + let rules = compile_test_rules(vec![rs_time_field_strict_greater_rule()]); + let violations = run_custom_rules(file.to_str().unwrap(), &rules); + assert_eq!(violations.len(), 1); + }Also applies to: 1380-1521
🤖 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/main.rs` around lines 1360 - 1366, The test suite is missing positive-detection tests for five time-field alternatives listed in the regex used by rs_time_field_strict_greater_rule (event_time, comment_created_at, published_at, posted_at, commented_at); add unit tests alongside the existing positive cases (the tests that assert violations.len() == 1) to cover each of these five fields so any typo in the TOML pattern will be caught. Locate rs_time_field_strict_greater_rule and the test block(s) that currently assert violations.len() == 1 for created_at, submitted_at, updated_at, comment_event_time and add similar tests that feed sample Rust input containing each of event_time, comment_created_at, published_at, posted_at, and commented_at (using the same test harness and expectations) to ensure each alternative triggers a violation.
🤖 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.
Nitpick comments:
In `@src/hooks-post-tool-linter/src/main.rs`:
- Around line 1360-1366: The test suite is missing positive-detection tests for
five time-field alternatives listed in the regex used by
rs_time_field_strict_greater_rule (event_time, comment_created_at, published_at,
posted_at, commented_at); add unit tests alongside the existing positive cases
(the tests that assert violations.len() == 1) to cover each of these five fields
so any typo in the TOML pattern will be caught. Locate
rs_time_field_strict_greater_rule and the test block(s) that currently assert
violations.len() == 1 for created_at, submitted_at, updated_at,
comment_event_time and add similar tests that feed sample Rust input containing
each of event_time, comment_created_at, published_at, posted_at, and
commented_at (using the same test harness and expectations) to ensure each
alternative triggers a violation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1d4e3e97-31ae-466d-96fe-e93eb72cfea1
📒 Files selected for processing (2)
.claude/custom-lint-rules.tomlsrc/hooks-post-tool-linter/src/main.rs
7 tasks
aloekun
added a commit
that referenced
this pull request
May 7, 2026
…P-1/P-2 ledger (順位 7 / §A-2 P-3) (#127) * feat(hooks-post-tool-linter): PowerShell (?i) flag validation + §A-2 P-1/P-2 ledger 記録 (順位 7 / §A-2 P-3) §A-2 Phase 5 dogfood P-3 (順位 7)。PR #91 で発覚した PowerShell case-insensitive regex の構造的落とし穴 (no-empty-powershell-catch / no-silent-error-action で (?i) 欠落 → CR Major 指摘) を機械強制で再発防止。 順位 7 (Tier 1, T1-1): - find_powershell_rules_missing_case_insensitive_flag() 関数追加: extensions に ps1 を含む rule で pattern に (?i) が無いものを ID リストで返す - load_custom_rules() で起動時 warn (本番運用層) - 7 unit tests (異種 violator / valid / mixed-ext / case-insensitive ext / multi-violator / non-ps1 ignore) + 1 deployed-config 全 rule 検証 test (CI 検出層) - 既存 no-ephemeral-todo-reference rule の pattern に (?i) を追加 (deployed validation を pass、Windows file path 大文字小文字混在対応の副次効果あり) - ~/.claude/rules/common/code-review.md § Custom lint rule patterns 追加 (PR #91 a15b263 fix の経緯 + 順位 7 機械強制の事後参照) §A-2 計測ログ (P-1/P-2) 記録: - P-1 (PR #125): findings: 0 (CR APPROVE no comments)、classifier 未起動 → dogfood 不発 - P-2 (PR #126): findings: 1 (CR Nitpick、review body <details> block 内、 check-ci-coderabbit 抽出漏れ)、手動 synthetic finding で classifier 実行 → action=human_review / action_confidence=0.0 / fallback=length_contract、 agreement: 1/1 (100%)、latency: 6.4s/件 (>5s 目標)、fallback: 1/1 - 既知 system gap: check-ci-coderabbit が review body の <details> Nitpick を 抽出しない (post-pr-monitor が classifier に渡す入力経路に欠落) build + deploy 済 (.claude/hooks-post-tool-linter.exe)。 全 82 tests pass、regression なし。 * docs(todo): 順位 7 (PowerShell (?i) flag 自動検証) 完了に伴い削除
This was referenced May 7, 2026
Merged
aloekun
added a commit
that referenced
this pull request
May 13, 2026
* docs(todo,analysis): D-4 を 順位 39 に re-pivot + stale 順位 47 entry 削除 順位 47 (>vs>= boundary lint) は PR #126 (commit b677b9d, 2026-05-08) で no-time-field-strict-greater rule として既に land 済 (custom-lint-rules.toml line 208-243) を D-4 着手前検証で発見。memory rule feedback_verify_task_not_already_done を適用して stale todo entry を削除し、D-4 を Round 2 計画から 順位 39 (takt workflow `model` 必須化 lint rule) に繰上げ、D-5 を 順位 56 + 119 bundle に再構成。 変更: - docs/local-llm-offload-analysis.md: D-4/D-5 row 更新 + 想定リスク に re-pivot 経緯追記 - docs/todo7.md: stale 順位 47 entry (38 行) 削除 - docs/todo-summary.md: 順位 47 row 削除 Phase E 着手前提 (5 PR 累積 dogfood) は変わらず、D-4〜D-7 で 4 PR 追加観測の方針継続。 * feat(hooks-post-tool-linter): takt-workflow-persona-without-model lint rule (順位 39 / Phase D D-4) PR #98 post-merge-feedback Tier 1 #1 採用。takt workflow yaml で persona: を持つ step に model: 未指定の場合を検出する custom lint rule (ルール⑨)。Bundle Z #B-α と同じ 決定論的防止層 (ADR-007 正規表現層)。 実装: - .claude/custom-lint-rules.toml: 新規 rule takt-workflow-persona-without-model - pattern: multi-line regex で persona: 直後の field 行が model: 以外なら fire - field enumeration 方式 (Rust regex lookahead 非対応の pragmatic 対処) - extensions=[yaml] + paths=[.takt/workflows/*.yaml] で範囲限定 (順位 102 PR #148 で 実装した paths filter を利用) - .takt/workflows/post-pr-review.yaml: 2 site に model: sonnet 追加で clean baseline - line 23: judge block (loop_monitor) の persona: supervisor 直下 - line 117: supervise step の persona: supervisor 直下 (Bundle Y2 完全性) - .takt/workflows/pre-push-review.yaml: 1 site に model: sonnet 追加で clean baseline - line 26: judge block (loop_monitor) の persona: supervisor 直下 - src/hooks-post-tool-linter/src/main.rs: unit tests 6 件追加 - takt_workflow_persona_detects_judge_block_violation - takt_workflow_persona_detects_supervise_step_violation - takt_workflow_persona_skips_when_model_directly_follows (clean baseline) - takt_workflow_persona_detects_multiple_violations_in_same_file - takt_workflow_persona_skips_non_yaml_extension (extensions filter) - deployed_takt_workflows_have_clean_baseline_for_persona_model_rule (regression test) Phase D D-4 dogfood: real diff として lint_screen の dogfood data 蓄積を目的。 Round 2 計画 (D-3 + D-4〜D-7 = 累積 5 PR) の 2 PR 目。 cargo test: 108 passed (前 102 + 新 6)。 * fix(hooks-post-tool-linter): takt persona-without-model rule に 4 fields 追加 (PR #150 CR Major) CodeRabbit Major finding (#150 (comment)): persona 直後の field 列挙 から output_contracts / pass_previous_response / required_permission_mode / parallel が漏れていた = false negative リスク。 4 fields を pattern alternation に追加し regression test も同梱。 変更: - .claude/custom-lint-rules.toml: ルール⑨ pattern alternation に 4 fields 追加 - src/hooks-post-tool-linter/src/main.rs: 同期更新 + 新 test takt_workflow_persona_detects_required_permission_mode_violation で pre-push-review.yaml fix step (persona: coder → required_permission_mode:) pattern が検出されることを assert cargo test: 109 passed (前 108 + 新 1、CR Major regression test) CR Minor (line 5、未来日進捗) は project local time (JST) と CR UTC の時差解釈 ギャップに起因 (CR 時点 = 2026-05-12 20:04 UTC = 2026-05-13 05:04 JST)。 2026-05-13 は session-start hook が認識する local 今日であり、'着手' は本 PR で 発生した事実。project 内既存 PR land 日付も全て local time (timezone qualifier 無し) で記載しており、本 PR の追記のみ qualifier 付与は逆に不整合を生む。 別 reply で resolved として close する。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
>vs>=混在) を構造的に防止する custom lint rule を追加Changes
.claude/custom-lint-rules.toml新ルール
no-time-field-strict-greater追加:検出対象: 9 種の時刻フィールド (created_at / submitted_at / updated_at / comment_event_time / event_time / comment_created_at / published_at / posted_at / commented_at) の strict
>比較で、RHS が alphabetic identifier の場合。Direction-specific 設計 (
>のみ flag):<の strict 比較 (例:is_staleのcreated_at < threshold) は意図的な exclusive 境界として正しい用途があるため scope 外<側の boundary 問題は観測されたら別 rule で対応src/hooks-post-tool-linter/src/main.rs11 unit tests + 3 helper 関数 で transition matrix を網羅:
detects_created_at_gt_push_timecreated_at > push_timedetects_submitted_at_gt_sincesubmitted_at > sincedetects_updated_at_gt_thresholdupdated_at > thresholddetects_comment_event_timecomment_event_time > nowskips_inclusive_comparisoncreated_at >= push_timeskips_strict_less_thancreated_at < thresholdskips_le_inclusivecreated_at <= cutoffskips_numeric_rhscreated_at > 0skips_doc_comment_with_inclusive/// created_at >= push_timeskips_unrelated_fieldcount > limitonly_targets_rscreated_at > push_timeHelper 関数 (test fixture を runtime 構築):
build_rs_source_with_op(field, op, rhs) -> Stringbuild_doc_comment_source(field, op, rhs) -> Stringbuild_toml_with_field(field, op, rhs) -> String理由: literal
created_at > push_timeを test source 内に書くと 新ルール自身が test source を flag して self-trigger ループに陥る。format!()経由で runtime 構築すると Edit-time lint の regex (literal adjacency 必須) を回避できる (= dogfood で実証された "lint rule self-violation" の structural pattern)。.claude/hooks-post-tool-linter.exepnpm build:hooks-post-tool-linterで release build を再生成し配備既存 codebase の lint 適用結果
grep -rn '\b(created_at|...)_at\s*>\s*[a-zA-Z_]'で 0 件)created_at >= push_time(doc コメント) は>=のため対象外is_staleのcreated_at < thresholdは<のため対象外 (Direction-specific 設計の効果)§A-2 dogfood (P-2) 観測ポイント
本 PR の post-pr-monitor で classifier が CodeRabbit findings を分類する 2 回目の dogfood サイクル (P-1 では findings ゼロで起動せず)。lint rule 追加 PR は CR から style / regex 厳密性 / edge case 指摘が出やすく、findings が複数発生する想定。
計測対象は P-1 と同じ:
action一致率 — 目標 ≥80%human_reviewfallback 比率 — 目標 ≤20%normalized_issue言語制約違反率: 英語 8 文字以上連続検出 — 目標 ≤10%Self-violation 知見の副産物
本 PR で 新 lint rule が test source に self-trigger するパターンを実体験。Edit-time lint hook (PostToolUse) は
new_string(Edit の追加文字列) を scan するため、test fixture に literal pattern を書くと Edit が即 reject される。回避策として test fixture をformat!()で runtime 構築する DSL pattern を確立。これは新 lint rule 追加時の standard pattern として再利用可能 (今後の T1 lint task で同様のテクニックが必要)。Test plan
cargo test -p hooks-post-tool-linter rs_time_field_strict_greater— 11/11 passcargo test -p hooks-post-tool-linter— 75/75 pass、regression なし>strict 違反 0 件確認関連
docs/todo5.md詳細エントリdocs/local-llm-offload-analysis.mdSummary by CodeRabbit
リリースノート
Tests
Chores