コンテンツにスキップ

dev-loop の設計 — ループ志向開発

dev-loop プラグインが実装する開発方式(AI コーディングエージェント前提の反復開発)の 設計ドキュメント。/dev-loop の各ステップが「なぜそうなっているか」をここで定義する。 手順そのものは プラグイン一覧の dev-loop 節 と、インストール後の SKILL.md を参照。

背景 — 「プロンプトを打つ」から「ループを書く」へ

もう自分でプロンプトを打つことはない、書いているのはループだ。

エージェント開発の要点は、指示を 1 つずつ手で与えることではなく、 「何を・どの条件を満たすまで繰り返すか」を設計してエージェントに委ねることにある。

1. なぜループ志向か

従来の「1 指示 = 1 応答」は、指示者がボトルネックになる。ループ志向では、開発者は

  1. 不変のルールCLAUDE.md
  2. 繰り返す手順(Skills — /dev-loop はこれ)
  3. 停止条件(検証 = 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_typeBash を持つかを先に確認する。レビュー特化の 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-reviewVerifier の有無に関わらず必須——手順 5 が落ちたときに手順 6 まで 一緒に落ちるのが典型的な事故の形だからだ。2 つは相互に代替できない別々の関門だが、 それは「同時には落ちない」という意味ではない。両方が同じ禁止で落ちうるからこそ、唯一の 防波堤は申告になる。

この申告ルールは Agent に依存するすべての手順に適用される(手順 5 の多レンズ化・手順 6 の レビュー fan-out も同じ)。任意の手順なので省略自体は許されるが、「やった」と報告しては ならない

「書かれているか」と「それが事実か」は別の検証

受入基準を「◯◯と書かれているか」の形だけで渡すと、Verifier は記述の存在を確認して充足と 判定し、その記述が事実として正しいかを検証しない。指示に 「主張 → 一次ソースの引用(ファイル:行・コマンド出力) → 一致/不一致」を 1 主張ごとに並べよ。 引用が無い箇所は『未確認』と明記せよを入れる。

実例: このページの旧版にあった「/code-reviewAgent を使わないので許可に依らず回せる」という 事実として誤った記述を、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 へ上げる余地のある箇所。

参考:

4. 1 Issue を 1 周する標準ループ

開発本体は 層 A を基本とする。GitHub Issue 1 件を次のサイクルで 1 周させる。

dev-loop の標準ループ

この図はループの図解であり、宣言的グラフではない

上の図は手順の流れを人間向けに描いたもので、実行される構造ではない。各ステップは SKILL.md の散文手順として、エージェントが毎周読み直して解釈する。§3.1 の 第 5 層(グラフ)に上げるには、ノードの入出力スキーマとデータの流れを Workflow スクリプトとして宣言する必要がある。

各ステップの対応:

  1. Issue 選択gh issue view <issue-number> で要件・受入条件・関連 PR を把握する。
  2. 文脈収集 — 関連ドキュメント・既存実装・過去の議論を読む。受入条件を「何を目視できれば 満たしたと言えるか」に翻訳しておく。
  3. 計画 — 変更範囲・影響を確定。設定フラグで切替可能かも先に判断(済むなら再ビルドを避けられる)。 計画と verify の受入基準はファイルに書き出すdocs/plans/issue-<n>.md 等)。会話コンテキストは 圧縮で失われるが、ファイルは残る——§7 の「記録」を計画にも適用する。 受入基準は §2.0 のとおり「不変条件 × それを破りうる経路」に展開する (経路は差分ではなくアプリの入口一覧から数える)。この環境では証明できないものを分けて 「未証明」と明示し、生成物があればその鮮度も受入基準に入れる(該当が無ければ「生成物なし」と明記)。
  4. 実装まず worktree を開始する(PR を出す周では必須)。そのうえで対象リポジトリの CLAUDE.md のルールを守り、既存コードの流儀に合わせて変更する。
  5. 検証(停止条件)§2 の verify が通るまで 4↔5 を繰り返す。ここがループの本体。 判定は手順 3 の計画ファイルに書いた受入基準に照らす(実装しながら基準を緩めない)。 受入条件の充足は、実装とは 別モデルの Verifier サブエージェントにも反証を探させて牽制する。 Verifier を回せないときは §2.1 のとおり着手前に申告して指示を仰ぐ
  6. レビュー/code-review で差分をレビューし、指摘を反映して PR を作成。/code-review は 手順 5 の Verifier の有無に関わらず必須で、受入基準は Verifier と /code-review の両方に 渡し、問いを局面に絞らない(絞った問いは絞った範囲の外を見ない)。指摘を直したら、その修正を 手順 5 の verify /code-review両方に当て直す(指摘対応で増えたコードはレビューを 一度も通っていない)。この 2 パスは差分の大小に依らず必要worktree 上にいることが PR 作成の 前提条件で、そうでなければ worktree へ移送してから作る。結果は PR コメントに残し、 手順 3 で「未証明」に分類した受入基準を名指しで書いて人間のコードレビューに回す。
  7. 本番反映 — 対象リポジトリの CLAUDE.md / deploy runbook の経路に従う。破壊的・不可逆な反映 (DB マイグレーション・インフラ apply 等)は前提条件を確認し、必要なら人間の承認を得る。
  8. 経験の還元 — この 1 周で得た学び(成功の型・失敗の教訓・非自明な事実)を CLAUDE.md / 該当 Skill / メモリへ焼き戻してから周を閉じる。変更は必ず PR で人間レビューを通す。

このループはスキル化されている

上記手順は毎回口頭で説明せず、/dev-loop に集約している。「ループを一度書いて再利用する」を 体現する。/dev-loop <issue> で起動する。

5. 実行例(ウォークスルー)

/dev-loop で 1 Issue を 1 周させる具体例。ここでは 「一覧 API に新しいフィールドを足し、 フロントにバッジ表示する」という架空の Issue #999(バックエンド + フロントの小改修)を題材にする。 👤 は 人間の承認が挟まるチェックポイントを表す。

起動

/dev-loop 999
以降、プラグインの SKILL.md の手順に沿って進む。

5.1 Issue 選択・文脈収集

gh issue view 999               # 要件・受入条件・関連 PR を把握(必須)

関連ドキュメントと既存実装(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-review5.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 の起動例

/schedule 毎週月曜 9:00「先週マージした PR とクローズ Issue を振り返り、
再発したレビュー指摘・手戻りを抽出。恒久ルール化すべき学びを
CLAUDE.md とメモリの更新 PR として起票(自動マージはしない)」

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)。