コンテンツにスキップ

dev-loop のオートクルーズ(複数 Issue を不在のまま回す)

依存のある複数の Issue を、1 つの親セッションで起票 → 実装 → 関門 → マージまで回し、 利用者が席を外していても止まらずに進めるための使い方です。 dev-loop は「1 Issue = 1 周」のスキルなので、オートクルーズはその周を束ねる運用です。 回す Issue を親 Issue のチェックリストに書いておき、/dev-loop:cruise <親 Issue> で起動します。

規範はスキルのディレクトリにあります

このページは部品の場所と使う順番の案内です。各部品の決まり(いつ書くか・どこで止まるか・何を守らないか)は スキル本文と references/、 スクリプトの docstring を正とします。ここに書き写すと片方だけが古くなるので、要点しか書いていません。

部品をそろえて通しで回した実績は、まだありません

部品は #389 から分けた Issue で入りました (台帳・実装役の委譲文・積んだ周・マージ・不在の線・環境点検・直す線)。 ただし、入った部品だけで複数の Issue を最後まで回したことは、まだありません。

389 のもとになった運用は、部品が入る前に親セッションが手で組み立てたものです。

最初は依存の少ない 2〜3 件で試し、台帳と計画ファイルを見ながら進めてください。

部品の一覧

部品 置き場所(スキルの base ディレクトリから) 役割
入口 ../cruise/SKILL.md・../cruise/scripts/parent-issue.py 親 Issue の一覧を読み、確かめてから台帳を作る。起動し直すと台帳から再開する
台帳 scripts/ledger.py・references/ledger.md Issue の依存と状態をファイルに持つ。再開の入口
実装役の委譲文 prompts/implementer.md 実装役(Agent)に渡す文面のテンプレート
積んだ周(stacked) references/stacked.md 未マージの下の周の上で、上の周を先に始める
マージ scripts/merge-pr.py CI 待ち → squash → worktree の撤去 → Issue が閉じたかの確認
不在の線 references/absent-lines.md 利用者がいないとき、止まる代わりに進んでよい範囲
環境点検 scripts/check-unattended-env.py 起動時に、周で使う操作の許可・止まりうる操作・親の起動場所を読むだけで点検する。席を外すなら自動継続・通知なども
直す線 references/fix-line.md 関門の指摘をどこまで周の中で直すか

スキルの base ディレクトリは、プラグインで入れていれば ~/.claude/plugins/cache/claude-code-setup/dev-loop/<版>/skills/dev-loop、 scripts/link-skills.sh で張っていれば ~/.claude/skills/dev-loop です。 キャッシュには古い版も残るので、<版> は下の「版を確かめる」で読み込まれている版にします。 スキルを起動すると、親セッションには base ディレクトリが渡されます。

0. 版を確かめる

部品がそろうのは dev-loop 1.55.0 からで、積んだ周のマージの歯止め(#426)が 入ったのは 1.56.0、起動のコマンド /dev-loop:cruise(#446)が 入ったのは 1.57.0、親 Issue の線(cruise: の行。#458)が入ったのは 1.58.0、周の途中で見つかった課題を台帳に足す線(#464)が入ったのは 1.59.0 です。 1.55.0 より前の版には、台帳も不在の線も入っていません。

claude plugin list --json                                 # 読み込まれる版を確かめる
claude plugin update dev-loop@claude-code-setup           # 古ければ上げる(そのあと再起動)

更新が届かない形と確かめ方は、プラグイン一覧の「更新のしかた」を正とします。

1. 対象リポジトリに宣言を書く(席を外す前)

不在のあいだに進めてよい範囲は、対象リポジトリの .claude/dev-loop.md に書きます。 PR を通る場所なので、許可の範囲が利用者の目を通ります。

不在の線: 仕様の穴 = 推奨で決めて起票
不在の線: 実機確認 = Refs でマージ
不在の線: マージ = 関門を通ればマージ
直す線: 既定
cruise の操作: gh workflow run infra-apply.yml
  • 書かなければ、どの線も「止まる」です。 マージも宣言が無ければしません(PR を出して止まります)。 必要な線だけを書きます。
  • 本番反映(デプロイ・migrate・本番の設定値)は広げられません。 main への push で自動デプロイする リポジトリでは、マージ自体が本番反映に数えられるので、マージ の線も効きません。
  • cruise の操作: は、周で打つ操作のうち既定の点検(git push・gh pr create・gh pr merge・gh pr comment・gh issue create)に 無いものを 1 行 1 コマンドで書きます(本番反映の口など)。起動時の点検がその許可を見ます。利用者が居る cruise でも書いておきます。
  • 値の一覧と、それぞれの線で何が起きるかは references/absent-lines.md を、直す線 は references/fix-line.md を正とします。

2. 環境を点検する(起動時に 1 度)

python3 <スキルの base ディレクトリ>/scripts/check-unattended-env.py --cruise            # 席を外すとき
python3 <スキルの base ディレクトリ>/scripts/check-unattended-env.py --cruise --present  # 居るとき

cruise は台帳を作ったあと、--absent に依らずこれを回して結果を見せます。 利用者が居ても、権限の拒否や確認で 周が止まり、操作を待つことになるためです(#466)。

  • 許可ルール——既定の操作と cruise の操作: で宣言した操作が allow に当たるか。
  • 止まりうる操作——自動モードの分類器と worktree 隔離のガードは settings に現れないので、許可があっても止まりえます。 起動時に操作ごとに選びます: 許可を足す/その操作だけ自分で打つ(台帳に残り、周はその操作の手前で「操作待ち」になって 依存しない次の周へ進みます)/その周を cruise の外に出す。
  • 親の起動場所——cruise の親は、メインの作業ツリーから worktree に入らずに起動するのが既定です。 worktree の中から起動すると、別の worktree・別のリポジトリへの操作がガードに拒まれます。
  • 席を外すとき(--present なし)は、利用上限での自動継続・質問の待ち・通知・スリープも読みます。

足りないものと直し方を出します。直すのは利用者です(スクリプトは書き換えません)。

通知は、設定が正しくても届かない形があります。iPhone をいまのセッションにつなぎ(/remote-control)、 端末を操作していない状態で試しに送って確かめます。手順は リモートコントロールの設定手順(不在中の運用)と、 スキル本文の「待ち時間・定時処理は別スキル」を正とします。

利用上限で止まったことをその場で記録・通知したいなら、StopFailure の hook を user の settings に足します (利用上限の停止をその場で記録する。登録は利用者が行います。 上限で実際に発火するかは確かめていません)。下の「利用上限で止まったとき」の自動継続の確認 (#456)を取りこぼさないためのものです。

3. 親 Issue に一覧を書いて起動する

回す Issue を、親 Issue(どの Issue でもよい)の本文にチェックリストで並べます。依存は (depends: …) で書きます。

- [ ] #12
- [ ] #13 ログイン画面 (depends: #12)
- [ ] #14 (depends: #12, #13)
- [x] #11
  • [x] の行は済んだものとして扱い、台帳に入れません。それへの依存は満たされたと読みます。
  • #番号 で始まらないチェックボックス(受入基準など)は台帳に入れず、起動時の確認に「読み飛ばした行」として並びます。 # の書き忘れはここで気づけます。
  • 依存の書き方を誤った行((depends: …) の外に「depends」「依存」や #番号 がある、など)や、閉じていないコードフェンス・行頭から始まって閉じない HTML コメントがあると、台帳を作らずに止まります。
  • コードフェンスと HTML コメント(<!-- … -->)の中は読みません。引用(>)の中の行は「読み飛ばした行」に並びます。
  • チェックリストの行が 1 本も無い Issue は親 Issue として扱いません(1 件だけなら /dev-loop:dev-loop <番号> で回します)。

周の途中で訊く判断を、親 Issue に書いておく(線)

同じ親 Issue に cruise: の行を書くと、周ごとに訊かれる判断を起動時に 1 度だけ確かめて、各周へ渡せます。

cruise: 仕様の穴 = 推奨で決めて起票
cruise: 直す線 = 既定
  • 起動時の確認に、書いた線と「書いていない」線が並びます。 書いていない線は台帳に残らず、--absent の周なら「1. 対象リポジトリに宣言を書く」の 不在の線: の宣言、無ければ既定(止まる)になります(直す線 は下のとおり起動時に訊かれます)。 確かめた線は台帳に残り、Issue の本文をあとで書き換えても、確かめ直すまでは台帳の値が使われます。
  • 確かめた 仕様の穴 と 直す線 は、利用者が居る周(--absent なし)でも効きます——仕様の穴 = 推奨で決めて起票 なら、 訊かずに推奨で決めて確認の Issue を立てて進みます(直す線 は周ごとに訊かなくなるだけです)。 実機確認 と マージ は --absent の周だけに効きます。.claude/dev-loop.md の 不在の線: の宣言も --absent の周だけに効きます。
  • 直す線 をどこにも書いていなければ、起動時に 1 度だけ訊かれます(周ごとには訊きません)。
  • 周の途中の課題 = 台帳に足して直す にすると、周の途中で見つかった課題も同じ cruise の中で直します(書いていなければ起動時に訊かれます。既定は 外に出す)。 各周はマージの前に、関門の残課題・狭いパスの指摘・仕様の穴・範囲の外にした機能・利用者の判断が要る行を振り分け、 実物で失敗を示せる行だけを Issue にして台帳に足します(依存は元の周。台帳の「出所」の列に、どの周のどの関門の行かが残ります)。 利用者の判断が要る行は止めておき、居るときは周の合間にまとめて訊かれます。--absent なら訊かずに、終えるときに渡されます。 元の周のマージの判断(狭いパスの指摘は人が決める、など)は変わりません。振り分けの決まりは references/found-lines.md を正とします。
  • 本番反映 の行は無視されます(広げられません)。書けない値や同じ線の 2 行は、台帳を作らずに止まります。
  • 線の意味と、各周がどの順で読むか(台帳 → .claude/dev-loop.md → 既定)は references/absent-lines.md の「cruise で確かめた線」 を正とします。 書式の決まりは parent-issue.py の docstring を正とします。

メインの作業ツリーで Claude Code を起動し、親 Issue の番号で起動します。

/dev-loop:cruise 50            # 居るとき(途中で訊きながら進む)
/dev-loop:cruise 50 --absent   # 不在で回す
  1. 取り出した一覧と依存(と読み飛ばした行・線)が表示されるので、確かめて答えます。 親 Issue の本文は誰でも書き換えられる入力として扱うので、 --absent を付けても、ここだけは起動の時点で訊かれます。確かめた後に本文が書き換えられていたら、台帳は作られません。
  2. 台帳が作られ、着手できる Issue から順に dev-loop の周として回ります。 台帳は <メインの作業ツリー>/.claude/plans/cruise-issue-<親>.json に置かれます。 各周は通常の dev-loop と同じで、Verifier と /code-review を 2 パスで打ち切るのもオートクルーズでも同じです。 台帳は周を束ねる道具で、周を軽くする道具ではありません。
  3. --absent を付けると、途中の問い(直す線・割り目・起票の承認)を訊かずに進みます。 進めてよい範囲は確かめた線と「1. 対象リポジトリに宣言を書く」の宣言だけで決まり、--absent は範囲を広げません。 マージは マージ の線を宣言していれば行い、無ければ PR を出したところで止まって、依存していない別の Issue へ進みます。

起動の手順の決まりは cruise スキルの本文 を正とします。

4. 依存先がマージ待ちのうちに始める(積んだ周)

依存先の PR がまだマージされていなくても、上の周が使う部分(API・型など)が下の関門を通っていれば、 下のブランチの上に積んで先に始められます。

  • 積むかどうかは人間が決めます。 不在のあいだに積んでよいかは、スキルは決めていません。 積ませたいなら、指示の中で「#14 は #13 の PR に積んで始めてよい」と明示してください。
  • 下の周がマージされたら、上の周を既定ブランチの上に載せ替えてからマージします。 merge-pr.py は載せ替えていない積んだ周の PR を止めますが、見分けられない形があります。
  • 手順は references/stacked.md を正とします。

5. 再開する(タイマー・/clear・別セッション)

同じ引数で起動し直せば、台帳から再開します(台帳は作り直しません)。親 Issue に後から足した Issue は名指しされます——台帳に足すかは利用者が決めます(自動では足しません)。

/dev-loop:cruise 50 --absent   # 前と同じ引数で

周を重ねると親セッションの文脈が積み上がるので、周と周の間で /clear して起動し直すのも同じ手です。 台帳の中身は ledger.py show issue-<親> でも見られます。

  • 終了コード 4(判定できなかった)なら再開しません。 台帳が読めないことを「全部済んだ」と読まないためです。
  • 進行中の Issue は、台帳の値ではなく実物(gh pr view・git worktree list)で確かめてから続けます。 各周の続きは、その周の計画ファイルの再開点から始めます。
  • 着手できるものも進行中のものも無いのに「すべてマージ済みか取り下げ」と出ていなければ、どこかで止まっています。 止まった Issue の note に理由が書かれています。

389 のもとになった運用では、30 分おきのタイマー(CronCreate)に台帳を読ませて再開していました。

タイマーを張るかどうかは利用者が決めます(スキルは自分で張りません)。張るなら、タイマーに渡すプロンプトも同じ引数の起動にします。

利用上限で止まったとき

autoContinueAtUsageLimit: true だけで続くとは、記録からは言えません。 下の表のとおり、待ちを張らなかった停止(理由は記録に残りません)と、 Claude Code が終わって消えた待ちがあります。一方で、張った待ちが予告の時刻まで放っておかれたのに自動継続しなかった例のうち、 理由が分かるのは取り消された 2 件だけで、残る 1 件は理由が分かりません——根拠は数件です。 不在で回すなら、タイマーを保険として張るかを考えてください(張るかは利用者が決めます)。

手元 1 台のトランスクリプト(2026-08-27〜10-23・main-chain)を scripts/count-usage-limit-resumes.py で数えた結果です(#454):

待ち
上限で止まった待ち 68
うち自動継続の待ちを張った(continuing automatically at … の予告が出た) 65
 予告の時刻の 1 分後に自動継続した 8
 予告の時刻より前に、人間の入力かローカルコマンドが来た 51
 予告の時刻の後、自動継続より先に人間が来た 3
 Claude Code が待ちの間に終わって取り消された 2
 何も来ずに記録が終わった 1
うち待ちを張らなかった(3 件とも週の上限 seven_day) 3
  • 張った待ちで、人間が予告の時刻まで来なかったものは 14 件で、自動継続したのは 8 件です。 残りは人間が数十秒先に来た 3 件・取り消された 2 件・理由の分からない 1 件です
  • 待ちを張らなかった停止があります——張らなかった 3 件は、どれも週の上限(seven_day)でした。 ただし週の上限で止まった 4 件のうち 1 件は張っているので、週の上限なら張らない、とは言えません (張らなかった理由は記録に残りません)
  • Claude Code が終わると待ちは消えます(Automatic continue cancelled · Claude Code exited during the wait)
  • どの層の設定から待ちを張ったのかは分かりません——設定の履歴は記録に残りません。 数えた日(2026-10-27)の手元の user の settings に autoContinueAtUsageLimit はありませんでしたが、 それぞれの停止の時点の値は分かりません。数え方と、数えないものはスクリプトの docstring を正とします
  • 上限を狙って起こす手段が無いので、user の層に true を明示したうえで自動継続した例は、まだ取れていません(#454)

6. 戻ってきたら見るもの

  • 台帳——ledger.py show issue-<親> で、どれがマージ済みで、どれが止まっているか(note に理由)。
  • 利用者の操作待ち——台帳の「利用者の操作待ち」に、打ってほしいコマンドが周ごとに載っています。 打ったあとで同じ引数で起動し直すと、cruise が実物を確かめてからその周の続きを回します。
  • 各 PR のコメント——関門の残課題、名指しの未証明、訊かずに進めた箇所が書かれています。 マージ の線でマージした PR も、戻ってから PR コメントで確かめる前提です。
  • 要確認 ラベルの Issue(ラベルが無いリポジトリでは題の先頭が 要確認:)——仕様の穴 の線で、 推奨で決めて進めた判断です。閉じずに残してあります。cruise から立てたものは台帳の「要確認」の列に番号が載り、 終えるときに開いているものが一覧で渡されます。
    • 承認するなら、その Issue を閉じます。
    • 直すなら、本文の「別の値を選んだらどこを直すか」から実装の Issue を立てて親 Issue のチェックリストに足し、 確認の Issue はその番号を書いて閉じます。同じ引数で起動し直すと、足した Issue が名指しされます(台帳に足すかは利用者が決めます)。
  • 開いたままの元の Issue——実機確認 の線で Refs のままマージした Issue です。実機で確かめてから閉じます。

関連