schema.yaml
結構定義的每個欄位,用於讀取或寫入。
schema.yaml 列出工作流程建立的規劃檔案,同時定義其順序以及交接至實作階段的方式。
位置
專案結構定義位於 openspec/schemas/<name>/:
openspec/schemas/review-first/
├── schema.yaml
└── templates/
├── proposal.md
└── tasks.mdOpenSpec 會檢查三個位置以尋找該目錄,採用第一個符合的項目。
| 副本 | 目錄 |
|---|---|
| 1. 專案 | <project>/openspec/schemas/<name>/ |
| 2. 使用者,macOS 和 Linux | ~/.local/share/openspec/schemas/<name>/ |
| 2. 使用者,Windows | %LOCALAPPDATA%\openspec\schemas\<name>\ |
| 3. 套件 | 隨 CLI 安裝的結構定義 |
若設定了 XDG_DATA_HOME,則所有平台上的使用者目錄會移至 $XDG_DATA_HOME/openspec/schemas/<name>/。
目錄名稱是 --schema、config.yaml 和 .openspec.yaml 使用的查閱索引鍵。若 name 欄位與目錄名稱不同,OpenSpec 仍會使用目錄名稱進行查閱。
openspec schema which <name> 會印出作用中的目錄,以及任何被其隱藏的較低優先順序副本。
頂層欄位
| 欄位 | 契約 |
|---|---|
name | 必填。 非空字串,儲存為結構定義名稱。查閱仍使用目錄名稱。 |
version | 必填。 正整數,儲存為結構定義修訂版本。此值不會改變 OpenSpec 的行為。 |
description | 由 openspec schemas 印出的選用字串。若無值,則結構定義沒有描述。 |
artifacts | 必填。 成品項目的非空清單。 |
apply | 選用的套用設定。若無此區塊,OpenSpec 會使用套用預設值。 |
成品欄位
artifacts 下的每個項目定義一個規劃檔案或一組檔案。
| 欄位 | 契約 |
|---|---|
id | 必填。 唯一且非空的字串,用於相依性、專案規則、指令和套用設定中。 |
generates | 必填。 相對路徑或 glob,告知代理程式在變更資料夾中寫入成品的位置。 |
description | 必填。 用於在傳送給代理程式的指示中標示成品的字串。 |
template | 必填。 結構定義 templates/ 資料夾中成品格式的相對路徑。 |
instruction | 選用指引,告知代理程式應產生什麼內容。 |
requires | 必須先完成的成品 ID 清單。預設:[]。 |
generates
路徑從變更資料夾開始。對於名為 add-auth 的變更:
generates: proposal.md成品會放在這裡:
openspec/changes/add-auth/proposal.mdglob 可以符合多個檔案:
generates: specs/**/*.md這會符合 openspec/changes/add-auth/specs/ 下的 Markdown 檔案。
OpenSpec 在 generates 中識別以下 glob 形式:
- 萬用字元和字元類別:包含
*、?或[的值,例如specs/**/*.md和review-[ab].md。 - 大括號展開:替代方案,例如
review-{api,ui}.md,以及範圍,例如file-{1..3}.md。 - 擴充 glob:模式,例如
@(proposal|design).md、+(proposal|design).md和!(proposal|design).md。
字面檔案名稱:單獨的前導 ! 不會使其成為 glob。使用 generates: '!review.md' 來命名該檔案。純括號,例如 (proposal|design).md,以及單元素大括號,例如 review-{api}.md,也保持為字面形式。
OpenSpec 會拒絕絕對路徑、包含 .. 區段的路徑,以及大括號或括號巢狀超過 16 層的 glob,例如 {a,{b,{c,...}}}。實際模式只需一層或兩層。它也會拒絕大括號展開為超過 1,024 個模式的 glob,例如重複十一次的 {a,b} 或範圍如 file-{1..5000}.md。錯誤訊息為 Artifact output pattern expands to more than 1024 patterns。實際模式展開為少數幾個。
完成
OpenSpec 會檢查輸出是否存在。它不會讀取檔案來決定成品是否完成。
generates 值 | 完成條件 |
|---|---|
proposal.md | 該檔案存在。 |
specs/**/*.md | glob 至少符合一個檔案。 |
template
路徑從結構定義的 templates/ 資料夾開始。在 review-first 結構定義中:
template: proposal.mdOpenSpec 會讀取此檔案:
openspec/schemas/review-first/templates/proposal.mdOpenSpec 將模板內容作為輸出格式提供給代理程式。它不會將模板複製到變更資料夾中。
OpenSpec 會拒絕絕對路徑和包含 .. 區段的路徑。
requires
- 相依性:
requires中的每個 ID 都必須命名同一結構定義中的另一個成品。 - 就緒狀態:成品在所有相依性完成後即變為就緒。
- 無效圖形:遺失的 ID、重複的 ID 和相依性循環會導致驗證失敗。
- 平手:當有多個成品就緒時,它們在
artifacts中的順序決定 OpenSpec 先返回哪一個。
Apply 欄位
apply 定義實作開始前必須存在的內容。
| 欄位 | 契約 |
|---|---|
requires | 必填。 套用指示變為就緒前必須存在的成品非空清單。 |
tracks | 選用的相對路徑或 glob,用於變更資料夾中的 Markdown 任務檔案。預設:null。 |
instruction | 選用指引,在套用就緒時傳送給代理程式。OpenSpec 預設使用內建指引。 |
成品 requires 控制規劃順序。apply.requires 控制套用指示何時變為就緒。
tracks
路徑從變更資料夾開始。對於名為 add-auth 的變更,tracks: tasks.md 會讀取:
openspec/changes/add-auth/tasks.mdglob,例如 tracks: "**/tasks.md",會讀取每個符合的檔案,例如 backend/tasks.md 和 frontend/tasks.md。OpenSpec 會合併其任務和進度。為成品的 generates 欄位使用相同的值,以便狀態和清單追蹤相同的檔案。generates 的大括號限制(16 層深、1,024 個展開模式)也適用於此處。
若沒有檔案符合,或符合的檔案不包含具有任務文字的核取方塊,則套用會保持封鎖狀態。OpenSpec 會計算以下核取方塊形式:
- [ ] Pending task
- [x] Completed task
* [X] Completed task
+ [ ] Pending task
1. [ ] Pending task
2) [x] Completed task任何 Markdown 清單標記都適用:-、*、+,或最多九位數的數字後接 . 或 )。允許前導空格。規格驅動頁面的 tasks.md 區段定義預設結構定義所產生的更嚴格格式。
追蹤的檔案驅動套用狀態:
blocked:沒有檔案符合,或沒有可讀取的檔案具有帶任務文字的核取方塊。ready:至少有一個待處理任務,或符合的檔案無法讀取而其他檔案提供任務。all_done:每個追蹤的任務都已核取,且每個符合的檔案都已讀取。
若符合的檔案無法讀取,套用會保留可讀取檔案的任務和進度,但不會將變更標記為 all_done。套用 JSON 輸出會識別每個無法使用的檔案及其原因。
OpenSpec 會拒絕絕對路徑和包含 .. 區段的路徑。
套用預設值
| 行為 | 預設值 |
|---|---|
| 必要成品 | 結構定義中的所有成品 |
| 進度追蹤 | 無追蹤檔案 |
| 代理程式指引 | 內建套用指引 |
完整範例
name: review-first
version: 1
description: Proposal and implementation checklist
artifacts:
- id: proposal
generates: proposal.md
description: Why the change is needed and what it affects
template: proposal.md
instruction: |
Explain the problem, the proposed change, and its impact.
requires: []
- id: tasks
generates: tasks.md
description: Trackable implementation checklist
template: tasks.md
instruction: |
Break the approved proposal into ordered implementation tasks.
requires:
- proposal
apply:
requires:
- tasks
tracks: tasks.md
instruction: |
Work through the pending tasks and mark each one complete.驗證
openspec schema validate <name> 會檢查:
- 欄位類型和必填欄位
- 相對路徑
- 成品 ID、相依性和循環
apply.requiresID:每個都必須是結構定義中的成品- 模板檔案
具有未知 apply.requires ID 的結構定義無法載入,因此使用它的每個指令都會報告錯誤。
當 apply.tracks 不完全等於某個成品的 generates 值時,驗證會發出警告但不會失敗。OpenSpec 透過比較這兩個字串來尋找追蹤的成品,因此任何其他情況都會讓它無法判斷檔案屬於哪個成品的進度。這包括拼寫錯誤,例如 task.md,以及 tracks: tasks/main.md 對應 generates: tasks/*.md,其中 glob 確實產生檔案但字串仍然不同。無論哪種方式,套用都會繼續讀取檔案,但 openspec list 和 openspec status 會改為計算 tasks.md。
驗證不會捕捉這些錯誤:
| 錯誤 | 結果 |
|---|---|
欄位拼寫錯誤,例如 instrution | OpenSpec 會忽略它。驗證不會報告拼寫錯誤。 |
name 與結構定義目錄不同 | 驗證通過。OpenSpec 仍會使用目錄名稱進行查閱。 |