kld-sdd 2.5.2 → 2.6.1
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.
- package/README.md +33 -10
- package/lib/init.js +11 -1
- package/package.json +3 -2
- package/skywalk-sdd/context-client.cjs +160 -0
- package/skywalk-sdd/index.cjs +118 -14
- package/skywalk-sdd/ontology/archive-package.cjs +489 -0
- package/skywalk-sdd/ontology/id.cjs +16 -19
- package/skywalk-sdd/ontology/identity-index.cjs +25 -0
- package/skywalk-sdd/ontology/runtime.cjs +179 -54
- package/skywalk-sdd/ontology/working-artifacts.cjs +243 -0
- package/templates/openspec/proposal.md +1 -1
- package/templates/skills/kld-sdd/opsx-apply/SKILL.md +27 -4
- package/templates/skills/kld-sdd/opsx-apply/checklist.md +29 -1
- package/templates/skills/kld-sdd/opsx-apply/implementer-prompt.md +54 -3
- package/templates/skills/kld-sdd/opsx-apply/reference.md +26 -0
- package/templates/skills/kld-sdd/opsx-archive/SKILL.md +10 -1
- package/templates/skills/kld-sdd/opsx-archive/checklist.md +5 -1
- package/templates/skills/kld-sdd/opsx-check/SKILL.md +21 -4
- package/templates/skills/kld-sdd/opsx-check/checklist.md +19 -1
- package/templates/skills/kld-sdd/opsx-design/SKILL.md +2 -0
- package/templates/skills/kld-sdd/opsx-propose/SKILL.md +2 -0
- package/templates/skills/kld-sdd/opsx-propose/checklist.md +2 -0
- package/templates/skills/kld-sdd/opsx-propose/reference.md +6 -4
- package/templates/skills/kld-sdd/opsx-spec/SKILL.md +23 -0
- package/templates/skills/kld-sdd/opsx-spec/checklist.md +5 -0
- package/templates/skills/kld-sdd/opsx-task/SKILL.md +43 -8
- package/templates/skills/kld-sdd/opsx-task/checklist.md +15 -0
- package/templates/skills/kld-sdd/opsx-task/reference.md +73 -2
- package/templates/skills/kld-sdd/opsx-test/SKILL.md +17 -0
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
在派发实现子代理时使用此模板。每个 DAG 任务由一个独立子代理执行。
|
|
4
4
|
|
|
5
|
+
## TDD 铁律(当 test-strategy=tdd 时生效)
|
|
6
|
+
|
|
7
|
+
**NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.**
|
|
8
|
+
|
|
9
|
+
- 如果要写生产代码,必须先有一个失败的测试
|
|
10
|
+
- 如果先写了生产代码再写测试:删掉生产代码,从测试开始
|
|
11
|
+
- "太简单不用测" → 如果值得写,就值得测
|
|
12
|
+
- "事后补测一样" → 不一样,TDD 的价值在于测试驱动设计
|
|
13
|
+
- "删了浪费" → 删掉重来比带着错误前提实现更省时间
|
|
14
|
+
|
|
15
|
+
### 执行 测试-RED 任务
|
|
16
|
+
1. 读取对应 spec.md 场景和 design.md 设计
|
|
17
|
+
2. 编写测试代码:Given-When-Then 结构 + 真实断言
|
|
18
|
+
3. 运行测试:`mvn test -Dtest=XxxTest#testMethodName`(或项目对应命令)
|
|
19
|
+
4. 确认测试失败:失败原因必须是"功能未实现"(如 NullPointerException、AssertionError)
|
|
20
|
+
5. 如果测试通过:说明测试无效或功能已存在,重新编写测试
|
|
21
|
+
6. 记录失败原因到任务状态
|
|
22
|
+
|
|
23
|
+
**⛔ RED 测试质量标准(Mock 边界,不 Mock 行为):**
|
|
24
|
+
|
|
25
|
+
- **禁止 mock 被测行为本身**:测试的 Given 应准备**真实的前置条件**(如真实的 invalid token 字符串),让被测代码自然走完链路;而非直接 mock 出期望的中间结果
|
|
26
|
+
- ❌ `when(jwtUtil.parseToken("invalid")).thenThrow(...)` — mock 了被测行为(解析失败),GREEN 只需加 try-catch 就通过,测试无意义
|
|
27
|
+
- ✅ 使用真实 JwtUtil + 真实 invalid token 字符串,让解析自然失败,测试验证完整链路
|
|
28
|
+
- **Mock 仅用于系统边界依赖**:数据库 Mapper、HTTP 客户端、消息队列等外部依赖可 mock;但被测类自身的业务逻辑、实现被测行为的工具类不可 mock
|
|
29
|
+
- ✅ Mock `BookMapper.countByPublisher()` — 数据库边界,需要真实 DB 环境才能验证
|
|
30
|
+
- ❌ Mock `JwtUtil.parseToken()` — 这是被测行为的实现,mock 它等于跳过了被测逻辑
|
|
31
|
+
- **RED 测试的 Given 必须是真实输入**:传入真实的数据(如 `"invalid"` 字符串、`null`、空对象),让被测代码自行处理;不能 mock 出"这个输入会导致什么结果"
|
|
32
|
+
- **判断标准**:如果删掉被测类的实现(方法体清空),测试是否仍然因为 mock 而通过?如果是,说明测试是假的——真实测试应该在实现缺失时失败
|
|
33
|
+
|
|
34
|
+
### 执行 实现-GREEN 任务
|
|
35
|
+
1. 读取对应 RED 任务的失败原因
|
|
36
|
+
2. 编写**最少代码**让该测试通过
|
|
37
|
+
3. 不提前实现没有测试要求的功能(YAGNI)
|
|
38
|
+
4. **⛔ 禁止捆绑未测试的代码**:
|
|
39
|
+
- 如果 RED 测试只测了 Service 方法,GREEN 不得同时实现 Controller 接口
|
|
40
|
+
- 如果 RED 测试只测了一个行为点,GREEN 不得同时实现其他行为点的逻辑
|
|
41
|
+
- 如果需要修改多个文件才能让测试通过,检查是否测试范围过大
|
|
42
|
+
5. 运行测试:确认通过
|
|
43
|
+
6. 如果引入了新功能但无对应测试:删除多余代码
|
|
44
|
+
7. 自检:本次修改的文件列表是否与 RED 测试覆盖的范围一致?如果超出,报告 DONE_WITH_CONCERNS
|
|
45
|
+
|
|
46
|
+
### 执行 重构-REFACTOR 任务
|
|
47
|
+
1. 在所有测试通过的状态下开始
|
|
48
|
+
2. 优化代码结构(提取方法、消除重复、改善命名)
|
|
49
|
+
3. 运行**全部测试**:`mvn test`(或项目对应命令)
|
|
50
|
+
4. 确认所有测试仍通过
|
|
51
|
+
5. 如果任何测试失败:回退重构,重新尝试
|
|
52
|
+
|
|
5
53
|
## 派发格式
|
|
6
54
|
|
|
7
55
|
```
|
|
@@ -13,7 +61,7 @@ Agent (general-purpose):
|
|
|
13
61
|
## 当前任务
|
|
14
62
|
|
|
15
63
|
[TASK-ID]: [完整任务描述,从 tasks.md 中提取]
|
|
16
|
-
- 类型: [
|
|
64
|
+
- 类型: [数据层/接口层/UI层/测试-RED/实现-GREEN/重构-REFACTOR/测试-验证/配置]
|
|
17
65
|
- 依赖: [前置任务列表] ✅ 已完成
|
|
18
66
|
- 层级: [N]
|
|
19
67
|
|
|
@@ -50,8 +98,11 @@ Agent (general-purpose):
|
|
|
50
98
|
2. 遵循 design.md 的设计约定
|
|
51
99
|
3. 遵循 overview.md 的全局规范
|
|
52
100
|
4. 保持变更最小化,不超出任务范围
|
|
53
|
-
5.
|
|
54
|
-
6.
|
|
101
|
+
5. **当任务类型为 测试-RED 时**:编写带真实断言的测试,运行并确认失败,记录失败原因
|
|
102
|
+
6. **当任务类型为 实现-GREEN 时**:读取对应 RED 的失败原因,写最少代码让测试通过,不提前实现未要求的功能
|
|
103
|
+
7. **当任务类型为 重构-REFACTOR 时**:在测试全绿状态下优化代码,运行全部测试确认仍绿
|
|
104
|
+
8. 自我审查(见下方)
|
|
105
|
+
9. 报告结果
|
|
55
106
|
|
|
56
107
|
工作目录:[项目根目录]
|
|
57
108
|
|
|
@@ -370,6 +370,32 @@ node skywalk-sdd/log.cjs record --type=ai_adoption_review --command=apply --proj
|
|
|
370
370
|
|
|
371
371
|
---
|
|
372
372
|
|
|
373
|
+
## §6.0a 测试反模式检查(TDD 模式下,RED 阶段 + GREEN 完成后双重检查)
|
|
374
|
+
|
|
375
|
+
> ⛔ **RED 阶段就必须检查**:不要等到 GREEN 之后才发现测试是假的。RED 写完立即自检,发现反模式立即重写。
|
|
376
|
+
|
|
377
|
+
### RED 阶段强制检查(写完测试、运行确认失败后)
|
|
378
|
+
|
|
379
|
+
| 反模式 | 表现 | 修复方案 |
|
|
380
|
+
|--------|------|---------|
|
|
381
|
+
| **Mock 被测行为本身** | `when(jwtUtil.parseToken("invalid")).thenThrow(...)` — mock 了被测行为(解析失败),GREEN 只需加 try-catch | 使用真实 JwtUtil + 真实 invalid token,让解析自然失败 |
|
|
382
|
+
| **Mock 预定结论而非准备条件** | `when(bookMapper.countByPublisher(1L)).thenReturn(3)` 后只测 `if (count > 0) throw` — trivial 逻辑 | Mock 边界依赖(Mapper)是合理的,但测试断言应验证完整行为链路(如 verify 不会执行 delete) |
|
|
383
|
+
| **Given 不是真实输入** | mock 出"这个输入会导致什么结果",而非传入真实数据让被测代码自行处理 | 传入真实数据(如 `"invalid"` 字符串、`null`),让被测代码自行决定结果 |
|
|
384
|
+
|
|
385
|
+
### GREEN 完成后补充检查
|
|
386
|
+
|
|
387
|
+
| 反模式 | 表现 | 修复方案 |
|
|
388
|
+
|--------|------|---------|
|
|
389
|
+
| 测试 mock 行为而非真实行为 | 测试验证的是 mock 被调用,而非真实业务逻辑 | 测试应验证输出/状态变化,而非方法调用 |
|
|
390
|
+
| 生产类中加测试专用方法 | 为方便测试在生产类中加了 public/protected 方法 | 通过公共 API 测试,不加测试专用方法 |
|
|
391
|
+
| 不理解依赖就 mock | mock 了不理解的依赖,隐藏了结构假设 | 先理解依赖的职责再决定是否 mock |
|
|
392
|
+
| 不完整的 mock | partial mock 隐藏了对象间的结构关系 | 要么完整 mock,要么用真实对象 |
|
|
393
|
+
| 集成测试作为事后补充 | 单元测试不足,用集成测试弥补 | 每个行为点应有独立的单元测试 |
|
|
394
|
+
|
|
395
|
+
> 参照来源:`skill-references/superpowers-tdd/testing-anti-patterns.md`
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
373
399
|
## §6.1 Worktree 收尾(仅当 §1.5 已创建 worktree)
|
|
374
400
|
|
|
375
401
|
> **⛔ 本次 Apply 若创建了 worktree**:DAG 全部完成且 **§6.0 测试门禁(若适用)** 通过后,必须在**主仓库根目录**执行收尾脚本(禁止在 `.worktrees/...` 内执行)。
|
|
@@ -107,7 +107,8 @@ node skywalk-sdd/log.cjs archive-docs --project=. --change=<变更名称> --reas
|
|
|
107
107
|
|
|
108
108
|
该命令成功后必须已经完成:
|
|
109
109
|
- 活动目录 `openspec/changes/<name>/` 被移入 `openspec/changes/archive/<日期>-<name>/`。
|
|
110
|
-
- 归档目录写入 `archive-manifest.json`。
|
|
110
|
+
- 归档目录写入 `archive-ontology.json`、`canonical-facts.json`、`conversion-report.json` 和新版 `archive-manifest.json`。
|
|
111
|
+
- 生成知识库可直接消费的 `openspec/changes/archive/<日期>-<name>.zip`,包内文件必须由 manifest 完整列举并通过 SHA-256 校验。
|
|
111
112
|
- Full Spec 的 `specs/<capability>/spec.md` 同步到 `openspec/specs/<capability>/spec.md`。
|
|
112
113
|
- archive 阶段写入 `stage_end`。
|
|
113
114
|
- 未勾选 tasks 被写入 `archive_result.task_completion`。
|
|
@@ -132,6 +133,8 @@ node skywalk-sdd/log.cjs end --event-id=<event_id> --command=archive --project=.
|
|
|
132
133
|
> - 归档目录:`openspec/changes/archive/<日期>-<name>/`
|
|
133
134
|
> - 最终报告(默认同时生成 .md + .html):`openspec/changes/archive/<日期>-<name>/reports/<name>-report.md`、`openspec/changes/archive/<日期>-<name>/reports/<name>-report.html`
|
|
134
135
|
> - 执行日志:`openspec/changes/archive/<日期>-<name>/logs/execution-log.md`
|
|
136
|
+
> - 知识库归档包:`openspec/changes/archive/<日期>-<name>.zip`
|
|
137
|
+
> - 本体消费入口:`openspec/changes/archive/<日期>-<name>/canonical-facts.json`
|
|
135
138
|
> - 未勾选任务:X 项,已记录到报告,不阻断归档
|
|
136
139
|
> - 正式 specs:`openspec/specs/`
|
|
137
140
|
|
|
@@ -159,7 +162,13 @@ node skywalk-sdd/log.cjs record --type=baseline_record --command=archive --proje
|
|
|
159
162
|
|
|
160
163
|
- 归档前必须运行 `node skywalk-sdd/log.cjs semantic-reconcile --project=. --change=<变更名称>`,不能只信任文件观察事件。
|
|
161
164
|
- 随后必须运行 `node skywalk-sdd/log.cjs semantic-check --project=. --change=<变更名称>`;有阻断诊断时禁止移动活动 Change。
|
|
165
|
+
- Archive 不负责首次生成 propose/spec/design/tasks 的工作态事实;它重新解析原文核对 pending revision,补充 `OntologySnapshot/project_id/archive_id` 后冻结为 confirmed。
|
|
162
166
|
- `archive-docs` 成功后必须在归档目录生成 `archive-ontology.json`,并将 `review_status` 标记为 `confirmed`。
|
|
167
|
+
- 生产端必须把 confirmed 本体转换为 `canonical-facts.json`;实体固定为 `fact_kind=semantic`、`assertion_type=asserted`、`review_status=confirmed`,关系必须补齐对应语义边界字段。
|
|
168
|
+
- `acceptedBy` 在消费协议中归一化为 `verifiedBy`;inferred 关系必须携带 `rule_id`、`generator` 和 `generator_version`。
|
|
169
|
+
- 每个 canonical 实体和关系的 `source.file` 必须存在于 Archive Package,`source.content_hash` 必须等于该原文文件的 SHA-256。
|
|
170
|
+
- `archive-manifest.json` 必须使用 `kld-sdd-archive-manifest/v2`,并与 canonical facts 的 project/archive/change 身份一致。
|
|
171
|
+
- `conversion-report.json` 必须记录源/目标 schema、转换状态、实体数、关系数和归一化告警。
|
|
163
172
|
- Archive 快照必须固化人工锚点、逻辑实体 UUID、版本 UUID、前序版本 UUID、delta-state 和内容哈希;任一 UUID 冲突或谱系断裂都不得 confirmed。
|
|
164
173
|
- 归档目录已经复制但语义快照失败时,不得删除活动 Change,不得标记 confirmed。
|
|
165
174
|
- unchanged 正文保留在前序 Archive;当前归档只固化差量事实、继承引用和来源锚点。
|
|
@@ -18,7 +18,11 @@ description: "opsx-archive 前后日志/总结自检清单 — 仅在 archive
|
|
|
18
18
|
## B. 归档后自检
|
|
19
19
|
|
|
20
20
|
- [ ] 归档目录 `openspec/changes/archive/<日期>-<变更名称>/` 存在
|
|
21
|
-
- [ ] `openspec/changes/archive
|
|
21
|
+
- [ ] `openspec/changes/archive/<日期>-<变更名称>/` 下 `archive-ontology.json`、`canonical-facts.json`、`conversion-report.json` 和 `archive-manifest.json` 均存在
|
|
22
|
+
- [ ] 活动 change 目录下的 `artifacts/*.ontology.json` 与 `artifact-index.json` 已随归档目录一并迁移
|
|
23
|
+
- [ ] `archive-manifest.json` 为 `kld-sdd-archive-manifest/v2`,且 `files` 精确覆盖 ZIP 内除 manifest 自身外的全部文件
|
|
24
|
+
- [ ] `openspec/changes/archive/<日期>-<变更名称>.zip` 存在并可由知识库 `ArchivePackageReader` 读取
|
|
25
|
+
- [ ] canonical facts 中每个实体/关系均能通过 `source.file`、`source.anchor_id`、`source.content_hash` 定向展开到包内原文
|
|
22
26
|
- [ ] 最终报告 `openspec/changes/archive/<日期>-<变更名称>/reports/<变更名称>-report.md` 存在且含「归档结果」段
|
|
23
27
|
- [ ] `reports/<变更名称>-report.md` 与 `reports/<变更名称>-report.html` 都已生成(md+html 双产物)
|
|
24
28
|
- [ ] html 报告含 `SDD 效果度量报告` 标题与各度量章节(执行摘要/效率/质量/过程/归档结果/说明)
|
|
@@ -33,7 +33,7 @@ allowed-tools:
|
|
|
33
33
|
> - 不要省略 `--source=opsx-command` 与 `--session-id=<会话ID>`。
|
|
34
34
|
> **📊 Telemetry(必做,不得跳过)**
|
|
35
35
|
> - 阶段开始:`node skywalk-sdd/log.cjs start --command=check --project=. --change=<变更名称> --capability=<可选capability-name> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID>`(保存 event_id)
|
|
36
|
-
> - 检查报告生成后,必须先记录结构化检查结果:`node skywalk-sdd/log.cjs record --type=check_result --command=check --project=. --change=<变更名称> --capability=<可选capability-name> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success/partial/failure --summary="检查结果摘要" --details-json="{\"check_results\":{\"total\":0,\"errors\":0,\"warnings\":0,\"warning_items\":[],\"suggestions\":0,\"fixed_before_apply\":0,\"consistency_score\":null,\"categories\":{\"completeness\":{\"passed\":0,\"total\":0},\"consistency\":{\"passed\":0,\"total\":0},\"executability\":{\"passed\":0,\"total\":0}},\"task_completion\":{\"completed\":0,\"incomplete\":0,\"total\":0,\"has_incomplete\":false,\"checked_for_archive_readiness\":false}}}"`
|
|
36
|
+
> - 检查报告生成后,必须先记录结构化检查结果:`node skywalk-sdd/log.cjs record --type=check_result --command=check --project=. --change=<变更名称> --capability=<可选capability-name> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success/partial/failure --summary="检查结果摘要" --details-json="{\"check_results\":{\"total\":0,\"errors\":0,\"warnings\":0,\"warning_items\":[],\"suggestions\":0,\"fixed_before_apply\":0,\"consistency_score\":null,\"categories\":{\"completeness\":{\"passed\":0,\"total\":0},\"consistency\":{\"passed\":0,\"total\":0},\"executability\":{\"passed\":0,\"total\":0},\"tdd_compliance\":{\"passed\":0,\"total\":0}},\"task_completion\":{\"completed\":0,\"incomplete\":0,\"total\":0,\"has_incomplete\":false,\"checked_for_archive_readiness\":false}}}"`
|
|
37
37
|
> - `check_result` 记录成功后,才允许阶段结束:`node skywalk-sdd/log.cjs end --event-id=<event_id> --command=check --project=. --change=<变更名称> --capability=<可选capability-name> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success/partial/failure --summary="摘要"`
|
|
38
38
|
> - **【B1 摘要数字校验】** `stage_end --summary` 中的数字(如「N 个场景」「N 层 DAG」「N 个任务」)必须与 `spec.md`/`tasks.md`/`test-scenarios.md` 的实统计交叉校验一致后再填写,不得凭记忆自填。典型失真:summary 写「11 个场景」实际 spec 含 13 条断言、「5 层 DAG」实际 tasks 修复后为 6 层。check 阶段发现不一致时,修正 summary 或补齐文档,使三者数字自洽。
|
|
39
39
|
|
|
@@ -45,7 +45,7 @@ allowed-tools:
|
|
|
45
45
|
|------|------|
|
|
46
46
|
| 核心问题 | 文档链质量是否达标 |
|
|
47
47
|
| 关键输出 | 检查报告(通过/警告/失败) |
|
|
48
|
-
| 检查维度 |
|
|
48
|
+
| 检查维度 | 完整性、一致性、算法正确性、可执行性、TDD合规性(仅test-strategy=tdd时) |
|
|
49
49
|
| 上游依赖 | proposal → specs → design → tasks 全文档链 |
|
|
50
50
|
|
|
51
51
|
---
|
|
@@ -81,7 +81,7 @@ openspec list
|
|
|
81
81
|
| 代码文件 | 验证 design 可行性、锚点准确性 | 可执行性 |
|
|
82
82
|
| 算法文档 | 验证算法设计正确性 | 算法正确性 |
|
|
83
83
|
|
|
84
|
-
### 4.
|
|
84
|
+
### 4. 执行五维质量检查
|
|
85
85
|
|
|
86
86
|
#### 4.1 完整性检查
|
|
87
87
|
|
|
@@ -111,6 +111,20 @@ openspec list
|
|
|
111
111
|
- [ ] 所有外部依赖已明确状态
|
|
112
112
|
- [ ] 代码锚点存在且可访问
|
|
113
113
|
|
|
114
|
+
#### 4.4a TDD 合规性检查(仅 test-strategy=tdd 时执行)
|
|
115
|
+
|
|
116
|
+
检查项:
|
|
117
|
+
1. RED 任务验收标准是否包含"测试运行失败"(而非"断言为空")
|
|
118
|
+
2. GREEN 任务是否为行为级粒度(一个 GREEN 对应一个 RED,非模块级)
|
|
119
|
+
3. DAG 中是否存在 RED→GREEN 循环对(而非 TEST(全部)→IMPL(全部)批次)
|
|
120
|
+
4. 是否存在 REFACTOR 任务(推荐但不强制)
|
|
121
|
+
5. 非 TDD 模块(前端/配置/SQL)是否正确排除红绿循环
|
|
122
|
+
6. GREEN 任务验收标准是否为"让对应 RED 通过"(而非"实现完整功能")
|
|
123
|
+
7. **GREEN 任务无捆绑**:每个 GREEN 任务的输出不包含未测试的 Controller/Filter/Config
|
|
124
|
+
8. **Controller 层策略已声明**:tasks.md 中明确声明 Controller 层使用策略 A 或策略 B
|
|
125
|
+
9. **RED 任务有测试方法名**:每个 RED 任务包含 `{method}_{state}_{outcome}` 格式的测试方法名
|
|
126
|
+
10. **REFACTOR 有具体方向**:每个 REFACTOR 任务列出至少 2 个具体重构点
|
|
127
|
+
|
|
114
128
|
#### 4.5 任务完成状态检查(实现后 / 归档前)
|
|
115
129
|
|
|
116
130
|
`task` 阶段允许 `tasks.md` 出现未完成项;这只是计划状态。但如果当前变更已经进入 apply 之后,或本次 check 发现实现代码、测试报告、`build_result/test_result/task_update/conformance_review` 等实施证据,必须检查任务勾选状态:
|
|
@@ -135,6 +149,7 @@ node skywalk-sdd/log.cjs tasks-status --project=. --change=<变更名称>
|
|
|
135
149
|
> | 一致性 | ✅/⚠️/❌ | [具体问题] |
|
|
136
150
|
> | 算法正确性 | ✅/⚠️/❌ | [具体问题] |
|
|
137
151
|
> | 可执行性 | ✅/⚠️/❌ | [具体问题] |
|
|
152
|
+
> | TDD合规性 | ✅/⚠️/❌/— | [仅test-strategy=tdd时检查] |
|
|
138
153
|
>
|
|
139
154
|
> **总体结果**:✅ 通过 / ⚠️ 有警告 / ❌ 未通过
|
|
140
155
|
>
|
|
@@ -158,7 +173,7 @@ node skywalk-sdd/log.cjs tasks-status --project=. --change=<变更名称>
|
|
|
158
173
|
|
|
159
174
|
在终端执行(必须成功):
|
|
160
175
|
```bash
|
|
161
|
-
node skywalk-sdd/log.cjs record --type=check_result --command=check --project=. --change=<变更名称> --capability=<可选capability-name> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success/partial/failure --summary="检查结果摘要" --details-json="{\"check_results\":{\"total\":0,\"errors\":0,\"warnings\":0,\"warning_items\":[],\"suggestions\":0,\"fixed_before_apply\":0,\"consistency_score\":null,\"categories\":{\"completeness\":{\"passed\":0,\"total\":0},\"consistency\":{\"passed\":0,\"total\":0},\"executability\":{\"passed\":0,\"total\":0}},\"task_completion\":{\"completed\":0,\"incomplete\":0,\"total\":0,\"has_incomplete\":false,\"checked_for_archive_readiness\":false}}}"
|
|
176
|
+
node skywalk-sdd/log.cjs record --type=check_result --command=check --project=. --change=<变更名称> --capability=<可选capability-name> --agent=<Agent类型> --source=opsx-command --session-id=<会话ID> --result=success/partial/failure --summary="检查结果摘要" --details-json="{\"check_results\":{\"total\":0,\"errors\":0,\"warnings\":0,\"warning_items\":[],\"suggestions\":0,\"fixed_before_apply\":0,\"consistency_score\":null,\"categories\":{\"completeness\":{\"passed\":0,\"total\":0},\"consistency\":{\"passed\":0,\"total\":0},\"executability\":{\"passed\":0,\"total\":0},\"tdd_compliance\":{\"passed\":0,\"total\":0}},\"task_completion\":{\"completed\":0,\"incomplete\":0,\"total\":0,\"has_incomplete\":false,\"checked_for_archive_readiness\":false}}}"
|
|
162
177
|
```
|
|
163
178
|
|
|
164
179
|
> **⚠️ P1-1 check_result details 不得为空**:`--details-json` 必须含 `consistency_score` / `categories` / `task_completion` 等字段,**禁止传空对象 `{}`**。空 details 会导致 report 的 Q5 跨文档一致性得分、P4b 修复率为 null(工具侧虽有 state fallback 兜底,但事件 details 是主数据源)。
|
|
@@ -215,6 +230,8 @@ node skywalk-sdd/log.cjs semantic-check --project=. --change=<变更名称> --pr
|
|
|
215
230
|
- 所有 profile 都必须阻断重复人工锚点、UUID 缺失/非法、跨 Change 或 Archive 的实体 UUID 误复用、版本 UUID 重用、版本谱系断裂、悬空引用、非法 domain/range 和 Task 依赖成环。
|
|
216
231
|
- `added` 必须使用全新实体/版本 UUID;`modified/removed` 必须复用实体 UUID并指向直接前序版本;`unchanged` 必须复用历史实体和版本 UUID且不得复制历史正文。
|
|
217
232
|
- 文件观察结果只能作为快速上下文,check 必须重新全量 semantic-reconcile。
|
|
233
|
+
- propose/spec/design/task 对应工作态 JSON 应已在各作者阶段生成;check 不负责首次生成业务事实,只重新解析 Markdown、核对各 JSON 与同一 revision,并在全部通过时把派生 revision 更新为 `review_status=pending`。
|
|
234
|
+
- Check 只读是指不修改 proposal/spec/design/tasks 原文;允许原子刷新 `openspec/changes/<变更名称>/` 下可再生的 `working-ontology.json`、`artifact-index.json` 与 `artifacts/*.ontology.json`。
|
|
218
235
|
|
|
219
236
|
## Guardrails
|
|
220
237
|
|
|
@@ -33,5 +33,23 @@ description: "opsx-check 阶段日志自检清单 — 仅在 check 自检时读
|
|
|
33
33
|
|
|
34
34
|
## D. 检查报告四维
|
|
35
35
|
|
|
36
|
-
- [ ]
|
|
36
|
+
- [ ] 完整性、一致性、算法正确性、可执行性、TDD合规性(仅test-strategy=tdd时)五维均已输出
|
|
37
37
|
- [ ] 报告问题对应修复建议(spec/design/task)
|
|
38
|
+
|
|
39
|
+
## E. TDD 合规性检查(仅 test-strategy=tdd 时)
|
|
40
|
+
|
|
41
|
+
- [ ] tasks.md 中 测试-RED 任务的验收标准包含"测试运行失败"
|
|
42
|
+
- [ ] tasks.md 中无"断言为空"或"编译通过但断言为空"的验收标准
|
|
43
|
+
- [ ] tasks.md 中 实现-GREEN 任务为行为级粒度(一对一对应 RED)
|
|
44
|
+
- [ ] tasks.md 中 DAG 存在 RED→GREEN 循环对
|
|
45
|
+
- [ ] tasks.md 中非 TDD 模块未拆红绿循环
|
|
46
|
+
- [ ] tasks.md 中 GREEN 任务的输出不包含未测试的 Controller/Filter/Config
|
|
47
|
+
- [ ] tasks.md 中已声明 Controller 层处理策略(策略 A 或策略 B)
|
|
48
|
+
- [ ] tasks.md 中每个 RED 任务包含测试方法名
|
|
49
|
+
- [ ] tasks.md 中每个 REFACTOR 任务列出至少 2 个具体重构点
|
|
50
|
+
- [ ] check_result 的 categories 中包含 `tdd_compliance`
|
|
51
|
+
|
|
52
|
+
## F. 语义门禁与工作态
|
|
53
|
+
|
|
54
|
+
- [ ] `openspec/changes/<变更名称>/artifact-index.json` 已覆盖当前全部 proposal/spec/design/tasks,且每份 `artifacts/*.ontology.json` 与 `working-ontology.json` revision 一致
|
|
55
|
+
- [ ] 全部语义门禁通过时工作态 JSON 已从 draft 刷新为 pending;check 未修改任何 Markdown 原文
|
|
@@ -172,6 +172,8 @@ design.md 中若使用 version 正则约束(如格式校验 `^\d+\.\d+\.\d+$`
|
|
|
172
172
|
- 每个 DES 必须通过 `**realizes**: STMT-*` 显式引用一个或多个真实 STMT。
|
|
173
173
|
- 不得仅凭文本相似创建 realizes;没有上游 STMT 时必须标记 unresolved。
|
|
174
174
|
- 生成结束后必须运行 `node skywalk-sdd/log.cjs semantic-reconcile --project=. --change=<name>`。
|
|
175
|
+
- reconcile 必须立即生成 `openspec/changes/<name>/artifacts/.../design.ontology.json`,其中 DES 和 realizes 关系保留原文 source;不得推迟到 check/archive。
|
|
176
|
+
- 阶段 `stage_end` 会在无 Hook 环境下幂等执行同步兜底。
|
|
175
177
|
|
|
176
178
|
## Guardrails
|
|
177
179
|
|
|
@@ -211,6 +211,8 @@ openspec instructions proposal --change "<name>" --json
|
|
|
211
211
|
- 每个 Change/Capability 同时写人工锚点、`entity-id`、`version-id` 和 `delta-state`。新增时必须调用 `node skywalk-sdd/log.cjs semantic-identity --delta-state=added`,不得手写或复制 UUID。
|
|
212
212
|
- 修改既有 Capability 时调用 `semantic-identity --delta-state=modified --entity-id=<历史实体UUID> --predecessor-version=<直接前序版本UUID>`;复用实体 UUID,但必须生成新版本 UUID。
|
|
213
213
|
- 本阶段只声明 Change 和 Capability,不得提前生成 STMT、AC、DES 或 TASK 事实。
|
|
214
|
+
- proposal.md 写入结束后必须立即运行 `node skywalk-sdd/log.cjs semantic-reconcile --project=. --change=<name>`,生成 `openspec/changes/<name>/artifacts/proposal.ontology.json`;不得等到 check 或 archive 才首次生成 JSON。
|
|
215
|
+
- 阶段 `stage_end` 会在无 Hook 环境下幂等执行同一次同步作为兜底,结果中的 `semantic_state.artifact_json_paths` 必须包含 proposal 对应 JSON。
|
|
214
216
|
|
|
215
217
|
## Guardrails
|
|
216
218
|
|
|
@@ -39,6 +39,8 @@ description: opsx-propose 的阶段强制检查点与自检清单。仅在执行
|
|
|
39
39
|
- [ ] Capabilities 章节是关键:决定后续 specs 文件夹结构
|
|
40
40
|
- [ ] 若跳过此文档,后续 specs 必须补齐影响范围
|
|
41
41
|
- [ ] 文档写入后验证文件确实存在
|
|
42
|
+
- [ ] proposal.md 写入后已运行 `semantic-reconcile`,`openspec/changes/<变更名称>/artifacts/proposal.ontology.json` 已存在
|
|
43
|
+
- [ ] 工作态 JSON 为 `canonical=false`、`review_status=draft`,实体能够通过 `source.file/source.anchor_id/source.content_hash` 展开到 proposal.md 原文
|
|
42
44
|
- [ ] 每次生成都提供文档摘要,等待用户确认后再继续
|
|
43
45
|
- [ ] ⛔ **阶段边界**:本阶段禁止执行任何代码创建/修改操作;用户要求处理代码时回复「当前处于 Propose 阶段,代码操作请在完成文档后使用 `/opsx-apply` 执行。」
|
|
44
46
|
- [ ] ⛔ **单阶段原则**:完成 proposal.md 后必须立即停止;仅提示用户下一步可运行 `/opsx-spec`,绝对禁止自动执行 spec/design/task 等后续阶段。每个阶段必须由用户主动触发。
|
|
@@ -56,10 +56,12 @@ description: opsx-propose 的详细模板:telemetry 命令、文档拆分模
|
|
|
56
56
|
|
|
57
57
|
> "🧪 **请选择测试策略:**
|
|
58
58
|
>
|
|
59
|
-
> **A) 测试驱动 (TDD)** -
|
|
60
|
-
> -
|
|
61
|
-
> - DAG:
|
|
62
|
-
> -
|
|
59
|
+
> **A) 测试驱动 (TDD)** - 红绿重构循环
|
|
60
|
+
> - 每个行为点先写失败测试(红),再写最少代码让它通过(绿),最后重构
|
|
61
|
+
> - DAG: RED → GREEN → REFACTOR → RED → GREEN → ...(行为级小步循环)
|
|
62
|
+
> - 任务数量较多(每个行为点一对红绿),但每个测试都真实驱动实现
|
|
63
|
+
> - 适合:核心业务逻辑、质量要求高、需要测试驱动设计
|
|
64
|
+
> - ⚠️ 注意:TDD 模式下任务数量会显著增加(约为模块级拆分的 3-5 倍)
|
|
63
65
|
>
|
|
64
66
|
> **B) 实现优先 (Impl-First)** - 代码先行
|
|
65
67
|
> - 先生成实现任务,测试作为验证步骤
|
|
@@ -107,6 +107,22 @@ openspec list
|
|
|
107
107
|
|
|
108
108
|
> 上下文类型(需求文档 / 代码文件 / API 文档)与用途见 `./reference.md`「§3 上下文类型与用途」。
|
|
109
109
|
|
|
110
|
+
**【默认尝试】工程 Spec 知识库上下文**:
|
|
111
|
+
|
|
112
|
+
从用户输入、proposal.md 中当前 Capability 的名称、业务目标、边界和约束组成一段自然语言查询。不要要求用户提供 `entity_id`。执行:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
node skywalk-sdd/context-client.cjs --query="<当前 Capability 的自然语言需求>" --target-stage=spec
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- 配置项:`ENGINEERING_KB_API`、`ENGINEERING_KB_SPACE_ID`、可选 `ENGINEERING_KB_TOKEN`。
|
|
119
|
+
- 若返回 `available=false` 或 `degraded=true`,记录降级原因并继续 Spec 流程,不得阻塞。
|
|
120
|
+
- 优先消费 `reuseBundles[].statements` 中的历史 STMT、AC、Constraint;`designElements` 只能作为理解上下文,不能写成 Spec 的 How。
|
|
121
|
+
- `answeredQuestions` 表示历史事实已经覆盖的内容,不要对用户重复提问。
|
|
122
|
+
- 只向用户询问 `clarificationQuestions` 中仍与当前 Capability 有关的问题。
|
|
123
|
+
- `reuseMode=REFERENCE` 只能参考复用,不得复制历史 UUID;只有 `reuseMode=INHERIT` 才允许按本体语义生成契约复用历史身份。
|
|
124
|
+
- 所有知识库内容均为 advisory;若与用户输入、proposal.md 或用户确认冲突,以当前用户确认和 proposal.md 为准。
|
|
125
|
+
|
|
110
126
|
**【可选】业务知识库检索**:
|
|
111
127
|
术语含义不清且可能影响 spec 准确性时,可调用 **opsx-knowledge** skill。
|
|
112
128
|
知识库结果仅供参考,spec 契约以用户确认和 proposal 为准;失败时不阻塞。
|
|
@@ -131,6 +147,9 @@ openspec list
|
|
|
131
147
|
|
|
132
148
|
第 3 层:当前 Capability 上下文
|
|
133
149
|
→ 已有的 spec.md(若为增量修改)
|
|
150
|
+
|
|
151
|
+
第 4 层:工程知识库 Spec Context Package
|
|
152
|
+
→ reuseBundles / answeredQuestions / clarificationQuestions
|
|
134
153
|
```
|
|
135
154
|
|
|
136
155
|
### 6. 创建 spec.md
|
|
@@ -184,8 +203,12 @@ openspec list
|
|
|
184
203
|
- `added` 必须调用 `semantic-identity --delta-state=added` 生成新的实体 UUID 和版本 UUID;禁止通过复制另一需求的 UUID 创建新实体。
|
|
185
204
|
- `modified/removed` 必须从 Archive 读取历史 `entity-id` 和直接前序 `version-id`,调用 `semantic-identity --delta-state=<modified|removed> --entity-id=<UUID> --predecessor-version=<UUID>`;实体 UUID 复用,版本 UUID 新建。
|
|
186
205
|
- AC 必须嵌套在所属 STMT 下;CON 必须通过 `**constrains**` 显式引用 STMT。
|
|
206
|
+
- 对 `reuseMode=REFERENCE` 的历史候选必须创建新的实体身份;禁止因为内容相似而复用历史 `entity-id`。
|
|
207
|
+
- 对 `reuseMode=INHERIT` 的历史事实,必须使用返回的实体与版本来源完成 unchanged/modified 身份参数校验。
|
|
187
208
|
- unchanged 内容只写人工锚点、历史实体 UUID、历史版本 UUID 和来源引用,不复制历史原文;调用 `semantic-identity --delta-state=unchanged --entity-id=<UUID> --version-id=<UUID>` 校验复用参数,引用断链时保持 unresolved 并交由 check 阻断。
|
|
188
209
|
- 生成结束后必须运行 `node skywalk-sdd/log.cjs semantic-reconcile --project=. --change=<name>`,根据诊断修复缺号、重号和悬空引用。
|
|
210
|
+
- reconcile 必须在 change 目录生成 `openspec/changes/<name>/artifacts/spec.ontology.json` 或 `openspec/changes/<name>/artifacts/specs/<capability>/spec.ontology.json`;该 JSON 是 draft 工作事实,不得等待 check/archive 才生成。
|
|
211
|
+
- 阶段 `stage_end` 会在无 Hook 环境下幂等执行同步兜底,并返回 `semantic_state.artifact_json_paths`。
|
|
189
212
|
|
|
190
213
|
## Guardrails
|
|
191
214
|
|
|
@@ -17,6 +17,7 @@ description: opsx-spec 的阶段强制检查点与自检清单。仅在执行 sp
|
|
|
17
17
|
- [ ] 即使用户提供代码作为上下文,只用于分析现有实现,不执行任何代码操作
|
|
18
18
|
- [ ] 代码实现将在 `/opsx-apply` 阶段进行
|
|
19
19
|
- [ ] ⛔ 完成本阶段后绝对禁止自动继续执行 design/task 等后续阶段
|
|
20
|
+
- [ ] 工程知识库未配置、超时或降级时继续 Spec 主流程,不阻塞本地创作
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
@@ -30,6 +31,9 @@ description: opsx-spec 的阶段强制检查点与自检清单。仅在执行 sp
|
|
|
30
31
|
- [ ] 技术契约章节完整(数据模型、接口契约)
|
|
31
32
|
- [ ] 文档末尾包含质量红线检查清单
|
|
32
33
|
- [ ] 100% 覆盖 proposal.md 中该 Capability 的描述
|
|
34
|
+
- [ ] 已消费工程知识库 `answeredQuestions`,没有重复询问历史事实已经回答的问题
|
|
35
|
+
- [ ] 仅将 `reuseMode=INHERIT` 的事实作为身份继承;`REFERENCE` 候选使用新实体身份
|
|
36
|
+
- [ ] 已处理与当前 Capability 有关的 `clarificationQuestions`
|
|
33
37
|
|
|
34
38
|
**如有任意一项未满足,重新生成对应章节,直至全部通过。** 自检完成后必须输出结构化自检报告(模板见 `./reference.md`「§7 质量自检报告模板」),未通过项自动修复后重新输出。
|
|
35
39
|
|
|
@@ -42,5 +46,6 @@ description: opsx-spec 的阶段强制检查点与自检清单。仅在执行 sp
|
|
|
42
46
|
- [ ] **需求项格式必须正确**:`####` 需求项、`#####` 场景
|
|
43
47
|
- [ ] 每个需求项必须有清晰的验收标准
|
|
44
48
|
- [ ] 技术契约必须可执行、无歧义
|
|
49
|
+
- [ ] 工程知识库结果只作为 advisory 上下文,不覆盖用户输入或 proposal.md
|
|
45
50
|
- [ ] ⛔ **阶段边界**:禁止执行任何代码创建/修改操作
|
|
46
51
|
- [ ] ⛔ **单阶段原则**:完成 spec.md 后必须立即停止;仅提示用户下一步可运行 `/opsx-design`,绝对禁止自动执行 design/task 等后续阶段。每个阶段必须由用户主动触发。
|
|
@@ -133,7 +133,7 @@ Simple 模式或单文件能力域下,**不要拆成多个同文件任务**。
|
|
|
133
133
|
**若已设置**:向用户确认
|
|
134
134
|
> "🧪 **当前测试策略:[test-strategy]**
|
|
135
135
|
>
|
|
136
|
-
> - `tdd`:
|
|
136
|
+
> - `tdd`: 红绿重构循环 - 每个行为点先写失败测试(红),再写最少代码让它通过(绿),最后重构
|
|
137
137
|
> - `impl-first`: 实现优先 - 先实现后测试
|
|
138
138
|
> - `none`: 无测试 - 不生成测试任务
|
|
139
139
|
>
|
|
@@ -142,10 +142,12 @@ Simple 模式或单文件能力域下,**不要拆成多个同文件任务**。
|
|
|
142
142
|
**若未设置**:使用 **AskUserQuestion** 工具询问
|
|
143
143
|
> "🧪 **未检测到测试策略配置,请选择:**
|
|
144
144
|
>
|
|
145
|
-
> **A) 测试驱动 (TDD)** -
|
|
146
|
-
> -
|
|
147
|
-
> - DAG
|
|
148
|
-
> -
|
|
145
|
+
> **A) 测试驱动 (TDD)** - 红绿重构循环
|
|
146
|
+
> - 每个行为点先写失败测试(红),再写最少代码让它通过(绿),最后重构
|
|
147
|
+
> - DAG 顺序:RED → GREEN → REFACTOR → RED → GREEN → ...(行为级小步循环)
|
|
148
|
+
> - 任务数量较多(每个行为点一对红绿),但每个测试都真实驱动实现
|
|
149
|
+
> - 适合:核心业务逻辑、质量要求高、需要测试驱动设计
|
|
150
|
+
> - ⚠️ 注意:TDD 模式下任务数量会显著增加(约为模块级拆分的 3-5 倍)
|
|
149
151
|
>
|
|
150
152
|
> **B) 实现优先 (Impl-First)** - 代码先行
|
|
151
153
|
> - 先生成实现任务,测试作为验证步骤
|
|
@@ -162,6 +164,16 @@ Simple 模式或单文件能力域下,**不要拆成多个同文件任务**。
|
|
|
162
164
|
|
|
163
165
|
向用户确认拆解维度、任务粒度、预计 DAG 层级。**根据 test-strategy 调整 DAG 生成规则**,规则表(tdd / impl-first / none 对应的 DAG 生成规则)见 `./reference.md`「§6 DAG 生成规则表」。
|
|
164
166
|
|
|
167
|
+
**当 test-strategy=tdd 时,必须向用户说明:**
|
|
168
|
+
> "🧪 TDD 模式将采用红绿重构循环:
|
|
169
|
+
> - 每个行为点拆为一对 RED+GREEN 任务(+可选 REFACTOR)
|
|
170
|
+
> - 任务数量会比模块级拆分更多,但每个测试都真实驱动一段实现
|
|
171
|
+
> - RED 任务验收标准:测试运行失败,且失败原因正确(功能未实现)
|
|
172
|
+
> - GREEN 任务验收标准:写最少代码让对应 RED 测试通过
|
|
173
|
+
> - 非 TDD 模块(前端 UI、配置、SQL DDL)不拆红绿,按常规任务处理
|
|
174
|
+
>
|
|
175
|
+
> 是否继续使用 TDD 策略?"
|
|
176
|
+
|
|
165
177
|
### 7. 创建局部 tasks.md(含 DAG 拓扑)
|
|
166
178
|
|
|
167
179
|
**输出路径**:`changes/<name>/specs/<capability>/tasks.md`
|
|
@@ -170,9 +182,30 @@ Simple 模式或单文件能力域下,**不要拆成多个同文件任务**。
|
|
|
170
182
|
|
|
171
183
|
> **必须包含**:任务执行拓扑图(DAG)+ 原子任务清单。任务结构字段(TASK-ID / 类型 / 依赖 / 状态 / 描述等)见 `./reference.md`「§7 任务结构」。
|
|
172
184
|
|
|
185
|
+
**当 test-strategy=tdd 时,任务生成规则:**
|
|
186
|
+
1. 将 spec.md 中每个需求项的每个场景拆为一个行为点
|
|
187
|
+
2. 每个行为点生成一对任务:`[TASK-XX-RED-N]` + `[TASK-XX-GREEN-N]`
|
|
188
|
+
3. RED 任务依赖:前置基础设施任务(如脚手架、数据层)
|
|
189
|
+
4. GREEN 任务依赖:对应的 RED 任务
|
|
190
|
+
5. 可选:每 3-5 个行为点后插入一个 `[TASK-XX-REFACTOR]` 任务
|
|
191
|
+
6. 模块末尾可保留一个 `[TASK-XX-VERIFY]` 任务做全量测试验证
|
|
192
|
+
7. 非 TDD 模块(如前端 UI、配置、SQL DDL)不拆红绿,按常规任务处理
|
|
193
|
+
8. RED 任务验收标准必须包含"测试运行失败,且失败原因正确(功能未实现)"
|
|
194
|
+
9. GREEN 任务验收标准必须包含"写最少代码让对应 RED 测试通过",不包含"实现完整功能"。
|
|
195
|
+
**⛔ 禁止在 GREEN 任务中捆绑未测试的代码**(如 Controller 接口、Filter、Config 等)。
|
|
196
|
+
如果 GREEN 需要同时修改多个文件才能让测试通过,检查是否测试范围过大或实现范围超出测试要求。
|
|
197
|
+
10. **GREEN 任务范围限制**:每个 GREEN 任务只能实现让对应 RED 测试通过的代码,禁止捆绑未测试的功能。具体规则:
|
|
198
|
+
- Service 层 GREEN 只实现当前行为点的 Service 方法逻辑
|
|
199
|
+
- Controller 层不捆绑在 Service GREEN 中,必须独立处理
|
|
200
|
+
11. **Controller 层处理策略**(二选一,由 AI 根据项目复杂度判断,必须在 tasks.md §2.0 中声明):
|
|
201
|
+
- 策略 A(推荐):为每个 Controller 接口生成 RED 测试(使用 @WebMvcTest),拆为 RED→GREEN 对
|
|
202
|
+
- 策略 B:将 Controller 层声明为非 TDD 模块,作为独立接口层任务,依赖对应 Service 完成
|
|
203
|
+
- 无论哪种策略,Controller 不得捆绑在 Service 的 GREEN 任务中
|
|
204
|
+
12. **RED 任务必须包含**:测试方法名(`{method}_{state}_{outcome}` 格式)、Given-When-Then 结构描述、输出文件路径、关联 spec 场景编号
|
|
205
|
+
|
|
173
206
|
### 8. 质量红线自检
|
|
174
207
|
|
|
175
|
-
> 逐项确认,完整 7
|
|
208
|
+
> 逐项确认,完整 7 项自检清单 + TDD 合规性自检(结构符合模板 / 拓扑图已绘制 / 依赖字段已填写 / 无循环依赖 / 颗粒度 ≤5 分钟 / 100% 覆盖 design / 每任务有验收标准)见 `./checklist.md`「§8 质量红线自检 + §8.1 TDD 合规性自检」。如有任意一项未满足,重新生成对应章节,直至全部通过。
|
|
176
209
|
|
|
177
210
|
### 9. 确认任务并输出
|
|
178
211
|
|
|
@@ -201,6 +234,8 @@ Simple 模式或单文件能力域下,**不要拆成多个同文件任务**。
|
|
|
201
234
|
- 每个 TASK 必须写 `**implements**: DES-*` 或 `**covers**: STMT-*`,不得生成无上游来源任务。
|
|
202
235
|
- 任务依赖必须写 `**dependsOn**: TASK-*`;无依赖显式写“无”,所有依赖必须构成 DAG。
|
|
203
236
|
- 生成结束后必须运行 `node skywalk-sdd/log.cjs semantic-reconcile --project=. --change=<name>`。
|
|
237
|
+
- reconcile 必须立即生成 `openspec/changes/<name>/artifacts/.../tasks.ontology.json`,包含 TASK、implements/covers/dependsOn 及原文 source;不得推迟到 check/archive。
|
|
238
|
+
- 阶段 `stage_end` 会在无 Hook 环境下幂等执行同步兜底。
|
|
204
239
|
|
|
205
240
|
## Guardrails
|
|
206
241
|
|
|
@@ -218,5 +253,5 @@ Simple 模式或单文件能力域下,**不要拆成多个同文件任务**。
|
|
|
218
253
|
|
|
219
254
|
## 渐进披露
|
|
220
255
|
|
|
221
|
-
- Read `checklist.md` 仅在执行 task 需要校验时 — 含阶段边界⛔(Task 阶段约束)、§8 质量红线自检(7
|
|
222
|
-
- Read `reference.md` 仅在需要参考详细模板时 — 含 📊 Telemetry 命令模板(start/end)、§6 DAG 生成规则表(tdd/impl-first/none)、§7 任务结构(TASK-ID/类型/依赖/状态/描述等字段)。
|
|
256
|
+
- Read `checklist.md` 仅在执行 task 需要校验时 — 含阶段边界⛔(Task 阶段约束)、§8 质量红线自检(7 项 + TDD 合规性自检)、Guardrails ⛔ 强制项勾选表。
|
|
257
|
+
- Read `reference.md` 仅在需要参考详细模板时 — 含 📊 Telemetry 命令模板(start/end)、§6 DAG 生成规则表(tdd/impl-first/none)、§6.1 TDD 拆分示例、§6.2 非 TDD 模块处理规则、§7 任务结构(TASK-ID/类型/依赖/状态/描述等字段)。
|
|
@@ -34,6 +34,21 @@ description: opsx-task 的阶段强制检查点与自检清单。仅在执行 ta
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
+
## §8.1 TDD 合规性自检(仅 test-strategy=tdd 时)
|
|
38
|
+
|
|
39
|
+
- [ ] **RED 任务有真实断言**:每个 测试-RED 任务的验收标准包含"测试运行失败",而非"断言为空"或"编译通过"
|
|
40
|
+
- [ ] **GREEN 任务为行为级粒度**:每个 实现-GREEN 任务只对应一个 RED 测试,不是模块级整体实现
|
|
41
|
+
- [ ] **存在红绿循环**:DAG 中存在 RED→GREEN 的循环对,而非 TEST(全部)→IMPL(全部)的批次模式
|
|
42
|
+
- [ ] **有 REFACTOR 任务**:每 3-5 个行为点后至少有一个重构任务(可选但推荐)
|
|
43
|
+
- [ ] **GREEN 验收为"最少代码"**:验收标准包含"让对应 RED 测试通过",不包含"实现完整功能"
|
|
44
|
+
- [ ] **非 TDD 模块已排除**:前端 UI、配置、SQL DDL 等不拆红绿循环
|
|
45
|
+
- [ ] **GREEN 任务无捆绑**:每个 GREEN 任务的输出文件不包含未测试的 Controller/Filter/Config(除非该 GREEN 对应的 RED 测试明确测试了这些组件)
|
|
46
|
+
- [ ] **Controller 层策略已声明**:tasks.md §2.0 中明确声明 Controller 层使用策略 A(拆 RED→GREEN)还是策略 B(非 TDD 任务)
|
|
47
|
+
- [ ] **RED 任务有测试方法名**:每个 RED 任务包含 `{method}_{state}_{outcome}` 格式的测试方法名
|
|
48
|
+
- [ ] **REFACTOR 有具体方向**:每个 REFACTOR 任务列出至少 2 个具体重构点
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
37
52
|
## Guardrails ⛔ 强制项
|
|
38
53
|
|
|
39
54
|
- [ ] 必须以 `openspec-templates/tasks.md` 为模板基准
|
|
@@ -22,19 +22,90 @@ description: opsx-task 的详细模板:telemetry 命令、DAG 生成规则表
|
|
|
22
22
|
|
|
23
23
|
| test-strategy | DAG 生成规则 |
|
|
24
24
|
|---------------|---------------|
|
|
25
|
-
| `tdd` |
|
|
25
|
+
| `tdd` | 每个行为点拆为 RED→GREEN 对,GREEN Depends-On RED;每 3-5 个行为点后可插入 REFACTOR(Depends-On 前一个 GREEN);模块末尾可加 VERIFY(Depends-On 最后一个 GREEN/REFACTOR) |
|
|
26
26
|
| `impl-first` | 实现任务在前,测试任务 Depends-On 实现任务 |
|
|
27
27
|
| `none` | 不生成测试任务,仅编译检查 |
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
+
## §6.1 TDD 拆分示例
|
|
32
|
+
|
|
33
|
+
### TDD 模式拆分示例(认证模块)
|
|
34
|
+
|
|
35
|
+
spec.md user-auth 定义了 7 个场景,拆为 7 对 RED+GREEN + 1 个 REFACTOR:
|
|
36
|
+
|
|
37
|
+
| 任务 ID | 行为点 | 类型 | 依赖 | 验收标准 |
|
|
38
|
+
|---------|--------|------|------|---------|
|
|
39
|
+
| TASK-05-RED-1 | 登录成功返回 Token | 测试-RED | TASK-04-IMPL | 测试带断言运行失败,失败原因:AuthService 未实现 |
|
|
40
|
+
| TASK-05-GREEN-1 | 登录成功最小实现 | 实现-GREEN | TASK-05-RED-1 | 写最少代码让 RED-1 通过,不提前实现密码校验等 |
|
|
41
|
+
| TASK-05-RED-2 | 密码错误返回 2001 | 测试-RED | TASK-05-GREEN-1 | 测试失败,失败原因:未校验密码 |
|
|
42
|
+
| TASK-05-GREEN-2 | 密码校验实现 | 实现-GREEN | TASK-05-RED-2 | 让 RED-2 通过 |
|
|
43
|
+
| TASK-05-RED-3 | 账号禁用返回 2002 | 测试-RED | TASK-05-GREEN-2 | 测试失败 |
|
|
44
|
+
| TASK-05-GREEN-3 | 账号状态校验 | 实现-GREEN | TASK-05-RED-3 | 让 RED-3 通过 |
|
|
45
|
+
| TASK-05-RED-4 | Refresh Token 有效 | 测试-RED | TASK-05-GREEN-3 | 测试失败 |
|
|
46
|
+
| TASK-05-GREEN-4 | Refresh 实现 | 实现-GREEN | TASK-05-RED-4 | 让 RED-4 通过 |
|
|
47
|
+
| TASK-05-RED-5 | Refresh Token 无效返回 3001 | 测试-RED | TASK-05-GREEN-4 | 测试失败 |
|
|
48
|
+
| TASK-05-GREEN-5 | Refresh 校验实现 | 实现-GREEN | TASK-05-RED-5 | 让 RED-5 通过 |
|
|
49
|
+
| TASK-05-RED-6 | 登出加入黑名单 | 测试-RED | TASK-05-GREEN-5 | 测试失败 |
|
|
50
|
+
| TASK-05-GREEN-6 | 登出实现 | 实现-GREEN | TASK-05-RED-6 | 让 RED-6 通过 |
|
|
51
|
+
| TASK-05-REFACTOR | 重构优化 | 重构-REFACTOR | TASK-05-GREEN-6 | 所有测试仍绿,代码清理 |
|
|
52
|
+
|
|
53
|
+
**关键区别**:
|
|
54
|
+
- 每个 RED 任务都带**真实断言**,跑起来确实失败
|
|
55
|
+
- 每个 GREEN 任务只写**让当前测试通过的最少代码**
|
|
56
|
+
- 行为点粒度,一次一个,有小步循环
|
|
57
|
+
- 重构独立成任务,在全部绿灯后进行
|
|
58
|
+
|
|
59
|
+
### Controller 层处理示例
|
|
60
|
+
|
|
61
|
+
**策略 A:Controller 也拆 RED→GREEN(推荐,适合接口数量少时)**
|
|
62
|
+
|
|
63
|
+
| 任务 ID | 行为点 | 类型 | 依赖 | 验收标准 |
|
|
64
|
+
|---------|--------|------|------|---------|
|
|
65
|
+
| TASK-05-RED-8 | POST /auth/login 返回 Token | 测试-RED | TASK-05-GREEN-1 | @WebMvcTest 测试 HTTP 请求,断言响应 JSON 含 accessToken,测试失败 |
|
|
66
|
+
| TASK-05-GREEN-8 | AuthController.login() 实现 | 实现-GREEN | TASK-05-RED-8 | 只实现 login 接口让 RED-8 通过 |
|
|
67
|
+
| TASK-05-RED-9 | POST /auth/refresh 返回新 Token | 测试-RED | TASK-05-GREEN-4 | 测试失败 |
|
|
68
|
+
| TASK-05-GREEN-9 | AuthController.refresh() 实现 | 实现-GREEN | TASK-05-RED-9 | 只实现 refresh 接口 |
|
|
69
|
+
| TASK-05-RED-10 | POST /auth/logout 返回成功 | 测试-RED | TASK-05-GREEN-6 | 测试失败 |
|
|
70
|
+
| TASK-05-GREEN-10 | AuthController.logout() 实现 | 实现-GREEN | TASK-05-RED-10 | 只实现 logout 接口 |
|
|
71
|
+
|
|
72
|
+
**策略 B:Controller 作为非 TDD 任务(适合接口数量多时)**
|
|
73
|
+
|
|
74
|
+
| 任务 ID | 行为点 | 类型 | 依赖 | 验收标准 |
|
|
75
|
+
|---------|--------|------|------|---------|
|
|
76
|
+
| TASK-05-CTRL | AuthController 3 个接口接线 | 接口层 | TASK-05-GREEN-6 | Controller 编译通过,调用对应 Service 方法,返回 Result 统一响应体 |
|
|
77
|
+
|
|
78
|
+
注意:策略 B 中 Controller 任务不是 GREEN,不对应任何 RED 测试,仅做编译检查。
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## §6.2 非 TDD 模块处理规则
|
|
83
|
+
|
|
84
|
+
以下模块不需要红绿循环,按常规任务处理:
|
|
85
|
+
- 前端 UI 页面(Vue 组件)→ UI层任务
|
|
86
|
+
- 项目脚手架/配置(pom.xml, application.yml)→ 配置任务
|
|
87
|
+
- 数据库迁移脚本(SQL DDL)→ 数据层任务
|
|
88
|
+
- 前端路由/状态管理/API 封装 → UI层任务
|
|
89
|
+
- Controller 层(可选)→ 接口层任务(当选择策略 B 时,Controller 作为接线层不拆红绿)
|
|
90
|
+
|
|
91
|
+
⚠️ Controller 层处理策略需在 tasks.md §2.0 中明确声明,不能默认选择。
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
31
95
|
## §7 任务结构
|
|
32
96
|
|
|
33
97
|
**必须包含**:
|
|
34
98
|
1. **任务执行拓扑图(DAG)** - 层级关系清晰
|
|
35
99
|
2. **原子任务清单** - 每个任务包含:
|
|
36
100
|
- `[TASK-XXX-01]` 唯一标识
|
|
37
|
-
- `类型`: 数据层 / 接口层 / UI层 /
|
|
101
|
+
- `类型`: 数据层 / 接口层 / UI层 / 测试-RED / 实现-GREEN / 重构-REFACTOR / 测试-验证 / 配置
|
|
38
102
|
- `依赖`: 前置依赖(无 或 TASK-ID 列表)
|
|
39
103
|
- `状态`: [ ] 未完成
|
|
40
104
|
- 任务描述、输入、输出、实现步骤、验收标准
|
|
105
|
+
- **测试-RED 任务额外必填**:
|
|
106
|
+
- 测试方法名:`{method}_{state}_{outcome}` 格式
|
|
107
|
+
- Given-When-Then 结构描述
|
|
108
|
+
- 输出文件路径
|
|
109
|
+
- 关联 spec 场景编号
|
|
110
|
+
- **重构-REFACTOR 任务额外必填**:
|
|
111
|
+
- 具体重构方向(至少列出 2 个重构点,如"提取公共方法""消除重复代码")
|
|
@@ -131,6 +131,23 @@ node skywalk-sdd/log.cjs record --type=test_result --command=test --project=. --
|
|
|
131
131
|
> |--------|------|---------|
|
|
132
132
|
> | [name] | [file:line] | [error] |"
|
|
133
133
|
|
|
134
|
+
### 5a. TDD 报告模式(当 test-strategy=tdd 时)
|
|
135
|
+
|
|
136
|
+
在标准测试报告基础上,增加 TDD 追踪信息:
|
|
137
|
+
|
|
138
|
+
| 行为点 | RED 状态 | GREEN 状态 | 测试方法 |
|
|
139
|
+
|--------|---------|-----------|---------|
|
|
140
|
+
| [行为点1] | ✅ 曾失败 | ✅ 已通过 | [testMethodName] |
|
|
141
|
+
| [行为点2] | ✅ 曾失败 | ✅ 已通过 | [testMethodName] |
|
|
142
|
+
| ... | | | |
|
|
143
|
+
|
|
144
|
+
反模式检测:
|
|
145
|
+
- [ ] 无"测试 mock 行为而非真实行为"
|
|
146
|
+
- [ ] 无"生产类中加测试专用方法"
|
|
147
|
+
- [ ] 无"不理解依赖就 mock"
|
|
148
|
+
- [ ] 无"不完整的 mock"
|
|
149
|
+
- [ ] 无"集成测试作为事后补充"
|
|
150
|
+
|
|
134
151
|
### 6. 【交互引导】根据结果引导下一步
|
|
135
152
|
|
|
136
153
|
**全部通过**:
|