@peterxiaoyang/superspec 0.1.31 → 0.1.33
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/dist/next.js +8 -4
- package/package.json +1 -1
- package/templates/workflow/AGENTS.md +2 -0
- package/templates/workflow/prompts/architect.md +4 -0
- package/templates/workflow/prompts/critic.md +6 -0
- package/templates/workflow/prompts/executor.md +2 -0
- package/templates/workflow/prompts/explore.md +7 -0
- package/templates/workflow/prompts/test-engineer.md +10 -0
- package/templates/workflow/prompts/verifier.md +4 -0
- package/templates/workflow/skills/superspec-apply/SKILL.md +1 -0
- package/templates/workflow/skills/superspec-archive/SKILL.md +6 -3
- package/templates/workflow/skills/superspec-explore/SKILL.md +19 -0
- package/templates/workflow/skills/superspec-propose/SKILL.md +10 -0
- package/templates/workflow/skills/superspec-review/SKILL.md +4 -1
package/dist/next.js
CHANGED
|
@@ -271,12 +271,16 @@ export function next(projectRoot, change, changeRoot, defaultRisk = "strict") {
|
|
|
271
271
|
if (snapshot.open_jobs.length > 0) {
|
|
272
272
|
return requiredJobsOutput("accepted", change, snapshot.open_jobs, `有 ${snapshot.open_jobs.length} 个待完成工作项,暂不归档`);
|
|
273
273
|
}
|
|
274
|
+
const ask = {
|
|
275
|
+
question: `审查已通过,流程停在 accepted。确认归档时请执行 ${transitionCommand(change, "archive")}`,
|
|
276
|
+
allowed_answers: ["确认归档"],
|
|
277
|
+
scope: "archive_confirmation",
|
|
278
|
+
};
|
|
274
279
|
return {
|
|
275
280
|
state: "accepted",
|
|
276
|
-
path: "
|
|
277
|
-
|
|
278
|
-
reason: "
|
|
279
|
-
missing_inputs: [],
|
|
281
|
+
path: "ask_user",
|
|
282
|
+
ask_user: ask,
|
|
283
|
+
reason: "审查通过,等待用户确认归档",
|
|
280
284
|
};
|
|
281
285
|
case "archive":
|
|
282
286
|
if (snapshot.open_jobs.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<!-- SUPERSPEC:AGENTS:START -->
|
|
2
2
|
本项目启用 SuperSpec。使用 `superspec-*` 工作流时,以 `superspec transition next --change "<change>"` 返回的下一步为准;流程完成前不得跳阶段、不得自称完成。
|
|
3
3
|
|
|
4
|
+
即使用户没有显式调用 `superspec-*`,如果新输入像是在改变业务规则、产品口径、验收标准、示例规范或影响范围,编辑代码前先提醒并做只读确认:这是实现偏差,还是需要先回 `superspec-propose` 更新计划文档;不要直接把这类自然语言当作 apply 授权。
|
|
5
|
+
|
|
4
6
|
当用户显式调用 `$superspec-explore` 工作流时,视为已明确授权启动 `explore` subagent 做只读深扫;其他 `$superspec-*` 阶段仅在工作流引擎创建独立工作项时,视为授权启动对应 subagent。
|
|
5
7
|
|
|
6
8
|
SuperSpec 创建的独立审查/验证工作项,视为已授权启动对应 subagent;无需再次询问用户。主会话不得自批这些工作项。
|
|
@@ -42,6 +42,10 @@ argument-hint: "本次架构审查说明"
|
|
|
42
42
|
|
|
43
43
|
- `proposal.md` 的 `## Impact` 应通过 `Area` / `Reason` 说明受影响区域和原因;如果只有泛目录、没有原因或把 `Area` 当路径白名单,应提出阻塞或风险
|
|
44
44
|
- `design.md` 应记录关键决策、替代方案和风险取舍;如果只是复制影响范围、任务清单或实现步骤,说明设计边界不清
|
|
45
|
+
- 当 discovery 含 `## 输入数据来源核查` 时,审查 `数据来源` 是否追到目标字段或集合最后一次会改变形态的位置;停在 consumer、validator、DTO 名称或机械一跳上游,应提出阻塞或风险
|
|
46
|
+
- 审查设计是否把输入完整性决策和 consumer 算法决策分开;如果把“数据是否加载完整”和“如何比较/计算”混成一个决策,应要求拆清
|
|
47
|
+
- 相关 `IDC-xxx` 为 `未知阻塞` 时,设计不得 ready;`未知非阻塞` 必须说明为什么不影响验收,并绑定验收口径或反例
|
|
48
|
+
- 审查边界保护:输入来源修复不得无说明地扩大相邻规则、查询、缓存或数据形态的语义
|
|
45
49
|
- `tasks.md` 可以用 Markdown 标题分组,但可执行边界必须落到顶格 checkbox 叶子 task
|
|
46
50
|
- 任务分组应贴合系统边界;高风险模块、跨入口行为或难以 review 的大改动,应要求拆成可独立验证的 task
|
|
47
51
|
- 如果分组标题、task id 或任务文本会让执行者容易启动错任务,应使用 `verdict:"fail"`
|
|
@@ -51,6 +51,10 @@ argument-hint: "本次反方审查说明"
|
|
|
51
51
|
- `影响范围候选` 中每个主要候选应有至少一个 `path:line` 或等价文档锚点;无法验证时必须标明不确定性。
|
|
52
52
|
- 风险必须绑定具体代码、行为、数据或文档事实。
|
|
53
53
|
- 未验证假设、会影响范围或验收的问题必须进入 `## 待确认问题`,或明确说明为什么非阻塞。
|
|
54
|
+
- discovery 必须含 `## 输入数据来源核查`,缺失用 `verdict:"fail"`。无运行时数据依赖(纯文档/改名/配置)时该段一行写明**具体原因**,只写"无依赖"按空话判 `verdict:"fail"`。
|
|
55
|
+
- 有运行时数据依赖却只分析 consumer/validator/算法、没追到上游数据来源(查询/装配/过滤/缓存/转换),用 `verdict:"fail"`。
|
|
56
|
+
- `区分依据` 必须可证伪(断点/日志/反例/静态锚点);`代码审查` / `见上` / `对照实现` 这类不可证伪写法按未核查处理,`verdict:"fail"`。
|
|
57
|
+
- `未知阻塞` 必须进入 `## 待确认问题` 的 `- [ ]`;`未知非阻塞` 必须说明为什么不影响验收并绑定验收口径或反例,否则按阻塞问题处理。
|
|
54
58
|
|
|
55
59
|
代码影响型 discovery 缺少事实锚点、需求理解与当前实现脱节、或把未验证假设当成事实时,使用 `verdict:"fail"`。
|
|
56
60
|
|
|
@@ -70,6 +74,8 @@ argument-hint: "本次反方审查说明"
|
|
|
70
74
|
- task id 重复、不稳定,或分组标题混入 task id,导致后续执行命令容易指错任务
|
|
71
75
|
- 普通说明或缩进 checkbox 承载了实际未完成工作,导致工作流无法自然推进
|
|
72
76
|
- task 中写入 RED/GREEN 命令、断言或预期输出,导致任务计划和实际执行证据混在一起
|
|
77
|
+
- 当 discovery 含 `## 输入数据来源核查` 时,`proposal.md ## Impact` 的相关 `Reason` 未引用对应 `IDC-xxx` 状态,导致 upstream data source 与影响范围脱节
|
|
78
|
+
- `design.md` 在相关 `IDC-xxx` 为 `未知阻塞` 时仍声称设计 ready,或把输入完整性问题只当普通风险处理
|
|
73
79
|
|
|
74
80
|
发现这些问题时使用 `verdict:"fail"`,并给出最小拆分或补充建议。
|
|
75
81
|
|
|
@@ -15,6 +15,8 @@ argument-hint: "本次执行说明"
|
|
|
15
15
|
- 不要修改 `proposal.md`/`design.md`/`tasks.md`/`specs/**`/`.superspec/**`,也不要写正式 evidence、ledger、review report 或 archive artifact。
|
|
16
16
|
- 不要勾选 task,不要运行 change-level review,不要替代 `code-reviewer`、`verifier` 或主流程判断。
|
|
17
17
|
- 如果 write scope 缺失、不安全、上下文不足、测试命令不明确或必须扩大范围,停止并报告 blocker。
|
|
18
|
+
- 如果实现过程中发现实际输入数据来源、字段形态或 producer-to-consumer 链路与 discovery 的 `输入数据来源核查` 不一致,停止扩大实现并报告 blocker;不要在 apply 阶段悄悄补改 proposal/design/test-contract 或扩大任务范围。
|
|
19
|
+
- 如果用户在本任务期间补充最新业务规则、产品口径、验收标准、示例规范或影响范围,停止实现并报告 blocker;不要把这类自然语言输入当作本 task 的实现授权。
|
|
18
20
|
|
|
19
21
|
## 本次任务说明
|
|
20
22
|
|
|
@@ -33,6 +33,13 @@ argument-hint: "本次探索说明"
|
|
|
33
33
|
- 风险和隐性约束
|
|
34
34
|
- 需要主流程确认的问题
|
|
35
35
|
|
|
36
|
+
### 输入数据来源核查
|
|
37
|
+
|
|
38
|
+
默认必做,每个 discovery 都要有 `## 输入数据来源核查`:
|
|
39
|
+
|
|
40
|
+
- 无运行时数据依赖:一行写明**具体原因**(不只是"无依赖")。
|
|
41
|
+
- 有依赖:逐项给 `消费位置 / 必需输入 / 数据来源 / 区分依据 / 状态`。`数据来源` 追到 producer 侧目标字段最后一次变形处(查询/组装/过滤/缓存/转换),不停在 consumer/validator/DTO。`区分依据` 须可证伪(断点/日志/反例/锚点),`代码审查`/`见上`/`对照实现` 不合格。`未知阻塞` 进 `## 待确认问题`。
|
|
42
|
+
|
|
36
43
|
## 输出风格
|
|
37
44
|
|
|
38
45
|
- 所有用户可见输出必须使用简体中文。
|
|
@@ -47,6 +47,16 @@ argument-hint: "本次测试审查说明"
|
|
|
47
47
|
- `tdd_required:false` 必须有明确 `no_tdd_reason`
|
|
48
48
|
- 不要求建立新的 test-contract 关联,也不要求把 RED/GREEN 细节塞回 task 行
|
|
49
49
|
|
|
50
|
+
## 输入数据覆盖审查口径
|
|
51
|
+
|
|
52
|
+
当 discovery 的 `## 输入数据来源核查` 段中存在 `IDC-xxx` 核查项,或明确描述运行时 producer-to-consumer 输入数据依赖时,`test-contract.md` 应包含 `## 输入数据覆盖验证`,并说明 producer 到 consumer 的输入完整性如何证明。
|
|
53
|
+
|
|
54
|
+
如果该段明确写明无运行时数据依赖并给出具体原因,不要求 `## 输入数据覆盖验证`;但原因空泛、与改动范围矛盾,或疑似遗漏运行时数据依赖时,应使用 `verdict:"fail"`。
|
|
55
|
+
|
|
56
|
+
可接受的证明方式包括源码锚点、fixture、targeted test、日志或 trace;不强制集成测试,但必须说明证明力。只证明 consumer 算法正确、没有证明目标输入从 producer 进入 consumer 时,应使用 `verdict:"fail"`。
|
|
57
|
+
|
|
58
|
+
`未知非阻塞` 的测试策略必须说明为什么该未知不影响验收;缺少说明时按覆盖缺口处理。
|
|
59
|
+
|
|
50
60
|
## 输出风格
|
|
51
61
|
|
|
52
62
|
- 所有用户可见输出必须使用简体中文。
|
|
@@ -56,6 +56,10 @@ apply worker report 字段以本次任务说明中的 `verifier_report_required_
|
|
|
56
56
|
- 缺少 `attempt_id`、只靠 `task_structure_digest` 匹配的 test-run 只能视为旧数据兼容,不作为新流程“确实跑了红绿验证”的强证明
|
|
57
57
|
- test-run 证据应说明目标测试身份、`test_id`、`command`、`cwd`、`exit_code` 和 `semantic_status`;退出码本身不等于证明,环境错误 / 构建错误不算 RED/GREEN
|
|
58
58
|
- 可追溯性以引擎记录的 test-run 事件、`raw_index` 和 `raw_digest` 为准;额外日志或 test-runner report 只作为补充引用
|
|
59
|
+
- 当 discovery 的 `## 输入数据来源核查` 段中存在 `IDC-xxx` 核查项,或明确存在运行时 producer-to-consumer 输入数据依赖时,核对相关 `IDC-xxx` / 输入链路是否闭环:`未知阻塞` 不得进入完成结论,`未知非阻塞` 必须有不影响验收的理由,`test-contract.md` 必须有对应 `输入数据覆盖验证`
|
|
60
|
+
- discovery 明确说明无运行时数据依赖并给出具体原因时,不要求 `test-contract.md` 增加 `输入数据覆盖验证`;但不得用空泛“无依赖”跳过来源检查
|
|
61
|
+
- 没有 producer-to-consumer 证据时,只能作为未完成风险或已确认的非阻塞例外记录;不得用“明确残余风险”替代完成证明
|
|
62
|
+
- 不得只用 GREEN 测试或 task 勾选证明输入完整性;如果测试只覆盖 consumer 算法而没有 producer-to-consumer 证据,应输出 `verdict:"fail"`
|
|
59
63
|
|
|
60
64
|
## 输出风格
|
|
61
65
|
|
|
@@ -66,6 +66,7 @@ no-TDD 任务(tdd_required:false + no_tdd_reason)跳过 RED/GREEN。
|
|
|
66
66
|
- 需要判断影响范围或改动原因不自明时,参考 `proposal.md` 的 `## Impact`,但不要把它当作路径白名单
|
|
67
67
|
- 编码时发现未列入影响范围的文件,如果从 diff 或引用链能直接解释为同一任务下的局部引用、测试辅助或机械连带改动,可以继续
|
|
68
68
|
- 如果发现新增能力、用户可见行为、明显新增影响范围或原因不自明,停止扩大实现并报告给主流程;不要在 apply 阶段补改 `proposal.md`
|
|
69
|
+
- 用户在 apply 期间或 apply 后补充“最新要求”时,先判断它是否改变业务规则、产品口径、验收标准、示例规范、兼容策略或影响范围;若改变,停止实现并交回主流程使用 `superspec-propose` 更新相关计划文档,不把自然语言当作 task 授权
|
|
69
70
|
- 不修改 `proposal.md`、`design.md`、`specs/**` 或 `.superspec/**`
|
|
70
71
|
- active attempt 期间不要修改 `tasks.md` 中除 `task-complete` 自动勾选目标 checkbox 外的内容
|
|
71
72
|
- 不跳过 RED 直接写 GREEN
|
|
@@ -8,7 +8,7 @@ metadata:
|
|
|
8
8
|
|
|
9
9
|
# SuperSpec Archive
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
你是归档阶段。职责:用户明确确认归档后,执行归档——保全清单记录当前文档指纹。
|
|
12
12
|
|
|
13
13
|
## 驱动方式
|
|
14
14
|
|
|
@@ -19,11 +19,13 @@ metadata:
|
|
|
19
19
|
3. 回到 1
|
|
20
20
|
|
|
21
21
|
如果下一步提示还有用户确认、审查或验证事项,先完成这些事项。完成前不要归档或宣布流程完成;对用户说明时使用自然语言,不默认复述内部 JSON 字段或完整 packet。
|
|
22
|
+
如果 next 返回 `archive_confirmation`,不要自行确认;只有用户明确要求归档时才执行 archive。
|
|
22
23
|
|
|
23
24
|
## 本阶段做什么
|
|
24
25
|
|
|
25
|
-
1.
|
|
26
|
-
2.
|
|
26
|
+
1. **确认用户已要求归档**
|
|
27
|
+
2. **确认状态为 accepted**:next 会检查
|
|
28
|
+
3. **archive**:`superspec transition archive --change "<change>"`
|
|
27
29
|
- 引擎记录当前文档指纹(proposal/tasks/design/discovery/bi/test-contract/specs)作为保全清单
|
|
28
30
|
- 状态推进到 archive(终态)
|
|
29
31
|
|
|
@@ -31,5 +33,6 @@ metadata:
|
|
|
31
33
|
|
|
32
34
|
- 不改文档内容(归档前应已定稿)
|
|
33
35
|
- 不跳过 accept 直接 archive
|
|
36
|
+
- 不替用户确认归档
|
|
34
37
|
- archive 后不可逆——确认无误再提交
|
|
35
38
|
- 不跳过 transition
|
|
@@ -69,6 +69,9 @@ metadata:
|
|
|
69
69
|
## 风险和边界
|
|
70
70
|
- 技术风险、依赖、兼容性;尽量绑定代码或文档锚点
|
|
71
71
|
|
|
72
|
+
## 输入数据来源核查
|
|
73
|
+
- 默认必做。无运行时数据依赖(纯文档/改名/配置)写明具体原因;有依赖见下方表格逐项核查。
|
|
74
|
+
|
|
72
75
|
## 待确认问题
|
|
73
76
|
- [ ] 问题1的描述
|
|
74
77
|
- [ ] 问题2的描述
|
|
@@ -79,6 +82,22 @@ metadata:
|
|
|
79
82
|
|
|
80
83
|
代码影响型需求的 `当前代码事实`、`影响范围候选`、`风险和边界` 应尽量包含 `path:line` 锚点。纯文档、配置或新文件任务没有代码锚点时,写明 `N/A` 理由并引用相关文档、配置或需求来源。
|
|
81
84
|
|
|
85
|
+
### 输入数据来源核查
|
|
86
|
+
|
|
87
|
+
默认必做,不是可选项。`## 输入数据来源核查` 段必须存在:
|
|
88
|
+
|
|
89
|
+
- 无运行时数据依赖(纯文档/改名/配置):一行写明**具体原因**,不是"无依赖"三个字。
|
|
90
|
+
- 有运行时数据依赖:按下表逐项核查。
|
|
91
|
+
|
|
92
|
+
| 核查ID | 消费位置 | 必需输入 | 数据来源 | 区分依据 | 状态/理由 |
|
|
93
|
+
|---|---|---|---|---|---|
|
|
94
|
+
| IDC-001 | 入口/规则/算法 | 字段/集合/枚举/状态 | 查询/组装/过滤/缓存/转换位置 | 见下 | 已证明 / 未知阻塞 / 未知非阻塞 |
|
|
95
|
+
|
|
96
|
+
- `数据来源` 追到 producer 侧目标字段**最后一次变形处**(查询、组装、过滤、缓存、转换);停在 consumer、validator、DTO 名或机械一跳上游,不算追到。
|
|
97
|
+
- `区分依据` 必须是**可证伪观测**(断点、日志、反例、静态锚点),能区分"规则算法错"和"输入数据缺"。`代码审查` / `见上` / `对照实现` 这类不可证伪写法不合格。
|
|
98
|
+
- `未知阻塞`(影响目标行为成立)必须同时进 `## 待确认问题` 的 `- [ ]`,否则引擎不拦。
|
|
99
|
+
- `未知非阻塞` 必须写明为何不影响验收并绑定验收口径或反例;理由缺失按 `未知阻塞` 处理。
|
|
100
|
+
|
|
82
101
|
## Guardrails
|
|
83
102
|
|
|
84
103
|
- 不改业务代码
|
|
@@ -47,6 +47,7 @@ SuperSpec 只增加一个轻量要求:在 OpenSpec 原生 `## Impact` 段落
|
|
|
47
47
|
- `proposal.md` 说明为什么要做、做什么、能力变化和影响范围
|
|
48
48
|
- `Area` 可以写代码区域、API、依赖、系统、配置或文档
|
|
49
49
|
- `Reason` 只解释为什么该范围受影响,不写详细实现方案
|
|
50
|
+
- discovery 含 `## 输入数据来源核查` 的 IDC 项时,相关 `Reason` 须引用对应 `IDC-xxx` 状态(`已证明` / `未知阻塞` / `未知非阻塞`)
|
|
50
51
|
- `Area` 不作为路径白名单
|
|
51
52
|
- 不写任务拆分
|
|
52
53
|
- 只有存在阻塞确认项时才增加 `## 待用户确认`
|
|
@@ -61,6 +62,7 @@ OpenSpec 能力规范增量(`openspec instructions specs` 格式)。
|
|
|
61
62
|
- `design.md` 写技术方案、关键决策、替代方案和风险取舍
|
|
62
63
|
- 不复制 `proposal.md` 的影响范围表
|
|
63
64
|
- 不写任务拆分
|
|
65
|
+
- discovery 含 `## 输入数据来源核查` 且影响设计成立时,记录输入完整性决策;相关 `IDC-xxx` 为 `未知阻塞` 时设计不得标 ready
|
|
64
66
|
- 只有存在阻塞确认项时才增加 `## 待用户确认`
|
|
65
67
|
|
|
66
68
|
### tasks.md
|
|
@@ -113,6 +115,14 @@ OpenSpec 能力规范增量(`openspec instructions specs` 格式)。
|
|
|
113
115
|
| TEST-002 | INV-002 | 订单金额为负时拒绝 |
|
|
114
116
|
```
|
|
115
117
|
|
|
118
|
+
如果 discovery 含 `## 输入数据来源核查` 的 IDC 项,在测试表后增加 `## 输入数据覆盖验证`:
|
|
119
|
+
|
|
120
|
+
| 核查ID | 验证方式 | 输入链路声明 | 证据或计划 |
|
|
121
|
+
|---|---|---|---|
|
|
122
|
+
| IDC-001 | 源码锚点 + 聚焦测试 | producer 产生的目标输入会进入 consumer | src/path.ts:10 + TEST-001 |
|
|
123
|
+
|
|
124
|
+
证明方式可用源码锚点、fixture、targeted test、日志或 trace,须说明证明力;不强制集成测试。只证 consumer 算法、没证 producer→consumer 输入完整性,测试契约不足。
|
|
125
|
+
|
|
116
126
|
### 待用户确认
|
|
117
127
|
如果计划阶段遇到会影响需求范围、验收标准、用户可见行为、方案取舍、测试策略、安全、权限、数据或迁移判断的关键不确定问题,先写入相关计划文档的 `## 待用户确认` 段落:
|
|
118
128
|
|
|
@@ -8,7 +8,7 @@ metadata:
|
|
|
8
8
|
|
|
9
9
|
# SuperSpec Review
|
|
10
10
|
|
|
11
|
-
你是审查阶段。职责:最终审查——验证实现质量、处理 verifier 最终验证工作项、推进到
|
|
11
|
+
你是审查阶段。职责:最终审查——验证实现质量、处理 verifier 最终验证工作项、推进到 accepted,并等待用户确认归档。
|
|
12
12
|
|
|
13
13
|
## 驱动方式
|
|
14
14
|
|
|
@@ -20,6 +20,7 @@ metadata:
|
|
|
20
20
|
4. 回到 1
|
|
21
21
|
|
|
22
22
|
如果下一步提示当前阶段还有用户确认、审查或验证事项,先完成这些事项。完成前不要 accept 或 archive;对用户说明时使用自然语言,不默认复述内部 JSON 字段或完整 packet。
|
|
23
|
+
当 next 在 `accepted` 状态返回归档确认提示时,停止循环并提醒用户确认归档;不要自行执行 archive。
|
|
23
24
|
|
|
24
25
|
如果下一步需要 verifier 工作项,先按返回的验证说明执行核对,再优先用 `superspec record job-submit --change "<change>" --job <JOB> --report -` 从 stdin 提交 JSON 验证报告内容;文件路径模式仍可作为 fallback。
|
|
25
26
|
|
|
@@ -30,6 +31,7 @@ metadata:
|
|
|
30
31
|
1. **确认所有任务完成**:review-ready 会检查 tasks.md 无未完成项
|
|
31
32
|
2. **处理 verifier**:核对 proposal + 实现 + 测试契约一致性
|
|
32
33
|
3. **accept**:`superspec transition accept --change "<change>"`
|
|
34
|
+
4. **等待归档确认**:accepted 后不要自动 archive,交给用户确认
|
|
33
35
|
|
|
34
36
|
## verifier gate 规则
|
|
35
37
|
|
|
@@ -44,5 +46,6 @@ metadata:
|
|
|
44
46
|
|
|
45
47
|
- 不改业务代码(审查阶段只读)
|
|
46
48
|
- 不跳过 verifier 最终验证直接 accept
|
|
49
|
+
- 不在 accepted 后自动 archive
|
|
47
50
|
- 审查报告必须真实引用文件内容,不编造
|
|
48
51
|
- 不跳过 transition
|