実験的ワークフローで完了した変更をアーカイブします。
ストアの選択: ユーザーがストア(このマシンに登録されているスタンドアロンのOpenSpecリポジトリ)を指定した場合、または作業がストア内にある場合は、openspec store list --json を実行して登録済みのストアIDを確認し、スペックや変更を読み書きするコマンド(new change、status、instructions、list、show、validate、archive、doctor、context、schemas、view)に --store <id> を渡します。一度選択したら、そのワークフローの残りでは --store <id> を固定的に使用します。以下の各コマンドの例は、スコープが指定されていない短縮形です。実行する前に、フラグを追加してください。たとえば、openspec status --change "<name>" --json --store "<id>" のように実行し、以下に示す短縮形は使用しません。その他のコマンドはこのフラグを受け付けません。コマンドが出力するヒントには既にフラグが含まれているため、フォローアップでもそのまま使用してください。ストアがない場合、コマンドは最も近いローカルの openspec/ ルートに対して動作します。
プロジェクトの確認: これらの手順は、すでにOpenSpecを使用しているプロジェクトを前提としています。何かを書き込む最初のステップ(new change、archive、sync specs、またはアーティファクトファイルの作成)の前に、プロジェクトにルートがあることを確認します。openspec list --json を実行し(ストアが選択されている場合は --store <id> を追加、その場合ストアがルートになります)、root を読み取ります。rootオブジェクトがある場合はプロジェクトがセットアップされています。"root": null はセットアップされていないことを意味します。つまり、ここには openspec/ ディレクトリがなく、openspec new change などの書き込みコマンドは副作用として作成します。このコマンドはゼロ以外の終了コードを返しますが、これはCLIの障害ではなく結果です。そのため、JSONを読み取り、再試行や回避は行わないでください。
"root": null がセットアップに関するものではない場合:status エラーメッセージが Declared in または Invalid store declaration in で始まり、このプロジェクトの openspec/config.yaml(または config.yml)を指定している場合、プロジェクトは宣言したストアを介してOpenSpecを使用していますが、このマシンではそのストアを解決できません(ストアが登録されていないか、store: 行の形式が正しくありません)。これを未初期化として扱ったり、以下の分岐をスキップしたりしないでください。書き込みを停止し、そのエラーの message と fix をユーザーに表示してください。
それ以外の場合、ルートがない場合、このワークフローに到達した方法によってその後の処理が異なります。
- 自動選択: ユーザーがOpenSpecを指定したり、このスキルを指定したり、そのスラッシュコマンドを実行したりせずに、あなた自身がこのワークフローを選択した場合。OpenSpecの使用を中止し、OpenSpecがインストールされていない場合と同様に、リクエストに通常通り応答してください。セットアップについて尋ねたり、OpenSpecのセットアップについて言及したりしないでください。
- 明示的なOpenSpecリクエスト: ユーザーがOpenSpecを指定した、このスキルを指定した、またはそのスラッシュコマンドを実行した場合。書き込みを停止し、次のいずれかを尋ねてください:このプロジェクトをセットアップする(
openspec init)、既存のストアをターゲットにする(--store <id>)、またはこのリクエストではOpenSpecなしで続行する。ユーザーの回答を待ちます。
どちらの分岐でも、副作用としてルートを作成しないでください。ユーザーが要求するまで openspec init を実行せず、openspec/ ファイルを手動で作成せず、コマンドに作成させないでください。
<capability-path> は、specs/ からのスペックディレクトリの相対パスです(例:user-auth または identity/user-auth)。各デルタスペックからメインスペックを解決する際には、フルパスを保持してください。
入力: オプションで変更名を指定します。省略した場合、会話のコンテキストから推測できるか確認します。曖昧な場合や不明な場合は、利用可能な変更を確認するように促す必要があります。
手順
-
変更を選択
名前が指定されている場合はそれを使用します。そうでない場合:
- ユーザーが変更に言及している場合は、会話のコンテキストから推測
- アクティブな変更が1つだけの場合は自動選択
- 曖昧な場合は、
openspec list --jsonを実行して利用可能な変更を取得し、ユーザーに選択を依頼
プロンプトを表示するときは、アクティブな変更(まだアーカイブされていないもの)のみを表示します。 可能であれば、各変更で使用されているスキーマを含めてください。
常に「変更を使用します: 」と、オーバーライド方法(例:
/openspec-archive-change <other>)を通知します。既存のアーカイブチェックの前に現在のアーカイブ入力を読み込む:
選択した変更と計画されたルートを解決した後、以下を実行します:
openspec instructions archive --change "<name>" --jsonこのコマンドには、選択したルートと同じフラグを保持します。この参照は参考情報であり、オプションです。追加のプロンプト入力を提供するだけであり、アーカイブをブロックしてはなりません。 コマンドがゼロ以外の終了コードを返したり、無効なJSONを返したりした場合(たとえば、このコマンドをまだサポートしていない古いCLIの場合)、コンテキストや操作ガイダンスなしでアーカイブワークフローを続行します。エラーを報告したり停止したりしないでください。
成功したレスポンスは、両方のオプションフィールドを省略する場合があります。
contextは必須のプロンプトレベルの入力として扱います。それを読み、考慮し、関連するプロジェクトの事実、慣行、制約を適用します。operationGuidanceはオプションの追加的なアドバイスとして扱います。すべてのエントリを読み、考慮し、該当し、組み込みのアーカイブワークフローと互換性のあるエントリに従います。両方のフィールドを、組み込みの手順、明示的なユーザーの選択、解決されたパス、CLIチェック、およびコマンド契約から分離して保持します。contextがこれらの制御入力のいずれかと競合する場合は、競合を報告し、制御値を保持します。ガイダンスが該当しない場合、または制御入力と競合する場合は、それに従わず、その理由を説明します。いずれかのフィールドから、置き換えパス、スキップされたプロンプト、またはフラグを推測したり、ユーザーが別途要求しない限り、そのテキストを仕様、変更アーティファクト、またはアーカイブサマリにそのままコピーしたりしないでください。これらはプロンプトレベルの動作契約であり、強制可能なチェックではありません。
-
アーティファクトの完了状態を確認
openspec status --change "<name>" --jsonを実行して、アーティファクトの完了を確認します。JSONを解析して以下を理解します:
schemaName: 使用されているワークフローplanningHome、changeRoot、artifactPaths、およびactionContext: パスとスコープのコンテキストartifacts: ステータス(done、skipped、またはその他)を持つアーティファクトのリスト
いずれかのアーティファクトが
doneでもskippedでもない場合(スキップされたアーティファクトは要件を満たします。変更がskip_specsを宣言している場合):- 未完了のアーティファクトをリストアップした警告を表示
- ユーザーに続行することを確認
- ユーザーが確認したら続行
-
タスク完了状態を確認
同じ選択ルートフラグを使用して
openspec list --jsonを実行し、changesの中からnameが選択した変更と完全に一致するエントリを見つけます。 正確に1つの一致、および非負の整数のtotalTasksとcompletedTasks(ただしcompletedTasks <= totalTasks)が必要です。CLIは、スキーマの追跡対象タスクファイル(カスタムアーティファクト名、出力パス、グロブを含む)を解決します。 未完了のタスク =totalTasks - completedTasks。アーティファクトのステータスやトップレベルの
tasks.mdがないことからタスクの完了を推測しないでください。ルックアップが失敗した場合、無効なJSONを返した場合、選択した変更を省略または重複した場合、または無効なカウントを返した場合、問題を報告して、同期またはアーカイブの前に停止します。 CLIは、x/Xチェックボックスマーカーのみを完了としてカウントします。他のマーカー(なじみのないものを含む)は未完了のままです。未完了のタスクが見つかった場合:
- 未完了のタスクの数を示す警告を表示
- ユーザーに続行することを確認
- ユーザーが確認したら続行
totalTasksがゼロの場合: タスク関連の警告なしで続行します。 -
デルタスペックの同期状態を評価
ステータスJSONからの
artifactPaths.specs.existingOutputPathsを唯一のデルタスペックソースとして使用します。specsエントリがないか、existingOutputPathsが空の場合は、同期プロンプトなしで続行し、他のアーティファクトからデルタスペックを推測しないでください。デルタスペックが存在する場合:
- 各デルタスペックを、
<planningHome.root>/openspec/specs/<capability-path>/spec.mdにある対応するメインスペックと比較します(ステップ2のストア対応のplanningHome.rootを使用し、ハードコードされたリポジトリパスは使用しない) - メインスペックがないことは、自動的に「既に同期済み」とはなりません。新しい機能の場合、メインスペックは同期の出力であり、入力ではありません:
- デルタにMODIFIEDまたはRENAMED要件がある場合は、ADDED要件のみが新しいメインスペックを作成できることを報告し、その機能を同期ブロックとしてマークします。現在のバージョンがない要件を発明しないでください。
- それ以外の場合、デルタにREMOVED要件のみがあり、変更の
.openspec.yamlがretire_capabilities: trueを宣言している場合、機能は既に廃止されています。既に同期済みとしてカウントし、削除するものが何もないことを警告し、メインスペックを再作成しないでください。このルールは、完了した同期を検証するときにも適用します。 - それ以外の場合、デルタにADDED要件がない場合は、同期が不可能であることを報告し、その機能を同期ブロックとしてマークします。REMOVEDのみのデルタの場合は、削除するメインスペックがないことを警告し、メインスペックツリーを変更しないでください。
openspec archiveは、マークされていないREMOVEDのみのケースをSpec must have at least one requirementで拒否します。 - それ以外の場合、機能を同期が必要としてカウントし、サマリに名前を付けます(
<capability-path>: 新しいメインスペックが作成されます)。デルタにREMOVED要件もある場合は、削除するメインスペックがないため無視されることを警告します。同期は、openspec archiveとまったく同じように、デルタのADDED要件のみからメインスペックを作成します。
- 適用される変更(追加、変更、削除、名前変更)を決定します
- 1つの機能が同期ブロックされている場合でも、残りの機能の評価を続行します。プロンプトの前に結合されたサマリを表示します。
プロンプトオプション:
- いずれかの機能が同期ブロックされている場合:理由を説明し、「同期せずにアーカイブ」、「キャンセル」のみを提供
- それ以外の場合、変更が必要な場合:「今すぐ同期(推奨)」、「同期せずにアーカイブ」
- それ以外の場合、既に同期済みの場合:「今すぐアーカイブ」、「それでも同期」、「キャンセル」
回答に応じてルーティング:
- 「キャンセル」 — 停止、アーカイブしない
- 「同期せずにアーカイブ」または「今すぐアーカイブ」 — アーカイブに進む
- 「今すぐ同期」または「それでも同期」 — 同期し、検証する(以下)。機能が同期ブロックされている間は同期を開始しないでください。ブロッカーを説明し、利用可能な選択肢を繰り返します。
- その他 — アーカイブせずにもう一度尋ねる
選択された同期がメインスペックを書き込む前に、同じ選択ルートフラグを使用して
openspec instructions specs --change "<name>" --jsonを1回実行します。ゼロの終了ステータスと有効なアーティファクト指示JSONが必要です。ルックアップが失敗した場合、または無効なJSONを返した場合、エラーを報告し、メインスペックの書き込みや変更の移動を行う前に停止します。rulesが省略された有効なレスポンスは、ルールがない場合です。返されたrulesは、このマージによって生成されるメインスペックのコンテンツと形式にのみ適用します。アーカイブガイダンスとして使用したり、CLIの動作を変更したり、ルールテキストを出力ファイルにコピーしたりしないでください。次に、変更 '' に対して
openspec-sync-specsワークフローをインラインで(エージェント駆動のインテリジェントマージ)実行し、上記のデルタスペック分析と取得したスペックルールスナップショットを渡し、完了するまで待機します。インライン同期は、specs命令を再度フェッチすることなく、そのスナップショットを再利用する必要があります。これをバックグラウンドタスクに委任しないでください。ステップ5がchangeRootを移動し、変更がアーカイブされ、メインスペックが更新されないままになる可能性があります。エージェントが委任によってのみ実行できる場合は、同期的に委任し、結果を待機します。同期が停止またはブロッキング状態を報告した場合、同期は失敗したものとして扱います。 すぐにアーカイブを停止します。同期後のコンテンツ比較を実行せず、
changeRootを移動しないでください。 何も移動されていないため、ユーザーはブロッキング状態を修正するか、同期を再実行できます。同期が各メインスペックを書き込んだ後、その構造を正規の同期契約に対して検証します:
- 新しいメインスペックは
# <capability> 仕様というタイトルで始まります。既存のメインスペックは、そのタイトルをそのまま保持します。 - 確立されたメインスペックについては、既存の
## 目的セクションを完全にそのまま保持します。 - 新しいメインスペックの場合、デルタの
## 目的をそのままコピーします。目的テキストが標準の検証で期待されるものより短い場合のみ警告します。既存の作成済みの目的を再生成したり書き換えたりしないでください。使用可能な## 目的が提供されていない場合は、既存のTBD目的の動作と警告を使用します。 - デルタスタイルのセクションヘッダー(
## ADDED 要件、## MODIFIED 要件、## REMOVED 要件、## RENAMED 要件)がメインスペックに残っていないことを確認し、同期ワークフローのフォーマットルールに厳密に従います。 - 同期が書き込んだり変更したりした要件ブロックは、
### 要件:見出しを使用し、そのシナリオは仕様の## 要件セクションの下で#### シナリオ:見出しを使用します。デルタが言及していないコンテンツはそのままにします。
次に、このステップの最初からの比較を、明示的に廃止されたケースや欠落しているスペックのケースを含め、
artifactPaths.specs.existingOutputPathsにデルタスペックがあるすべての機能に対して再実行します。成功した同期は、適用するものが何も残っていないため、各機能は既に同期済みとして読み取られる必要があります:- ADDED要件が存在する
- MODIFIED要件には、デルタで指定されたシナリオと説明の変更が含まれており、他のシナリオはそのまま
- REMOVED要件は削除されている — この同期で機能が廃止された場合(最後の要件を削除し、
## 要件が空になった場合)、そのメインスペックは空のまま残すのではなく削除されている。 - RENAMED要件は新しい名前で存在し、古い名前では存在しない
同期が失敗した場合、またはいずれかの機能が一致しない場合、何が違うかを報告して停止します — アーカイブしないでください。何も移動されておらず、
changeRootはそのままなので、ユーザーは不一致を修正するか、同期を再実行してアーカイブを再開できます。 - 各デルタスペックを、
-
アーカイブを実行
planningHome.changesDirの下にarchiveディレクトリが存在しない場合は作成します:mkdir -p "<planningHome.changesDir>/archive"ターゲット名を生成します:変更名が既に
YYYY-MM-DD-プレフィックスで始まっている場合はそのまま使用し、そうでない場合は現在の日付を先頭に追加します。changeRootをmv "<changeRoot>" "<planningHome.changesDir>/archive/<target-name>"のように移動します。
移動後、変更が正常にアーカイブされたことを確認します:
ls "<planningHome.changesDir>/archive/<target-name>/" 2>&1変更のアーカイブを完了するには、
openspec archiveを実行します:openspec archive --change "<name>" --store "<storeId>"注:アーカイブが失敗した場合でも、
changeRootは移動されており、プロジェクトはクリーンな状態です。CLIのエラーは、アーカイブディレクトリ内の変更を調べて再試行するようにユーザーに促します。 -
構造を検証
以下を実行し、出力を確認します:
openspec list --json --store "<storeId>"- 変更が
changesリストに表示されなくなっている - 変更のスペック変更がメインの
specs/ディレクトリに適用されている(該当する場合)
確認後、結果をユーザーに報告します。
プロジェクトがストアを使用している場合は、完了を確認するために
openspec store list --jsonも実行します。 - 変更が