@peterxiaoyang/superspec 0.1.44 → 0.1.45

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 (40) hide show
  1. package/README.md +13 -1
  2. package/dist/cli.js +23 -24
  3. package/dist/code_review.js +7 -2
  4. package/dist/format.d.ts +4 -2
  5. package/dist/format.js +50 -16
  6. package/dist/git_state.d.ts +12 -1
  7. package/dist/git_state.js +45 -0
  8. package/dist/install.d.ts +1 -0
  9. package/dist/install.js +12 -0
  10. package/dist/next.d.ts +1 -1
  11. package/dist/next.js +3 -8
  12. package/dist/phase_confirmation.d.ts +6 -0
  13. package/dist/phase_confirmation.js +22 -6
  14. package/dist/phase_plan.d.ts +8 -1
  15. package/dist/phase_plan.js +130 -21
  16. package/dist/record.d.ts +1 -1
  17. package/dist/record.js +38 -30
  18. package/dist/review.js +18 -2
  19. package/dist/sync.js +13 -4
  20. package/dist/task.js +15 -2
  21. package/dist/task_evidence.d.ts +1 -1
  22. package/dist/task_evidence.js +85 -10
  23. package/dist/transition.d.ts +4 -3
  24. package/dist/transition.js +162 -29
  25. package/dist/types.d.ts +24 -1
  26. package/dist/types.js +1 -0
  27. package/dist/workflow_config.d.ts +24 -0
  28. package/dist/workflow_config.js +127 -0
  29. package/package.json +1 -1
  30. package/templates/workflow/AGENTS.md +1 -1
  31. package/templates/workflow/prompts/architect.md +1 -1
  32. package/templates/workflow/prompts/code-reviewer.md +2 -2
  33. package/templates/workflow/prompts/critic.md +4 -5
  34. package/templates/workflow/prompts/executor.md +2 -2
  35. package/templates/workflow/prompts/test-engineer.md +3 -4
  36. package/templates/workflow/prompts/verifier.md +1 -1
  37. package/templates/workflow/skills/superspec-apply/SKILL.md +13 -71
  38. package/templates/workflow/skills/superspec-explore/SKILL.md +5 -9
  39. package/templates/workflow/skills/superspec-propose/SKILL.md +26 -26
  40. package/templates/workflow/skills/superspec-review/SKILL.md +21 -50
@@ -0,0 +1,127 @@
1
+ // SuperSpec 项目级工作流配置。所有阶段从同一位置解析默认 mode,
2
+ // 避免 CLI、Explore、Propose、Review 各自保留不同默认值。
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ export const WORKFLOW_CONFIG_PATH = ".superspec/config.json";
6
+ /** 新安装项目写入配置时采用的默认档位。 */
7
+ export const DEFAULT_WORKFLOW_RISK = "normal";
8
+ /** 未安装项目继续沿用历史 strict 默认,避免无配置的旧项目静默放宽。 */
9
+ const LEGACY_WORKFLOW_RISK = "strict";
10
+ export class WorkflowConfigError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = "WorkflowConfigError";
14
+ }
15
+ }
16
+ function isReviewRisk(value) {
17
+ return value === "minimal" || value === "normal" || value === "strict";
18
+ }
19
+ function workflowModeFromPayload(payload) {
20
+ return isReviewRisk(payload.workflow_mode) ? payload.workflow_mode : null;
21
+ }
22
+ /**
23
+ * Propose-ready 是一个 planning round 的冻结点。配置只影响尚未冻结的计划;
24
+ * 已就绪计划必须沿用当时的 mode,直到 reopen 回到 propose 后创建新 round。
25
+ */
26
+ export function workflowRiskForProposeRound(events, fallback) {
27
+ for (let i = events.length - 1; i >= 0; i--) {
28
+ const event = events[i];
29
+ if (event.event_type !== "transition_commit")
30
+ continue;
31
+ const payload = event.payload;
32
+ if (payload.transition !== "propose-ready" || payload.to_state !== "propose_ready")
33
+ continue;
34
+ return workflowModeFromPayload(event.payload) ?? fallback;
35
+ }
36
+ return fallback;
37
+ }
38
+ /** 是否已经由当前引擎在 propose-ready 冻结 mode;缺失时是历史 planning round。 */
39
+ export function hasFrozenWorkflowModeForProposeRound(events) {
40
+ for (let i = events.length - 1; i >= 0; i--) {
41
+ const event = events[i];
42
+ if (event.event_type !== "transition_commit")
43
+ continue;
44
+ const payload = event.payload;
45
+ if (payload.transition !== "propose-ready" || payload.to_state !== "propose_ready")
46
+ continue;
47
+ return workflowModeFromPayload(event.payload) !== null;
48
+ }
49
+ return false;
50
+ }
51
+ /** Apply round 从 start-apply 起冻结;兼容首批事件中只写 review_policy 的格式。 */
52
+ export function workflowRiskForApplyRound(events, fallback) {
53
+ let latestStartApplyIndex = -1;
54
+ for (let i = events.length - 1; i >= 0; i--) {
55
+ const event = events[i];
56
+ if (event.event_type !== "transition_commit")
57
+ continue;
58
+ const payload = event.payload;
59
+ if (payload.transition === "start-apply" && payload.to_state === "apply") {
60
+ latestStartApplyIndex = i;
61
+ const frozenMode = workflowModeFromPayload(event.payload) ??
62
+ (isReviewRisk(payload.review_policy?.review_risk) ? payload.review_policy.review_risk : null);
63
+ if (frozenMode)
64
+ return frozenMode;
65
+ break;
66
+ }
67
+ }
68
+ // 升级前 review policy 首次在 review-ready 才落盘;只在当前 start-apply 之后查找,
69
+ // 防止 reopen 后新 round 泄漏第一轮策略。
70
+ if (latestStartApplyIndex >= 0) {
71
+ for (let i = events.length - 1; i >= latestStartApplyIndex; i--) {
72
+ const event = events[i];
73
+ if (event.event_type !== "transition_commit")
74
+ continue;
75
+ const payload = event.payload;
76
+ if (isReviewRisk(payload.review_policy?.review_risk))
77
+ return payload.review_policy.review_risk;
78
+ }
79
+ }
80
+ return fallback;
81
+ }
82
+ /** 供阶段确认和登记共用,避免任何调用者从 JSON/CLI 注入本轮 mode。 */
83
+ export function workflowRiskForState(events, state, fallback) {
84
+ switch (state) {
85
+ case "propose_ready":
86
+ return workflowRiskForProposeRound(events, fallback);
87
+ case "apply":
88
+ case "apply_done":
89
+ case "review":
90
+ case "accepted":
91
+ return workflowRiskForApplyRound(events, fallback);
92
+ default:
93
+ return fallback;
94
+ }
95
+ }
96
+ /**
97
+ * 读取项目默认模式。新安装项目由配置提供 normal;缺少配置的旧项目保留 strict。
98
+ * 配置格式:{ "workflow": { "mode": "normal" } }
99
+ */
100
+ export function workflowRiskForProject(projectRoot) {
101
+ const configPath = join(projectRoot, WORKFLOW_CONFIG_PATH);
102
+ if (!existsSync(configPath))
103
+ return LEGACY_WORKFLOW_RISK;
104
+ let parsed;
105
+ try {
106
+ parsed = JSON.parse(readFileSync(configPath, "utf8"));
107
+ }
108
+ catch {
109
+ throw new WorkflowConfigError(`${WORKFLOW_CONFIG_PATH} 必须是有效 JSON`);
110
+ }
111
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
112
+ throw new WorkflowConfigError(`${WORKFLOW_CONFIG_PATH} 顶层必须是 JSON object`);
113
+ }
114
+ const workflow = parsed.workflow;
115
+ if (workflow === undefined)
116
+ return DEFAULT_WORKFLOW_RISK;
117
+ if (!workflow || typeof workflow !== "object" || Array.isArray(workflow)) {
118
+ throw new WorkflowConfigError(`${WORKFLOW_CONFIG_PATH} 的 workflow 必须是 object`);
119
+ }
120
+ const mode = workflow.mode;
121
+ if (mode === undefined)
122
+ return DEFAULT_WORKFLOW_RISK;
123
+ if (!isReviewRisk(mode)) {
124
+ throw new WorkflowConfigError(`${WORKFLOW_CONFIG_PATH} 的 workflow.mode 只能是 minimal、normal 或 strict`);
125
+ }
126
+ return mode;
127
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peterxiaoyang/superspec",
3
- "version": "0.1.44",
3
+ "version": "0.1.45",
4
4
  "description": "SuperSpec 流程引擎 — transition engine with lightweight fact-sync",
5
5
  "type": "module",
6
6
  "engines": {
@@ -3,7 +3,7 @@
3
3
 
4
4
  即使用户没有显式调用 `superspec-*`,如果新输入像是在改变业务规则、产品口径、验收标准、示例规范、影响范围,或说明 PRD/文档/原型等需求源已更新,编辑代码前先提醒并做只读确认:这是实现偏差,还是需要先回 `superspec-propose` 更新计划文档;不要直接把这类自然语言当作 apply 授权。
5
5
 
6
- 用户补充 SuperSpec 相关内容时,先确定对应 change,再按 next 返回处理;无法确定时只询问归属,不执行流转。内部命令由主流程完成,不交给用户。
6
+ 用户补充 SuperSpec 相关内容时,先确定对应 change,再按 next 返回处理;无法确定时只询问归属,不执行流转。同一 change 的方案、需求、验收或实现约束补充,按影响回到该 change 的 `propose`,不要另建 repair change;内部命令由主流程完成,不交给用户。
7
7
 
8
8
  当用户显式调用 `$superspec-explore` 工作流时,视为已明确授权启动 `explore` subagent 做只读深扫;其他 `$superspec-*` 阶段仅在工作流引擎创建独立工作项时,视为授权启动对应 subagent。
9
9
 
@@ -43,7 +43,7 @@ argument-hint: "本次架构审查说明"
43
43
  - 有直接证据证明某个系统边界、消费者、视图差异或用户 / 系统可观察行为会被本次 change 改变,但 Impact 未登记且无排除理由,并且该遗漏会影响明确验收或使实现无法落地时,才判为 Impact / design 对账缺口;仅被检查但行为不变的范围、纯测试脆弱性和实现复杂度不要求进入 Impact
44
44
  - 输入来源修复不得无说明地扩大相邻规则、查询、缓存或数据形态的语义
45
45
  - task 的 `设计` 引用应指向技术上可行的实现方案、共享契约或边界约束;`边界` 应保护具体系统行为、数据语义、外部接口或共享规则。引用存在但方案不可行、边界与 design / Impact 冲突,或有直接证据证明本次 change 改变的关键边界未被保护且会影响明确验收时,应失败
46
- - task 分组应符合本次 change 实际涉及的系统责任边界;只有多个独立行为、跨入口改动或大改动确实无法在一个 RED/GREEN 闭环中独立验证时才要求拆分,不因模块通常被视为高风险就机械增加 task
46
+ - task 分组应符合本次 change 实际涉及的系统责任边界;只有多个独立行为、跨入口改动或大改动确实无法在一个独立验证边界内完成时才要求拆分,不因模块通常被视为高风险就机械增加 task
47
47
 
48
48
  ## 输出风格
49
49
 
@@ -33,9 +33,9 @@ argument-hint: "本次代码审查说明"
33
33
 
34
34
  工作项说明按 task 给出执行依据、改动归属线索、测试证据引用、范围扩大说明或测试覆盖豁免记录时,按 task 对照审查:
35
35
 
36
- - 执行依据快照是该 task 启动时执行依据五字段(测试/设计/来源/原因/边界)的定格版本:对照设计引用的原文审查实现路线是否一致;对照边界审查累计 diff 是否越界;对照来源和原因审查 task 拆分与实际改动是否一致。快照与当前 `tasks.md` 不一致本身就是审查信息(执行依据事后被修改)。
36
+ - 执行依据快照是该 task 启动时执行依据五字段(测试/设计/来源/验收/边界)的定格版本:对照设计引用的原文审查实现路线是否一致;对照边界审查累计 diff 是否越界;对照来源和验收审查 task 拆分与实际改动是否一致。快照与当前 `tasks.md` 不一致本身就是审查信息(执行依据事后被修改)。
37
37
  - 改动归属线索是该 task 执行窗口内变化过的文件列表,是线索不是结论;以累计 diff 为准,用它缩小对照范围。归属未知或标注不完整的 task,扩大对照范围。
38
- - 测试证据引用给出每个声明测试的 RED/GREEN 记录;核对测试断言是否真的覆盖对应 test-contract 场景,而不是只看有通过记录。
38
+ - 测试证据引用给出每个声明测试的记录;按 task-start 冻结的 `required_evidence` 核对:`red_required` 要求 RED,`green_required` 要求每个声明 TEST 的允许 GREEN。仍须核对测试断言是否真的覆盖对应 test-contract 场景,而不是只看有通过记录。
39
39
  - 范围扩大说明是执行者完成 task 时登记的:判断扩大是否合理、其验证引用是否覆盖扩大的影响面、是否需要补充 task 或回 propose;改动明显超出执行依据声明的边界却没有登记说明的,作为审查问题提出。
40
40
  - 没有归属到任何 task 的无主改动文件,逐个判断是否合理(如构建产物、机械连带),不合理的追问归属或要求补充说明。
41
41
  - 测试覆盖豁免记录解释了未绑定 task 的测试的用户决策;核对豁免理由与实现现状是否仍然成立。
@@ -68,7 +68,7 @@ argument-hint: "本次反方审查说明"
68
68
  - discovery 含链路五要素时,有证据确认会被本次 change 改变的下游消费者或视图差异未进入 Impact 且无排除理由;或 Impact 引用的 `CHAIN-xxx` 所代表的用户可观察行为没有测试场景映射且无不覆盖理由。仅被检查但行为不变的消费者不进入 Impact 或测试。design 仅引用 CHAIN 解释路线不重复产生测试映射;design 暴露的新消费者、视图差异或可观察行为影响必须先进入 Impact。对账不要求每条 CHAIN 单独进入 Impact;同一链路已由 IDC 覆盖且互相引用时不重复报错。
69
69
  - proposal、design、specs 与已确认的 CHAIN / IDC 结论显式矛盾,且没有声明为待确认或本次有意变更。
70
70
  - `specs/` 增量与 proposal 能力变化不对应:声明的能力缺规范增量、specs 引入未声明能力,或规范正文写成实现路线 / 过程描述。绑定为目录时须逐个打开 Markdown 规范;无法读取时必须失败。
71
- - `tasks.md` 无法定位到 design 的实现方案或边界约束,任务过粗,或多个独立行为混在同一 RED/GREEN 闭环。
71
+ - `tasks.md` 无法定位到 design 的实现方案或边界约束,任务过粗,或多个独立行为混在同一验证边界。
72
72
  - task ID 重复 / 不稳定,标题混入 task ID,缩进 checkbox 或普通说明承载实际工作,task 中写入 RED/GREEN 命令、断言或预期输出。
73
73
  - tasks 顺序与依赖矛盾:被依赖 task 出现在依赖它的 task 之后;标题分组和行内依赖说明不改变全文顶格 checkbox 执行顺序。
74
74
  - 分组标题、task ID 或任务文本会让执行者容易启动错任务时应失败;不要为弥补拆分不清而要求父子任务状态、额外设计字段或 tasks 反向引用 design。
@@ -81,13 +81,12 @@ argument-hint: "本次反方审查说明"
81
81
 
82
82
  至少有一个执行依据块已正确绑定时,追加:
83
83
 
84
- - 普通 `tdd_required:true` task 缺 `执行依据:`,或其执行依据缺 `测试` 字段(`tdd_required:false` task `测试` 按需填写,不作为阻塞条件)。
85
- - 普通 `tdd_required:true` task 的执行依据缺 `设计`、`来源`、`原因` 或 `边界` 字段。
84
+ - 普通 task 缺 `执行依据:`,或其执行依据缺 `测试`、`设计`、`来源`、`验收` `边界` 字段。`测试` 必须显式出现;纯文档、配置或机械 task 可以留空,但代码/行为 task 必须绑定至少一个 `TEST-xxx`。
86
85
  - 执行依据字段重复,或块内出现 checkbox(会变成无人执行的暗任务)。
87
86
  - `设计`、`来源` 引用无法定位到原文(对应文件不存在该标题/摘录/ID),或引用不带文件前缀导致无法回读。`边界` 默认可以直接写具体保护语义,不要求文件前缀;只有它声明引用既有文档原文时,才要求可定位。
88
87
  - 声明的 `TEST-xxx` 不存在于 `test-contract.md`。
89
- - 单个 task 声明的测试超过 3 个但 `原因` 未说明为什么不再拆分;或 `原因` 与 `来源` 明显不支持该 task 的拆分边界。
90
- - 字段内容是放在任何 task 上都成立的套话(如 `边界` 写"不破坏现有功能"、`原因` 写"需要单独实现"),无法用来对照实现或审查越界;或多个 task 的执行依据互相复制、与各自任务内容不对应。
88
+ - 单个 task 声明的测试超过 3 个但 `验收` 未说明为什么不再拆分;或 `验收` 与 `来源` 明显不支持该 task 的拆分边界。
89
+ - 字段内容是放在任何 task 上都成立的套话(如 `边界` 写"不破坏现有功能"、`验收` 写"完成实现"),无法用来对照实现或审查越界;或多个 task 的执行依据互相复制、与各自任务内容不对应。是否需要 RED/GREEN 由 task-start 写入的有效证据快照决定;历史 `tdd_required` / `no_tdd_reason` 仅用于旧记录回放,不得作为新计划审查条件。
91
90
  - `设计` 引用虽可定位,但内容与 task 实质无关时阻塞;引用方案在技术上是否可行、边界是否充分,由 Architect 审查。
92
91
 
93
92
  ## 输出风格
@@ -7,7 +7,7 @@ argument-hint: "本次执行说明"
7
7
 
8
8
  ## 角色身份
9
9
 
10
- 你是 Executor。你只负责一个 SuperSpec apply task 的实现编辑,把已声明测试从 RED 推到 GREEN;你不负责流程判断、审查结论、证据归档或 task checkbox。
10
+ 你是 Executor。你只负责一个 SuperSpec apply task 的实现编辑:严格执行 task-start 返回的 `required_evidence`;`red_required` 为真时先取得 RED,`green_required` 为真时取得允许的 GREEN,二者都为假时不要自行添加测试阶段。你不负责流程判断、审查结论、证据归档或 task checkbox。
11
11
 
12
12
  ## 读写边界
13
13
 
@@ -20,7 +20,7 @@ argument-hint: "本次执行说明"
20
20
 
21
21
  ## 本次任务说明
22
22
 
23
- 先读取主流程提供的本次执行说明。以本次任务说明中的 `task_id`、`declared_task_write_scope`、`guard_fingerprint`、`apply_worker_chain_id`、`chain_activation_template`、`openspec_context_file_refs`、`task_refs`、`test_contract_refs`、报告策略和停止条件为准。
23
+ 先读取主流程提供的本次执行说明。以其中的 `task_id`、`required_evidence`、`declared_task_write_scope`、`guard_fingerprint`、`apply_worker_chain_id`、`chain_activation_template`、`openspec_context_file_refs`、`task_refs`、`test_contract_refs`、报告策略和停止条件为准。`execution_policy` 仅用于审计展示,不用于自行推断验证步骤;不运行或伪造快照未要求的 RED,也不把缺少快照所要求 GREEN 的实现报告为完成。
24
24
 
25
25
  只有主流程已经记录 `chain_activation_template` 为 active `apply_worker_chain` 后,才允许开始实现。不要依赖本 prompt 记忆输出 schema。
26
26
 
@@ -26,18 +26,17 @@ argument-hint: "本次测试审查说明"
26
26
  - recommendation 只能描述需要证明的行为、边界或证据,不把测试偏好和新的基础设施方案写成 required fix;推荐方案不是 finding 成立的证据。
27
27
  - 已声明行为和本次直接边界都有可信证明时停止,不为“更全面”而继续增加与验收无关的组合、故障矩阵或基础设施测试。
28
28
 
29
- ## 任务拆分与 RED/GREEN 审查口径
29
+ ## 任务拆分与执行证据审查口径
30
30
 
31
31
  重点审查设计约束是否可验证,以及 task / design / test-contract 是否形成可信闭环。能力覆盖和文档可审查性由 Critic 主责;技术路线和系统边界由 Architect 主责。
32
32
 
33
- - TDD task 应形成清晰 RED/GREEN 闭环;`tasks.md` 只声明任务边界和 `tdd_required:true/false`,不得写 RED/GREEN 命令、断言或预期输出
33
+ - `tasks.md` 只声明任务边界及执行依据(测试/设计/来源/验收/边界),不得写 RED/GREEN 命令、断言、预期输出或模式标记;task-start `required_evidence` 决定本次是否需要 RED/GREEN
34
34
  - 根据 design 已采纳的实现方案、边界约束、共享契约和有当前证据的真实风险判断 test-contract 是否覆盖本次主要风险;不要求 design 使用固定字段或可选风险章节
35
35
  - task 或 test-contract 场景无法定位到对应实现方案、共享契约或边界约束,因而无法推导测试条件和预期结果时,应失败
36
36
  - task 执行依据声明的 `TEST-xxx` 必须存在,scenario 必须确实验收该 task;scenario 无法推导断言、与 task 描述明显不匹配,或 task 的主要验收路径及其边界没有测试覆盖且无豁免时,应失败
37
37
  - task 的 `设计` 引用与声明测试必须匹配;当本次 change 明确新增或改变关键边界、状态转换、优先级、一致性 / 并发 / 兼容约束,且这些行为影响验收时,只覆盖 happy path 应判为覆盖缺口。未改变的既有语义和无证据的假想风险不要求新增测试
38
38
  - `test-contract.md` 必须可解析,表头含 `test_id` 和 `scenario`,无重复 `test_id`;未绑定任何 task 的 TEST 必须有合理说明或留待用户豁免,不能把文档内的不覆盖理由当成已豁免
39
- - 测试方案必须能定义目标测试身份、RED 失败信号和 GREEN 覆盖映射;不能只靠退出码或笼统命令证明
40
- - `tdd_required:false` 必须有明确 `no_tdd_reason`;只有 `no_tdd_reason:characterization` 的 task 可以用特征化通过作为测试证据
39
+ - 测试方案必须能定义目标测试身份、覆盖映射和 task-start 所要求的失败/通过证据;不能只靠退出码或笼统命令证明。新计划统一使用 `expected_success` 作为通过证据;`characterization_pass` 只为历史 attempt 回放保留,历史标记不构成新计划要求
41
40
 
42
41
  ## 输入数据与链路覆盖审查口径
43
42
 
@@ -35,7 +35,7 @@ argument-hint: "本次验证说明"
35
35
  - 已完成任务、测试记录、审查记录和提交给 verifier 的证据,是否能对应到 proposal、design、tasks、test-contract 的目标。
36
36
  - 计划材料是否被绕过工作流改写;合法自动勾选和代码审查追加的修复项以工作项说明和事件记录为准。
37
37
  - 工作项、用户输入或引用材料显示需求源已更新时,最终证据必须能对应已处理该变化的最新计划材料;仍引用旧计划且无 `## 需求变化` 处理时,按证据不足失败。
38
- - RED/GREEN 证据是否同一次任务尝试闭环;退出码、环境错误或构建错误不能单独作为行为证明。带执行依据的 task,每个声明测试都要有当前任务尝试内的有效通过证据;特征化任务(为固化既有行为而写保护测试的任务)的特征化通过记录等价于通过证据。
38
+ - 测试证据是否符合每个 task 的 `required_evidence` 且来自同一次任务尝试;`red_required` 为真时需要 RED,`green_required` 为真时每个声明 TEST 都需要 `accepted_green_statuses` 允许的 GREEN。`execution_policy` 只作审计展示,不能代替该快照。退出码、环境错误或构建错误不能单独作为行为证明。
39
39
  - 输入数据来源核查是否闭环;不得只用 GREEN 测试或 task 勾选证明输入完整性。
40
40
  - 工作项说明带代码状态检查结果时:它记录代码审查通过后代码是否又发生了变化;存在差异时在报告中列出差异文件,交主流程和用户裁决是否需要重新代码审查;不自行判定这些改动无害,也不据此自动否定已接受的代码审查。
41
41
  - 已完成 task 的范围扩大说明是否与最终改动一致;test-contract 中未绑定 task 的测试是否都有用户豁免决策留痕。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: superspec-apply
3
- description: "三.按 tasks.md 逐任务实现代码,并按要求完成红/绿验证"
3
+ description: "三.按 tasks.md 逐任务实现并登记验证结果"
4
4
  metadata:
5
5
  author: SuperSpec
6
6
  source: SuperSpec
@@ -8,18 +8,15 @@ metadata:
8
8
 
9
9
  # SuperSpec Apply
10
10
 
11
- 你是执行阶段。目标是按 `tasks.md` 的可执行 task 完成实现:先 RED,再 GREEN,然后用 `task-complete` 标记完成。
11
+ 你是执行阶段。目标是按 `tasks.md` 的可执行 task 完成实现、登记真实验证结果,并用 `task-complete` 标记完成。
12
12
 
13
- ## 驱动方式
13
+ ## 使用方式
14
14
 
15
- 所有状态由工作流引擎管理,按这个循环执行:
15
+ 先运行 `superspec transition next --change "<change>"`,并把输出当成当前的一组工作项。它会给出要开始/完成的 task、需要的确认或审查;逐项处理,不要自行推断或描述内部流程。
16
16
 
17
- 1. `superspec transition next --change "<change>"` 获取下一步。
18
- 2. 执行返回的命令。
19
- 3. 登记结果。
20
- 4. 回到第 1 步。
21
-
22
- 如果 next 返回用户确认、审查或验证事项,停止当前 apply 推进,并按 next 交给对应工作项或用户确认处理。处理完成前不要继续下一个 task,也不要进入下一阶段;任务完成时说明改动、RED/GREEN 或 no-TDD 证据和下一步;发现范围、验收或用户可见行为变化时,停止实现并说明要回 propose。
17
+ - 收到 task:按下文完成一个 task,再重新获取下一步。
18
+ - 收到确认或审查:暂停编码,先处理该事项。
19
+ - 发现范围、验收或用户可见行为变化:停止实现,说明发现和影响,让引擎给出重新计划的动作。
23
20
 
24
21
  ## 普通 task 执行
25
22
 
@@ -29,67 +26,13 @@ metadata:
29
26
 
30
27
  1. **计划核对**:执行 `task-start` 前,确认当前 task 是 `tasks.md` 顶格任务。task 带 `执行依据:` 块时,以它为主要执行上下文;没有执行依据的历史 task 对应 `design.md` 的实现方向和 `proposal.md` 的 `## Impact` 受影响原因。缺少映射、需要新增能力/验收/影响范围时先停止,交回 propose,不写 RED。
31
28
  2. **任务开始**:执行 next 下发的 task-start 命令。
32
- 3. **读取执行依据快照**:task-start 的返回结果包含本次任务尝试 ID(`attempt_id`,登记测试时要用)和执行依据快照(五字段在启动时刻的定格版本)。返回结果带快照时,实现和验收以它为准;返回结果标明是历史任务(`legacy_contract`)时,即使 `tasks.md` 里有执行依据文本也不采纳为引擎契约,按原有方式回读 `proposal.md`、`design.md` 和 `test-contract.md`,test-run 走历史规则。
33
- 4. **RED**:执行依据声明了测试时,测试必须对应其中的 `TEST-xxx`(登记其他 TEST 会被拒绝);没有执行依据的历史 task 确认测试意图能对应 `test-contract.md` 的 `test_id`,缺少对应关系时先停止,交回 propose。运行后确认失败,并用 `superspec record test-run --change "<change>" --input -` 登记。
34
- 5. **实现**:根据任务写代码,保持范围小。`design.md` 不锁死字段名、函数名、SQL 或局部写法。
35
- 6. **GREEN**:运行测试确认通过,并登记 test-run。执行依据声明多个测试时,每个声明 TEST 都要有 GREEN;普通 `tdd_required:true` task 还要求至少一个 TEST 形成同 TEST 先 RED 后 GREEN,其余可以只有 GREEN 作为回归覆盖。
36
- 7. **完成 task**:执行 next 下发的 task-complete 命令。实现中发现改动明显超出 `执行依据:` 的 `边界`、`设计` 或 task 描述暗示的影响范围、但仍服务于当前 task 时,在该命令后追加 `--input -` 登记范围扩大说明(见「范围扩大说明」一节);范围扩大改变了用户可见能力、验收标准或规范时,不要用范围扩大说明掩盖,停止实现交回 propose。
37
-
38
- no-TDD 任务(`tdd_required:false` + `no_tdd_reason`)不要求 RED/GREEN 配对,但仍必须有清楚的完成证据。注意:如果该任务的 `执行依据:` 声明了 `测试`,每个声明 TEST 仍需登记一次通过证据才能完成,否则 task-complete 会被拒绝(特征化任务即 `no_tdd_reason:characterization`——为固化既有行为而写保护测试的任务——用特征化通过状态登记,其余用普通通过状态,取值见「test-run 输入」)。
39
-
40
- `tasks.md` 不写 RED/GREEN 命令、断言或预期输出。RED/GREEN 的真实证明来自 apply 阶段实际执行后登记的 `record test-run`。
41
-
42
- 如果 task id 以 `REVIEW-FIX-` 开头,或任务行带 `review_fix_of:<job_id>#<problem_id>`,把它当作普通 task 执行,不另起流程。它只表示该任务来自代码审查问题:实现范围只限对应问题;RED 或 characterization 要证明问题存在,GREEN 要证明问题已修复;完成前还要登记已完成任务的 GREEN 回归,或等价更大范围回归。修复中发现计划文档需要变化时,停止扩大实现,交回主流程处理。
43
-
44
- ## test-run 输入
45
-
46
- `record test-run` 优先从 stdin 登记 JSON:
47
-
48
- ```json
49
- {
50
- "test_id": "TEST-XXX",
51
- "attempt_id": "ATT-TASK-XXX-...",
52
- "command": "npm test",
53
- "cwd": "<工作目录>",
54
- "exit_code": 1,
55
- "semantic_status": "expected_failure"
56
- }
57
- ```
58
-
59
- 证据规则:
60
-
61
- - task 带执行依据时,示例中的六个字段全部必填,且 `test_id` 必须属于执行依据声明的测试。没有执行依据的历史 task 沿用旧规则:至少需要 `test_id` 和 `task_structure_digest`(当前 task 结构版本)。
62
- - `attempt_id` 来自当前 task attempt;新产生的 TDD 证据必须带当前 `attempt_id`。
63
- - `semantic_status` 使用 `expected_failure`(RED,要求 `exit_code != 0`)/ `expected_success`(GREEN,要求 `exit_code == 0`)/ `characterization_pass`(要求 `exit_code == 0`,且只有 `tdd_required:false no_tdd_reason:characterization` 的 task 可以使用)。
64
- - `covers_task_ids` 可选,只在回归或等价场景中填写到同一份 test-run JSON,用来说明这次测试覆盖了哪些已完成任务;省略表示不声明覆盖关系。
65
- - `command`、`cwd`、`exit_code` 和目标测试身份必须能说明目标测试确实运行。
66
- - 退出码本身不等于证明;环境错误或构建失败不算 RED 或 GREEN。
67
- - 缺少 `attempt_id`、只靠 `task_structure_digest` 匹配的旧 test-run 只能作为弱引用,不作为强证明。
68
- - 其他可选字段只有在有明确来源时再填;不要为通过校验编造。
69
-
70
- ## 范围扩大说明
71
-
72
- 实现时发现必须扩大影响范围(本次改动明显超出执行依据的 `边界`、`设计` 或 task 描述的暗示),且仍服务于当前 task 时,在 next 下发的 task-complete 命令后追加 `--input -`,从 stdin 传入 JSON(四个字段全部必填,`verification` 为非空字符串数组,格式不合法时引擎会说明原因并拒绝完成):
73
-
74
- ```json
75
- {
76
- "scope_note": {
77
- "reason": "为什么需要超出原执行依据的边界",
78
- "changed_area": "实际扩大的代码或行为范围",
79
- "plan_alignment": "扩大后仍如何服务于当前 task 或原设计",
80
- "verification": ["TEST-001", "覆盖该变化的其他说明引用"]
81
- }
82
- }
83
- ```
84
-
85
- - 这是完成 task 时的一次性说明,task 完成后不能补写;需要说明但没写的,会被代码审查作为问题提出。不要为了通过校验编造字段。
86
- - 范围扩大改变了用户可见能力、验收标准或 OpenSpec 规范时,不适用本机制,交回 propose。
87
-
88
- ## 测试覆盖豁免
29
+ 3. **读取执行快照**:task-start 的返回结果包含本次任务尝试 ID(`attempt_id`,登记验证时要用)和执行依据快照。实现与验证以该快照为准;不要根据风险模式、task 标记或历史经验自行选择验证步骤。
30
+ 4. **实现并验证**:根据任务写代码,保持范围小;执行引擎要求的验证并用 `record test-run` 登记真实结果。缺少可执行验证或发现计划不再适用时,停止并交回计划处理。
31
+ 5. **完成 task**:执行 next 下发的 task-complete 命令。实现中发现改动明显超出 `执行依据:` 的 `边界`、`设计` 或 task 描述暗示的影响范围、但仍服务于当前 task 时,在该命令后追加 `--input -` 登记范围扩大说明(见「范围扩大说明」一节);范围扩大改变了用户可见能力、验收标准或规范时,不要用范围扩大说明掩盖,停止实现交回 propose。
89
32
 
90
- 进入审查前,`test-contract.md` 中每个 TEST 要么绑定到某个 task 的 `测试` 字段,要么有用户豁免决策。被阻断提示某个 TEST 未绑定时,先向用户确认原因(不要代替用户决策),再按阻断消息给出的命令和格式登记。注意:计划文档里写了不覆盖理由不等于已豁免,引擎只认已登记的用户决策。
33
+ ## 结果登记
91
34
 
92
- 以上两种登记在向用户沟通时都用人话说明(如"这次实现比计划多改了导出列,原因和验证已记录在案"、"测试契约里的 TEST-003 没有任务实现它,请确认是否豁免及原因"),不要原样复述命令、JSON 字段或内部事件。
35
+ 验证结果、范围扩大说明和测试覆盖豁免都按引擎当前返回的命令与输入契约登记;不要在 Skill 中猜测字段、复用旧输入或编造证据。向用户说明时只说实际改动、原因、验证与需要的业务确认,不复述内部 JSON
93
36
 
94
37
  ## Guardrails
95
38
 
@@ -100,6 +43,5 @@ no-TDD 任务(`tdd_required:false` + `no_tdd_reason`)不要求 RED/GREEN 配
100
43
  - 用户在 apply 期间或 apply 后补充最新业务规则、产品口径、验收标准、示例规范、兼容策略、影响范围,或说明需求源已更新时,停止实现并交回主流程使用 `superspec-propose` 更新计划文档;交回时说明变化来源、变化内容、影响范围和建议处理方式。
101
44
  - 不修改 `proposal.md`、`design.md`、`specs/**` 或 `.superspec/**`。
102
45
  - active attempt 期间不要修改 `tasks.md` 中除 `task-complete` 自动勾选目标 checkbox 外的内容。
103
- - 不跳过 RED 直接写 GREEN。
104
46
  - 不手改 tasks.md 复选框;`task-complete` 会自动补丁。
105
- - 不跳过 transition。
47
+ - 不手写复选框或推进结果;只执行 `next` 当前返回的命令。
@@ -10,16 +10,13 @@ metadata:
10
10
 
11
11
  职责:只读调查现状、梳理范围、识别风险,并把结论写入 `openspec/changes/<change>/.superspec/artifacts/discovery.md`。
12
12
 
13
- ## 驱动方式
13
+ ## 使用方式
14
14
 
15
- 所有状态由工作流引擎管理:
15
+ 把 `superspec transition next --change "<change>"` 的输出当成当前任务卡:只处理它给出的一组事项,不自行推断流程位置或补造命令。
16
16
 
17
- 1. `superspec transition next --change "<change>"`
18
- 2. 执行返回的命令、工作项或用户确认
19
- 3. 用户确认用 `superspec record user-decision --change "<change>" --input -`;工作项审查报告用 `superspec record job-submit --change "<change>" --job <JOB> --report -`
20
- 4. 回到第 1 步
21
-
22
- 进入下一阶段前,必须先处理 next 返回的用户确认、审查或验证事项。默认完整审查路径下,`explore -> propose` 会创建 `critic` 工作项审查 discovery。
17
+ - 返回调查/编辑动作:完成本 Skill 要求的 discovery,再重新获取下一步。
18
+ - 返回用户确认或审查工作项:暂停调查,按输出给出的格式登记决策或提交独立审查报告。
19
+ - 不确定时先补证据;只有业务口径、验收、范围或数据来源无法由现有材料裁决时才问用户。
23
20
 
24
21
  如果 next 提示 discovery 不完整或有未确认问题,先检查并填写 discovery,不要把草稿占位、格式缺口或路径空白直接转问用户。用户明确说 PRD、文档、原型或其它需求源已更新时,先重新核对来源,不复用旧依据。什么未知该进 `## 待确认问题`,判定标准见「写作规则」。
25
22
 
@@ -106,7 +103,6 @@ subagent 结论写入 discovery 前,抽验决定影响范围判断的关键短
106
103
 
107
104
  - 不改业务代码。
108
105
  - 不写 proposal/specs/design/tasks。
109
- - 不跳过 transition。
110
106
  - 不跳过完整审查路径下的审查工作项。
111
107
  - 用户未确认的决策不自行推断。
112
108
  - 审查通过后、推进前不做非必要的文档编辑;文档变更会作废已通过的审查并触发重审。
@@ -10,20 +10,17 @@ metadata:
10
10
 
11
11
  你是计划阶段。职责:把探索结论转化为可执行的计划——写 proposal.md / specs / design.md / tasks.md + test-contract.md。
12
12
 
13
- ## 驱动方式
13
+ ## 使用方式
14
14
 
15
- 所有状态由工作流引擎管理:
15
+ 先运行 `superspec transition next --change "<change>"`;它给出的命令、确认或工作项就是当前要处理的一组事项。不要根据历史 job 或记忆自行拼接推进命令。
16
16
 
17
- 1. `superspec transition next --change "<change>"`
18
- 2. 执行返回的命令、工作项或用户确认
19
- 3. 用户确认用 `superspec record user-decision --change "<change>" --input -`;工作项审查报告用 `superspec record job-submit --change "<change>" --job <JOB> --report -`(文件路径模式仍可作为 fallback)
20
- 4. 回到第 1 步
21
-
22
- 进入下一阶段前,必须先处理 next 返回的用户确认、审查或验证事项。默认完整审查路径下,进入实现前会要求 `critic`、`architect`、`test-engineer` 三个独立审查工作项完成;审查必须由独立角色执行,不能由主流程自审代替,报告按工作流返回的格式提交并记录实际审查来源。
17
+ - 文档未就绪:补齐本 Skill 定义的计划材料,再重新获取下一步。
18
+ - 需要用户确认:汇总真正影响业务、验收或范围的选择,按输出格式登记。
19
+ - 需要审查:交给输出指定的独立角色,使用返回的提交格式记录报告;主流程自检不能替代独立审查。
23
20
 
24
21
  什么问题需要用户确认,判定标准见「待用户确认」一节;就绪或审查后向用户只概括任务可验证性、关键风险/证据覆盖和下一步。
25
22
 
26
- 执行 propose-ready 前,对照 critic / architect / test-engineer 的阻塞条件快速自检(非穷尽):Impact 与 CHAIN/IDC 对账、specs 增量与 proposal 能力变化互相对应、design 的功能点与实现方案能推出 tasks、DEC 已有行内结论并回写、task 粒度单一行为且顺序可执行、每个普通 TDD task 有完整可定位的 `执行依据:`(声明的 TEST 都存在于 test-contract,`边界`/`原因` 具体到该 task 而非套话)、specs 中的核心业务规则可验证、test-contract 覆盖 Impact 引用的 CHAIN、test-contract 中未绑定任何 task 的 TEST 有明确取舍(绑定到 task 或留待用户豁免决策)。自检不替代审查工作项,只为减少驳回往返。
23
+ 执行 propose-ready 前,对照 critic / architect / test-engineer 的阻塞条件快速自检(非穷尽):Impact 与 CHAIN/IDC 对账、specs 增量与 proposal 能力变化互相对应、design 的功能点与实现方案能推出 tasks、DEC 已有行内结论并回写、task 粒度单一行为且顺序可执行、每个普通 task 有完整可定位的 `执行依据:`(声明的 TEST 都存在于 test-contract,`边界`/`验收` 具体到该 task 而非套话)、specs 中的核心业务规则可验证、test-contract 覆盖 Impact 引用的 CHAIN、test-contract 中未绑定任何 task 的 TEST 有明确取舍(绑定到 task 或留待用户豁免决策)。自检不替代审查工作项,只为减少驳回往返。
27
24
 
28
25
  人类可读正文默认使用简体中文;OpenSpec 结构标题、规范关键字、命令、路径、JSON 字段、代码标识符保留原文。OpenSpec 生成文档语言不符合预期时,先检查 `openspec/config.yaml` 的官方 `context` 设置;不要在变更文档里添加自定义 `language` 字段。
29
26
 
@@ -139,43 +136,47 @@ metadata:
139
136
 
140
137
  ## Review verifier
141
138
 
142
- - [ ] 1.1 检查 verifier 绑定文档 tdd_required:true
139
+ - [ ] 1.1 检查 verifier 绑定文档
143
140
  执行依据:
144
141
  - 测试: test-contract.md#TEST-001
145
142
  - 设计: design.md#Verifier 文档绑定:沿用现有校验入口
146
143
  - 来源: proposal.md#Impact;specs/review/spec.md#verifier 绑定
147
- - 原因: 独立可验收行为,可由 TEST-001 验收
144
+ - 验收: 独立可验收行为,可由 TEST-001 验收
148
145
  - 边界: 保持既有 job 提交协议不变
149
- - [ ] 1.2 检查 verifier 绑定执行证据 tdd_required:true
146
+ - [ ] 1.2 检查 verifier 绑定执行证据
150
147
  执行依据:
151
148
  - 测试: test-contract.md#TEST-002,TEST-003
152
149
  - 设计: design.md#执行证据核对:复用现有证据链
153
150
  - 来源: proposal.md#Impact;discovery.md#CHAIN-001
154
- - 原因: 证据核对与文档绑定是两个独立验收入口
151
+ - 验收: 证据核对与文档绑定是两个独立验收入口
155
152
  - 边界: 不改变历史证据的判定语义
156
153
 
157
154
  ## Documentation
158
155
 
159
- - [ ] 2.1 更新文档 tdd_required:false no_tdd_reason:documentation-only
156
+ - [ ] 2.1 更新文档
157
+ 执行依据:
158
+ - 测试:
159
+ - 设计: design.md#文档说明
160
+ - 来源: proposal.md#Impact
161
+ - 验收: 文档准确反映已确定的行为变化
162
+ - 边界: 不改业务代码或行为
160
163
  ```
161
164
 
162
165
  规则:
163
- - 每个普通 TDD task(`tdd_required:true`)必须紧跟一个 `执行依据:` 块,包含五个字段:`测试`(该 task 必须兑现的 test-contract 场景,引用 `test-contract.md#TEST-xxx`,多个用逗号合并)、`设计`(执行路线在 `design.md` 的位置或短摘录)、`来源`(task 产生依据,如 `proposal.md#Impact`、spec delta、`discovery.md#CHAIN-xxx,IDC-xxx`,已有明确文件路径的补充材料用 `.superspec/artifacts/...`)、`原因`(为什么单独拆出这个 task)、`边界`(执行时需要保护的边界)
166
+ - 每个普通 task 必须紧跟一个 `执行依据:` 块,包含五个字段:`测试`(该 task 必须兑现的 test-contract 场景,引用 `test-contract.md#TEST-xxx`,多个用逗号合并;没有自动化测试的纯文档/机械任务留空)、`设计`(执行路线在 `design.md` 的位置或短摘录)、`来源`(task 产生依据,如 `proposal.md#Impact`、spec delta、`discovery.md#CHAIN-xxx,IDC-xxx`,已有明确文件路径的补充材料用 `.superspec/artifacts/...`)、`验收`(完成后可检查的结果)、`边界`(执行时需要保护的边界)
164
167
  - `执行依据:` 必须紧跟所属 task 行(中间最多允许一个空行);字段不得重复;块内不得出现 checkbox(`- [ ]` / `- [x]`),否则会变成无人执行的暗任务并被引擎拒绝
165
168
  - `设计`、`来源` 的标题或短摘录引用必须使用带文件名前缀的可定位格式,如 `design.md#...`、`proposal.md#...`、`specs/.../spec.md#...`;只有 ID 型引用(TEST/CHAIN/IDC)可以逗号合并。`边界` 默认直接写可对照 diff 的具体保护语义,不需要文件前缀;只有主动引用既有文档原文时才写对应文件和锚点
166
169
  - 声明的每个 `TEST-xxx` 必须存在于 `test-contract.md`,否则 `propose-ready` 和 `start-apply` 会被阻断
167
- - 五个字段的内容必须针对该 task 具体可核验,执行者和审查者要拿它们对照实现:`边界` 写出改动不应触碰的具体行为、模块或语义(能对着 diff 判断有没有越界),不写"不破坏现有功能"这类放在任何 task 上都成立的套话;`原因` 说明这个 task 独立存在的理由,不写"需要单独实现";不同 task 的执行依据不应互相复制
170
+ - 五个字段的内容必须针对该 task 具体可核验,执行者和审查者要拿它们对照实现:`边界` 写出改动不应触碰的具体行为、模块或语义(能对着 diff 判断有没有越界),不写"不破坏现有功能"这类放在任何 task 上都成立的套话;`验收` 写出完成后的可检查结果,不写"完成实现";不同 task 的执行依据不应互相复制
168
171
  - 写不出可定位的 `设计` 引用时,说明 `design.md` 缺少该 task 的实现方案或边界约束——先补设计,不编造引用
169
- - 单个 task 声明的测试超过 3 个时,`原因` 必须说明为什么不再拆分
170
- - `tdd_required:false` task 可以写执行依据,`测试` 字段按需填写;特征化任务(characterization task,指为固化既有行为而写保护测试、不引入新行为的任务)用 `tdd_required:false no_tdd_reason:characterization` 标记,只有这类任务可以在执行阶段以特征化通过作为测试证据
172
+ - 单个 task 声明的测试超过 3 个时,`验收` 必须说明为什么不再拆分
173
+ - Propose 只声明 TEST 和验收目标,不写 `tdd_required`、`no_tdd_reason`、RED/GREEN 或模式参数;`task-start` 会把本轮已冻结的策略与该声明编译为执行要求。代码/行为 task 必须声明至少一个 TEST;纯文档、配置或机械任务的 `测试` 留空,并在验收与边界中说明其非行为性质
171
174
  - `REVIEW-FIX-*` task 由引擎在审查返工时追加,不需要手写执行依据
172
175
  - `<task_id>` 可以是 `1.1` 或 `TASK-001.1`,必须唯一、稳定;标题不要包含 task id token,例如不要写 `## 1.1 Review verifier`
173
176
  - task 内部步骤用普通 bullet,不用缩进 checkbox——引擎只解析顶格 checkbox 行,缩进的会变成无人执行的暗任务
174
- - `tdd_required:true`(默认)——改运行时代码/业务逻辑/权限/外部接口
175
- - `tdd_required:false` + `no_tdd_reason:xxx`——纯文档/配置/机械改名/生成物
176
- - task 行只标记是否需要 TDD,不写 RED/GREEN 命令、断言或预期输出;实际 RED/GREEN 由 apply 阶段执行并记录
177
+ - task 行不写 RED/GREEN 命令、断言、预期输出或执行模式;实际需要的验证由 task-start 返回的执行快照决定
177
178
  - 一个 task 对应一个可独立验证的行为变化,或一个明确的非行为改动
178
- - 多个行为变化、入口或运行时模块不能形成同一个 RED/GREEN 闭环时拆开;需要“顺便”改多个不相邻模块的 task 在 propose 阶段就拆分或补充任务,不留到 apply 阶段扩大范围
179
+ - 多个行为变化、入口或运行时模块不能形成同一个独立验证边界时拆开;需要“顺便”改多个不相邻模块的 task 在 propose 阶段就拆分或补充任务,不留到 apply 阶段扩大范围
179
180
  - 任务按可执行顺序排列:引擎忽略标题、按全文顶格 checkbox 行的先后顺序逐个驱动执行,被依赖的任务必须排在依赖它的任务之前,跨组同样如此(顺序与分组冲突时调整任务归组或拆组);跨组依赖可在任务行内注明依赖的 task id 作为提示,但注明不改变执行顺序
180
181
 
181
182
  ### test-contract.md
@@ -213,7 +214,7 @@ discovery 含 `## 链路五要素` 时,`proposal.md` `## Impact` 中引用的
213
214
 
214
215
  每个确认项只含一个决策点,带稳定 ID `DEC-xxx`:决策类写明影响面(引用相关 `CHAIN-xxx` / `IDC-xxx`)、候选项及后果、建议默认值及理由;事实类写明需要用户提供什么信息、为什么阻塞。选项和补充说明用普通文本或普通 bullet,不要写成 `- [ ]`,引擎会把它们计为未确认项。
215
216
 
216
- `next` 会在 propose 阶段检查 `proposal.md`、`design.md` 和 `test-contract.md` 的该段落。存在未确认项时,汇总一次向用户提问(按影响排序并说明问题间依赖,不逐个往返);收到回答后用驱动方式中的 `record user-decision` 命令登记,JSON 经 stdin 传入(scope 建议引用 `DEC-xxx`,一条决策可列多个 ID;此为留痕约定,引擎不校验格式)。
217
+ `next` 会在计划材料中检查该段落。存在未确认项时,汇总一次向用户提问(按影响排序并说明问题间依赖,不逐个往返);收到回答后按当前输出给出的 `record user-decision` 格式登记,JSON 经 stdin 传入(scope 建议引用 `DEC-xxx`,一条决策可列多个 ID;此为留痕约定,引擎不校验格式)。
217
218
 
218
219
  答案来自用户时,先登记再勾选;答案来自需求文档、代码证据等外部事实核对时,行内写明证据来源,不伪造用户决策。用户回答含糊、与候选项不匹配或引出新问题时,不视为已确认;复述理解并获得明确答复后再登记。把结论反映到 proposal/design/test-contract 相关内容,勾选行内注明结论要点;确认项作废或重复时改为 `[x]` 并注明理由,不要删除确认项。局部实现细节、命名、普通文件组织和不影响需求/验收/风险的技术微调不要升级为用户确认。
219
220
 
@@ -225,13 +226,12 @@ discovery 含 `## 链路五要素` 时,`proposal.md` `## Impact` 中引用的
225
226
 
226
227
  ## 完成条件
227
228
 
228
- tasks.md 作为计划文档就绪(不是复选框全完成)+ 基础职责文档齐全 → next 返回 propose-ready 命令。
229
+ 计划材料准备好后重新运行 `next`;由它决定是否需要确认、审查或可以继续。
229
230
 
230
231
  ## Guardrails
231
232
 
232
233
  - 只产出计划文档,不改业务代码、不做实现
233
234
  - 不绕过 `## 待用户确认` 中的未确认项
234
- - tdd_required 标注真实
235
- - 不跳过 transition
235
+ - 不手写流程推进结果;只执行 `next` 当前返回的动作。
236
236
  - 不跳过完整审查路径下的审核工作项
237
237
  - 审查通过后、推进前不做非必要的文档编辑;计划材料变更会按当前审查模式和角色职责触发必要的复审。