目次
- はじめに:Claude CodeをPR差分レビュー専用で運用する
- PR差分レビューで決めた運用方針
- Codex・Claude Code・ChatGPT・人間の役割分担
- 先に覚えておきたいClaude Codeの基本コマンド
- PR差分レビュー用Skillを作成する
/pr-diff-reviewで実際にレビューする- Bash確認画面で許可・拒否を判断する
- Bashを全面禁止して分かった問題
- レビュー中のPlanファイル書き込み要求を拒否した
- Claude Codeから出た指摘を人間が確認する
- 安全な運用をドキュメントとテストに残す
- 実際に運用して感じたこと
- まとめ
- 関連記事
はじめに:Claude CodeをPR差分レビュー専用で運用する
Claude Codeの導入と初期設定が終わったため、実際のPythonプロジェクトでPR差分レビューに使用しました。
今回は、Claude Codeへ実装修正を任せず、PR差分レビュー専用のSkillを作成しています。
実際に運用すると、Bashを禁止しすぎて差分を正しく確認できない問題や、レビュー中に計画ファイルを書き込もうとする場面もありました。
この記事では、PR差分レビュー用Skillの作成方法だけでなく、Bash確認画面で何を許可・拒否したか、Claude Codeの指摘をどのように評価したかまでまとめます。
PR差分レビューで決めた運用方針
今回は、Claude Codeに実装や修正を任せるのではなく、PR差分レビュー専用として使うことにしました。
最初から広い権限を与えず、次の方針で運用します。
- レビュー対象として指定した差分だけを確認する
- ファイルの編集や修正は行わせない
-
commit、push、mergeなどのGit変更操作は行わせない - 実ログ、実IP、ローカル設定値、秘密情報は読ませない
- 状態確認や差分確認に必要な読み取り系Gitコマンドだけを許可する
- Bashコマンドは自動許可せず、人間が内容を確認する
- テストは、ユーザーが明示した対象限定コマンドだけを実行させる
- Claude Codeの指摘をそのまま採用せず、最終判断は人間が行う
安全性を理由にBashをすべて禁止すると、git diffなども使えず、現在の変更内容を正確に確認できない場合があります。
そのため今回は、すべてを禁止するのではなく、レビューに必要な読み取り操作だけを人間の確認付きで許可する方針にしました。
Codex・Claude Code・ChatGPT・人間の役割分担
今回は、1つのAIに実装からレビューまですべて任せるのではなく、役割を分けて運用しました。
Codexは実装・テスト・ドキュメント修正を担当する
Codexには、Issueの要件に沿った実装、テスト追加、ドキュメント修正を担当させます。
作業前にREADME、AGENTS.md、関連ドキュメントを確認させ、変更対象と変更しないファイルを明確にしてから作業を進めます。
ただし、ブランチ作成、commit、push、mergeなどのGit変更操作は任せません。
Claude CodeはPR差分レビューを担当する
Claude Codeには、Codexが変更したPR差分のレビューを担当させます。
指定したファイルだけを確認し、ファイル編集や修正は行わせません。
レビューでは、秘密情報や実ログの混入、仕様との不整合、テスト不足、ドキュメントとの矛盾などを確認させます。
別のAIモデルでレビューすることで、実装担当とは異なる視点から確認できるようにしました。
ChatGPTはIssue設計とレビュー指摘の整理を担当する
ChatGPTには、Issue本文、受け入れ条件、ブランチ名、PR本文、作業手順の整理を担当させています。
Claude Codeから指摘が出た後は、その指摘が今回の差分に関係するか、修正すべきか、別Issueへ分けるべきかを整理します。
Claude Codeの指摘をそのまま採用するのではなく、仕様や実際の差分と照らし合わせて判断する役割です。
Git操作と最終判断は人間が行う
ブランチ作成、commit、push、PR作成、merge、ブランチ削除などのGit変更操作は、すべて自分で行います。
Bashの権限確認画面でも、表示されたコマンドが読み取り系か、書き込みや外部通信を伴うものかを確認してから許可します。
AIから提案や指摘を受けても、最終的に採用するかどうかは人間が判断します。
先に覚えておきたいClaude Codeの基本コマンド
Claude Codeでは、Ubuntuなどのターミナルから実行するコマンドと、Claude Codeを起動した後に入力するスラッシュコマンドがあります。
最初は、この違いが少し分かりにくかったため、今回よく使ったものだけ簡単に整理します。
まずは、実行場所と用途を一覧で確認します。
| コマンド | 実行場所 | 用途 |
|---|---|---|
claude |
ターミナル | 新しいセッションを開始 |
claude --continue |
ターミナル | 現在のプロジェクトの直前セッションを再開 |
claude --resume |
ターミナル | 過去のセッション一覧から選択 |
claude --resume <session-id-or-name> |
ターミナル | IDまたは名前を指定して再開 |
/compact |
Claude Code内 | 会話を要約してコンテキストを整理 |
/usage |
Claude Code内 | 使用状況・利用上限を確認 |
/model |
Claude Code内 | 使用モデルを選択 |
/permissions |
Claude Code内 | 権限ルールを確認 |
/skills |
Claude Code内 | 利用可能なSkillを確認 |
/diff |
Claude Code内 | Git差分を対話画面で確認 |
/context |
Claude Code内 | コンテキスト使用状況を確認 |
ターミナルから実行するコマンド
Claude Codeを起動する
claude
現在のディレクトリを対象として、新しいClaude Codeの対話セッションを起動します。
プロジェクトの CLAUDE.md や .claude/settings.json、Skillsを読み込ませるため、基本的にはプロジェクトルートで実行します。
現在のプロジェクトで、直前のセッションを再開する
claude --continue
現在のディレクトリで最後に使用したセッションを再開します。
短縮形も使用できます。
claude -c
過去のセッション一覧から選択する
claude --resume
保存されているセッション一覧を表示し、再開するセッションを選択します。
特定のセッションIDまたはセッション名を指定することもできます。
claude --resume <session-id-or-name>
短縮形は次のとおりです。
claude -r <session-id-or-name>
記事や公開ドキュメントへ載せる場合は、実際のセッションIDをそのまま掲載せず、<session-id> のようなダミー表記にします。
Claude Code内で実行するスラッシュコマンド
次のコマンドは、Claude Codeを起動した後の入力欄で使用します。
コンテキストを整理する
/compact
長くなった会話を要約し、コンテキストの使用量を減らします。
残したい内容を補足することもできます。
/compact Issue番号、変更ファイル、未完了タスク、安全上の注意を残してください
ただし、圧縮後も以前の細かい指示が完全に維持されるとは決めつけず、重要なSkillやレビュー対象は再度指定します。
使用状況を確認する
/usage
現在のセッションの使用状況、プランの利用上限、アクティビティなどを確認します。
使用するモデルを変更する
/model
使用するモデルを選択します。
引数を付けずに実行すると、選択画面が表示されます。
権限設定を確認する
/permissions
Claude Codeが使用できるツールの allow、ask、deny を確認します。
レビュー中に、どのBashコマンドが確認対象になっているかを確認したい場合にも使えます。
利用できるSkillを確認する
/skills
現在利用できるSkillの一覧を表示します。
今回作成したSkillが読み込まれていれば、一覧に次が表示されます。
pr-diff-review
差分を確認する
/diff
未コミットの変更や、Claude Codeの操作によって発生した差分を確認するための画面を開きます。
今回の運用ではClaude Codeへ編集を許可していませんが、現在のGit差分を確認する補助として利用できます。
コンテキストの使用状況を確認する
/context
現在のコンテキストが、どの情報によって使用されているかを確認します。
会話が長くなり、不要なファイル内容や過去の作業が増えてきた場合の確認に使えます。
セッションを引き継ぐときの注意点
claude --continue や claude --resume は便利ですが、重要な作業ではセッション履歴だけに依存しないようにしています。
必要に応じて、Claude Codeへ次のように引き継ぎメモを作成させます。
このセッションの引き継ぎメモをMarkdownで作成してください。
実ログ、実IP、ローカル設定値、外部応答全文は含めないでください。
次回は claude --resume で再開する前提で、
Issue番号、現在のブランチ、変更内容、未完了タスク、
テスト結果、安全上の注意点をまとめてください。
また、/compact やセッション再開後は、以前のSkillが有効なままだと決めつけず、レビュー時には改めて次のように呼び出します。
/pr-diff-review <レビュー対象ファイル>
PR差分レビュー用Skillを作成する
毎回同じレビュー条件を入力する手間と、指示漏れを減らすため、PR差分レビューの手順をプロジェクト専用Skillとしてまとめました。
ここでは、Skillの配置場所、frontmatter、引数、安全ルールについて説明します。
毎回のレビュー指示をSkillへまとめた理由
最初は、Claude CodeへPR差分レビューを依頼するたびに、レビュー対象、許可するコマンド、禁止事項、出力形式をプロンプトへ書いていました。
しかし、毎回長い指示を入力すると、書き忘れや表現のずれが起こりやすくなります。
実際に、あるレビューではBashを全面禁止する指示を入れたため、Claude Codeが git diff を使えず、現在の差分を正確に確認できませんでした。
その結果、以前のセッション内容をもとに、過去の変更を今回の差分として扱う場面がありました。
一方で、Bashを広く許可すると、ファイル書き込みや外部通信など、レビューには不要な操作まで実行される可能性があります。
そこで、毎回同じ長いプロンプトを書くのではなく、次の内容をPR差分レビュー専用のSkillへまとめることにしました。
- レビュー対象の受け取り方
- 使用できる読み取り系Gitコマンド
- 禁止するGit変更操作
- ファイル編集と外部通信の禁止
- 対象限定テストの扱い
- レビュー結果の出力形式
Skillとして手順を固定することで、レビューごとの指示漏れを減らし、同じ方針で繰り返し利用できるようにしました。
プロジェクト専用Skillとして配置する
今回は、PR差分レビュー用Skillを次の場所へ配置しました。
.claude/skills/pr-diff-review/SKILL.md
ディレクトリ構成は次のとおりです。
.claude/
└── skills/
└── pr-diff-review/
└── SKILL.md
.claude/skills/ 配下へ配置することで、このリポジトリ専用のSkillとして管理できます。
ディレクトリ名を pr-diff-review としたため、Claude Code内では次のように呼び出します。
/pr-diff-review
今回はアクセスログ解析プロジェクト固有の禁止事項やレビュー手順を含むため、個人環境全体で共有するSkillではなく、リポジトリ内へ配置しました。
これにより、Skill本体をほかのソースコードやドキュメントと同じようにGitで管理し、変更履歴やレビュー対象として扱えます。
frontmatterでSkillの起動条件を設定する
SKILL.md の先頭には、Skillの名前や説明、起動方法を定義するfrontmatterを記載します。
今回の設定は次のとおりです。
---
name: pr-diff-review
description: 指定されたPR差分を、読み取り系Gitコマンドとユーザーが明示した対象限定テストだけで安全にレビューする。
argument-hint: "[レビュー対象ファイルまたは差分範囲] [任意: 実行を許可する対象限定テスト]"
disable-model-invocation: true
---
各項目には次の役割があります。
| 項目 | 役割 |
|---|---|
name |
Skill一覧に表示する名前を定義する。省略時はディレクトリ名が使用される |
description |
どのような場面で使うSkillかを説明する |
argument-hint |
Skill呼び出し時に渡す引数の例を表示する |
disable-model-invocation |
Claude Codeによる自動起動を無効にする |
今回使用する/pr-diff-reviewという呼び出し名は、Skillを配置したpr-diff-reviewディレクトリに対応しています。
今回は、PR差分レビューをユーザーが明示的に開始した場合だけ実行させたいため、次を設定しました。
disable-model-invocation: true
これにより、Claude Codeが必要だと判断してSkillを自動起動するのではなく、ユーザーが次のように入力した場合だけ使用します。
/pr-diff-review <レビュー対象>
PR差分レビューでは、対象ファイルや許可するテストコマンドを人間が確認してから渡したいため、自動起動させない構成にしました。
実際のSkillも、name、argument-hint、disable-model-invocation: trueをfrontmatterへ定義しています。
allowed-toolsを設定しなかった理由
allowed-toolsを指定すると、登録したツールをSkillの実行中に確認なしで使用できるようになります。
ただし、allowed-toolsは使用可能なツールを限定する設定ではありません。指定していないツールには、引き続き通常の権限設定が適用されます。
今回の運用では、読み取り系Gitコマンドについても、実行前に人間がコマンド内容と対象範囲を確認する方針にしました。
そのため、Skillのfrontmatterにはallowed-toolsを設定せず、.claude/settings.jsonの権限設定とBash確認画面での人間による承認を安全境界にしています。
詳細は、Claude Code公式ドキュメントのSkills解説で確認できます。
$ARGUMENTSでレビュー対象を明示する
Skillを呼び出す際は、レビュー対象のファイルや差分範囲を引数として渡します。
今回のSkillでは、呼び出し時に入力された内容を $ARGUMENTS で受け取ります。
- `$ARGUMENTS` からレビュー対象ファイル、差分範囲、任意の対象限定テストを確認します。
Claude Code内では、次のように呼び出します。
/pr-diff-review .claude/skills/pr-diff-review/SKILL.md docs/CLAUDE_CODE_REVIEW.md
この場合、$ARGUMENTS には次の部分が渡されます。
.claude/skills/pr-diff-review/SKILL.md docs/CLAUDE_CODE_REVIEW.md
対象限定テストを実行させる場合は、レビュー対象とあわせて正確なコマンドを明示します。
/pr-diff-review .claude/skills/pr-diff-review/SKILL.md
実行を許可する対象限定テスト:
PYTHONPATH=src .venv/bin/python -m pytest tests/test_claude_code_review_skill.py -q
Skill側でテスト対象やコマンドを推測させず、ユーザーが指定した範囲だけを確認させる構成にしました。
レビュー対象が不明確な場合は、Claude Codeが勝手に対象範囲を広げず、ユーザーへ確認するようにしています。
レビューで許可する操作と禁止する操作を定義する
Skillには、レビュー時に使用できる操作と、実行してはいけない操作を明記しました。
許可する操作
レビュー範囲の確認に必要な読み取り系Gitコマンドだけを使用できます。
git status --short
git branch --show-current
git diff -- <指定されたファイル>
git diff --cached -- <指定されたファイル>
git diff HEAD -- <指定されたファイル>
git diff --check
対象限定テストは、ユーザーが正確なコマンドを明示した場合だけ実行できます。
引数なしの広範囲な git diff は、ユーザーが全差分のレビューを明示した場合だけ使用します。
禁止する操作
ファイル編集には、次のツールを使用しません。
Edit
Write
NotebookEdit
Git変更操作も禁止します。
git branch --show-currentによる現在ブランチの確認は許可しますが、ブランチの作成・削除・名前変更を伴う操作は禁止します。
git switch
git checkout
git pull
git fetch
git branch <新しいブランチ名>
git branch -d <ブランチ名>
git branch -D <ブランチ名>
git branch -m <新しいブランチ名>
git add
git commit
git push
git merge
git rebase
git reset
git restore
git stash
git clean
git tag
外部通信を行うコマンドやツールも使用しません。
curl
wget
whois
dig
nslookup
ssh
scp
rsync
WebFetch
MCP
外部AIコネクタ
また、次のようなデータはレビュー対象として指定されても読みません。
config.yml.env- 実アクセスログ
- 実エラーログ
- 実IP一覧
- Excel原本
- キャッシュ
- 秘密鍵
- tokenファイル
- 外部応答全文
すべてのBashを禁止するのではなく、レビューに必要な読み取り操作だけを人間の確認付きで許可する方針にしました。
/pr-diff-reviewで実際にレビューする
Skillを追加したら、新しいClaude Codeセッションで実際にPR差分レビューを行います。
今回は、レビュー対象の3ファイルと、実行を許可する対象限定テストを明示してSkillを呼び出しました。
Claude Codeには、現在のブランチと変更状態を確認させ、staged・unstaged・untrackedを区別したうえで、指定した範囲だけをレビューさせます。
新しいセッションで/pr-diff-reviewを呼び出す
Skillを追加した後は、プロジェクトルートで新しいClaude Codeセッションを起動します。
claude
Claude Codeが起動したら、作成したSkillを明示的に呼び出します。
/pr-diff-review <レビュー対象ファイル>
今回は disable-model-invocation: true を設定しているため、Claude CodeがこのSkillを自動的に起動することはありません。
ユーザーが /pr-diff-review を入力した場合だけ実行されます。
また、/compact や claude --resume の後は、以前のSkillの指示がそのまま維持されていると仮定せず、必要に応じてもう一度 /pr-diff-review を呼び出します。
レビュー対象ファイルを具体的に指定する
/pr-diff-review を呼び出す際は、レビューしてほしいファイルを引数として明示します。
今回は、次の3ファイルを指定しました。
/pr-diff-review .claude/skills/pr-diff-review/SKILL.md docs/CLAUDE_CODE_REVIEW.md tests/test_claude_code_review_skill.py
レビュー対象を明示することで、Claude Codeが関係のないファイルまで確認範囲を広げることを防ぎます。
今回の3ファイルには、次の状態が混在していました。
- 既存ファイルの変更
- 新規追加した未追跡ファイル
- Gitへまだstageしていない差分
通常の git diff では未追跡ファイルの本文は表示されません。
そのため、既存ファイルはGitの差分で確認し、未追跡ファイルは指定されたファイルだけをReadで確認させるようにしました。
プロジェクト全体をレビューさせるのではなく、Issueで変更したファイルだけを指定することで、レビュー範囲を明確にしています。
実行を許可する対象限定テストを明示する
レビュー対象だけでなく、Claude Codeに実行させるテストも明示します。
今回は、PR差分レビュー用Skillの退行防止テストだけを対象にしました。
実行を許可する対象限定テスト:
PYTHONPATH=src .venv/bin/python -m pytest tests/test_claude_code_review_skill.py -q
Skillの呼び出しとまとめて渡す場合は、次のように入力します。
/pr-diff-review .claude/skills/pr-diff-review/SKILL.md docs/CLAUDE_CODE_REVIEW.md tests/test_claude_code_review_skill.py
実行を許可する対象限定テスト:
PYTHONPATH=src .venv/bin/python -m pytest tests/test_claude_code_review_skill.py -q
テストファイル名だけを伝えて、Claude Code側にコマンドを推測させる運用にはしませんでした。
ユーザーが実行してよいコマンドを正確に指定し、Bashの確認画面に同じコマンドが表示された場合だけ許可します。
今回の実行結果は次のとおりでした。
7 passed
一方で、次のような広い検証は既定では実行させません。
- 全テスト
- coverage
- lint
- formatter
- build
- 外部通信を伴うテスト
- 実ログを参照するテスト
これらが必要な場合は、対象限定テストと同じように、実行するコマンドと目的を人間が確認してから個別に許可します。
また、pytestが見つからない、仮想環境が有効でないなどの問題が起きても、Claude Codeにパッケージ導入や環境変更を任せません。
実行できなかったことをレビュー結果へ記載させ、環境の修正や追加検証は人間または実装担当側で判断します。
staged・unstaged・untrackedを区別して確認する
Gitの変更は、現在の状態によって確認方法が異なります。
今回のレビュー対象には、既存ファイルの変更だけでなく、新しく追加した未追跡ファイルも含まれていました。
Claude Codeが現在の変更を正確に確認できるように、Skillでは次の3つを区別させています。
| 状態 | 意味 | 主な確認方法 |
|---|---|---|
| unstaged | 変更したが、まだgit addしていない |
git diff -- <path> |
| staged |
git add済みで、次のcommit対象になっている |
git diff --cached -- <path> |
| untracked | Gitがまだ管理していない新規ファイル | 指定されたファイルをReadで確認 |
unstagedの差分を確認する
既存ファイルを変更したものの、まだstageしていない場合は、次のコマンドで確認します。
git diff -- <対象ファイル>
今回の例では、既存の運用ドキュメントがunstagedの状態でした。
git diff -- docs/CLAUDE_CODE_REVIEW.md
stagedの差分を確認する
git add済みの変更は、通常のgit diffでは表示されません。
そのため、次のコマンドを使用します。
git diff --cached -- <対象ファイル>
HEADから現在までの変更をまとめて確認する場合は、次のコマンドも使用できます。
git diff HEAD -- <対象ファイル>
untrackedファイルを確認する
新しく作成した未追跡ファイルは、通常のgit diffでは本文が表示されません。
今回追加した次の2ファイルも、レビュー時点では未追跡でした。
.claude/skills/pr-diff-review/SKILL.md
tests/test_claude_code_review_skill.py
そのため、Claude Codeには、レビュー対象として明示した未追跡ファイルだけをReadで確認させました。
未追跡だからといってリポジトリ全体を探索させるのではなく、ユーザーが指定したファイルだけを読ませます。
また、次のような禁止対象ファイルが未追跡であっても、Readは許可しません。
config.yml
.env
logs/
output/
.cache/
実ログ
実IP一覧
秘密鍵
tokenファイル
変更状態を最初に確認する
レビュー開始時には、最初に次のコマンドで現在の状態を確認させます。
git status --short
今回のような状態では、次のように表示されます。
M docs/CLAUDE_CODE_REVIEW.md
?? .claude/skills/
?? tests/test_claude_code_review_skill.py
先頭の記号から、変更状態を判断できます。
| 表示 | 意味 |
|---|---|
M |
unstagedの変更 |
M |
stagedの変更 |
A |
stage済みの新規ファイル |
?? |
untrackedファイル |
Claude Codeにこの状態を確認させてからレビューを開始することで、過去の変更や前回セッションの内容を、今回の差分として誤認しにくくなります。
通常のgit diffだけでは、stagedやuntrackedの内容をすべて確認できません。
そのため、PR差分レビューでは、変更状態に応じて確認方法を切り替えることが重要でした。
Bash確認画面で許可・拒否を判断する
今回の設定では、Claude CodeによるBash実行を自動許可していません。
Bashコマンドを実行しようとすると確認画面が表示されるため、コマンドの内容を人間が確認し、許可または拒否を判断します。
ここで重要なのは、コマンド名だけを見て判断するのではなく、次の点を確認することです。
- ファイルやGitの状態を確認するだけか
- ファイルの作成・上書き・削除を伴わないか
- 対象範囲が広すぎないか
- 外部通信を行わないか
- 実ログや秘密情報へアクセスしないか
- ユーザーが事前に許可したテストコマンドか
読み取り系Gitコマンドは内容を確認して許可する
PR差分レビューでは、現在のブランチや変更状態を確認するために、読み取り系Gitコマンドが必要です。
今回のSkillでは、次のコマンドを確認用途として使用できるようにしました。
git status --short
git branch --show-current
git diff -- <指定されたファイル>
git diff --cached -- <指定されたファイル>
git diff HEAD -- <指定されたファイル>
git diff --check
それぞれの用途は次のとおりです。
| コマンド | 用途 |
|---|---|
git status --short |
staged・unstaged・untrackedの状態を確認する |
git branch --show-current |
現在のブランチを確認する |
git diff -- <path> |
unstagedの差分を確認する |
git diff --cached -- <path> |
stagedの差分を確認する |
git diff HEAD -- <path> |
HEADから現在までの差分を確認する |
git diff --check |
空白エラーなどを確認する |
これらはGitの状態を変更せず、現在の状態や差分を確認するためのコマンドです。
ただし、読み取り系Gitコマンドであっても、レビュー対象外のファイルまで広く確認しようとしていないかは確認します。
たとえば、次のように対象ファイルが明示されていれば、今回のレビュー範囲と一致しているか判断できます。
git diff -- docs/CLAUDE_CODE_REVIEW.md
一方で、レビュー対象を限定しているのに、引数なしのgit diffでリポジトリ全体を確認しようとしている場合は、実行目的を確認してから許可します。
対象範囲を限定した確認コマンドだけを許可する
Git以外にも、ファイルの存在やディレクトリ構成を確認するために、findなどのコマンドを使う場合があります。
find自体はファイルを変更するコマンドではありませんが、指定された探索範囲によって安全性が変わります。
たとえば、次のように今回のレビュー対象へ限定されていれば、確認目的として許可できます。
find .claude/skills/pr-diff-review -type f
テストファイルを限定して探す場合も同様です。
find tests -name 'test_claude_code_review_skill.py'
一方で、次のようにリポジトリ全体を探索するコマンドは許可しません。
find . -type f
このコマンドでは、レビュー対象外のファイルだけでなく、次のような禁止対象へ到達する可能性があります。
config.yml
.env
logs/
output/
.cache/
秘密鍵
tokenファイル
実ログ
実IP一覧
確認系のコマンドでも、対象範囲が必要以上に広い場合は安全とは限りません。
コマンドの種類だけでなく、引数や探索先まで確認することが重要です。
ファイル書き込みを伴うコマンドは拒否する
PR差分レビューでは、Claude Codeにファイルを作成・編集させません。
そのため、次のような書き込みを伴う記号やコマンドが含まれている場合は拒否します。
| 表記・コマンド | 主な動作 |
|---|---|
> |
ファイルを新規作成または上書きする |
>> |
ファイルの末尾へ追記する |
tee |
標準入力をファイルへ書き込む |
cat > file |
ファイルを作成または上書きする |
sed -i |
ファイルを直接編集する |
rm |
ファイルやディレクトリを削除する |
mv |
ファイルを移動し、場合によっては上書きする |
実際のレビューでは、Planファイルを作成する書き込みコマンドが確認画面に表示されました。
このコマンドは許可せず、計画ファイルを作らずにレビュー結果をチャットへ直接出力するよう指示しました。
具体的なコマンドの内容と判断理由は、後の「レビュー中のPlanファイル書き込み要求を拒否した」で詳しく説明します。
外部通信を伴うコマンドは拒否する
今回のプロジェクトでは、Claude Codeによる外部通信も許可していません。
次のようなコマンドは実行を拒否します。
curl
wget
whois
dig
nslookup
ssh
scp
rsync
これらのコマンドには、次のような可能性があります。
- 外部サイトやAPIへアクセスする
- ファイルをダウンロードする
- IPアドレスやドメイン情報を外部へ問い合わせる
- 別のサーバーへ接続する
- ファイルを外部へ転送する
今回のプロジェクトでは、実IPやローカル情報を扱うため、意図しない外部送信を避ける必要があります。
Claude Codeのレビューでは、外部情報を取得しなくても、リポジトリ内のコード、テスト、ドキュメント、Git差分だけで確認できる範囲に限定しました。
WebFetch、MCP、外部AIコネクタについても使用しない方針です。
判断できないコマンドは許可しない
確認画面に表示されたコマンドの意味や影響を判断できない場合は、その場で許可しません。
安全そうに見えるコマンドでも、引数やリダイレクトの組み合わせによって、ファイルの書き込みや外部通信が発生する場合があります。
今回の運用では、次のように判断しました。
- 状態や差分を読むだけなら、対象を確認して許可する
- ユーザーが明示した対象限定テストなら許可する
- ファイルへの書き込みを伴う場合は拒否する
- Gitの状態を変更する場合は拒否する
- 外部通信を伴う場合は拒否する
- 対象範囲が広すぎる場合は拒否する
- 意味が分からない場合は、理解するまで許可しない
Claude Codeの確認画面にコマンドの説明機能が表示されている場合は、実行前に目的や副作用を確認できます。
ただし、説明を表示しただけで安全になるわけではありません。
最終的には、表示されたコマンドが今回許可したレビュー範囲に収まっているかを人間が判断します。
今回の経験から、Claude Codeを安全に使うには、設定ファイルによる権限制御だけでなく、利用者側にも最低限のLinuxコマンドの知識が必要だと感じました。
すべてのBashを禁止するのでも、すべてを許可するのでもなく、必要な読み取り操作だけを、人間が内容を確認したうえで許可する運用にしています。
Bashを全面禁止して分かった問題
Claude Codeを安全に使うため、最初はレビュー用の指示でBashを全面禁止していました。
ファイル編集やGit変更操作をさせないためには、Bash自体を使わせなければ安全だと考えたためです。
しかし、実際にPR差分レビューで使ってみると、Bashを全面禁止したことで別の問題が起きました。
git diffを実行できずレビュー範囲がずれた
PR差分レビューでは、現在の変更内容を確認するために、次のような読み取り系Gitコマンドが必要です。
git status --short
git branch --show-current
git diff -- <対象ファイル>
git diff --cached -- <対象ファイル>
git diff HEAD -- <対象ファイル>
git diff --check
これらはファイルやGitの状態を変更するコマンドではなく、現在のブランチ、変更状態、差分内容を確認するためのコマンドです。
ところが、レビュー用の指示で次のようにBashを全面禁止していました。
Bashは実行しないでください。
Git操作は行わないでください。
この書き方では、git commitやgit pushなどの変更系Git操作だけでなく、git diffやgit statusなどの読み取り系Git操作まで使えなくなります。
その結果、Claude Codeは現在の差分をGitから取得できず、以前のセッションで読んだファイル内容や、現在のファイル全体をもとにレビューを行いました。
実際のレビューでは、以前のIssueで追加済みだった変更を、今回の差分に含まれる変更として扱う場面がありました。
人間側で実際のgit diffを確認すると、今回変更したのは数行だけでした。
つまり、Claude Codeの指摘内容そのものよりも、レビュー対象として認識している差分範囲がずれていました。
この経験から、PR差分レビューでは、単に現在のファイルを読むだけでは不十分だと分かりました。
次の情報を区別して確認する必要があります。
- 今回変更した行
- 以前から存在するコード
- stagedの変更
- unstagedの変更
- untrackedの新規ファイル
- 過去のIssueですでに追加された内容
差分を確認できない状態では、正しいコードレビューであっても、今回のPRに対するレビューにはならない可能性があります。
必要な読み取り系コマンドだけ許可する方針へ変えた
Bash全面禁止による差分確認の問題を受けて、運用方針を見直しました。
変更後は、すべてのBashを禁止するのではなく、レビューに必要な読み取り系コマンドだけを、人間の確認付きで許可します。
今回許可した主なコマンドは次のとおりです。
git status --short
git branch --show-current
git diff -- <指定されたファイル>
git diff --cached -- <指定されたファイル>
git diff HEAD -- <指定されたファイル>
git diff --check
一方で、次のようなGit変更操作は引き続き禁止します。
git branch --show-currentによる現在ブランチの確認は許可しますが、ブランチの作成・削除・名前変更を伴う操作は禁止します。
git switch
git checkout
git pull
git fetch
git branch <新しいブランチ名>
git branch -d <ブランチ名>
git branch -D <ブランチ名>
git branch -m <新しいブランチ名>
git add
git commit
git push
git merge
git rebase
git reset
git restore
git stash
git clean
git tag
この方針では、Bashが自動的に実行されるわけではありません。
Claude CodeがBashを使おうとすると確認画面が表示されるため、人間がコマンド内容を確認してから許可します。
判断基準は次のようにしました。
- 現在の状態や差分を読むだけなら許可する
- 指定した対象ファイルだけを確認するなら許可する
- ユーザーが明示した対象限定テストなら許可する
- ファイル作成・編集・削除を伴う場合は拒否する
- Gitの状態を変更する場合は拒否する
- 外部通信を伴う場合は拒否する
- 対象範囲が必要以上に広い場合は拒否する
また、レビュー用プロンプトの表現も変更しました。
変更前は次のように書いていました。
修正、ファイル編集、Git操作は行わないでください。
この表現では、読み取り系Git操作まで禁止するように受け取れます。
そこで、次のように変更しました。
修正、ファイル編集、Git変更操作は行わないでください。
レビュー範囲の確認に必要な読み取り系Gitコマンドだけを使用してください。
「Git操作」ではなく「Git変更操作」と書くことで、禁止対象を明確にしました。
さらに、同じ誤りが再びドキュメントへ戻らないように、退行防止テストも追加しました。
self.assertIn("Git変更操作は行わないでください", doc)
self.assertNotIn(
"修正、ファイル編集、Git操作は行わないでください",
doc,
)
これにより、レビュー用プロンプトが再びGit操作全面禁止の表現へ戻った場合は、テストで検出できます。
今回の経験から、安全性を高めるために操作をすべて禁止すると、レビュー精度まで下がる場合があると分かりました。
重要なのは、許可する操作と禁止する操作を具体的に分けることです。
- 必要な読み取り操作は、人間の確認付きで許可する
- 書き込み、Git変更、外部通信は拒否する
- 実行前に対象範囲と副作用を確認する
このバランスに変更したことで、Claude Codeが現在の差分を正確に確認しながら、安全にレビューできるようになりました。
レビュー中のPlanファイル書き込み要求を拒否した
今回のClaude Code設定では、既定の権限モードをPlan Modeにしています。
Plan Modeは、いきなり実装を始めず、最初に作業内容を整理させるために設定しました。
しかし、実際のPR差分レビューでは、Claude Codeが計画内容をチャットへ表示するのではなく、ローカル環境へPlanファイルを書き込もうとする場面がありました。
今回は読み取り専用のレビューを依頼しており、ファイルの作成は許可していません。
そのため、Bash確認画面に表示されたコマンドを確認し、実行を拒否しました。
>とヒアドキュメントを含むコマンドが表示された
レビュー中に、次のようなBashコマンドが確認画面へ表示されました。
cat > /home/<user>/.claude/plans/<plan-name>.md << 'EOF'
placeholder
EOF
ユーザー名やファイル名は、記事掲載用に置き換えています。
一見するとcatで内容を表示するだけのコマンドにも見えますが、実際にはファイルへ書き込む処理です。
このコマンドは、複数の要素で構成されています。
| 表記 | 動作 |
|---|---|
cat |
標準入力から受け取った内容を出力する |
> |
出力先のファイルを新規作成または上書きする |
<< 'EOF' |
EOFまでの複数行を標準入力として渡す |
~/.claude/plans/...md |
書き込み先となるPlanファイル |
<< 'EOF'は、複数行の文字列をコマンドへ渡すヒアドキュメントです。
その内容を>でファイルへリダイレクトしているため、全体としては次の処理になります。
-
EOFまでの内容をcatへ渡す -
catの出力をPlanファイルへ書き込む - ファイルが存在しなければ新規作成する
- ファイルが存在すれば内容を上書きする
つまり、これは読み取りや状態確認ではなく、ローカルファイルを作成するコマンドです。
読み取り専用レビューには不要な書き込みと判断した
今回Claude Codeへ依頼したのは、指定したPR差分のレビューです。
許可していた操作は、次の範囲に限定していました。
- 現在のブランチと変更状態の確認
- 指定したファイルの差分確認
- 指定した未追跡ファイルの読み取り
- ユーザーが明示した対象限定テスト
- レビュー結果のチャット出力
一方で、次の操作は許可していません。
- ソースコードやドキュメントの編集
- 新しいファイルの作成
- 既存ファイルへの追記や上書き
- Gitの状態を変更する操作
- 外部通信
Planファイルはプロジェクトのソースコードではありませんが、ローカル環境へ新しいファイルを書き込むことに変わりはありません。
また、今回のレビューを完了するために、計画をファイルとして保存する必要もありませんでした。
そのため、次の理由から実行を拒否しました。
-
>によるファイル書き込みが含まれている - レビューに必要な読み取り操作ではない
- ユーザーが許可した対象限定テストでもない
- チャット上だけで作業を完了できる
- 事前に決めた「ファイル編集・作成を行わせない」という方針に反する
Plan Modeを使用していても、確認画面へ表示されたコマンドが必ず読み取り専用になるとは限りません。
少なくとも今回の動作では、計画を保存するためのファイル書き込みが要求されました。
そのため、モード名だけで安全と判断せず、実際に表示されたBashコマンドを確認する必要があります。
計画ファイルを作らずチャットへ出力させた
Bash確認画面でコマンドを拒否した後、Claude Codeへ次のように指示しました。
このレビューでは計画ファイルを作成しないでください。
ファイルへの書き込みは行わず、読み取り系Gitコマンドと
指定済みの対象限定テストだけでレビューを続け、
結果はチャット上に直接出力してください。
この指示では、単にコマンドを拒否するだけでなく、次に取るべき行動も明示しています。
- Planファイルを作成しない
- ファイルへ書き込まない
- 読み取り系Gitコマンドだけを使用する
- 指定済みの対象限定テストだけを実行する
- レビュー結果はチャットへ直接出力する
その後はPlanファイルを作成せず、指定した差分の確認と対象限定テストを続け、レビュー結果をチャット上へ出力できました。
コマンドを拒否したからといって、レビュー自体を中止する必要はありません。
拒否した理由と、代わりにどの方法で続けるかを具体的に伝えることで、許可した範囲内で作業を継続できます。
今回の経験から、Bash確認画面ではコマンド名だけでなく、次の記号も確認するようになりました。
>
>>
<<
|
&&
;
特に>や>>が含まれている場合は、ファイルへの新規作成、上書き、追記が行われないかを確認します。
また、複数のコマンドが|、&&、;などで連結されている場合は、後半に書き込みや外部通信が含まれていないかも確認します。
今回のような読み取り専用レビューでは、計画を立てることと、計画ファイルを書き込むことは別の操作として判断する必要がありました。
計画内容はチャットへ直接出力できるため、不要なファイル作成を許可せずにレビューを完了させています。
Claude Codeから出た指摘を人間が確認する
Claude Codeのレビュー結果は、正しい修正指示としてそのまま採用するのではなく、判断材料の一つとして扱います。
今回のSkillでは、指摘を次の3段階で整理させました。
High
Medium
Low
ただし、Claude Codeが付けた優先度も確定ではありません。
本当に今回の差分に含まれる問題なのか、Issueの受け入れ条件に関係するのかを人間が確認し、採用・見送り・別Issue化を判断します。
High・Medium・Lowで整理する
レビュー結果では、指摘がない分類も省略せず、特になしと記載させます。
## 指摘事項
### High
特になし
### Medium
特になし
### Low
- 指摘内容
優先度は、次の基準で判断します。
| 優先度 | 主な対象 |
|---|---|
| High | 秘密情報の漏えい、禁止ファイルの参照、破壊的操作、データ損失、重大なセキュリティ問題 |
| Medium | 仕様との不整合、実装・テスト・ドキュメントの矛盾、運用上の誤解、必要なテストの不足 |
| Low | 表記ゆれ、軽微な保守性改善、将来的なリファクタリング、今回の受け入れ条件に直接影響しない提案 |
今回のアクセスログ解析ツールでは、特に次の問題を優先して確認します。
- 実ログや実IPが含まれていないか
-
config.ymlや.envなどの禁止対象を参照していないか - 外部通信が既定OFFのままか
- Git変更操作やファイル編集を行う内容が含まれていないか
- Skill、設定ファイル、運用ドキュメント、テストが矛盾していないか
- Claude Codeが今回の差分と過去の変更を混同していないか
High・Medium・Lowへ分けることで、すぐに対応すべき問題と、将来の改善候補を区別しやすくなりました。
採用した指摘を実際の差分へ反映する
Claude Codeから指摘が出た場合は、最初に本当に今回の差分に含まれているかを確認します。
今回採用したのは、対象限定テストに関する運用ドキュメントの矛盾です。
PR差分レビュー用Skillでは、次の条件で対象限定テストを実行できるようにしていました。
- ユーザーが正確なコマンドを明示している
- レビュー対象に関係するテストだけである
- 外部通信を行わない
- 実ログや禁止対象ファイルを参照しない
- Bash確認画面で人間がコマンドを確認する
一方、既存の運用ドキュメントには、次の趣旨の古い説明が残っていました。
Claude Codeにテスト実行を任せません。
このままでは、Skillでは対象限定テストを許可しているのに、運用ドキュメントではすべてのテストを禁止しているように読めます。
Claude Codeの指摘を受けて実際の差分と既存ドキュメントを確認したところ、運用上の矛盾になると判断しました。
そこで、次の方針が伝わる説明へ修正しました。
対象限定テストは、ユーザーが正確な実行コマンドを明示した場合だけ実行できます。
全テスト、coverage、lint、formatter、buildなどは、既定では実行しません。
修正後は、ドキュメントだけでなく、同じ表現へ戻らないように退行防止テストも追加しました。
self.assertIn(
"対象限定テスト",
review_doc,
)
指摘を採用する場合も、Claude Code自身には修正させません。
指摘内容を人間とChatGPTで確認し、実装担当側で修正した後、再度テストと差分確認を行いました。
今回は見送った指摘と理由
Claude Codeから出た指摘を、すべて同じIssueへ取り込む必要はありません。
今回見送ったのは、受け入れ条件に直接影響しないLow相当の改善案です。
たとえば、Skillのfrontmatterへallowed-toolsを追加し、特定のツールを確認画面なしで実行できるようにする方法があります。
しかし、allowed-toolsは使用できるツールを限定する設定ではありません。
指定したツールを事前承認し、Skillの実行中に確認なしで使用できるようにする設定です。指定していないツールについては、引き続き通常の権限設定が適用されます。
今回の運用では、読み取り系Gitコマンドであっても、人間が内容と対象範囲を確認してから許可したかったため、allowed-toolsは設定しませんでした。
---
name: pr-diff-review
description: 指定されたPR差分を安全にレビューする。
disable-model-invocation: true
---
現在の安全境界は、次の組み合わせで管理しています。
- リポジトリの
.claude/settings.json -
CLAUDE.mdの運用ルール -
AGENTS.mdの禁止事項 - Skill本文の許可・禁止ルール
- Bash確認画面での人間による承認
Skillへallowed-toolsを追加すると、設定内容によってはツールの利用範囲が分かりにくくなったり、既存の権限設定と責務が重複したりする可能性があります。
そのため、初版では追加せず、次の方針をSkillへ明記しました。
allowed-toolsは設定しません。
既存の権限設定と人間の承認を安全境界にします。
さらに、意図せずallowed-toolsが追加されないように、テストでも確認しています。
self.assertNotIn("allowed-tools", frontmatter)
改善案として成立していても、現在の設計方針と一致しない場合は採用しません。
必要性が出た場合は、今回のIssueへ追加するのではなく、別Issueとして権限設計から検討します。
また、次のようなLow指摘も、無理に今回のPRへ入れない方針にしました。
- 表記を少し整えるだけの変更
- 将来的なリファクタリング候補
- 現在の受け入れ条件に含まれない機能追加
- 既存の設定やテストですでに防止できている問題
- 修正によって今回の差分が必要以上に広がる提案
Lowだから無視するのではなく、必要であれば別Issue候補として残します。
指摘を鵜呑みにせず最終判断する
Claude Codeの指摘を確認するときは、次の順番で判断しました。
- 本当に今回の差分に含まれているか
-
git diffまたは指定ファイルのReadで根拠を確認できるか - 過去の変更を今回の差分と誤認していないか
- Issueの受け入れ条件に関係するか
- セキュリティや実運用へ影響するか
- 修正によって別の仕様を壊さないか
- 今回対応すべきか、別Issueへ分けるべきか
特に重要なのは、指摘された内容と実際の差分を照合することです。
Claude Codeが正しい一般論を述べていても、その問題が今回のPRに含まれていなければ、今回の修正対象ではありません。
反対に、小さな文言の指摘に見えても、運用ドキュメントとSkillの矛盾によって誤操作につながる場合は、Medium相当として対応する必要があります。
AIのレビュー結果は、次のように分けて扱いました。
| 判断 | 対応 |
|---|---|
| 今回の差分に含まれ、受け入れ条件に関係する | 今回のPRで修正する |
| セキュリティや運用へ重大な影響がある | 優先して確認・修正する |
| 正しい提案だが今回の範囲外 | 別Issue候補にする |
| 既存の設定やテストですでに対応済み | 見送る |
| 根拠となる差分が確認できない | 採用しない |
| 過去の変更を今回の差分と誤認している | 今回の指摘から除外する |
Claude Codeは、人間が気づかなかった矛盾を見つけることがあります。
一方で、プロジェクト固有の運用意図や、今回のIssueで変更する範囲まで完全に判断できるとは限りません。
そのため、Claude Codeを「修正内容を決める存在」ではなく、別の視点から問題候補を提示するレビュアーとして使っています。
最終的な採用判断、修正方針、Git操作、マージ判断は人間が行います。
安全な運用をドキュメントとテストに残す
Claude Codeの安全な運用ルールを、会話や個人の記憶だけに頼ると、時間が経ったときに判断基準が分からなくなる可能性があります。
また、Skillや権限設定を変更した際に、以前禁止していた操作が意図せず許可されることも考えられます。
そこで今回は、実際のレビューで確認した運用手順をドキュメントへ残し、重要な安全ルールをテストで固定しました。
対象とした主なファイルは次のとおりです。
.claude/settings.json
.claude/skills/pr-diff-review/SKILL.md
docs/CLAUDE_CODE_REVIEW.md
tests/test_claude_code_settings.py
tests/test_claude_code_review_skill.py
人間向けのレビュー手順をドキュメント化する
Claude Codeを安全に使うには、設定ファイルだけでなく、人間がどのように操作するかも決めておく必要があります。
そこで、PR差分レビューの運用手順を次のファイルへまとめました。
docs/CLAUDE_CODE_REVIEW.md
ドキュメントには、主に次の内容を記載しています。
- Claude CodeをPR差分レビュー専用で使用すること
-
/pr-diff-reviewの呼び出し方 - レビュー対象ファイルの指定方法
- 対象限定テストの指定方法
- 読み取り系Gitコマンドの扱い
- staged・unstaged・untrackedの確認方法
- ファイル編集やGit変更操作を許可しないこと
- 実ログや秘密情報を読ませないこと
- 外部通信を許可しないこと
- Planファイルの書き込み要求を拒否すること
- レビュー結果をHigh・Medium・Lowで確認すること
- 最終的な採用判断は人間が行うこと
実際に使用するプロンプト例も、ドキュメントへ残しました。
/pr-diff-review .claude/skills/pr-diff-review/SKILL.md docs/CLAUDE_CODE_REVIEW.md tests/test_claude_code_review_skill.py
実行を許可する対象限定テスト:
PYTHONPATH=src .venv/bin/python -m pytest tests/test_claude_code_review_skill.py -q
Bash確認画面でPlanファイルの書き込み要求が表示された場合の対応も記載しています。
このレビューでは計画ファイルを作成しないでください。
ファイルへの書き込みは行わず、読み取り系Gitコマンドと
指定済みの対象限定テストだけでレビューを続け、
結果はチャット上に直接出力してください。
このように、正常な操作だけでなく、想定外の動作が起きた場合の対応もドキュメント化しました。
なお、最初のドキュメントには次の趣旨の説明が残っていました。
Claude Codeにテスト実行を任せません。
しかし、現在の運用では、ユーザーが正確なコマンドを指定した対象限定テストだけは実行できます。
そのため、次の方針が分かる表現へ修正しました。
対象限定テストは、ユーザーが正確なコマンドを明示した場合だけ実行できます。
全テスト、coverage、lint、formatter、buildなどは、既定では実行しません。
運用中に分かった問題をその都度ドキュメントへ反映することで、Skill、権限設定、人間の操作手順を一致させています。
Skillの安全ルールを退行防止テストで固定する
PR差分レビュー用Skillには、許可する操作と禁止する操作を文章で記載しています。
ただし、文章だけでは、将来の修正時に重要な禁止事項が削除されても気づけない可能性があります。
そこで、次のテストファイルを追加しました。
tests/test_claude_code_review_skill.py
テストでは、Skillのfrontmatterと本文を読み取り、重要な設定やルールが残っていることを確認します。
たとえば、Skillがユーザーから明示的に呼び出された場合だけ動作することを確認します。
self.assertIn(
"disable-model-invocation: true",
frontmatter,
)
allowed-toolsを意図的に設定していないことも確認します。
self.assertNotIn(
"allowed-tools",
frontmatter,
)
レビュー対象を引数で受け取ることも固定します。
self.assertIn(
"$ARGUMENTS",
skill_body,
)
Git変更操作が禁止されていることも確認します。
self.assertIn(
"Git変更操作",
skill_body,
)
対象限定テストについては、ユーザーが正確なコマンドを指定した場合だけ実行できることを確認します。
self.assertIn(
"対象限定テスト",
skill_body,
)
外部通信やファイル編集の禁止事項についても、必要な記述が存在することをテストします。
self.assertIn("外部通信", skill_body)
self.assertIn("Edit", skill_body)
self.assertIn("Write", skill_body)
self.assertIn("NotebookEdit", skill_body)
また、以前使用していた曖昧な禁止表現へ戻らないことも確認します。
self.assertNotIn(
"修正、ファイル編集、Git操作は行わないでください",
review_doc,
)
代わりに、読み取り系Gitと変更系Gitを区別した表現が存在することを確認します。
self.assertIn(
"Git変更操作は行わないでください",
review_doc,
)
このようなテストを追加することで、Skillやドキュメントを変更したときに、次のような退行を検出できます。
-
disable-model-invocationが削除された - 意図せず
allowed-toolsが追加された -
$ARGUMENTSによる対象指定が削除された - Git変更操作の禁止が消えた
- 対象限定テストの条件が曖昧になった
- 外部通信やファイル編集の禁止が削除された
- Git操作を全面禁止する古い表現へ戻った
SkillはMarkdownファイルですが、実際にはClaude Codeの動作を制御する重要な設定です。
そのため、通常のソースコードと同じように、変更によって安全ルールが壊れていないかをテストしています。
Claude Code設定もコードと同じように検証する
Claude Codeの設定ファイルやSkillは、アプリケーションの実行コードではありません。
しかし、許可する操作や禁止する操作を決めるため、変更内容によってはプロジェクトの安全性へ直接影響します。
そのため、次のファイルも通常のコードと同じように差分確認とテストの対象にしました。
.claude/settings.json
CLAUDE.md
.claude/skills/pr-diff-review/SKILL.md
docs/CLAUDE_CODE_REVIEW.md
.claude/settings.jsonについては、次のテストで設定内容を確認しています。
tests/test_claude_code_settings.py
主に確認しているのは、次の項目です。
- 既定の権限モードがPlan Modeであること
- Edit、Write、NotebookEditが禁止されていること
- Git変更系コマンドが禁止されていること
- 外部通信を伴うコマンドが禁止されていること
- 実ログや秘密情報の読み取りが禁止されていること
- Skill内のシェル実行が無効であること
- 不要な広い許可設定が追加されていないこと
Skill用の対象限定テストは、次のコマンドで実行しました。
PYTHONPATH=src .venv/bin/python -m pytest tests/test_claude_code_review_skill.py -q
実行結果は次のとおりです。
7 passed
設定ファイルのテストも含めて全体を確認する場合は、通常のテストスイートを実行します。
PYTHONPATH=src .venv/bin/python -m pytest -q
今回の最終確認では、すべてのテストが成功しました。
341 passed, 784 subtests passed
coverageも確認し、次の結果になりました。
94%
さらに、不要な空白や競合マーカーなどが残っていないかを確認します。
git diff --check
Claude Codeの設定変更でも、通常の機能開発と同じように次の流れで確認しました。
- Issueで目的と受け入れ条件を決める
- 設定、Skill、ドキュメントを変更する
- 対応する退行防止テストを追加する
- 対象限定テストを実行する
- 全テストへの影響を確認する
-
git diff --checkで差分を確認する - Claude CodeでPR差分レビューを行う
- 指摘を人間が確認する
- 最終的なGit操作とマージ判断を人間が行う
設定ファイルだからといって、動作確認せずに変更すると、禁止していた操作が意図せず許可される可能性があります。
反対に、禁止を強くしすぎると、今回のgit diffのように、レビューに必要な読み取り操作まで使えなくなります。
そのため、安全設定についても、目的、実際の動作、ドキュメント、テストの4つを一致させることが重要だと感じました。
Claude Codeの運用ルールをコードと同じようにGitで管理し、テストで検証することで、安全性を個人の注意力だけに依存しない構成にしています。
実際に運用して感じたこと
Claude CodeをPR差分レビュー専用として実際に運用してみると、単に権限を厳しくすれば安全になるわけではないと分かりました。
最初はBashを全面禁止していましたが、それではgit statusやgit diffも実行できず、現在の変更範囲を正確に確認できませんでした。
安全性を高めるための制限によって、レビュー精度を下げてしまう状態です。
そのため、現在は次のように役割を明確に分けています。
- 読み取り系Gitコマンドは、人間が内容を確認して許可する
- ファイルの作成・編集・削除は許可しない
- Git変更操作は許可しない
- 外部通信は許可しない
- テストは、ユーザーが正確なコマンドを指定した場合だけ許可する
- Claude Codeの指摘を採用するかは人間が判断する
この形に変更したことで、必要な差分確認は行いつつ、Claude Codeが勝手にファイルを変更することは防げるようになりました。
一方で、確認画面に表示されたコマンドを判断するには、利用する側にも最低限のLinuxコマンドとGitの知識が必要です。
たとえば、次のような記号の意味を知らなければ、読み取りコマンドだと思ってファイル書き込みを許可してしまう可能性があります。
>
>>
<<
|
&&
;
今回表示されたPlanファイル作成コマンドも、catというコマンド名だけを見ると、ファイルを読む処理のように見えました。
しかし、実際には>とヒアドキュメントを組み合わせた書き込み処理でした。
Claude Codeの確認画面が表示されるだけで安全になるのではなく、表示された内容を人間が理解して判断することが重要です。
また、Claude Codeを実装担当とは別のレビュアーとして使うことで、既存ドキュメントと新しいSkillの矛盾を見つけることができました。
実装時には問題ないと思っていた内容でも、別のAIモデルから確認させると、異なる視点の指摘が出ることがあります。
ただし、指摘が出たからといって、すべてを修正する必要はありません。
今回も、実際の差分に関係する指摘は採用しましたが、現在の設計方針と合わない提案や、受け入れ条件の範囲外となる改善案は見送りました。
AIによるレビューでは、指摘の正しさだけでなく、次の点も確認する必要があります。
- 本当に今回の差分に含まれる問題か
- 過去の変更を今回の差分と誤認していないか
- Issueの受け入れ条件に関係するか
- 現在の設計方針と一致するか
- 今回修正すべきか、別Issueへ分けるべきか
また、運用ルールをドキュメントとテストへ残したことも有効でした。
会話の中だけで「この操作は禁止する」と決めても、時間が経てば判断基準が分からなくなる可能性があります。
重要な設定や禁止事項をテストで固定することで、将来Skillや設定を変更した際に、安全ルールの退行を検出できます。
今回の運用では、次の役割分担が自分には合っていると感じました。
| 担当 | 役割 |
|---|---|
| Codex | 実装、テスト追加、ドキュメント修正 |
| Claude Code | 指定したPR差分のレビュー |
| ChatGPT | Issue設計、作業手順、指摘内容の整理 |
| 人間 | Bash承認、Git操作、修正判断、マージ判断 |
1つのAIに実装からレビュー、修正、Git操作まで任せるのではなく、それぞれの役割を分けることで、確認する機会を増やせます。
Claude Codeは、すべてを自動で任せるツールとしてではなく、変更内容を別の視点から確認するレビュアーとして使うと、自分の開発フローへ取り入れやすいと感じました。
今後も、権限を必要以上に広げるのではなく、実際の運用で必要になった操作だけを確認しながら追加していく方針です。
まとめ
今回は、Claude Codeを実装担当としてではなく、PR差分レビュー専用のレビュアーとして運用しました。
最初は安全性を優先してBashを全面禁止していましたが、その状態ではgit statusやgit diffも使えず、現在の変更範囲を正確に確認できませんでした。
そこで、すべてのBashを禁止するのではなく、次のように許可する操作と禁止する操作を分けました。
- 読み取り系Gitコマンドは、人間が内容を確認して許可する
- レビュー対象はファイル単位で明示する
- staged・unstaged・untrackedを区別して確認する
- テストは、ユーザーが正確なコマンドを指定した場合だけ許可する
- ファイルの作成・編集・削除は許可しない
- Git変更操作は許可しない
- 外部通信は許可しない
- 実ログや秘密情報は読ませない
また、毎回同じ長いレビュー指示を書かなくても済むように、次のSkillを作成しました。
.claude/skills/pr-diff-review/SKILL.md
Skillでは、$ARGUMENTSからレビュー対象を受け取り、High・Medium・Lowの形式で結果を出力させます。
自動起動はさせず、ユーザーが次のように明示的に呼び出した場合だけ使用する構成にしました。
/pr-diff-review <レビュー対象ファイル>
実際のレビューでは、Planファイルの書き込み要求が表示されましたが、読み取り専用レビューには不要と判断して拒否しました。
その後、計画ファイルを作成せず、レビュー結果をチャットへ直接出力するように指示することで、許可した範囲内でレビューを継続できました。
Claude Codeから出た指摘についても、すべてをそのまま採用したわけではありません。
次の点を実際の差分と照らし合わせて確認しました。
- 今回の差分に含まれる問題か
- 過去の変更を誤認していないか
- Issueの受け入れ条件に関係するか
- 現在の設計方針と一致するか
- 今回修正すべきか、別Issueへ分けるべきか
実際の差分に関係するドキュメントの矛盾は修正しましたが、現在の設計方針と合わない提案や、今回の受け入れ条件に含まれない改善案は見送りました。
さらに、今回決めた運用ルールを会話だけで終わらせず、ドキュメントと退行防止テストへ残しました。
docs/CLAUDE_CODE_REVIEW.md
tests/test_claude_code_settings.py
tests/test_claude_code_review_skill.py
Claude Codeの設定やSkillも、通常のコードと同じようにGitで管理し、変更によって安全ルールが崩れていないかをテストしています。
今回の運用で重要だと感じたのは、権限を単純に広く許可したり、すべて禁止したりするのではなく、目的に必要な操作だけを具体的に分けることです。
また、確認画面が表示されるだけで安全になるわけではありません。
表示されたコマンドが読み取りなのか、書き込みなのか、外部通信を伴うのかを、人間が理解して判断する必要があります。
現在は、Codexを実装担当、Claude Codeをレビュー担当、ChatGPTを設計・整理担当とし、Bash承認、Git操作、修正判断、マージ判断は人間が行う役割分担にしています。
Claude Codeは、すべての作業を自動で任せるためのツールではなく、変更内容を別の視点から確認するレビュアーとして使うことで、安全性とレビュー精度のバランスを取りやすくなりました。
今後も、最初から権限を広げるのではなく、実際の運用で必要になった操作だけを、人間が確認しながら追加していく方針です。
関連記事
今回の記事とあわせて、WSL Ubuntu環境の準備やLinuxコマンドの基礎、AIコードレビュー運用に関係する記事もまとめておきます。