write-plan について
write-planは、承認済みのbrainstorm-beagle仕様書を、エンジニアや後続エージェントが実行できる実装計画に変換するスキルです。プロジェクト規約とファイル構成を確認し、細かなテスト駆動タスクを作成しますが、計画の実行や製品コードの変更は行いません。
主な機能
- 01brainstorm-beagleの仕様書が必須
- 02プロジェクト規約と関連コードを確認
- 03タスク作成前にファイル構成を整理
- 04TDDの手順にタスクを分解
- 05未検証の前提にスパイクを追加
- 06仕様書に照らして計画をレビュー
活用シーン
- 01承認済み仕様書から実行計画を作成
- 02リポジトリ規約に沿う作業を計画
- 03スパイクで検証すべきツールの挙動を特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ existential-birds/ beagle --skill write-planインストール後、Claude Code で/write-planを入力して読み込まれたか確認します。
同梱ファイルreferences/plan-reviewer.mdreferences/plan-template.md
詳細
Write Plan:仕様から実装計画へ
brainstorm-beagle の仕様を、エンジニア(または後続のエージェント)が意図を再確認せずにタスクごとに実行できる、包括的な実装計画に変換します。
出力は、仕様と同じコンセプトフォルダー内の .beagle/concepts/<slug>/plan.md に保存する、単一の Markdown 計画ドキュメントです。この計画では HOW(ファイル構成、タスクの分割、正確なコード、正確なコマンド)を扱います。WHAT と WHY はすでに仕様で定義されています。
<hard_gate>
.beagle/concepts/<slug>/spec.md に brainstorm-beagle の仕様が存在するまで、計画の作成を始めてはいけません。存在しない場合は作業を止め、まず brainstorm-beagle を利用するようユーザーに案内してください。仕様を省略すると、検討されていない前提を組み込んだ計画ができてしまいます。仕様は、このスキルが計画を立てる際の基準となるものです。
</hard_gate>
ワークフロー
以下の手順を順番に完了します。
- 仕様を見つける —
.beagle/concepts/<slug>/spec.mdを探します。見つからない場合は作業を止め、brainstorm-beagle を利用するよう案内します - 仕様を読む — すべてのセクションを確認します。言い換えたり、要件を要約して省略したりしてはいけません
- プロジェクトの規約を読む — プロジェクトの規約(ルートおよびネストされた
AGENTS.mdやCLAUDE.mdなど)を確認し、計画が遵守すべきテスト、コメント、アーキテクチャのルールを把握します - 関連コードを調べる — 計画で変更するファイルや、パターンの参考にする既存ファイルを読みます。構成を推測してはいけません
- ファイル構成を設計する — タスクを書く前に、作成または変更するファイルを整理します
- タスクに分解する — 各タスクは、正確なパスとコードを含む、2~5 分で完了できる TDD 主導の小さな手順にします
- セルフレビューする — 仕様との整合性を確認し、プレースホルダーを洗い出し、型の一貫性を検証します(下記の セルフレビュー を参照)
- 必要に応じてレビューパスを実施する — 長い計画や、なじみのない領域を扱う計画に限ります。エージェントがサブエージェントに対応している場合は、レビュアーのサブエージェントに依頼します。対応していない場合は、同じレビューをその場で実施します。出力は同一です(
references/plan-reviewer.mdを参照) - ドラフトをユーザーに提示する — チャットでドラフトを提示してレビューを受け、必要に応じて修正します
- ディスクに書き込む — ユーザーの明示的な承認を得てから
.beagle/concepts/<slug>/plan.mdに保存します
Spec at .beagle/concepts/<slug>/spec.md? ── No → STOP, route to brainstorm-beagle
── Yes → Read spec + project conventions + relevant code
↓
Design file structure
↓
Decompose into TDD tasks
↓
Self-review → fix inline
↓
(optional) Dispatch reviewer subagent
↓
Present draft → User review
├─ Changes? → Revise
└─ Approved? → Write to plan.md
最終状態は、計画が書き込まれていることです。 このスキルは計画を実行せず、テストを実行せず、本番コードも変更しません。書き込み後、実行引き継ぎプロンプトを生成するかユーザーに尋ねます。生成する場合は subagent-prompt スキル(../../../beagle-core/skills/subagent-prompt/SKILL.md)を読み込み、このセッションでプロンプトを作成します。生成しない場合は、計画の準備ができたことをユーザーに伝えます。
仕様を見つける
デフォルトの入力パスは .beagle/concepts/<slug>/spec.md です。
スラッグの特定優先順位(上から順):
- ユーザーが指定したパスまたはスラッグ(
write-plan auth-rewrite、「.beagle/concepts/foo/spec.mdの仕様を計画して」など) .beagle/concepts/内で最近編集された仕様- 複数の仕様が候補となる場合は、ユーザーに確認します
仕様が見つからない場合:
「
.beagle/concepts/<slug>/spec.mdに brainstorm-beagle の仕様が見つかりません。まず brainstorm-beagle を実行して仕様を作成してから、戻って計画を立ててください。」
作業を進めてはいけません。仕様は基準となるものです。仕様なしで計画を立てると、別の名前で仕様を作り直すことになり、brainstorm-beagle が定めているレビューの段階を省略してしまいます。
スコープの確認
仕様に複数の独立したサブシステムが含まれている場合は、ブレインストーミングの段階で分割しておくべきです。分割されていない場合は、作業を止めて分割を提案してください。brainstorm-beagle ワークフローには、このための スコープ評価 の手順があります。各計画では、まとまりのある単一のサブシステムについて、動作しテスト可能なソフトウェアを作成する必要があります。
仕様の範囲が広すぎて、1 つのドキュメントで計画できない兆候:
- 共通のコアループがないのに、必須要件が約 15 件を超えている
- 要件が独立したサブシステムにまたがっている(認証、課金、分析など、それぞれ別の計画が必要)
- コアループを 30 秒で説明できない
**対応:**ユーザーに次のように伝えて、分割を提案してください。「この仕様には、まとまりのあるシステムが複数含まれています。brainstorm-beagle の段階で分割し、それぞれのサブ仕様を個別に計画することをおすすめします。そうしますか?それとも、大きな計画を 1 つ作成して進めますか?」
プロジェクトの規約を確認する
タスクを設計する前に、計画に影響するプロジェクトのルールを確認してください。
- リポジトリのルートおよび変更する各サブディレクトリにあるプロジェクトの規約(例:
AGENTS.mdやCLAUDE.md) — テストの階層、コメントの方針、コミットの規約、禁止されているパターン - テストフレームワークとランナー — Cargo、pytest、npm test、mix test など。タスクでは適切なコマンドを使用する必要があります。
- 既存のパターン — コードベースで特定のファイル構成を採用している場合は、それに従ってください。仕様の 制約 と 参照ポイント で指定されていることもよくあります。
プロジェクトの規約ドキュメントで特定の要件(例:「ユーザーに見える機能にはすべて、コンパイル済みバイナリを通じて実行する tier-3 テストが必要」)が定められている場合、計画にはその規則を満たすタスクを含める必要があります。プロジェクトのポリシーに反する計画を黙って作成してはいけません。問題点を明示し、対応してください。
計画を確定する前にスパイクを実施する
ドキュメントだけをもとに作成した計画には、コードベースで最初に試した際に破綻するツールチェーンの前提が組み込まれがちです。計画を確定する前に、「ツール X は動作 Y をサポートする」または「コマンド Z は出力 W を生成する」という主張のうち、このリポジトリにもチームにも動作例がないものをすべて特定してください。これらはそれぞれスパイク候補です。
各スパイク候補について、計画には本文に次の内容を含む Task 0: Spike <claim> を必ず追加してください。
- リポジトリで、計画の以降の作業が依存する標準的なコマンドを、文書化された手順として実行する。
- 実際の出力(成功時の処理と失敗時の動作の両方)を記録する。
- 次のいずれかを行う:仕様の主要な決定がそのまま維持できることを確認する、または他のタスクを実行する前に、具体的な修正案とともに調査結果をユーザーに返す。
仕様の主要な決定が、このリポジトリでチームが検証していないツールの挙動を前提としている場合、Task 0 は必須です。スパイクが必要となる主張の例:
- 「ツール X の
--workspaceフラグを使えば、このリポジトリのマルチバックエンド構成を 1 回の実行で処理できる。」 - 「ライブラリ Y のデフォルトのテスト属性では、本番環境で使うものと同じプール設定が使われる。」
- 「CLI Z のイントロスペクションでは、作成するすべてのクエリ形式を網羅できる。」
- 「マイグレーションフレームワーク W は、新しい DB に対して複数のマイグレーターを並行実行しても冪等に処理できる。」
- **入力形状の前提:**仕様で、上流から入力が形状 X(全体、ソート済み、重複排除済み、完全、検証済みなど)で届くと仮定しているものの、このリポジトリでその形状になることを誰も検証していない。(保持仕様では「ツールの出力は全体が届く」と仮定していましたが、ストリーミングツールではそうなりません。新しいレイヤーが受け取る前に、ローリングバッファによって先頭部分がすでに破棄されていました。)上流データの形状に関する、重要な前提は既定の事実ではなく、スパイク候補です。
スパイクに失敗した場合、または注意点が明らかになった場合は、作業を止めて仕様を修正してください。追加の計画タスクで発見を取り繕ってはいけません。前提どおりに動作しないツールを主要な決定の根拠とする仕様には、さらなる回避策ではなく、ブレインストーミングをもう一度行う必要があります。
このルールは、既存の Assumption Audit よりも厳格です。前提とは「未検証の挙動について推測している」ということです。スパイク候補とは「誰も検証していない挙動を根拠に、仕様で重要な決定を下している」ということです。前者は記録し、後者は実行して確認します。
並行実装ゲート
既存の機能を並行して実装する計画を追加する場合(同じトレイトを介した 2 つ目のデータベースバックエンド、同じ UI の 2 つ目のプラットフォームターゲット、同じサービスの 2 つ目のプロトコルアダプターなど)、計画の最後には、本文が次の内容である最終タスクを必ず追加してください。
- 既存の実装で観測可能な動作を固定する、正式なコントラクトテストスイートを特定します。
- 同じ実行で、そのスイートを両方の実装に対して実行します。
- 観測可能な動作(戻り値、永続化された行、発行されたイベント、エラーのバリアント)がバイト単位で一致することを検証します。内部の構造体レイアウトは対象外です。
- どちらかの実装でコントラクトテストが失敗した場合は、タスクを失敗とします。スイートで差異が確認できる状態のまま、計画を完了と宣言してはいけません。
このタスクは最後のゲートであり、省略できません。これがなければ、「2 つ目のバックエンドを並行して実装する」計画は差異を抱えたままリリースされます。実行者が各バックエンドのタスクを個別に完了と宣言する一方で、両方を検証するコントラクトテストは失敗したまま、見過ごされます。
動作の同等性を検証するゲートは、タスクごとのコントラクトテストとは別のものです。タスクごとのテストは、1 つの実装の動作を固定します。このゲートでは、それらの実装が一致することを証明します。
ファイル構成
タスクを定義する前に、作成または変更するファイルと、それぞれの役割を洗い出します。ここで、分解方針を確定します。
- 明確な境界と適切に定義されたインターフェースを持つ単位を設計します。各ファイルには、明確な責務を 1 つだけ持たせます。
- 一度にコンテキストに収められるコードほど、適切に推論できます。また、ファイルの対象範囲が絞られているほど、編集の信頼性も高まります。多くの処理を抱え込んだ大きなファイルより、規模が小さく、対象を絞ったファイルを優先してください。
- 一緒に変更するファイルは、同じ場所に配置します。技術レイヤーではなく、責務ごとに分割してください。
- 既存のコードベースでは、確立されたパターンに従います。コードベースで大きなファイルを使用している場合、一方的に再構成してはいけません。ただし、変更対象のファイルが扱いにくいほど大きくなっているなら、計画に分割を含めるのは妥当です。
ファイル構成のセクションは計画書自体に記載します。これにより、エンジニア(または次のエージェント)は、個々のタスクを読む前に作業の全体像を把握できます。
細かく分けたタスクの粒度
各ステップは 1 つの作業(2~5 分)にします。
- 「失敗するテストを書く」— ステップ
- 「テストを実行して、失敗することを確認する」— ステップ
- 「テストを通すための最小限のコードを実装する」— ステップ
- 「テストを実行し、成功することを確認する」— ステップ
- 「コミットする」— ステップ
複数の作業をまとめたステップ(「テストと実装を書く」など)は粒度が大きすぎるため、分割してください。動作を抽象的に記述したステップ(「検証を追加する」など)は曖昧すぎるため、コードを示してください。
計画書の形式
references/plan-template.md のテンプレートを使用します。計画書には次のセクションを、この順序で記載します。
- ヘッダー — タイトル、目標、アーキテクチャの概要、技術スタック、仕様書へのリンク
- ファイル構成 — 作成または変更するファイルと、それぞれの役割の一覧
- タスク N ブロック — 作業のまとまりごとに 1 つずつ設け、TDD のステップを含める
- 自己レビューの結果 — 自己レビューを誠実に実施したことを確認する簡潔なメモ
すべての計画書は、次のヘッダーから必ず始めてください(リテラルな Markdown で、角括弧内を記入します)。
# [Feature Name] Implementation Plan
> **Source spec:** `.beagle/concepts/<slug>/spec.md`
> **For downstream agents:** Execute task-by-task. Each task uses `- [ ]` checkboxes for tracking. Do not skip the test-first steps — they catch wiring bugs that pure-logic tests miss.
**Goal:** [One sentence describing what this builds, mirroring the spec's Core Value]
**Architecture:** [2-3 sentences about approach — how the pieces fit together]
**Tech Stack:** [Key technologies/libraries this plan uses]
---
タスクテンプレート
### Task N: [Component Name]
**Files:**
- Create: `exact/path/to/file.ext`
- Modify: `exact/path/to/existing.ext:123-145`
- Test: `tests/exact/path/to/test.ext`
- [ ] **Step 1: Write the failing test**
```
// Show the assertions and the call site under test. The seed/setup
// loops are recovered by the executor from existing types and helpers
// — name a helper (e.g. `seed_entries(&store, id, count)`) but do not
// implement it here.
//
// Target: ~15 lines or less. Assertions pin observable consequence
// (a value, a file, a row, an output the next call would see), never
// dispatch ("the handler was called", "an event was emitted").
```
- [ ] **Step 2: Run test to verify it fails**
Run: `<exact project test command for this one test>`
Expected: FAIL — "<the exact failure message you expect>"
- [ ] **Step 3: Implement against the test**
**Files touched:** `path/to/impl.ext`
**Behavior contract** (what the implementation must satisfy — the executor writes the code):
- [The new/changed behavior bullet 1 — what's different from the reference]
- [The new/changed behavior bullet 2]
- [Up to 5 bullets total; past that, replace with a tighter reference]
**Reference:** `path/to/analog.ext:line-line` — [one-sentence delta: what to mirror, what to change]. Pointers only; do NOT paste the cited code inline. The executor opens the file.
- [ ] **Step 4: Run the new test AND the relevant suite, verify both green**
Run: `<same test command as Step 2>` → Expected: PASS.
Then run: `<the broader test scope this task lives in — the module, the package, the contract suite, whichever covers the surface this task touched>` → Expected: PASS with zero regressions.
A new test that passes while a sibling test silently turns red is a task failure, not a deferred concern. "I only ran the one I wrote" is how a contract test stays red across an entire plan. Specify the exact broader-scope command in this step; do not leave it as "run the suite" — the executor needs a copy-pasteable command.
- [ ] **Step 5: Sweep modified files for leftovers**
Describe sweep targets in plain language: "remove stale references to `<old_name>`, the orphaned `<import>`, and doc-comments describing the old shape." The executor greps for them. Do NOT enumerate line numbers in the plan — they will be wrong by execution time and the executor can find them faster than you can list them. New-file-only and config-only tasks skip this step.
- [ ] **Step 6: Commit**
```bash
git add <specific paths>
git commit -m "<type>(<scope>): <imperative summary>"
```
ステップごとのコード記述:テストは記述し、実装は記述しない
計画の役割は、各タスクの契約を明確に定めることです。テストが契約であり、実装は実行者が契約を満たす方法です。計画では、この2つを異なる方法で扱います。
実際に使う正確なコードを記述するもの:
- テストのステップ本体 — アサーションが契約です。テストが誤った内容をアサートすると、実装が間違っていてもテストスイートは通ってしまいます。テストは、実際に使用する関数と型を用い、プロジェクトの言語で、計画に正確に記述する必要があります。
- コマンド — テストコマンド、マイグレーションコマンド、リント/型チェックのコマンドを正確に記述します。言い換えは不可です。
- コミットメッセージ — 正確な文字列を記述します。
- 設定変更 — 値が契約となる設定ファイルの変更(依存関係のバージョン、機能フラグ、環境変数など)を、正確な差分で記述します。
完全なコードを記述しないもの:
-
実装ステップの本体 — プランナーは、実際の型シグネチャ、実際のライブラリバージョン、そして実行者には見えてもプランナーには見えない周辺コードのもとで書かれるコードを推測しています。計画にあらかじめ書かれた実装は、実行開始時にはほとんどの場合すでに間違っています。その結果、実行者は自分の実コードをプランナーのスケッチに合わせる必要が生じ、何もない場合より悪い状況になります。
代わりに、実装ステップには以下を記載します。
- 変更対象ファイル — 正確なパス
- 動作契約 — 実装が満たすべき内容を、平易な言葉で2〜5個の箇条書きにします。直前のステップのテストで検証可能な内容にしてください。
- 参考情報 — 最も近い既存の実装、または仕様の Reference Points にある最も近い類似例への参照
これは曖昧に書いてよいという意味ではありません。「動作契約」とは、テストで検証する具体的な観測可能な動作を指します。「エラーを処理する」のような箇条書きは禁止です。「入力に重複した ID が含まれている場合、プロジェクトのエラー型による Err/例外を返し、そのメッセージに重複した ID を含める」のように記述する必要があります。
原則はこうです。計画で正しさの基準を定め、実行者がその基準を満たすコードを書く。 これは TDD がすでに示していることです。計画時と実行時に実装を二度書くのは、その順序を逆転させています。
失敗伝播の方針は、失敗する可能性のある操作を導入するすべての契約で必須です。 新しいシリアライズ、デシリアライズ、パース、型変換、ネットワーク呼び出し、ファイルオープン、その他エラーを返しうる操作をタスクで追加する場合、契約にはエラーの伝播方法を必ず記載します。
- 必須の方針 — 境界内部のコードパス(入力がすでに検証された後に実行される処理)では、プロジェクトのエラー型を使ってエラーを伝播します。
?/change_context/map_errでプロジェクトのバリアントに変換します。判断は呼び出し元に委ねます。 - 禁止パターン —
NoneまたはErrを、もっともらしいプレースホルダー値に変換する.unwrap_or(<non-default fallback string>)。デフォルト値が意味のある値(空文字列、ゼロ ID、デフォルトの enum バリアント)である型に対する.unwrap_or_default()。エラーを黙って破棄する.ok()。 - 許可される例外 — 契約で明記されている場合に限ります。型システム上明白な真のデフォルト(「結果なし」が仕様上の結果である場合の空の vec など)を使う場合は、そのデフォルトが正しい理由を1文で記載します。
「entry_type を行にシリアライズする」といった箇条書きだけでは不十分です。「to_value でシリアライズする。文字列への変換は .as_str().ok_or_else(...)? で行い、フォールバックのバリアントに黙って置き換えない」と記載する必要があります。契約にこの方針が記載されていないと、実行者は .unwrap_or を使い、バグがそのままリリースされることになります。
復元可能性テスト
各ステップを作成したら、行ごとに読み返して、次のように問いかけます。
「実行者はこの行を必要とするか、それとも参照先のファイルを読めば把握できるか?」
実行者が把握できる内容は削除します。計画とは、コードベースを Markdown で再現したものではありません。実行者が自力では導き出せない、必要最小限の差分です。実行者はコードベースを開いています。参照先のファイルを読みます。テストヘルパー、既存の実装、マイグレーション履歴、トレイトのシグネチャも確認します。それらを計画にコピーする必要はありません。
コミットする前に、すべてのステップで復元可能性テストを行います。
- テスト本体: 実行者はシードやセットアップのループを自分で書けます。アサーションと呼び出し箇所を示してください。ほかの情報源からは復元できないのは、仕様を固定するアサーションがどれかという点です。
- 動作の契約: 実行者は類似する既存の実装を読めます。
file.ext:line-lineで示してください。参照先からは復元できないのは、このタスクを参照先と異ならせる新しい動作です。 - 参照ブロック: 参照とはポインターです(
launch.rs:397-400)。実行者はファイルを開きます。引用したコードをそのままインラインで貼り付けるのは重複であり、元のコードが変更されればすぐに古くなります。 - 一括整理の指示: 「古いコメントと孤立した
PgPoolのインポートを削除する」で十分です。実行者は自分でファイル内を検索できます。行番号(「71~72 行、117~122 行、194 行」)を列挙するのは、実行時の実行者の役割です。
復元可能性テストに合格しない計画は、詳細なのではなく冗長です。冗長さ ≠ 具体性。 具体性とは、適切な不変条件を固定する一文です。冗長さとは、参照で済むのに、すべての細部を列挙することです。
テスト作成の指針
各タスクのステップ 1 に書くテストコードに関する 4 つのルールです。
**コントラクトとは、違反するとテストが失敗する最小限の記述です。**それを超える部分はすべて推測です。テスト本体が約 15 行を超えるなら、実行者が自分で書けるセットアップを再構成している可能性が高いです。アサーションがコントラクトであり、セットアップは配線にすぎません。
**アサーションと呼び出し箇所を示してください。シードループは省略してください。**テストで固定するのは動作であり、セットアップではありません。コンパクションのテストで SessionEntry の値を 5 つ明示的に作る必要はありません。示すべきなのは、compact_entries(_, N, summary) の呼び出し、load_entries がその後に返す内容のアサーション、挿入された要約行の seq に関するアサーションです。データの構築方法は、実行者が既存の型と既存のヘルパーから把握できます。
**まず再利用し、合うものがなければ新しく作ってください。**新たに make_user()、test_entry()、pty_spawn、偽の DB プール、フィクスチャを書く前に、同じ形の既存のものがコードベースにないか grep してください。計画に新しいヘルパーを追加するのは例外であり、デフォルトではありません。既存のヘルパーには、計画で再構成する必要のある規律がすでに組み込まれています。適切なクリーンアップ、現実的なデータ形状、プロジェクトで一般的なエラー処理などです。計画で新しいヘルパーを導入する場合は、検討した既存のヘルパーを具体的に挙げ、合わなかった理由を説明してください。「grep しなかった」は理由になりません。実行者が作成するヘルパーを計画で参照する場合は、シグネチャ(seed_entries(&store, session_id, count: i64))とともに名前を示しますが、計画本文では実装しないでください。
**考えられるすべてのエッジケースではなく、仕様を固定してください。**テストは、仕様で明示された特定の要件が満たされていること、または仕様や Assumption Audit で名指しされた特定の障害モードが解消されていることを証明するためにあります。目標は、仕様で指定された動作ごとに正確なテストを 1 つ、名指しされたバグの種類ごとにテストを 1 つです。同じ関数に対する「念のため」の境界値テストが 5 つ目になりそうなら、そこで止めてください。保守コストとテストスイートに加わるノイズを考慮すると、追加のカバレッジはかえってマイナスになる可能性が高いです。入力空間を網羅するための推測的なテストは、プロジェクトにあればプロパティベーステストやファズハーネスに任せてください。そうでなければ、過剰設計です。YAGNI は実装だけでなく、テストにも当てはまります。
**例外 — ペイロード保持の不変条件。**保持・復元・変換の不変条件(切り詰め後も出力が保持される、データが往復する、順序が維持される)を固定するテストでは、構造的に異なる生成元の集合と破損した領域は、推測的なエッジケースではありません。これらが仕様そのものです。データ経路が異なる生成元(ストリーミングと退避の組み合わせと、文字列全体を使う場合)をすべて列挙し、それぞれについて破損した領域にあるセンチネルをアサートしてください。YAGNI を理由に、これらを 1 つの正常系生成元にまとめてはいけません。それこそ、復元テストがバグのないツール 1 つに対して通ってしまう原因です。
動作コントラクトの指針
実装ステップごとの動作コントラクトに関する 2 つのルールです。
**箇条書きは 3〜5 個が目安です。5 個を超える場合、残りは参照に置き換えてください。**動作コントラクトには、このタスクの実装で新しくなる点や異なる点を列挙します。構造、エラー処理、コーデック、ヘルパー関数などはすべて、参照先の類似実装に記載されています。型、インデックス、フィールド、根拠を説明する箇条書きを 12 個書いているなら、Markdown 形式で実装を再構成しているだけです。次のように置き換えてください:Schema matches <reference migration file> with <one-sentence delta>。具体性を持たせるのは参照との差分であり、全体像ではありません。
**参照は場所を示すものであり、内容を貼り付けるものではありません。**参照には、行範囲を含むファイルパスを指定します:core/osprey-core/src/session/pg.rs:271-309。「Reference:」の下にインラインコードブロックを置くのはアンチパターンです。実行者がファイルを開けば読むコードを重複させるうえ、元のコードが変更されるとすぐに古くなります。関数シグネチャより長い内容を貼り付けているなら、参照を再実装に変えてしまっています。そこで止めて、ファイルと行番号の指定に置き換えてください。
クリーンアップの徹底
既存ファイルを変更するすべてのタスクは、最後に一掃作業を行います。変更によって古くなったものはすべて削除します。これはタスクの一部であり、別のフェーズではありません。
一掃の対象は、このタスクで変更したファイル内の次のものです。
- 古い動作、名前、シグネチャを参照していたコメント(例:関数が
Arc<dyn Store>を返すようになったのに// returns the PG poolと記されている場合) - 変更で削除したコードでのみ使われていたインポート
- 変更で置き換えた呼び出し箇所でのみ使われていた関数パラメーター、構造体フィールド、列挙型のバリアント、ヘルパー関数
- 到達不能な分岐、到達不能なコード、未使用のプライベート関数
- ファイルや関数に付いた古いドキュメントコメント。特に、もはや根拠として必要ではないフェーズ/PR/チケットへの参照
新しいものを追加しても、古いコメント、インポート、不要なヘルパー関数をそのまま残しているタスクは、完了ではありません。変更が不完全なままリリースされ、次に読む人が何がまだ有効なのかを探し回ることになります。計画では一掃作業を明確にしてください。各タスクのステップ 5 のコミットには、変更したファイルをすべて列挙します。実行者がそれらのファイルをステージングする際に、一掃作業を行います。
例外:
- 新規ファイルの作成のみを行うタスクでは、一掃するものはありません。
- 設定ファイル(Cargo.toml、package.json、CI YAML)の編集のみを行うタスクでは、それらのファイルだけを一掃します。
これは、他のタスクが触れていないファイルに残った不要なものを整理する、専用の Cleanup タスクとは別です。同じ計画に両方を含めてもかまいません。それぞれ、異なる残りものを処理します。タスクごとの一掃ルールにより、リファクタリングによって変更対象のファイル内に不要なものが残るというよくある事態を防ぎます。
プレースホルダー禁止
各ステップには、実行者が必要とする実際の内容をすべて記載してください。以下は計画の不備に当たるため、絶対に記載しないでください。
- 「TBD」「TODO」「後で実装する」「詳細を記入する」「未定」
- どのエラー、どの検証ルール、どのエッジケースかを明示せずに、「適切なエラー処理を追加する」「検証を追加する」「エッジケースに対応する」と記載すること
- テストが行うべき具体的なアサーションを示さずに、「上記の内容をテストする」と記載すること
- 繰り返しへの適切な対処法については、以下のパターンを参照してください。追加情報なしに「タスク N と同様」と記載すること
- 正確なアサーションがないテスト手順、正確なコマンドがないコマンド手順、正確なメッセージがないコミット手順
- どのタスクにも定義されておらず、既存のコードベースにも存在しない型、関数、メソッドへの参照
実装ステップに示す動作仕様はプレースホルダーではありません。これは、実行者がそれに従って実装するための明確な仕様です。禁止されるのは、仕様を伴わない曖昧な記述です。必要なのは、推測に基づくコードではなく、具体的な仕様です。
パターン:繰り返しを一度だけ命名する
同じ変換を多くの箇所に適用する場合(例:「N 個の呼び出し箇所を新しい API に変換する」「N 個のテストファイルを新しいフィクスチャに移行する」)、計画の重複を避けるため、計画の先頭にある Patterns セクションでパターンを一度だけ命名し、各タスクから参照します。そのパターンを使う各タスクには、引き続き次の内容が必要です。
- 固有のファイルを明記する(「ファイル一覧を参照」としない — 一覧はタスク内に記載します)
- 実際のアサーションを含む独自のテスト手順を記載する
- 独自のメッセージを付けた独自のコミットを作成する
Patterns セクションにまとめるのは、変換の形と参照例だけです。テストやコミットをまとめてはいけません。目的は、下流のエージェントが他のタスクを読まなくても一度に 1 つのタスクを実行できるようにしつつ、計画で同じ段落を 49 回書かずに済むようにすることです。
例:あるファイル内のクエリ呼び出し箇所 14 個を変換するタスクは、パターンを参照し、変換後もそのファイルのテストが通ることをテストで検証し、そのファイルだけを対象にコミットします。別のファイル内の 4 箇所を変換する 2 つ目のタスクも同じパターンを参照し、独自のテストとコミットを持ちます。
パターン適用の監査。 パターンを多くの箇所に適用する場合、計画には最後の箇所の変換タスクの直後に、最終タスク Audit: <pattern name> を必ず含めます。監査タスクには次の 3 つの手順を含めます。
- 古いパターンが残っている箇所がゼロであることを grep で確認します。 正確なコマンドと、出力が空であることを期待値として記載します。
- 本番設定との相違点を列挙します。 変換したすべての箇所を確認し、新しいパターンで再現されない本番固有の設定(プール設定、タイムアウト、分離レベル、環境変数、シグナルハンドラー)に依存している箇所を明示します。監査タスクの本文では、これらの箇所を具体的に列挙します。「箇所を確認する」ではなく、「ファイル A の行 X にある箇所は X に依存し、ファイル B の行 Y にある箇所は Y に依存する」と記載します。監査タスク内で各箇所を修正する(カスタムフィクスチャ、ヘルパーのオーバーライドなど)か、先に進む前にフォローアップタスクを作成します。
- 変換済みの箇所からランダムに 3 つ選び、本番の配線と照らし合わせて検証します。 3 つの箇所を選び、対応する本番配線のテスト(プロジェクトの階層化ルールに従って tier-2 または tier-3)を実行し、変換後のテストでも元のバグの種類が引き続きカバーされていることをアサートします。いずれかのサンプルでリグレッションが発生した場合は、そのパターンにサイトごとの例外対応が必要です。監査でそれを明記します。
監査はスタイル上の手順ではありません。N 箇所にパターンを盲目的に適用すると、本番設定との相違(例:テストのプール設定が本番のプール設定と気付かないうちに異なること)が、すべてグリーンのままリリースされる原因になります。監査によって、計画者は箇所を列挙し、実行者は検証するよう促されます。
前提の監査
実装計画には、仕様で常に明示されているとは限らない前提が含まれます。計画を確定する前に、自分が置いた前提(データの形状、命名、ライブラリの選択、エラーの意味、永続化の境界)を列挙し、それぞれを仕様と照らし合わせて確認します。
仕様で指定されたファイルを読み直します。 仕様によるファイルや関数の説明が古くなっていたり、部分的だったりする場合があります。そのファイルのドキュメントコメント、ヘッダー、周辺コードには、仕様が見落とした制約が記されていることがあります。仕様の説明が、コード内の重要なコメントやパターンと矛盾する場合、仕様を鵜呑みにせず、前提の監査項目として明らかにします。仕様の作成者は記憶を頼りにしていることが多く、真実はコードにあります。
ある前提が仕様に裏付けられておらず、別の選択肢も十分に考えられる場合は、Draft Review の段階でユーザーに提示します。ユーザーが確認したら(そのまま進め)、修正したら(計画を見直し)ます。黙って選択してはいけません。
確認済みの前提は、ヘッダーの下に短い「Assumptions」ブロックとして記録します。後から読む人(および実行エージェント)が、仕様だけでなく、ここで何が決定されたかを確認できるようにする必要があります。
セルフレビュー
計画をすべて作成したら、新たな視点で仕様を見直し、計画が仕様に沿っているか確認します。これは自分で行うチェックリストであり、サブエージェントに割り当てる作業ではありません。
| 項目 | 確認事項 |
|---|---|
| 仕様の網羅性 | 仕様の各セクションに目を通します。必須要件をすべて実装するタスクを、それぞれ指摘できますか?不足があれば列挙します。 |
| プレースホルダーの確認 | 上記の失敗パターンを検索します。該当箇所をその場で修正します。 |
| 型の一貫性 | 後続タスクの型、シグネチャ、名前は先行タスクと一致していますか? Task 3 の clearLayers() と Task 7 の clearFullLayers() の違いはバグです。 |
| テストの規律 | 振る舞いを変更するすべてのタスクに、実装手順の前に失敗するテストの手順がありますか? |
| テスト階層の網羅性 | この計画が対象とする、プロジェクト規約で定められた Tier 3(またはプロジェクトが定義する同等の階層)のトリガーをすべて列挙します。対象には、main.rs/エントリーポイント、CLI 引数の解析、環境変数の解決、ターミナル/pty/シグナルの処理、実際の stdin/stdout のパイピング、シェルの意味論が契約となるシェルスクリプト、契約の一部として安定性が求められるユーザー向け文字列リテラルが含まれます。それぞれについて、計画で追加する Tier 3(または同等の階層)のテストを示すか、そのタスクを未完了とします。シェルスクリプトのタスクにおける bash の認証情報漏えいは、プロセス内テストでは検出できません。検出できるのは Tier 3 テストだけです。 |
| スパイク候補 | Assumptions ブロックと仕様の Key Decisions を読み直します。このリポジトリにもチームにも動作するサンプルがないのに、「ツール X は Y を行う」という形式の主張がある場合、すべてに Task 0 のスパイクがありますか?なければ追加するか、仕様を修正します。 |
| 並行実装のゲート | 既存のトレイトまたはインターフェースの背後に、2 つ目のバックエンド/プラットフォーム/アダプターを追加しますか?追加する場合、両方の実装に対して標準のコントラクトスイートを実行し、観測可能な動作がバイト単位で同一であることを検証する最終タスクがありますか?なければ追加します。 |
| 失敗伝播の契約 | 新たに失敗する可能性のある操作(シリアライズ/解析/変換/オープン/接続)を導入するすべてのタスクで、その動作契約に伝播方針が明記されていますか?明示的な契約上の根拠がない .unwrap_or(<もっともらしいフォールバック>) はバグの原因となるため、契約を修正します。 |
| 利用側の確認 | この計画で導入するすべての新しいパブリック API(トレイトメソッド、エクスポートされる関数、パブリックフィールド、エンドポイント、CLI フラグ)に、少なくとも 1 つ、名前を明記した 本番環境での利用側、つまり同じ計画内のテスト以外のパスから呼び出すコードがありますか?コントラクトテスト/単体テストは利用側ではありません。呼び出し元がテストしかない場合は、本番環境での利用側を明記するか、API を削除します(利用側の作業を番号付きの後続作業として示し、延期扱いにします)。そうでなければ計画は不合格です。コントラクトテストを満たすだけのプリミティブは、実装に不要な表面積を強いるだけです。 |
| 問題を識別できるアサーション | 各テストについて、アサーションを通過してしまう、もっともらしい壊れた実装/何もしない実装を説明します。そのような実装がある場合、アサーションの対象が不適切です。バグによって破損する領域や形状に対象を移します。保持/復元/変換の不変条件については、バグが損なう領域にあるセンチネルを検証します(保持された先頭/末尾ではなく、失われた中央部分です)。構造的に異なるすべての生成元を通じてテストします(バッファを追い出すストリーミング生成元と、文字列全体を扱う生成元は、同じ経路ではありません)。誤って成功するテストが 1 つでもある場合、計画は不合格です。 |
| タスクごとのスイート成功 | 各タスクの Step 4 に、単一テストのコマンドと、より広い範囲のスイートを実行するコマンドの両方が指定されていますか?単一テストだけの成功では、タスク間の回帰を見落とします。 |
| パターン適用の監査 | 1 つの Pattern が多くの箇所に適用される場合、最終の Audit タスク(grep + 本番設定との差異の列挙 + 3 箇所のサンプル検証)がありますか? |
| プロジェクト規約 | 読んだプロジェクト規約(例:AGENTS.md や CLAUDE.md)に従っていますか?(例:実パスのテストカバレッジ、コメントの方針、コミット形式) |
| 対象外事項 | 仕様で対象外とされている内容がタスクに紛れ込んでいませんか?あれば削除します。 |
問題があれば、その場で修正します。再レビューは不要です。そのまま進めてください。タスクが割り当てられていない仕様要件があれば、タスクを追加します。 提示可能な状態になる前の確認: すべての項目に正直に「はい」と答えられる場合にのみ進んでください。「問題なさそう」では不十分です。
任意:レビュアーサブエージェントを起動する
長い計画(タスクが 10 件を超える場合)、不慣れな分野、または影響の大きい作業では、計画書レビュアーのサブエージェントを起動してください。プロンプトのテンプレートについては、references/plan-reviewer.md を参照してください。
短く、よく知っている計画であれば、セルフレビューで十分です。形式的に毎回起動しないでください。いずれにせよ、その後に人間がレビューする段階で、ほとんどの問題を見つけられます。
草案のレビュー
ディスクに書き込む前に、レビュー用の草案をチャットに提示してください。ユーザーは変更を依頼することも、承認することもできます。
提示する内容:
- 計画の Markdown 全文(ユーザーが最初から最後まで読める 1 つのまとまり)
- 立てた前提の簡潔な一覧(前提条件の監査に基づくもの)
- 計画で作成または変更するファイルの一覧
- 元の仕様書へのリンク
草案を提示可能と判断する前の確認:
- セルフレビューのチェックリストが、すべての観点で正直に「はい」となっている
- 草案の文章が、要約や「計画の説明」ではなく、具体的な文章として会話内にある
- すべてのテスト手順に実際のテストコードと正確なアサーションが含まれ、すべてのコマンド手順に正確なコマンドが含まれ、すべての実装手順に具体的な動作仕様が含まれている(曖昧な動詞ではない)
ユーザーから変更を依頼された場合は、チャット上で修正して再度提示してください。このやり取りの間は、ディスクに書き込まないでください。
計画の書き込み
plan.md を作成または上書きする前の確認: 次の 2 つを満たすまで、書き込まないでください。
- ユーザーの承認: ユーザーが草案を明示的に承認した、またはファイルの保存・書き込みを指示した。漠然とした好意的な反応だけでは承認とはみなされません。不明な場合は確認してください。
- パスの確定: 対象パスが確定している。デフォルトは
.beagle/concepts/<slug>/plan.mdで、slug は仕様書のフォルダーから引き継ぎます。
- デフォルトのパス:
.beagle/concepts/<slug>/plan.md - slug の参照元: 仕様書の親フォルダーから引き継ぎます(
.beagle/concepts/配下の<slug>部分)。ユーザーの希望がある場合は、デフォルトより優先します。 - ユーザーがコミットを明示的に依頼した場合は、
docs: add <slug> implementation planを使用します。 - 書き込み後、ユーザーに次のように伝えます。
"Plan written to
<path>. Review it on disk and let me know if you want changes." - その後、次の質問を正確にします。"Do you want a prompt to execute this plan in a new session?"
- はいの場合: subagent-prompt スキル(../../../beagle-core/skills/subagent-prompt/SKILL.md)を読み込み、書き込んだばかりの
plan.mdのパスを参照資料として指定します。これにより、参照資料とタスク分解の確認は計画書に基づいて完了し、ユーザーへの再質問は不要になります。 - いいえの場合: 計画の準備ができたことを伝え、新しいセッションで subagent-prompt スキルを呼び出せば、後から引き継ぎプロンプトを作成できると案内してから終了します。
- subagent-prompt を利用できない場合(例:
beagle-coreがインストールされていない場合):ユーザー自身で subagent-prompt スキルを呼び出すよう案内します。
- はいの場合: subagent-prompt スキル(../../../beagle-core/skills/subagent-prompt/SKILL.md)を読み込み、書き込んだばかりの
- 作業が完了したと判断する前に、次の指示を待ちます。
実行への引き継ぎ
計画書は引き継ぎ用のドキュメントであり、実行の指示ではありません。書き込み後、write-plan は引き継ぎプロンプトを今作成するかどうかを尋ねます。
- はいの場合: subagent-prompt スキル(../../../beagle-core/skills/subagent-prompt/SKILL.md)を読み込み、書き込んだばかりの
plan.mdに基づいて、このセッションでオーケストレーション用プロンプトを作成します。プロンプトの仕様は subagent-prompt が担うため、ここで繰り返さないでください。 - いいえの場合、または
beagle-coreを利用できない場合: ユーザー自身が新しいセッションで実行できるよう subagent-prompt スキルを案内するか、プロジェクトが提供する別の後続実行スキルを案内します。 - それ以外の場合は、計画の準備ができており、ユーザー自身でタスクごとに実行を進められると伝えます。
実行を開始しないでください。 このスキルが作成するのは計画(および任意の引き継ぎプロンプト)です。実行は別の判断事項であり、多くの場合、独自の作業規律を持つ別のスキルで行います。
主要な原則
- 仕様が契約です — 仕様に根拠のない要件を決して作り出さないでください
- 常に小さな単位で進めます — 1ステップは2〜5分とし、複数の作業をまとめないでください
- テストが契約であり、実装は契約を満たすものです — テストのステップでは実際のテストアサーションと呼び出し箇所を示してください。実装のステップでは動作契約(ファイル+3〜5項目の箇条書き+類似例への参照)を示してください。実行者は推測ではなく、テストに基づいてコードを書きます
- 原則としてTDDで進めます — 毎回、実装より先に失敗するテストを書いてください
- 信頼できる情報源は1つにします — 仕様は「何を」を定義し、計画は契約レベルでの「どのように」を定義し、実行者はコードレベルでの「どのように」を定義します
- 復元可能性テスト — 実行者が参照先ファイルを読めば復元できる情報は削除してください。冗長さは具体性ではありません
- 契約とは、違反するとテストが失敗する最小限の記述です — それを超えるものは推測です。テスト本体が約15行を超えること、動作契約が5項目を超えること、「Reference:」ブロックに関数シグネチャ以外の内容が含まれることは、いずれも計画が実装を再導出している兆候です
- 参照は場所を示すものであり、内容を貼り付けるものではありません —
file.ext:line-lineが参照です。「Reference:」の下にインラインコードブロックを貼ると、元のコードが変更された時点で古くなります - パターンを使ってDRYに繰り返します — 1つの変換をN箇所に適用する場合は、パターンに名前を付けて1回だけ記述してください。ただし、各タスクにはそれぞれのファイル、テスト、コミットが必要です
- テストでは既存の足場を再利用します — 新たに考案する前にgrepしてください。計画で新しいヘルパーが必要な場合は、既存のどのヘルパーが適合しなかったのか、その名前を挙げてください
- テストにもYAGNIを適用します。ただし、ペイロード保持の不変条件は例外です — 想定可能なあらゆるエッジケースではなく、仕様と名前が挙がっているバグの種類を押さえてください。入力空間を推測で網羅しようとするのは過剰設計です。ただし、保持・復元・変換の不変条件では、構造的に異なる生成元と破損した領域そのものが仕様です。すべての生成元を列挙し、破損した領域にセンチネルがあることをアサートしてください
- 作業の最後に整理します — ファイルを変更するすべてのタスクは、そのファイル内の孤立したコメント、未使用のインポート、使われていないパラメーター/フィールド/ヘルパーを削除して終えてください。整理対象は行番号ではなく平易な言葉で記述してください。実行者がgrepします
- 前提を明示します — タスクに暗黙に含めるのではなく、計画に見える形で盛り込んでください。仕様の記述を鵜呑みにせず、仕様が名前を挙げているファイルを読み直してください
- プロジェクトの慣例を尊重します — テストコマンド、コミットの慣例、コメント方針、テスト階層のルールはプロジェクトごとに異なります。プロジェクトの慣例(AGENTS.mdやCLAUDE.md、または
CONTRIBUTING.mdなどの同等ファイル)を確認し、それに沿って計画を立ててください - 計画だけで完結させます — 後続のエージェントが仕様を読み直さなくても実行できる計画にしてください
このスキルが適さない場合
このスキルは、次の前提に基づいています。
- 仕様が存在する(ない場合はbrainstorm-beagleを使用してください)
- 作業の対象が一貫性のある1つのシステムに限定されている(そうでない場合はブレインストーミング中に分解してください)
- 後続の実行者がTDDを理解しているエージェントまたはエンジニアである
作業が1行の修正、1ファイル内のリファクタリング、または実験的なスパイク作業であれば、完全な計画を立てるのは過剰です。このスキルは大がかりすぎるとユーザーに伝え、直接作業するよう提案してください。