Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions docs/autopilot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ autopilot は、複数の GitHub Issue を Claude が**並行**して
専用 **GitHub Projects v2「Autopilot」** のフィールドで一元管理する。

設計の出発点となった課題と意思決定の経緯は Issue #760(EPIC)に集約されている。
スキル/Runner が従う詳細な契約は [`autonomous-contract.md`](./autonomous-contract.md) を参照。
プロンプト/Runner が従う詳細な契約は [`autonomous-contract.md`](./autonomous-contract.md) を参照。

---

Expand Down Expand Up @@ -41,7 +41,7 @@ autopilot は、複数の GitHub Issue を Claude が**並行**して
| **Claude runner** | 対話 Claude Code を tmux で起動し send-keys で駆動、watchdog で監視 | `tools/autopilot/src/runner.js` |
| **Web モニタ** | item 一覧・状態・ログ閲覧・手動操作(daemon が `GET /` で配信) | `tools/autopilot/src/monitor.js` |
| **CLI** | 単一フェーズを単一 Issue で実行(動作確認・ドライラン) | `tools/autopilot/bin/autopilot` |
| **フェーズ・スキル** | 各フェーズの「頭脳」。非対話で1フェーズを遂行 | `.claude/skills/autopilot-*` |
| **フェーズ・プロンプト** | 各フェーズの「頭脳」。非対話で1フェーズを遂行 | `tools/autopilot/prompts/autopilot-*` |
| **worktree** | Issue ごとの隔離作業場(軽量・即作成) | `bin/autopilot-worktree` |

> daemon は常駐の単独プロセスとして起動する。並行数は設定可能(既定 2、必要に応じて増やす)。
Expand Down Expand Up @@ -74,12 +74,12 @@ No Status(未設定) → Backlog / Icebox → Sprint Backlog(autopilot キュー
> 正規化して扱う(`tools/autopilot/src/phases.js` の `status || 'New Item'`)。本ドキュメントの
> 表記は UI に合わせて「No Status」で統一する。

### AI Status — AI 専用の細フェーズ(各値 ≈ 1 スキル
### AI Status — AI 専用の細フェーズ(各値 ≈ 1 プロンプト

人間は Status を見れば十分。AI Status は daemon が「次に呼ぶスキル」を引くための内部状態で、
人間は Status を見れば十分。AI Status は daemon が「次に呼ぶプロンプト」を引くための内部状態で、
Issue を状態の正とすることで daemon が落ちても現在地が分かる。

| AI Status | 対応スキル | 主な Status |
| AI Status | 対応プロンプト | 主な Status |
|---|---|---|
| Triaging | autopilot-triage | No Status |
| Understanding | autopilot-understand | No Status / Backlog(EPIC) |
Expand Down Expand Up @@ -174,10 +174,10 @@ daemon は **構造化シグナル(approve/changes-requested)で機械的に
`autopilot-address-review` を起動する**(`phaseForItem` が Review 解除 → `address-review`)。

approve でも本文に改善依頼が書かれていたり、"changes requested" でも実質 LGTM だったりと、
自由文の意図は構造化シグナルでは判定できない。そこで**判断はスキル側に置く**: address-review が
自由文の意図は構造化シグナルでは判定できない。そこで**判断はプロンプト側に置く**: address-review が
PR の **diff と全コメント(Issue/レビュー本文/インライン)**を読んで分類する。

| スキルの分類(HITL 解除後) | 対応 |
| プロンプトの分類(HITL 解除後) | 対応 |
|---|---|
| 質問 | bot で返信(必要ならコード修正)→ 再レビューへ |
| 改善依頼 / 変更要求 | worktree で修正・push → 再レビューへ |
Expand All @@ -189,7 +189,7 @@ PR の **diff と全コメント(Issue/レビュー本文/インライン)**
で判定)。daemon が両面を atomic に同期する(後述「PR 側の状態可視化」)ので、人間は目の前の
PR ラベルを外すだけで差し戻せる。
- address-review は **既存 PR ブランチ**で作業する(daemon が worktree を `--pr` で用意)。
- **コンフリクトは autopilot で解消しない**(rebase/merge コンフリクトは人間の役割)。スキルは
- **コンフリクトは autopilot で解消しない**(rebase/merge コンフリクトは人間の役割)。プロンプトは
解消を試みず HITL で人間に渡す。

---
Expand Down Expand Up @@ -227,9 +227,8 @@ LLM は in-container で回さず、**純粋な I/O + 文字列テンプレー
- **NG**: ホスト/人間が PR に NG をコメントし `🙋 HITL` を外す → daemon が **DoD 解除 → address-review**
を起動(Review と対称。`phaseForItem` が DoD 解除 → `address-review`、OR セマンティクスも同じ)。

> 既存の `autopilot-verify` スキル(`.claude/skills/`)は手動 inject 用に残してよいが、自動経路は
> この daemon 生成を使う(スキル本体は `.claude/` にあり、書き換えると autopilot 自身の implement が
> 確認プロンプトで止まるため・#820/#821)。
> 既存の `autopilot-verify` プロンプト(`tools/autopilot/prompts/`)は手動 inject 用に残してよいが、
> 自動経路はこの daemon 生成(`applyDodHandoffs`)を使う(#821)。

---

Expand Down Expand Up @@ -292,7 +291,7 @@ watchdog が次を処理する:

## 自律コントラクト

すべての `autopilot-*` スキルは [`autonomous-contract.md`](./autonomous-contract.md) に従う。要点:
すべての `autopilot-*` プロンプトは [`autonomous-contract.md`](./autonomous-contract.md) に従う。要点:

- **対話的に人間へ質問しない**。判断が要れば bot で Issue/PR にコメントし `AUTOPILOT_HITL` で終了。
- 終了直前に `AUTOPILOT_RESULT_FILE` へ JSON を書き、pane に signal トークン(`AUTOPILOT_DONE` /
Expand Down Expand Up @@ -424,11 +423,11 @@ cd tools/autopilot && node --test # 純粋ロジックの unit テスト(
| パス | 内容 |
|---|---|
| `docs/autopilot/README.md` | 本ドキュメント(機能全体の入口) |
| `docs/autopilot/autonomous-contract.md` | スキル/Runner の契約 |
| `.claude/skills/autopilot-*/` | 各フェーズのスキル |
| `docs/autopilot/autonomous-contract.md` | プロンプト/Runner の契約 |
| `tools/autopilot/prompts/autopilot-*/` | 各フェーズのプロンプト |
| `bin/autopilot-worktree` | 軽量 worktree スクリプト |
| `tools/autopilot/src/contract.js` | 番兵/結果ファイルの検証(純粋) |
| `tools/autopilot/src/phases.js` | フェーズ↔スキル、結果→フィールド意図、watchdog 判断、HITL 解除、merge-progression、PR 投影(純粋) |
| `tools/autopilot/src/phases.js` | フェーズ↔プロンプト、結果→フィールド意図、watchdog 判断、HITL 解除、merge-progression、PR 投影(純粋) |
| `tools/autopilot/src/project.js` | GitHub Projects v2 + Issue/PR ラベル・Draft・sticky への gh ラッパ |
| `tools/autopilot/src/runner.js` | tmux runner + watchdog |
| `tools/autopilot/src/daemon.js` | 常駐 daemon(ポーリング・ディスパッチ・HTTP 制御・merge-progression) |
Expand All @@ -448,13 +447,13 @@ cd tools/autopilot && node --test # 純粋ロジックの unit テスト(

## 運用上の注意(実地で得た知見)

- **worktree のスキル可用性**: `autopilot-*` スキルが対象ブランチに存在する必要がある(develop に
- **worktree のプロンプト可用性**: `autopilot-*` プロンプトが対象ブランチに存在する必要がある(develop に
マージ済みなら worktree でも解決可能)。
- **非対話権限**: runner は権限プロンプトで止まらない設定(許可ツール指定など)で claude を起動する。

---

## ライセンス

autopilot のツール群(`tools/autopilot/**`)と autopilot スキル(`.claude/skills/autopilot-*/**`)は、
autopilot のツール群(`tools/autopilot/**`)と autopilot プロンプト(`tools/autopilot/prompts/autopilot-*/**`)は、
リポジトリ全体の AGPL-3.0 ではなく **MIT ライセンス**とする。詳細は `tools/autopilot/LICENSE` を参照。
39 changes: 22 additions & 17 deletions docs/autopilot/autonomous-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@
> **🆕 Smalruby 独自** — autopilot(Claude による Issue ライフサイクル自律オーケストレーター)の
> 中核規約。upstream には存在しない。設計の出発点は Issue #760。

このドキュメントは、autopilot の各**フェーズ・スキル**(`autopilot-triage` / `autopilot-understand` /
このドキュメントは、autopilot の各**フェーズ・プロンプト**(`autopilot-triage` / `autopilot-understand` /
`autopilot-decompose` / `autopilot-implement` / `autopilot-review` / `autopilot-address-review` /
`autopilot-verify`)と、それらを tmux 上で駆動する **Claude Runner** の間の**契約**を定める。

すべての `autopilot-*` スキルは本コントラクトに従う。スキルの冒頭は必ず
すべての `autopilot-*` プロンプトは本コントラクトに従う。プロンプトの冒頭は必ず
「**Follow the autopilot autonomous contract: `docs/autopilot/autonomous-contract.md`**」を宣言する。

> **これらは `tools/autopilot/prompts/<phase>.md` に置く Markdown プロンプトであり、Claude Code の
> Skill ではない**(`.claude/skills/` には置かない)。開発者が誤って `/autopilot-*` としてスラッシュ
> 起動すると期待どおり動かないため、Skill として登録しない。Runner は各プロンプトファイルを
> 対話 Claude に **Read させて手順に従わせる**(起動メッセージは `phases.js` の `phasePromptCommand`)。

---

## 1. 最重要不変条件: 対話的に人間へ質問しない

autopilot のスキルは、**人間が enter を押すのと同じ形で tmux 経由に起動された対話 Claude Code**
autopilot のプロンプトは、**人間が enter を押すのと同じ形で tmux 経由に起動された対話 Claude Code**
の中で動く。したがって次を**絶対**に守る:

- **`AskUserQuestion` を使わない。** いかなる対話的プロンプト・選択 UI も出さない。
Expand All @@ -41,7 +46,7 @@ tmux pane のテキストは長い行が**折り返される**ため、JSON を
### 2.1 ペイロードファイル

Runner は環境変数 **`AUTOPILOT_RESULT_FILE`**(書き込み先の絶対パス)を渡す。
スキルは**終了直前に、まずこのファイルへ単一の JSON オブジェクトを書き込む**。
プロンプトは**終了直前に、まずこのファイルへ単一の JSON オブジェクトを書き込む**。

### 2.2 pane signal トークン(最後の出力・1 行・折り返さない短語)

Expand All @@ -62,7 +67,7 @@ Runner はこの短語を pane で検出してから `AUTOPILOT_RESULT_FILE` を
| key | 型 | 説明 |
|---|---|---|
| `issue` | number | 対象 Issue 番号 |
| `phase` | string | 実行したスキル(`triage`/`decompose`/`implement`/`review`/`address-review`/`verify`/`understand`) |
| `phase` | string | 実行したプロンプト(`triage`/`decompose`/`implement`/`review`/`address-review`/`verify`/`understand`) |
| `signal` | string | `done` / `hitl` / `error`(pane トークンと一致させる) |
| `summary` | string | 人間向け 1 行要約 |

Expand Down Expand Up @@ -110,24 +115,24 @@ AUTOPILOT_DONE
## 3. 状態の書き込み責務(単一ライター原則)

- **Project フィールド(Status / AI Status / Size / Kind ...)と HITL(`🙋 HITL` ラベル)の書き込みは
daemon(または CLI)が行う。** スキルは**結果ファイルで「こうしてほしい」という意図を伝えるだけ**で、
daemon(または CLI)が行う。** プロンプトは**結果ファイルで「こうしてほしい」という意図を伝えるだけ**で、
Project やラベルを直接書き換えない(二重ライターによる競合を避ける)。HITL は Project フィールドではなく
`🙋 HITL` ラベルで一本化する(#813。理由: PR は Project フィールドを持てないため)。
- **GitHub の Issue / PR への副作用**(コメント投稿・PR 作成・sub-issue 作成・コミット)は
**スキルが行う**。これらは Project 状態とは別物。
- daemon が落ちても **Issue / PR / Project が状態の正**。スキルは再実行されうる前提で冪等にする(次節)。
**プロンプトが行う**。これらは Project 状態とは別物。
- daemon が落ちても **Issue / PR / Project が状態の正**。プロンプトは再実行されうる前提で冪等にする(次節)。

---

## 4. 冪等性・再入可能性

スキルはクラッシュ・再起動後に**同じ Issue に対して再実行されうる**。よって:
プロンプトはクラッシュ・再起動後に**同じ Issue に対して再実行されうる**。よって:

- 副作用を出す前に**現状を確認**する(既に同種コメントを出していないか、PR が既にあるか、
sub-issue を既に作っていないか)。
- 重複投稿・重複 PR・重複 sub-issue を作らない。判定には GitHub 上の既存状態を使う。
- 途中再開時、Runner は**再投入プロンプトに強めの no-interview 注意**を前置する(課題2 対策)。
スキルはこの前置きがある前提で、同じインタビューで再停止しないこと。
プロンプトはこの前置きがある前提で、同じインタビューで再停止しないこと。

---

Expand All @@ -140,7 +145,7 @@ AUTOPILOT_DONE

---

## 6. Runner が渡す環境(スキルが参照してよい
## 6. Runner が渡す環境(プロンプトが参照してよい

| 環境変数 | 内容 |
|---|---|
Expand All @@ -167,7 +172,7 @@ PR を見ただけで連携 Issue の状態が分かるよう、**daemon が PR
| **sticky ステータスコメント** | bot が1つのコメントを編集し続け、連携 Issue の Project 状態(Status / AI Status / HITL / Size)を投影 | フェーズ遷移ごとに更新 |

- 専用の「作業中」ラベルは作らない(**Draft** が「AI 作業中・触らないで」を兼ねる)。
- スキルは PR を作るとき **Draft で作成**し、HITL に渡すフェーズ末で **Ready + `🙋 HITL`** を要求する
- プロンプトは PR を作るとき **Draft で作成**し、HITL に渡すフェーズ末で **Ready + `🙋 HITL`** を要求する
(実際のラベル付与・Draft 切替・sticky 更新は daemon が結果ファイルの意図を見て行う)。

### HITL は `🙋 HITL` ラベルに一本化(#813)
Expand All @@ -184,10 +189,10 @@ Issue/PR の両面を賄え、成果物ページにも見える。ラベルは I
→ 人間はレビュー中に**目の前の PR の `🙋 HITL` ラベルを外すだけ**で autopilot に差し戻せる。
PR の無い段階(triage/decompose 等)では PR ラベルは非適用(Issue ラベルのみで判定)。

### DoD は daemon が headful 引き継ぎを生成する(スキル run ではない・#821)
### DoD は daemon が headful 引き継ぎを生成する(プロンプト run ではない・#821)

DoD(実機ブラウザでの最終確認)は**コンテナ内 daemon が headless で実ブラウザを動かせない**ため、
**スキル run ではなく daemon の tick ステップ**(`applyDodHandoffs`)として扱う。`Status=DoD` の leaf に
**プロンプト run ではなく daemon の tick ステップ**(`applyDodHandoffs`)として扱う。`Status=DoD` の leaf に
対し、daemon が「プレビュー URL + Issue の DoD チェックリスト + 定型 headful 手順 + 報告の出口」を
**テンプレート生成**して `autopilot:dod-handoff` マーカー付きコメントを PR に投稿する(child Claude を
起動せず、純粋な I/O + 文字列テンプレートで完結。冪等)。これを**ホスト側の Claude(headful Playwright)**
Expand All @@ -197,12 +202,12 @@ DoD(実機ブラウザでの最終確認)は**コンテナ内 daemon が hea
- **NG** → ホスト/人間が PR にコメントし `🙋 HITL` を外す → **DoD 解除 → `address-review`**(Review と対称。
`phaseForItem` の DoD 解除パス。OR セマンティクスも同じ)。

`autopilot-verify` スキルは手動 inject 用に残置(自動経路は使わない)。詳細は
`autopilot-verify` プロンプトは手動 inject 用に残置(自動経路は使わない)。詳細は
[`README.md`](./README.md) の「DoD — headful 検証の引き継ぎ生成」。

---

## 8. スキル実装のチェックリスト
## 8. プロンプト実装のチェックリスト

- [ ] 冒頭で本コントラクトに従うと宣言している
- [ ] `AskUserQuestion` を一切使っていない
Expand All @@ -216,5 +221,5 @@ DoD(実機ブラウザでの最終確認)は**コンテナ内 daemon が hea

## ライセンス

autopilot のツール群(`tools/autopilot/**`)と autopilot スキル(`.claude/skills/autopilot-*/**`)は、
autopilot のツール群(`tools/autopilot/**`)と autopilot プロンプト(`tools/autopilot/prompts/autopilot-*/**`)は、
リポジトリ全体の AGPL-3.0 ではなく **MIT ライセンス**とする。詳細は `tools/autopilot/LICENSE` を参照。
1 change: 0 additions & 1 deletion tools/autopilot/LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ MIT License
This license applies to the Smalruby autopilot tooling, specifically:

- tools/autopilot/**
- .claude/skills/autopilot-*/**

These files are licensed under the MIT License below, which takes precedence
over the repository's top-level AGPL-3.0 license (LICENSE) for this subtree.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
---
name: autopilot-address-review
description: autopilot のレビュー対応フェーズ。人間が HITL を解除した PR について diff と全コメントを理解し、質問・改善依頼に対応し、再び人間に渡す。autopilot Runner から非対話で起動される。
argument-hint: "[issue number]"
disable-model-invocation: true
---

# /autopilot-address-review — Review handling phase

**Follow the autopilot autonomous contract: `docs/autopilot/autonomous-contract.md`.**
対話的に質問しない。終了時に `AUTOPILOT_RESULT_FILE` へ JSON を書き、pane に signal トークンを出す。

対象 Issue は `$ARGUMENTS` または `AUTOPILOT_ISSUE`。人間が **`🙋 HITL` を外した(差し戻した)** PR を扱う。
対象 Issue は 環境変数 `AUTOPILOT_ISSUE`。人間が **`🙋 HITL` を外した(差し戻した)** PR を扱う。

このフェーズは Review 解除時の**唯一の入口**(#815)。daemon は approve / changes-requested などの
構造化シグナルで分岐せず、解除されたら必ずこのスキルを起動する。**何をすべきかはここで判断する**:
Expand Down Expand Up @@ -110,4 +104,4 @@ echo AUTOPILOT_HITL

## License

This skill is part of the Smalruby autopilot and is licensed under the **MIT License** (not the repository's AGPL-3.0). See `tools/autopilot/LICENSE`.
This phase prompt is part of the Smalruby autopilot and is licensed under the **MIT License** (not the repository's AGPL-3.0). See `tools/autopilot/LICENSE`.
Loading