specops について
SpecOpsは、エージェントや開発者向けの仕様駆動開発スキルです。合意済みで検証可能なソフトウェアの目標状態を実装に先立って定め、機能ブランチとPRで仕様、コード、検証をまとめます。
主な機能
- 01実装前に目標状態を定義
- 02宣言的で検証可能な仕様の作成
- 03判断基準となるプロジェクト原則の記述
- 04対象別の仕様整理
- 05仕様変更、実装、検証の連携
活用シーン
- 01AI支援による機能実装の計画
- 02複数エージェント間での期待動作の共有
- 03合意済み要件に照らしたコードレビュー
- 04仕様とソフトウェアの既知の差異の追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jarvusinnovations/ specops --skill specopsインストール後、Claude Code で/specopsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/audit-spec-drift.mdparallel-execution-protocol.mdplans-protocol.mdspec-drift-auditor.mdscripts/specopsspecops.mjs詳細
仕様駆動開発(SpecOps)
基本理念
仕様には、ソフトウェアに望まれる完全な状態を記述します。実装は仕様に従います。すべての作業は仕様の更新から始まります。
これはドキュメント駆動開発(構築したものをドキュメントに記述する手法)ではありません。仕様駆動開発です。仕様には「何が存在すべきか」を記述し、実装をそれに適合させます。仕様が先導し、コードがそれに続きます。
なぜ重要なのか
エージェントや開発者が機能を実装するとき、何百もの細かな判断を下します。仕様がなければ、個々の判断はユーザーの意図に合っているかどうかわからない推測になります。仕様があれば、そうした判断はすでに済んでおり、実装者の仕事は創造ではなく実行です。これは、複数のエージェントが同じシステムの異なる部分を担当することがあるAI支援開発で、特に効果を発揮します。
基本のサイクル
1. Spec change → propose what should be true
2. Accept → reviewer agrees on desired state
3. Implement → bring code into conformance
4. Verify → compare running software to spec
対応する仕様がないコードは、仕様外の動作です。実用上の理由で存在することはあっても、何も保証されません。対応するコードがない仕様は、認識済みの未対応事項です。そしてメインブランチでは、認識済みの未対応事項にはコミット済みの計画が伴います。実装も計画もない仕様は未対応事項ではなく、未展開の草案です。実際の仕様になるまで、草案の計画PRで管理します(開発中の仕様の置き場所を参照)。
ブランチとPRは実装を中心に構成する。仕様だけにしない
仕様のみ、または計画のみのPRは作成しないでください。 作業を始める際は、リリースする機能の名前を付けたブランチとPRをそれぞれ1つ作成し、契約を早期にレビューできるように、docs(specs):コミットと計画ファイルから着手します(ドラフトPRでも構いません)。その後、同じブランチに実装コミットを追加し、最後に完了処理のコミットを追加します。そして、計画が完了した場合に限りPRをマージします。レビュー担当者は、契約、適合性の証拠、計画の検証内容を一か所で確認でき、仕様が先導する順序で並んでいます。
これは、specopsプロジェクトにおける作業のすべてのまとまりに適用するデフォルトです。単独の仕様PRが認められるのは、設計について引き続き調整が必要な仕様をまとめて扱う草案の計画PR(これも計画一式と一緒にマージします)、外部関係者の承認を条件とする提案計画、または差分が大きすぎて実装の差分が埋もれてしまう仕様に限られます。いずれにも当てはまらず、今後実装が追加されないPRを作成しようとしている場合は、立ち止まってください。第2のバックログを作ろうとしています。ライフサイクル全体については、references/plans-protocol.md § 機能ブランチを参照してください。
仕様の書き方
適切な詳細度
仕様には、実装の方法ではなく、何が正しい状態であるべきかを記述します。
適切な詳細度 — 宣言的な状態とルール:
「各行には、from_stop_name、to_stop_name、pathway_modeのラベル、完了率(入力済みフィールド数 / 該当フィールド数)を表示する。並び順:未完了の項目を先にし、その後from_stop_nameのアルファベット順にする。from_stopとto_stopのlevel_idが同じ場合、そのpathwayは『このレベル』に属する。」
これは、何が正しい状態であるべきかを実装者に伝えつつ、方法を指定しません。画面を見て適合性を検証できるため、テスト可能です。
曖昧すぎる — 機能の説明:
「タスクリストでは、経路をレベル別にまとめ、進捗を追跡できる。」
これを読んだエージェントは、依然として何百もの判断を下す必要があります。どのフィールドを使うのか。どの順序で並べるのか。データが欠けている場合はどうするのか。
詳細すぎる — 実装の疑似コード:
「pathwaysをWHERE from_stop.level_id == to_stop.level_idでクエリし、field_notesをLEFT JOINし、field_complete ASCでORDER BYし、それぞれを
<li>としてレンダリングする……」
これでは同じコードを2度書いているにすぎません。実装が仕様から外れた時点で、仕様は陳腐化します。
列挙されたルールだけでなく、基本理念も反映する
2つの言葉、1つの考え。 プロジェクトの哲学とは、その行動を導く基本姿勢、つまり、どのように振る舞うかの理由です(「オフライン優先にする」「デスクの分析担当者より、現場で使う人を優先する」)。その哲学を原則として書き記します。原則とは、それぞれがトレードオフの一方を明確に選ぶ、個別の断定的なルールです。哲学は全体であり、原則はその構成単位です。したがって、「哲学を具体化する」とは、実装者が読む場所に原則を記すことを意味します。このスキルでは、「哲学」は基本姿勢を、「原則」は書き記された単位を指します。principles.md と仕様書の ## Principles セクションには原則を記します。
このスキルが必要な理由を思い出してください。実装者は何百もの細かな判断を行いますが、その判断を意図に沿ったものにするのが仕様書です。列挙したルールでカバーできるのは、あらかじめ予測した判断、つまり書き留めようと思ったケースだけです。原則はそれ以外をカバーします。列挙されたルールでは対応できないケースも、作者ならどう判断するかと同じように解決する、生成的なルールです。
この2つは一緒に機能します。
- 列挙されたルール — 「未完了の経路を先に並べ、その後は from_stop_name のアルファベット順に並べる。」特定のケースを1つ解決します。
- 原則 — 「これは、移動中の駅で片手でスマートフォンを操作して使う、現場でのデータ入力ツールです。表示や操作の判断が相反する場合は、デスクにいる分析担当者より、歩きながら調査する人を優先してください。」列挙したルールで対応できなかったあらゆるケースを、作者ならどう判断するかと同じように解決します。
仕様書の原則としてふさわしいのは、明確な判断を示すものだけです。実際のトレードオフの一方を選び、他方を退けなければなりません。次の例を比べてください。
- 原則ではないもの(ありきたりな言葉で、何も退けていない):「UI はすっきりとしていて、使いやすいものにします。」
- 原則(明確な判断を示し、実装者がそれに基づいて行動できる):「更新中は画面をブロックするより、最終更新時刻を表示して古いデータを見せることを優先します。地下で電波が届かない調査担当者が、常に最後に確認できた状態を見られるようにします。」
判断基準は、ほかの仕様と同じです。2人の実装者がそれを読んで、コードが準拠しているかどうかについて意見が分かれるでしょうか。「使いやすい」なら、分かれるため役に立ちません。「時刻付きの古いデータを、画面のブロックより優先する」なら、分かれないため、準拠を確認できます。
原則を記す場所は、原則が適用される最も具体的な仕様書を基本とします。 1つの画面だけに影響する原則は、その画面の仕様書の ## Principles セクションに記し、それが支えるルールのすぐ隣に置きます。そうすれば、その仕様書を読む実装者の目に留まります。principles.md に記すのは、特定の機能仕様書だけでは扱えない、真にプロジェクト全体に関わる原則に限ります。ローカルな原則が、その仕様書の範囲を超える判断にも適用されるようになったら、principles.md に昇格させ、元の場所には参照先を残します。注目すべき具体的なきっかけは、同じ原則、または似た原則が2つ目の仕様書に現れることです。重複が見つかったら、1つの仕様書だけに属する原則ではなくなったという合図です。原則を一箇所にまとめ、重複した記述は参照に置き換えてください。似た記述が2つに分かれたまま食い違うのを防げます。これにより、principles.md が何でも詰め込む場所ではなく、簡潔で要点の明確なものになり、各原則も導く対象となる作業の近くに置かれます。記録する時点で配置を悩みすぎないでください。まず作業中の仕様書に記し、適用範囲が広がったら後から昇格させます。
関連するプロジェクト原則を各仕様書に記載します。 原則の昇格は上向きに伝えますが、これは逆方向、つまり下向きの流れです。エージェント(および人)は、principles.md を一度も開かずに、仕様書を1つか2つだけ確認することがよくあります。そのため、ある画面をひそかに規定しているプロジェクト全体の原則が、その画面を担当する人に見えません。これを防ぐため、仕様書の ## Principles セクションでは、その仕様書に特に強く関係する principles.md の項目を挙げ、それぞれについて、ここでどのように適用されるかを一行で説明し、原則の全文にリンクします。 この仕様書だけを読む実装者も、適用される原則を引き継ぎ、見落とさずに済みます。選択的に記載してください。仕様書の判断を実際に左右する原則だけを参照し、すべてを列挙してはいけません。すべての原則にリンクする仕様書からは何も学べません。ローカルな原則を principles.md に昇格させたとき、そこに残すポインターがこの参照の1つになります。
仕様書に記載する内容
- 表示ルール — どのデータを、どの条件で表示するか
- データ要件 — データの取得元(API、ローカル DB、派生データ)
- アクション — ユーザーができることと、各アクションが引き起こす結果
- ナビゲーション — ここから移動できる場所と、ここに来る前の場所
- ビジネスルール — 計算、状態遷移、検証ロジック
- API コントラクト — リクエスト/レスポンスの形式、認証、エラーケース
- 原則 — 明示されていない細かな判断を一貫して解決する決定的なルール。書き留めた設計思想です(上記の「設計思想を列挙されたルールだけでなく、原則として記述する」を参照)
仕様書に記載しない内容
- ビジュアルデザイン — 色、余白、フォント。これらはワイヤーフレームとテーマ定数で扱います。
- ウィジェット/コンポーネントの分解 — 画面をクラスに分割する方法。これは実装上の判断です。
- テストケース — テストは仕様書から導きますが、テスト自体は仕様書ではありません。
- 変数名、ファイルパス — 自由に変更される実装の詳細です。
仕様書のディレクトリ構成
作成時期ではなく、記述する内容に基づいて仕様書を整理します。
specs/
├── README.md # Workflow docs, directory layout, format conventions
├── principles.md # Project-wide principles — the decisive rules (your philosophy, written down) that resolve unspecified decisions
├── architecture.md # Tech stack, project structure, foundational decisions
├── data-model.md # Schema, field definitions, relationships
├── api/ # One file per endpoint or endpoint group
│ ├── conventions.md # Auth, versioning, error envelope, content types
│ └── <endpoint>.md
├── screens/ # One file per screen/route
│ └── <screen-name>.md
└── behaviors/ # Cross-cutting rules that span multiple screens
└── <behavior>.md
principles.md — 原則として書き留めたプロジェクトの設計思想です。列挙されたルールでは解決できない細かな判断を解決する、決定的で分野横断的なルールです。architecture.md(具体的な技術や構成の選択)とは異なり、原則は、妥当な実装方法が2つあり意見が分かれるときに、どちらかを選ぶ価値判断です。1つの画面や動作に限られる原則は、その仕様書の ## Principles セクションに記載します。principles.md には全体に適用される原則を記載し、機能仕様書は、それらを自身の ## Principles セクションから参照します。
screens/ — 画面/ルートごとに1ファイル。ユーザーがその URL で見ること、できることを記載します。
behaviors/ — 複数の画面にまたがるルールを記載します。画面仕様書に「完了率」とある場合、完了動作の仕様書でその計算方法を定義します。
api/ — クライアントとサーバー間のコントラクトを記載します。双方がこれらの仕様に基づいて実装します。
仕様書のテンプレート
画面仕様書
# Screen: <Name>
## Route
The path/URL for this screen.
## Data Requirements
What data this screen needs and where it comes from.
## Display Rules
Declarative description of what appears and under what conditions.
This is what a reviewer checks the implementation against.
## Actions
What the user can do and what each action causes.
## Navigation
Where you can go from here, where you came from.
## Principles (optional)
The decisive rules governing this screen — what to favor for any case the rules
above don't enumerate.
**Inherited** — project principles from `principles.md` that especially bite here:
- [Offline-first beats fresh](../principles.md#offline-first-beats-fresh) — this screen
must render last-known state instantly; treat the live refresh as a background nicety.
**Local** — principles owned by this screen (promote to `principles.md` if they spread):
- ...
Omit either subsection if empty. Reference only principles that genuinely shape this
screen's decisions — not the whole list.
動作仕様書
# Behavior: <Name>
## Rule
The invariant or rule, stated declaratively.
## Applies To
Which screens or components this behavior affects.
## Details
Edge cases, calculations, timing, error handling.
## Principles (optional)
Same two-part shape as the screen template: **Inherited** — linked `principles.md`
entries that especially govern this behavior, each with a one-line gloss of how it
applies; **Local** — the decisive trade-off behind this rule, if any (promote if it
spreads). Omit either subsection if empty.
API 仕様書
# API: <Name>
## Endpoint
Method, path, auth requirements.
## Request
Parameters, body shape with field types.
## Response
Success body shape with field types. Error cases.
## Notes
Caching, idempotency, offline implications.
## Principles (optional)
Same two-part shape as the screen template: **Inherited** — linked `principles.md`
entries that especially govern this endpoint, each with a one-line gloss; **Local** —
the decisive trade-off for this endpoint (e.g. what to favor when consistency and
latency conflict), promoted if it spreads. Omit either subsection if empty.
原則(principles.md)
# Principles
The project's philosophy, written down as principles. Each is decisive: it picks a
side of a real trade-off so an implementer can resolve an unspecified case the way
the author would.
## <Principle name>
The principle, stated as a rule that rules something out. Include the *why* — the
context that makes the trade-off land — so a future reader applies it correctly.
> Example: **Offline-first beats fresh.** This tool runs in stations with no signal.
> When freshness and availability conflict, always show last-known state with a
> timestamp rather than block on a network round-trip.
各原則には、短く安定した ## <Name> 見出しを付けます。この見出しがアンカーになり、機能仕様書はそれぞれの ## Principles セクションから principles.md#<name> としてリンクします。参照の方向は一方通行です。仕様書から principles.md を参照します。principles.md 内に「この原則が適用される仕様書」の一覧を管理しないでください。手書きの DAG と同様、仕様書が変更された時点で古くなってしまいます。ある原則が何を規定するかを調べるには、そのアンカーへのリンクを grep してください。
画面、動作、API の仕様書には、その仕様書だけに適用される原則を記載する ## Principles セクションを任意で追加できます。基準は同じです。つまり、決定的であり、何らかの選択肢を除外するものであることです。その原則が1つのファイルを越えて判断に影響するようになったら、principles.md に昇格させます。
エージェントによる仕様書の活用方法
機能を実装するとき、またはバグを修正するときは、次の手順に従います。
- まず該当する仕様書を読みます。 すべての画面、エンドポイント、動作には仕様ファイルがあります。コードを書く前に読んでください。
- 仕様書が答えるのは「何を」であり、「どのように」ではありません。 どのデータを表示するか、どのアクションがあるか、どのルールが適用されるかを記載します。ウィジェットツリーやクラス階層は指定しません。
- 仕様書が曖昧な場合は、推測してコードを書くのではなく、仕様書を明確にします。 仕様書の修正を提案してください。
- 仕様書に誤りがある場合は、コードで回避するのではなく、仕様書を修正します。
- 完了したら、仕様書に照らして作業を確認します。 すべての表示ルール、すべてのアクション、すべての条件分岐を確認してください。
新機能に着手するとき
まず、どの種類の作業なのかを判断します。これによって、計画を今作成するのか、後で作成するのか、仕様書と並行して作成するのかが変わります(計画を作成する場合と作成しない場合を参照)。以下の手順は、一般的なケースである、周辺の仕様書が安定しているプロジェクトで、範囲を限定した1つの機能を実装する場合の標準的な進め方です。
すべての作業は、リリースする機能を軸にした1つのブランチと1つのPRで行います。作業開始時にPRを作成し、計画を完了させてから一度だけマージします(全工程についてはreferences/plans-protocol.md § The feature branchを参照)。
- 統合ブランチから分岐し、仕様書ではなく機能名をブランチ名にします
- まず仕様ファイルを作成または更新し、ブランチの先頭に
docs(specs):コミットとして追加します - コードを仕様書に適合させる計画を作成します。範囲、実装する仕様書、依存関係、検証基準を記載します(範囲を限定した1つの機能の場合は、仕様書の変更と計画を並行して作成し、実装に着手する前に両方を提示して承認を得ます)
- 今すぐPRをドラフトとして作成し、機能名をタイトルにします。この時点で含まれるのは仕様書と計画だけです。それが目的です。コードが存在する前に、コードを含めるPR上で契約をレビューします
- 同じブランチで、仕様書に一致するよう実装します
- 実行中のソフトウェアが仕様書に一致することを確認し、最後のコミットで計画を完了させます。計画は、構築したものを記録する資料として確定します
- PRをレビュー可能な状態にします。レビュアーは仕様書の差分を契約として読み、次にそれに対する実装を確認し、最後に計画の検証証拠を確認します。レビューは1回、マージも1回です
内容が仕様書と計画だけのPRを作成してはなりません(ブランチとPRは実装を軸にするを参照)。例外となる、設計中の作業一式に対するドラフト計画PR、提案段階の計画、実装の差分が埋もれてしまう仕様書の差分については、該当箇所で説明しています。
開発中の仕様が置かれる場所:計画策定中のPR
specs/ ツリーの監査可能性を保つ不変条件は、mainブランチ上のすべての仕様が、実装済みであるか、コミット済みの計画を伴っていることです。 この不変条件のもとでは、仕様の監査は意味を保ちます。Table-1の「仕様化済みだが未実装」という指摘は、常に想定内の進行状況(計画があるため、それを参照として示せる)か、実際の違反のどちらかです。これがなければ、監査ツールはチームが実現に向けて進めている未対応項目と、誰かが置いたままにした草案とを見分けられず、未対応項目の表はノイズに埋もれていきます。
望ましい状態についてまだ合意形成中の仕様はマージしません。計画策定中のPRに置きます。これは開発中の仕様(そして最終的にはその計画一式)を含むブランチで、ドラフト状態から切り替わり、最終確定した仕様と、それを実装する計画がそろって初めてマージされます。PR本文には、未解決の設計上の疑問、変更が必要な関連仕様、作成すべき計画を記載します。
mainブランチ上のstatus: draftマーカーより、ドラフトPRが優れている理由:
- 曖昧さのないマーカーは「存在しないこと」だけです。 mainブランチ上にドラフトを置いても、grepの結果や読解の文脈を汚します。また、
specs/を参照する実装担当者(またはエージェント)が、実装に取りかかる前にステータスフィールドを確認するという確実な習慣を持つとは限りません。 - すべてのツールがそのマーカーを認識する必要があります。ドリフト監査ツール、
grepベースの仕様参照、計画のspecs:フィールドなどです。存在しなければ、誰も何もする必要がありません。 - レビューのやり取りは、もともとレビューが行われる場所で行えます。中途半端なファイルをmainブランチ上で編集するのではなく、PR上で差分に紐づけてスレッド形式で進められます。
実際には、計画は完成した状態でマージされるため(references/plans-protocol.md § The feature branchを参照)、この不変条件はほぼすべてのケースで実装済みの仕様によって満たされます。mainブランチ上のplanned計画は、これから一括処理される初期立ち上げ用の一群と、提案計画の2つの場合に限られます。これら以外の理由でplans/にplannedファイルが蓄積している場合、その作業は課題トラッカーで管理してください。
計画策定中のPRを、仕様と計画だけを含む状態で早期に作成する通常の機能PRと混同しないでください。機能PRは1つの実装を中心に構成され、その実装を含みます。一方、計画策定中のPRには、設計がまだ流動的で計画一式もまだない仕様が複数含まれます。単一の機能の仕様が計画を立てられる程度に確定しているなら、計画策定中のPRは必要ありません。機能PRを作成してください。
管理上の注意:長期化している仕様ブランチは定期的にmainブランチにリベースし、最終的なマージがスムーズに行えるようにしてください。また、設計のまとまりごとに計画策定中のPRを1つだけ作成してください(関連する仕様の一群は1つのPRにまとめ、無関係な設計のまとまりは分けます)。
これを提案計画と混同しないでください。 提案計画は次の段階を扱うもので、契約についてはすでに合意済みでも、外部の関係者が行動するまで実装できない場合に使います。提案計画は、設計が確定しており、その記録をバージョン管理して共有可能にする必要があるため、仕様とawaits:を含むblocked計画をまとめてマージします。計画も一緒に含まれるため、不変条件は保たれます。計画策定中のPRは合意形成より前の段階にあり、設計はまだ流動的で、計画もなく、不変条件を保つものが何もないため、mainブランチには一切置きません。ドラフトから提案計画に移行することもあります。ドラフトの設計が確定していても、外部要因によって実装が制限される場合は、提案計画としてマージしてください。
バグを修正するとき
- その挙動が仕様化されているか確認します。仕様化されている場合、仕様は正しく、コードに誤りがあります。
- 挙動が仕様化されていない場合は判断します。このケースを扱うよう仕様を更新すべきか、それとも修正が明白なのでコードだけ変更すればよいかを決めます。
- 大きな修正の場合は、修正内容を記録するため、まず仕様を更新します。
コードをレビューするとき
実装を、自分ならどう動作させるかという考えではなく、仕様と照らし合わせてください。仕様が受け入れ基準です。
常に:仕様に記載すべき決定事項や原則を見逃さない
これは一時的なフェーズではなく、常に担う責任です。実装、デバッグ、レビュー、あるいはユーザーと問題について話し合っているだけのときも、重要な決定が下されたり、原則が定まったりする瞬間(プロジェクトの理念が明確になり、書き留められるルールになる瞬間)を常に見逃さないようにしてください。こうした瞬間は、仕様作業ではなく進捗のように感じられるため、見落としやすいものです。
- ユーザーが、ある方法を望む理由を説明し、今後の判断を導く原則が明らかになる。
- 会話の中でトレードオフに決着がつく(「X と Y が衝突する場合は、常に Y より X を優先する」)。
- 仕様に定めのないケースに遭遇し、答えを選ぶ。その答えが一般的なルールを示唆している。
- レビューコメントによって、コードベース全体で従うべき規約が定まる。
- 「常にこうする/決してこうしない」という考えが浮かぶ。ほとんどの場合、その裏には原則が隠れています。
- **2つ目の仕様書に、同じ(またはほとんど言い換えただけの)原則を書いた、あるいはそれに気づいた。**仕様書間の重複は、原則を格上げすべきであることを示す最も明確なサインです。その原則は、すでに1つの仕様書だけに収まるものではありません。2つの記述が食い違うままにならないようにしてください。原則を一度
principles.mdにまとめ、両方の記述を、その項目への## Principles参照に置き換えてください(理念を明文化するを参照)。同一の原則だけでなく、類似した原則にも注意してください。たとえば、「現場のユーザーをデスクワークの分析担当者より優先する」とそれぞれ異なる言葉で書かれた2つの仕様書は、同じ原則を示しています。
このようなものに気づいたら、作業を止めて、その内容を明示してください。決定事項の名前を挙げ、それが列挙ルールなのか原則なのかを示し、どこに運用可能な形で記載すべきかを具体的に提案してください。原則として、その決定が関係する最も具体的な仕様書(画面/動作/API の仕様書のルールまたは ## Principles セクション)を選び、principles.md はプロジェクト全体に関わるものに限ります(理念を明文化するを参照)。その後、忘れ去られる前に、通常の仕様優先の進め方に従って仕様を変更するか、変更案を提示してください。
指摘する基準:**ある決定によって、将来の実装者が細かな判断を下す方法が変わるなら、仕様に記載する必要があります。**この1行だけにしか影響しないなら、そのままにしてかまいません。
これが重要な理由:コード、コミットメッセージ、チャットの履歴だけに存在する決定は、コンテキストウィンドウが閉じた瞬間に、仕様のない動作になります。次のエージェントはその決定を再び議論することになり、別の結論に至る可能性もあります。その結果、コードベースは一貫性を失っていきます。この注意深さこそが、仕様を単なる説明ではなく、実装を導くものにします。仕様は機能の着手時に一度書かれて凍結されるものではありません。プロジェクトで決着した判断を積み重ねていくものであり、その判断の多くは、ほかの作業の最中に定まります。
Plans:仕様をコードにつなぐ作業 DAG
仕様は状態(常に満たされるべきこと)を記述します。Plans は進行(次にどう実現するか)を記述します。機能開発の各チャンクは、スコープ、実装する仕様、他の Plans への依存関係、具体的な検証基準を宣言する plans/ 内の plan ファイルから始まります。plan ファイル全体で、プロジェクトの作業計画となるマイクロ DAG を形成します。
Plans は時間軸に沿ったものです。マージ後は履歴記録として固定されます。マージ済み PR へのリンクと完了した検証基準が、何をどのように構築し、何を先送りしたかを示すプロジェクトの作業記憶になります。
plan のフロントマター:
---
status: planned # planned | in-progress | done | blocked | cancelled
depends: [other-plan-slug]
specs: # spec files in THIS repo that this plan implements
- specs/architecture.md
upstream-specs: # (optional) specs in OTHER repos this plan consumes
- other-repo:specs/behaviors/transactions.md
issues: [128]
pr: 42 # set at closeout
---
plan の本文には固定テンプレートがあります:Scope、Implements、Approach、Validation(重要なチェックボックスリスト。「進行中」を「完了」に変換します)、Risks / unknowns、Notes(クローズアウト時に記入)、Follow-ups(クローズアウト時に記入)。
フロントマターのスキーマ、本文テンプレート、ステータスのライフサイクル、ブランチの更新、クローズアウトコミットの手順、Follow-ups の分類(Issue / Deferred to plan / Tracked as / None)、および先送り事項を吸収するルールを含む完全なプロトコルは、references/plans-protocol.md に記載されています。plan の作成、実装、クローズアウトを行う前にお読みください。
実装ブランチは直線的に保ってください: 統合ブランチをマージするのではなく、リベースし、影響を受ける検証を再実行して、クローズアウトを最後に行います。リポジトリポリシーの優先順位、共有ブランチの調整、意味上の解決内容の保持、書き換えた履歴の公開については、ブランチ更新ルールに従ってください。
プランを作成する場合と作成しない場合
specops プロジェクトでは、plans/ の DAG が計画システムです。 エージェントに組み込まれた「プランモード」や、その場限りの計画用スクラッチパッドで代用しないでください。ターンが終わるとそれらは消え、何を構築したのか、なぜ構築したのかが DAG に記録されません。考えるためにスクラッチパッドを使う場合も、成果物は必ずプランファイルとして残してください。特に注意が必要な失敗パターンがあります。「仕様 X を書き、それから構築する」といった一時的なプランを作成し、そのとおりに進めた結果、レビュー済みの仕様変更もプランもどちらも残らないというものです。代わりに分けてください。仕様変更は仕様ファーストのフローで進め、実行作業はプランファイルに記録します。
プランをいつ作成するかは、ユーザーが何をしているかによって異なります。
-
複数の仕様をまとめて整理する場合 — まだ構築には着手せず、複数の仕様にわたる望ましい状態を大まかに描きます。進めながらプランを作成しないでください。 プランは作業の流れを示すものです。望ましい状態がまだ固まっていない間は、仕様ごとにプランを作成すると変更が頻発し、作業を適切に分割できないことがほとんどです。まず一連の仕様を完成させ、その後に全体を見直して、作業を適切な単位に分け、依存関係順に並べたプランのセットを提案してください。適切な分割は、通常、仕様ファイルと一対一には対応しません。内容が固まるまでは、まとめた内容をメインブランチではなくドラフト計画 PR に蓄積します。開発中の仕様の配置場所を参照してください。一連の仕様とプランのセットがそろって確定したら、その PR を更新してマージします。
-
成熟したプロジェクトで、範囲の明確な機能を 1 つ仕様化して構築する場合 — 周辺の仕様が安定しており、範囲も小さい場合です。仕様変更とプランを並行して作成してください。 仕様の更新と、それを実行するためのプランを一緒に作成して提示し、両方が承認されたら進めます。
-
意図が不明確な場合 — ユーザーが仕様をまとめているのか、今すぐ実行する仕様を 1 つ書いているのかが明らかでない場合は、決めつけて進める前に確認してください。「まず仕様を整理してから構築を計画しますか? それとも、今すぐ構築するものが 1 つありますか?」と尋ねます。回答に応じて上記の進め方を選びます。
すぐに終わる単発の作業でも、プランを残してください。 変更が「小さい」からという理由でプランを省きたくなることこそ、DAG が空洞化する原因です。範囲の明確な変更でも、done に固定されるプランファイルを作成します。この固定された記録(マージ済み PR と検証の確認)は、何を構築したのかを示すプロジェクトの作業記憶です。プランを省けば、今の数秒を節約する代わりに、後で変更が未記録になります。(記録する時点ですでに小さな変更の検証が済んでいる場合は、締めくくりのコミットでプランを status: done として直接作成しても構いません。ファイルは同じ PR に含まれます。)
プラン DAG の実行
一連のプランを作成し、レビューして planned にした後、その実装は別途、明示的なトリガーを受けて行うステップです。同じターン内に組み込んではいけません。プランを完成させても、構築への同意を得たことにはなりません。 DAG を実行するかどうかを提案し、人間からトリガーされるまで待ってください。トリガーとなるフレーズは 「drain the DAG」(または、これに相当する明示的な実行指示)です。自分の判断で実装作業の割り当てを始めてはいけません。
トリガーを受けた後、大規模な複数プラン DAG を実行する方法は、依存関係によって制御されるウェーブ方式で、隔離されたワークツリーのサブエージェントを使用し、各ディスパッチのたびにビルダー階層のモデルを明示的に指定して(オーケストレーターから引き継がない)、ウェーブ間にレビュー/マージゲートを設けることです。オーケストレーターは準備済みのプラン群(specops next)を計算し、最新の統合ブランチから準備済みの各プラン用にワークツリーを作成します。それぞれにサブエージェントを割り当て、実装 → プッシュ → PR 作成まで行わせます(マージは禁止)。その後、オーケストレーターがすべての PR をレビューし、直接修正を行い、CI を確認してマージします。マージのたびに、次のウェーブが実行可能になります。エージェントへの指示、レビュー/マージゲート、並列作業での競合解決、エージェントごとのライブ依存関係の隔離、自動実行してはならないプラン(運用上のプランまたはリポジトリ横断のプラン)を含む完全なプロトコルは、references/parallel-execution-protocol.mdに記載されています。実行を開始する前に読んでください。
仕様が変更されたら、影響を受ける計画を見直す
仕様を編集すると、以前の望ましい状態を前提として、すでに計画済みまたは進行中の作業が取り残されることがあります。**仕様を変更するたびに、それを実装する計画を確認し、更新を提案してください。**変更したファイルを specs: フロントマターから grep して、該当する計画を見つけます。
grep -l 'specs/path/to/changed.md' plans/*.md
該当する計画ごとに、planned の計画はスコープ、アプローチ、または検証方法の見直しが必要な場合があります。in-progress の計画については、目標が変更されたことを担当者に知らせてください(実装の途中にある計画を、ひそかに書き換えてはいけません)。これは「仕様が先」の裏返しです。仕様が動いたら、それを追う計画も追いつく必要があります。
計画 DAG の照会
plans/README.md では、手描きの DAG やステータス表を意図的に管理していません。誰かが更新を忘れた途端に、内容が古くなるからです。同梱の specops CLI は、信頼できる計画のフロントマターをその場で照会し、エージェントが扱いやすい TOON 形式で出力します。
計画
scripts/specops next [--include-in-progress] [--slugs-only] [--dir <path>]— 準備状況に応じて計画を並べます。まず準備完了(依存関係が満たされ、待機中の項目がないもの)、次に外部待ち、ブロック中の順で、より多くの作業を進められるものを上位に表示します。scripts/specops dag [--direction TB|LR|BT|RL] [--fence] [--include-cancelled] [--dir <path>]— 計画 DAG の Mermaid グラフを出力します。ノードはステータス別にスタイル分けされ、外部ブロッカーは破線で表示されます。
セッション
scripts/specops hook install [--scope project|global] [--dir <path>] | hook status | hook uninstall [--scope project|global]— 各エージェントセッションの開始時に、このリポジトリの計画ダッシュボードを読み込む SessionStart フックを管理します。
コマンドを指定せずに実行すると(scripts/specops)、現在のリポジトリの計画ダッシュボードを表示します。準備状況の概要、進行中の項目、準備完了の項目、ブロック中の項目、完了した直近の計画(リポジトリが Git チェックアウトの場合は、Git 履歴から日付を取得)を確認できます。依存関係の参照切れや、ブロック理由が記録されていない status: blocked の計画など、管理上の警告はエージェントが確認できるよう stdout に表示されます。
この CLI は、ファイルを中心としたワークフローに、決定性をもたらす薄いレイヤーです。すべての計画ファイルを対象に、準備状況、順序、依存関係グラフ、警告を計算します。これはエージェントが目視だけで確実に行うのが難しい作業です。単一の計画を読んだり編集したりする場合は、ファイルを直接開いてください。意図的に view/show コマンドは用意していません。
これは自己完結型のバンドルとして scripts/specops.mjs に含まれており(scripts/specops シム経由で実行)、npm install や node_modules なしで node ≥ 20 上で動作します。bun run build を使って src/cli/ 内の TypeScript から再ビルドできます。各エージェントセッションで計画ダッシュボードを自動的に読み込むには、リポジトリ内で scripts/specops hook install を一度実行してください。
新しいプロジェクトで仕様主導の開発を始める
まず、このスキルを対象プロジェクトにベンダーとして組み込み、開発手法をコードベースとともに持ち運べるようにします。 プロジェクト単位でインストールすると、すべてのコントリビューターと各自が実行するすべてのエージェントが、同じ仕様と計画の作成方法に従って作業できます。また、同梱の specops CLI は設定不要でリポジトリ内から解決されます。プロジェクトのルートから実行します。
mkdir -p .claude && npx skills add JarvusInnovations/specops -y --skill specops --agent claude-code universal
これにより、スキルが .agents/skills/specops/(エージェントに依存しない標準の保存場所)にインストールされ、.claude/skills/specops からそこへシンボリックリンクが作成されたうえで、skills-lock.json が書き込まれます。インストールを再現可能にするため、この3つすべてをコミットしてください。claude-code とともに universal エージェントを指定することで、このシンボリックリンク構成が選択されます。claude-code のみを対象にインストールすると、共有の .agents/ 保存場所は作成されず、スキルが .claude/skills/ に直接コピーされます。mkdir -p .claude により、エージェントごとのシンボリックリンクがスキップされずに作成されます。後から別のエージェント(例:Codex)を追加するには、その名前を末尾に加えて再実行します。同じ標準の保存場所へのシンボリックリンクが作成されます。--global は、複数のリポジトリで個人利用する場合のみにしてください。その場合は、プロジェクトごとのベンダーとしての組み込みは適用されません。
続いて、次の手順を実施します。
- プロジェクトのルートに
specs/ディレクトリを作成します - ワークフローとディレクトリ構成を記載した
specs/README.mdを作成します - 基盤となる技術的な決定を記載した
specs/architecture.mdを作成します - すでに掲げている原則をまとめた
specs/principles.mdを作成します。すべての実装者の指針となるよう、「Y よりも常に X を優先する」という明確なトレードオフとして、プロジェクトの理念を書き残します。現時点でわかっていることをまとめ、決定が固まるにつれて内容を充実させていきます(仕様を活用し続けるを参照) - 機能領域ごとに、コーディングを始める前に関連する仕様ファイルを作成します
- プロジェクトの CLAUDE.md に specops フックを追加します(以下のCLAUDE.md フックを参照)。これは常に読み込まれる指針であり、エージェントをスキルと計画プロトコルへ誘導します
- 次の規約を確立します。動作を変更する PR では、まず
docs(specs):コミット、その次に計画、その次に実装、最後にクローズアウトを含めます。ブランチは1つとし、計画が完了した状態でマージします(references/plans-protocol.md § 機能ブランチを参照) - 仕様のドリフトを監査する仕組みを設定します(以下を参照)
- 計画プロトコルを設定します(以下を参照)
CLAUDE.md フック
SKILL.md とリファレンスドキュメントには手法の全容が記載されていますが、これらが読み込まれるのはスキルがトリガーされたときだけです。あらゆるターンでコンテキストに含まれるのは、プロジェクトの CLAUDE.md です。そこで、specops が抑制するエージェントのデフォルトの傾向、すなわち、仕様なしでコードをリリースすることや、計画ファイルを書く代わりに組み込みの「計画モード」に移行することに対処します。このブロックは最小限にしてください。その役割は、こうした振る舞いを抑制し、それ以外のすべてについてスキルへ誘導することであり、手法を再記述することではありません。
プロジェクトの CLAUDE.md に、このブロックを挿入します(インストール先に合わせて <specops-skill-path> を調整してください)。これが CLAUDE.md に必要な specops の内容のすべてです。以前の設定手順で別途説明していた監査と計画に関する注記も、このブロックに含まれています。
## Spec-driven development (specops)
This project uses spec-driven development. `specs/` is the source of truth for what
*should be true*; `plans/` is the work-in-flight DAG that bridges specs to merged code.
The **specops** skill carries the full methodology — invoke it (the skill triggers on
"spec", "plan", starting a feature, etc.) before writing specs, planning, or building.
- **Specs lead.** Before changing behavior, change the spec; bring code into conformance
after. Spec↔code drift is a bug, not debt. Specs merge implemented-or-planned; a spec
still being designed rides a draft planning PR, not the main branch.
- **Never a spec-only PR.** Open the branch and PR for the *feature*, start it with the
`docs(specs):` commits and the plan (draft PR is fine), add the implementation on the same
branch, and merge only when the plan is complete.
- **`plans/` is the planning system — not your built-in plan mode.** Every chunk of work
lands as a file in `plans/` that freezes to `done` as the durable record of what got
built. One feature branch carries spec → plan → code → closeout and merges with the plan
complete; the issue tracker, not `plans/`, is the backlog. Don't let an ephemeral plan
substitute for a plan file, and don't skip it for "small" changes. (Classic trap: an
ad-hoc plan of "write spec X, then build it" that ends with neither a reviewed spec nor a
plan file — split those into the two real artifacts.)
- **When to author a plan depends on intent:** mapping out a batch of specs → finish the
batch first, then propose a *set* of plans; speccing one bounded feature in a mature
project → draft the spec change and its plan in tandem; intent unclear → ask. The skill
details each mode.
- **A spec change ripples to its plans.** After editing a spec, review the plans that
implement it (`grep -l '<spec-path>' plans/*.md`) and offer to update them.
Query the DAG: `<specops-skill-path>/scripts/specops next` (what to work on next) and
`<specops-skill-path>/scripts/specops dag` (graph). Run `/audit-spec-drift` to compare
specs against the implementation.
spec drift auditor の設定
spec drift auditor は、specs/ ディレクトリと実際の実装を徹底的に比較し、差分、ドキュメントに記載されていない実装、矛盾を表にまとめる特化型エージェントです。プロジェクトに設定するには、次の手順を実行します。
-
エージェント定義をコピーします。 このスキルの
references/spec-drift-auditor.mdの内容を、プロジェクトの.claude/agents/spec-drift-auditor.mdにコピーします。「Methodology」のフェーズは、プロジェクトの構成に合わせてカスタマイズしてください。たとえば、Phase 3(「Inventory the Implementation」)に、コードベース内の具体的なディレクトリや主要ファイル(ソースディレクトリ、マイグレーションのパス、フロントエンドコード、インフラストラクチャファイルなど)を記載します。 -
コマンド定義をコピーします。 このスキルの
references/audit-spec-drift.mdの内容を、プロジェクトの.claude/commands/audit-spec-drift.mdにコピーします。これにより、監査エージェントを起動する/audit-spec-driftスラッシュコマンドをユーザーが利用できるようになります。 -
CLAUDE.md で参照します。
/audit-spec-driftの参照先は CLAUDE.md フック ブロックにすでに含まれているため、そのブロックを追加すれば、ほかに追加するものはありません。
参照ファイルの場所は次のとおりです。
references/spec-drift-auditor.md— エージェント定義(.claude/agents/に配置)references/audit-spec-drift.md— コマンド定義(.claude/commands/に配置)
注:監査エージェントは、plan ファイルの specs: フィールドと specs/ ツリーを確認します。upstream-specs: は確認しません(設計上、これは別のリポジトリが管理します。plans protocol を参照してください)。
plans protocol の設定
plans protocol を使うと、進行中の作業が放置されて形骸化しないよう、プロジェクトで構造化して追跡できます。設定するには、次の手順を実行します。
- プロジェクトのルートに
plans/ディレクトリを作成します。 plans/README.mdを作成します。 plans とは何か(motion と state)を簡潔に説明し、完全な仕様については references/plans-protocol.md を参照するよう記載します。DAG の図やステータス表をここで管理したい誘惑には負けないでください。どちらもすぐに古くなります。specopsCLI を使えば、必要に応じてそのビューを再生成できます。- プロジェクトの CLAUDE.md に protocol を記載します。 これは CLAUDE.md フック ブロックに含まれています。このブロックでは、plans を計画システムとするルールをすでに示し、ステータス、クローズアウトコミット、Follow-ups の分類を含む完全な protocol についてスキルを参照しています。protocol を CLAUDE.md に重ねて記載せず、簡潔に保ち、詳細はスキルに任せてください。
- スキル内から
specopsCLI をそのまま使用します。scripts/specopsはこのスキルに同梱された自己完結型のバンドルです。スキルのインストールディレクトリから、プロジェクトのplans/を対象に実行してください。コピー、シンボリックリンク、ベンダリングは不要で、npm installも必要ありません(node ≥ 20で動作します)。specops が起動すると、Claude がスキルのパスを自動的に解決します。プロジェクトのルートから実行する場合のコマンドは<specops-skill-path>/scripts/specops next(またはdag)です。必要であれば、<specops-skill-path>/scripts/specops hook installを一度実行すると、リポジトリ内のすべてのセッションで plans ダッシュボードが最初に表示されます。 - チーム内で慣例を定めます。 新しい作業のまとまりは plan ファイルから始め、マージ前の最後のコミットでステータスを
doneに変更します。plan は完了した状態でマージし、課題トラッカーはバックログとして維持します。クローズアウト用のクイックリファレンスチェックリストは references/plans-protocol.md にあります。
仕様書を最新の状態に保つ
仕様書は実態と乖離すると陳腐化します。次の方法で防ぎましょう。
- PR プロセスの一環として仕様書を更新します。コードの変更によって動作が変わる場合は、仕様書も変更します
- 実行中のソフトウェアと照らし合わせて、仕様書を定期的に監査します
- 仕様書とコードの乖離は技術的負債ではなく、バグとして扱います
- 実装前にエージェントに仕様書を読ませます。仕様書に誤りがあった場合、自然なフィードバックループが生まれます
- 決定事項や原則は、確定した時点で記録します(常に:仕様書に記載すべき決定事項や原則に注意するを参照)。プロジェクトで長く役立つ判断の多くはタスクの途中で確定します。そうした判断をスクロールバックではなく仕様書に記録して初めて、仕様書を最新の状態に保てます