CLAUDE LABEN
TEACHERS — AnthropicがClaude for Teachersを公開。米国K-12の認証済み教員に、プレミアム機能と授業向けスキル、全50州の学習指導基準に沿ったカリキュラム連携を無償提供しますADMIN — Claude Enterprise全組織でAdmin APIがベータ提供に。メンバーと招待の操作はベータヘッダー不要、グループとカスタムロールは専用ヘッダーが必要ですM365 — Microsoft 365コネクタに書き込みツールが追加。メールの下書き・送信・整理、カレンダー操作、OneDriveとSharePointのファイル作成・更新まで任せられますMCP — --mcp-configや.mcp.jsonのサーバ単位request_timeout_msが無視され、新規セッションで60秒既定のままタイムアウトする不具合が修正されましたSUBAGENT — --forward-subagent-textとCLAUDE_CODE_FORWARD_SUBAGENT_TEXTが追加。サブエージェントのテキストと思考をstream-json出力に含められますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。残り7日、speed: "fast" はエラーになるためOpus 4.8への移行をご確認くださいTEACHERS — AnthropicがClaude for Teachersを公開。米国K-12の認証済み教員に、プレミアム機能と授業向けスキル、全50州の学習指導基準に沿ったカリキュラム連携を無償提供しますADMIN — Claude Enterprise全組織でAdmin APIがベータ提供に。メンバーと招待の操作はベータヘッダー不要、グループとカスタムロールは専用ヘッダーが必要ですM365 — Microsoft 365コネクタに書き込みツールが追加。メールの下書き・送信・整理、カレンダー操作、OneDriveとSharePointのファイル作成・更新まで任せられますMCP — --mcp-configや.mcp.jsonのサーバ単位request_timeout_msが無視され、新規セッションで60秒既定のままタイムアウトする不具合が修正されましたSUBAGENT — --forward-subagent-textとCLAUDE_CODE_FORWARD_SUBAGENT_TEXTが追加。サブエージェントのテキストと思考をstream-json出力に含められますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。残り7日、speed: "fast" はエラーになるためOpus 4.8への移行をご確認ください
記事一覧/Claude Code
Claude Code/2026-05-01上級

リリースゲートを Claude Code に任せる — 「通った理由」が読めるデプロイ前検証の組み立て方

CI が緑でもリリース直前に事故は起きます。Claude Code に「通った理由・止めた理由」を文章で書かせる、運用に耐える 7 項目のリリースゲートを実装の細部まで紹介します。

claude-code129ci-cd8releasedeployment4code-review5

ある金曜日の夕方、私のチームでは「明日の朝には本番に出します」と Slack に書き込んだ直後に、誰も触っていないはずのテストが突然落ち始めました。原因をたどると、二週間前にマージされた他人の PR と、その日の昼にマージした自分の小さな変更が、依存ライブラリのバージョン更新でたまたま噛み合って壊れていたのでした。CI は緑だったのに、なぜこうなるのでしょうか。

「リリース前のチェックは CI が通ればよい」と長らく考えていました。けれど開発スピードが上がり、Claude Code に小さな改善 PR を量産させるようになってから、CI の通過は「壊れていない」の証明としては不十分だと感じるようになりました。テストカバレッジに穴があるところは静かにすり抜けますし、設定ファイルの更新忘れや環境変数の取り違えはユニットテストでは捕まりません。

そこで試行錯誤して整えたのが、本番デプロイの直前に Claude Code に通させる「リリースゲート」です。普通のチェックリストとの違いは、合否だけでなく 「なぜ通したのか/止めたのか」を人間が読める形で出力させる ところにあります。ここではその思想・実装・運用上の落とし穴までを、私が実際に踏んだ失敗と一緒に共有します。

なぜ「通った理由」が読める必要があるのか

Pass / Fail の二値だけを返すゲートは、長期的には信頼を失います。緑が続けば誰も読まなくなり、赤が出ても「またあの不安定なチェックか」と無視されるようになります。ある時期の私のチームでは、毎日 30 件以上のチェック結果が Slack に流れていましたが、誰も読んでいませんでした。

そこで考えたのが、ゲートを「短いレビュー報告書」として書かせる設計です。Claude Code に対しては「以下の 7 項目を順番に確認し、各項目について (1) 何を見たか、(2) 判断結果、(3) その判断の根拠 を 3 行ずつ書け」と指示します。

claude review:release-gate --target=main --base=production

成功時の出力はたとえばこのようになります。

[1/7] DB マイグレーション差分
  - 確認: prisma/migrations 配下の追加 2 件、削除 0 件
  - 結果: PASS(reversible — DROP 文なし、NOT NULL 追加にデフォルト値あり)
  - 根拠: migrations/20260428_add_user_locale.sql の DEFAULT 'en' が
    既存行を埋めるため、ロールバック時の整合性が保たれる

[2/7] 環境変数の追加
  - 確認: .env.example 差分 +2 行、本番側 secrets 未更新
  - 結果: BLOCK
  - 根拠: GEMINI_API_KEY と STRIPE_WEBHOOK_SECRET が追加されているが、
    本番側 secrets manager に未投入。デプロイすると 500 エラーになる

赤を出したとき「なぜ赤か」が一行で読めるので、判断に時間を取られません。緑のときも、根拠が書いてあれば「ああ、これはちゃんと見てくれた」と納得できます。レビューの説得力は、結論よりも「結論にいたる過程」が見えていることに宿る、というのが運用していて強く感じたことでした。

ゲートに含めるべき 7 つの観点

私が長く運用しているチェック項目は次の 7 つです。プロジェクトによって増減はありますが、この骨格はかなり広い範囲のサービスで使い回せています。

  1. DB マイグレーション差分 — reversible か、DROP / RENAME はあるか、NOT NULL 追加に既存データを埋める手当があるか
  2. 環境変数・シークレット.env.example で増えた変数がすべて本番側にも投入されているか
  3. API のリクエスト/レスポンス互換性 — クライアントが古いバージョンで呼んでも動く差分か
  4. 依存ライブラリのバージョン変更 — major bump があるか、changelog で破壊的変更が言及されていないか
  5. i18n キーの差分 — 日本語版を加えたら英語版も加わっているか(私のサイト群でこれを忘れると 404 が出ます)
  6. ビルド成果物のサイズ — 急に増えた chunk はないか
  7. 本番だけ通る経路の手動レビュー — Stripe webhook、メール送信、外部 API 呼び出しなど、CI ではモックしている部分の差分

各項目は小さな MCP ツールやシェルスクリプトに分けておき、Claude Code から Bash 経由で呼びます。ツール側は機械可読な JSON を返し、Claude が「読める文章」に翻訳する分担にしています。この分担にしてから、ツールを単体テストしやすくなり、Claude が報告書を書くときに「数字を曲げる」余地もなくなりました。

観点ごとに小さな実装を持つ — 環境変数チェックの例

最初の頃、私はすべてを 1 つの MCP ツールに詰め込もうとしました。release-gate という名前のツールに 7 項目のチェックを実装し、結果を JSON で返す。Claude Code はそれを呼ぶだけ。シンプルで美しい。けれど、すぐに行き詰まりました。

理由は二つあります。第一に、項目ごとに必要な「文脈」が違うのです。マイグレーションの判断にはスキーマの履歴が必要ですし、i18n キーの差分判断には記事フォルダの構造を理解している必要があります。第二に、人間がレビュー結果を読むときに知りたいのは 「数字」ではなく「物語」 です。「DROP 文 0 件」より「ロールバック可能な追加マイグレーションが 2 件あります」のほうが頭に入ります。

そこで現在の構成では、各観点を独立した小さなツールに分け、Claude Code 自身に「ツールを順番に呼びながら、各項目について報告書のセクションを 1 つずつ書く」ことを任せています。

たとえば「環境変数チェック」は、こんな小さなスクリプトです。

#!/usr/bin/env bash
# scripts/release-gate/env-diff.sh
set -euo pipefail
 
# .env.example で増えたキー
ADDED_KEYS=$(git diff "${BASE:-production}"...HEAD -- .env.example \
  | grep -E '^\+[A-Z_]+=' \
  | sed -E 's/^\+([A-Z_]+)=.*/\1/')
 
# Cloudflare Workers の secrets と比較
EXISTING=$(npx wrangler secret list --env=production 2>/dev/null \
  | jq -r '.[].name')
 
MISSING=()
for key in $ADDED_KEYS; do
  echo "$EXISTING" | grep -qx "$key" || MISSING+=("$key")
done
 
if [ ${#MISSING[@]} -eq 0 ]; then
  echo '{"status":"PASS","added":'"$(jq -Rsc 'split("\n")|map(select(length>0))' <<< "$ADDED_KEYS")"'}'
else
  printf '{"status":"BLOCK","missing":%s}\n' \
    "$(printf '%s\n' "${MISSING[@]}" | jq -Rsc 'split("\n")|map(select(length>0))')"
fi

Claude Code にはこのスクリプトの出力を渡し、「PASS なら『追加された変数 N 個はすべて本番に投入済み』と書け、BLOCK なら『以下の変数が本番側 secrets に未投入。デプロイ前に投入してください』と書け」とプロンプトで指示します。出力フォーマットは固定し、文章だけを Claude に書かせる構造にすると、ぶれが激減します。

マイグレーション安全性チェックを「読める根拠」付きで

DB マイグレーションは、リリース事故の頻出地点です。私の実装では、生 SQL に対して 5 つのパターンを正規表現で検出し、それぞれ「危険度」を付けて Claude に渡しています。

// scripts/release-gate/migration-safety.ts
import { readdir, readFile } from "node:fs/promises";
import { join } from "node:path";
 
interface Finding {
  file: string;
  pattern: string;
  severity: "block" | "warn" | "note";
  excerpt: string;
}
 
const PATTERNS: Array<[RegExp, string, Finding["severity"]]> = [
  [/\bDROP\s+TABLE\b/i, "DROP TABLE", "block"],
  [/\bDROP\s+COLUMN\b/i, "DROP COLUMN", "warn"],
  [/\bRENAME\s+(TO|COLUMN)\b/i, "RENAME", "warn"],
  [/\bNOT\s+NULL\b(?![^;]*DEFAULT)/i, "NOT NULL without DEFAULT", "block"],
  [/\bALTER\s+COLUMN\s+\S+\s+TYPE\b/i, "TYPE change", "warn"],
];
 
export async function inspect(dir: string): Promise<Finding[]> {
  const files = (await readdir(dir)).filter((f) => f.endsWith(".sql"));
  const findings: Finding[] = [];
  for (const file of files) {
    const sql = await readFile(join(dir, file), "utf8");
    for (const [re, name, severity] of PATTERNS) {
      const match = sql.match(re);
      if (match) {
        findings.push({
          file,
          pattern: name,
          severity,
          excerpt: sql.slice(Math.max(0, match.index! - 30), match.index! + 80),
        });
      }
    }
  }
  return findings;
}

Claude Code には、findings 配列を渡し、「block が一つでもあれば結論は BLOCK、warn のみなら WARN、空配列なら PASS」というルールで判定させます。各 finding に対しては、excerpt を引用しながら「この SQL のこの行で〇〇が起きるため、〇〇という影響があります」と書かせます。正規表現が引っかかった行を毎回引用させるのが大事で、こうしておくと Claude が「あるはずのない懸念」を捏造して書く事故 が起きません。

ゲート全体の組み立て:コマンド定義

各観点のスクリプトは独立しているので、最後にこれを Claude Code のスラッシュコマンドとしてまとめます。

// .claude/commands/release-gate.json
{
  "description": "Run pre-deploy verification and write a readable report",
  "system": "あなたはリリース前検証担当のエンジニアです。各ツールの出力を機械的に転記せず、人間が読む報告書として書いてください。BLOCK / WARN / NOTE の判断は各ツールの結果に従い、迷ったら一段階下げて記述してください。",
  "steps": [
    { "tool": "git_diff_summary", "args": { "base": "production" } },
    { "tool": "migration_safety_check", "args": { "path": "prisma/migrations" } },
    { "tool": "env_var_diff", "args": { "example": ".env.example" } },
    { "tool": "api_compat_check" },
    { "tool": "deps_changelog_summary" },
    { "tool": "i18n_key_diff" },
    { "tool": "bundle_size_diff" }
  ],
  "output": "report.md"
}

Claude Code には、最後に report.md を読み返して総合判断(GO / NO-GO / WAIT)を末尾に追記させます。総合判断は「7 項目のうち、どれが赤だと止めるか」のルールを文章で渡しておきます。たとえば「マイグレーションが赤なら無条件に NO-GO、env が赤なら追加投入を依頼してから WAIT、それ以外の赤は人間レビュー必須の WAIT」という具合に。

「赤の出し方」を設計する — 警告疲れを避ける

ゲートを長く運用していて気づいたのは、赤の出し方そのものに設計が要るということです。すべてを赤にすると、警告疲れで誰も読まなくなります。私が落ち着いた区分は次の三段階です。

  • BLOCK(赤) — 本番に出すと事故が起きる。マイグレーションのデータ破壊、シークレット未投入など
  • WARN(黄) — 動くが不健全。chunk サイズの急増、依存の major bump、changelog の不読
  • NOTE(青) — 観点として記録しておきたい。新しい i18n キーの追加、API の追加(既存互換)など

私のチームでは BLOCK が一つでもあるとデプロイが自動で止まります。WARN は人間に通知するだけ、NOTE は報告書に書かれて後で読むだけです。Claude Code には「迷ったら一段階下にする」と指示しています。BLOCK を乱発するエージェントは信用されなくなるからです。

この三段階に分けたとき、特に運用が楽になったのは「WARN を放置する自由」を明示できたことでした。WARN だらけのリリースもあれば、BLOCK ゼロ・WARN ゼロのリリースもあります。後者ばかりを目指すと PR が大きくなり、レビュー負荷が逆に上がるという逆説に気づきました。

報告書をリリースノートに繋げる

このゲートをしばらく運用していて、思わぬ副産物が出ました。report.md がそのままリリースノートの下書きになるのです。各項目の根拠説明を 1 行ずつ抜き出すと、ユーザーに伝えるべき変更点がほぼ揃っています。

claude release-notes --from=report.md --audience=end-user

このコマンドは、report.md の中から「ユーザーに影響する差分」だけを抜き出し、敬体の日本語と英語に変換します。私は最後に手で目を通すだけで、リリースノートの執筆時間がほぼゼロになりました。Claude Code に「お客さま向けの言葉で書いてください。社内用語は避けてください」と指示しておくと、内部実装の用語が漏れることもほぼありません。

ロールバック手順をゲートに同梱する

もう一つ、運用してから付け足したのが「ロールバック手順の自動生成」です。各観点のチェック結果に対して、Claude Code に「この変更を戻すには何をすればよいか」を一文ずつ書かせます。

[1/7] DB マイグレーション差分
  - 結果: PASS
  - ロールバック: prisma migrate resolve --rolled-back 20260428_add_user_locale
    の後、production ブランチに git revert でも安全

これがあると、本番投入後に問題が起きてもパニックになりません。「ロールバック手順は report.md に書いてある」と決めておけば、深夜にオンコールが起きてもまずそこを読みに行く運用が身につきました。リリースゲートが「前進のためのゲート」だけでなく「後退のためのナビ」も兼ねる形です。

落とし穴:ゲートを「絶対の権威」にしない

最後に、私自身がやらかした失敗を共有させてください。ゲートを作って数週間経ったある日、Claude Code が「すべて GO です」と出した PR をそのままマージしたところ、本番でレートリミットの計算ロジックが壊れていました。原因は、API 互換性チェックがリクエスト/レスポンスのスキーマしか見ておらず、意味的な互換性(同じスキーマで違う挙動)を見ていなかったことでした。

それ以来、ゲートは 「人間レビューを置き換えるもの」ではなく「人間が見落とす定型を網羅するもの」 だと位置づけ直しました。Claude Code には「あなたが GO を出しても、人間レビューが NO-GO なら NO-GO が勝つ」と最初に伝えています。エージェントとの協働は、最終責任を人間が持つという前提を崩した瞬間に脆くなる、というのがこの失敗から学んだことでした。

それから、もう一つの教訓として「ゲートのコード自体もゲートを通す」を徹底するようにしました。release-gate のスクリプトを更新する PR は、当然そのスクリプト自身にレビューしてもらいます。自己参照的に見えますが、ゲートに穴ができたタイミングを「本番事故」ではなく「ゲート PR のレビュー」で気づくための仕掛けです。

いま、あなたが最初にやるべき一手

長くなりました。最後に「ここから何を始めればいいか」を一つだけ提案させてください。リリースゲート全体を作るのは時間がかかりますが、「環境変数の差分チェック」だけなら 30 分で書けます。.env.example を git diff して、本番の secrets manager(あるいは Cloudflare Workers の wrangler.toml)と比較し、不足を Claude Code に報告させる。それだけで、私のチームではデプロイ事故の半分が消えました。

完璧なゲートを最初から作る必要はありません。「最も多く失敗している箇所」から一つだけ自動化するのが、長続きするコツだと感じています。あなたのチームで一番よく起きるリリース事故は何でしょうか。そこから一つ、Claude Code に「読める根拠」付きでチェックさせてみてください。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Claude Code2026-06-03
Claude Code で .xcresult を解析し、iOS テスト失敗を最短で特定する実装メモ
Xcode 16 で xcresulttool のレガシー JSON が廃止され、.xcresult からテスト失敗を機械的に取り出す手順が変わりました。新しい test-results フォーマットを jq で整形し、Claude Code に渡して失敗原因と該当コードまで一気に絞り込む実装を、6アプリ並行運用の実体験とともにまとめます。
Claude Code2026-05-25
Claude Code と GitHub Actions で 4 サイトの自動投稿パイプラインを 7 ヶ月運用して見えてきた品質ゲート設計
Claude Code とスケジュールタスクで Lab 4 サイトに毎日 16 本の記事を自動投稿してきた中で、Helpful Content System のインデックス崩壊を経験してから設計し直した品質ゲート、トークン管理、ロールバック手順を実装サンプル込みでまとめます。
Claude Code2026-05-07
Claude Code と husky/lint-staged で『変更ファイルだけ』AIレビューさせる Pre-commit ガイド
git commit の直前に、ステージング済みファイルだけを Claude Code に渡して軽量レビューを走らせる方法。lint-staged で対象を絞ることで、コストと待ち時間を最小化する個人開発者向けのレシピです。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →