@ifrankwang/openspec-agents 0.147.2 → 0.149.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/.dsh-plugin/opx-tools.mjs +6 -6
  2. package/.mcp-server/cli.mjs +9 -9
  3. package/README.md +3 -2
  4. package/assets/agents/openspec-developer.md +1 -1
  5. package/assets/agents/openspec-reviewer.md +6 -3
  6. package/assets/skills/architecture-evolution/SKILL.md +5 -5
  7. package/assets/skills/openspec-standard/SKILL.md +2 -2
  8. package/assets/skills/openspec-standard/templates/openspec/config.yaml +7 -4
  9. package/assets/skills/openspec-standard/templates/schemas/spec-driven-standard/README.md +18 -10
  10. package/assets/skills/openspec-standard/templates/schemas/spec-driven-standard/schema.yaml +71 -3
  11. package/assets/skills/openspec-standard/templates/schemas/spec-driven-standard/templates/clarify.md +3 -2
  12. package/assets/skills/openspec-standard/templates/schemas/spec-driven-standard/templates/design.md +11 -0
  13. package/assets/skills/openspec-standard/templates/schemas/spec-driven-standard/templates/proposal.md +17 -0
  14. package/assets/skills/openspec-standard/templates/schemas/spec-driven-standard/templates/spec.md +8 -0
  15. package/assets/skills/test-design/SKILL.md +70 -0
  16. package/assets/workflows/review-simple.yaml +4 -2
  17. package/assets/workflows/review.yaml +4 -2
  18. package/assets/workflows/task-simple.yaml +4 -2
  19. package/assets/workflows/task.yaml +6 -2
  20. package/dsh/cordis.patch.yml +7 -4
  21. package/package.json +1 -1
  22. package/src/core/tools/gate.ts +4 -3
  23. package/src/core/tools/schemas.ts +2 -2
  24. package/src/core/tools/submit.ts +12 -10
  25. package/src/core/tools/types.ts +1 -1
  26. package/src/core/workflow/status.ts +2 -2
@@ -5830,7 +5830,7 @@ function renderCheckpoint(rec, workflow, item) {
5830
5830
  const entry = rec.stepId ? workflow.stepMap.get(rec.stepId) : undefined;
5831
5831
  const stepCaps = Array.from(new Set((entry?.step.agents ?? []).flatMap((a) => a.capability_tags)));
5832
5832
  if (resolveMustDoForCaps(stepCaps).length > 0) {
5833
- lines.push(`质量门类 step 的 giveup 决策:未覆盖必做项须经 \`checkpoint_skip_reasons\` 逐项申报结构化降级理由(格式:\`${SKIP_REASON_FORMAT}\`),缺理由 giveup 不会被受理。`, "");
5833
+ lines.push(`含必做清单的 step 的 giveup 决策:未覆盖必做项须经 \`checkpoint_skip_reasons\` 逐项申报结构化降级理由(格式:\`${SKIP_REASON_FORMAT}\`),缺理由 giveup 不会被受理。`, "");
5834
5834
  }
5835
5835
  return lines.join(`
5836
5836
  `);
@@ -8149,8 +8149,8 @@ function handleReviewParams(item, params, newChildren, stepId, opts) {
8149
8149
  if (params.verdict === "passed" && !opts.skipMustDoGate) {
8150
8150
  const uncovered = uncoveredMustDo(opts.capabilityTags, params.validation_steps);
8151
8151
  if (uncovered.length > 0) {
8152
- throw new Error(`提交的验证步骤未覆盖质量门 skill 必做清单,缺少以下必做项:${uncovered.join("、")}。
8153
- ` + `请按已加载质量门类 skill 的必做清单逐项执行并逐项申报结果(completed=true);` + `确实无法执行的必做项须以结构化 skip_reason 申报降级理由` + `(格式:${SKIP_REASON_FORMAT})。` + `低成本必做项必须实跑后申报;核验申报仅限 workflow 指令白名单限定的高成本必做项。`);
8152
+ throw new Error(`提交的验证步骤未覆盖已加载 skill 的必做清单,缺少以下必做项:${uncovered.join("、")}。
8153
+ ` + `请按已加载 skill 的必做清单逐项执行并逐项申报结果(completed=true);` + `确实无法执行的必做项须以结构化 skip_reason 申报降级理由` + `(格式:${SKIP_REASON_FORMAT})。` + `低成本必做项必须实跑后申报;核验申报仅限 workflow 指令白名单限定的高成本必做项。`);
8154
8154
  }
8155
8155
  }
8156
8156
  const isTaskVerifyStep = stepId === "verify_task" || stepId === "quality_review";
@@ -8433,7 +8433,7 @@ async function applyCheckpointDecision(params, item, workflow, ctx, state) {
8433
8433
  }
8434
8434
  const missing = uncovered.filter((m) => !provided.has(m));
8435
8435
  if (missing.length > 0) {
8436
- throw new Error(`giveup 无法应用:当前 step 的质量门必做清单存在未覆盖项,须逐项提供结构化降级理由。
8436
+ throw new Error(`giveup 无法应用:当前 step 的已加载 skill 必做清单存在未覆盖项,须逐项提供结构化降级理由。
8437
8437
  ` + `缺少降级理由的必做项:${missing.join("、")}
8438
8438
  ` + `请通过 checkpoint_skip_reasons 逐项提供(giveup 未覆盖项不可跳过申报):
8439
8439
  ` + `[${SKIP_REASON_FORMAT}]`);
@@ -8671,7 +8671,7 @@ var checkpointSkipReasonItem = {
8671
8671
  type: "object",
8672
8672
  description: "giveup 决策的必做项结构化降级理由",
8673
8673
  properties: {
8674
- item: { type: "string", minLength: 1, description: "对应的必做项(质量门 skill 的 must_do 清单项)" },
8674
+ item: { type: "string", minLength: 1, description: "对应的必做项(已加载 skill 的 must_do 清单项)" },
8675
8675
  category: { type: "string", minLength: 1, description: "降级类别,如环境不可用 / 用户裁定豁免 / 无人值守自动降级" },
8676
8676
  adjudication: {
8677
8677
  type: "string",
@@ -8852,7 +8852,7 @@ var agentSubmitSchema = {
8852
8852
  },
8853
8853
  checkpoint_skip_reasons: {
8854
8854
  type: "array",
8855
- description: "giveup 决策配套:对当前 step 质量门必做清单未覆盖项的结构化降级理由(未覆盖项缺理由则拒绝 giveup)",
8855
+ description: "giveup 决策配套:对当前 step 已加载 skill 必做清单未覆盖项的结构化降级理由(未覆盖项缺理由则拒绝 giveup)",
8856
8856
  items: checkpointSkipReasonItem
8857
8857
  },
8858
8858
  new_children: {
@@ -8282,7 +8282,7 @@ ${content.join(`
8282
8282
  var version = {
8283
8283
  major: 4,
8284
8284
  minor: 6,
8285
- patch: 6
8285
+ patch: 7
8286
8286
  };
8287
8287
 
8288
8288
  // node_modules/zod/v4/core/schemas.js
@@ -27427,7 +27427,7 @@ function renderCheckpoint(rec, workflow, item) {
27427
27427
  const entry = rec.stepId ? workflow.stepMap.get(rec.stepId) : undefined;
27428
27428
  const stepCaps = Array.from(new Set((entry?.step.agents ?? []).flatMap((a) => a.capability_tags)));
27429
27429
  if (resolveMustDoForCaps(stepCaps).length > 0) {
27430
- lines.push(`质量门类 step 的 giveup 决策:未覆盖必做项须经 \`checkpoint_skip_reasons\` 逐项申报结构化降级理由(格式:\`${SKIP_REASON_FORMAT}\`),缺理由 giveup 不会被受理。`, "");
27430
+ lines.push(`含必做清单的 step 的 giveup 决策:未覆盖必做项须经 \`checkpoint_skip_reasons\` 逐项申报结构化降级理由(格式:\`${SKIP_REASON_FORMAT}\`),缺理由 giveup 不会被受理。`, "");
27431
27431
  }
27432
27432
  return lines.join(`
27433
27433
  `);
@@ -29746,8 +29746,8 @@ function handleReviewParams(item, params, newChildren, stepId, opts) {
29746
29746
  if (params.verdict === "passed" && !opts.skipMustDoGate) {
29747
29747
  const uncovered = uncoveredMustDo(opts.capabilityTags, params.validation_steps);
29748
29748
  if (uncovered.length > 0) {
29749
- throw new Error(`提交的验证步骤未覆盖质量门 skill 必做清单,缺少以下必做项:${uncovered.join("、")}。
29750
- ` + `请按已加载质量门类 skill 的必做清单逐项执行并逐项申报结果(completed=true);` + `确实无法执行的必做项须以结构化 skip_reason 申报降级理由` + `(格式:${SKIP_REASON_FORMAT})。` + `低成本必做项必须实跑后申报;核验申报仅限 workflow 指令白名单限定的高成本必做项。`);
29749
+ throw new Error(`提交的验证步骤未覆盖已加载 skill 的必做清单,缺少以下必做项:${uncovered.join("、")}。
29750
+ ` + `请按已加载 skill 的必做清单逐项执行并逐项申报结果(completed=true);` + `确实无法执行的必做项须以结构化 skip_reason 申报降级理由` + `(格式:${SKIP_REASON_FORMAT})。` + `低成本必做项必须实跑后申报;核验申报仅限 workflow 指令白名单限定的高成本必做项。`);
29751
29751
  }
29752
29752
  }
29753
29753
  const isTaskVerifyStep = stepId === "verify_task" || stepId === "quality_review";
@@ -30030,7 +30030,7 @@ async function applyCheckpointDecision(params, item, workflow, ctx, state) {
30030
30030
  }
30031
30031
  const missing = uncovered.filter((m) => !provided.has(m));
30032
30032
  if (missing.length > 0) {
30033
- throw new Error(`giveup 无法应用:当前 step 的质量门必做清单存在未覆盖项,须逐项提供结构化降级理由。
30033
+ throw new Error(`giveup 无法应用:当前 step 的已加载 skill 必做清单存在未覆盖项,须逐项提供结构化降级理由。
30034
30034
  ` + `缺少降级理由的必做项:${missing.join("、")}
30035
30035
  ` + `请通过 checkpoint_skip_reasons 逐项提供(giveup 未覆盖项不可跳过申报):
30036
30036
  ` + `[${SKIP_REASON_FORMAT}]`);
@@ -30255,7 +30255,7 @@ var checkpointSkipReasonItem = {
30255
30255
  type: "object",
30256
30256
  description: "giveup 决策的必做项结构化降级理由",
30257
30257
  properties: {
30258
- item: { type: "string", minLength: 1, description: "对应的必做项(质量门 skill 的 must_do 清单项)" },
30258
+ item: { type: "string", minLength: 1, description: "对应的必做项(已加载 skill 的 must_do 清单项)" },
30259
30259
  category: { type: "string", minLength: 1, description: "降级类别,如环境不可用 / 用户裁定豁免 / 无人值守自动降级" },
30260
30260
  adjudication: {
30261
30261
  type: "string",
@@ -30436,7 +30436,7 @@ var agentSubmitSchema = {
30436
30436
  },
30437
30437
  checkpoint_skip_reasons: {
30438
30438
  type: "array",
30439
- description: "giveup 决策配套:对当前 step 质量门必做清单未覆盖项的结构化降级理由(未覆盖项缺理由则拒绝 giveup)",
30439
+ description: "giveup 决策配套:对当前 step 已加载 skill 必做清单未覆盖项的结构化降级理由(未覆盖项缺理由则拒绝 giveup)",
30440
30440
  items: checkpointSkipReasonItem
30441
30441
  },
30442
30442
  new_children: {
@@ -30575,7 +30575,7 @@ async function ensureDefaultUnattended(args, ctx) {
30575
30575
  }
30576
30576
  } catch {}
30577
30577
  }
30578
- var PKG_VERSION = "0.147.2";
30578
+ var PKG_VERSION = "0.149.0";
30579
30579
  function buildMcpServer(worktree, opts = {}) {
30580
30580
  const mcp = new McpServer({ name: "openspec-agents", version: PKG_VERSION });
30581
30581
  for (const [name, spec] of Object.entries(TOOL_SPECS)) {
@@ -31567,7 +31567,7 @@ var makeCloseHandler = (req, incoming, outgoing, needsBodyCleanup) => () => {
31567
31567
  if (incoming.errored) {
31568
31568
  recordBodyBufferedBeforeDisconnect(incoming);
31569
31569
  req[abortRequest](incoming.errored.toString());
31570
- } else if (!outgoing.writableFinished) {
31570
+ } else if (!outgoing.writableFinished || incoming instanceof Http2ServerRequest && incoming.aborted) {
31571
31571
  recordBodyBufferedBeforeDisconnect(incoming);
31572
31572
  req[abortRequest]("Client connection prematurely closed.");
31573
31573
  }
package/README.md CHANGED
@@ -128,14 +128,14 @@ openspec/states/
128
128
 
129
129
  ## 内置的规范库
130
130
 
131
- 插件自带 22 份 skill(含两个流程入口),装了就有,不用自己写提示词;审查的 AI 会按当前任务需要自动挂上对应的一组。
131
+ 插件自带 23 份 skill(含两个流程入口),装了就有,不用自己写提示词;审查的 AI 会按当前任务需要自动挂上对应的一组。
132
132
 
133
133
  **两个入口**
134
134
 
135
135
  - `orchestrator` —— 编排准则,主代理按它分派子代理、推进流程。
136
136
  - `openspec-standard` —— 提案标准初始化。
137
137
 
138
- **9 份通用规范**:DDD 分层与六边形、REST 接口约定、数据库设计约定、安全审查基线、确定性质量门、技术债识别、架构演进审查、API 自动化测试、隔离环境清理。
138
+ **10 份通用规范**:DDD 分层与六边形、REST 接口约定、数据库设计约定、安全审查基线、确定性质量门、测试设计、技术债识别、架构演进审查、API 自动化测试、隔离环境清理。
139
139
 
140
140
  **11 份 Java 后端配套**:在通用规范之上补齐 Java / Spring 的实现细节 —— Lombok、日志与命名约定、REST 接口的 Java 实现、MyBatisPlus 与 Flyway、DDD 的 Java 实现与 ArchUnit 规则、Maven / Spotless / PMD / SonarQube 质量门、工具规则改进、Java 开发实践、Java 安全实现、Java 性能与可维护性、Java 技术债形态。
141
141
 
@@ -151,6 +151,7 @@ OpenSpec 官方默认的流程是 `proposal → specs → design → tasks`,
151
151
  | 需求澄清 | 澄清不强制,靠 explore 用法自行把握 | 决策树逐轮提问,每题附推荐答案;事实类疑问自己查代码,不抛给你 |
152
152
  | 动笔门禁 | 无 | 疑点问完 + 你确认方案,才允许开始写文档;确认必须文字回复,点选项不算 |
153
153
  | 改动范围 | proposal 里一句 Impact 描述 | 关联场景清点:把用到这块逻辑的入口、复用链路、数据上下游全列出来,每条附代码位置,逐条跟你确认纳入还是排除;共用逻辑的所有入口必须同一变更里一起改 |
154
+ | 规则边界推演 | 无 | 新增或改动规则、校验、拦截逻辑时,先推演这条规则本身站不站得住:该拦的条件与例外、功能上合法却会被误伤的合法反例(各对应 spec 一条「应当放行」场景)、同一业务意图的等价执行路径与判定挂载点(挂在业务意图层的动作上,不落在被别的流程复用的底层动作上);变更新增或改了执行路径时,逐条核对既有规则在新路径上是否仍该生效 |
154
155
  | 契约变更 | 无专门要求 | 逐条列:建表到列(名/类型/可空/默认值/用途)、接口到字段与方法路径、兼容性影响 |
155
156
  | 文档语言 | 要求 spec 避免类名、函数名 | 方案摘要与实施逻辑也必须用人话,禁止类名、方法名这类代码黑话(契约事实与技术设计文档除外) |
156
157
  | 任务划分 | 分组 + 每条带验证方式 | 追加:每组必须有真实代码改动(禁止「收尾组」凑数)、测试跟着实现同组、只覆盖本仓库 |
@@ -11,7 +11,7 @@ permission:
11
11
 
12
12
  ## 角色(开发者身份)
13
13
 
14
- 你是后端开发工程师,专注于实现 OpenSpec 任务组中的代码开发任务,同时是质量门与接口测试的执行责任人:确定性检查与接口测试由你执行并经自检申报留痕,自检申报是 reviewer 分级复验的事实输入。
14
+ 你是后端开发工程师,专注于实现 OpenSpec 任务组中的代码开发任务,同时是质量门、接口测试与测试设计的执行责任人:确定性检查与接口测试由你执行并经自检申报留痕,自检申报是 reviewer 分级复验的事实输入。
15
15
 
16
16
  提交前按已加载 skill(含质量维度规范类)完成自检,审查兜底与终局裁定仍由对应 reviewer 承担(自检不替代 reviewer 裁定)。
17
17
 
@@ -65,7 +65,7 @@ Info 级别 issue 的 description/suggestion 中禁止出现阶段/时机相关
65
65
  |------|-------------|-------------|---------|
66
66
  | Critical | 核心 task 产出文件缺失 | 服务无法启动(无论是否本次变更引起) | 测试依赖无隔离环境导致 CI 必然失败 |
67
67
  | High | 关键 task 产出不完整;行为无实现(仅状态标记未实际生效);流程执行正常但关键数据产出缺失/未落库/落错位置(区别于『仅打状态标记未实际生效』:本行=流程与响应正常,产出物缺失或落错位) | 健康检查不通过;关键外部依赖不可用;新增接口无法调通(不论原因) | 核心业务逻辑无测试覆盖;Mock 了被测对象本身;测试仅断言可见状态/响应而 spec 要求的一并操作行为(入队/落库/下游消费等)无断言,将缺陷固化为期望行为;测试仅验证流程跑通/响应成功,未对 spec 要求的关键数据产出(落位/完整性)断言 |
68
- | Medium | task 产出存在但质量不达标;关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 | 启动有 WARN 但服务可用 | 断言过于宽松;缺少边界值测试;关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 |
68
+ | Medium | task 产出存在但质量不达标;关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 | 启动有 WARN 但服务可用 | 断言过于宽松;缺少边界值测试或未提交测试设计物证据(行为面清单/用例矩阵/反向探针记录);关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 |
69
69
  | Low | 产出文件位置不符合约定 | 启动日志格式不统一 | 测试命名不规范但不影响运行 |
70
70
  | Info | 建议补充额外产出物 | 建议增加启动度量指标 | 建议补充边缘用例 |
71
71
 
@@ -81,7 +81,10 @@ Info 级别 issue 的 description/suggestion 中禁止出现阶段/时机相关
81
81
  |------|--------------|--------------------------|
82
82
  | Critical | 核心层依赖框架导致循环依赖或编译失败 | design 中的 schema 与实现冲突导致无法建表/编译;tasks 缺失核心步骤导致实施方向错误;实施所需关键信息缺失(如模板路径、字段映射未明),导致无法开始实施;设计架构方案违反 architecture skill 的 MUST 规则 |
83
83
  | High | 表示层直接绕过领域层访问基础设施 | spec 需求在 tasks 中无对应任务;基础架构任务错排位置;实施所需信息不完整,部分任务需等待补充信息才能推进;设计方案偏离 architecture skill 推荐做法,存在可通过调整规避的风险;设计方案破坏既有接口/数据/行为契约且无兼容或过渡安排;重构方案改变既有行为语义且未显式声明 |
84
+ | High | 已实现的校验/拦截把功能上合法的场景拦住,或判定挂在被其它业务流程复用的底层动作上致其误触,且无兼容或过渡安排 | 方案新增/修改的规则会误伤功能上合法的场景,或判定挂载点会被复用该动作的其它流程误触,且方案未说明 |
85
+ | High | 本次变更新增或重排的执行路径绕过了既有校验/拦截(该拦未拦),且无兼容或过渡安排 | 方案新增或重排的执行路径会使既有规则/校验/拦截失效(该拦未拦),且方案未说明如何在新路径上保持该判定 |
84
86
  | Medium | 依赖注入方式不符合约定(如字段注入);数据对象可变导致并发风险;应基础设施化的共性能力被分散实现(多处重复、横向共性需求、新增场景易遗漏调用);引入与既有实现功能重叠的平行实现(另起一套逻辑),同类能力多套方案并存且无迁移方案;引入或延续可识别技术债且无偿还规划(如采用 EOL/弃用技术选型、临时方案长期固化、接口契约不一致);重构/变更破坏既有契约(接口/数据/行为)或改变既有行为语义且无兼容说明 | tasks 范围模糊;design 技术细节与 tasks 完成标准不一致 |
87
+ | Medium | 已实现的校验/拦截落在被其它业务流程复用的底层动作上,或未覆盖 design.md 列出的例外与等价执行路径,无法确认是否会误伤 | 方案未给出规则边界结论(该拦条件、该放的例外与合法反例、等价执行路径与判定挂载点),无法判断是否会误伤 |
85
88
  | Low | 数据对象缺少不可变修饰但当前无并发场景;已有代码中违反分层原则但影响极小的结构性缺陷 | 文档引用路径有冗余前缀;描述用词与 spec 不一致但不影响理解 |
86
89
  | Info | 建议拆分为独立服务;建议引入某设计模式(仅当不属于 Low 及以上时) | 建议补充某边缘场景说明;可 `(待补充)` 占位、不阻塞开工的边缘信息缺失 |
87
90
 
@@ -145,7 +148,7 @@ Info 级别 issue 的 description/suggestion 中禁止出现阶段/时机相关
145
148
  - 命名合理性:按 skill 中的通用语言与命名规范——命名体现意图、不与其他场景混淆、与术语表一致防漂移
146
149
  - 方案复用与平行实现:识别引入与既有实现功能重叠的平行实现(另起一套逻辑)的情况——同类能力已有既有实现时须优先复用或扩展,另建实现且不改动原实现、无迁移方案则报 issue;方案确需平行引入(新旧并存)时按需用户拍板问题的确认机制确认并存期与技术债,无人值守缺省裁决为方案必须包含原技术实现的迁移方案。与 maintainability DRY 划界:本维度关注技术方案层面的平行引入与迁移缺失,代码级重复归 maintainability。具体复用与迁移要求按 skill 约定
147
150
  - 技术债识别:按 skill 中的技术债识别约定——识别存量与新增技术债(过时技术选型、迁移中断残留、平行实现、临时方案固化、契约不一致),按统一严重级别报 issue;方案引入的债务须在方案中规划偿还或说明可接受理由
148
- - 架构演进审查:按 skill 中的架构演进审查约定——方案/实现是否延续项目整体架构方向、是否支持长期迭代演进、是否破坏既有契约(接口签名/数据格式/行为语义兼容性)、重构是否贴合项目历史逻辑并保持既有行为语义;实施侧破坏兼容或改变既有语义按统一严重级别报 issue,方案侧破坏兼容或偏离架构脉络须在方案中说明理由与过渡安排;涉及字段/实体承载位置搬迁时,方案须明确数据承接与迁移设计:新承载位置、产出字段写入目标、存量数据迁移、旧位置兼容与清理;缺失按既有契约破坏/重构贴合判例报 issue
151
+ - 架构演进审查:按 skill 中的架构演进审查约定——方案/实现是否延续项目整体架构方向、是否支持长期迭代演进、是否破坏既有契约(接口签名/数据格式/行为语义兼容性)、重构是否贴合项目历史逻辑并保持既有行为语义;实施侧破坏兼容或改变既有语义按统一严重级别报 issue,方案侧破坏兼容或偏离架构脉络须在方案中说明理由与过渡安排;涉及字段/实体承载位置搬迁时,方案须明确数据承接与迁移设计:新承载位置、产出字段写入目标、存量数据迁移、旧位置兼容与清理;变更涉及新增/修改业务规则、校验或拦截,或新增/改变任何执行路径时,核对规则边界推演——该拦条件与例外、功能上合法的反例(是否存在不该拦而拦)、既有规则在新执行路径上是否仍成立(是否存在该拦未拦)、同一业务意图的等价执行路径及其判定挂载点(判定须挂在业务意图层的动作上,不得落在被其它业务流程复用的底层动作上);推演缺失或不完整按统一严重级别报 issue
149
152
 
150
153
  ### 可维护性维度
151
154
 
@@ -194,7 +197,7 @@ Info 级别 issue 的 description/suggestion 中禁止出现阶段/时机相关
194
197
  ## 职责边界(确定性检查与任务验证)
195
198
 
196
199
  - **确定性工具检查**:工具维度审查者与 simple 合并审查者被允许运行确定性工具检查(代码格式/架构约束/静态分析/单元测试编译/深度扫描),按已加载质量门 skill 的必做清单执行并将输出映射为统一 issue 结构;检查结果纳入审查结论
197
- - **任务验证**:任务维度审查者与 simple 合并审查者承担任务验证职责,验证 task 产出完整性、服务健康与 API 测试质量;未通过的 task 经 failed_tasks 上报;验证完成后按清理规范做幂等清理,不留环境残留;数据产出核验——对照 spec 数据产出要求核验关键数据产出落位/完整性/搬迁承接/基线对比,识别『流程正常但数据缺失/落错位置』类缺陷
200
+ - **任务验证**:任务维度审查者与 simple 合并审查者承担任务验证职责,验证 task 产出完整性、服务健康与 API 测试质量;未通过的 task 经 failed_tasks 上报;验证完成后按清理规范做幂等清理,不留环境残留;数据产出核验——对照 spec 数据产出要求核验关键数据产出落位/完整性/搬迁承接/基线对比,识别『流程正常但数据缺失/落错位置』类缺陷;测试设计核验——对照 spec 与独立推导的行为面核验测试设计物(行为面清单、用例矩阵、反向探针记录),识别漏面、漏格、断言放水与探针缺失
198
201
  - **维度审查锚点**:以 spec 验收标准、行为组与数据产出要求为主锚做对照审查,skill 检查点清单与 dev 自检申报对照兜底(抽查申报遗漏项)
199
202
  - **工具改进**:可工具化的质量 pattern 双报业务 issue 与工具改进 issue(规则草案由审查者提供),实施工作由开发者完成,审查者不直接改动规则/配置文件以外的实现
200
203
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: architecture-evolution
3
- description: 架构演进审查(架构维度)——方案/变更与项目整体架构脉络的契合度、长期迭代演进支持、拓展性与兼容性、重构对历史逻辑与既有行为语义的贴合。技术栈无关。
3
+ description: 架构演进审查(架构维度)——方案/变更与项目整体架构脉络的契合度、长期迭代演进支持、拓展性与兼容性(新增/修改的规则、校验或拦截误伤功能上合法的既有操作、既有规则在新执行路径上是否仍成立、判定挂载点是否落在被其它业务流程复用的底层动作上)、重构对历史逻辑与既有行为语义的贴合。技术栈无关。
4
4
  capabilities: ["architecture"]
5
5
  ---
6
6
 
@@ -45,10 +45,10 @@ capabilities: ["architecture"]
45
45
 
46
46
  变更是否破坏既有契约——接口签名、数据格式、行为语义;破坏时是否有兼容或过渡安排;应预留拓展点而未预留。
47
47
 
48
- - 识别信号:修改既有接口签名/响应结构/字段语义且调用方未同步;存量数据/历史行为不兼容;破坏性变更无过渡方案
49
- - 判据:破坏既有契约且无兼容/过渡安排
50
- - 处置:破坏既有契约且无兼容/过渡安排 → 至少 Medium 级别 issue
51
- - 划界:跨接口/模块同一语义表达不一致(枚举 vs 数字码)归契约不一致职责;本类关注变更对既有契约的破坏与兼容安排
48
+ - 识别信号:修改既有接口签名/响应结构/字段语义且调用方未同步;存量数据/历史行为不兼容;破坏性变更无过渡方案;本次新增/变更的规则、校验或拦截把功能上合法的既有操作一并拦住(不该拦而拦);既有规则、校验或拦截在被本次变更新增或重排的执行路径上失效(该拦未拦);判定挂在被其它业务流程复用的底层动作上,致那些流程被误触
49
+ - 判据:破坏既有契约且无兼容/过渡安排;既有规则、校验或拦截在本次新增/重排的执行路径上失效(该拦未拦),或本次新增/变更的规则把功能上合法的既有操作一并拦住(不该拦而拦);或未给出规则边界推演结论(未列出该放行的例外与合法反例、同一业务意图的其它执行路径、判定挂载点)致结论无法核验
50
+ - 处置:破坏既有契约且无兼容/过渡安排 → 至少 Medium 级别 issue;规则误伤功能上合法的场景、或判定挂在被其它业务流程复用的底层动作上致其误触 → 至少 Medium 级别 issue;规则边界推演缺失或无法核验 → 至少 Medium 级别 issue;既有规则在新增/重排的执行路径上失效(该拦未拦)致行为语义变更 → 至少 Medium 级别 issue(无兼容或过渡安排时按架构维度判例表 High 级口径)
51
+ - 划界:跨接口/模块同一语义表达不一致(枚举 vs 数字码)归契约不一致职责;本类关注变更对既有契约的破坏与兼容安排,以及规则在既有合法路径上是否仍成立、判定挂在哪一层;规则类问题的判据措辞用「不该拦而拦 / 该拦未拦」,不按契约破坏口径表述
52
52
 
53
53
  ### 4. 重构贴合历史逻辑
54
54
 
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: openspec-standard
3
- description: OpenSpec 提案标准初始化与升级——把标准版提案规则(openspec/config.yaml + spec-driven-standard schema 全套)安装到当前项目,统一后续提 change 的质量门槛(关联场景清点、契约变更详列、人话变更清单与实施逻辑、结构化方案摘要、动笔前访谈与用户确认)。当用户要求初始化、升级或标准化 openspec 提案标准/提案规范时使用。
3
+ description: OpenSpec 提案标准初始化与升级——把标准版提案规则(openspec/config.yaml + spec-driven-standard schema 全套)安装到当前项目,统一后续提 change 的质量门槛(关联场景清点、规则边界推演、契约变更详列、人话变更清单与实施逻辑、结构化方案摘要、动笔前访谈与用户确认)。当用户要求初始化、升级或标准化 openspec 提案标准/提案规范时使用。
4
4
  capabilities: ["openspec-standard"]
5
5
  ---
6
6
 
7
7
  ## 职责
8
8
 
9
- 把本 skill 目录 `templates/` 下的标准文件安装到当前项目的 `openspec/` 目录,使该项目此后用 openspec 提 change 时自动遵循统一标准:关联场景清点(共享处理逻辑的变更须与其全部消费入口同一 change 统一适配,同一数据多条落库路径的校验一致性为访谈必问分支)、契约变更详列、实施逻辑人话分步(proposal 单列实施逻辑小节,禁代码级名词)、结构化方案摘要(访谈穷尽后才给出,一句话做什么、变更内容人话逐条列明并禁代码级名词,以普通消息确认)、动笔前访谈门与用户确认门、任务组实质变更主体、测试随实现同组(禁为测试单开任务组)、单仓变更范围(分仓的前后端默认互不纳入,除非用户明确要求)等。幂等:重跑即把标准升级到插件当前版本,项目自定义内容按下方合并策略保留。
9
+ 把本 skill 目录 `templates/` 下的标准文件安装到当前项目的 `openspec/` 目录,使该项目此后用 openspec 提 change 时自动遵循统一标准:关联场景清点(共享处理逻辑的变更须与其全部消费入口同一 change 统一适配,同一数据多条落库路径的校验一致性为访谈必问分支)、规则边界推演(新增/修改规则须推演该拦条件、该放的合法例外与反例、同一业务意图的等价执行路径与判定挂载点)、契约变更详列、实施逻辑人话分步(proposal 单列实施逻辑小节,禁代码级名词)、结构化方案摘要(访谈穷尽后才给出,一句话做什么、变更内容人话逐条列明并禁代码级名词,以普通消息确认)、动笔前访谈门与用户确认门、任务组实质变更主体、测试随实现同组(禁为测试单开任务组)、单仓变更范围(分仓的前后端默认互不纳入,除非用户明确要求)等。幂等:重跑即把标准升级到插件当前版本,项目自定义内容按下方合并策略保留。
10
10
 
11
11
  ## 前置检查
12
12
 
@@ -1,10 +1,9 @@
1
1
  schema: spec-driven-standard
2
2
 
3
3
  context: |
4
- 项目技术背景、架构约定与工程规范以项目根目录 AGENTS.md 为准。
5
- 本文件仅承载 OpenSpec 流程的通用规则;与项目相关的特化约束
6
- (技术栈、分层架构、数据库约定、质量门、方法论选择等)一律写入
7
- 项目 AGENTS.md,生成与复核子代理会被指示读取它。
4
+ 项目特化约束以项目根目录 AGENTS.md 为索引入口(技术栈、目录结构、项目阶段、
5
+ 跨模块复用约定与关键坑位),规则细则以 openspec/specs/ 下的主 spec 为权威锚,
6
+ 操作流程与方法在项目级 skill(.agents/skills/);生成与复核子代理会被指示读取它。
8
7
  explore 模式与 proposal 侧同源同严:凡涉及理清需求,必须按
9
8
  spec-driven-standard schema clarify 指令的决策树访谈方法论逐轮穷尽
10
9
  疑点;疑点未穷尽不得收束结论、不得捕获任何变更工件
@@ -18,10 +17,14 @@ rules:
18
17
  - "实施逻辑与方案摘要结构(强制):proposal.md 必须单列「实施逻辑(Implementation Outline)」小节,按步骤用业务语言(人话)讲清具体怎么做——数据从哪来、经过什么校验与处理、落到哪、关联场景小节划入的每条链路怎么适配;禁止出现类名/方法名/内部函数名等代码级名词(用户明确要求技术深度时除外;契约变更点小节的表名/列名/端点路径等契约事实不受此限、保持精确)。方案摘要必须按 spec-driven-standard schema clarify 指令 Plan confirmation gate 的要素清单结构化逐项展开——先用一句话说明本次变更做什么,变更内容再用自然语言(人话)逐条列出,每条形如「导出功能新增「状态」字段」并视需要展开必要背景(如该字段的来源、用途),禁止掺杂类名/方法名等代码级名词(限制口径同实施逻辑小节);摘要含人话分步实施逻辑与关联链路划界结论,两三句话的摘要视为未完成。"
19
18
  - "动笔前用户确认门(强制):proposal/specs/design/tasks 任一文档动笔前,clarify.md 的 Architecture Direction 必须已记录用户对方案摘要的明确确认;确认必须以普通消息直接列出方案摘要要素点(要素清单见 spec-driven-standard schema clarify 指令的 Plan confirmation gate)并停下等待用户直接文字回复,禁止通过提问工具发起确认,提问工具的选项点击不视为确认;未记录时禁止写任何文档——主代理亲自写时先停下向用户补确认,生成子代理则立即终止并向编排方报告,不得以「需求简单」等理由跳过或代用户确认。"
20
19
  - "单仓变更范围(强制):本 change 的变更点只落在本次会话所在的仓库——在独立的前端仓或后端仓会话中,不得把另一端仓库的改动(如后端仓的 change 纳入前端页面代码、前端仓的 change 纳入后端接口实现)写入 proposal/specs/design/tasks 任一工件。关联场景清点发现另一端仓库存在消费方时,按「排除(属另一仓库,另提 change)」记录并附理由,且不得在本 change 内为其排任务。仅当用户明确要求跨仓时才纳入,并在 proposal.md 单列「拆分边界」小节写明哪部分改动归本仓、哪部分归另一仓库、各自如何实施与验证。前后端同处一个仓库时不存在「另一端仓库」,不适用本约束。"
20
+ - "规则边界推演(强制):凡变更新增/修改业务规则、校验或拦截逻辑,或新增/改变任何执行路径,proposal.md 必须单列「规则边界(Rule Boundary)」小节,以表格逐条列出每条规则的该拦条件、该放的例外与合法反例(附应有处理)、判定挂载点,并给出同一业务意图的其它执行路径清单及逐条结论;不涉及规则的变更写「不适用」+ 一句理由。缺该小节或仅以「无特殊情况」泛写而无推演结论视为 proposal 未完成。推演方法以 schema clarify 指令的规则边界分支为权威源,本条目只定门禁口径。"
21
21
  specs:
22
22
  - "数据行为需求(如\"系统 SHALL 持久化 X 含审计字段\")放 spec;物理 DDL 放 design.md。"
23
23
  - "MODIFIED 的需求描述直接给出变更后的终态契约表述(\"系统 SHALL 使用 Y\"),供归档合并时原样落入主 spec;禁止以\"原 X 改为 Y\"的历史对比充当主 spec 内容。"
24
24
  - "同一语义只保留一条需求:修改已有需求用 MODIFIED,不得以新标题重复描述同一能力。"
25
+ - "规则边界三类场景(强制):新增/修改业务规则、校验或拦截逻辑,或新增/改变任何执行路径的变更,spec 必须按规则边界结论逐条给出三类 Scenario——应当拦截(含判定成立的最小条件)、应当放行(例外与合法反例)、同一业务意图的其它执行路径应当放行(每条路径一个 Scenario);不适用的写明理由,只有拦截侧场景视为需求未完成。"
26
+ design:
27
+ - "判定挂载点(强制):新增/修改业务规则、校验或拦截逻辑,或新增/改变任何执行路径的变更,design.md 必须写明判定挂在哪个业务动作/哪一层,以及为何不会被同一业务意图的其它执行路径(含复用该底层动作的其它流程)误触;不涉及规则的变更写明「不适用」+ 一句理由。"
25
28
  tasks:
26
29
  - "每个任务组必须以实质变更为主体(强制):组内至少一个任务承载真实的代码/配置行为变更(实现 + 测试);文档/脚本/部署文档同步、验证、回归、质量门只是随行工作,不构成组的实质内容。任务条数不等于实质——排到末位的剩余工作若只剩同步与验证,必须并入前一个功能组,禁止为其新开组(反例:「阶段二收尾:文档、脚本与全量验证」式收尾组)。"
27
30
  - "任务组覆盖关联入口(强制):tasks.md 的任务组划分必须覆盖 proposal.md「关联场景」小节划入本 change 的全部消费入口;任一划入入口缺少对应适配任务视为 tasks 未完成。"
@@ -2,16 +2,24 @@
2
2
 
3
3
  通用 spec-driven 工作流模板:clarify → proposal → specs → design → tasks,
4
4
  增强三点:
5
- 1. **clarify 前置门槛 + 关联场景清点**:每次变更先做需求澄清与关联场景清点
6
- (首轮提问前枚举变更触及能力的全部消费方——功能入口 / 共享处理逻辑 /
7
- 数据流下游,附代码证据;每个清点条目在访谈中经用户划界确认——纳入本
8
- change 统一适配或排除附理由;同一数据存在多条落库路径时各路径校验与
9
- 处理逻辑的一致性为必问分支;共享处理逻辑变更须与其全部消费入口同一
10
- change 统一适配);访谈穷尽后、写任何文档之前,主代理必须先向用户汇报
11
- 结构化方案摘要(按要素清单逐项编号展开:一句话做什么 + 变更内容人话
5
+ 1. **clarify 前置门槛 + 关联场景清点 + 规则边界推演**:每次变更先做需求澄清
6
+ 与关联场景清点(首轮提问前枚举变更触及能力的全部消费方——功能入口 /
7
+ 共享处理逻辑 / 数据流下游,附代码证据;每个清点条目在访谈中经用户划界
8
+ 确认——纳入本 change 统一适配或排除附理由;同一数据存在多条落库路径时
9
+ 各路径校验与处理逻辑的一致性为必问分支;共享处理逻辑变更须与其全部消费
10
+ 入口同一 change 统一适配);规则边界推演与清点分工:清点管「谁受影响」,
11
+ 规则边界推演管「判定条件本身站不站得住」——凡新增/修改业务规则、校验或
12
+ 拦截逻辑,或新增/改变任何执行路径的变更,须逐条推演该拦的条件与例外、
13
+ 功能上合法却会被误伤的合法反例(各对应 spec 一条「应当放行」场景)、同一
14
+ 业务意图的等价执行路径与判定挂载点(判定挂在业务意图层的动作上,不得落在
15
+ 被其它业务流程复用的底层动作上),并逐条核对新路径下既有规则是否仍该生效;
16
+ 结论落进 proposal 的「规则边界」小节与 spec 的应当拦截 / 应当放行 / 等价
17
+ 执行路径三类场景,其余变更写「不适用」+ 一句理由;访谈穷尽后、写任何
18
+ 文档之前,主代理必须先向用户汇报结构化方案摘要(按要素清单逐项编号展开:
19
+ 一句话做什么 + 变更内容人话
12
20
  逐条列明(形如「导出功能新增「状态」字段」,视需要说明字段来源等
13
21
  背景)+ 是否动契约 + 选定方案与备选取舍 + 人话分步实施逻辑 +
14
- 关联链路划界结论 + 影响的能力面)并取得用户明确确认(HARD-GATE:摘要须以普通消息呈现,禁止用提问
22
+ 关联链路划界结论 + 规则边界推演结论 + 影响的能力面)并取得用户明确确认(HARD-GATE:摘要须以普通消息呈现,禁止用提问
15
23
  工具发起确认,访谈中的问答不视为确认;访谈未穷尽禁止呈现方案求确认,
16
24
  轮次中每题附的推荐答案不视为方案),确认记录落在 clarify.md,后续文档
17
25
  不得偏离。proposal.md 单列「实施逻辑」小节,以人话分步讲清怎么做(禁
@@ -74,8 +82,8 @@ openspec/schemas/<schema-name>/
74
82
 
75
83
  | 位置 | 承载内容 | 例子 |
76
84
  |---|---|---|
77
- | `schema.yaml` instruction | 生成方法论与文档格式要求(官方方法论为底) | 场景标题 4 个 #、SHALL/MUST、ADDED/MODIFIED/REMOVED、任务组格式、每组自带测试与质量门、测试随实现同组、关联场景清点维度与单仓变更范围、实施逻辑小节 |
78
- | `openspec/config.yaml` rules | **仅** schema 未覆盖的项目补充规则 | MODIFIED 终态契约表述、同语义一条需求、前置 change 标注格式、契约变更详列、访谈门与用户确认门、实施逻辑与方案摘要结构、单仓变更范围与跨仓拆分边界、测试随实现同组 |
85
+ | `schema.yaml` instruction | 生成方法论与文档格式要求(官方方法论为底) | 场景标题 4 个 #、SHALL/MUST、ADDED/MODIFIED/REMOVED、任务组格式、每组自带测试与质量门、测试随实现同组、关联场景清点维度与单仓变更范围、实施逻辑小节、规则边界推演维度与三问 |
86
+ | `openspec/config.yaml` rules | **仅** schema 未覆盖的项目补充规则 | MODIFIED 终态契约表述、同语义一条需求、前置 change 标注格式、契约变更详列、访谈门与用户确认门、方案摘要结构、跨仓拆分边界、规则边界门禁口径(结论必列、三类场景、判定挂载点) |
79
87
  | 项目 `AGENTS.md` | 项目特化约束 | 技术栈、分层架构、数据库约定、质量门工具、方法论 |
80
88
 
81
89
  同一规则只写一处:通用生成方法论以 schema instruction 为准,config.yaml
@@ -73,6 +73,13 @@ artifacts:
73
73
  consistency (clarify direction ↔ proposal capabilities ↔ specs
74
74
  requirements ↔ design decisions ↔ tasks with [spec:...]
75
75
  traceability tags);
76
+ - for changes that add or alter a rule, validation or blocking check,
77
+ or introduce/reorder an execution path, check the rule-boundary
78
+ findings entry by entry: the proposal's Rule Boundary section, the
79
+ design's mount point, and the spec's blocked / allowed /
80
+ equivalent-path scenarios must all match the rule-boundary
81
+ conclusions recorded in clarify.md - use the clarify record as the
82
+ baseline and do not invent criteria;
76
83
  - read openspec/specs/ main specs (read-only) and cross-check:
77
84
  proposal capabilities actually exist there, and delta
78
85
  requirements/contracts (e.g. error codes, rate-limit semantics,
@@ -141,6 +148,33 @@ artifacts:
141
148
  * Data model: which entities/tables/fields are involved? any new tables or columns?
142
149
  * Business rules: which are deterministic vs non-deterministic, per the
143
150
  project's conventions (see AGENTS.md)?
151
+ * Rule boundary (规则边界推演): for every business rule, validation or
152
+ blocking check this change adds or alters - and for every execution
153
+ path or action sequence the change introduces or reorders - work out
154
+ and resolve with the user, as branches of the decision tree:
155
+ 1) judgement condition and exception: which cases must be blocked,
156
+ and which look similar but must be allowed (state the minimal
157
+ condition under which the block applies);
158
+ 2) legitimate counter-examples: every functionally legal scenario the
159
+ new rule would wrongly block, and the handling each one should get
160
+ (each becomes an "allowed" scenario in the spec);
161
+ 3) equivalent paths and the mount point of the check: whether the same
162
+ business intent has more than one execution path (several screens,
163
+ several endpoints, an action composed of other actions - e.g.
164
+ switching a user's role implemented as remove-then-add), and which
165
+ action or layer the check is mounted on; the check belongs on the
166
+ business-intent action, never on a lower-level action that other
167
+ flows reuse.
168
+ Also ask whether this change introduces or reorders any execution
169
+ path; if so, go through every EXISTING rule, validation or blocking
170
+ check and decide whether it should still fire on the new path
171
+ (blocked when it should not be, not blocked when it should be).
172
+ Division of labour: the Related-surface survey enumerates WHO is
173
+ affected; this branch decides whether the judgement itself holds. The
174
+ multiple-persistence-path consistency branch keeps the judgement
175
+ semantics consistent across paths (no missed blocking); this branch's
176
+ mount point keeps the check off shared low-level actions (no wrongful
177
+ blocking).
144
178
  * Integration boundaries: external systems, APIs, ports/adapters?
145
179
  * Architecture direction: propose 2-3 approaches with tradeoffs and a recommendation.
146
180
  - Round mechanics: each round asks every question whose prerequisites
@@ -195,6 +229,10 @@ artifacts:
195
229
  5. the related-surface verdicts: for every surveyed surface,
196
230
  adapted in this change or excluded, each with a one-line reason;
197
231
  6. the capabilities affected.
232
+ 7. the rule-boundary verdicts: for every rule this change adds or
233
+ alters, the blocking condition, the exceptions and legitimate
234
+ counter-examples that must be allowed, and the equivalent execution
235
+ paths with the mount point of the check - each with its verdict.
198
236
  Present it as a
199
237
  plain message — do NOT use the question tool for this confirmation
200
238
  (the question tool belongs to the interview rounds, not to this
@@ -219,11 +257,20 @@ artifacts:
219
257
  - **Architecture Direction**: the crystallized approach, key decisions,
220
258
  alternatives considered, and the confirmed plan summary with
221
259
  the user's explicit confirmation — the summary structured per the
222
- six elements of the plan confirmation gate (including the
260
+ seven elements of the plan confirmation gate (including the
223
261
  itemized plain-language change list, the plain-language
224
- implementation outline and the related-surface verdicts),
262
+ implementation outline, the related-surface verdicts and the
263
+ rule-boundary verdicts),
225
264
  presented as a plain message only after the interview
226
- was exhausted. This is the HARD-GATE output.
265
+ was exhausted. The rule-boundary conclusions must appear here item by
266
+ item for changes that add or alter a rule, validation or blocking
267
+ check, or that introduce or reorder an execution path.
268
+ This is the HARD-GATE output.
269
+ - **Authoring Tier**: SIMPLE or COMPLEX with a one-line rationale
270
+ (criteria in the Phase 2 complexity criteria above), recorded before
271
+ authoring starts; SIMPLE means the orchestrating agent writes the
272
+ remaining artifacts itself, COMPLEX means one fresh generation
273
+ subagent writes them.
227
274
  - **Initial Capabilities**: preliminary guess of which specs will be touched
228
275
  (kebab-case). Finalized in proposal.md.
229
276
 
@@ -279,6 +326,15 @@ artifacts:
279
326
  method, or internal function names) unless the user explicitly asked
280
327
  for technical depth; contract facts (table, column, and endpoint
281
328
  names) are exempt and stay precise.
329
+ - **Rule Boundary (规则边界)**: required when this change adds or alters a
330
+ business rule, validation or blocking check, or introduces/reorders an
331
+ execution path; otherwise state 「不适用」 with a one-line reason. One
332
+ table row per rule - the blocking condition, the exceptions and
333
+ legitimate counter-examples that must be allowed (with their intended
334
+ handling), and the mount point of the check - plus one line per
335
+ equivalent execution path with its verdict. The reasoning method lives
336
+ in the Rule boundary branch of the clarify instruction; do not restate
337
+ it here.
282
338
  - **Capabilities**: Identify which specs will be created or modified:
283
339
  - **New Capabilities**: List capabilities being introduced. Each becomes a new `specs/<capability-path>/spec.md`. Use kebab-case for path segments you introduce (e.g., `user-auth` or `identity/user-auth`) and follow the project's existing spec organization.
284
340
  - **Modified Capabilities**: List existing capabilities whose REQUIREMENTS are changing. Only include if spec-level behavior changes (not just implementation details). Each needs a delta spec file. Use the exact existing path under `openspec/specs/`. Leave empty if no requirement changes.
@@ -367,6 +423,13 @@ artifacts:
367
423
  - Each scenario: `#### Scenario: <name>` with WHEN/THEN format
368
424
  - **CRITICAL**: Scenarios MUST use exactly 4 hashtags (`####`). Using 3 hashtags or bullets will fail silently.
369
425
  - Every requirement MUST have at least one scenario.
426
+ - Rule-type changes (a business rule, validation or blocking check added
427
+ or altered, or an execution path introduced/reordered) need one Scenario
428
+ per rule-boundary conclusion, covering three kinds: blocked (with the
429
+ minimal blocking condition), allowed (exceptions and legitimate
430
+ counter-examples), and allowed on equivalent execution paths (one
431
+ Scenario per path). Conclusions that do not apply are stated with a
432
+ reason. A spec with only blocked-side scenarios is incomplete.
370
433
 
371
434
  New capabilities only: start the delta spec with a `## Purpose` section -
372
435
  one or two sentences (50+ characters, or `openspec validate --strict`
@@ -427,6 +490,11 @@ artifacts:
427
490
  (see AGENTS.md / openspec/config.yaml rules). If the change does not
428
491
  involve persistence, state that explicitly ("本变更不涉及持久化" or the
429
492
  project's equivalent phrasing).
493
+ - **Rule Boundary Attachment**: MANDATORY when the change adds or alters a
494
+ business rule, validation or blocking check, or introduces/reorders any
495
+ execution path. State which action or layer the check is mounted on, and
496
+ why no other flow reusing that action can trip it. State explicitly when
497
+ the change involves no rules.
430
498
  - **Risks / Trade-offs**: Known limitations, things that could go wrong. Format: [Risk] → Mitigation
431
499
  - **Migration Plan**: Steps to deploy, rollback strategy (if applicable)
432
500
  - **Open Questions**: Unknowns that can safely be answered later without
@@ -36,9 +36,10 @@
36
36
  <!-- The crystallized approach: chosen direction, key decisions, 2-3 alternatives
37
37
  considered with tradeoffs, and the plan summary the user explicitly confirmed
38
38
  (interview answers alone do not count as confirmation; the summary must be
39
- structured per the six elements of the plan confirmation gate — including
39
+ structured per the seven elements of the plan confirmation gate — including
40
40
  the itemized plain-language change list, the plain-language
41
- implementation outline and the related-surface verdicts —
41
+ implementation outline, the related-surface verdicts and
42
+ the rule-boundary verdicts —
42
43
  presented as a plain message listing the key points, never a question-tool
43
44
  prompt, and only AFTER the interview was exhausted: presenting the plan or
44
45
  asking for its confirmation mid-interview is forbidden, and the recommended
@@ -22,10 +22,21 @@
22
22
  rules: table prefix, primary key strategy, logical delete, audit columns).
23
23
  If no persistence, state that explicitly. -->
24
24
 
25
+ ## Rule Boundary Attachment
26
+
27
+ <!-- Required when this change adds or alters a business rule, validation or
28
+ blocking check, or introduces/reorders an execution path; otherwise state
29
+ 「不适用」 with a one-line reason. State which action or layer the check is
30
+ mounted on, and why no other flow reusing that action can trip it. -->
31
+
25
32
  ## Risks / Trade-offs
26
33
 
27
34
  <!-- Known risks and trade-offs. Format: [Risk] → Mitigation -->
28
35
 
36
+ ## Migration Plan
37
+
38
+ <!-- Steps to deploy, rollback strategy (if applicable). Omit if not applicable. -->
39
+
29
40
  ## Open Questions
30
41
 
31
42
  <!-- Outstanding decisions or unknowns to resolve -->
@@ -25,6 +25,23 @@
25
25
  names) unless the user explicitly asked for technical depth; contract facts
26
26
  (table/column/endpoint names) are exempt and stay precise. -->
27
27
 
28
+ ## Rule Boundary
29
+
30
+ <!-- 规则边界:required when this change adds or alters a business rule,
31
+ validation or blocking check, or introduces/reorders an execution path;
32
+ otherwise write 「不适用」 + a one-line reason. One table row per rule, plus
33
+ the equivalent-path list. The table form is required so each conclusion can
34
+ be checked item by item. The reasoning method lives in the Rule boundary
35
+ branch of the clarify instruction in schema.yaml - point there, do not
36
+ restate it here.
37
+
38
+ | 规则 | 该拦的条件 | 该放的例外与合法反例(附应有处理) | 判定挂载点 |
39
+ |---|---|---|---|
40
+ | <rule> | <minimal condition that blocks> | <exception / legitimate counter-example + intended handling> | <business-intent action the check sits on> |
41
+
42
+ Equivalent execution paths: one line per path - the intent, the path, and
43
+ whether the check fires correctly on it. -->
44
+
28
45
  ## Capabilities
29
46
 
30
47
  ### New Capabilities
@@ -1,3 +1,11 @@
1
+ <!-- Rule-type changes (a business rule, validation or blocking check added or
2
+ altered, or an execution path introduced/reordered): one Scenario per
3
+ rule-boundary conclusion, covering three kinds - blocked (with the minimal
4
+ blocking condition), allowed (exceptions and legitimate counter-examples),
5
+ and allowed on equivalent execution paths (one Scenario per path).
6
+ Conclusions that do not apply are stated with a reason. Blocked-side
7
+ scenarios alone count as an incomplete spec. -->
8
+
1
9
  ## ADDED Requirements
2
10
 
3
11
  ### Requirement: <!-- requirement name -->
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: test-design
3
+ description: 测试设计规范(技术栈无关)——从 spec 与契约独立推导行为面与用例矩阵,定义覆盖类别、断言强度、用例与实现解耦、反向探针与证据形态。
4
+ capabilities: ["test-design"]
5
+ # 机器可读检查项清单:与下方「证据形态」表格逐项对应。
6
+ must_do: ["behavior_surface", "case_matrix", "negative_probe"]
7
+ ---
8
+
9
+ > **项目规范优先**:本 skill 所列约定为推荐标准。若项目已有明确规范且与本 skill 不一致,以项目规范为准。
10
+
11
+ ## 行为面推导
12
+
13
+ 从 spec 与接口/数据契约推导本次变更牵动的行为面,作为覆盖的完整边界;禁止把验收标准的条目直接当成行为面清单:
14
+
15
+ - 状态与流程:新增/变更的状态、状态流转路径、初始态与终止态
16
+ - 数据承载:新增/变更字段、字段的产出与读写位置、可空性、默认值
17
+ - 枚举与取值域:有限取值集合、类别标记、字典项
18
+ - 权限与可见性:谁能调用、越权访问的拒绝路径
19
+ - 外部依赖:第三方与下游调用、超时与失败路径
20
+ - 可选路径:可选字段、可选分支、可跳过的步骤
21
+ - 异步产出:延迟落库、消息入队、下游消费
22
+
23
+ 行为面条目多于验收标准条目属正常:一条验收标准常牵动多条行为面。
24
+
25
+ ## 用例矩阵
26
+
27
+ 每条行为面至少覆盖三类,缺一类即覆盖不全:
28
+
29
+ | 类别 | 取值与场景 |
30
+ |------|-----------|
31
+ | 正常 | 按契约传入合法值,断言响应结构与关键产出 |
32
+ | 边界 | 空值/空集合/零、极值、超长、边界长度、类型非法、精度与舍入、日期与时间边界 |
33
+ | 异常 | 非法状态跳转、重复提交与幂等、并发、事务回滚、部分失败、依赖不可用与超时、越权访问 |
34
+
35
+ 组合与状态迁移:多个可选字段或条件并存时按判定表收敛组合;状态机逐条迁移覆盖合法边与非法边,非法迁移须断言被拒绝。
36
+
37
+ ## 断言强度
38
+
39
+ - 每条行为至少一条「实现写错就红」的断言:断具体值、状态流转结果、副作用是否发生,而不是「没报错」
40
+ - 仅断言响应成功、字段非空、流程跑通,不构成断言
41
+ - 同一请求内一并发生的多个行为逐个断言,禁止以其中一个行为的断言替代其余
42
+ - 断言范围包括连带效果:状态落库、消息入队、下游可消费、产出字段落位与完整性
43
+
44
+ ## 用例与实现解耦
45
+
46
+ - 预期值来自 spec 与契约,不得先运行实现再把实际结果抄成期望
47
+ - 禁止 mock 被测对象本身;替身只用于外部依赖
48
+ - 用例只依赖契约与可观察行为,不依赖实现内部结构(私有方法名、内部字段)
49
+
50
+ ## 反向探针
51
+
52
+ 取至少一条关键用例做对抗校验,证明用例真能发现问题:
53
+
54
+ 1. 把实现改坏(拔掉被测行为、翻转判定条件、让产出落错位置)
55
+ 2. 确认该用例失败
56
+ 3. 还原实现,确认该用例恢复通过
57
+
58
+ 记录探针的改坏点、变红的用例、还原确认结果。反向探针未通过的用例视为无对抗力,须重写。
59
+
60
+ ## 证据形态
61
+
62
+ | 检查项 | 交付物 |
63
+ |--------|--------|
64
+ | behavior_surface | 行为面清单(按上节维度列出,标注对应验收标准) |
65
+ | case_matrix | 用例矩阵:行为面 × 类别 → 用例名/脚本名,每格注明断什么 |
66
+ | negative_probe | 探针记录:改坏点、变红用例、还原确认结果 |
67
+
68
+ ## 适用范围
69
+
70
+ 有代码、接口契约或数据口径变更时必须执行;纯文档、纯格式与注释变更不适用。
@@ -34,7 +34,7 @@ phases:
34
34
  - id: implement
35
35
  agents:
36
36
  - id: openspec-developer
37
- capability_tags: [efficiency, api-testing, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
37
+ capability_tags: [efficiency, api-testing, test-design, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
38
38
  transitions:
39
39
  on_pass: quality_review
40
40
  on_fail: implement
@@ -43,6 +43,7 @@ phases:
43
43
  - "执行边界缺省整个 worktree(独立审查无分析环节,不生成边界白名单);issue 的 file 字段指向的文件即修复边界,修复这些文件(含回归引入问题)不算越界;可按 issue 的 suggestion 直接执行修复;reviewer 的 boundary_expansion 已并入边界"
44
44
  - "对修复未过次数≥2 的 issue 须先完成 5-Why 根因分析再动手,不得跳过分析直接改代码"
45
45
  - "修复完成后先 git commit 再提交;提交前按已加载的质量门类 skill 完成本地构建验证,并按维度规范类 skill(style/architecture/performance/security/maintainability 能力类别)对本次修复文件逐项自检,自检结论与工具检查结果一并汇总进 self_check_results"
46
+ - "有代码、接口契约或数据口径变更时,须按已加载的测试设计规范产出行为面清单、用例矩阵与反向探针记录,随提交在 self_check_results 中逐项申报;反向探针结束后必须先还原实现并复跑全量用例确认全绿再提交,禁止带着改坏的实现提交"
46
47
  - "自证/验证需启动服务或基础设施时,一律按已加载技术栈 skill 的隔离启动规范以隔离方式启动,隔离标识与建议端口以视图 Worktree 区块为准;验证完成后停止本次启动的实例,不留残留,残留判定遵循已加载清理规范的归属判别,无法确认归属本变更的进程一律不清;禁止为腾出端口或资源而停止、复用或干扰非本会话启动的进程"
47
48
  - "确定性质量工具检查出的问题不得以压制手段(压制注解/注释抑制/规则排除配置/平台状态标注/构建跳过开关等)静默规避:确需压制时,必须在压制处代码注释说明清楚理由,并经 exempt_issue_ids 申请豁免由报源 reviewer 裁定;不得以 fixed_issue_ids 冒充修复"
48
49
  - "提交 opx_agent_submit:必传 verdict;修复完成的 issue 经 fixed_issue_ids 上报、不可修 issue 经 exempt_issue_ids 申请豁免"
@@ -56,7 +57,7 @@ phases:
56
57
  - id: quality_review
57
58
  agents:
58
59
  - id: openspec-reviewer
59
- capability_tags: [quality-gate, api-testing, dev-practices, efficiency, style, architecture, performance, security, maintainability, tool-improvement, cleanup]
60
+ capability_tags: [quality-gate, api-testing, test-design, dev-practices, efficiency, style, architecture, performance, security, maintainability, tool-improvement, cleanup]
60
61
  transitions:
61
62
  on_pass: done
62
63
  on_fail: implement
@@ -65,6 +66,7 @@ phases:
65
66
  - "审查锚点按视图「审查范围」:PR 区间形态为 base..head 区间(首轮)或检查点增量(修复轮);全量形态为整个代码库——全量形态下的工具违规无论是否本轮引入一律映射为 issue,不得以不在变更清单为由丢弃"
66
67
  - "「有变更」分支先审查上方「本次变更证据」区块的变更文件清单与区间 diff 内容后自行判断:若确认本次变更仅为注释/文档性且无逻辑影响,可自行决定跳过全量工具检查直接提交 passed(validation_steps 以 step=no_change 申报整体豁免必做清单);无法确认或含逻辑/结构变更,必须顺序运行全部确定性工具检查;裁量仅免除全量工具扫描,不免除复核/裁定——本层 blocking issue 仍须处理至终态后提交"
67
68
  - "回归验证(独立审查场景,无 spec 验收标准——以既有测试与行为基线为锚):①构建通过;②既有测试全量执行不引入新失败——首轮跑出的存量失败按 issue 上报进入处置通道(审并修模式进修复闭环或豁免,只审模式进报告),修复轮出现「上轮未登记的新失败」即回归、verdict=failed 并报 issue(说明失败用例与归因);③可启动服务时按已加载技术栈 skill 的隔离启动规范隔离启动做冒烟与既有 API 测试脚本执行(存在时),验证后按已加载的清理规范幂等清理(含 verdict=failed 轮次);无法启动服务或无脚本时 ③ 置 completed=false 并以结构化 skip_reason 申报"
69
+ - "核验测试设计物(独立审查无 spec:行为面从变更 diff 与既有实现推导):核验既有与新增测试的行为面清单、用例矩阵与反向探针记录(检查点按已加载测试设计规范与任务维度判例执行);证据缺失或不足时据实上报,不得跳过核验直接提交通过;无测试对象(无代码、接口契约与数据口径变更)时以 completed=false + 结构化 skip_reason 申报"
68
70
  - "加载匹配维度 skill 做五维度合并审查(style/architecture/performance/security/maintainability),结合领域知识做拓展审查(skill 仅为最低基准);顺带发现的其他缺陷按对应维度严重级别标准报 issue,禁止静默丢弃"
69
71
  - "审查新 issue 前先查看视图「待复核」区块中的既有 issue(仅本审查者报源),避免语义重复"
70
72
  - "报 issue 时必须显式声明归因维度 dimension(style/architecture/performance/security/maintainability):本 reviewer 不归属任一质量维度,dimension 即该 issue 归属的目标质量维度"
@@ -33,7 +33,7 @@ phases:
33
33
  - id: implement
34
34
  agents:
35
35
  - id: openspec-developer
36
- capability_tags: [efficiency, api-testing, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
36
+ capability_tags: [efficiency, api-testing, test-design, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
37
37
  transitions:
38
38
  on_pass: verify_tool
39
39
  on_fail: implement
@@ -42,6 +42,7 @@ phases:
42
42
  - "执行边界缺省整个 worktree(独立审查无分析环节,不生成边界白名单);issue 的 file 字段指向的文件即修复边界,修复这些文件(含回归引入问题)不算越界;可按 issue 的 suggestion 直接执行修复;reviewer 的 boundary_expansion 已并入边界"
43
43
  - "对修复未过次数≥2 的 issue 须先完成 5-Why 根因分析再动手,不得跳过分析直接改代码"
44
44
  - "修复完成后先 git commit 再提交;提交前按已加载的质量门类 skill 完成本地构建验证,并按维度规范类 skill(style/architecture/performance/security/maintainability 能力类别)对本次修复文件逐项自检,自检结论与工具检查结果一并汇总进 self_check_results"
45
+ - "有代码、接口契约或数据口径变更时,须按已加载的测试设计规范产出行为面清单、用例矩阵与反向探针记录,随提交在 self_check_results 中逐项申报;反向探针结束后必须先还原实现并复跑全量用例确认全绿再提交,禁止带着改坏的实现提交"
45
46
  - "自证/验证需启动服务或基础设施时,一律按已加载技术栈 skill 的隔离启动规范以隔离方式启动,隔离标识与建议端口以视图 Worktree 区块为准;验证完成后停止本次启动的实例,不留残留,残留判定遵循已加载清理规范的归属判别,无法确认归属本变更的进程一律不清;禁止为腾出端口或资源而停止、复用或干扰非本会话启动的进程"
46
47
  - "确定性质量工具检查出的问题不得以压制手段(压制注解/注释抑制/规则排除配置/平台状态标注/构建跳过开关等)静默规避:确需压制时,必须在压制处代码注释说明清楚理由,并经 exempt_issue_ids 申请豁免由报源 reviewer 裁定;不得以 fixed_issue_ids 冒充修复"
47
48
  - "提交 opx_agent_submit:必传 verdict;修复完成的 issue 经 fixed_issue_ids 上报、不可修 issue 经 exempt_issue_ids 申请豁免"
@@ -79,12 +80,13 @@ phases:
79
80
  - id: verify_task
80
81
  agents:
81
82
  - id: openspec-reviewer-task
82
- capability_tags: [api-testing, efficiency, dev-practices, cleanup]
83
+ capability_tags: [api-testing, test-design, efficiency, dev-practices, cleanup]
83
84
  transitions:
84
85
  on_pass: verify_quality
85
86
  on_fail: implement
86
87
  instructions:
87
88
  - "回归验证层(独立审查场景,无 spec 验收标准——以既有测试与行为基线为锚)逐项验证:①构建通过;②既有测试全量执行不引入新失败——首轮跑出的存量失败按 issue 上报进入处置通道(审并修模式进修复闭环或豁免,只审模式进报告),修复轮出现「上轮未登记的新失败」即回归、verdict=failed 并报 issue(说明失败用例与归因);③可启动服务时按已加载技术栈 skill 的隔离启动规范隔离启动做冒烟与既有 API 测试脚本执行(存在时),验证后幂等清理"
89
+ - "核验测试设计物(独立审查无 spec:行为面从变更 diff 与既有实现推导):核验既有与新增测试的行为面清单、用例矩阵与反向探针记录(检查点按已加载测试设计规范与任务维度判例执行);证据缺失或不足时据实上报,不得跳过核验直接提交通过;无测试对象(无代码、接口契约与数据口径变更)时以 completed=false + 结构化 skip_reason 申报"
88
90
  - "验证完成后(含 verdict=failed 轮次)按已加载的清理规范执行幂等清理:停止残留的服务实例、清理本会话的隔离环境、删除残留的隔离扫描项目;无残留即通过,清理结果纳入 validation_steps 申报"
89
91
  - "无法启动服务或不存在 API 测试脚本时,③置 completed=false 并以结构化 skip_reason 申报(格式:{\"item\":\"<对应验证项>\",\"category\":\"<降级类别>\",\"adjudication\":\"user_response|unattended_auto|env_unavailable\",\"note\":\"<说明>\"}),注明判定依据"
90
92
  - "报 issue 时必须显式声明归因维度 dimension(style/architecture/performance/security/maintainability):本 reviewer 不归属任一质量维度,dimension 即该 issue 归属的目标质量维度"
@@ -23,7 +23,7 @@ phases:
23
23
  - id: implement
24
24
  agents:
25
25
  - id: openspec-developer
26
- capability_tags: [efficiency, api-testing, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
26
+ capability_tags: [efficiency, api-testing, test-design, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
27
27
  transitions:
28
28
  on_pass: quality_review
29
29
  on_fail: implement
@@ -32,6 +32,7 @@ phases:
32
32
  - "按 Task 项顺序逐个实现,聚焦当前子任务,不超出执行边界"
33
33
  - "实施前识别 spec 描述的一并操作行为组(如状态变更与数据入队这类需同时发生的多个行为);实施后逐项自证每个行为真实生效,禁止以单一状态字段的实现替代其他行为"
34
34
  - "涉及数据模型或流程产出变更(含字段/实体承载位置搬迁、AI 生成等流程产物)时,自证须包含关键数据产出断言:产出字段已持久化到 spec 指定承载位置且值完整非空、搬迁承接与同一输入产出基线一致(按已加载接口测试规范执行);禁止仅以流程跑通/接口成功替代"
35
+ - "有代码、接口契约或数据口径变更时,须按已加载的测试设计规范产出行为面清单、用例矩阵与反向探针记录,随提交在 self_check_results 中逐项申报;反向探针结束后必须先还原实现并复跑全量用例确认全绿再提交,禁止带着改坏的实现提交"
35
36
  - "自证/验证需启动服务或基础设施时,一律按已加载技术栈 skill 的隔离启动规范以隔离方式启动,隔离标识与建议端口以视图 Worktree 区块为准;隔离对象不限于数据库——为本变更启动的 mock 服务、消息队列/缓存等中间件、扫描分析平台等一切环境资源均须按隔离标识隔离,禁止复用既有实例或共享端口;启动前发现隔离环境有残留时,先按已加载的清理规范幂等清空再启动;残留判定遵循已加载清理规范的归属判别,无法确认归属本变更的进程一律不清"
36
37
  - "涉及接口契约或数据口径变更(按已加载的接口测试规范判定)时,实施过程中即时更新/新建与变更接口对应的 `.http` 测试脚本(已有脚本更新为匹配变更后契约,尚无脚本则新建,并同步 SQL 前置数据脚本),按已加载接口测试规范的完整执行顺序(含 SQL 前置数据准备、隔离启动基础设施与服务、执行 `.http` 脚本)执行接口测试,确保变更内容真实有效;执行结果(附执行顺序与覆盖接口清单)经 test_results 参数提交,作为审查者分级复验的事实输入;修复被驳回 issue 后再次提交前同样须执行"
37
38
  - "自证完成后停止本次启动的服务/基础设施实例,不留残留"
@@ -64,7 +65,7 @@ phases:
64
65
  - id: quality_review
65
66
  agents:
66
67
  - id: openspec-reviewer
67
- capability_tags: [quality-gate, api-testing, dev-practices, efficiency, style, architecture, performance, security, maintainability, tool-improvement, cleanup]
68
+ capability_tags: [quality-gate, api-testing, test-design, dev-practices, efficiency, style, architecture, performance, security, maintainability, tool-improvement, cleanup]
68
69
  transitions:
69
70
  on_pass: done
70
71
  on_fail: implement
@@ -73,6 +74,7 @@ phases:
73
74
  - "「有变更」分支先审查上方「本次变更证据」区块的变更文件清单与区间 diff 内容后自行判断:若确认本次变更仅为注释/文档性且无逻辑影响(非注释掉代码、非结构性/格式化变更、非文件重命名),可自行决定跳过全量工具检查直接提交 passed(validation_steps 以 step=no_change 申报整体豁免必做清单);无法确认或含逻辑/结构变更,必须按分级复验口径执行确定性检查;裁量仅免除全量工具扫描,不免除复核/裁定——本层 blocking issue 仍须处理至终态后提交"
74
75
  - "分级复验:低成本必做项(分钟级)全量实跑 + 逐项申报(completed=true 附执行结果);deep_scan 核验上方「开发者自检申报」区块的 dev 申报(证据完整性、命中项与 diff 的合理性)并抽验命中项(如本地复跑单规则静态分析验证命中真实存在),不重扫全量,申报形态为 step 名首段 deep_scan、completed=true、描述注明核验方式与抽验样本;白名单口径:仅高成本必做项(deep_scan)允许核验申报形态,低成本必做项必须实跑后申报;升级回退全量重跑触发条件(统一四处):dev 申报缺证据或不完整 / 抽验失败 / 发现断言放水类 issue / 本轮为修复轮且修复波及接口契约或数据口径——命中任一即本轮高成本项改为实跑全量"
75
76
  - "对抗性判断(独立视角,不重走 dev 路径):①task 产出完整性 ②③按 spec 验收标准选样的核心链路抽样重放(1-2 条端到端,覆盖创建-检索-变更-删除闭环中 spec 声明的关键行为;服务健康并入抽样重放——能重放即健康)并审查 `.http` 脚本质量(对照 spec 核断言覆盖/放水/Mock 过度——防作弊主力;含 API 测试自闭环链路:创建后可检索、状态变更后可见、删除后不可见;测试数据贴近业务语义,禁止无意义占位值)④审查测试代码质量(断言放水/Mock 过度/覆盖不足)⑤业务行为真实性:对照 spec 逐项核验每个业务行为的实现与断言证据(含一并操作的行为组、连带效果、下游消费),识别『仅打状态标记未实际生效』类缺陷 ⑥关键数据产出核验:对照 spec 数据产出要求,核验实现与测试是否覆盖产出数据落位(spec 指定承载位置)、完整非空、搬迁承接与同一输入基线一致,识别『流程正常但数据缺失/落错位置』类缺陷;轮次口径:首轮按上述分级复验与对抗判断全项执行;复核轮(二轮起)聚焦被修复 issue 相关面 + 本轮修复 diff 波及面 + dev 再自检申报(「开发者自检申报」区块),首轮已通过且无波及的维度与低成本工具结论不重审,但低成本工具实跑保留(防修复引入回归)"
77
+ - "核验测试设计物:对照 spec 与独立推导的行为面,核验 dev 提交的行为面清单、用例矩阵与反向探针记录(检查点按已加载测试设计规范与任务维度判例执行);证据缺失或不足时据实上报,不得跳过核验直接提交通过;无测试对象(无代码、接口契约与数据口径变更)时以 completed=false + 结构化 skip_reason 申报"
76
78
  - "验证完成后(含 verdict=failed 报 issue 回退 implement 的轮次)按已加载的清理规范执行幂等清理:停止残留的服务实例(含抽样重放启动的服务)、清理本 change 的隔离环境、删除残留的隔离扫描项目;无残留即通过,不因重复执行报错;清理结果纳入 validation_steps 申报(未执行须以 completed=false + 结构化 skip_reason 说明)"
77
79
  - "本次变更仅含测试代码(判定:视图「变更范围」文件清单全部命中已加载技术栈 skill 定义的测试代码路径,且无生产代码、接口契约、构建与测试配置等非测试文件)时,豁免②③核心链路抽样重放,仅验证①④;豁免时 validation_steps 中②③置 completed=false,并以结构化 skip_reason 申报(格式:{\"item\":\"<对应验证项>\",\"category\":\"<降级类别>\",\"adjudication\":\"user_response|unattended_auto|env_unavailable\",\"note\":\"<说明>\"}),note 注明「本次变更仅含测试代码,豁免抽样重放」及判定依据;⑤⑥的实现核验在纯测试代码变更场景无对象,其断言证据核验并入④测试代码质量"
78
80
  - "读取 design.md 的 API 定义(请求/响应结构、数据模型)与 specs/ 下相关 spec.md(需求细节、验收标准与数据产出要求),用于准备测试数据与对照 API 合约、选样核心链路"
@@ -39,6 +39,7 @@ phases:
39
39
  instructions:
40
40
  - "校验 design.md 与 tasks.md、specs/ 下相关 spec.md 的一致性(据 tasks.md 各行 `[spec:xxx]` 溯源定位相关 spec.md 一并复核)"
41
41
  - "按评估维度逐项审查 design.md 并给出结论:architecture / api-design / db-design(无问题也需简要确认),不以假设替代确认"
42
+ - "方案涉及新增/修改业务规则、校验或拦截逻辑,或新增/改变任何执行路径时,按架构维度检查点清单核对规则边界推演结论(对照 proposal.md 的「规则边界」小节、specs 下相关 spec.md 的场景、design.md 的判定挂载点,聚焦当前任务组直接相关的规则变更);命中检查点定义的缺陷 → 提交 blocker(category: architecture_design),不以假设替代确认"
42
43
  - "校验设计文档与任务前提的一致性,评估架构模式合规性"
43
44
  - "输出执行边界:allowed_directories(含测试目录)与 allowed_packages 白名单,notes 仅填实施建议(关键坑位/组件复用/边缘场景/框架应用/通用做法),不重复目录与包路径,无补充时留空"
44
45
  - "存在缺口时提交 blocker(category: architecture_design / info_gap),不以假设替代确认"
@@ -53,7 +54,7 @@ phases:
53
54
  - id: implement
54
55
  agents:
55
56
  - id: openspec-developer
56
- capability_tags: [efficiency, api-testing, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
57
+ capability_tags: [efficiency, api-testing, test-design, quality-gate, dev-practices, db-design, style, architecture, performance, security, maintainability, cleanup]
57
58
  transitions:
58
59
  on_pass: verify_tool
59
60
  on_fail: analyze
@@ -62,6 +63,7 @@ phases:
62
63
  - "按 Task 项顺序逐个实现,聚焦当前子任务,不超出执行边界"
63
64
  - "实施前识别 spec 描述的一并操作行为组(如状态变更与数据入队这类需同时发生的多个行为);实施后逐项自证每个行为真实生效,禁止以单一状态字段的实现替代其他行为"
64
65
  - "涉及数据模型或流程产出变更(含字段/实体承载位置搬迁、AI 生成等流程产物)时,自证须包含关键数据产出断言:产出字段已持久化到 spec 指定承载位置且值完整非空、搬迁承接与同一输入产出基线一致(按已加载接口测试规范执行);禁止仅以流程跑通/接口成功替代"
66
+ - "有代码、接口契约或数据口径变更时,须按已加载的测试设计规范产出行为面清单、用例矩阵与反向探针记录,随提交在 self_check_results 中逐项申报;反向探针结束后必须先还原实现并复跑全量用例确认全绿再提交,禁止带着改坏的实现提交"
65
67
  - "自证/验证需启动服务或基础设施时,一律按已加载技术栈 skill 的隔离启动规范以隔离方式启动,隔离标识与建议端口以视图 Worktree 区块为准;隔离对象不限于数据库——为本变更启动的 mock 服务、消息队列/缓存等中间件、扫描分析平台等一切环境资源均须按隔离标识隔离,禁止复用既有实例或共享端口;启动前发现隔离环境有残留时,先按已加载的清理规范幂等清空再启动;残留判定遵循已加载清理规范的归属判别,无法确认归属本变更的进程一律不清"
66
68
  - "涉及接口契约或数据口径变更(按已加载的接口测试规范判定)时,实施过程中即时更新/新建与变更接口对应的 `.http` 测试脚本(已有脚本更新为匹配变更后契约,尚无脚本则新建,并同步 SQL 前置数据脚本),按已加载接口测试规范的完整执行顺序(含 SQL 前置数据准备、隔离启动基础设施与服务、执行 `.http` 脚本)执行接口测试,确保变更内容真实有效;执行结果(附执行顺序与覆盖接口清单)经 test_results 参数提交;修复被驳回 issue 后再次提交前同样须执行"
67
69
  - "自证完成后停止本次启动的服务/基础设施实例,不留残留"
@@ -122,12 +124,14 @@ phases:
122
124
  - id: verify_task
123
125
  agents:
124
126
  - id: openspec-reviewer-task
125
- capability_tags: [api-testing, efficiency, dev-practices, cleanup]
127
+ capability_tags: [api-testing, test-design, efficiency, dev-practices, cleanup]
126
128
  transitions:
127
129
  on_pass: verify_quality
128
130
  on_fail: implement
129
131
  instructions:
130
132
  - "逐项验证:①task 产出完整性 ②启动服务并检查健康 ③独立执行全量 API 测试并审查质量(含 API 测试自闭环链路:创建后可检索、状态变更后可见、删除后不可见;测试数据贴近业务语义,禁止无意义占位值) ④审查测试代码质量(断言放水/Mock 过度/覆盖不足)⑤业务行为真实性:对照 spec 逐项核验每个业务行为的实现与断言证据(含一并操作的行为组、连带效果、下游消费),识别『仅打状态标记未实际生效』类缺陷 ⑥关键数据产出核验:对照 spec 数据产出要求,核验实现与测试是否覆盖产出数据落位(spec 指定承载位置)、完整非空、搬迁承接与同一输入基线一致,识别『流程正常但数据缺失/落错位置』类缺陷"
133
+ # 全模式 verify_task 视图不渲染开发者自检申报,故证据源取变更 diff 与 worktree 测试代码;simple 模式该 step 可核验 dev 申报
134
+ - "核验测试设计物:对照 spec 与独立推导的行为面,核验测试对行为面的覆盖、用例矩阵(正常/边界/异常与断言强度)与反向探针证据(以本次变更 diff 与 worktree 测试代码为准);无测试对象(无代码、接口契约与数据口径变更)时以 completed=false + 结构化 skip_reason 申报;不得跳过核验直接提交通过"
131
135
  - "验证完成后(含 verdict=failed 轮次)按已加载的清理规范执行幂等清理:停止残留的服务实例、清理本 change 的隔离环境、删除残留的隔离扫描项目;无残留即通过,清理结果纳入 validation_steps 申报"
132
136
  - "本次变更仅含测试代码(判定:视图「变更范围」文件清单全部命中已加载技术栈 skill 定义的测试代码路径,且无生产代码、接口契约、构建与测试配置等非测试文件)时,豁免②启动服务并检查健康与③独立执行全量 API 测试,仅验证①④;豁免时 validation_steps 中②③置 completed=false,并以结构化 skip_reason 申报(格式:{\"item\":\"<对应验证项>\",\"category\":\"<降级类别>\",\"adjudication\":\"user_response|unattended_auto|env_unavailable\",\"note\":\"<说明>\"}),note 注明「本次变更仅含测试代码,豁免启动服务与 API 测试」及判定依据;⑤⑥的实现核验在纯测试代码变更场景无对象,其断言证据核验并入④测试代码质量"
133
137
  - "读取 design.md 的 API 定义(请求/响应结构、数据模型)与 specs/ 下相关 spec.md(需求细节、验收标准与数据产出要求),用于准备测试数据与对照 API 合约"
@@ -44,7 +44,7 @@
44
44
 
45
45
  ## 角色(开发者身份)
46
46
 
47
- 你是后端开发工程师,专注于实现 OpenSpec 任务组中的代码开发任务,同时是质量门与接口测试的执行责任人:确定性检查与接口测试由你执行并经自检申报留痕,自检申报是 reviewer 分级复验的事实输入。
47
+ 你是后端开发工程师,专注于实现 OpenSpec 任务组中的代码开发任务,同时是质量门、接口测试与测试设计的执行责任人:确定性检查与接口测试由你执行并经自检申报留痕,自检申报是 reviewer 分级复验的事实输入。
48
48
 
49
49
  提交前按已加载 skill(含质量维度规范类)完成自检,审查兜底与终局裁定仍由对应 reviewer 承担(自检不替代 reviewer 裁定)。
50
50
 
@@ -140,7 +140,7 @@
140
140
  |------|-------------|-------------|---------|
141
141
  | Critical | 核心 task 产出文件缺失 | 服务无法启动(无论是否本次变更引起) | 测试依赖无隔离环境导致 CI 必然失败 |
142
142
  | High | 关键 task 产出不完整;行为无实现(仅状态标记未实际生效);流程执行正常但关键数据产出缺失/未落库/落错位置(区别于『仅打状态标记未实际生效』:本行=流程与响应正常,产出物缺失或落错位) | 健康检查不通过;关键外部依赖不可用;新增接口无法调通(不论原因) | 核心业务逻辑无测试覆盖;Mock 了被测对象本身;测试仅断言可见状态/响应而 spec 要求的一并操作行为(入队/落库/下游消费等)无断言,将缺陷固化为期望行为;测试仅验证流程跑通/响应成功,未对 spec 要求的关键数据产出(落位/完整性)断言 |
143
- | Medium | task 产出存在但质量不达标;关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 | 启动有 WARN 但服务可用 | 断言过于宽松;缺少边界值测试;关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 |
143
+ | Medium | task 产出存在但质量不达标;关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 | 启动有 WARN 但服务可用 | 断言过于宽松;缺少边界值测试或未提交测试设计物证据(行为面清单/用例矩阵/反向探针记录);关键数据产出部分缺失、值不完整或与 spec 指定承载位置不一致 |
144
144
  | Low | 产出文件位置不符合约定 | 启动日志格式不统一 | 测试命名不规范但不影响运行 |
145
145
  | Info | 建议补充额外产出物 | 建议增加启动度量指标 | 建议补充边缘用例 |
146
146
 
@@ -156,7 +156,10 @@
156
156
  |------|--------------|--------------------------|
157
157
  | Critical | 核心层依赖框架导致循环依赖或编译失败 | design 中的 schema 与实现冲突导致无法建表/编译;tasks 缺失核心步骤导致实施方向错误;实施所需关键信息缺失(如模板路径、字段映射未明),导致无法开始实施;设计架构方案违反 architecture skill 的 MUST 规则 |
158
158
  | High | 表示层直接绕过领域层访问基础设施 | spec 需求在 tasks 中无对应任务;基础架构任务错排位置;实施所需信息不完整,部分任务需等待补充信息才能推进;设计方案偏离 architecture skill 推荐做法,存在可通过调整规避的风险;设计方案破坏既有接口/数据/行为契约且无兼容或过渡安排;重构方案改变既有行为语义且未显式声明 |
159
+ | High | 已实现的校验/拦截把功能上合法的场景拦住,或判定挂在被其它业务流程复用的底层动作上致其误触,且无兼容或过渡安排 | 方案新增/修改的规则会误伤功能上合法的场景,或判定挂载点会被复用该动作的其它流程误触,且方案未说明 |
160
+ | High | 本次变更新增或重排的执行路径绕过了既有校验/拦截(该拦未拦),且无兼容或过渡安排 | 方案新增或重排的执行路径会使既有规则/校验/拦截失效(该拦未拦),且方案未说明如何在新路径上保持该判定 |
159
161
  | Medium | 依赖注入方式不符合约定(如字段注入);数据对象可变导致并发风险;应基础设施化的共性能力被分散实现(多处重复、横向共性需求、新增场景易遗漏调用);引入与既有实现功能重叠的平行实现(另起一套逻辑),同类能力多套方案并存且无迁移方案;引入或延续可识别技术债且无偿还规划(如采用 EOL/弃用技术选型、临时方案长期固化、接口契约不一致);重构/变更破坏既有契约(接口/数据/行为)或改变既有行为语义且无兼容说明 | tasks 范围模糊;design 技术细节与 tasks 完成标准不一致 |
162
+ | Medium | 已实现的校验/拦截落在被其它业务流程复用的底层动作上,或未覆盖 design.md 列出的例外与等价执行路径,无法确认是否会误伤 | 方案未给出规则边界结论(该拦条件、该放的例外与合法反例、等价执行路径与判定挂载点),无法判断是否会误伤 |
160
163
  | Low | 数据对象缺少不可变修饰但当前无并发场景;已有代码中违反分层原则但影响极小的结构性缺陷 | 文档引用路径有冗余前缀;描述用词与 spec 不一致但不影响理解 |
161
164
  | Info | 建议拆分为独立服务;建议引入某设计模式(仅当不属于 Low 及以上时) | 建议补充某边缘场景说明;可 `(待补充)` 占位、不阻塞开工的边缘信息缺失 |
162
165
 
@@ -220,7 +223,7 @@
220
223
  - 命名合理性:按 skill 中的通用语言与命名规范——命名体现意图、不与其他场景混淆、与术语表一致防漂移
221
224
  - 方案复用与平行实现:识别引入与既有实现功能重叠的平行实现(另起一套逻辑)的情况——同类能力已有既有实现时须优先复用或扩展,另建实现且不改动原实现、无迁移方案则报 issue;方案确需平行引入(新旧并存)时按需用户拍板问题的确认机制确认并存期与技术债,无人值守缺省裁决为方案必须包含原技术实现的迁移方案。与 maintainability DRY 划界:本维度关注技术方案层面的平行引入与迁移缺失,代码级重复归 maintainability。具体复用与迁移要求按 skill 约定
222
225
  - 技术债识别:按 skill 中的技术债识别约定——识别存量与新增技术债(过时技术选型、迁移中断残留、平行实现、临时方案固化、契约不一致),按统一严重级别报 issue;方案引入的债务须在方案中规划偿还或说明可接受理由
223
- - 架构演进审查:按 skill 中的架构演进审查约定——方案/实现是否延续项目整体架构方向、是否支持长期迭代演进、是否破坏既有契约(接口签名/数据格式/行为语义兼容性)、重构是否贴合项目历史逻辑并保持既有行为语义;实施侧破坏兼容或改变既有语义按统一严重级别报 issue,方案侧破坏兼容或偏离架构脉络须在方案中说明理由与过渡安排;涉及字段/实体承载位置搬迁时,方案须明确数据承接与迁移设计:新承载位置、产出字段写入目标、存量数据迁移、旧位置兼容与清理;缺失按既有契约破坏/重构贴合判例报 issue
226
+ - 架构演进审查:按 skill 中的架构演进审查约定——方案/实现是否延续项目整体架构方向、是否支持长期迭代演进、是否破坏既有契约(接口签名/数据格式/行为语义兼容性)、重构是否贴合项目历史逻辑并保持既有行为语义;实施侧破坏兼容或改变既有语义按统一严重级别报 issue,方案侧破坏兼容或偏离架构脉络须在方案中说明理由与过渡安排;涉及字段/实体承载位置搬迁时,方案须明确数据承接与迁移设计:新承载位置、产出字段写入目标、存量数据迁移、旧位置兼容与清理;变更涉及新增/修改业务规则、校验或拦截,或新增/改变任何执行路径时,核对规则边界推演——该拦条件与例外、功能上合法的反例(是否存在不该拦而拦)、既有规则在新执行路径上是否仍成立(是否存在该拦未拦)、同一业务意图的等价执行路径及其判定挂载点(判定须挂在业务意图层的动作上,不得落在被其它业务流程复用的底层动作上);推演缺失或不完整按统一严重级别报 issue
224
227
 
225
228
  ### 可维护性维度
226
229
 
@@ -269,7 +272,7 @@
269
272
  ## 职责边界(确定性检查与任务验证)
270
273
 
271
274
  - **确定性工具检查**:工具维度审查者与 simple 合并审查者被允许运行确定性工具检查(代码格式/架构约束/静态分析/单元测试编译/深度扫描),按已加载质量门 skill 的必做清单执行并将输出映射为统一 issue 结构;检查结果纳入审查结论
272
- - **任务验证**:任务维度审查者与 simple 合并审查者承担任务验证职责,验证 task 产出完整性、服务健康与 API 测试质量;未通过的 task 经 failed_tasks 上报;验证完成后按清理规范做幂等清理,不留环境残留;数据产出核验——对照 spec 数据产出要求核验关键数据产出落位/完整性/搬迁承接/基线对比,识别『流程正常但数据缺失/落错位置』类缺陷
275
+ - **任务验证**:任务维度审查者与 simple 合并审查者承担任务验证职责,验证 task 产出完整性、服务健康与 API 测试质量;未通过的 task 经 failed_tasks 上报;验证完成后按清理规范做幂等清理,不留环境残留;数据产出核验——对照 spec 数据产出要求核验关键数据产出落位/完整性/搬迁承接/基线对比,识别『流程正常但数据缺失/落错位置』类缺陷;测试设计核验——对照 spec 与独立推导的行为面核验测试设计物(行为面清单、用例矩阵、反向探针记录),识别漏面、漏格、断言放水与探针缺失
273
276
  - **维度审查锚点**:以 spec 验收标准、行为组与数据产出要求为主锚做对照审查,skill 检查点清单与 dev 自检申报对照兜底(抽查申报遗漏项)
274
277
  - **工具改进**:可工具化的质量 pattern 双报业务 issue 与工具改进 issue(规则草案由审查者提供),实施工作由开发者完成,审查者不直接改动规则/配置文件以外的实现
275
278
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ifrankwang/openspec-agents",
3
- "version": "0.147.2",
3
+ "version": "0.149.0",
4
4
  "description": "OpenSpec change orchestration plugin for AI coding agents (Claude Code, Codex, ZCode, DeepSeek Harness, OpenCode)",
5
5
  "author": "ifrankwang",
6
6
  "license": "MIT",
@@ -1,9 +1,10 @@
1
1
  /**
2
- * 质量门必做清单(must_do)覆盖度门禁与降级理由(skip_reason)结构化解析。
2
+ * skill 必做清单(must_do)覆盖度门禁与降级理由(skip_reason)结构化解析。
3
3
  *
4
4
  * 语义:skill 在 frontmatter 声明机器可读的 must_do 必做清单后,review 提交(verify_tool)的
5
5
  * validation_steps 必须逐项覆盖(completed=true,或 completed=false 且 skip_reason 为合法结构化
6
- * JSON)。未声明 must_do 的 skill 与解析不到质量门 skill 的 step 优雅跳过(不误伤非质量门 step)。
6
+ * JSON)。门禁按各 skill 声明的 must_do 通用生效,不限质量门类;未声明 must_do 的 skill 与解析不到
7
+ * 声明 must_do 的 skill 的 step 优雅跳过(不误伤无必做清单的 step)。
7
8
  * giveup 决策复用同一套未覆盖项推导,要求对未覆盖必做项补充结构化降级理由(checkpoint_skip_reasons),
8
9
  * 杜绝「放弃审查 → 直接推进收尾」的无痕绕过通道。
9
10
  *
@@ -45,7 +46,7 @@ export interface SkipReasonData {
45
46
 
46
47
  /**
47
48
  * 测试注入:覆盖门禁使用的 skill 索引。
48
- * 存量测试基建(tests/helpers.ts setupWorkspace)默认注入空索引以豁免门禁(解析不到质量门 skill),
49
+ * 存量测试基建(tests/helpers.ts setupWorkspace)默认注入空索引以豁免门禁(解析不到声明 must_do 的 skill),
49
50
  * 新增门禁用例显式注入构造索引或真实索引(scanSkillTags())验证。null=无注入,走真实文件扫描。
50
51
  */
51
52
  let overrideIndex: SkillTagIndex | null = null
@@ -134,7 +134,7 @@ export const checkpointSkipReasonItem: JSONSchema = {
134
134
  type: "object",
135
135
  description: "giveup 决策的必做项结构化降级理由",
136
136
  properties: {
137
- item: { type: "string", minLength: 1, description: "对应的必做项(质量门 skill 的 must_do 清单项)" },
137
+ item: { type: "string", minLength: 1, description: "对应的必做项(已加载 skill 的 must_do 清单项)" },
138
138
  category: { type: "string", minLength: 1, description: "降级类别,如环境不可用 / 用户裁定豁免 / 无人值守自动降级" },
139
139
  adjudication: {
140
140
  type: "string",
@@ -330,7 +330,7 @@ export const agentSubmitSchema: JSONSchema = {
330
330
  },
331
331
  checkpoint_skip_reasons: {
332
332
  type: "array",
333
- description: "giveup 决策配套:对当前 step 质量门必做清单未覆盖项的结构化降级理由(未覆盖项缺理由则拒绝 giveup)",
333
+ description: "giveup 决策配套:对当前 step 已加载 skill 必做清单未覆盖项的结构化降级理由(未覆盖项缺理由则拒绝 giveup)",
334
334
  items: checkpointSkipReasonItem,
335
335
  },
336
336
  new_children: {
@@ -511,8 +511,9 @@ function handleReviewParams(
511
511
  }
512
512
 
513
513
  // 必做清单覆盖度门禁:verdict=passed 且非补交豁免(仅裁定参数)时,validation_steps 须逐项覆盖
514
- // 当前 agent 能力集解析出的质量门 skill 必做清单(must_do)。遗漏必做项且无有效降级证据 → 拒绝提交。
515
- // 未声明 must_do 的 skill / 解析不到质量门 skill 的 step 自动跳过(不误伤 verify_task/verify_quality)。
514
+ // 当前 agent 能力集解析出的已加载 skill 必做清单(must_do)。遗漏必做项且无有效降级证据 → 拒绝提交。
515
+ // 门禁按各 skill 声明的 must_do 通用生效,不限质量门类;未声明 must_do 的 skill / 解析不到声明
516
+ // must_do 的 skill 的 step 自动跳过(不误伤无必做清单的 step)。
516
517
  // 覆盖口径:核验申报(completed=true + 描述注明核验方式与抽验样本,step 名首段 token 命中必做项)是
517
518
  // 高成本必做项的合法覆盖形态,仅限 workflow 指令白名单限定的高成本必做项(deep_scan);低成本必做项
518
519
  // 必须实跑后申报(机制层只认 token 命中不区分形态,白名单口径在错误提示中明示)。
@@ -520,8 +521,8 @@ function handleReviewParams(
520
521
  const uncovered = uncoveredMustDo(opts.capabilityTags, params.validation_steps)
521
522
  if (uncovered.length > 0) {
522
523
  throw new Error(
523
- `提交的验证步骤未覆盖质量门 skill 必做清单,缺少以下必做项:${uncovered.join("、")}。\n` +
524
- `请按已加载质量门类 skill 的必做清单逐项执行并逐项申报结果(completed=true);` +
524
+ `提交的验证步骤未覆盖已加载 skill 的必做清单,缺少以下必做项:${uncovered.join("、")}。\n` +
525
+ `请按已加载 skill 的必做清单逐项执行并逐项申报结果(completed=true);` +
525
526
  `确实无法执行的必做项须以结构化 skip_reason 申报降级理由` +
526
527
  `(格式:${SKIP_REASON_FORMAT})。` +
527
528
  `低成本必做项必须实跑后申报;核验申报仅限 workflow 指令白名单限定的高成本必做项。`
@@ -791,8 +792,9 @@ export async function agentSubmitExecute(params: AgentSubmitParams, ctx: ToolCon
791
792
  const newChildren = (params.new_children ?? []).map((nc) => buildIssueChild(nc, ctx.agent))
792
793
 
793
794
  if (stepPhase === "review") {
794
- // 必做清单覆盖度门禁取「当前提交 agent 的能力集」:verify_quality 多 agent 各自 capability 解析
795
- // 不出质量门 skill(自动跳过),verify_tool 的 reviewer 按 quality-gate 能力集校验。
795
+ // 必做清单覆盖度门禁取「当前提交 agent 的能力集」:各 agent 只按自身 capability_tags 解析 skill。
796
+ // verify_quality 多 agent 各自解析不出声明 must_do 的 skill(自动跳过),verify_tool 按 quality-gate
797
+ // 能力集、verify_task 按 test-design 能力集分别校验各自的必做清单。
796
798
  const stepCfg = workflow.stepMap.get(params.step_id)!.step
797
799
  const agentCfg = stepCfg.agents.find((a) => a.id === ctx.agent)
798
800
  handleReviewParams(item, params, newChildren, params.step_id, {
@@ -957,10 +959,10 @@ async function applyCheckpointDecision(
957
959
  if (decision === "continue") {
958
960
  applyCheckpointContinue(item, step)
959
961
  } else {
960
- // giveup 必做清单核对(堵 giveup 侧门):当前 step 若含质量门 skill 必做清单(must_do),
962
+ // giveup 必做清单核对(堵 giveup 侧门):当前 step 若解析出已加载 skill 必做清单(must_do),
961
963
  // 未覆盖项必须有结构化降级理由(checkpoint_skip_reasons),否则拒绝 giveup——
962
- // 杜绝「放弃审查 → 自动推进 → 收尾合码」的无痕绕过通道。非质量门 step 或未声明 must_do
963
- // 的 skill 环境下 uncovered 为空,giveup 行为不受影响(与「编排改动须评估全流程连锁影响」一致)。
964
+ // 杜绝「放弃审查 → 自动推进 → 收尾合码」的无痕绕过通道。未声明 must_do 的 skill 环境下
965
+ // uncovered 为空,giveup 行为不受影响(与「编排改动须评估全流程连锁影响」一致)。
964
966
  const stepCaps = Array.from(new Set(step.agents.flatMap((a) => a.capability_tags)))
965
967
  const prevSteps = (item.metadata["validation_steps"] as Array<{ step: string; completed: boolean }> | undefined)
966
968
  const uncovered = uncoveredMustDo(stepCaps, prevSteps)
@@ -972,7 +974,7 @@ async function applyCheckpointDecision(
972
974
  const missing = uncovered.filter((m) => !provided.has(m))
973
975
  if (missing.length > 0) {
974
976
  throw new Error(
975
- `giveup 无法应用:当前 step 的质量门必做清单存在未覆盖项,须逐项提供结构化降级理由。\n` +
977
+ `giveup 无法应用:当前 step 的已加载 skill 必做清单存在未覆盖项,须逐项提供结构化降级理由。\n` +
976
978
  `缺少降级理由的必做项:${missing.join("、")}\n` +
977
979
  `请通过 checkpoint_skip_reasons 逐项提供(giveup 未覆盖项不可跳过申报):\n` +
978
980
  `[${SKIP_REASON_FORMAT}]`
@@ -77,7 +77,7 @@ export interface AgentSubmitParams {
77
77
  reject_reason?: string
78
78
  }>
79
79
  checkpoint_decision?: "continue" | "giveup"
80
- /** giveup 决策配套:对当前 step 质量门必做清单(must_do)未覆盖项逐项提供的结构化降级理由
80
+ /** giveup 决策配套:对当前 step 已加载 skill 必做清单(must_do)未覆盖项逐项提供的结构化降级理由
81
81
  * (giveup 未覆盖项缺理由则拒绝 giveup)。adjudication 取值 user_response / unattended_auto / env_unavailable。 */
82
82
  checkpoint_skip_reasons?: Array<{
83
83
  item: string
@@ -131,13 +131,13 @@ function renderCheckpoint(rec: EngineRecommendation, workflow: LoadedWorkflow, i
131
131
  `唯一动作:调用 \`opx_agent_submit({ step_id: "${step}", checkpoint_decision: "continue" })\`(continue / giveup 二选一)推进。`,
132
132
  "",
133
133
  ]
134
- // 质量门类 step(当前 step 能力集解析出质量门必做清单)giveup 时,未覆盖必做项须经
134
+ // 解析出必做清单的 step(各 skill 声明 must_do 即生效,不限质量门类)giveup 时,未覆盖必做项须经
135
135
  // checkpoint_skip_reasons 逐项申报结构化降级理由(操作指引层面,不解释门禁内部实现)。
136
136
  const entry = rec.stepId ? workflow.stepMap.get(rec.stepId) : undefined
137
137
  const stepCaps = Array.from(new Set((entry?.step.agents ?? []).flatMap((a) => a.capability_tags)))
138
138
  if (resolveMustDoForCaps(stepCaps).length > 0) {
139
139
  lines.push(
140
- `质量门类 step 的 giveup 决策:未覆盖必做项须经 \`checkpoint_skip_reasons\` 逐项申报结构化降级理由(格式:\`${SKIP_REASON_FORMAT}\`),缺理由 giveup 不会被受理。`,
140
+ `含必做清单的 step 的 giveup 决策:未覆盖必做项须经 \`checkpoint_skip_reasons\` 逐项申报结构化降级理由(格式:\`${SKIP_REASON_FORMAT}\`),缺理由 giveup 不会被受理。`,
141
141
  "",
142
142
  )
143
143
  }