feat: Agent Operational Rules と post_commit_adr_reminder フックを追加 - #610
Conversation
## AGENTS.md - Operational Rules セクション追加: - Memory Management: Worktree環境はgit commitで永続化必須 - Temporary Files: .context/ に配置、/tmp/ 禁止 - ADR: 大きめの変更は docs/adr/ に記録 - Plan Review: ユーザー提示前にAIレビューで品質担保 ## post_commit_adr_reminder.py - git commit後にアーキテクチャ関連の変更を検出しADR作成をリマインド - package.json, tsconfig, Dockerfile, terraform/, CI/CD等を検出 - ブロックはせず情報提供のみ(常にexit 0) - settings.json, README.md, repo-maintenance.md に登録 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a non-blocking PostToolUse hook that detects architecture-impacting files changed by Changes
Sequence Diagram(s)sequenceDiagram
participant DevShell as Developer Bash
participant HookRunner as CLAUDE Hook Runner
participant Git as Git (repo)
participant ADRDocs as docs/adr/
DevShell->>HookRunner: PostToolUse (stdin JSON with git commit)
HookRunner->>HookRunner: run post_commit_adr_reminder.py
HookRunner->>Git: git diff-tree --name-only HEAD (timeout)
Git-->>HookRunner: list of changed files
alt any file under docs/adr/
HookRunner->>HookRunner: exit silently (no reminder)
else matches architecture-impacting patterns
HookRunner-->>DevShell: stdout JSON (hookSpecificOutput ADR reminder)
else no matching signals
HookRunner->>HookRunner: exit silently
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
🔍 AI Code Review (Local Hook)Models: Codex (default) / Gemini (default) 🤖 Codex Review指摘事項はありません。変更はドキュメント更新と非ブロッキングなリマインダーフック追加で、正確性・パフォーマンス・セキュリティ・保守性・DXの観点で問題は見当たりませんでした。 判定: patch is correct 🤖 Generated by post_pr_ai_review.py hook |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a61a649771
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| result = subprocess.run( | ||
| ["git", "diff-tree", "--no-commit-id", "--name-only", "-r", "HEAD"], | ||
| capture_output=True, |
There was a problem hiding this comment.
Skip ADR reminder when
git commit did not create a commit
This hook reads HEAD immediately after any Bash command containing git commit, but it never checks whether the commit actually succeeded. When git commit fails (for example: nothing to commit, commit blocked by hooks, or unresolved merge state), HEAD still points to an older commit, so the reminder can be generated from unrelated historical changes and mislead users. Please gate the HEAD diff lookup on a successful commit result from tool_response (or otherwise verify that HEAD changed).
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ure) AGENTS.md はセッション開始時の User Message として注入されるため、 後半で効果が薄れる。ルール類は .claude/rules/ に移し、 対象ファイル操作時に注入される conditional rules として配置。 - .claude/rules/development-standards.md: TDD, Quality Gates, AI Prompt Design - .claude/rules/git-conventions.md: Branch naming, Conventional Commits, PR guard - .claude/rules/release-types.md: paths 限定で release-triggering types を強制 - AGENTS.md: Development Standards セクションを削除しスリム化 Ref: https://zenn.dev/cureapp/articles/65b9a99d22ce2b Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
(aside) |
|
Claude finished @keito4's task in 7m 37s —— View job CI調査・修正結果
調査結果すべての CI チェックは現在 ✅ 全て SUCCESS です。
ローカルでも全品質ゲートを確認済みです:
PR がブロックされている理由
これは外部サービス(CodeRabbit)のレート制限によるもので、自動的に解消されます。CI 自体は正常に動作しています。 補足:Codex インラインレビューの指摘についてCodex レビューで
これはコード品質の改善点ですが、CI 失敗の直接原因ではありません。 現時点での対応: CI は全て緑です。CodeRabbit のレート制限が解消され次第、PR はマージ可能な状態になります。 |
- development-standards.md, git-conventions.md, release-types.md を マネージドファイルリストに追加 - /repo-maintenance 実行時に config から他リポジトリへ自動同期 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
(aside) |
|
Claude finished @keito4's task in 5m 49s —— View job CI修正完了
調査結果・実施内容原因: PRブランチが 対処: GitHub APIでPRブランチを
残る BLOCKED の理由: PRレビューの承認(Approve)がまだ行われていません。ブランチ保護ルールでレビュアーの承認が必要な設定になっているため、レビュアーがApproveすればマージ可能になります。 |
|
(aside) |
|
Claude finished @keito4's task in 9m 44s —— View job CI修正完了
調査結果現時点のCI状況:全チェック ✅ 通過済み
PRが 実施した修正Codex P2指摘対応: 修正内容 ( # tool_response を取得
tool_response = data.get("tool_response", {}) or {}
# コミットが実際に成功したか確認
stdout = tool_response.get("stdout", "")
stderr = tool_response.get("stderr", "")
combined = stdout + stderr
# 成功パターン: "[branch hash] message" 形式
if not re.search(r"\[[^\]]+\s+[0-9a-f]{5,}\]", combined):
sys.exit(0)
補足:残存するBLOCKED理由コードの問題は修正済みですが、ブランチ保護ルールで レビュアーのApprove が必要です。CIが緑になった状態でレビュアーがApproveすればマージ可能になります。 |
Codex P2レビュー指摘対応: post_commit_adr_reminderフックがgit commit 失敗時にも旧HEADを参照してADRリマインドを誤表示する問題を修正。 tool_responseのstdoutに '[branch hash] message' パターンが存在する 場合のみHEAD diffを参照するよう変更。 Co-authored-by: keito4 <keito4@users.noreply.github.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.claude/hooks/post_commit_adr_reminder.py (1)
27-29: Minor edge case: flag detection may have false positives.The substring check
"-n" in commandcould match-nappearing within a commit message (e.g.,git commit -m "fix -n bug"), causing the hook to skip when it shouldn't. Since this is a non-blocking reminder with low-impact false negatives, this is acceptable—but consider using a more precise pattern if needed in the future.♻️ Optional: More precise flag detection
-if any(flag in command for flag in ["--help", "-h", "--dry-run", "-n"]): +# Match flags as standalone arguments (not inside quoted strings) +if re.search(r'(?:^|\s)(?:--help|-h|--dry-run|-n)(?:\s|$)', command): sys.exit(0)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/hooks/post_commit_adr_reminder.py around lines 27 - 29, The current substring check in the if block (checking "--help", "-h", "--dry-run", "-n" against the string variable command) can produce false positives when "-n" appears inside commit messages; update detection to examine command tokens instead of raw substring matching by splitting the command into arguments (e.g., via shlex.split(command) or similar) and checking for exact flag tokens, or use a regex that matches flag boundaries (e.g., match r'(^|\s)-n($|\s)'); modify the conditional that uses command so it checks the tokenized/regex-matched flags before calling sys.exit(0).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.claude/hooks/post_commit_adr_reminder.py:
- Around line 27-29: The current substring check in the if block (checking
"--help", "-h", "--dry-run", "-n" against the string variable command) can
produce false positives when "-n" appears inside commit messages; update
detection to examine command tokens instead of raw substring matching by
splitting the command into arguments (e.g., via shlex.split(command) or similar)
and checking for exact flag tokens, or use a regex that matches flag boundaries
(e.g., match r'(^|\s)-n($|\s)'); modify the conditional that uses command so it
checks the tokenized/regex-matched flags before calling sys.exit(0).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cd45bb54-edb4-42ba-86a8-e0b871395e5e
📒 Files selected for processing (1)
.claude/hooks/post_commit_adr_reminder.py
|
(aside) |
CI修正完了
根本原因
実施した修正コミット
CI トリガー方法 現在のCIステータス
PRの |
- post_commit_adr_reminder.py: shlex.splitによる-nフラグの誤検知修正 コミットメッセージ中の"-n"文字列による誤スキップを防ぐため、 shlex.splitでトークン単位に検査するよう変更 - settings.json: block_dangerous_commandsフックをPreToolUseに追加 AGENTS.mdに記載済みだが未登録だったhookを正式に登録 Co-authored-by: keito4 <keito4@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/hooks/post_commit_adr_reminder.py:
- Around line 41-42: The current success detection uses a brittle regex on the
variable combined (if not re.search(r"\[[^\]]+\s+[0-9a-f]{5,}\]", combined):
sys.exit(0)) which misses commits when git is run with --quiet or when
core.abbrev < 5; update the logic to prefer the tool_response exit code (the
variable tool_response produced earlier) as the primary success indicator and
only fall back to inspecting combined output when tool_response is missing or
non-deterministic, and when doing so relax the hash check to accept shorter hex
sequences (e.g., {4,}) or use a more forgiving pattern; modify the conditional
around combined and tool_response to call sys.exit(0) only when tool_response
indicates success or the relaxed regex confirms a commit.
- Around line 25-34: The code wrongly treats "-n" as a dry-run flag; update the
token checks so "-n" is not lumped with "--dry-run": keep the dry-run/help check
using tokens and flags ["--help","-h","--dry-run"], and add a separate check for
the no-verify form (check for "--no-verify" or "-n" in tokens) if you intend to
still skip when users explicitly request no-verify; use the existing
tokens/shlex.split logic and modify the any(...) condition(s) around tokens to
implement this split.
- Around line 46-54: The subprocess.run call that sets result and changed must
be hardened: resolve the git executable with shutil.which("git") and fail fast
if not found, build the command using that full path, and after running check
result.returncode (or call with check=True and handle
subprocess.CalledProcessError) instead of assuming success; also replace the
broad except Exception with specific handlers for subprocess.TimeoutExpired and
FileNotFoundError/OSError (and subprocess.CalledProcessError if using
check=True), logging or exiting appropriately so failures are explicit rather
than swallowed. Ensure you update the symbols referenced (the subprocess.run
invocation, the result variable, and the changed assignment) accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cf68ed18-4332-4773-a530-f3630fdff719
📒 Files selected for processing (2)
.claude/hooks/post_commit_adr_reminder.py.claude/settings.json
🚧 Files skipped from review as they are similar to previous changes (1)
- .claude/settings.json
|
(aside) |
|
Claude finished @keito4's task in 10s —— View job CI修正完了
調査結果・実施内容現在のCIはすべて ✅ SUCCESS であり、技術的なCI失敗はありません。
PRが 修正内容(
|
| 修正 | 詳細 |
|---|---|
-n フラグの誤分類 |
git commit -n は --no-verify の意味。--dry-run のリストから除外 |
| 成功判定の堅牢化 | tool_response.exit_code を優先し、存在しない場合のみ正規表現フォールバック |
| ハッシュ正規表現を緩和 | {5,} → {4,}(core.abbrev < 5 環境への対応) |
| subprocess 堅牢化 | shutil.which("git") でフルパス解決(Ruff S607 対応) |
| returncode チェック | result.returncode != 0 で失敗時は早期終了 |
| 例外を絞り込み | except Exception → except (TimeoutExpired, OSError)(Ruff BLE001 対応) |
| Branch |
- -n を dry-run から除外:git commit -n は --no-verify の意味
- tool_response.exit_code を優先した成功判定に変更(--quiet 対応)
- ハッシュ正規表現を {5,} -> {4,} に緩和(core.abbrev 設定対応)
- shutil.which('git') でフルパス解決(S607 対応)
- result.returncode チェックを追加
- except Exception -> except (TimeoutExpired, OSError)(BLE001 対応)
Co-authored-by: keito4 <keito4@users.noreply.github.com>
|
🎉 This PR is included in version 1.103.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
post_commit_adr_reminder.pyフックを新規作成(git commit後にADRリマインド)AGENTS.md Operational Rules
.context/に配置。/tmp/禁止(他Agent から不可視)docs/adr/に記録post_commit_adr_reminder.py
nyosegawa/test-docs の実装 を参考に Python で実装。
PostToolUse(Bash)でgit commitを検出docs/adr/が既にコミットに含まれていればスキップChanges
AGENTS.md: Operational Rules セクション追加.claude/hooks/post_commit_adr_reminder.py: 新規フック.claude/hooks/README.md: フックのドキュメント追加.claude/settings.json: PostToolUse にフック登録.claude/commands/repo-maintenance.md: マネージドファイルリストに追加Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores