dev-loop の設計 — ループ志向開発
dev-loop プラグインが実装する開発方式(AI コーディングエージェント前提の反復開発)の
設計ドキュメント。/dev-loop の各ステップが「なぜそうなっているか」をここで定義する。
手順そのものは プラグイン一覧の dev-loop 節 と、インストール後の
SKILL.md を参照。
背景 — 「プロンプトを打つ」から「ループを書く」へ
もう自分でプロンプトを打つことはない、書いているのはループだ。
エージェント開発の要点は、指示を 1 つずつ手で与えることではなく、 「何を・どの条件を満たすまで繰り返すか」を設計してエージェントに委ねることにある。
1. なぜループ志向か
従来の「1 指示 = 1 応答」は、指示者がボトルネックになる。ループ志向では、開発者は
- 不変のルール(
CLAUDE.md) - 繰り返す手順(Skills —
/dev-loopはこれ) - 停止条件(検証 = verify が通ること)
の 3 つを一度定義し、あとはエージェントが「実装 → 検証 → 修正」を停止条件に達するまで自走する。 この前提が整うほど、ループに安全に委ねられる。
2. ループの心臓は「verify の定義」
ループが空回りしないための鍵は、停止条件を曖昧にしないこと。/dev-loop は対象リポジトリの
CLAUDE.md(および任意の .claude/dev-loop.md)から verify の定義を発見し、それをそのまま
ループの停止条件に据える。プロジェクト側で最低限、以下を明文化しておくと効く。
| 局面 | 検証(停止条件)に書くべきこと |
|---|---|
| マージ前 | ロジック変更を実際に動かして目視確認する手順(開発サーバ起動・実データ接続・E2E 実行) |
| 本番反映 | 何をマージ/ビルド/apply すると本番に反映されるか(デプロイ経路) |
| 変更種別の分岐 | バックエンド/インフラ/フロント等で経路が分かれるか |
| フラグ切替 | 設定・環境変数の更新だけで反映できる挙動はどれか(再ビルド不要な近道) |
これらが CLAUDE.md に無ければ、/dev-loop はテスト実行+アプリ起動での手動確認という
汎用手順に縮退する。
検証を伴わないループは禁止
「テストが緑」だけを停止条件にしない。ロジック変更は 実際に動かして挙動を目視するまで 完了扱いにしない。停止条件が弱いループは、もっともらしいが誤った結果を通してしまう。
別モデルの Verifier で牽制する
実装したエージェントは自分の変更に甘く、ほぼ確実に自己採点が高い。受入条件の充足は
実装とは別モデルの Verifier サブエージェントに判定させる(Agent ツールで model に
実装時と別ティア=例: 実装が Opus なら sonnet を指定)。反証が挙がれば実装に戻す。
同一モデルだと盲点を一緒に見逃すため、モデルを変えるのが要点。
渡すのは §2.0 の不変条件と経路の一覧まるごとで、問いを局面に絞らない。
「この不変条件を破りうる経路を全部挙げて、それぞれ守られているか確認せよ。反証は証拠
(テスト結果・ログ・目視項目)で示せ」の形にする。手順 6 の /code-review に渡すときと
同じ要件で、片方だけ緩めてはならない。
Verifier には Bash を持つ subagent を指定する
「証拠で示せ」と指示しても、その subagent がコマンドを実行できなければ意味がない。
テスト・ビルド・git を自分で走らせられない agent を指定すると、報告は静的なファイル読解に
縮退し、肝心の検証が実装側に差し戻される。自分の変更に甘い側が検証を担うことになり、
牽制の目的が半分失われる。
| 指定するとき | 見るべき点 |
|---|---|
| ツール可用性 | subagent_type が Bash を持つかを先に確認する。レビュー特化の agent は持たないことがある |
| 既定の選択 | 汎用 agent(例: general-purpose)+「ファイルを変更するな。検証だけせよ」の明示。書き込みもできるためガードが要る |
| 読み取り専用にしたい場合 | Explore / Plan のように書き込み権限を持たない agent(Bash は持つ)。レビュー志向ではない分、指示を厚く書く |
| 指示に必ず入れる | 「コマンドを実行できない場合はその旨を明記せよ」。黙って縮退した報告を「反証なし」と読み違えないため |
2.0 受入基準は「不変条件 × それを破りうる経路」に展開する
受入基準の書き方が verify の射程を決める。「◯◯が正しく動くこと」で止めると、検証は 実装者が想像した経路しか通らない。守るべき不変条件を列挙し、各不変条件について「それを 破りうる入口」を全部数え上げる。
経路は差分からではなく、アプリの入口一覧から数える
差分を読むレビューは、差分に現れていない経路を構造的に見落とす。 差分を起点に経路を 数えると、触っていない入口は最初から視野に入らない。
数え上げる入口の例(プロジェクトの構成に読み替える):
| 層 | 入口 |
|---|---|
| データ層 | 通常の保存 / 一括更新 / 直接 SQL・shell |
| API 層 | REST / GraphQL |
| 管理系 | 管理画面とそのインライン / インポート・エクスポート |
| 一括処理 | 移行スクリプト / バッチ |
実例: あるフィールドの不変性を移行コマンドの中だけで守っており、通常の保存・一括更新・ REST PATCH・管理画面・インポートはすべて素通しだった。レビューの問いを「移行コマンドの 冪等性」に限定したため、別経路を誰も見なかった。経路ごとにどう守るか(モデル層で拒否 / API 層で 400 / 管理画面で readonly)まで書けば、1 箇所直して全部守れたつもりになるのを防げる。
この環境では証明できない受入基準を、黙って「検証済み」に混ぜない
受入基準を「検証で証明できるもの」と「この環境では証明できないもの」に分けて書く。 証明できないものは「未証明」と明示し、人間のコードレビューに回すことを申告する。
これは §2.1 の申告ルールと同じ原則で、対象が権限の衝突ではなく検証環境の 限界になっただけ。
実例: 行ロックによる直列化を実装したが、開発環境の DB ではロック取得が no-op のため競合が 原理的に再現しない。テストは緑だがその修正はテストで証明できていない。単一プロセス・ 単一スレッド・小さな固定データセットでの検証は、並行性・大規模データ・外部連携の性質を 原理的に検出できない——何が検出できないかを先に書き出しておく。
生成物があるなら、その鮮度を受入基準に入れる(該当する場合は必須)
自動生成コード・スキーマ定義・CSV・図の書き出し(drawio → SVG 等)・スナップショット。 再生成して差分ゼロを確認する。ソースだけ直して生成物を再生成し忘れるのは、差分を見ても 気づけない(生成物は差分に現れないので「変えていない」と見える)。
--check 相当(再生成せずに乖離を検出して非ゼロ終了する手段)が無ければ作る。
makemigrations --check のような仕組みが無いこと自体が、見落としの原因になる。
「該当する場合は必須」は、判定を省略してよいという意味ではない。 リポジトリの生成物を
数え上げ(CLAUDE.md の生成手順・Makefile / package.json scripts・CI の鮮度チェック)、
該当が無ければ「生成物なし」と計画ファイルに明記する。黙って触れないのは「飛ばした」と
区別できない。
2.1 関門が「回せない」ときこそ、黙って落とさない
Verifier は Agent ツールを要求するが、Agent はセッション単位で禁止されていることがある。
Do not call the AgentTool unless the user requested it のような指示がセッション開始時に注入される
ケースがあり、これは ~/.claude/settings.json にも CLAUDE.md にも現れない。つまり
許可は毎セッション取り直しになり、スキルの必須手順とセッション指示が正面から衝突する。
事故の本体は衝突ではなく「黙って落として検証済みと報告すること」
衝突の扱いが書かれていないと、エージェントは片方を黙って落とし、検証が済んだかのように
報告できてしまう。実際に、Verifier(手順 5)と /code-review(手順 6)の両方を飛ばして
本番に出し、prod にバグを 2 つ出した事例がある。後から /code-review を 1 回回したら
6 件すべてが実問題だった。
権限を一度与えるだけでは再発する(次のセッションで既定に戻るため)。必要なのは 「回せないときにどうするか」を手順として書いておくこと。
回せないときは着手前に申告して指示を仰ぐ。次のどれかを明示的に選ぶ。
| 選択肢 | 得られるもの | 注意 |
|---|---|---|
| 使用許可を求める(第一候補) | 敵対的な別モデル視点(本来の牽制) | 別モデル=下位ティアなので、本実装より軽いコストで済む旨を添える |
/code-review に受入基準を渡した追加パス |
受入基準に照らしたレビュー | 手順 6 の必須分とは別に回すこと。手順 6 の 1 回で済ませて「代替した」は代替になっていない |
| 理由付きで省略を宣言 | 何を検証していないかの記録 | Issue/PR コメントに残し、後から追える状態にする |
/code-review は「Agent フリーの逃げ道」ではない
/code-review の実装は多くの場合、内部でサブエージェントに fan-out する。公式のレビュー
コマンドは適格性判定・CLAUDE.md の収集・PR 要約・適格性の再確認をそれぞれ別の Haiku
エージェントに割り振り、レビュー本体を Sonnet 5 体の並列で行い、指摘ごとに Haiku で
確信度を採点する。組み込みのレビュースキルも、フォークされた別実行として走る。
つまり Agent が禁止された周は、手順 5 と手順 6 が同時に落ちうる。
実装の内訳は環境・バージョン・どのレビューコマンドが有効かで変わる。 覚えるべきは体数では
なく、「これは Agent を使わないから大丈夫」と仮定してはならないという一点。回す前に
確かめられないなら、回してみて落ちたら申告する。
手順 6 の /code-review は Verifier の有無に関わらず必須——手順 5 が落ちたときに手順 6 まで
一緒に落ちるのが典型的な事故の形だからだ。2 つは相互に代替できない別々の関門だが、
それは「同時には落ちない」という意味ではない。両方が同じ禁止で落ちうるからこそ、唯一の
防波堤は申告になる。
この申告ルールは Agent に依存するすべての手順に適用される(手順 5 の多レンズ化・手順 6 の
レビュー fan-out も同じ)。任意の手順なので省略自体は許されるが、「やった」と報告しては
ならない。
「書かれているか」と「それが事実か」は別の検証
受入基準を「◯◯と書かれているか」の形だけで渡すと、Verifier は記述の存在を確認して充足と 判定し、その記述が事実として正しいかを検証しない。指示に 「主張 → 一次ソースの引用(ファイル:行・コマンド出力) → 一致/不一致」を 1 主張ごとに並べよ。 引用が無い箇所は『未確認』と明記せよを入れる。
実例: このページの旧版にあった「/code-review は Agent を使わないので許可に依らず回せる」という
事実として誤った記述を、Verifier は「書かれている=充足」と判定して見逃した。同じ差分を
/code-review に掛けたら、レビューコマンドの実装ファイルを読んで即座に検出した。
一次ソースを開くだけでは分からない挙動は、実際に走らせて観測させる。ただし実行の許可には
「観察に留めよ」の歯止めが要る——--fix や --comment のような書き込み系フラグ・PR への
投稿・外部送信を禁じておく。「ファイルを変更するな」だけでは、--comment のような
ファイルを変更しない副作用を止められない。
Verifier が報告を返さなかったら、それは「反証なし」ではない
エラー・タイムアウト・空応答で票が欠けたら再実行する。1 体構成でも同じで、欠票のまま 手順 6 へ進んではならない。「たぶん問題なかったのだろう」と解釈する誘惑が最も強い場面なので、 明文で禁じておく。
欠票と遅延は外から区別できない。 この節を書いた周では、1 体が API エラーで報告を返せず、 もう 1 体は報告が届かないので欠票と判断して代わりを立てたが、後になってその報告が届いた (しかも反証を 1 件含んでいた)。区別できないなら再実行が正しい。遅れて届いた票は、 届いた時点で採用する。
報告が途中で切れる事故を減らすには、検証スコープを絞って報告を短く要求する。網羅的な長大 レポートを 1 体に求めるより、観点を分けて短く返させるほうが完走する。
「テストが緑」を敵対的レビューの代わりにしない
実装者が書いたテストは実装者の盲点をそのまま持つ。「テストは通った」は Verifier を省略する 根拠にならない。
実例: 冪等性テストを「同じ日に 2 回実行しても増えない」でしか書いておらず、 「翌日実行したら同じ入力が新規扱いで再作成される」を見ていなかった。テストは緑で、本番では 同じ記事が毎日「新しいシグナル」として立ち続けた。テストが確かめたのは 実装者が想像した失敗の形だけだった。
レビュー指摘の修正も、母集団で当て直す
指摘の修正は「小さい変更」に見えるので検証が省かれやすい。実例では、recall を落としていた 指摘を直したところその修正自体が退行を含んでいた——母集団(19 件)に当てて初めて、 監視対象の中核エンティティを 1 つ落としていたと判明した。差分だけを見ていては分からない。
受入基準は Verifier と /code-review の両方に渡す
片方にしか渡さないと、渡していない側は差分の局所的な読解に縮退し、受入条件に紐づく経路を 見ない。2 つの関門に同じ受入基準(§2.0 の不変条件と経路の一覧)を与える。
実例: 受入条件を Verifier にだけ渡し、/code-review には渡さなかった。さらにその問いを
「移行コマンドの冪等性」に絞ったため、REST と管理画面という別経路を誰も見なかった。
両方の関門が「渡された範囲だけ」を見て、範囲外は無検査で通った。問いを局面に絞らない——
「この不変条件を破りうる経路を全部挙げて、それぞれ守られているか確認せよ」の形にする。
指摘対応で増えたコードは、レビューを一度も通っていない
verify に当て直すだけでは足りない。指摘への対応として書いた新しいコードは、まだ誰も レビューしていない。「指摘に対応して結果を報告した時点で止める」のが典型的な穴で、 増えた分がそのまま無検査でマージされる。
実例: /code-review の指摘に応えて機能を 1 つ追加し、対応報告を書いて周を閉じた。
その追加分だけレビューを通っていなかったため、後の人間レビューで設計と食い違う挙動
(サービス非依存のはずのレコードをサービス別処理で無効化していた)が発見された。
指摘対応後は手順 5(verify)と手順 6(レビュー)の両方に当て直す。片方では足りない。
3. 反復の道具は 4 つの層で使い分ける
粒度に応じて道具を選ぶ。A〜C は「ループ」の層で、上ほど開発の本体・下ほど待ち時間の自動化。 D はその外側にあるグラフの層で、1 本のループでは待ちが無駄になるときに移る先。
| 層 | 道具 | 停止条件/構造の書き方 | 使いどころ |
|---|---|---|---|
| A. 構造ループ(1 Issue = 1 周) | /dev-loop(+任意でフェーズ分割型プランニングプラグイン) |
Issue 選択 → 計画 → 実装 → verify を Issue 単位で回す | 機能追加・仕様変更の本体 |
| B. セッション内の反復 | /loop(間隔指定 or 自走) |
「CI が緑になるまで」「デプロイ PR がマージされるまで」 | ビルド/CI/デプロイの完了待ち・監視 |
| C. 定時の自律ループ | /schedule(cron クラウドエージェント) |
「毎朝 inbox を 1 件トリアージ」等 | 定型作業・夜間バッチ結果の点検 |
| D. グラフ(宣言的な調整構造) | Workflow ツール(動的ワークフロー) |
ノードとデータの流れを一度スクリプトで宣言し、parallel() / pipeline() で fan-out させる |
多段の受け渡しに入出力スキーマの検証が要る、条件分岐で経路が変わる、飽和まで回す収束ループを組む——宣言しないと管理できない構造 |
/dev-loop が担うのは 層 A。B・C は待ち時間や定時処理を切り出す別スキルで、未導入環境では
手動の待機・確認に読み替えてよい。D は層 A の代替ではない——§3.1 のとおり、
ループはグラフの簡易版であって、両者は競合しない。
「並列にする」ことと「グラフにする」ことは別
Agent をバックグラウンドで複数起動するだけでも並列実行はできる(/dev-loop の手順
2 / 5 / 6 はこれを既定にしている)。ただしそれは手続き的な fan-out で、得られるのは
並列性だけ。
並列 Agent 呼び出し |
Workflow(層 D) |
|
|---|---|---|
| 並列実行 | ○ | ○ |
| 調整構造を一度宣言する | ✗ 毎回その場で呼ぶ | ○ スクリプトで宣言 |
| 入出力スキーマの検証 | ✗ | ○ schema |
| ノード間のデータフロー定義 | ✗ | ○ 辺として明示 |
| 動作条件 | Agent があればどこでも |
Workflow ツールが必要 |
グラフエンジニアリングの要件は「調整構造を一度宣言すること」なので、並列 Agent 呼び出しは
層 D には届かない中間段。速くはなるが宣言的にはならない。この区別を曖昧にすると、
「並列化したからグラフ化した」と誤認する。
3.1 5 レイヤーの中での位置づけ
エージェント設計は プロンプト → コンテキスト → ハーネス → ループ → グラフ の 5 層で捉えられる。
/dev-loop はこのうち第 4 層(ループ)の実装で、上の表の層 D が第 5 層(グラフ)にあたる。
| 層 | 設計対象 | この文書での実体 |
|---|---|---|
| 1. プロンプト | 1 つの指示の言い方 | 各ステップでエージェントに与える指示 |
| 2. コンテキスト | 判断の瞬間に何を持っているか | §4 手順 2 の文脈収集・手順 3 の計画ファイル |
| 3. ハーネス | 道具・権限・作業環境 | CLAUDE.md、worktree、権限設定 |
| 4. ループ | 反復と停止条件 | /dev-loop(層 A) + /loop(層 B)・/schedule(層 C) |
| 5. グラフ | 分岐・並列・承認の経路 | Workflow ツール(層 D) |
要点はこの 5 層が競合しないこと。「ループは単純なグラフに過ぎない」——ループエンジニアリングは グラフの簡易版であって、置き換えられる関係ではない。1 本の反復で足りるならループのままでよく、 役割分担・並列・承認ゲートが要るようになった時点でグラフへ上げる。
層を上げても必須要件は消えない
グラフへ上げるとき、ゲートの中身をノードとして宣言する必要がある——各ノードに §2.0 の不変条件と経路の一覧まるごとを渡し、Verifier とレビューの 2 つの関門と初回・指摘対応後の 2 パスをノードとして残す(2 パス目のノードにも受入基準を 渡す)。
これは Workflow に限らない。任意の fan-out・多レンズ化・プランニングプラグインへの委譲でも
同じ——任意なのは「分けるかどうか」だけで、必須要件は分けた先にも付いてくる。
とくに「指摘ごとに 1 ノード」の分解は、定義上「問いを局面に絞る」ことになる。分解するなら 「経路を全部挙げる」ノードを別に置き、絞られた範囲の外を誰かが見るようにする。 層を上げた先で必須要件が消えるのは、任意手順への委譲(多レンズ化・プランニングプラグイン)と 同型の穴。
エッジは「その次に」ではなくデータの流れ
グラフでは実際に値が渡るときだけ辺を引く。「A の次に B」という時間順序で辺を引くと、 存在しない依存で待ちが生まれる。§4 の標準ループは意図的に 1 本の線にして あるが、その中にはデータを渡していない辺(例: 手順 2 で複数の資料を読む部分)が含まれる。 そこが層 D へ上げる余地のある箇所。
参考:
- AIエージェント設計の5レイヤー — プロンプト・コンテキスト・ハーネス・ループ・グラフは競合しない
- Claude Code の動的ワークフローで組むグラフエンジニアリング 14 ステップ
- グラフエンジニアリング(概念)
4. 1 Issue を 1 周する標準ループ
開発本体は 層 A を基本とする。GitHub Issue 1 件を次のサイクルで 1 周させる。
この図はループの図解であり、宣言的グラフではない
上の図は手順の流れを人間向けに描いたもので、実行される構造ではない。各ステップは
SKILL.md の散文手順として、エージェントが毎周読み直して解釈する。§3.1 の
第 5 層(グラフ)に上げるには、ノードの入出力スキーマとデータの流れを Workflow
スクリプトとして宣言する必要がある。
各ステップの対応:
- Issue 選択 —
gh issue view <issue-number>で要件・受入条件・関連 PR を把握する。 - 文脈収集 — 関連ドキュメント・既存実装・過去の議論を読む。受入条件を「何を目視できれば 満たしたと言えるか」に翻訳しておく。
- 計画 — 変更範囲・影響を確定。設定フラグで切替可能かも先に判断(済むなら再ビルドを避けられる)。
計画と verify の受入基準はファイルに書き出す(
docs/plans/issue-<n>.md等)。会話コンテキストは 圧縮で失われるが、ファイルは残る——§7 の「記録」を計画にも適用する。 受入基準は §2.0 のとおり「不変条件 × それを破りうる経路」に展開する (経路は差分ではなくアプリの入口一覧から数える)。この環境では証明できないものを分けて 「未証明」と明示し、生成物があればその鮮度も受入基準に入れる(該当が無ければ「生成物なし」と明記)。 - 実装 — まず worktree を開始する(PR を出す周では必須)。そのうえで対象リポジトリの
CLAUDE.mdのルールを守り、既存コードの流儀に合わせて変更する。 - 検証(停止条件) — §2 の verify が通るまで 4↔5 を繰り返す。ここがループの本体。 判定は手順 3 の計画ファイルに書いた受入基準に照らす(実装しながら基準を緩めない)。 受入条件の充足は、実装とは 別モデルの Verifier サブエージェントにも反証を探させて牽制する。 Verifier を回せないときは §2.1 のとおり着手前に申告して指示を仰ぐ。
- レビュー —
/code-reviewで差分をレビューし、指摘を反映して PR を作成。/code-reviewは 手順 5 の Verifier の有無に関わらず必須で、受入基準は Verifier と/code-reviewの両方に 渡し、問いを局面に絞らない(絞った問いは絞った範囲の外を見ない)。指摘を直したら、その修正を 手順 5 の verify と/code-reviewの両方に当て直す(指摘対応で増えたコードはレビューを 一度も通っていない)。この 2 パスは差分の大小に依らず必要。worktree 上にいることが PR 作成の 前提条件で、そうでなければ worktree へ移送してから作る。結果は PR コメントに残し、 手順 3 で「未証明」に分類した受入基準を名指しで書いて人間のコードレビューに回す。 - 本番反映 — 対象リポジトリの
CLAUDE.md/ deploy runbook の経路に従う。破壊的・不可逆な反映 (DB マイグレーション・インフラ apply 等)は前提条件を確認し、必要なら人間の承認を得る。 - 経験の還元 — この 1 周で得た学び(成功の型・失敗の教訓・非自明な事実)を
CLAUDE.md/ 該当 Skill / メモリへ焼き戻してから周を閉じる。変更は必ず PR で人間レビューを通す。
このループはスキル化されている
上記手順は毎回口頭で説明せず、/dev-loop に集約している。「ループを一度書いて再利用する」を
体現する。/dev-loop <issue> で起動する。
5. 実行例(ウォークスルー)
/dev-loop で 1 Issue を 1 周させる具体例。ここでは 「一覧 API に新しいフィールドを足し、
フロントにバッジ表示する」という架空の Issue #999(バックエンド + フロントの小改修)を題材にする。
👤 は 人間の承認が挟まるチェックポイントを表す。
5.1 Issue 選択・文脈収集
関連ドキュメントと既存実装(API・フロントの表示箇所)を読む。
5.2 計画 — 変更経路を見極める
まず 「設定フラグで済むか / コード変更が要るか」 を判断する。ここが後段のデプロイ経路を決める。
| 判断 | 帰結 |
|---|---|
| 設定・環境変数で挙動を切替できる | コード変更なし。フラグ更新 + 再起動で反映 |
| 表示ロジックの追加が要る | バックエンド + フロントの変更 → フル 1 周(本例はこちら) |
判断できたら、計画を docs/plans/issue-999.md に書き出す。ここに書いた受入基準が 5.4 の
停止条件になる。コンテキストが圧縮された後や翌日の再開時は、このファイルを読み直してから続ける。
受入基準は §2.0 のとおり「不変条件 × それを破りうる経路」に展開する。
「一覧にバッジが出ること」で止めると、is_new を書き換えられる他の入口(一括更新・REST・
管理画面・インポート)が視野に入らない。
## 変更範囲
- backend: 一覧 API に `is_new` フィールド追加 / frontend: 一覧行にバッジ
- 触らない: 検索条件・ページング
## デプロイ経路
- コード変更あり → main マージ → CI ビルド → 通常デプロイ
## verify の受入基準
### 不変条件 1: `is_new` は作成日時から導出され、外部から書き換えられない
| 経路 | どう守るか | 確認 |
|:--|:--|:--|
| 通常の保存 / 一括更新 | モデル層で読み取り専用プロパティ | [ ] |
| REST(POST / PATCH) | シリアライザで read-only(送っても無視) | [ ] |
| 管理画面・インライン | readonly フィールド | [ ] |
| インポート | 列を受け付けない | [ ] |
### 不変条件 2: 既存レコードの表示が変わらない(回帰なし)
| 経路 | 確認 |
|:--|:--|
| 一覧画面 | [ ] 新規レコードにだけバッジが出る |
| 一覧画面 | [ ] 既存レコードにはバッジが出ない |
| 一覧 API のレスポンス | [ ] 既存フィールドの形が変わっていない |
### この環境では証明できない(→ 人間のコードレビューに回す)
- [ ] **未証明**: 日付境界をまたぐ挙動。開発環境では時刻を固定しているため、
「翌日になったらバッジが消える」を実際には再現できない
### 生成物の鮮度
- 該当なし(**生成物なし**——`Makefile` / CI に生成タスクが無いことを確認済み)
## 未解決
- バッジの表示期間(何日で消えるか)→ Issue でプロダクト確認中
経路の表は「1 箇所直して全部守れたつもり」を防ぐ
上の不変条件 1 は、モデル層だけ直しても REST と管理画面が素通しになる。層が違えば実装も 違うので、経路ごとに「どう守るか」まで書いておく。
5.3 実装 — worktree で作業する
ファイルを触る前に worktree を開始する。 PR を出す変更では必須で、メインの作業ツリーを 汚さずに他の周と並行できる。
# EnterWorktree ツールが使える環境ではそれを使う。同等の素の操作:
git worktree add ../myrepo-issue-999 -b issue/999-add-badge
cd ../myrepo-issue-999
# backend: API に新フィールドを追加
# frontend: 一覧にバッジ表示を追加
5.4 検証(停止条件)— ここがループの本体 👤
「テスト緑」では完了にしない。 対象リポジトリの verify 手順(開発サーバ起動・実データ接続)で 実際の画面を開き、挙動を目視する。期待どおりでなければ 5.3 に戻る(4↔5 の反復がループの本体)。
受入条件の充足は §2 のとおり別モデルの Verifier に判定させる。渡すのは 5.2 の
不変条件と経路の表まるごとで、問いを局面に絞らない(絞った問いは絞った範囲の外を見ない)。
差分が大きいときは
Agent をバックグラウンドで 3 体起動し、レンズを変えて(正しさ/回帰/再現性)多数決で
判定してもよい(任意)。2 体以上が反証を挙げたら 5.3 に戻る。1 体だけの反証は証拠を確認して
判断する。結果待ち(同期)で呼ぶと 1 体ずつ逐次実行になるので、並列にしたつもりで逐次に
なっていないか、各体の実行区間が重なっているかで確かめる。
Agent がこのセッションで禁止されていて Verifier を回せないなら、ここで手を止めて申告する
(§2.1)。黙って 5.5 へ進んではならない。5.5 の /code-review も内部で
サブエージェントを使うため、同じ禁止で一緒に落ちうる——「レビューで拾えるから先へ進む」と
考えてはならない。任意の多レンズ化(3 体並列)も同じ禁止の対象で、省略はできるが「やった」とは
報告しない。
5.5 レビュー → PR 👤
/code-review は 5.4 の Verifier を回せたかどうかに関わらず必須。5.2 の不変条件と経路の表を
/code-review にも渡す(Verifier にだけ渡すと、渡していない側は差分の局所的な読解に縮退する)。
# 受入基準を「表まるごと」渡し、問いを局面に絞らない。素の /code-review では差分の局所読解に縮退する
/code-review 計画は docs/plans/issue-999.md。不変条件 1(is_new は外部から書き換えられない)と
不変条件 2(既存表示の回帰なし)の経路表をまるごと見て、各経路が守られているか確認してほしい。
未証明にした「日付境界をまたぐ挙動」も、コードから読み取れる範囲で見てほしい
# 2 パス目。「もう一度回す」だけでは素の差分レビューに縮退するので、ここでも受入基準を渡す
/code-review 指摘対応で書いたコードが対象。受入基準は同じ経路表まるごと。増えたコードは
まだ誰もレビューしていないので、経路のどれかを新たに破っていないか確認してほしい
# PR 作成の前提条件: worktree 上にいること(そうでなければ 5.3 に戻る)
test "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" || exit 1
gh pr create --base main --fill # PR 作成 → 人間レビュー・承認
指摘を直したら、その修正を 5.4 の verify(母集団に当て直す)と /code-review の両方に掛ける。
PR コメントには、5.2 で「未証明」に分類した受入基準を名指しで書き、「この項目はコードレビューでの
確認をお願いします」と明示する——5.2 の申告の着地点はここで、書かなければ申告はどこにも残らない。
5.6 本番反映 👤
対象リポジトリの deploy runbook に沿って、承認済み PR をマージ後に反映する。破壊的・不可逆な 手順は前提条件(例: マイグレーションのタイミング)を確認し、人間の承認を挟む。
1 周で完了しなければ、そのまま次の周へ
検証で仕様漏れが見つかったら Issue にメモして 5.3 から回し直す。 「同じ手戻りが何度も出る」パターンは §7 Dreaming の振り返りで恒久ルール化する。
6. Claude Code の 4 要素との対応
Claude Code の設計は 4 要素で捉えられる。/dev-loop を使う際の実体は以下。
| 要素 | 役割 | 実体 |
|---|---|---|
| ループ | 停止条件つきの繰り返し | §3 の層 A〜C(/dev-loop / /loop / /schedule) |
| CLAUDE.md | ループ間で不変の「憲法」 | コーディング規約・検証/デプロイ制約を固定し、毎周の逸脱を防ぐ |
| Skills | 反復の中で呼ぶ再利用手順 | /dev-loop・/code-review・(任意で)フェーズ分割型プランニングプラグイン |
| Dreaming | セッション間の自律的な自己改善 | §7 を参照 |
この 4 要素はループ層(第 4 層)の内訳で、閉じた分類ではない。グラフ層(第 5 層 = Workflow)
との関係は §3.1 を参照。
6.1 プラグインの同梱(.claude/settings.json)
依存を各自の環境任せにせず、.claude/settings.json(Git 追跡・チーム共有)に
マーケットプレイス参照と有効化プラグインを宣言すると、clone した各メンバーの Claude Code が
同じプラグインを認識できる。dev-loop を全メンバーへ配布する例:
{
"extraKnownMarketplaces": {
"claude-code-setup": { "source": { "source": "github", "repo": "hdknr/claude-code-setup" } }
},
"enabledPlugins": { "dev-loop@claude-code-setup": true }
}
- プロジェクト固有の verify/デプロイ経路/制約は
.claude/dev-loop.mdに置く(/dev-loopが読む)。 /code-review・/loop・/scheduleは Claude Code のビルトイン相当で宣言不要。フェーズ分割型の プランニングプラグイン(GSD 系など)は各自導入前提で任意——/dev-loopはその価値の中核である 「計画の永続化」を手順 3 に内製しているため、無くても成立する。
7. Dreaming — セッション間の自己改善
Dreaming とは「エージェントがジョブとジョブの合間に過去のセッションを振り返り、失敗パターンから 学んで次回以降の手順を自律調整するスケジュールプロセス」。学びの記録には 2 つの時間軸がある。
- セッション内の記録 —
CLAUDE.md/ メモリファイルへの書き込み。今この作業で得た学びを残す。 - セッション間の自己改善(= Dreaming) — 作業の合間に過去の複数セッションを俯瞰し、繰り返す
失敗を見つけて手順そのもの(
CLAUDE.md・Skills)を更新する。
既存の道具で Dreaming を近似実装できる。
| 層 | 何をする | 道具 | 頻度 |
|---|---|---|---|
| 記録 | セッション内で得た事実・制約を永続化 | メモリファイル(memory/ + MEMORY.md) |
都度 |
| 抽出 | 完了した周の成果物から決定・教訓・驚きを抽出 | /dev-loop 手順 8「経験の還元」(計画ファイルの残課題も回収) |
1 周の終わり |
| 反芻(Dreaming 本体) | 直近の PR / クローズ Issue / デバッグ記録を俯瞰し、繰り返す失敗を見つけて更新を提案 | /schedule の定時エージェント |
定時(例: 週次) |
週次 Dreaming の起動例
Dreaming に載せないもの
自己改善の対象は 開発手順(CLAUDE.md・Skills・メモリ) に限る。本番の発停・課金・実発注・
不可逆な操作は Dreaming の自律更新の対象外とし、必ず通常の §4 標準ループ
(実機検証 + 人間レビュー + デプロイ手順)を経由させる。Dreaming の産物は自動マージしない。
8. コスト — トークンバーンの現実
ループは人手を離れて自走する分、トークンを速く消費する。目安として、中規模タスクのシングル エージェントループで 5 万〜20 万トークン、オーケストレーター + スペシャリスト数体のフリートループで 50 万〜200 万トークン、毎朝のスケジュール実行だと週に数百万トークンに達しうる。抑制の効き所:
| コストが乗る箇所 | 何が増やすか | 抑制策 |
|---|---|---|
| 標準ループ本体 | 実装↔検証の手戻り回数(§4 の 4↔5) | verify を明確化し空回りを防ぐ(§2)。設定フラグで済む変更はコードループを回さない |
| 別モデル Verifier | 1 周ごとに検証エージェント分が追加 | 粗探しに最上位モデルは不要。実装より安いティアを使う(例: 実装 Opus → 検証 sonnet) |
/schedule 定時ジョブ |
定期起動 × 毎回の入力量 | 入力を前回実行以降の差分に絞り、頻度も週次に絞る |
抑制の対象外——ここを削るなら申告に乗せる
次の 2 つはコストを理由に削ってはならない。削るなら §2.1 の申告に乗せて 人間の指示を仰ぐ(黙って削るのは「関門を黙って落とす」と同じ)。
| 削ってはいけないもの | なぜ |
|---|---|
受入基準(不変条件と経路の一覧)を Verifier と /code-review の両方に渡す |
片方に絞ると、渡していない側は差分の局所読解に縮退する。入力量の削減がそのまま検証範囲の削減になる |
| 指摘対応後の再レビュー(2 パス目) | 指摘に応えて書いたコードは、まだ誰もレビューしていない |
上の表の「入力を差分に絞る」は /schedule の定時ジョブに対する策で、受入基準の受け渡しには
適用しない。受入基準は差分に現れていない経路を拾うためにあるので、差分に絞ると存在意義が消える。
- クローズドループを既定にする。オープンループ(広い裁量で自律探索)はトークン消費が読めない。
- 待ちループ(
/loop)は間隔を長めに。完了通知で起きられる場面で短周期ポーリングをしない。 - メモリ/経験の還元を効かせる。同じ発見を毎周やり直さないことが再推論コストを直接削る。 「モデルは忘れる、リポジトリは忘れない」。
9. アンチパターン
- 停止条件がテストのみ — ロジックは実データで挙動確認するまで完了にしない(§2)。
- 受入基準を差分から数える — 経路はアプリの入口一覧から数える。差分を起点にすると、触って いない入口(REST/管理画面/一括更新/インポート)は最初から視野に入らない(§2.0)。
- 問いを局面に絞って渡す — 「この局面での冪等性は?」と聞くと、絞った範囲の外は誰も見ない。 「この不変条件を破りうる経路を全部挙げよ」の形にする(§2.0)。
- 片方の関門にしか受入基準を渡さない — 渡していない側は差分の局所読解に縮退する。Verifier と
/code-reviewは相互に代替できない別々の関門(§2.1)。 - 未証明を「検証済み」に混ぜる — この環境では原理的に証明できない項目は「未証明」として分け、 PR コメントに名指しして人間レビューに回す(§2.0)。
- 生成物の該当判定を省く — 「該当する場合は必須」は判定を省いてよい意味ではない。該当が 無ければ「生成物なし」と明記する。黙って触れないのは「飛ばした」と区別できない (§2.0)。
- 指摘対応で増えたコードを無検査で出す — 指摘に応えて書いたコードは、まだ誰もレビューして いない。初回と指摘対応後の 2 パスは差分の大小に依らない(§2.1)。
- 関門を黙って落とす — 権限の衝突・環境の限界・道具の不在で回せないなら、着手前に申告する。 落としたことを報告から省いて「検証済み」と述べない(§2.1)。
- CLAUDE.md を無視した実装 — 規約違反はループが増幅させる。ルールは
CLAUDE.mdに固定する。 - 本番へ直接ループを向ける — 発停・課金・取引・不可逆操作は自律ループに載せない。
- 層の取り違え — 機能追加を
/loop(層 B)で回さない。層 B は「待ち」の自動化に限る。 - 層を上げて必須要件を落とす —
Workflow(層 D)や任意の fan-out・委譲に移しても、受入基準の 受け渡しと 2 つの関門・2 パスは残る(§3.1)。