Claude Codeハーネスエンジニアリング実践──PR作成からマージまでを4層防衛で自動化する

Claude Codeハーネスエンジニアリング実践──PR作成からマージまでを4層防衛で自動化する AI開発

Claude Codeに実装を任せ始めると、次のような悩みが出てきます。「Claudeが書いたコードがlintを通っていない」「PRコメントへの返信が”後で対応します”ばかり」「レビュー通過後にマージし忘れる」。これらは個々のプロンプトを工夫しても解決しません。仕組みとして品質を担保する設計が必要です。

この考え方をハーネスエンジニアリングと呼びます。プロンプトで出力品質を上げる「狩り」から、仕組みで品質を担保する「稲作」へ、という転換です。本記事では、PR作成からマージまでの開発フローを4層防衛で自動化する実践的な設計をまとめます。

各コンポーネントの基礎は関連記事で確認できます。Claude Code Hooks完全ガイドSkills・コマンドガイドGitHub Actions自動化ガイドClaude Code レビューループ設計も参照してください。

スポンサーリンク

4層防衛モデルの全体像

品質担保の仕組みを速度と網羅性で4層に分けます。ローカルで速く動く検証と、リモートで網羅的に動く検証を組み合わせるのが設計の要点です。

タイミング 主体 役割 ツール例
第1層 Claude Code操作前後 Claude Code hooks AIの行動をリアルタイム制御 pre-bash-guard, post-edit-lint
第2層 git操作時 Lefthook コミット・プッシュ前ゲート Clippy, ast-grep, Biome
第3層 任意タイミング Claude Code skills 複雑な検証をコマンドで実行 /pre-push-review
第4層 push後 GitHub Actions + CodeRabbit 最終防衛・網羅的チェック CodeRabbit, jscpd

重要なのは「速いローカル検証と網羅的なリモート検証を分離する」という思想です。すべてをCIに任せると待ち時間が長く、Claudeのフィードバックループが遅くなります。逆にローカルだけでは見落としが生じます。両者を組み合わせることで、速さと確実性を両立します。

第1層:Claude Code Hooksによるリアルタイム制御

Claude Code hooksは、AIがツールを実行する直前(PreToolUse)・直後(PostToolUse)に任意のシェルコマンドを差し込める仕組みです。ここに「守らせたいルール」を実装することで、Claudeが破れない制約を作ります。

.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/pre-bash-guard.sh"
          }
        ]
      },
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/pre-edit-guard.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/post-edit-lint.sh"
          }
        ]
      },
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/post-push-monitor.sh"
          }
        ]
      }
    ]
  }
}

pre-bash-guard:AI先送り返信を防ぐ

ハーネスエンジニアリングで最も重要なhookの一つがpre-bash-guardです。Claudeはレビューコメントへの返信で「後で対応します」「次のPRで修正します」といった先送り返信を書きがちです。これをBashコマンド実行前に検出してブロックします。

.claude/hooks/pre-bash-guard.sh
#!/bin/bash
# Bashコマンドに渡す内容を標準入力から受け取る
INPUT=$(cat)

# 先送り表現の検出
if echo "$INPUT" | grep -qE "後で対応|次回対応|別のPRで|追って修正|TODO.*後で"; then
  echo "先送り返信を検出しました。以下の2択で対応してください:" >&2
  echo "  1. その場で修正してからコメントに返信する" >&2
  echo "  2. GitHub Issueを作成し、Issue番号を添えて返信する" >&2
  exit 2  # exit 2 でClaudeへのフィードバックとして返す
fi

# 危険なコマンドのブロック
if echo "$INPUT" | grep -qE "git push --force|--no-verify|rm -rf /"; then
  echo "危険なコマンドが検出されました。実行を中止します。" >&2
  exit 2
fi

# PRゲート(pre-push-reviewを通していなければgh pr createをブロック)
if echo "$INPUT" | grep -q "gh pr create"; then
  if [ ! -f ".claude/tmp/.review-passed" ]; then
    echo "/pre-push-review を先に実行してください。" >&2
    echo "レビューを通過するまでgh pr createはブロックされます。" >&2
    exit 2
  fi
fi

pre-edit-guard:設定ファイルの意図しない変更を防ぐ

Claudeが「効率化」のつもりで.claude/settings.jsonlefthook.ymlを書き換えてしまうことがあります。pre-edit-guardでこれを防ぎます。

.claude/hooks/pre-edit-guard.sh
#!/bin/bash
FILE=$(echo "$CLAUDE_TOOL_INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))")

# 保護対象ファイル
PROTECTED=(".claude/settings.json" "lefthook.yml" ".github/workflows")

for p in "${PROTECTED[@]}"; do
  if [[ "$FILE" == *"$p"* ]]; then
    echo "保護対象ファイル ($p) の編集は禁止されています。" >&2
    echo "変更が必要な場合は人間に確認してください。" >&2
    exit 2
  fi
done

post-edit-lint:編集後に即時フィードバック

ファイル編集の直後にlint/formatを走らせ、問題をすぐにClaudeへ返します。CIを待たずにフィードバックループを高速化できます。

.claude/hooks/post-edit-lint.sh
#!/bin/bash
FILE=$(echo "$CLAUDE_TOOL_INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))")

case "$FILE" in
  *.ts|*.tsx)  npx biome check --apply "$FILE" 2>&1 ;;
  *.rs)        cargo clippy -- -D warnings 2>&1 ;;
  *.py)        ruff check "$FILE" 2>&1 ;;
esac

第2層:Lefthookによるgit前ゲート

Lefthookはgit hooksをYAMLで管理するツールです。コミット・プッシュ前に複数のチェックを並列実行できるのが特徴で、AIも人間も同じ制約を受けるゲートとして機能します。

lefthook.yml
pre-commit:
  parallel: true
  commands:
    fmt:
      run: cargo fmt --check
      fail_text: "フォーマットが崩れています。cargo fmt を実行してください。"
    clippy:
      run: cargo clippy -- -D warnings -D clippy::pedantic
      fail_text: "Clippyエラーがあります。"
    biome:
      run: npx biome check .
      fail_text: "Biomeのチェックが失敗しました。"
    ast-grep:
      run: sg scan --config .ast-grep/rules/
      fail_text: "アーキテクチャ制約違反があります。"

pre-push:
  commands:
    test:
      run: cargo test --workspace

ast-grepでアーキテクチャ制約を強制する

ast-grepはASTベースの構造検索ツールで、「domainレイヤーからinfrastructureをimportしてはいけない」といったアーキテクチャ制約をコードとして定義できます。lintルールでは検出できない設計違反を機械的に止められます。

.ast-grep/rules/no-infra-in-domain.yml
id: no-infra-in-domain
language: rust
rule:
  kind: use_declaration
  regex: "infrastructure"
files:
  - "src/domain/**/*.rs"
severity: error
message: |
  domainレイヤーからinfrastructureをimportしてはいけません。
  WHY: DDDのレイヤー依存ルール違反。domainは外部依存を持たない。
  FIX: domainにトレイトを定義し、infrastructureで実装してください。

第3層:/pre-push-reviewスキルによるPR前レビュー

第3層は/pre-push-reviewカスタムスラッシュコマンドです。PR作成前に4つのレビューを並列実行し、重大な問題は自動修正、それ以外は人間に確認を求めます。このスキルを通過するまでgh pr createはpre-bash-guardにブロックされます。

.claude/skills/pre-push-review.md
---
name: pre-push-review
description: PR作成前の並列レビュー(セキュリティ・品質・複雑度)
---

以下の4つのレビューを並列で実行してください。

## 実行内容

1. **code-simplifier**(サブエージェント)
   - 過剰な抽象化・重複コード・テストされていないコードを検出
   - 自動で単純化できるものは修正する

2. **security-auditor**(サブエージェント)
   - 認証漏れ・OWASP Top 10・入力バリデーション不備を確認
   - HIGH以上の問題は即時修正

3. **coderabbit-cli**(スキル実行)
   - PR作成前にCodeRabbit CLIでレビューを実行
   - 重大な指摘は修正してから次へ進む

4. **security-review**(スキル実行)
   - HIGH CONFIDENCE と判定された脆弱性のみ抽出

## 完了後

すべてのチェックが通過したら `.claude/tmp/.review-passed` を作成してください。
gh pr create が解除されます。

ポイント:このフラグファイル方式(.review-passed)がハーネスとして機能します。pre-bash-guardがフラグの存在を確認するため、レビューをスキップしてPRを作ることをAIも人間もできなくなります。フラグはpost-push-monitorがプッシュ後に自動で削除します。

第4層:GitHub Actions + CodeRabbitによる最終防衛

ローカルの3層を通過したコードが最終的にGitHub Actionsで検証されます。ここでは時間のかかる包括的なテスト・CodeRabbitによる自動コードレビューを行います。

.github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: cargo test --workspace
      - name: Check duplicate code
        run: npx jscpd --min-lines 10 --reporters json
      - name: CodeRabbit review
        uses: coderabbitai/ai-pr-reviewer@latest
        with:
          openai_light_model: gpt-4o-mini

post-push-monitor:push後の自動監視

pushが成功した後、post-push-monitor hookが起動します。CronCreateツールを使って1分間隔のポーリングを設定し、CodeRabbitのレビュー完了を待ちます。完了したらレビュー内容を取得し、Claudeに自動で対応を開始させます。

post-push-monitorの流れ(プロンプト例)
# post-push-monitor hook が起動すると以下を実行

1. gh pr view --json number で最新PRを取得
2. CronCreate で1分間隔の監視を設定:
   "/check-ci-coderabbit PR番号を確認し、CodeRabbitのレビューが
    完了していれば指摘内容を取得して対応を開始してください"
3. CodeRabbitのレビューコメントを取得
4. 指摘への返信前に pre-bash-guard が先送り表現を検出・ブロック
5. その場で修正 or Issue作成してから返信
6. 全コメントに返信完了 → /merge-and-cleanup を実行

Rules と Hooks の役割分担

CLAUDE.mdやrulesファイルとhooksの使い分けは、「破ろうと思えば破れるか」で判断します。

仕組み 強制力 使うべき場面
CLAUDE.md なし(ガイドライン) コンテキスト・背景の説明 プロジェクトの目的・設計思想
rules 弱い(読まれれば従う) ファイルパス別のガイドライン 「domainにはインフラを書かない」
hooks 強い(物理的にブロック) 絶対に守らせたいこと 先送り返信・危険コマンドの禁止
Lefthook 強い(commit/pushできない) コード品質の最低基準 lint・formatエラーがあればコミット不可

よくある失敗:「絶対に守ってほしいこと」をrules(Markdownファイル)に書いても、Claudeがそのファイルを読まなければ守られません。本当に強制したいことはhooksかLefthookに昇格させてください。rulesはあくまで「破ろうと思えば破れる」ガイドラインです。

自動化できること vs 人間が判断すべきこと

ハーネスエンジニアリングは人間を排除するものではありません。AIに任せる部分と、人間が価値を出す判断を明確に分けることが目的です。

自動化できること 人間が判断すること
編集時のlint/format実行 設計・実装方針の承認
コミット時の品質チェック レビュー指摘を直すかどうか
PR作成前のセキュリティ・品質レビュー 未解決コメントを解決済みにしてよいか
push後のCI/CodeRabbit監視 アーキテクチャに関わる変更の判断
レビューコメントへの返信・修正 ビジネスロジックの優先度判断
マージ・チケットクローズ・ブランチ削除 リリースタイミングの決定

よくある質問

Qハーネスエンジニアリングはどんなチームに向いていますか?
AClaude Codeで日常的にコードを書いていて、「AIが生成したコードの品質管理に手間がかかっている」「レビューループが遅い」と感じているチームに向いています。個人開発でも、品質の自動担保という意味で導入価値があります。
QLefthookは必須ですか?Huskyではダメですか?
AHuskyでも同じコンセプトは実現できます。Lefthookは並列実行・設定のシンプルさ・速度で優れているため記事内では採用されていますが、チームが使い慣れたgit hooksツールで代替可能です。
QCodeRabbitがなくても4層防衛は成立しますか?
A第4層をGitHub Actionsのみ(テスト・lintのみ)で構成することも可能です。CodeRabbitの代わりにPR Agentや人間によるレビューで代替できます。第1〜3層だけでも品質は大きく改善します。
Qpre-bash-guardで正規表現の誤検知が怖いです。
A「後で対応」を文字列マッチしているだけなので、コード内のコメント文字列にこのフレーズが含まれると誤検知します。パターンをより厳密にする(コンテキストを見る)か、対象をgit commitやgh prへの入力に絞るのが現実的な調整です。
Qhooks設定を変更するにはどうすればよいですか?
Apre-edit-guardで保護しているため、Claude Codeからは直接変更できません。人間がエディタで直接編集してください。これは意図的な設計です。hooksの設定変更はAIに委ねるべきではありません。

まとめ

ハーネスエンジニアリングの核心は、「プロンプトで頑張る(狩り)から、仕組みで品質を担保する(稲作)へ」という転換です。

  • 第1層(hooks):AIの行動をリアルタイムで制御。先送り返信・危険コマンド・PRゲートを実装
  • 第2層(Lefthook):git前ゲートで全員が同じ制約を受ける
  • 第3層(skills):/pre-push-reviewで並列レビュー。通過しないとPR作成不可
  • 第4層(GitHub Actions/CodeRabbit):最終防衛で網羅的なチェック

人間が本当に価値を出す「設計承認・レビュー判断・リリース決定」に集中できる環境を、仕組みとして作るのがゴールです。

関連記事:Claude Code Hooks完全ガイド / Skills・コマンドガイド / レビューループ設計 / GitHub Actions自動化ガイド