Skip to content

概念

本指南說明 OpenSpec 背後的核心理念,以及它們如何相互配合。關於實際使用方式,請參閱 快速入門工作流程

設計理念

OpenSpec 建立在四個原則之上:

流動而非僵化         — 沒有階段關卡,專注於有意義的工作
迭代而非瀑布式       — 在建構中學習,在過程中精進
簡易而非複雜         — 輕量級設定,最少的繁文縟節
棕地優先             — 適用於現有程式碼庫,而不僅是全新專案

為何這些原則很重要

流動而非僵化。 傳統的規格系統將你鎖定在階段中:先規劃,然後實作,最後完成。OpenSpec 更為靈活——你可以按照對工作最有意義的順序來建立產出物。

迭代而非瀑布式。 需求會改變。理解會加深。一開始看似不錯的方法,在實際接觸程式碼庫後可能不再適用。OpenSpec 接受並擁抱這個現實。

簡易而非複雜。 有些規格框架需要大量的設定、僵化的格式或繁重的流程。OpenSpec 不會妨礙你。幾秒鐘內即可初始化,立即開始工作,僅在需要時才進行自訂。

棕地優先。 大多數的軟體工作並非從零開始建構——而是修改現有系統。OpenSpec 基於差異的方法,讓你輕鬆地規格化對現有行為的變更,而不僅僅是描述新系統。

全局概覽

OpenSpec 將您的工作組織為兩個主要區域:

┌────────────────────────────────────────────────────────────────────┐
│                        openspec/                                   │
│                                                                    │
│   ┌─────────────────────┐      ┌───────────────────────────────┐   │
│   │       specs/        │      │         changes/              │   │
│   │                     │      │                               │   │
│   │  真實來源           │◄─────│  提出的修改                   │   │
│   │  描述您的系統       │ merge│  每個變更 = 一個資料夾       │   │
│   │  目前的運作方式     │      │  包含產出物與差異             │   │
│   │                     │      │                               │   │
│   └─────────────────────┘      └───────────────────────────────┘   │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

規格 (Specs) 是真實來源——它們描述了您的系統目前的行為。

變更 (Changes) 是提出的修改——它們存放在獨立的資料夾中,直到您準備好將它們合併。

這種分離是關鍵。您可以同時處理多個變更而不會產生衝突。您可以在變更影響主要規格之前對其進行審查。當歸檔一個變更時,其差異可以乾淨地合併到真實來源中。

規格 (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 權杖。

#### 情境:有效的憑證
- 假設一個擁有有效憑證的使用者
- 當使用者提交登入表單
- 則返回一個 JWT 權杖
- 且使用者被重新導向至儀表板

#### 情境:無效的憑證
- 假設無效的憑證
- 當使用者提交登入表單
- 則顯示錯誤訊息
- 且不發放任何權杖

### 需求:會話過期
系統必須在 30 分鐘不活動後使會話過期。

#### 情境:閒置逾時
- 假設一個已認證的會話
- 當 30 分鐘過去且無活動
- 則該會話被失效
- 且使用者必須重新認證

關鍵元素:

元素用途
## 目的此規格領域的高層次描述
### 需求:系統必須具備的特定行為
#### 情境:需求在實際運作中的具體範例
SHALL/MUST/SHOULDRFC 2119 關鍵字,表示需求的強度

為何要如此結構化規格

需求是「做什麼」——它們陳述系統應該做什麼,而不指定實作方式。

情境是「何時」——它們提供可被驗證的具體範例。好的情境:

  • 是可測試的(您可以為它們編寫自動化測試)
  • 涵蓋了正常路徑和邊緣情況
  • 使用 Given/When/Then 或類似的結構化格式

RFC 2119 關鍵字(SHALL、MUST、SHOULD、MAY)傳達意圖:

  • MUST/SHALL — 絕對需求
  • SHOULD — 建議,但存在例外
  • MAY — 可選

規格是什麼(以及不是什麼)

規格是一份行為合約,而不是實作計畫。

好的規格內容:

  • 使用者或下游系統所依賴的可觀察行為
  • 輸入、輸出和錯誤條件
  • 外部約束(安全性、隱私、可靠性、相容性)
  • 可被測試或明確驗證的情境

在規格中應避免:

  • 內部類別/函數名稱
  • 函式庫或框架的選擇
  • 逐步的實作細節
  • 詳細的執行計畫(這些應屬於 design.mdtasks.md

快速測試:

  • 如果實作可以改變而不改變外部可見的行為,它很可能不屬於規格。

保持輕量:漸進式嚴謹

OpenSpec 旨在避免官僚主義。使用最輕量級別,同時仍能使變更可驗證。

輕量規格(預設):

  • 簡短的行為優先需求
  • 清晰的範圍與非目標
  • 幾個具體的驗收檢查

完整規格(用於較高風險):

  • 跨團隊或跨儲存庫的變更
  • API/合約變更、遷移、安全/隱私問題
  • 歧義可能導致昂貴返工的變更

大多數變更應保持在輕量模式。

人類與代理協作

在許多團隊中,人類探索,代理起草產出物。預期的循環是:

  1. 人類提供意圖、上下文和約束。
  2. 代理將其轉換為行為優先的需求和情境。
  3. 代理將實作細節保留在 design.mdtasks.md 中,而非 spec.md
  4. 驗證在實作前確認結構和清晰度。

這使得規格對人類可讀,對代理一致。

變更 (Changes)

一個變更是一個對您系統的修改提案,打包成一個資料夾,包含理解和實作它所需的一切。

變更結構

openspec/changes/add-dark-mode/
├── proposal.md           # 為什麼與做什麼
├── design.md             # 如何做(技術方法)
├── tasks.md              # 實作檢查清單
├── .openspec.yaml        # 變更中繼資料(可選)
└── specs/                # 差異規格
    └── ui/
        └── spec.md       # ui/spec.md 中的變更內容

每個變更是自包含的。它包含:

  • 產出物 — 捕捉意圖、設計和任務的文件
  • 差異規格 — 關於正在新增、修改或移除內容的規格
  • 中繼資料 — 此特定變更的可選配置

為何變更是資料夾

將變更打包為資料夾有幾個好處:

  1. 所有內容集中。 提案、設計、任務和規格都在一個地方。無需在不同位置搜尋。

  2. 並行工作。 多個變更可以同時存在而不衝突。在 fix-auth-bug 進行的同時處理 add-dark-mode

  3. 乾淨的歷史。 歸檔時,變更會移動到 changes/archive/,並保留其完整上下文。您可以回顧並理解不僅僅是變更了什麼,還有為什麼。

  4. 便於審查。 變更資料夾易於審查——打開它,閱讀提案,檢查設計,查看規格差異。

產出物 (Artifacts)

產出物是變更中指導工作的文件。

產出物流程

提案 ──────► 規格 ──────► 設計 ──────► 任務 ──────► 實作
    │               │             │              │
   為什麼         做什麼         如何做        要採取的
 + 範圍         變更內容        方法          步驟

產出物相互構建。每個產出物都為下一個提供上下文。

產出物類型

提案 (proposal.md)

提案在高層次上捕捉意圖範圍方法

markdown
# 提案:新增深色模式

## 意圖
使用者要求提供深色模式選項,以減少夜間使用時的眼睛疲勞,並符合系統偏好設定。

## 範圍
在範圍內:
- 設定中的主題切換
- 系統偏好偵測
- 在 localStorage 中保存偏好設定

不在範圍內:
- 自訂顏色主題(未來工作)
- 每頁主題覆蓋

## 方法
使用 CSS 自訂屬性進行主題化,並使用 React context 進行狀態管理。在首次載入時偵測系統偏好,允許手動覆蓋。

何時更新提案:

  • 範圍改變(縮小或擴大)
  • 意圖更清晰(對問題有更好的理解)
  • 方法根本性轉變

規格(specs/ 中的差異規格)

差異規格描述相對於當前規格正在改變的內容。請參閱下方的差異規格

設計 (design.md)

設計捕捉技術方法架構決策

markdown
# 設計:新增深色模式

## 技術方法
透過 React Context 管理主題狀態,以避免屬性逐層傳遞。
CSS 自訂屬性實現運行時切換,無需切換類別。

## 架構決策

### 決策:使用 Context 而非 Redux
使用 React Context 來管理主題狀態,原因如下:
- 狀態簡單且為二元性質(淺色/深色)
- 無需複雜的狀態轉換
- 避免引入 Redux 依賴

### 決策:使用 CSS 自訂屬性
使用 CSS 變數而非 CSS-in-JS,原因如下:
- 與現有樣式表相容
- 無運行時效能開銷
- 瀏覽器原生解決方案

## 資料流
```
ThemeProvider (context)


ThemeToggle ◄──► localStorage


CSS Variables (applied to :root)
```

## 檔案變更
- `src/contexts/ThemeContext.tsx` (新增)
- `src/components/ThemeToggle.tsx` (新增)
- `src/styles/globals.css` (已修改)

何時更新設計:

  • 實作時發現該方法不可行
  • 發現更好的解決方案
  • 依賴項或限制條件發生變化

任務 (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 的雙因素驗證。

#### 場景:2FA 註冊
- 給定一個未啟用 2FA 的使用者
- 當使用者在設定中啟用 2FA
- 則顯示一個 QR 碼以供驗證器應用程式設定
- 且使用者必須在啟用前使用驗證碼進行驗證

#### 場景:2FA 登入
- 給定一個已啟用 2FA 的使用者
- 當使用者提交有效的憑證
- 則呈現一個 OTP 挑戰
- 且僅在提供有效的 OTP 後才完成登入

## 修改需求

### 需求:Session 過期
系統必須在 Session 閒置 15 分鐘後使其過期。
(先前:30 分鐘)

#### 場景:閒置逾時
- 給定一個已認證的 Session
- 當 15 分鐘無活動過去
- 則該 Session 被失效

## 移除需求

### 需求:記住我
(已棄用,改為使用 2FA。使用者應在每次 Session 重新認證。)

增量章節

章節含義封存時發生什麼
## 新增需求新行為附加至主規格
## 修改需求已變更行為替換現有需求
## 移除需求已棄用行為從主規格中刪除

為何使用增量而非完整規格

清晰度。 增量精確地顯示了正在變更的內容。閱讀完整規格時,你必須在腦中與當前版本進行差異比對。

避免衝突。 兩個變更可以觸及同一個規格檔而不衝突,只要它們修改的是不同的需求。

審查效率。 審查者看到的是變更,而非未變更的上下文。專注於重要的部分。

適合既有系統。 大部分工作是修改現有行為。增量使修改成為一等公民,而非事後才考慮。

結構描述

結構描述定義了工作流程的產物類型及其依賴關係。

結構描述如何運作

yaml
# openspec/schemas/spec-driven/schema.yaml
name: spec-driven
artifacts:
  - id: proposal
    generates: proposal.md
    requires: []              # 無依賴,可首先建立

  - id: specs
    generates: specs/**/*.md
    requires: [proposal]      # 需要先有提案才能建立

  - id: design
    generates: design.md
    requires: [proposal]      # 可與規格平行建立

  - id: tasks
    generates: tasks.md
    requires: [specs, design] # 需要先有規格和設計

產物形成一個依賴圖:

                    proposal
                   (根節點)

         ┌─────────────┴─────────────┐
         │                           │
         ▼                           ▼
      specs                       design
   (requires:                  (requires:
    proposal)                   proposal)
         │                           │
         └─────────────┬─────────────┘


                    tasks
                (requires:
                specs, design)

依賴是促成因素,而非關卡。 它們顯示了可以建立什麼,而非你必須接下來建立什麼。如果你不需要設計,可以跳過它。你可以在設計之前或之後建立規格——兩者都只依賴於提案。

內建結構描述

spec-driven(預設)

規格驅動開發的標準工作流程:

proposal → specs → design → tasks → implement

適用於:大多數功能開發,你希望在實作前就規格達成共識。

自訂結構描述

為你的團隊工作流程建立自訂結構描述:

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]   # 提案基於研究結果

  - id: tasks
    generates: tasks.md
    requires: [proposal]   # 跳過規格/設計,直接進入任務

詳見 自訂 以了解建立和使用自訂結構描述的完整細節。

封存

封存透過將其增量規格合併到主規格中,並保留變更以供歷史記錄,從而完成一個變更。

封存時發生什麼

封存前:

openspec/
├── specs/
│   └── auth/
│       └── spec.md ◄────────────────┐
└── changes/                         │
    └── add-2fa/                     │
        ├── proposal.md              │
        ├── design.md                │ 合併
        ├── tasks.md                 │
        └── specs/                   │
            └── auth/                │
                └── spec.md ─────────┘


封存後:

openspec/
├── specs/
│   └── auth/
│       └── spec.md        # 現在包含 2FA 需求
└── changes/
    └── archive/
        └── 2025-01-24-add-2fa/    # 保留以供歷史記錄
            ├── proposal.md
            ├── design.md
            ├── tasks.md
            └── specs/
                └── auth/
                    └── spec.md

封存流程

  1. 合併增量。 每個增量規格章節(新增/修改/移除)都套用到對應的主規格。

  2. 移至封存。 變更資料夾移至 changes/archive/,並加上日期前綴以便按時間順序排列。

  3. 保留上下文。 所有產物在封存中保持完整。你隨時可以回顧以了解為何做出某個變更。

為何封存很重要

乾淨的狀態。 活動變更 (changes/) 僅顯示進行中的工作。已完成的工作會移開。

審計軌跡。 封存保留了每個變更的完整上下文——不僅是變更了什麼,還有解釋為何變更的提案、解釋如何變更的設計,以及顯示已完成工作的任務。

規格演進。 隨著變更被封存,規格有機地成長。每次封存都合併其增量,隨時間建立起全面的規格。

整體如何運作

┌──────────────────────────────────────────────────────────────────────────────┐
│                              OPENSPEC 流程                                   │
│                                                                              │
│   ┌────────────────┐                                                         │
│   │  1. 開始       │  /opsx:propose (核心) 或 /opsx:new (擴展)               │
│   │     變更       │                                                         │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  2. 建立       │  /opsx:ff 或 /opsx:continue (擴展工作流程)              │
│   │     產物       │  建立提案 → 規格 → 設計 → 任務                           │
│   │                │  (基於結構描述依賴)                                      │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  3. 實作       │  /opsx:apply                                            │
│   │     任務       │  逐步完成任務,並將其核銷                               │
│   │                │◄──── 隨著你的了解更新產物                               │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐                                                         │
│   │  4. 驗證       │  /opsx:verify (可選)                                    │
│   │     工作       │  檢查實作是否符合規格                                   │
│   └───────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│   ┌────────────────┐     ┌──────────────────────────────────────────────┐    │
│   │  5. 封存       │────►│  增量規格合併到主規格                         │    │
│   │     變更       │     │  變更資料夾移至 archive/                      │    │
│   └────────────────┘     │  規格現在是更新後的真實來源                   │    │
│                          └──────────────────────────────────────────────┘    │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘

良性循環:

  1. 規格描述當前行為
  2. 變更提出修改建議(以增量形式)
  3. 實作使變更成為現實
  4. 封存將增量合併到規格中
  5. 規格現在描述新的行為
  6. 下一個變更基於更新的規格建立

術語表

術語定義
Artifact變更中的一份文件(提案、設計、任務或差異規格)
Archive完成變更並將其差異合併至主規格的過程
Change對系統的建議修改,以包含多個 artifact 的資料夾形式封裝
Delta spec描述相對於當前規格之變更(新增/修改/移除)的規格
Domain規格的邏輯分組(例如 auth/payments/
Requirement系統必須具備的特定行為
Scenario需求的具體範例,通常採用 Given/When/Then 格式
SchemaArtifact 類型及其依賴關係的定義
Spec描述系統行為的規格,包含需求與情境
Source of truthopenspec/specs/ 目錄,包含當前已達成共識的行為規範

後續步驟