`openspec/config.yaml` 解析与生效机制

文件位置

openspec/config.yaml(也支持 .yml 扩展名)

核心解析入口:src/core/project-config.ts

文件由 readProjectConfig(projectRoot) 函数解析,流程如下:

  1. 查找文件 --- 通过 resolveConfigFilePath() 依次尝试 openspec/config.yaml 和 openspec/config.yml,先用哪个读哪个。
  2. YAML 解析 --- 用 yaml 库解析为对象。
  3. 字段级校验 --- 使用 Zod schema 逐字段安全解析(safeParse),某个字段坏了不影响其他字段。

配置结构(Zod Schema 定义)

typescript 复制代码
const ProjectConfigSchema = z.object({
  schema:   z.string().min(1),                       // 工作流 schema 名称
  context:  z.string().optional(),                    // 项目上下文(≤50KB)
  rules:    z.record(z.string(), z.array(z.string())) // artifact 级规则
    .optional(),
  store:    z.string().optional(),                    // 声明式默认 store
})
// references 字段由 parseDeclarationList() 独立解析

各字段校验规则

字段 类型 校验逻辑
schema 非空字符串 缺失/空串跳过,后续 fallback 到默认值 'spec-driven'
context 字符串 上限 50KB(UTF-8 字节),超限忽略并告警
rules { artifactId: [string] } 空字符串规则被过滤
references string[] 或 {id, remote}[] 去重、无效项跳过(有告警)
store 字符串 仅 config-only 目录下生效

各字段生效路径

1. schema --- 决定工作流

解析出的 schema 字段在 resolveSchemaForChange() (src/utils/change-metadata.ts:166)中按优先级决定:

复制代码
1. 命令行 --schema 参数(显式覆盖)
2. [change-dir]/.openspec.yaml 里的 schema(变更级元数据)
3. openspec/config.yaml 里的 schema     ← 这里!
4. 默认 'spec-driven'

一旦确定 schema,会加载对应的 schemas/<schema-name>/schema.yaml 来驱动变更工作流(生成哪些 artifact、依赖关系、模板)。

2. context --- 注入 AI 指令上下文

在 generateInstructions() (src/core/artifact-graph/instruction-loader.ts:273)中:

  • 读取 projectConfig.context,注入到 ArtifactInstructions.context 字段
  • 这些文本作为约束/背景信息传给 AI,但不会写入最终 artifact 文件本身
  • 作用是告诉 AI 工具:本项目用 TypeScript、package manager 是 pnpm、注意跨平台路径等

3. rules --- artifact 级额外规则

同样在 generateInstructions() 中:

  • 按 artifactId 匹配 projectConfig.rules[artifactId]
  • 注入到 ArtifactInstructions.rules 字段
  • 同时调用 validateConfigRules() 校验 artifactId 是否在 schema 中存在,不存在的 ID 会告警

4. references --- 引用其他 store 的 spec

在 assembleReferenceIndex() (src/core/references.ts:259)中处理:

  • 遍历声明的 store id,去注册中心查找对应的本地 checkout
  • 读取被引用 store 的所有 spec,提取每份 spec 的第一行 Purpose
  • 生成一个只读索引 (最大也是 50KB),注入到 artifact instructions 的 <referenced_stores> 块中
  • 这样 AI 生成时就知道可以去哪些上游 store 查 spec

5. store --- 声明式默认 store

在 readStorePointer() (src/core/project-config.ts:393)中解析:

  • 仅当 openspec/ 目录下没有 specs/ 或 changes/ 子目录时才会生效
  • 用于 root resolution:指向另一个已注册 store 作为实际工作目录

文件不存在时的行为

整个 readProjectConfig() 返回 null,系统完全正常工作 --- 所有字段都有默认 fallback:

字段 缺失时的默认行为
schema 'spec-driven'
context 不注入额外上下文
rules 不添加额外规则
references 不引用外部 store
store 无声明式 store

初始化流程

openspec init 命令(src/core/init.ts)在项目初始化时:

  • 自动创建 openspec/config.yaml(包含默认内容 schema: spec-driven)
  • 已有的 config 文件不会覆盖

设计要点

  1. 弹性解析(Resilient Parsing) --- 坏掉的字段单独被忽略而不是整体失败,文件缺失也完全可接受(走默认值)。
  2. 无缓存策略 --- 每次需要都直接读文件(1KB 约 0.5ms),避免缓存失效的复杂性。
  3. AI 辅助设计 --- context 和 rules 的设计目标是为 AI 生成提供项目级约束,而非控制程序逻辑。
相关推荐
lhbweilai8 分钟前
QT(了解各个控件和布局)上
数据库·qt
莫晓燚29 分钟前
搭建Redis 主从复制---实战
数据库·redis·缓存
灵晔君1 小时前
【MySQL】数据库基础
数据库·mysql·adb
香蕉大香蕉(06敬畏市场)1 小时前
MySQL 单点详解(03)
java·数据库·mysql·面试·八股·大厂实习
赤生云电竞1 小时前
云游戏边缘节点部署:机房选址与网络拓扑优化实践——接入延迟、VXLAN与GPU虚拟化选型
数据库·游戏
Y002 小时前
PostgreSQL 权限管理踩坑记:从 42501 到默认权限和 RLS
数据库·postgresql
呆萌很3 小时前
达梦(DM8)数据库常用SQL
数据库·sql
跟太阳说早安3 小时前
极简数据库SQL
数据库·sql
前端 贾公子3 小时前
第 5 章:Codex 从可运行程序到可交付工具
java·前端·数据库
杨云龙UP3 小时前
MySQL 主从复制管理:暂停、恢复、清理主从关系及命令执行位置
运维·数据库·mysql·主从配置·主从命令·reset replica·清除复制