全体像:4つの仕組み
| 仕組み | 役割 | 読み込まれるタイミング | 向いている内容 |
|---|---|---|---|
| CLAUDE.md | 常時読み込む指示書 | 毎セッション開始時、常にコンテキストに載る | プロジェクト全体の規約、「常にXする」ルール |
| .claude/rules/ | CLAUDE.mdの分割版 | 全ファイル対象、またはpaths指定でファイル種別ごと |
CLAUDE.mdが肥大化した時の分割先。「PHPファイルの時だけ」等 |
| Skills | オンデマンドで読み込む知識/手順 |
/コマンドで呼ぶか、Claudeが必要と判断した時 |
時々必要な詳細、多ステップの手順(PR前チェックなど) |
| Hooks | ライフサイクルイベントで発火するスクリプト | ツール実行前後・セッション開始/終了など特定タイミング | 「必ず・機械的に」やること(lint/format自動実行など) |
決定的な違い:CLAUDE.md/rules/skillsはClaudeに「お願いする」もの(指示であって強制ではない)。hooksはClaude Codeが機械的に必ず実行するもの。
判断基準:どこに書くか
| 判断できるか | 例 | 置き場所 |
|---|---|---|
| スクリプトが機械的にpass/fail判定できる | インデント幅、クォート統一、import順序 | リンタ/フォーマッタの設定ファイル + フック |
| 文章で説明しないと伝わらない・文脈判断が要る | 命名規則、「この処理はバルクインサートすべきか」等のプロジェクト固有の判断 | CLAUDE.md(増えたら.claude/rules/) |
| 時々必要な多ステップの手順 | PR前チェック、デプロイ手順 | Skill |
フォーマット・リント関連
-
既存のリンタ/フォーマッタ(Laravel Pint、ESLintなど)がある場合:ルールの実体はツールの設定ファイル(
pint.json、.eslintrc)に書く。フックは「編集後にそのツールを自動実行する」トリガーだけを書く// .claude/settings.json { "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "./vendor/bin/pint" }] } ] } } -
ツールがまだない場合:導入コストは低い(
composer require laravel/pint --dev、npm install --save-dev eslint prettier)ので、CLAUDE.mdに書くより先にツール導入を検討する。CLAUDE.mdに書くのはあくまで次善策 -
ツールを導入済みだが使っていない:
composer.json/package.jsonのrequire-dev/devDependenciesを確認し、既存ツールがあればそれをフックに配線するのが最優先。CLAUDE.mdからフォーマット関連の記述は不要になる
CLAUDE.mdに書く内容の質
-
「Laravelの規約に従いましょう」のような一般論は書いても意味が薄い(Claudeは標準規約を元々知っている)
-
書くなら具体的に:「Eloquentのリレーションは
xxx()メソッドで定義する」など -
プロジェクト固有の判断・過去の失敗由来のルールは理由付きで書く
# DBパフォーマンス - 大量データの一括登録は chunk() ではなく insert() の配列一括投入(バルクインサート)を使う 理由: chunk()はクエリ回数が増えて遅い。1万件超のシーダー/バッチ処理で特に注意
コーディングの基本方針
1. 書く前に考える
- 曖昧な要求を勝手に一つの解釈で進めない。仮定した内容は明示する。
- 複数の解釈がありうる場合は、それを提示してどちらか確認する。
- 不明な点があれば、憶測で進めずに質問する。
2. シンプルさを優先する
- 頼まれていない機能・抽象化・設定を追加しない。
- 1回しか使わないコードを無理に汎用化しない。
- 滅多に起きないケースへの過剰な防御的コードを書かない。
- 50行で済むところを200行にしない。
3. 頼まれた範囲を守る(スコープを守る)
- 依頼に直接関係するファイルだけを触る。
- ついでに関係ないコードをリファクタリングしない。
4. 明示的に検証する
-
「動くはず」で終わらせず、実際に動かして確認してから完了とする。
-
何をどう確認したかを報告する。
-
目安200行以内。増えたら
.claude/rules/にpaths指定で分割(例:paths: ["app/**/*.php"])
PR前チェック:Skillとして設計
副作用のあるワークフローなので disable-model-invocation: true を付けて /pre-pr-check のように明示的に呼ぶ形にする。
.claude/skills/pre-pr-check/SKILL.md
---
name: pre-pr-check
description: PR作成前の自己チェック
disable-model-invocation: true
---
以下を順に実行し、結果をまとめて報告する:
1. git diff main...HEAD で変更点を確認
2. php artisan test を実行し、失敗があれば報告
3. ./vendor/bin/pint --test でフォーマッタ差分を確認(自動整形はフックに任せる)
4. CLAUDE.mdの規約と照らして逸脱がないか確認
5. 新しいsubagentにdiffだけを渡してレビューさせ、指摘をまとめる
-
標準の
/code-review(bundled skill)を先に試す選択肢もある。diffを新しいsubagentコンテキストでレビューしてくれる - レビュー部分を新しいsubagentに投げる理由:実装した本人のセッションのままだと自分の思い込みを引きずって見落としがちなため(adversarial review パターン)
- 機械的な部分(テスト/lint実行)と判断が要る部分(規約準拠・設計妥当性)を分けて設計する
- 「絶対に忘れずに実行させたい」場合は、後から
git push前のPreToolUseフックでこのskillの実行有無をチェックする形に強化できる(まずはskillで手動運用してみてから検討)
まとめ表
| 内容 | 置き場所 |
|---|---|
| インデント幅・クォート統一などフォーマット | ツール設定ファイル + フック |
| 命名規則・アーキテクチャ判断・プロジェクト固有の注意点 | CLAUDE.md(増えたら.claude/rules/) |
| PR前の一連の確認手順(テスト実行→フォーマッタ確認→レビュー依頼) | PR前チェックskill |