Skip to content

schema.yaml ​

schema 定义的每个字段,无论用于读取还是编写 schema。

schema.yaml 列出工作流创建的规划文件。它还定义这些文件的顺序,以及向实现交接的方式。

位置 ​

项目 schema 位于 openspec/schemas/<name>/ 下:

text
openspec/schemas/review-first/
├── schema.yaml
└── templates/
    ├── proposal.md
    └── tasks.md

OpenSpec 会在三个位置查找该目录。首个匹配项生效。

副本目录
1. 项目<project>/openspec/schemas/<name>/
2. 用户,macOS 和 Linux~/.local/share/openspec/schemas/<name>/
2. 用户,Windows%LOCALAPPDATA%\openspec\schemas\<name>\
3. 包随 CLI 安装的 schema

如果设置了 XDG_DATA_HOME,则在所有平台上,用户目录都会移动到 $XDG_DATA_HOME/openspec/schemas/<name>/。

目录名是 --schema、config.yaml 和 .openspec.yaml 使用的查找键。如果 name 字段与目录名不同,OpenSpec 仍使用目录名进行查找。

openspec schema which <name> 会打印当前生效的目录,以及它所遮蔽的所有较低优先级副本。

顶层字段 ​

字段约定
name必填。 作为 schema 名称存储的非空字符串。查找仍使用目录名。
version必填。 作为 schema 修订版本存储的正整数。该值不会改变 OpenSpec 的行为。
description由 openspec schemas 打印的可选字符串。若无值,则 schema 没有描述。
artifacts必填。 非空的工件条目列表。
apply可选的 apply 设置。如果没有该块,OpenSpec 使用 apply 默认值。

工件字段 ​

artifacts 下的每个条目定义一个规划文件或一组文件。

字段约定
id必填。 用于依赖项、项目规则、命令和 apply 设置中的唯一非空字符串。
generates必填。 相对路径或 glob,告知智能体在变更文件夹内将工件写入何处。
description必填。 在发送给智能体的指令中标识该工件的字符串。
template必填。 指向 schema 的 templates/ 文件夹中工件格式的相对路径。
instruction可选指导,告知智能体应生成哪些内容。
requires必须先完成的工件 ID 列表。默认值:[]。

generates ​

该路径从变更文件夹开始。对于名为 add-auth 的变更:

yaml
generates: proposal.md

工件写入此处:

text
openspec/changes/add-auth/proposal.md

glob 可匹配多个文件:

yaml
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(extglob):诸如 @(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 ​

该路径从 schema 的 templates/ 文件夹开始。在 review-first schema 中:

yaml
template: proposal.md

OpenSpec 读取此文件:

text
openspec/schemas/review-first/templates/proposal.md

OpenSpec 会将模板内容作为输出格式提供给智能体。它不会将模板复制到变更文件夹中。

OpenSpec 会拒绝绝对路径以及包含 .. 路径段的路径。

requires ​

  • 依赖项:requires 中的每个 ID 都必须指向同一 schema 中的另一个工件。
  • 就绪状态:当某个工件的所有依赖项都完成后,该工件才会变为就绪。
  • 无效依赖图:缺失的 ID、重复的 ID 和依赖循环会导致验证失败。
  • 并列情况:当多个工件都已就绪时,它们在 artifacts 中的顺序决定 OpenSpec 先返回哪一个。

Apply 字段 ​

apply 定义实现开始前必须存在的内容。

字段约定
requires必填。 在 apply 指令变为就绪前必须存在的工件的非空列表。
tracks可选的相对路径或 glob,用于变更文件夹中的 Markdown 任务文件。默认值:null。
instruction可选指导,在 apply 就绪时发送给智能体。默认情况下,OpenSpec 使用内置指导。

工件的 requires 控制规划顺序。apply.requires 控制 apply 指令何时变为就绪。

tracks ​

该路径从变更文件夹开始。对于名为 add-auth 的变更,tracks: tasks.md 会读取:

text
openspec/changes/add-auth/tasks.md

诸如 tracks: "**/tasks.md" 的 glob 会读取每个匹配文件,例如 backend/tasks.md 和 frontend/tasks.md。OpenSpec 会合并它们的任务和进度。请为工件的 generates 字段使用相同的值,以便状态和列表跟踪相同的文件。generates 中的花括号限制(深度 16 层、最多展开为 1,024 个模式)同样适用于此处。

如果没有文件匹配,或匹配的文件中没有任何带任务文本的复选框,apply 会保持阻塞状态。OpenSpec 会计入以下复选框形式:

markdown
- [ ] Pending task
- [x] Completed task
* [X] Completed task
+ [ ] Pending task
1. [ ] Pending task
2) [x] Completed task

任何 Markdown 列表标记均可使用:-、*、+,或最多九位数字后跟 . 或 )。允许前导空格。spec-driven 页面中的 tasks.md 部分 定义了默认 schema 生成的更严格格式。

被跟踪的文件决定 apply 状态:

  • blocked:没有文件匹配,或没有任何可读文件包含带任务文本的复选框。
  • ready:至少有一个任务待处理,或某个匹配文件无法读取,而另一个文件提供了任务。
  • all_done:每个被跟踪的任务都已勾选,并且每个匹配文件都已读取。

如果某个匹配文件无法读取,apply 会保留可读文件中的任务和进度,但不会将该变更标记为 all_done。Apply JSON 输出 会标明每个不可用文件及其原因。

OpenSpec 会拒绝绝对路径以及包含 .. 路径段的路径。

Apply 默认值 ​

行为默认值
必需工件schema 中的每个工件
进度跟踪无跟踪文件
智能体指导内置 apply 指导

完整示例 ​

yaml
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.requires ID:每个都必须是 schema 中的工件
  • 模板文件

如果 schema 包含未知的 apply.requires ID,则不会加载,因此使用它的每个命令都会报告该错误。

当 apply.tracks 与某个工件的 generates 值不完全相等时,验证会发出警告,但不会失败。OpenSpec 通过比较这两个字符串来查找被跟踪的工件,因此任何不一致都会使其无法判断该文件属于哪个工件的进度。这包括像 task.md 这样的拼写错误,也包括 tracks: tasks/main.md 与 generates: tasks/*.md 这样的组合:glob 确实会生成该文件,但字符串仍然不同。无论哪种情况,apply 都会继续读取该文件,但 openspec list 和 openspec status 会改为统计 tasks.md。

验证不会捕获以下错误:

错误会发生什么
字段拼写错误,例如 instrutionOpenSpec 会忽略它。验证不会报告该拼写错误。
name 与 schema 目录不同验证通过。OpenSpec 仍使用目录名进行查找。