Skip to content

OpenSpec エージェント契約

openspec CLI の機械可読なサーフェスを src/ に対して検証済みです(キャップストーン監査、2026-06-11)。以下の各構造体は、出力元コードから文書化されています。

1. 一般規約

  • 1 回の呼び出しにつき 1 つの JSON ドキュメント。 --json モードでは、stdout に厳密に 1 つの JSON ドキュメント(2 スペースの改行あり整形)が出力されます。人間向けの文章、スピナー、ストアバナーは stderr に出力されます。
  • ストアバナー。 人間モードでは、ストアが選択したルートについて Using OpenSpec root: <id> (<path>) を stderr に出力します。JSON モードでは決して出力されません。
  • キーの大文字小文字はサーフェスに依存します(既知の不整合を参照):store/doctor/context ペイロードは snake_case を使用します。ワークフローペイロード(statusinstructionsnew changevalidatelist)は camelCase を使用しますが、埋め込まれた root オブジェクトは常に store_id を使用する点が例外です。
  • オプションのキーは null ではなく省略されます。ほとんどのペイロードでは、オプションのキーは省略され、null にはなりません(例:root.store_idmember.path)。明示的な null を使用する例外は、各構造体ごとに記載されています(store doctor の git.*、失敗ペイロードなど)。

2. 診断エンベロープ

すべての機械可読診断(StoreDiagnostic)で共通のエンベロープ構造が使用されます:

json
{
  "severity": "error" | "warning" | "info",
  "code": "snake_case_string",
  "message": "human sentence",
  "target": "dotted.surface (optional)",
  "fix": "one actionable sentence/command (optional)"
}

診断は2つの位置に表示されます:ステータス配列status: StoreDiagnostic[]、トップレベルまたは各エントリごと)による正常性調査結果、およびコマンド失敗時に単一要素のstatus配列に変換されてスローされるエラーです。

3. ルート選択とRootOutput

すべてのルート解決コマンド(listshowvalidatestatusinstructionsinstructions applynew changearchivedoctorcontext)は、以下の優先順位で1つのOpenSpecルートを解決します:

  1. --store <id> → 登録済みストアのルート(source: "store")。
  2. それ以外の場合、openspec/を含む最寄りの上位ディレクトリ → プランニングシェイプ → source: "nearest"store:ポインタはstderrに警告を出して無視されます);有効なstore:ポインタを持つ設定専用ディレクトリ → そのストア、source: "declared"
  3. 最寄りのルートなし + グローバルdefaultStoreが設定されている場合(openspec config set defaultStore <id>) → そのストア、source: "global_default";古いIDの場合は基盤となるストアエラーとopenspec config unset defaultStoreを指定するfixで失敗します。
  4. 最寄りのルートなし、デフォルトなし + 登録済みストアが存在する場合 → エラーno_root_with_registered_stores
  5. ルートなし、デフォルトなし、ストアなし:スキャフォールディングコマンドはcwdをsource: "implicit"として扱います;診断コマンド(doctorcontext)は代わりにno_openspec_rootで失敗します — これらは検査のみを行い、スキャフォールディングは行いません。

成功したJSONペイロードにはルートが埋め込まれます:

json
"root": { "path": "/abs/path", "source": "store" | "declared" | "global_default" | "nearest" | "implicit", "store_id": "id (only when store-selected)" }

ルート失敗契約:JSONモードでは、解決失敗時にstdoutに{ ...commandNullShape, "status": [diagnostic] }を出力し、終了コード1で終了します。

4. コマンドJSONシェイプ

4.1 list --json

{ "changes": [ { "name", "completedTasks", "totalTasks", "lastModified", "status": "no-tasks"|"complete"|"in-progress" } ], "root": RootOutput } — 各チェンジごとのstatusはここでは文字列列挙型です。--specs{ "specs": [ { "id", "requirementCount" } ], "root" }

4.2 show <item> --json

チェンジ:{ "id", "title", "deltaCount", "deltas": [...], "root" }。スペック:{ "id", "title", "overview", "requirementCount", "requirements": [...], "metadata": { "version", "format", "sourcePath"? }, "root" }

4.3 validate --json

{ "items": [ { "id", "type": "change"|"spec", "valid", "issues": [ { "level", "path", "message", "line"?, "column"? } ], "durationMs" } ], "summary": { "totals": {items,passed,failed}, "byType": {...} }, "version": "1.0", "root" }。いずれかのアイテムが失敗した場合に終了コード1で終了します。

4.4 status --json

{ "changeName", "schemaName", "planningHome"?: { "kind", "root", "changesDir", "defaultSchema" }, "changeRoot", "artifactPaths": { "<id>": {outputPath, resolvedOutputPath, existingOutputPaths} }, "nextSteps": ["..."], "actionContext": { "mode": "repo-local", "sourceOfTruth": "repo", "planningArtifacts", "linkedContext", "allowedEditRoots", "requiresAffectedAreaSelection", "constraints" }, "isComplete", "applyRequires", "artifacts": [ {id, outputPath, status: "done"|"skipped"|"ready"|"blocked", requires, missingDeps?} ], "root" }。各アーティファクトのrequiresはその直接依存IDです(すべてのステータスに存在するため、アーティファクトがdoneの場合でも推移的必須セットを計算可能です);missingDepsblockedの場合にのみ表示されます。"skipped"は、チェンジの.openspec.yamlskip_specs: trueを宣言している場合に、generatesパスがspecs/の下にあるアーティファクトにマークされます — 依存関係は満たされますが、作成してはなりません。アクティブなチェンジなし:{ "changes": [], "message", "root" }、終了コード0。

4.5 instructions <artifact> --json

{ "changeName", "artifactId", "schemaName", "changeDir", "planningHome"?, "outputPath", "resolvedOutputPath", "existingOutputPaths", "description", "instruction"?, "context"?, "rules"?, "references"?: ReferenceIndexEntry[], "skipped"?, "warning"?, "template", "dependencies": [{id,done,path,description,skipped?}], "unlocks", "root" }"skipped": true"warning"と共に)は、チェンジがskip_specs: trueを宣言し、このアーティファクトがスキップされる場合に表示されます — ファイルを作成しないでください。skipped: trueの依存関係エントリは、ファイルなしで満たされます — パスを読み取ろうとしないでください。

ReferenceIndexEntry{ "store_id", "root"?, "specs"?: [{id,summary}], "fetch"?, "status": [] } — 解決済みエントリはroot/specs/fetchを保持;未解決エントリはstore_id + 警告ステータスを保持。インデックスは50KBで制限されます(reference_index_truncated)。

4.6 instructions apply --json

{ "changeName", "changeDir", "schemaName", "contextFiles": { "<artifactId>": ["/abs", ...] }, "progress": {total,complete,remaining}, "tasks": [{id,description,done}], "state": "blocked"|"all_done"|"ready", "missingArtifacts"?, "instruction", "references"?, "root" }

4.7 new change <name> --json

成功時:{ "change": { "id", "path", "metadataPath", "schema" }, "root" }。失敗時:{ "change": null, "status": [d] }、終了コード1。

4.8 archive <name> --json

成功時:{ "archive": { "change", "archivedAs": "YYYY-MM-DD-name", "path", "specsUpdated", "totals"? }, "root" }。失敗時:{ "archive": null, "root"?, "status": [d] }、終了コード1。JSONモードは厳密に非インタラクティブです:すべてのプロンプトポイントがarchive_*コードになります。

4.9 doctor --json

{ "root": { "path", "source", "store_id"?, "healthy", "status": [] }, "store": { "id", "metadata": {present,valid,remote?}, "origin_url"?, "drift"?: {ahead,behind}, "status": [] } | null, "references": [...], "status": [] }drift(git対応ストアチェックアウトでアップストリームトラッキング参照がある場合にのみ存在)は、ライブリモートではなく最後にフェッチしたアップストリームに対するahead/behindカウントです。重大度を問わず正常性調査結果がある場合、終了コード0。失敗ペイロード:{ "root": null, "store": null, "references": [], "status": [d] }、終了コード1。

4.10 context --json

{ "root": { "path", "source", "store_id"?, "role": "openspec_root" }, "members": [ { "role": "referenced_store", "id", "path"?, "remote"?, "fetch"?, "status": [] } ], "status": [] }。AVAILABLE = パスが存在 かつ ステータスが空。--code-workspace <path>{folders:[{name,path}]}を書き込みます(利用可能な参照ストアのみ、ref:プレフィックス付き);JSONモードでは書き込みが出力前に行われるため、書き込み失敗時でもstdoutには常に1つのドキュメントのみが含まれます。失敗時:{ "root": null, "members": [], "status": [d] }、終了コード1。

4.11 store ... --json

setup/register:{ "store": {id, root, metadata_path?}, "registry": {path, registered, already_registered}, "git": {is_repository, initialized, committed}, "created_files": [], "status": [] }。unregister/remove:{ "store", "registry": {path, removed}, "files": {deleted, deleted_path, left_on_disk}, "status": [] }。list:{ "stores": [{id, root}], "status": [] }。doctor:{ "stores": [ { id, root, metadata_path?, openspec_root: {...healthy, status}, metadata: {present, valid, id?, remote}, git: {is_repository, has_commits, has_uncommitted_changes, has_remote, origin_url}, status } ], "status": [] }null = 不明/プローブされていません)。正常性調査結果がある場合は終了コード0;失敗時は終了コード1で対応するnullシェイプを出力。プロンプトキャンセルは終了コード130。

4.12 schemas --json / templates --json

schemas:ベア配列[ {name, description, artifacts, source} ]templates:キー付きオブジェクト{ "<artifactId>": {path, source} }。両方ともcwdベースで、root/statusキーはありません。

5. 終了コード契約

状況終了コードStdout
成功、正常性調査結果を含む(doctor/context/store doctor)0ペイロード
--jsonモードでのコマンド失敗1status: [d]とコマンドのnullシェイプを含む1つのJSONドキュメント
失敗アイテムを含むvalidate1完全なレポート
プロンプトキャンセル(storeグループ、人間モード)130stderrのみ

6. 診断コードカタログ

解決

no_openspec_rootno_root_with_registered_storesno_registered_storesunknown_storestore_identity_mismatchunhealthy_store_rootstore_path_not_supportedinvalid_store_pointerinitiative_option_removedareas_option_removed;パススルー:invalid_store_idinvalid_store_registryinvalid_store_metadata

OpenSpecルート正常性(エラー、修正なし)

openspec_store_root_missingopenspec_store_root_not_directoryopenspec_root_missingopenspec_root_not_directoryopenspec_config_missingopenspec_config_not_fileopenspec_specs_not_directoryopenspec_changes_not_directoryopenspec_archive_not_directory。ストアベータ期間中、openspec/specs/openspec/changes/openspec/changes/archive/は正常なルートに存在しない場合があります;存在するがディレクトリでない場合にのみ正常性エラーとなります。

ストアレジストリ/アイデンティティ/状態

invalid_store_idinvalid_store_registryinvalid_store_metadatastore_registry_busystore_not_foundno_store_registrystore_registry_changedstore_metadata_missingstore_metadata_id_mismatchstore_metadata_invalidstore_id_conflictstore_path_conflictstore_already_registered(info)。

ストアセットアップ/登録/削除

store_setup_id_requiredstore_setup_path_requiredstore_setup_path_not_directorystore_setup_inside_git_repostore_setup_non_empty_directorystore_setup_cancelledstore_path_requiredstore_path_missingstore_path_not_directorystore_root_pointer_declaredstore_register_root_unhealthystore_register_identity_confirmation_requiredstore_register_cancelledstore_remote_emptystore_remote_requires_hand_editstore_remove_confirmation_requiredstore_remove_cancelledstore_remove_path_not_directorystore_remove_metadata_missingstore_root_missing(removeでは警告、doctorではエラー)、store_root_not_directory

ストアGit

store_git_init_failedstore_git_identity_missingstore_git_commit_failedstore_git_no_commits(警告)、store_clone_fragile_directories(警告)、store_remote_divergence(info、doctor)、store_checkout_drift(info、doctor)。

参照(警告)

reference_invalid_idreference_registry_unreadablereference_unresolvedreference_root_unhealthyreference_index_truncated

リレーションシップ(警告;doctor;contextはレジストリのもののみ保持)

relationship_registry_unreadableroot_pointer_ignoredroot_pointer_invalidpointer_declarations_inert

アーカイブ(JSONモード)

archive_change_name_requiredarchive_change_not_foundarchive_validation_failedarchive_confirmation_requiredarchive_tasks_incompletearchive_spec_update_failedarchive_spec_validation_failedarchive_target_existsarchive_error

コンテキスト書き込み

context_file_existscontext_output_dir_missing

フォールバック

doctor_failedcontext_failedstore_errorchange_errorarchive_error

既知の非整合性

キャップストーン監査で記録;公開キー名変更は本リリース後に延期される製品決定です:

  1. --jsonモードでは、いくつかの失敗パスがJSONドキュメントなしでstderrのみを出力していました。 キャップストーンガントレットラウンドで修正済み:show/validateの不明および曖昧なアイテムは{status:[{code: unknown_item | ambiguous_item, ...}]}を出力;status/instructions/list/show/validateのスローエラーはJSON対応失敗ヘルパーを経由(コマンドのnullシェイプ + status);store <unknown subcommand> --json{status:[{code: unknown_store_subcommand}]}を出力;listは解決失敗時に{changes|specs: [], root: null}のnullシェイプを保持します。
  2. store_root_missingは2つの重大度で出力されます(removeでは警告、store doctorではエラー)— 文脈依存、上記で記載。
  3. snake_case(ストアファミリー)とcamelCase(ワークフローファミリー)のキー大文字規則;root.store_idは常にsnake_case。
  4. srcに4つの並列エンベロープ型宣言が存在;アーカイブ診断はtargetを一切持ちません。
  5. list --jsonは各チェンジごとにstatusキーを文字列列挙型として再利用します。
  6. validate出力のみがversionフィールドを持ちます。
  7. schemas/templatesはルート選択を無視します(cwdベース、--storeなし)。
  8. 非推奨の名詞形式(change/specサブコマンド)はroot/statusのない非エンベロープペイロードを出力します。