feat(pr-monitor): WP-09 PR 監視の GitHub Actions バックストップ Phase A(読み取り専用)#258
Conversation
.github/workflows/pr-monitor.yml を新設。セッション不在時のバックストップとして PR のレビュー・CI 状態を分析し日本語コメントを投稿する(読み取り専用、ADR-022 原則 6)。 - トリガーはレビュアー非依存: pull_request_review(全レビュアー)+ pull_request (opened/ready_for_review)+ issue_comment(coderabbitai 発のみ)。CodeRabbit 固有条件は issue_comment の 1 条件に局所化しロックインを回避。 - 読み取り専用は GITHUB_TOKEN の permissions(contents: read)で決定論的に担保。 指示層が破られても push は 403 で失敗(ADR-043 fail-closed と同思想)。 - 暴走ガード: PR 単位 concurrency + synchronize 非対象 + max-turns 30 + 重複コメント skip。fork PR 対象外、pull_request_target 不使用。model=sonnet。 - ローカル cli-pr-monitor は高速経路として併存。 ADR-022 に原則 6「PR 監視経路の二重化と権限の非対称」を追記。 harness-improvement-plan.md の WP-09 を実装済に更新。
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthrough読み取り専用のバックストップPR監視を行う ChangesPR監視ワークフロー導入
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubEvent
participant AnalyzeJob
participant ClaudeCodeAction
participant GitHubAPI
GitHubEvent->>AnalyzeJob: pull_request/review/issue_comment発火
AnalyzeJob->>AnalyzeJob: 実行条件チェック(fork/bot除外)
AnalyzeJob->>AnalyzeJob: gh pr view (is_fork判定)
AnalyzeJob->>ClaudeCodeAction: レビュー/CI情報の分析依頼
ClaudeCodeAction->>GitHubAPI: gh pr checks / gh api reviews / gh pr diff
ClaudeCodeAction-->>AnalyzeJob: result (分析結果 or SKIP)
AnalyzeJob->>AnalyzeJob: jqでresult抽出、SKIP判定
alt skip=false
AnalyzeJob->>GitHubAPI: gh pr comment --body-file
else skip=true
AnalyzeJob-->>AnalyzeJob: コメント投稿せず終了
end
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
|
情報収集が完了しました。CodeRabbit のレビューはまだ「Review in progress」のプレースホルダーコメントのみで、実際の指摘(findings)は投稿されていません。レビュー指摘が0件のため、指示のステップ3に従い CI 状態と diff 概要のみの軽量サマリーを作成しました。過去の「🤖 PR Monitor 分析」コメントは存在しないため重複ガードには該当しません。 以下が最終応答(分析結果)です。 🤖 PR Monitor 分析 (GitHub Actions バックストップ)
Applicable Findings (Critical / High / Major)該当なし(レビュー指摘自体がまだ0件) Applicable Findings (Medium 以下)該当なし Filtered (not applicable)該当なし Diff 概要3 ファイル変更、追加中心の PR(WP-09: PR 監視の GitHub Actions バックストップ Phase A 読み取り専用実装):
次のアクション
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 @.github/workflows/pr-monitor.yml:
- Line 190: The `allowedTools` list in the workflow needs to permit paginated
`gh api` calls for pull request reviews and comments, since the current `gh api
repos/*/pulls/*/reviews` and `.../comments` patterns do not cover `--paginate`
or `--jq` usage and can miss later pages. Update the matching entries in the
workflow’s `allowedTools` configuration so the read-only `gh api` permissions
for reviews/comments explicitly allow full retrieval of all pages while keeping
the scope limited to the existing repo pull/review/comment endpoints.
- Around line 199-210: The PR monitor workflow’s skip detection only handles the
"SKIP: no new information" marker, so an empty analysis still falls through and
causes the later comment step to fail. Update the trimming/skip check in the
analysis processing block to treat an empty TRIMMED value as skip=true as well,
alongside the existing sentinel, so the job can safely bypass gh pr comment when
jq produces no result.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 62eaadf6-853d-46ee-85e0-70085f29eb46
📒 Files selected for processing (3)
.github/workflows/pr-monitor.ymldocs/adr/adr-022-automation-responsibility-separation.mddocs/harness-improvement-plan.md
| claude_args: | | ||
| --model claude-sonnet-5 | ||
| --max-turns 30 | ||
| --allowedTools "Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr checks:*),Bash(gh api repos/*/pulls/*/reviews),Bash(gh api repos/*/pulls/*/comments),Bash(gh api repos/*/issues/*/comments),Bash(gh run view:*),Bash(gh run list:*),Read(CLAUDE.md),Read(docs/adr/**),Read(.takt/facets/instructions/analyze-coderabbit.md)" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🌐 Web query:
Claude Code allowedTools Bash pattern exact match without trailing wildcard does it block additional flags
💡 Result:
In Claude Code, using an exact-match Bash pattern in allowedTools (e.g., Bash(npm run build)) without a wildcard does indeed restrict the command to that exact string, effectively blocking additional flags or arguments [1][2]. If you provide a rule like Bash(npm run build), the tool will only permit that precise command [1]. Any attempt by the model to append flags or arguments (such as npm run build -- --watch) will fail to match the pattern [2]. To allow a command while also permitting additional flags or arguments, you must include a wildcard character, typically formatted as Bash(npm run build *) [1][2]. Key behavioral details: - Exact Matching: Without a wildcard, the pattern requires a literal string match [1]. - Wildcard Usage: Adding * at the end (with a space) effectively creates a prefix match, allowing the base command to be followed by any additional arguments [1][2]. - Caveats: - Pattern matching has historically faced reports of inconsistency or "pass-through" behavior in certain modes (such as when bypassPermissions is active) [3][4]. - Wildcards are generally expected at the end of the command; support for wildcards in the middle of commands (e.g., Bash(make docker-:* )) has been reported as unreliable or unsupported [5]. - Ensure your pattern does not conflict with rules in the permissions.ask list, as ask rules may trigger prompts even if the command is otherwise permitted by your allow rules [2].
Citations:
- 1: https://code.claude.com/docs/en/permissions.md
- 2: https://aitoolsguidebook.com/en/articles/claude-code-bash-sandbox-blocks-command/
- 3: [Bug] Bash(pattern:*) in --allowedTools/--tools does not restrict commands anthropics/claude-code#47613
- 4: [BUG]
--allowedToolshas no effect when permission bypass flags are active anthropics/claude-code#50303 - 5: [Bug] Bash permission pattern matching fails with wildcard in middle of command anthropics/claude-code#10467
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the workflow around the cited line
git ls-files .github/workflows/pr-monitor.yml
wc -l .github/workflows/pr-monitor.yml
sed -n '1,260p' .github/workflows/pr-monitor.yml | cat -n
# Find any related design notes referenced in the comment
git ls-files | rg '(^|/)CLAUDE\.md$|(^|/)docs/adr/|(^|/)\.takt/facets/instructions/analyze-coderabbit\.md$'Repository: aloekun/claude-code-hook-test
Length of output: 1981
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for permission patterns and gh usage in the repo to understand expected call shapes
rg -n 'allowedTools|gh api repos/.*/pulls/.*/reviews|gh api repos/.*/pulls/.*/comments|gh pr view|gh pr diff|gh pr checks|--paginate|--jq| per_page=100|pull-requests: write' .github docs .takt CLAUDE.md 2>/dev/null || trueRepository: aloekun/claude-code-hook-test
Length of output: 1981
gh api の許可パターンを見直してください。
末尾ワイルドカードがないため、--paginate や --jq を付けた gh api repos/*/pulls/*/reviews / .../comments は許可されません。reviews と comments は既定で 1 ページ 30 件なので、件数が多い PR では後続ページを取りこぼします。読み取り専用のまま全件取得できる形にしてください。
🤖 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 @.github/workflows/pr-monitor.yml at line 190, The `allowedTools` list in the
workflow needs to permit paginated `gh api` calls for pull request reviews and
comments, since the current `gh api repos/*/pulls/*/reviews` and `.../comments`
patterns do not cover `--paginate` or `--jq` usage and can miss later pages.
Update the matching entries in the workflow’s `allowedTools` configuration so
the read-only `gh api` permissions for reviews/comments explicitly allow full
retrieval of all pages while keeping the scope limited to the existing repo
pull/review/comment endpoints.
| set -euo pipefail | ||
| ANALYSIS_FILE="$RUNNER_TEMP/pr-monitor-analysis.md" | ||
| jq -r '.[] | select(.type == "result") | .result' \ | ||
| "$EXECUTION_FILE" > "$ANALYSIS_FILE" | ||
| echo "analysis_file=$ANALYSIS_FILE" >> "$GITHUB_OUTPUT" | ||
|
|
||
| TRIMMED=$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' "$ANALYSIS_FILE") | ||
| if [ "$TRIMMED" = "SKIP: no new information" ]; then | ||
| echo "skip=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "skip=false" >> "$GITHUB_OUTPUT" | ||
| fi |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the workflow and inspect the surrounding steps around the cited lines.
wf=".github/workflows/pr-monitor.yml"
echo "== line count =="
wc -l "$wf"
echo
echo "== lines 160-260 =="
sed -n '160,260p' "$wf"
echo
echo "== search for analysis_file / skip / gh pr comment usage =="
rg -n "analysis_file|skip=true|skip=false|gh pr comment|--body-file|EXECUTION_FILE|SKIP: no new information" "$wf"Repository: aloekun/claude-code-hook-test
Length of output: 1981
🌐 Web query:
aloekun/claude-code-hook-test .github/workflows/pr-monitor.yml gh pr comment --body-file analysis_file skip false empty analysis
💡 Result:
The query appears to reference an automated GitHub Actions workflow (pr-monitor.yml) associated with the repository aloekun/claude-code-hook-test [1], which is part of a community-developed suite for testing Claude Code hooks [2][3]. The specific command provided, gh pr comment --body-file analysis_file, is used by the GitHub CLI to post a comment on a pull request using the contents of a specified file (analysis_file) as the body [4][5][6]. The flags skip false empty analysis are likely custom arguments or shell variables defined within the context of that specific workflow script, rather than standard flags for the gh pr comment command [4][5][7]. In the context of testing Claude Code hooks: 1. gh pr comment is frequently used in CI/CD automation to post analysis or diagnostic results back to a pull request [4][8]. 2. The --body-file flag is the correct way to pipe dynamic content (like a generated analysis) from a file into a GitHub PR comment [4]. 3. Claude Code hook development often involves scripts that validate tool behavior, simulate hook triggers, and report findings [2][9][10]. The claude-code-hook-test repository is a known community effort designed to verify whether Claude Code hooks fire correctly under various conditions [3]. If you are encountering errors with this command, ensure that: - analysis_file exists and contains valid markdown or text content before the gh pr comment command runs. - The GH_TOKEN environment variable is correctly set in your workflow to allow the GitHub CLI to authenticate and post comments [11]. - The arguments skip, false, and empty are intended to be processed by your wrapper script or analysis_file generator, as they are not native gh pr comment flags [5][7].
Citations:
- 1:
jj bookmark setcan't handle double dashes in bookmark names jj-vcs/jj#7593 - 2: https://github.com/VoxCore84/claude-code-hook-tester
- 3: https://github.com/grahama1970/claude-code-hooks-test
- 4:
gh pr commentwith body from STDIN cli/cli#12136 - 5: https://man.archlinux.org/man/gh-pr-comment.1.en.raw
- 6: https://linuxcommandlibrary.com/man/gh-pr-comment
- 7: https://cli.github.com/manual/gh_pr_create
- 8: Feature Request: Automated Test Failure Detection and Self-Remediation for GitHub PRs anthropics/claude-code#6581
- 9: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/hook-development/scripts/README.md
- 10: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/hook-development/scripts/test-hook.sh
- 11: https://github.com/smigolsmigol/llmkit/blob/b4a83973d4507c16076a1817f09b4af5db5a32b8/.github/workflows/pr-monitor.yml
🌐 Web query:
"aloekun/claude-code-hook-test" "pr-monitor.yml" "analysis_file" "gh pr comment" "skip=true" "SKIP: no new information"
💡 Result:
The query refers to components of an automated Pull Request (PR) monitoring system designed for Claude Code or similar LLM-driven development workflows [1][2][3][4]. These components typically appear in scripts (e.g., pr-monitor.yml [5] or custom shell-based hooks [2]) used to check for new activity on GitHub PRs and avoid redundant processing [4][6]. Key components identified in your query include: 1. "aloekun/claude-code-hook-test": This appears to be a repository specifically used as a testbed for developing and validating custom Claude Code hooks [2]. 2. "pr-monitor.yml": A common filename for a GitHub Actions workflow or a local script used to monitor PR states, comments, or CI status [5][7]. 3. "analysis_file": This refers to a temporary JSON or Markdown file (often named prNN-analysis.md or similar) used to store the current state of a PR or the output of a previous analysis [4][8][6]. The system reads this file to determine if the state has changed since the last check [5][4]. 4. "gh pr comment": The GitHub CLI command (gh pr comment) is used to post summaries or feedback back to the PR once the script completes its analysis [4][7]. 5. "skip=true" / "SKIP: no new information": These are control flags and log messages used in the monitor's logic [4][9]. When a script compares the current PR state (fetched via gh api or gh pr view) against the cached "analysis_file" and finds no substantive changes (e.g., no new comments, no state transitions), it sets a skip flag (often skip=true) or logs a "SKIP: no new information" message to terminate the execution early, thereby saving compute cycles and API tokens [5][4][7][10]. This pattern is a standard architectural choice in LLM automation to prevent redundant re-analysis of static PR data [4][6][10].
Citations:
- 1: https://github.com/kawaz/claude-gh-monitor
- 2: https://github.com/mshashank0/claude-code-toolkit?tab=readme-ov-file
- 3: https://github.com/adevra/claude-pr-review-loop
- 4: https://github.com/auldsyababua/instructor-workflow/tree/main/skills/pr-comment-analysis
- 5: https://github.com/smigolsmigol/llmkit/blob/b4a83973d4507c16076a1817f09b4af5db5a32b8/.github/workflows/pr-monitor.yml
- 6: https://raw.githubusercontent.com/NeverSight/skills_feed/refs/heads/main/data/skills-md/auldsyababua/instructor-workflow/pr-comment-analysis/SKILL.md
- 7: https://github.com/hasundue/dotnix/blob/b42d61596853b79309002eec3edc161337f40bd8/.github/workflows/issue-monitor.yml
- 8: https://github.com/vinhnxv/rune/blob/main/plugins/rune/skills/resolve-all-gh-pr-comments/SKILL.md
- 9: https://github.com/edloidas/skills/blob/master/review/review-comments/SKILL.md
- 10: https://unpkg.com/@clipboard-health/ai-rules@2.29.5/skills/babysit-pr/SKILL.md
🌐 Web query:
gh pr comment --body-file empty file behavior
💡 Result:
When using the GitHub CLI command gh pr comment with the --body-file flag, providing an empty file will typically result in the command failing to create a comment because the GitHub API rejects empty issue or pull request comments [1][2]. Specifically, the GitHub API requires that comments contain at least some content. If you provide an empty file to --body-file, the GitHub CLI will attempt to send that empty body to the API, which will respond with an error (usually indicating that the body is missing or cannot be blank). If your goal is to automate commenting and you want to avoid errors when the content might be empty, you should add a check in your script or pipeline to verify that the file is not empty before executing the command [3][4]. For example: if [ -s "file.txt" ]; then gh pr comment <PR_NUMBER> --body-file file.txt fi This prevents the gh command from attempting to post an empty body to the pull request [1][2].
Citations:
- 1: https://cli.github.com/manual/gh_pr_comment
- 2: https://man.archlinux.org/man/gh-pr-comment.1.en
- 3: https://docs.continue.dev/guides/github-pr-review-bot
- 4: https://github.com/orgs/community/discussions/69944
空の分析結果も skip 扱いにする
jq の抽出結果が空だと skip=false になり、後続の gh pr comment --body-file に空本文を渡して失敗します。-z "$TRIMMED" も skip=true に含めてください。
🤖 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 @.github/workflows/pr-monitor.yml around lines 199 - 210, The PR monitor
workflow’s skip detection only handles the "SKIP: no new information" marker, so
an empty analysis still falls through and causes the later comment step to fail.
Update the trimming/skip check in the analysis processing block to treat an
empty TRIMMED value as skip=true as well, alongside the existing sentinel, so
the job can safely bypass gh pr comment when jq produces no result.
- Extract step: 空出力 (エージェント異常終了・抽出失敗) を skip 扱いにし、空コメント 投稿を防止 (CodeRabbit Minor #258-2)。 - prompt: 最終応答を前置きなしで見出しから開始するよう明示 + extract step で見出し行 以降のみ採用して正規化 (初回 run で前置き混入を実観測、重複ガードの見出し検出も安定化)。 見出し不在の異常時は原文維持で空投稿を回避。 ADR-022 原則5 に従い PR 包含 commit を amend せず child commit として分離。
WP-10: ADR-052 起票。自律 actor 限定で操作を 2 クラス(自動実行可 / ゲート必須)に 事前分類し、分類不能は fail-closed でゲート必須へ(ADR-043)。ADR-028 のゲートを除去 せず commitment 点(ready 化 / マージ)へ移設する 2 段化が本質。Rust 分類関数は呼び手 (自律実行経路)不在のため今回見送り、consumer 着手時に gate.rs の docs-only 判定を lib 切り出しで再利用実装する方針を明記。ADR-039 パターンで試験運用。 - CLAUDE.md の ADR 一覧に ADR-052 追加。 - harness-improvement-plan.md: WP-10 を実装済、WP-09 を観測中(GitHub Actions バック ストップが PR #258 でマージ・本稼働、secrets 登録済・スモークテスト成功を反映)に更新。
概要
WP-09(ハーネス改善計画 1-C)。PR 監視をローカルセッションの寿命から切り離す第一歩として、GitHub Actions 上の読み取り専用バックストップ監視
.github/workflows/pr-monitor.ymlを新設する。セッション不在時に PR のレビュー・CI 状態を無人で分析し、日本語コメントを PR に投稿する(fix push はしない = Phase A)。背景: ローカル cli-pr-monitor は wakeup 機構がセッション寿命に依存し、PR #237 で失効を実測。Actions 経路をバックストップとして併存させる(責務分離は ADR-022 原則6 に追記)。
設計のポイント
pull_request_review(全レビュアー)+pull_request(opened/ready_for_review)+issue_comment(coderabbitai[bot] 発のみ)。特定レビューツール固有の条件は issue_comment の 1 条件に局所化し、CodeRabbit へのロックインを回避。レートリミット時も待機・ポーリングせず、required check にも登録しないためマージ・他ツールを一切ブロックしない。--body-fileでデータとして実行(injection を受けた出力がコマンド/secrets 露出に転じない)。permissions: contents: read(push は 403)、persist-credentials: false。synchronize非対象、timeout-minutes: 15、--max-turns 30、重複コメント skip。fork PR 対象外、pull_request_target不使用。pre-push セキュリティレビューの成果
本 PR の pre-push review が land 前に secret-exfiltration/scope 系 3 件を検出・修正した:
gh apiの過剰スコープ → GET エンドポイント完全一致に限定。persist-credentialsによる GITHUB_TOKEN の.git/config書き込み →false化。指示層のみに頼らず LLM 外側で担保する設計が機能した実例。
有効化とユーザー作業
CLAUDE_CODE_OAUTH_TOKENは登録済み。pull_requestトリガーは本 PR 自体で発火し初回スモークテストになる(認証・権限・読み取り専用の疎通確認)。pull_request_review/issue_commentトリガーはデフォルトブランチ(master)上の定義でのみ発火するため、バックストップの本稼働はマージ後から。変更
.github/workflows/pr-monitor.yml(新規)docs/adr/adr-022-automation-responsibility-separation.md— 原則6「PR 監視経路の二重化と権限の非対称」追記docs/harness-improvement-plan.md— WP-09 を実装済に更新dogfood / follow-up(非ブロッキング)
gh pr commentが要求する write scope(pull-requests / issues)を実 run で確認し不要な方を削る。gh pr checksがchecks/statusesscope を要するか dogfood で確認。Summary by CodeRabbit
新機能
ドキュメント