1. 背景
Devlimeは開発・ステージ・本番の3環境で運用しており、これらを管理するgitopsリポジトリは2つあります。どの環境に反映する場合でも、デプロイの前後には同じ点検を行います。今回何が反映されるのか、DBへの反映事項があるか、またそれがガイドどおりに記述されているか、サービス間で参照するライブラリのバージョンにずれがないか、未コミット・未プッシュがないかなどを確認する作業です。
点検が終わったら、反映内容を整理します。ステージに反映した直後には、チームが確認すべき項目とともにチーム内で共有し、テストと修正を経て本番にデプロイしたら、それまでの内容をまとめてユーザーに告知します。本番への反映はまだ過渡期にあるため、ステージの設定を本番設定として確認しながら移行する作業がもう一つあります。
この点検と整理は難しくありません。その一方で項目が多く、抜け漏れがあるとすぐに事故につながり、デプロイのたびに繰り返されます。VoCに迅速に対応するためデプロイが日単位になり、この繰り返しが毎日になりました。チームではすでにClaude CodeとCoworkを開発に使用しており、プラットフォームチームにはVizend agent hubというチームハーネスもありますが、ハブは開発コンテキストを扱うためのものなので、デプロイ点検のように人手なしで動くべき運用手順には別の構成が必要でした。この手順自体が過渡期にあるため、大規模に構築せず、必要な分だけ作ることにし、この記事ではその最初の構成と、修正すべき時期が来たことを示す兆候、そしてその後の改善について説明します。
図1. Devlimeのデプロイループ。下の点線のボックスがAIに任せた作業です。
2. 技術選定の背景
|
階層 |
機能 |
何をするのか |
公式ドキュメントが示す導入時期 |
|---|---|---|---|
|
L1 |
CLAUDE.md · rules · メモリ |
セッション開始時に自動的に読み込まれるルールとコンテキスト |
同じルールを2回以上間違えるとき |
|
L2 |
スキル · MCP · LSP |
手順をファイルに固定し、外部システムをツールとして接続 |
同じプロンプトを3回目に入力しているとき |
|
L3 |
サブエージェント · ワークフロー |
付随作業を別のコンテキストで実行し、並列化 |
付随作業が会話を出力で埋め尽くすとき |
|
L4 |
フック |
ツール呼び出しの前後にシェルコマンドで強制・検査 |
尋ねなくても毎回発生しなければならないとき |
|
L5 |
スケジュール(/loop · Desktop作業 · Cloud Routines) |
人がいなくても実行 |
繰り返しの点検が定期化されたとき |
|
L6 |
プラグイン · マーケットプレイス · 管理設定 |
構成要素をまとめてデプロイ・バージョン管理 |
2つ目のリポジトリでも同じ設定が必要になったとき |
|
L7 |
validate · eval |
スキルが発動するか、結果が改善したかを測定 |
プラグインをデプロイする前 |
Claude Code公式ドキュメントの「Extend Claude Code」と「Run prompts on a schedule」にある項目を、私が階層として再構成した表です。導入時期の文言はドキュメントの表現に従い、L1~L7の番号は説明の便宜上、私が付けたものです。
7つの階層のうち、最初に使ったのはL2のスキルとL5のスケジュール作業の2つです。判断基準は3つありました。
1つ目は、ドキュメントの導入時期にそのまま従ったことです。実際に踏んだトリガーは、「同じ手順を3回目に説明している」と「点検がデプロイのたびに繰り返される」の2つでした。フックのトリガーである「毎回強制されなければならないルール」は、手順を何度か実行してみて初めて、それが何なのか分かるものでした。
2つ目は、取り消せない行為は人が行うことです。マージ・コミット・プッシュ・タグ付けと本番環境の変更は、チームの原則として人が行うため、「単独で動かしてよい範囲」が自然に定まりました。確認、ドキュメントの作成、コミット直前までのファイル修正です。
3つ目は、規模に合わせたことです。この点検を行う人は現在私一人で、手順は過渡期にあります。一人で使う過渡期の手順に、プラグインのバージョン管理と評価を先に組み込むのは順序が適切ではありません。その代わり、後から移行できるように手順をスキルファイルに完結する形で記述し、スケジュールプロンプトはスキルを呼び出す形にしました。
スケジュール方式も同じ基準で選びました。Claude Codeのドキュメントが案内している方式は3つあり、その中からDesktopスケジュール作業(Cowork)を選びました。
|
方式 |
実行場所と開始条件 |
この記事の点検に適しているか |
|---|---|---|
|
Cloud Routines |
クラウドでリポジトリを新たに clone して実行。cron(最低 1 時間)、API 呼び出し、GitHub イベントで開始。権限プロンプトなし |
リポジトリが社内 GitLab にあるため、クラウドセッションに認証情報が必要。現段階では行わないことにした |
|
Desktop スケジュールタスク |
PC に接続されたフォルダーを新しいセッションにマウントして実行。タスクごとに権限を設定。時刻を指定するか、人が実行 |
選択。リポジトリはすでに PC にあり、最新化は実行前に人が行う |
|
/loop |
開いているセッション内で繰り返す。セッションに依存 |
「押しておいて別のことをする」点検には合わない |
Cloud Routines が最もスムーズですが、私たちのリポジトリは社内 GitLab にあるため、クラウドセッションに認証情報を置く必要があり、現段階ではその構成を行わないことにしました。Desktop タスクは PC に接続されたフォルダーを新しいセッションにマウントして実行し、リポジトリの最新化(fetch)は実行前に私が行います。
実行時点を時刻で指定していないのには、デプロイが定期的ではないという理由もあります。現在は日単位に近く、安定化後は定期デプロイにホットフィックスが混在することになりますが、いずれの場合も開始条件は時刻ではなく、「最新化を完了した」というイベントです。そのため、どちらのタスクも cron は空欄にして、実行ボタンを人が押します。
3. 初期構成
初期構成はスキル 2 つとスケジュールタスク 2 つです。
|
構成 |
内容 |
|---|---|
|
スキル 2 つ |
ステージ反映前の点検と反映内容の整理を行うものが 1 つ、ステージ・運用の gitops 照合と反映を行うものが 1 つです。それぞれ Markdown ファイル 1 つで構成します |
|
スケジュールタスク 2 つ |
スキルと 1:1 で対応。時刻は指定せず、実行ボタンを人が押す。新しいセッションで自動承認により実行し、終了すると通知 |
|
ルール |
「コミット・プッシュ・タグは人が行う」、「確認できなかったものは確認できなかったとする」。スキルとプロンプト内の文言 |
|
記憶 |
プロジェクト文書。次回の実行では、前回の告知文書を読み、番号を採番して画面表示を再利用 |
スキルファイルに記載したのは、手順よりも判断に関する内容でした。点検の順序はどこでも共通していますが、どの値を移してはいけないか、何を翻訳せずどこから探すべきか、意見が分かれたときにどのように提示するかは、私たちの環境でしか通用しない話です。たとえば、ステージ gitops のディレクトリ名も prd なので、ディレクトリではなくリポジトリとして区別しなければならないことや、画面名はリポジトリにはなく lingo ラベルから渡されるため、翻訳せずにラベルから探すべきことなどが、そのような判断に当たります。こうしたことをファイルに記載しておけば、新しいセッションが毎回同じ基準で点検します。
動作は単純です。リポジトリを最新化して実行ボタンを押すと、新しいセッションがスキルを読み込み、変更範囲、DB 反映事項、バージョンの整合性を点検したうえで、レポートと告知の草案を残します。私はレポートを読み、判断が必要な項目だけを選びます。最初から大きな構成にしなかったのは意図的でした。ただ、何度か実行してみると、この構成がどこまで耐え、どこから修正が必要になるのかが見え始めました。
4. 修正の時期を示すサイン
サインは 5 つありました。そのうち 3 つは、公式ドキュメントに記載されていた導入時点そのものでした。
本文が手順ではなくシェルの断片で埋まっている
2 つのスキルファイルが 400 行前後になり、その半分がコードブロックでした。リポジトリのスナップショット、イメージタグの照合、DB マイグレーションのファイル名検査、バージョンマトリクス、画面パスの抽出など、決定論的な処理を、AI が本文のシェル断片を見て毎回入力し直して実行する構造でした。実行するたびに少しずつ異なり、以前の実行で残ったファイルを読み込んで誤った不一致を出したこともありました。公式ドキュメントの表現を借りれば、「整列をトークンで行うより、整列アルゴリズムを実行するほうが安い」ということです。SKILL.md の本文は起動時にすべてコンテキストへ読み込まれますが、スクリプトは実行されるだけで、トークンを使うのは出力だけです。
同じルールのコピーが複数の場所にある
git のルールが、2 つのスキルと 2 つのスケジュールプロンプト、計 4 か所にありました。プロンプトに「スキルがなければ以下の手順に従う」として、手順全体を複製していたためです。二重化する意図はよかったものの、ルールを 1 回修正するのに 4 か所を編集する必要があり、そのうち 1 つのコピーはずれていました。
実行環境が 1 つの問題を引き起こした
スケジュールタスクが動作する環境では、接続されたフォルダー内のファイル削除が禁止されていました。しかし git は、読み取り専用に見えるコマンドでもロックファイルを作成して削除するため、削除できなかった空のロックファイルがリポジトリごとに残りました。「読み取り専用コマンドなら問題ない」と記載していたルールは、この環境では誤ったルールでした。この問題から学んだことは、ロックファイルそのものよりも 2 つあります。実行環境の性質は設計の一部であること、そして文章で記載されたルールは公式ドキュメントの言うとおり「要求であって保証ではない」ということです。毎回守られるべきルールはフックにすべきです。
手順が固定された
2 つのスキルの章構成が同じになりました。原則 → 対象 → スナップショット・鮮度 → 範囲 → ブロック条件 → 成果物の順です。これは、どの段階をスクリプトで確定でき、どの段階が AI の判断なのかを分けられる状態になったということです。そして、推奨される構造(本文は手順、ルールは参照ファイル、コードはスクリプト)へ移行するタイミングでもあります。最初からその構造で始めていたら、何が決定論的で何が判断なのか分からず、誤った分け方をしていたでしょう。
次の利用者のための形になっていない
スキルは私のアカウントに同期され、既知の差異と表記辞書は散文の一覧で、本文には日付が埋め込まれた文がありました。私一人で使っている間は問題ありません。しかし、これを別途使用しているハーネスに組み込んだり、チームや組織の AI 活用に載せたりするなら、プラグイン単位である必要があり、設定はデータである必要があり、ルールは 1 か所に集約されている必要があります。過渡期の手順だからといって、捨てられる形にしておくと、次の段階で再び作り直すことになります。
5. 改善
改善の方向性は一文で言えます。ルールが定められた検査はスクリプトが行い、判断は AI がスキルに従って行い、ルールは 1 か所だけに置き、守られるべきルールはフックで強制します。2 つのスキルをこの基準で再編成し、1 つのプラグインにまとめました。
devlime-release-ops/
├── skills/ release-check · release-notes · prd-gitops-sync
│ (각 50줄 안팎, 체크리스트 + 판단)
├── references/ repos · git-rules · flyway-check · configmap-compare
│ notice-style · known-deviations · history · ledger
├── config/ 저장소 표 · gitops 대조 규칙 · 기준값 · 버전 상호 참조
│ 알려진 편차 · ledger (JSON)
├── scripts/ snapshot · freshness · changes · flyway_lint · version_matrix
│ cm_pair · routes · locate · ledger · notice_lint · image_tags
│ configmap_diff · plan_validate · plan_apply · plan_verify
├── hooks/ hooks.json + guard.py (명령 실행 전 규칙 검사)
├── evals/ 스킬별 평가 + 트리거 질의
└── tests/ 합성 저장소 생성 + 검사
検査はスクリプトが行い、終了コードで伝えます。リポジトリの最新化の有無、変更範囲、DB 反映事項の形式、ライブラリバージョンの整合性、イメージタグの照合のように、ルールが定められた検査は Python スクリプトが担当します。結果はファイルとして残し、終了コードで「合格 / ブロック / 要確認 / エラー」を知らせます。ブロックの場合、スキルはレポートの最上部に記載して停止し、要確認の場合は判断に委ねます。スキル本文には、これらのスクリプトを順番に呼び出すチェックリストと、判断が必要な項目をどのように確認するかの説明だけが残りました。
Release check:
- [ ] 1. 스냅샷 snapshot.py
- [ ] 2. 신선도 freshness.py (낡았으면 멈추고 최신화 명령을 사용자에게)
- [ ] 3. 변경 범위 changes.py
- [ ] 4. DB 반영 사항 flyway_lint.py (판단이 필요한 항목만 가이드 문서를 읽고 판정)
- [ ] 5. 버전 정합 version_matrix.py
- [ ] 6. 보고서 조립 → 문서 저장
元に戻せない変更は、計画、検証、適用、確認の 4 段階に分けます。運用設定の修正は、照合結果を見てすぐにファイルを修正していた方式から、AI がまず計画ファイル(どのファイルのどの値を何に変更するか、そしてその理由)を作成し、検証スクリプトがその計画をルールおよび現在のファイルと照合してから適用する方式に変わりました。計画に判断を保留した項目が 1 つでもあれば実行せず、ユーザーが承認した値がその間に変わっていれば停止します。社内ブログの「決定ゲート」と「スナップショットベースの承認」をそのまま取り入れたものです。適用後は、実際の変更が計画と完全に一致しているかを再確認します。
ルールは 1 か所に置き、フックで強制します。4 か所に分散していたルールは、1 つの参照ファイルを原本とし、スキルとスケジュールプロンプトはそのファイルを参照するだけにしました。同じルールをフックがツール呼び出しの段階で検査し、矛盾するコマンドは理由とともに拒否します。文章で記載されたルールは AI が従うことを期待するものですが、フックは従わざるを得ないようにします。スケジュールタスクのプロンプトは手順を複製せず、「スキルを実行する。なければ停止する」の 2 行になりました。日付の付いた経緯は別ファイルに移し、本文にはルールだけを残しました。
前後比較
|
項目 |
最初の構成 |
プラグイン |
|---|---|---|
|
スキル本文 |
400行前後 × 2、その半分がコードブロック |
50行前後 × 3、チェックリストと判断だけ |
|
ルールが定められた検査 |
AIが本文中のシェル断片を再入力して実行 |
スクリプト13個、終了コードで通過・ブロック・要確認を区別 |
|
ルール |
4か所にコピー、文章 |
参照ファイル1か所 + フック |
|
設定・辞書 |
本文の散文 |
設定ファイル(JSON)。スクリプトとスキルが同じファイルを読み込む |
|
運用設定の変更 |
照合後すぐに修正 |
計画 → 検証 → 適用 → 確認 |
|
承認の根拠 |
更新日時 |
更新日時 + リポジトリごとのコミットハッシュ |
|
スケジュールプロンプト |
スキル呼び出し + 手順全体の複製 |
呼び出し2行、未インストール時は中断 |
|
検証 |
なし |
スキルごとの評価セット、合成リポジトリテスト |
6. まとめ
今回の構成は、スキルセット、スクリプト13個、フック1つ、そしてそれらをまとめたプラグイン1つです。Claude Codeが提供する7層の拡張機能で見ると、依然として一部にすぎず、ユーザーは1人です。しかし、この範囲は不足していたからではなく、順序を定めて導き出したものです。公式ドキュメントに各機能の導入時期が記されているため、どのトリガーを踏み、どのトリガーをまだ踏んでいないのかを説明でき、次の機能がいつ必要になるのかもあらかじめ分かります。
最初の構成からプラグインに至るまでで最も大きく変わったのは、チェック項目の置き場所です。私の頭の中とメッセージ履歴にあったものがファイルに移され、そのファイルの半分は人が読むルール、残りの半分はスクリプトが実行する検査になりました。そのため、同じ順序で同じものを見るようになり、判断を先送りした項目が毎回同じ場所に残るようになり、承認した値がその間に変わると停止するようになりました。デプロイの点検をAIと一緒に行うことで得られたものは、時間の短縮よりもこちらのほうが大きかったです。
次は、実際のリポジトリでこの構成を検証することです。この構成をどのように管理し、いつチームに共有するのかについては、次の記事「個人AI構成をチーム資産にする基準」で扱います。
Juno