概念
本指南說明 OpenSpec 的核心概念,以及各概念之間的關聯。實際使用方式請參閱 入門指南 與 工作流程。
理念
OpenSpec 圍繞以下四項原則建構:
靈活而非僵化 — 無階段關卡,專注於合理的工作事項
迭代而非瀑布式 — 建置過程中持續學習,逐步優化
簡易而非複雜 — 輕量級設定,減少繁文縟節
棕地優先 — 適用於現有程式碼庫,不限於從零開始的綠地專案為何這些原則至關重要
靈活而非僵化。 傳統規格系統會將工作侷限在固定階段:先規劃、再實作、最後完成。OpenSpec 更具彈性——你可以根據工作需求,以任何合理的順序建立產出物。
迭代而非瀑布式。 需求會不斷變動,認知也會逐步深化。起初看似可行的方案,在深入瞭解程式碼庫後可能不再適用。OpenSpec 擁抱這種現實。
簡易而非複雜。 部分規格框架需要繁雜的設定、僵化的格式,或沉重的流程。OpenSpec 不會干擾你的工作流程,幾秒即可完成初始化,立刻就能開始工作,僅在需要時進行自訂。
棕地優先。 大部分軟體工作並非從零開始建置,而是修改現有系統。OpenSpec 採用基於差異的方法,能輕鬆規格化現有行為的變更,而不僅僅是描述新系統。
整體架構
OpenSpec 將你的工作分為兩個主要區域:
┌────────────────────────────────────────────────────────────────────┐
│ openspec/ │
│ │
│ ┌─────────────────────┐ ┌───────────────────────────────┐ │
│ │ specs/ │ │ changes/ │ │
│ │ │ │ │ │
│ │ 唯一的真實來源 │◄─────│ 建議的修改內容 │ │
│ │ 描述系統目前的運作 │ 合併 │ 每個變更 = 一個資料夾 │ │
│ │ │ │ 包含產出文件 + 增量規格 │ │
│ │ │ │ │ │
│ └─────────────────────┘ └───────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────┘Specs(規格文件) 是唯一的真實來源——描述你系統目前的運作方式。
Changes(變更提案) 是建議的修改內容——在你準備合併之前,它們會存放在獨立的資料夾中。
這種分離設計是核心要點:你可以同時進行多個變更提案而不會產生衝突;可以在變更影響主規格文件之前先行審查;當歸檔變更時,其增量內容會乾淨地合併進真實來源中。
Specs
Specs(規格文件)透過結構化的需求與場景描述系統的運作行為。
結構
openspec/specs/
├── auth/
│ └── spec.md # 驗證行為
├── payments/
│ └── spec.md # 支付流程處理
├── notifications/
│ └── spec.md # 通知系統
└── ui/
└── spec.md # UI 行為與主題依領域組織規格文件——也就是對你的系統而言有意義的邏輯分組。常見模式:
- 依功能領域劃分:
auth/、payments/、search/ - 依元件劃分:
api/、frontend/、workers/ - 依界限上下文劃分:
ordering/、fulfillment/、inventory/
規格格式
一份規格文件包含需求,每個需求下又有對應的場景:
markdown
# 驗證規格書
## 目的
應用程式的驗證與工作階段管理功能。
## 需求
### 需求:使用者驗證
系統應在使用者成功登入時核發 JWT 權杖。
#### 場景:憑證有效
- GIVEN 一位持有有效憑證的使用者
- WHEN 使用者提交登入表單
- THEN 返回 JWT 權杖
- AND 使用者被重新導向至儀表板
#### 場景:憑證無效
- GIVEN 無效憑證
- WHEN 使用者提交登入表單
- THEN 顯示錯誤訊息
- AND 不核發任何權杖
### 需求:工作階段逾期
系統必須在 30 分鐘無活動後使工作階段失效。
#### 場景:閒置逾時
- GIVEN 已驗證的工作階段
- WHEN 經過 30 分鐘無任何活動
- THEN 工作階段失效
- AND 使用者必須重新驗證關鍵元素:
| 元素 | 用途 |
|---|---|
## Purpose | 本規格領域的高階說明 |
### Requirement: | 系統必須具備的特定行為 |
#### Scenario: | 需求在實際運作中的具體範例 |
| SHALL/MUST/SHOULD | RFC 2119 關鍵字,用於標示需求的強制程度 |
為何採用此規格結構
需求是「做什麼」——說明系統應該達成什麼目標,但不指定實作方式。
場景是「何時發生」——提供可驗證的具體範例。優質的場景:
- 可進行測試(你可以為其編寫自動化測試)
- 同時涵蓋正常流程與邊界情況
- 使用 Given/When/Then 或類似的結構化格式
RFC 2119 關鍵字(SHALL、MUST、SHOULD、MAY)用於傳達需求強度:
- MUST/SHALL — 強制性要求
- SHOULD — 建議遵循,但允許例外
- MAY — 可選項目
規格文件的定位(能做與不能做的事)
規格文件是行為契約,而非實作計畫。
優質規格文件的內容應包含:
- 使用者或下游系統依賴的可觀察行為
- 輸入、輸出與錯誤條件
- 外部限制(安全性、隱私性、可靠性、相容性)
- 可進行測試或明確驗證的場景
規格文件中應避免出現:
- 內部類別/函式名稱
- 程式庫或框架的選擇
- 逐步實作細節
- 詳細執行計畫(這類內容應放在
design.md或tasks.md中)
快速驗證原則:
- 如果實作方式變更不會影響外部可見行為,那麼這類內容大概率不屬於規格文件。
保持輕量:漸進式嚴格度
OpenSpec 旨在避免官僚流程,請使用能確保變更可驗證的最低強度等級。
輕量規格(預設):
- 簡短的行為導向需求
- 清楚的範圍與非目標
- 數項具體的驗收標準
完整規格(適用於高風險場景):
- 跨團隊或跨程式庫的變更
- API/介面合約變更、遷移、安全性/隱私性相關變更
- 模糊性可能導致高成本返工的變更
大部分變更應使用輕量模式即可。
人機協作模式
在多數團隊中,人類負責探索方向,AI 代理負責起草產出文件,預期的流程如下:
- 人類提供意圖、上下文與限制條件。
- AI 代理將其轉換為行為導向的需求與場景。
- AI 代理將實作細節保留在
design.md與tasks.md中,而非spec.md。 - 在實作前透過驗證確認文件的結構與清晰度。
這樣能確保規格文件對人類而言易於閱讀,對 AI 代理而言則保持一致。
變更提案
變更提案是對系統的建議修改內容,被封裝成一個資料夾,內含理解與實作該變更所需的所有文件。
變更結構
openspec/changes/add-dark-mode/
├── proposal.md # 原因與內容
├── design.md # 實作方式(技術方案)
├── tasks.md # 實作檢查清單
├── .openspec.yaml # 變更中繼資料(選填):schema、建立時間、跳過規格檢查
└── specs/ # 增量規格
└── ui/
└── spec.md # ui/spec.md 的變更內容每個變更都是獨立的,包含以下內容:
- Artifacts(產出文件):記錄意圖、設計與任務的文件
- Delta specs(增量規格):描述新增、修改或刪除內容的規格文件
- Metadata(中繼資料):針對此特定變更的選填配置
為何將變更封裝為資料夾
將變更封裝為資料夾有以下好處:
- 所有內容集中存放:提案、設計、任務與規格文件都在同一個位置,無需在多個地方搜尋。
- 支援平行作業:多個變更可同時存在而不會產生衝突,例如在進行
add-dark-mode的同時,也可以推進fix-auth-bug的變更。 - 完整的歷史紀錄:歸檔時變更會連同完整上下文一起移至
changes/archive/,往後查詢時不僅能知道改了什麼,還能理解背後的緣由。 - 便於審查:變更資料夾易於審閱——打開資料夾、閱讀提案、查看設計、確認規格增量即可。
產出文件
Artifacts(產出文件)是變更中用於引導工作的各類文件。
產出文件流程
proposal ──────► specs ──────► design ──────► tasks ──────► implement
│ │ │ │
原因 內容 方式 步驟
+ 範圍 變更內容 方案 執行各產出文件層層遞進,每一份文件都為下一份提供上下文。
產出文件類型
提案(proposal.md)
提案在高階層面記錄意圖、範圍與方案。
markdown
# 提案:新增深色模式
## 意圖
使用者請求新增深色模式選項,以減少夜間使用時的視覺疲勞,並符合系統偏好設定。
## 範圍
範圍內:
- 設定頁面中的主題切換開關
- 系統偏好偵測
- 將偏好設定儲存至 localStorage
範圍外:
- 自訂色彩主題(後續功能)
- 單頁面主題覆蓋設定
## 方案
使用 CSS 自訂屬性實現主題切換,搭配 React Context 進行狀態管理。首次載入時偵測系統偏好,同時允許使用者手動覆蓋。提案更新時機:
- 範圍發生調整(縮小或擴大)
- 意圖更加明確(對問題有更深入的理解)
- 方案發生根本性調整
規格文件(specs/ 中的增量規格)
增量規格描述相對於目前規格的變更內容,詳見下方的 增量規格 小節。
設計文件(design.md)
設計文件記錄技術方案與架構決策。
markdown
# 設計:新增深色模式
## 技術方案
主題狀態透過 React Context 管理,避免屬性透傳。CSS 自訂屬性支援執行時切換,無需切換 class。
## 架構決策
### 決策:採用 Context 而非 Redux
選擇 React Context 管理主題狀態的原因:
- 僅需處理二元狀態(淺色/深色)
- 無複雜的狀態流轉
- 避免引入 Redux 依賴
### 決策:採用 CSS 自訂屬性
選擇 CSS 變數而非 CSS-in-JS 的原因:
- 可與現有樣式表協同運作
- 無執行時開銷
- 瀏覽器原生支援的方案
## 資料流
```
ThemeProvider (context)
│
▼
ThemeToggle ◄──► localStorage
│
▼
CSS Variables (applied to :root)
```
## 檔案變更
- `src/contexts/ThemeContext.tsx` (new)
- `src/components/ThemeToggle.tsx` (new)
- `src/styles/globals.css` (modified)設計文件更新時機:
- 實作過程中發現方案不可行
- 發現更優的解決方案
- 依賴或限制條件發生變化
任務清單(tasks.md)
任務清單是實作檢查清單,包含帶有核取方塊的具體步驟。
markdown
# 任務清單
## 1. 主題基礎設施
- [ ] 1.1 建立具備淺色/深色狀態的 ThemeContext
- [ ] 1.2 新增用於色彩的 CSS 自訂屬性
- [ ] 1.3 實作 localStorage 持久化儲存
- [ ] 1.4 新增系統偏好偵測功能
## 2. UI 元件
- [ ] 2.1 建立 ThemeToggle 元件
- [ ] 2.2 在設定頁面新增切換開關
- [ ] 2.3 更新 Header 以加入快速切換功能
## 3. 樣式設計
- [ ] 3.1 定義深色主題色彩組合
- [ ] 3.2 更新元件以使用 CSS 變數
- [ ] 3.3 測試無障礙對比度任務清單最佳實踐:
- 將相關任務歸類在同一標題下
- 使用階層式編號(如 1.1、1.2)
- 任務粒度足夠小,可在單次工作週期內完成
- 完成任務後立即勾選核取方塊
增量規格
增量規格是 OpenSpec 適用於棕地開發(既有系統開發)的核心概念,它描述變更內容,而非重述整個規格文件。
格式
markdown
# 驗證模組增量規格
## 新增需求
### 需求:雙因素驗證
系統必須支援基於 TOTP 的雙因素驗證。
#### 場景:啟用雙因素驗證
- GIVEN 未啟用雙因素驗證的使用者
- WHEN 使用者在設定中啟用雙因素驗證
- THEN 顯示用於驗證器應用程式設定的 QR Code
- AND 使用者必須在啟用前輸入驗證碼完成驗證
#### 場景:雙因素驗證登入
- GIVEN 已啟用雙因素驗證的使用者
- WHEN 使用者提交有效憑證
- THEN 顯示一次性密碼挑戰
- AND 僅在驗證通過一次性密碼後完成登入
## 修改需求
### 需求:工作階段逾期
系統必須在 15 分鐘無活動後使工作階段失效。
(先前為 30 分鐘)
#### 場景:閒置逾時
- GIVEN 已驗證的工作階段
- WHEN 經過 15 分鐘無任何活動
- THEN 工作階段失效
## 刪除需求
### 需求:記住我的登入狀態
(因雙因素驗證功能上線而棄用。使用者應每次工作階段都重新驗證。)增量區段說明
| 區段 | 含義 | 歸檔時處理方式 |
|---|---|---|
## ADDED Requirements | 新增行為 | 追加至主規格文件 |
## MODIFIED Requirements | 變更行為 | 取代既有需求 |
## REMOVED Requirements | 棄用行為 | 從主規格文件中刪除 |
為何採用增量規格而非完整規格
清晰明確:增量規格直接標示變更內容,若閱讀完整規格則需要自行與目前版本比對差異。
避免衝突:只要兩個變更修改的是不同需求,就可以同時修改同一份規格文件而不會產生衝突。
提升審查效率:審查者只需關注變更內容,無需閱讀未修改的上下文,能專注在重點上。
適合棕地開發:大部分開發工作都是修改既有行為,增量規格能讓修改成為一等公民,而非事後補充的內容。
結構描述(Schemas)
結構描述用於定義工作流程中的產出物類型及其依賴關係。
結構描述運作方式
yaml
# openspec/schemas/spec-driven/schema.yaml
name: spec-driven
artifacts:
- id: proposal
generates: proposal.md
requires: [] # 無依賴項,可優先建立
- id: specs
generates: specs/**/*.md
requires: [proposal] # 建立前需要提案(proposal)
- id: design
generates: design.md
requires: [proposal] # 可與規格書(specs)並行建立
- id: tasks
generates: tasks.md
requires: [specs, design] # 建立前需要規格書(specs)與設計(design)兩者產出物會形成依賴圖:
proposal
(root node)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)依賴關係是「使能條件」,而非「強制門檻」。 它們顯示的是「可以建立什麼產出物」,而非「下一步必須建立什麼」。如果不需要設計(design),你可以跳過它;你可以在設計之前或之後建立規格書(specs)——兩者都僅依賴提案(proposal)。
內建結構描述
spec-driven(預設)
適用於規格驅動開發的標準工作流程:
proposal → specs → design → tasks → implement適用場景:大多數功能開發工作,你希望在實作前先確認規格書(specs)。
自訂結構描述
可為團隊的工作流程建立自訂結構描述:
bash
# 從頭建立
openspec schema init research-first
# 或基於現有結構描述衍生
openspec schema fork spec-driven research-first自訂結構描述範例:
yaml
# openspec/schemas/research-first/schema.yaml
name: research-first
artifacts:
- id: research
generates: research.md
requires: [] # 先進行研究
- id: proposal
generates: proposal.md
requires: [research] # 提案(proposal)基於研究結果擬定
- id: tasks
generates: tasks.md
requires: [proposal] # 跳過規格書(specs)/設計(design),直接進入任務(tasks)階段如需建立與使用自訂結構描述的完整說明,請參閱 自訂功能。
封存
封存操作會將變更的差分規格書(delta specs)合併至主規格書,並保留該變更的歷史記錄,從而完成整個變更流程。
封存時的處理流程
封存前:
openspec/
├── specs/
│ └── auth/
│ └── spec.md ◄────────────────┐
└── changes/ │
└── add-2fa/ │
├── proposal.md │
├── design.md │ 合併
├── tasks.md │
└── specs/ │
└── auth/ │
└── spec.md ─────────┘
封存後:
openspec/
├── specs/
│ └── auth/
│ └── spec.md # 現已包含雙重驗證需求
└── changes/
└── archive/
└── 2025-01-24-add-2fa/ # 保留於歷史記錄中
├── proposal.md
├── design.md
├── tasks.md
└── specs/
└── auth/
└── spec.md封存流程
- 合併差分內容。 每個差分規格書的區段(ADDED/MODIFIED/REMOVED)會套用至對應的主規格書。
- 移至封存目錄。 變更資料夾會移至
changes/archive/,並加上日期前綴以便依時間順序排序。 - 保留上下文。 所有產出物都會完整保存在封存區中,你隨時可以回溯查看某次變更的緣由。
封存的重要性
整潔的狀態。 進行中的變更(changes/)只顯示尚未完成的工作,已完成的變更會被移出,不會干擾當前進度。
審計軌跡。 封存區保留了每一次變更的完整上下文——不僅包含變更內容本身,還包含說明變更原因的提案、說明實作方式的設計,以及記錄已完成工作的任務清單。
規格書的演化。 隨著變更陸續被封存,規格書會自然成長。每一次封存都會合併對應的差分內容,逐步累積成一份完整的系統規格書。
整體運作架構
┌──────────────────────────────────────────────────────────────────────────────┐
│ OPENSPEC 流程 │
│ │
│ ┌────────────────┐ │
│ │ 1. 開始變更 │ /opsx:propose (核心) 或 /opsx:new (擴展流程) │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 2. 建立產出物 │ /opsx:ff 或 /opsx:continue (擴展工作流程) │
│ │ │ 依序建立提案 → 規格書 → 設計 → 任務清單 │
│ │ │ (依據結構描述的依賴關係) │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 3. 實作任務 │ /opsx:apply │
│ │ │ 依序完成任務,並逐項勾選完成 │
│ │ │◄──── 學習過程中同步更新產出物 │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 4. 驗證成果 │ /opsx:verify (可選) │
│ │ │ 確認實作內容與規格書一致 │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
│ │ 5. 封存變更 │────►│ 差分規格書合併至主規格書 │ │
│ │ │ │ 變更資料夾移至封存目錄 │ │
│ └────────────────┘ │ 規格書即為更新後的唯一可信來源 │ │
│ └──────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘正向循環:
- 規格書描述當前系統行為
- 變更以差分形式提出修改方案
- 實作讓變更落地
- 封存將差分內容合併至規格書
- 規格書此時描述的是更新後的系統行為
- 下一次變更以更新後的規格書為基礎進行
術語表
| 術語 | 定義 |
|---|---|
| 產出物(Artifact) | 變更內包含的文件,類型包含提案、設計、任務清單或差分規格書 |
| 封存(Archive) | 完成變更並將其差分內容合併至主規格書的流程 |
| 變更(Change) | 對系統提出的修改方案,以包含產出物的資料夾形式封裝 |
| 差分規格書(Delta spec) | 描述相對於當前規格書之變更內容(ADDED/MODIFIED/REMOVED)的規格書 |
| 領域(Domain) | 規格書的邏輯分組(例如 auth/、payments/) |
| 需求(Requirement) | 系統必須滿足的特定行為 |
| 場景(Scenario) | 需求的具體範例,通常採用 Given/When/Then 格式編寫 |
| 結構描述(Schema) | 產出物類型及其依賴關係的定義 |
| 規格書(Spec) | 描述系統行為的規格文件,包含需求與場景 |
| 唯一可信來源(Source of truth) | 儲存當前全體同意的系統行為的 openspec/specs/ 目錄 |