# 在 CI 中用規格檢查器檢查規格

Canonical: https://specscore.md/zh-tw/articles/lint-specs-in-ci/

最近更新：2026年11月4日

規格檢查器是一支程式，它檢查規格裡的結構錯誤，發現錯誤時以失敗碼結束。[持續整合](https://specscore.md/zh-tw/validators/)（CI，continuous integration）是對每一項提議變更的自動檢查。持續整合與持續交付（CI/CD，continuous integration and continuous delivery）是執行這項檢查、並讓通過的變更保持可發行的流水線。[規範驅動開發](https://specscore.md/zh-tw/spec-driven-development/)（SDD，spec-driven development）是在寫程式之前寫下規格，並把規格當作事實來源。產品需求文件（PRD，product requirements document）是陳述問題和範圍的散文。在 [SpecScore](https://specscore.md/) 裡，需求（REQ）是功能內部一條有名字的規則，驗收標準（AC，acceptance criterion）是可選的抽象條件，指向其中一條或多條規則。這項檢查是[命令列介面](https://specscore.md/zh-tw/cli/)（CLI，command-line interface）命令 `specscore spec lint`，來自 [specscore/specscore-cli](https://github.com/specscore/specscore-cli)（[Apache-2.0](https://github.com/specscore/specscore-cli/blob/main/LICENSE)）裡的 CLI。[EARS](https://specscore.md/zh-tw/articles/ears-requirements/)（Easy Approach to Requirements Syntax）是一條需求的句式。這個檢查器檢查標題、必要的小節和參照。它不為英語打分。

## 檢查一份規格是什麼意思

檢查一份規格，和檢查程式碼是同一類檢查。一支確定性的程式讀取檔案並報告規則違規。它不判斷產品是不是個好主意，也不把需求改寫成更好的散文。[驗證器頁面](https://specscore.md/zh-tw/validators/)把那項結構檢查和藉助 AI 的人工復查分開。`specscore spec lint` 就是那項結構檢查。

命令的說明寫在 [internal/cli/spec.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/internal/cli/spec.go)，位於 CLI 標籤 v0.55.1，以及本儲存庫工作流程所安裝的 v0.39.1 標籤。說明寫的是：對照結構約定的違規來驗證規格樹。一次乾淨的執行印出 `0 violations found` 並以 0 結束。發現違規的執行為每筆發現印出一行，並以 1 結束。這個結束碼會讓 CI 作業失敗。無效參數以 2 結束。缺少 `specscore.yaml` 時以 3 結束，訊息要你執行 `specscore init`。

## 規格檢查器檢查什麼

規則屬於 CLI，不是另一項雲端服務。產生的規則一覽 [docs/lint-rules.md](https://github.com/specscore/specscore-cli/blob/v0.55.1/docs/lint-rules.md) 在標籤 v0.55.1 列出 183 條規則。本網站的工作流程安裝的是較舊的發行 v0.39.1，因此只存在於較晚標籤裡的規則，並不是那個作業所執行的。本節所點名的規則，兩個標籤裡都有。預設的 `--severity` 是 `error`。只有在傳入 `--severity warning` 或 `info` 時才會印出警告，預設命令不會因此失敗。規則一覽把 `dogfood-version-bump` 標為警告，所以當工作流程的釘選落後於二進位檔時，預設命令不會失敗。

### 必要的檔案和小節

規則 `readme-exists`（[readme_exists.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/readme_exists.go)）要求規格的每個目錄裡都有 `README.md`。規則 `oq-section`（[oq_section.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/oq_section.go)）要求功能 README 包含 `## Open Questions` 小節。舊式標題 `## Outstanding Questions` 是另一筆發現，`--fix` 會就地改寫該標題。下面範例裡的訊息「Open Questions section not found」，是從一份拿掉了該小節的功能 README 得到的發現。

### 索引列與子目錄

規則 `index-entries`（[index_entries.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/index_entries.go)）把功能索引和磁碟上的子目錄相對照。未列入的子目錄是違規，連結指向一個不存在的子目錄的列也是違規。`--fix` 可以刪掉那條幽靈列，並插入缺少的列。這是目錄和索引的完整性。它不是去爬散文裡的每一個 URL。

### 驗收標準標題的形態

規則 `ac-heading-format`（[ac_heading.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/ac_heading.go)）適用於功能 README，也就是標題為 `# Feature:` 的檔案。看起來像驗收標準標題的一行，必須恰好是 `### AC: <id>`，冒號後有一個空白，id 為 kebab-case。`### AC: <id> (verifies ...)` 這種標題也被接受。`--fix` 只修復空白。帶大寫字母或底線的 id 會被報告，並留給人來處理。這條規則不要求 `**Requirements:**` 行，不為「graceful」或「fast」這類詞打分，散文裡出現 Given、When 或 Then 時也不警告。標準本身怎麼寫，見[寫出 AI 代理驗得過的驗收標準](https://specscore.md/zh-tw/articles/acceptance-criteria/)。

### 計畫對這些識別碼的參照

在點名了來源功能的計畫上，[plan_rules.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/plan_rules.go) 讀取該功能 README 裡的 `### AC:` 標題。規則 `P-002` 報告：任務的 `**Verifies:**` 值沒有解析到這些標題之一的 `<feature-slug>#ac:<ac-slug>`、空的 `**Verifies:**` 行、缺少或無法辨識的來源行，或者來源功能沒有解析到一份功能 README。規則 `P-001` 報告：沒有任何任務涵蓋、並且沒有列在 `## Deferred AC Coverage` 之下的標題。以來源為構想的計畫（`**Source:** idea:<slug>`）和帶有 `**Source:** none` 的計畫免於這些規則，處於終態處置狀態的計畫也同樣免除。`P-002` 在規則一覽裡的一行文字是「valid dependency references」；那個檔案裡的檢查器，就是剛才描述的 AC 參照檢查。

### 一次通過的檢查不是什麼

同一條命令不判斷一條需求是否解決了所陳述的問題，不判斷一個名字是否說得通，也不判斷兩個功能是否在意義上互相矛盾。驗證器頁面把這些列在 CLI 檢查器之外。它也不檢查情境步驟的關鍵字。`specscore rehearse` 執行情境檔案。本儲存庫的工作流程執行 `specscore spec lint`，並不呼叫 rehearse。規則一覽還點出更多類別——構想、決策、實體、屬性、教訓、議題，以及其餘的計畫規則——每條規則適用於它負責的檔案。規則一覽就是那份清單。本頁不重述全部 183 條說明。

## 在 CI 中執行 specscore spec lint

命令從工作目錄向上尋找 `specscore.yaml`。沒有這個檔案時以 3 結束，並點名 `specscore init`。因此 CI 作業需要取出的內容裡有這份設定檔。[scripts/install.sh](https://github.com/specscore/specscore-cli/blob/v0.55.1/scripts/install.sh) 讀取 `SPECSCORE_VERSION`，變數未設定時預設使用 `latest`。如果希望每次執行都是同一套規則，就釘住一個標籤。

本儲存庫的檢查是 [dogfood.yml](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml)。它把 `SPECSCORE_VERSION` 設為 `v0.39.1` 來安裝 CLI，然後不加額外旗標執行 `specscore spec lint`，觸發於 pull request 以及向 main 的 push。該行程以非零結束時，GitHub Actions 讓這個步驟失敗。下面的摘錄保留了那些安裝和檢查步驟。該檔案還設定 `permissions: contents: read`、一個並行群組，以及一條說明為何釘選不是 `latest` 的註解。

### dogfood.yml 裡的安裝與檢查步驟

```yaml
name: Dogfood lint

on:
  push:
    branches: [main]
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
      - name: Install specscore CLI (pinned)
        env:
          SPECSCORE_VERSION: v0.39.1
        run: |
          curl -fsSL https://specscore.md/install/get-cli | \
            SPECSCORE_INSTALL_DIR="$HOME/.local/bin" sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
          specscore --version
      - name: Lint spec tree
        run: specscore spec lint
```

### 失敗報告（specscore 0.55.0，v0.39.1 的行形態相同）

```text
features/apply-discount/README.md:0 [error] oq-section: Open Questions section not found
features/apply-discount/README.md:0 [error] index-entries: Child directory not listed in index: refunds
features/apply-discount/refunds:0 [error] readme-exists: README.md not found

3 violations found (3 errors)
```

### 乾淨的報告

```text
0 violations found
```

每筆發現都是 `file:line [severity] rule: message`。摘要是 `N violations found`，再加上括號裡的計數，例如 `(3 errors)`。結束碼是行程狀態，不是報告裡的一行。上面三行取自 specscore 0.55.0，當時一份功能的 Open Questions 小節已被移除，索引也漏了一個空的子目錄。它們和 CLI 頁面展示的是同一份報告。`--format` 接受 `text`（預設）、`json` 或 `yaml`。`--rules` 和 `--ignore` 用來選擇規則，不能同時使用。`--fix` 會改寫帶有修復器的發現，包括 Outstanding Questions 標題。dogfood 作業不傳入 `--fix`。

## 不在 CI 中檢查這種格式的工具

在這個 CLI 裡，需求品質檢查就是上面的結構檢查。它不是給散文打分。其他規範驅動的工具公布的是不同的檢查。下面各段只用那些專案自己的頁面所說的內容。[工具彙整](https://specscore.md/zh-tw/spec-driven-development/tools/) 把同樣的頁面記為 2026年10月30日讀過，例外是印著 2026年9月28日的 Spec Kit 文件首頁，以及印著 2026年8月4日的 Kiro 功能規範頁。

[GitHub Spec Kit](https://github.github.io/spec-kit/) 是一套代理工作流程，寫出 Markdown 產出物。[代理式 SDD 參考](https://github.github.io/spec-kit/reference/agentic-sdd.html) 把 `/speckit.analyze` 描述為跨規格、計畫和任務的不一致報告，並且不編輯檔案。你在代理裡執行它。文件首頁還點名社群擴充，其中包括一個叫 CI Guard 的擴充，它們加上合規閘門。那不是一條會檢查 SpecScore 功能 README 的命令。

[OpenSpec](https://github.com/Fission-AI/OpenSpec) 的確公布了一項結構檢查。`openspec validate`，記載於[CLI 參考](https://openspec.dev/docs/cli)，檢查 OpenSpec 的變更和規格結構，驗證失敗時以非零結束，參考裡還包含一段 CI 作業可以執行的 shell 片段。那項檢查是 OpenSpec 的形態，不是 `### AC:` 標題，也不是 SpecScore 的索引。

[Kiro 的功能規範頁](https://kiro.dev/docs/specs/feature-specs/) 把需求檢視（Analyze Requirements）描述為 Kiro 內部、設計之前的一項檢查，尋找不一致、歧義、互相衝突的約束和缺口。它不是 `dogfood.yml` 裡的命令。Kiro 所寫的句式在[EARS 需求語法](https://specscore.md/zh-tw/articles/ears-requirements/)。

[BMAD Method](https://github.com/bmad-code-org/BMAD-METHOD) 的 README 描述該方法的產出物和代理工作流程。它沒有記載一條在 CI 裡檢查固定規格綱要的命令。[Task Master](https://github.com/eyaltoledano/claude-task-master) 的 README 描述用 `task-master parse-prd` 把 PRD 解析成任務。它沒有描述那個 PRD 的檢查器。PRD 仍然可以是 SpecScore 功能的輸入，而隨後檢查該功能檔案的是 `specscore spec lint`。

## 常見問題

### 什麼是規格檢查器？

規格檢查器讀取規格檔案並報告結構違規。`specscore spec lint` 就是針對 SpecScore 樹的那條命令。在所選嚴重程度下什麼都沒發現時以 0 結束，發現違規時以 1 結束。

### 規格檢查器會從用字判斷需求品質嗎？

不會。`ac-heading-format` 檢查的是 `### AC:` 標題。它不為「graceful」或「fast」這類詞打分，一條標準裡出現 Given、When 或 Then 時也不警告。用字是寫作的工作。驗證器頁面把那項確定性檢查和藉助 AI 的人工復查分開。

### 怎樣在 CI 裡檢查規格？

安裝 CLI 時把 `SPECSCORE_VERSION` 設為一個發行標籤，然後執行 `specscore spec lint`。取出的內容需要一份 `specscore.yaml`。[dogfood.yml](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml) 是一個能用的 GitHub Actions 範例。它釘住 v0.39.1。

### 失敗的一次執行會印出什麼？

每筆發現一行，`file:line [severity] rule: message`，然後是類似 `3 violations found (3 errors)` 的摘要。行程以 1 結束。一棵乾淨的樹印出 `0 violations found` 並以 0 結束。

### 其他規範驅動的工具會在 CI/CD 裡驗證規格嗎？

OpenSpec 的 `openspec validate` 可以讓 CI 作業失敗，它檢查的是 OpenSpec 自己的變更結構。Spec Kit 的 `/speckit.analyze` 在代理的工作階段裡執行。Kiro 的需求檢視（Analyze Requirements）在 Kiro 內部執行。BMAD Method 和 Task Master 的 README 沒有記載給 CI 用的格式檢查器。SpecScore 的 dogfood 工作流程在 SpecScore 樹上執行 `specscore spec lint`。

## 來源

CLI 行為已於 2026年11月4日對照 specscore-cli 標籤 v0.55.1 與 v0.39.1 檢查。其他專案的頁面就是下面連結的那些；工具彙整把它們記為 2026年10月30日讀過，頁面自己印有日期的除外。

- [specscore/specscore-cli](https://github.com/specscore/specscore-cli)
- [specscore-cli — Apache-2.0 授權](https://github.com/specscore/specscore-cli/blob/main/LICENSE)
- [specscore/specscore](https://github.com/specscore/specscore)
- [specscore-cli v0.55.1 — lint 規則一覽（183 條規則）](https://github.com/specscore/specscore-cli/blob/v0.55.1/docs/lint-rules.md)
- [specscore/specscore — dogfood.yml（CLI v0.39.1）](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml)
- [specscore-cli — install.sh（SPECSCORE_VERSION）](https://github.com/specscore/specscore-cli/blob/v0.55.1/scripts/install.sh)
- [specscore-cli v0.55.1 — readme-exists](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/readme_exists.go)
- [specscore-cli v0.55.1 — oq-section](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/oq_section.go)
- [specscore-cli v0.55.1 — index-entries](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/index_entries.go)
- [specscore-cli v0.55.1 — ac-heading-format](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/ac_heading.go)
- [specscore-cli v0.55.1 — 計畫規則 P-001 與 P-002](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/plan_rules.go)
- [SpecScore 驗證什麼](https://specscore.md/zh-tw/validators/)
- [寫出 AI 代理驗得過的驗收標準](https://specscore.md/zh-tw/articles/acceptance-criteria/)
- [EARS 需求語法詳解與範例](https://specscore.md/zh-tw/articles/ears-requirements/)
- [GitHub Spec Kit 文件（頁面日期 2026年9月28日）](https://github.github.io/spec-kit/)
- [GitHub Spec Kit — 代理式 SDD 參考（/speckit.analyze）](https://github.github.io/spec-kit/reference/agentic-sdd.html)
- [OpenSpec CLI 參考 — openspec validate](https://openspec.dev/docs/cli)
- [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec)
- [Kiro — 功能規範（更新於 2026年8月4日）](https://kiro.dev/docs/specs/feature-specs/)
- [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD)
- [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master)
- [規範驅動開發工具](https://specscore.md/zh-tw/spec-driven-development/tools/)

## 相關

- [用 Claude Code 和 Cursor 做規範驅動開發](https://specscore.md/zh-tw/articles/claude-code-specs/)
- [給 AI 寫程式用的 Markdown PRD 範本](https://specscore.md/zh-tw/articles/feature-spec-template/)
- [寫出 AI 代理驗得過的驗收標準](https://specscore.md/zh-tw/articles/acceptance-criteria/)
- [EARS 需求語法詳解與範例](https://specscore.md/zh-tw/articles/ears-requirements/)
- [SpecScore 驗證什麼](https://specscore.md/zh-tw/validators/)
- [CLI](https://specscore.md/zh-tw/cli/)
- [安裝 CLI](https://specscore.md/zh-tw/cli/install/)
- [規範驅動開發](https://specscore.md/zh-tw/spec-driven-development/)
- [規範驅動開發工具](https://specscore.md/zh-tw/spec-driven-development/tools/)
- [功能規範](https://specscore.md/feature-specification)
- [驗收標準規範](https://specscore.md/acceptance-criteria-specification)
