openspec-sdd-e2e-kit 0.1.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.
- package/README.md +63 -0
- package/bin/sdd-e2e-kit.mjs +53 -0
- package/kit/.codex/skills/feature-to-e2e/SKILL.md +188 -0
- package/kit/.codex/skills/feature-to-e2e/agents/openai.yaml +4 -0
- package/kit/.codex/skills/openspec-apply-change/SKILL.md +180 -0
- package/kit/.codex/skills/openspec-archive-change/SKILL.md +157 -0
- package/kit/.codex/skills/openspec-continue-change/SKILL.md +136 -0
- package/kit/.codex/skills/openspec-explore/SKILL.md +292 -0
- package/kit/.codex/skills/openspec-full-spec-discovery/SKILL.md +356 -0
- package/kit/.codex/skills/openspec-full-spec-discovery/references/backlog-row-to-main-spec.md +447 -0
- package/kit/.codex/skills/openspec-new-change/SKILL.md +92 -0
- package/kit/.codex/skills/openspec-propose/SKILL.md +132 -0
- package/kit/.codex/skills/spec-to-gherkin/SKILL.md +686 -0
- package/kit/SDD_E2E_FLOW.md +268 -0
- package/kit/manifest.json +78 -0
- package/kit/openspec/config.yaml +18 -0
- package/kit/openspec/schemas/sdd-e2e/schema.yaml +128 -0
- package/kit/openspec/schemas/sdd-e2e/templates/acceptance-coverage.md +9 -0
- package/kit/openspec/schemas/sdd-e2e/templates/design.md +29 -0
- package/kit/openspec/schemas/sdd-e2e/templates/feature.feature +13 -0
- package/kit/openspec/schemas/sdd-e2e/templates/proposal.md +23 -0
- package/kit/openspec/schemas/sdd-e2e/templates/spec.md +21 -0
- package/kit/openspec/schemas/sdd-e2e/templates/tasks.md +16 -0
- package/kit/openspec/schemas/sdd-e2e/templates/test-cases.md +35 -0
- package/kit/openspec/schemas/sdd-e2e.yaml +160 -0
- package/kit/openspec/sdd-e2e-flow.md +290 -0
- package/kit/openspec/sdd-e2e-maintenance.md +98 -0
- package/kit/scripts/sdd/check-report.mjs +34 -0
- package/kit/scripts/sdd/lib.mjs +290 -0
- package/kit/scripts/sdd/lint-features.mjs +60 -0
- package/kit/scripts/sdd/lint-tasks.mjs +41 -0
- package/kit/scripts/sdd/self-test.mjs +185 -0
- package/kit/scripts/sdd/summarize-acceptance.mjs +41 -0
- package/package.json +19 -0
- package/src/check.mjs +86 -0
- package/src/diff.mjs +101 -0
- package/src/install.mjs +159 -0
- package/src/lib.mjs +221 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
name: sdd-e2e
|
|
2
|
+
version: 1
|
|
3
|
+
description: 项目级 OpenSpec SDD + E2E 工作流规范。以 OpenSpec artifact 为主干,在 spec 与 tasks 之间加入 feature 契约,并以 phase acceptance gate 关闭开发切片。
|
|
4
|
+
|
|
5
|
+
status: project-extension
|
|
6
|
+
owner: front-mindflow-setting
|
|
7
|
+
|
|
8
|
+
principles:
|
|
9
|
+
- OpenSpec 管理需求、设计、任务和归档生命周期。
|
|
10
|
+
- Gherkin feature 是 spec 与 tasks 之间的项目级验证契约。
|
|
11
|
+
- tasks 必须按 feature 中的 phase 分组。
|
|
12
|
+
- phase 完成必须依赖 acceptance gate;smoke 不能关闭 phase。
|
|
13
|
+
- mismatch 必须回到实现或 artifact 修正,不能通过削弱断言绕过。
|
|
14
|
+
- 本 schema 是项目级扩展,不修改 OpenSpec CLI 本体。
|
|
15
|
+
|
|
16
|
+
lifecycle:
|
|
17
|
+
order:
|
|
18
|
+
- proposal
|
|
19
|
+
- specs
|
|
20
|
+
- features
|
|
21
|
+
- design
|
|
22
|
+
- tasks
|
|
23
|
+
- phase-acceptance
|
|
24
|
+
- final-acceptance
|
|
25
|
+
- archive
|
|
26
|
+
|
|
27
|
+
artifacts:
|
|
28
|
+
proposal:
|
|
29
|
+
path: openspec/changes/<change>/proposal.md
|
|
30
|
+
required: true
|
|
31
|
+
purpose: 说明为什么做、做什么、涉及哪些 capability 和影响面。
|
|
32
|
+
|
|
33
|
+
specs:
|
|
34
|
+
path: openspec/changes/<change>/specs/**/spec.md
|
|
35
|
+
required: true
|
|
36
|
+
dependsOn:
|
|
37
|
+
- proposal
|
|
38
|
+
purpose: 用 SHALL/MUST/SHOULD 描述需求行为和业务规则。
|
|
39
|
+
|
|
40
|
+
features:
|
|
41
|
+
path: openspec/changes/<change>/specs/**/features/*.feature
|
|
42
|
+
required: true
|
|
43
|
+
dependsOn:
|
|
44
|
+
- specs
|
|
45
|
+
purpose: 从 specs 扩写可验收 Scenario,并提供 phase/task/e2e 的追溯标签。
|
|
46
|
+
requiredScenarioTags:
|
|
47
|
+
- "@phase:<phase-id>"
|
|
48
|
+
- "@validation:<type>"
|
|
49
|
+
- "@req:<requirement-id>"
|
|
50
|
+
- "@p0 | @p1 | @p2"
|
|
51
|
+
validationTypes:
|
|
52
|
+
- mock-e2e
|
|
53
|
+
- real-smoke
|
|
54
|
+
- component
|
|
55
|
+
- unit
|
|
56
|
+
- api
|
|
57
|
+
- manual
|
|
58
|
+
boundaryTags:
|
|
59
|
+
- race-condition
|
|
60
|
+
- degradation
|
|
61
|
+
- anti-duplicate
|
|
62
|
+
- form-validation
|
|
63
|
+
- conditional-render
|
|
64
|
+
- cross-view-sync
|
|
65
|
+
- state-machine
|
|
66
|
+
- feedback
|
|
67
|
+
- negative
|
|
68
|
+
|
|
69
|
+
testCases:
|
|
70
|
+
path: openspec/changes/<change>/test-cases.md
|
|
71
|
+
required: true
|
|
72
|
+
dependsOn:
|
|
73
|
+
- features
|
|
74
|
+
purpose: 汇总 Scenario 覆盖矩阵、优先级、phase 和 validation 类型。
|
|
75
|
+
|
|
76
|
+
design:
|
|
77
|
+
path: openspec/changes/<change>/design.md
|
|
78
|
+
required: true
|
|
79
|
+
dependsOn:
|
|
80
|
+
- specs
|
|
81
|
+
- features
|
|
82
|
+
- testCases
|
|
83
|
+
purpose: 基于需求和 feature 风险面形成实现方案、边界处理和验证策略。
|
|
84
|
+
|
|
85
|
+
tasks:
|
|
86
|
+
path: openspec/changes/<change>/tasks.md
|
|
87
|
+
required: true
|
|
88
|
+
dependsOn:
|
|
89
|
+
- design
|
|
90
|
+
- features
|
|
91
|
+
purpose: 按 @phase 分组实现任务,并为每个 phase 声明 smoke 与 acceptance 验证任务。
|
|
92
|
+
phaseContract:
|
|
93
|
+
requiredHeading: "## Phase: <phase-id>"
|
|
94
|
+
requiredCoverageLine: "Covers: `@phase:<phase-id>`"
|
|
95
|
+
requiredValidationTask: "Acceptance 验证 `@phase:<phase-id>`"
|
|
96
|
+
|
|
97
|
+
phaseReports:
|
|
98
|
+
path: specs/e2e/bdd/<change>/validation-report.<phase-id>.md
|
|
99
|
+
required: true
|
|
100
|
+
dependsOn:
|
|
101
|
+
- tasks
|
|
102
|
+
purpose: 每个 phase 的 acceptance gate 报告。
|
|
103
|
+
requiredCoverageFields:
|
|
104
|
+
- selected
|
|
105
|
+
- automated
|
|
106
|
+
- passed
|
|
107
|
+
- mismatch
|
|
108
|
+
- blocked
|
|
109
|
+
- manual
|
|
110
|
+
- gap-pending
|
|
111
|
+
- gate
|
|
112
|
+
|
|
113
|
+
finalAcceptance:
|
|
114
|
+
path: openspec/changes/<change>/acceptance-coverage.md
|
|
115
|
+
required: true
|
|
116
|
+
dependsOn:
|
|
117
|
+
- phaseReports
|
|
118
|
+
purpose: 汇总所有 phase gate,给出 change 级最终验收结论。
|
|
119
|
+
|
|
120
|
+
gates:
|
|
121
|
+
featureLint:
|
|
122
|
+
command: pnpm sdd:lint-features <change>
|
|
123
|
+
blocks:
|
|
124
|
+
- Scenario 缺少 @phase、@validation、@req 或优先级标签。
|
|
125
|
+
- "@validation 不在允许列表。"
|
|
126
|
+
- "P0 Scenario 使用 @gap-pending。"
|
|
127
|
+
- 自动化 Scenario 无法追溯到 requirement。
|
|
128
|
+
|
|
129
|
+
taskLint:
|
|
130
|
+
command: pnpm sdd:lint-tasks <change>
|
|
131
|
+
blocks:
|
|
132
|
+
- tasks 中存在 feature 未声明的 phase。
|
|
133
|
+
- feature 中存在 tasks 未覆盖的 phase。
|
|
134
|
+
- phase 缺少 acceptance 验证任务。
|
|
135
|
+
|
|
136
|
+
phaseAcceptance:
|
|
137
|
+
command: pnpm sdd:phase <change> <phase>
|
|
138
|
+
blocks:
|
|
139
|
+
- P0/P1 自动化 Scenario 没有 100% 结果覆盖。
|
|
140
|
+
- report 中存在未解释的 mismatch、blocked 或 manual。
|
|
141
|
+
- 只有 smoke 报告,没有 acceptance report。
|
|
142
|
+
|
|
143
|
+
finalAcceptance:
|
|
144
|
+
command: pnpm sdd:acceptance <change>
|
|
145
|
+
blocks:
|
|
146
|
+
- 任意必需 phase gate 未通过。
|
|
147
|
+
- final acceptance summary 缺失。
|
|
148
|
+
|
|
149
|
+
failureSemantics:
|
|
150
|
+
passed: 实现符合 feature 描述。
|
|
151
|
+
mismatch: 实际行为与 feature 不一致,需要修正实现或 artifact。
|
|
152
|
+
blocked: 环境、登录、权限、数据或依赖阻塞,当前无法可靠验证。
|
|
153
|
+
manual: 无法稳定自动化,需要记录人工步骤、证据和接受人。
|
|
154
|
+
gap-pending: spec 明确未决的延期场景,必须记录原因和后续任务。
|
|
155
|
+
|
|
156
|
+
fallback:
|
|
157
|
+
openspecCliUnavailable:
|
|
158
|
+
allowed: true
|
|
159
|
+
rule: 当 openspec CLI 不可用但 openspec/changes/<change>/ artifact 存在时,skills 和脚本可以直接消费 artifact 继续执行。
|
|
160
|
+
report: 必须在总结或 validation report 中记录 CLI 不可用和 fallback 行为。
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# 项目级 OpenSpec SDD + E2E 工作流规范
|
|
2
|
+
|
|
3
|
+
本文定义当前项目的第二层 OpenSpec 规范:不修改 OpenSpec CLI 本体,而是在本仓库中约束 change artifact、Codex skills 和 E2E gate 的协作方式。
|
|
4
|
+
|
|
5
|
+
规范入口:
|
|
6
|
+
|
|
7
|
+
- OpenSpec 原生 schema:`openspec/schemas/sdd-e2e/schema.yaml`
|
|
8
|
+
- 项目级契约说明:`openspec/schemas/sdd-e2e.yaml`
|
|
9
|
+
- Change 目录:`openspec/changes/<change>/`
|
|
10
|
+
- Feature 目录:`openspec/changes/<change>/specs/**/features/*.feature`
|
|
11
|
+
- Phase E2E 报告:`specs/e2e/bdd/<change>/validation-report.<phase-id>.md`
|
|
12
|
+
- 升级维护说明:`openspec/sdd-e2e-maintenance.md`
|
|
13
|
+
|
|
14
|
+
## 分层边界
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
OpenSpec 本体 / CLI
|
|
18
|
+
负责基础 artifact 生命周期,不在本项目中修改
|
|
19
|
+
|
|
20
|
+
项目级 OpenSpec 规范
|
|
21
|
+
定义 sdd-e2e schema、artifact 契约、phase gate 和失败语义
|
|
22
|
+
|
|
23
|
+
Codex Skills / Scripts
|
|
24
|
+
作为执行器,读取项目级规范并落地到具体 change
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
本规范实现第二层。第三层的 skills 和 scripts 必须服从本规范。
|
|
28
|
+
|
|
29
|
+
## 标准生命周期
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
proposal
|
|
33
|
+
-> specs
|
|
34
|
+
-> features
|
|
35
|
+
-> design
|
|
36
|
+
-> tasks
|
|
37
|
+
-> phase acceptance
|
|
38
|
+
-> final acceptance
|
|
39
|
+
-> archive
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
约束:
|
|
43
|
+
|
|
44
|
+
- `features` 必须在 specs 之后、design/tasks 最终定稿之前生成。
|
|
45
|
+
- `design` 必须参考 features 暴露的边界、降级、竞态、防重复和跨视图同步风险。
|
|
46
|
+
- `tasks` 必须按 features 中的 `@phase:*` 分组。
|
|
47
|
+
- 每个 phase 必须通过 acceptance gate 才能关闭。
|
|
48
|
+
- smoke 只能验证入口和基础链路,不能替代 acceptance。
|
|
49
|
+
|
|
50
|
+
## Artifact 契约
|
|
51
|
+
|
|
52
|
+
每个 `schema: sdd-e2e` 的 change 至少包含:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
openspec/changes/<change>/.openspec.yaml
|
|
56
|
+
openspec/changes/<change>/proposal.md
|
|
57
|
+
openspec/changes/<change>/specs/**/spec.md
|
|
58
|
+
openspec/changes/<change>/specs/**/features/*.feature
|
|
59
|
+
openspec/changes/<change>/test-cases.md
|
|
60
|
+
openspec/changes/<change>/design.md
|
|
61
|
+
openspec/changes/<change>/tasks.md
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
完成后还应包含:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
specs/e2e/bdd/<change>/validation-report.<phase-id>.md
|
|
68
|
+
openspec/changes/<change>/acceptance-coverage.md
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Feature 标签契约
|
|
72
|
+
|
|
73
|
+
每个 Scenario 必须包含:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
@phase:<phase-id>
|
|
77
|
+
@validation:<type>
|
|
78
|
+
@req:<requirement-id>
|
|
79
|
+
@p0 | @p1 | @p2
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
允许的 `@validation`:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
mock-e2e
|
|
86
|
+
real-smoke
|
|
87
|
+
component
|
|
88
|
+
unit
|
|
89
|
+
api
|
|
90
|
+
manual
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
边界类 Scenario 应包含至少一个风险标签:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
@race-condition
|
|
97
|
+
@degradation
|
|
98
|
+
@anti-duplicate
|
|
99
|
+
@form-validation
|
|
100
|
+
@conditional-render
|
|
101
|
+
@cross-view-sync
|
|
102
|
+
@state-machine
|
|
103
|
+
@feedback
|
|
104
|
+
@negative
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
规则:
|
|
108
|
+
|
|
109
|
+
- 没有 `@phase:*` 的 Scenario 不能进入 tasks。
|
|
110
|
+
- 没有 `@req:*` 的 Scenario 不能进入实现。
|
|
111
|
+
- P0 Scenario 不能使用 `@gap-pending`。
|
|
112
|
+
- P1 Scenario 使用 `@gap-pending` 时,必须记录原因和后续任务。
|
|
113
|
+
|
|
114
|
+
## Tasks 与 Phase 绑定
|
|
115
|
+
|
|
116
|
+
`tasks.md` 必须按 phase 组织:
|
|
117
|
+
|
|
118
|
+
```md
|
|
119
|
+
## Phase: <phase-id>
|
|
120
|
+
|
|
121
|
+
Covers: `@phase:<phase-id>`
|
|
122
|
+
|
|
123
|
+
- [ ] 实现任务
|
|
124
|
+
- [ ] Smoke 验证 `@phase:<phase-id>`
|
|
125
|
+
- [ ] Acceptance 验证 `@phase:<phase-id>` 全部自动化 Scenario
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
规则:
|
|
129
|
+
|
|
130
|
+
- tasks 不能发明 feature 中不存在的 phase id。
|
|
131
|
+
- feature 中出现的每个 phase 必须在 tasks 中出现。
|
|
132
|
+
- 每个 phase 必须有 acceptance 验证任务。
|
|
133
|
+
- 调整 phase 时,必须同步修改 feature 和 tasks。
|
|
134
|
+
|
|
135
|
+
## Phase Gate
|
|
136
|
+
|
|
137
|
+
phase completion 的判定以 acceptance report 为准。
|
|
138
|
+
|
|
139
|
+
phase acceptance 必须覆盖:
|
|
140
|
+
|
|
141
|
+
- 当前 phase 下所有不含 `@gap-pending` 的 P0/P1 `@validation:mock-e2e` Scenario。
|
|
142
|
+
- 当前 phase 下所有不含 `@gap-pending` 的 P0/P1 `@validation:real-smoke` Scenario。
|
|
143
|
+
- 被声明为自动化的 P0/P1 Scenario。
|
|
144
|
+
|
|
145
|
+
phase report 至少包含:
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
selected
|
|
149
|
+
automated
|
|
150
|
+
passed
|
|
151
|
+
mismatch
|
|
152
|
+
blocked
|
|
153
|
+
manual
|
|
154
|
+
gap-pending
|
|
155
|
+
gate: passed | failed
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
以下情况 phase 不能关闭:
|
|
159
|
+
|
|
160
|
+
- 只有 smoke,没有 acceptance report。
|
|
161
|
+
- 自动化范围内 Scenario 没有 100% 结果覆盖。
|
|
162
|
+
- 存在未解释的 `mismatch`。
|
|
163
|
+
- 存在未解除的 `blocked`。
|
|
164
|
+
- 存在未被产品接受的 `manual`。
|
|
165
|
+
|
|
166
|
+
## 失败语义
|
|
167
|
+
|
|
168
|
+
```text
|
|
169
|
+
passed
|
|
170
|
+
实现符合 feature。
|
|
171
|
+
|
|
172
|
+
mismatch
|
|
173
|
+
实际行为与 feature 不一致,需要修正实现或 artifact。
|
|
174
|
+
|
|
175
|
+
blocked
|
|
176
|
+
环境、登录、权限、数据或依赖阻塞,当前无法可靠验证。
|
|
177
|
+
|
|
178
|
+
manual
|
|
179
|
+
无法稳定自动化,需要记录人工步骤、证据和接受人。
|
|
180
|
+
|
|
181
|
+
gap-pending
|
|
182
|
+
spec 明确未决的延期场景,必须记录原因和后续任务。
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`blocked` 和 `manual` 默认不算通过。只有明确记录接受原因和责任人时,才能在 final acceptance 中作为已知例外处理。
|
|
186
|
+
|
|
187
|
+
## Spec Impact Review
|
|
188
|
+
|
|
189
|
+
主 spec SHOULD 在末尾包含非规范性的 `## Code Scope` 区块,记录当前 spec 对应的主要实现范围。该区块用于归档前影响审查,不属于业务规则。
|
|
190
|
+
|
|
191
|
+
`Code Scope` 推荐记录:
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
routes:
|
|
195
|
+
- <route>
|
|
196
|
+
files:
|
|
197
|
+
- <source-file>
|
|
198
|
+
apis:
|
|
199
|
+
- <method> <path>
|
|
200
|
+
gitnexus_processes:
|
|
201
|
+
- <process name>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
归档 change 前,执行者 MUST 比较本次改动范围与已有主 spec 的 `Code Scope` 是否重合。比较基线默认使用 `master`;如果 change、PR 或仓库约定明确使用其他目标分支,则使用该目标分支。
|
|
205
|
+
|
|
206
|
+
在网络和权限允许时,执行者 SHOULD 先执行 `git fetch origin <base_ref>`,保证本地比较基线尽量接近远端最新状态。随后优先使用 GitNexus compare 模式分析完整影响范围;如果 GitNexus 不可用,则使用 `git diff --name-only <base_ref>...HEAD` 降级检查。
|
|
207
|
+
|
|
208
|
+
存在重合时,归档摘要 MUST 记录处理结论:
|
|
209
|
+
|
|
210
|
+
- 已同步更新相关主 spec
|
|
211
|
+
- 行为未变化,不需要更新
|
|
212
|
+
- 仅实现细节重合
|
|
213
|
+
- 需要后续补充 spec gap
|
|
214
|
+
|
|
215
|
+
如果 fetch、GitNexus compare 或 base ref 不可用,执行者 MUST 记录降级原因,并至少使用 changed files 与 `Code Scope.files` 做降级检查。
|
|
216
|
+
|
|
217
|
+
## 推荐命令
|
|
218
|
+
|
|
219
|
+
第一版 gate 只做最小检查:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
pnpm sdd:lint-features <change>
|
|
223
|
+
pnpm sdd:lint-tasks <change>
|
|
224
|
+
pnpm sdd:phase <change> <phase>
|
|
225
|
+
pnpm sdd:acceptance <change>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
命令职责:
|
|
229
|
+
|
|
230
|
+
- `sdd:lint-features`:检查 Scenario 标签完整性和优先级规则。
|
|
231
|
+
- `sdd:lint-tasks`:检查 feature phase 与 tasks phase 双向一致。
|
|
232
|
+
- `sdd:phase`:检查某个 phase 的 acceptance report。
|
|
233
|
+
- `sdd:acceptance`:聚合所有 phase report,生成 final acceptance summary。
|
|
234
|
+
|
|
235
|
+
## OpenSpec CLI Fallback
|
|
236
|
+
|
|
237
|
+
如果当前环境没有 `openspec` CLI,但 `openspec/changes/<change>/` 下存在 artifact,skills 和 scripts 可以直接读取 artifact 继续执行。
|
|
238
|
+
|
|
239
|
+
fallback 要求:
|
|
240
|
+
|
|
241
|
+
- 必须记录 `openspec CLI unavailable`。
|
|
242
|
+
- 不允许跳过 feature、tasks 或 acceptance gate。
|
|
243
|
+
- 不允许因为 CLI 不可用而降低 phase completion 标准。
|
|
244
|
+
|
|
245
|
+
## 使用准则
|
|
246
|
+
|
|
247
|
+
新需求默认优先使用:
|
|
248
|
+
|
|
249
|
+
```yaml
|
|
250
|
+
schema: sdd-e2e
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
小型修复可以继续使用 `spec-driven`,但只要变更涉及 UI 行为、交互状态、发布流程、配置表单、异步请求或跨视图同步,就应使用 `sdd-e2e`。
|
|
254
|
+
|
|
255
|
+
`sdd-e2e` 不是为了生成更多测试,而是为了让每个开发切片都有可追溯的验收边界。
|
|
256
|
+
|
|
257
|
+
不要在 `.openspec.yaml` 中继续使用 `schemaFile`。OpenSpec CLI 通过 `openspec/schemas/sdd-e2e/schema.yaml` 自动发现 project-local schema。
|
|
258
|
+
|
|
259
|
+
## 规则强度
|
|
260
|
+
|
|
261
|
+
### MUST
|
|
262
|
+
|
|
263
|
+
- `schema: sdd-e2e` 的 change 必须包含 specs、features、test-cases、design 和 tasks。
|
|
264
|
+
- 每个 Scenario 必须有 `@phase:*`、`@validation:*`、`@req:*` 和优先级标签。
|
|
265
|
+
- P0/P1 Scenario 必须有风险/边界类型标签。
|
|
266
|
+
- tasks 必须与 feature phase 双向一致。
|
|
267
|
+
- 每个 phase 必须有 acceptance 验证任务。
|
|
268
|
+
- phase acceptance report 必须通过 `pnpm sdd:phase <change> <phase>`。
|
|
269
|
+
- final acceptance 必须通过 `pnpm sdd:acceptance <change>` 后才能归档。
|
|
270
|
+
- 归档前必须执行 Spec Impact Review,并在存在 Code Scope 重合时记录处理结论。
|
|
271
|
+
- P0 不允许 `@gap-pending`。
|
|
272
|
+
|
|
273
|
+
### SHOULD
|
|
274
|
+
|
|
275
|
+
- UI、异步、表单、发布流程、跨视图同步类变更应该默认使用 `sdd-e2e`。
|
|
276
|
+
- 主 spec 应该包含 `Code Scope`,用于归档前影响审查。
|
|
277
|
+
- 每个 phase 应该控制在可独立验收的小切片。
|
|
278
|
+
- feature 应该优先描述用户可观察行为,避免泄露接口字段和实现细节。
|
|
279
|
+
- smoke 可以作为开发中快速反馈,但应该明确标为 smoke,不能替代 acceptance。
|
|
280
|
+
|
|
281
|
+
### MAY
|
|
282
|
+
|
|
283
|
+
- 纯文案、样式微调、无状态的轻量修复可以继续使用 `spec-driven`。
|
|
284
|
+
- P2 场景可以只进入 coverage matrix,不一定进入 phase acceptance。
|
|
285
|
+
- `manual` 可以用于无法稳定自动化的外部依赖场景,但必须记录人工步骤和接受人。
|
|
286
|
+
|
|
287
|
+
### DEFER
|
|
288
|
+
|
|
289
|
+
- pilot-run 可以在流程规范和 gate 脚本完成后单独执行。
|
|
290
|
+
- 更复杂的 CI 集成、HTML 报告、跨浏览器矩阵不属于第一版规范的必须范围。
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# SDD-E2E 维护说明
|
|
2
|
+
|
|
3
|
+
本文说明如何维护当前项目的 OpenSpec SDD + E2E 流程,尤其是 OpenSpec CLI 升级后如何保护本项目的定制 skill。
|
|
4
|
+
|
|
5
|
+
## 资产分层
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
OpenSpec CLI
|
|
9
|
+
上游依赖,只通过 npm 升级,不修改包源码
|
|
10
|
+
|
|
11
|
+
Project schema
|
|
12
|
+
openspec/schemas/sdd-e2e/schema.yaml
|
|
13
|
+
openspec/schemas/sdd-e2e/templates/*
|
|
14
|
+
|
|
15
|
+
Project contract
|
|
16
|
+
openspec/schemas/sdd-e2e.yaml
|
|
17
|
+
openspec/sdd-e2e-flow.md
|
|
18
|
+
SDD_E2E_FLOW.md
|
|
19
|
+
|
|
20
|
+
Project executor
|
|
21
|
+
.codex/skills/openspec-*
|
|
22
|
+
.codex/skills/spec-to-gherkin
|
|
23
|
+
.codex/skills/feature-to-e2e
|
|
24
|
+
scripts/sdd/*
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
OpenSpec CLI 负责 artifact 图、instructions、templates 和基础 status。`scripts/sdd/*` 负责本项目的语义 gate。不要把 `openspec status isComplete=true` 当作 phase 或 final acceptance 通过。
|
|
28
|
+
|
|
29
|
+
## Skill 策略
|
|
30
|
+
|
|
31
|
+
`.codex/skills/openspec-*` 是本项目的 sdd-e2e overlay,不再视为可被 `openspec update` 直接覆盖的纯官方生成物。
|
|
32
|
+
|
|
33
|
+
维护规则:
|
|
34
|
+
|
|
35
|
+
- 可以吸收 OpenSpec 官方 skill 的新命令、新字段和 bug fix。
|
|
36
|
+
- 必须保留 `schema: sdd-e2e` 默认策略、artifact 顺序、phase gate、final acceptance gate。
|
|
37
|
+
- 不允许恢复 `schemaFile` fallback。
|
|
38
|
+
- 不允许在 `sdd-e2e` 适用场景静默 fallback 到 `spec-driven`。
|
|
39
|
+
- 不允许把 smoke、manual、blocked 或 OpenSpec artifact complete 当作 phase complete。
|
|
40
|
+
|
|
41
|
+
## OpenSpec 升级流程
|
|
42
|
+
|
|
43
|
+
升级 OpenSpec CLI 后,不要先在当前项目运行 `openspec update`。
|
|
44
|
+
|
|
45
|
+
推荐步骤:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
openspec --version
|
|
49
|
+
npm view @fission-ai/openspec version dist-tags --json
|
|
50
|
+
openspec schema validate sdd-e2e --json
|
|
51
|
+
openspec schemas --json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
如果要查看新版官方 skill,生成到临时目录,并重定向 `CODEX_HOME`,避免写入真实的 `~/.codex/prompts`:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
tmp="$(mktemp -d)"
|
|
58
|
+
CODEX_HOME="$tmp/codex-home" openspec init "$tmp/project" --tools codex
|
|
59
|
+
diff -ru "$tmp/project/.codex/skills" ".codex/skills"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
只手动合并对本项目有价值的差异。合并后运行:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
openspec schema validate sdd-e2e --json
|
|
66
|
+
openspec instructions proposal --change codify-sdd-e2e-flow --json
|
|
67
|
+
openspec instructions apply --change codify-sdd-e2e-flow --json
|
|
68
|
+
pnpm sdd:self-test
|
|
69
|
+
pnpm sdd:lint-features codify-sdd-e2e-flow
|
|
70
|
+
pnpm sdd:lint-tasks codify-sdd-e2e-flow
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
如果确实需要运行 `openspec update`,先确认当前 `.codex/skills/openspec-*` 已有备份或可从 git diff 恢复,并确认是否会写入全局 Codex prompts。
|
|
74
|
+
|
|
75
|
+
## 新项目迁移清单
|
|
76
|
+
|
|
77
|
+
最小迁移包:
|
|
78
|
+
|
|
79
|
+
- `openspec/config.yaml`
|
|
80
|
+
- `openspec/schemas/sdd-e2e/schema.yaml`
|
|
81
|
+
- `openspec/schemas/sdd-e2e/templates/*`
|
|
82
|
+
- `openspec/schemas/sdd-e2e.yaml`
|
|
83
|
+
- `openspec/sdd-e2e-flow.md`
|
|
84
|
+
- `openspec/sdd-e2e-maintenance.md`
|
|
85
|
+
- `SDD_E2E_FLOW.md`
|
|
86
|
+
- `.codex/skills/openspec-*`
|
|
87
|
+
- `.codex/skills/spec-to-gherkin`
|
|
88
|
+
- `.codex/skills/feature-to-e2e`
|
|
89
|
+
- `scripts/sdd/*`
|
|
90
|
+
- `package.json` 中的 `sdd:*` scripts
|
|
91
|
+
|
|
92
|
+
迁移后先运行:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
openspec schema validate sdd-e2e --json
|
|
96
|
+
openspec schemas --json
|
|
97
|
+
pnpm sdd:self-test
|
|
98
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { getChangeName, reportResult, validatePhaseReport } from './lib.mjs';
|
|
4
|
+
|
|
5
|
+
const change = getChangeName();
|
|
6
|
+
const phase = process.argv[3];
|
|
7
|
+
const errors = [];
|
|
8
|
+
|
|
9
|
+
if (!phase) {
|
|
10
|
+
errors.push('Usage: pnpm sdd:phase <change> <phase>');
|
|
11
|
+
reportResult(`sdd:phase ${change}`, errors);
|
|
12
|
+
process.exit();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const reportPath = path.join(
|
|
16
|
+
process.cwd(),
|
|
17
|
+
'specs',
|
|
18
|
+
'e2e',
|
|
19
|
+
'bdd',
|
|
20
|
+
change,
|
|
21
|
+
`validation-report.${phase}.md`,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (!fs.existsSync(reportPath)) {
|
|
25
|
+
errors.push(`phase report not found: ${reportPath}`);
|
|
26
|
+
reportResult(`sdd:phase ${change} ${phase}`, errors);
|
|
27
|
+
process.exit();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (fs.existsSync(reportPath)) {
|
|
31
|
+
errors.push(...validatePhaseReport(change, phase, reportPath).errors);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
reportResult(`sdd:phase ${change} ${phase}`, errors);
|