@xulthekl/team-flow 0.36.2 → 0.36.3

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 (42) hide show
  1. package/.claude/always/phase-guard.md +1 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/.cursor-plugin/marketplace.json +1 -1
  6. package/.cursor-plugin/plugin.json +1 -1
  7. package/.github/plugin/marketplace.json +2 -2
  8. package/AGENTS.md +4 -4
  9. package/CHANGELOG.md +16 -0
  10. package/GEMINI.md +1 -1
  11. package/INSTALL.md +1 -1
  12. package/README.md +2 -2
  13. package/agents/architecture-design.md +24 -4
  14. package/agents/architecture-reviewer.md +10 -6
  15. package/agents/cross-change-consistency-checker.md +2 -1
  16. package/docs/README_en.md +1 -1
  17. package/gemini-extension.json +1 -1
  18. package/hooks/pre-tool-use-guard +15 -0
  19. package/hooks/session-start +2 -2
  20. package/llms.txt +1 -1
  21. package/package.json +1 -1
  22. package/plugin.json +1 -1
  23. package/scripts/guard/checks/arch-gate-exemptions.mjs +32 -17
  24. package/scripts/guard/checks/arch-snapshot.mjs +7 -0
  25. package/scripts/lib/arch-merge.mjs +22 -6
  26. package/scripts/lib/cmd-doctor.mjs +27 -0
  27. package/scripts/lib/solutions-capture.mjs +1 -1
  28. package/skills/architecture-design/SKILL.md +14 -0
  29. package/skills/architecture-design/chapters/ch06-integration.md +2 -2
  30. package/skills/architecture-design/references/s3.5-architecture-template.md +1 -1
  31. package/skills/architecture-design/references/s3.5-loading-protocol.md +1 -1
  32. package/skills/architecture-design/references/s3.5-product-architecture.md +13 -1
  33. package/skills/ce-compound/references/v0.5-upgrade.md +3 -0
  34. package/skills/release-archivist/SKILL.md +2 -0
  35. package/skills/workflow-bootstrap/SKILL.md +8 -5
  36. package/skills/workflow-bootstrap/references/b1-reconnaissance.md +2 -2
  37. package/skills/workflow-orchestrator/SKILL.md +1 -1
  38. package/skills/workflow-orchestrator/references/s4-split-validate.md +2 -1
  39. package/skills/workflow-orchestrator/references/s5-monitoring.md +1 -0
  40. package/skills/workflow-orchestrator/references/state-model.md +1 -1
  41. package/skills/workflow-start/references/routing-rules.md +2 -0
  42. package/wave-batch-receipt-analysis-report.md +0 -561
@@ -1,561 +0,0 @@
1
- # Wave/Batch/Receipt 实现分析报告
2
-
3
- ## 1. Execution Plan 相关文件
4
-
5
- ### 核心文件路径
6
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/lib/execution-plan.mjs`
7
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/lib/cmd-execution.mjs`
8
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/lib/execution-recommendation.mjs`
9
-
10
- ### Wave 数据结构定义
11
-
12
- ```javascript
13
- // 从 execution-plan.mjs 和测试文件中提取
14
- {
15
- id: string, // wave 唯一标识,如 'wave-1', 'foundation'
16
- strategy: 'serial' | 'parallel', // 执行策略
17
- tasks: string[], // 任务 ID 列表,如 ['1.1', '1.2']
18
- depends_on: string[] // 依赖的其他 wave ID 列表,如 ['wave-1', 'foundation']
19
- }
20
- ```
21
-
22
- ### Execution Plan 完整数据结构
23
-
24
- ```javascript
25
- {
26
- mode: 'inline' | 'batch-inline' | 'sdd', // 执行模式(EXECUTION_MODES)
27
- source: string, // 计划来源,如 'user-confirmed', 'user-confirmed-revision'
28
- rationale: string, // 选择该模式的理由
29
- waves: Wave[], // wave 数组
30
- artifacts_hash: string, // 制品哈希(sha256:...)
31
- contract_hash: string, // 契约哈希(sha256:...)
32
- workflow: string, // 工作流类型:'full' | 'hotfix' | 'tweak'
33
- revision: number, // 修订版本号
34
- hash: string, // 计划内容哈希(sha256:...)
35
- recommendation?: { // 推荐信息(full/hotfix 必需)
36
- available_modes: string[],
37
- recommendation: {
38
- mode: string,
39
- reasons: string[]
40
- },
41
- facts: object
42
- },
43
- recommendation_receipt?: { // 推荐凭证(full/hotfix 必需)
44
- recommendation: object,
45
- waves: Wave[],
46
- artifacts_hash: string,
47
- contract_hash: string,
48
- workflow: string,
49
- execution_plan_revision_at_recommendation: number | null,
50
- created_at: string,
51
- hash: string
52
- },
53
- selection?: { // 用户选择信息(full/hotfix 必需)
54
- confirmed: boolean,
55
- followed_recommendation: boolean,
56
- acknowledged_non_recommendation: boolean
57
- }
58
- }
59
- ```
60
-
61
- ### 关键代码片段
62
-
63
- **创建计划 (execution-plan.mjs:14-33)**
64
- ```javascript
65
- export function createPlan(changeDir, input) {
66
- const state = readState(changeDir);
67
- const plan = {
68
- mode: input?.mode,
69
- source: input?.source,
70
- rationale: input?.rationale,
71
- waves: input?.waves,
72
- artifacts_hash: computeArtifactsHash(changeDir),
73
- contract_hash: computeContractHash(changeDir),
74
- workflow: state.workflow,
75
- revision: input?.revision ?? state.revision ?? 1,
76
- };
77
- // ... validation and hash computation
78
- }
79
- ```
80
-
81
- **Wave 解析 (cmd-execution.mjs:163-178)**
82
- ```javascript
83
- function parseWaves(values) {
84
- // 格式: <id>:<strategy>:<task,...>[:<depends-on,...>]
85
- // 示例: 'wave-1:parallel:1.1,1.2' 或 'wave-2:serial:2.1:wave-1'
86
- return values.map(value => {
87
- const [id, strategy, taskList, dependencyList, ...extra] = value.split(':');
88
- const tasks = taskList.split(',').map(task => task.trim()).filter(Boolean);
89
- const depends_on = dependencyList === undefined ? [] : dependencyList.split(',').map(id => id.trim()).filter(Boolean);
90
- return { id, strategy, tasks, depends_on };
91
- });
92
- }
93
- ```
94
-
95
- ---
96
-
97
- ## 2. Receipt 相关实现
98
-
99
- ### 核心文件路径
100
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/lib/execution-plan.mjs` (recordReview, readCurrentReview)
101
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/guard/checks/execution-reviews-passed.mjs`
102
-
103
- ### Review Receipt 数据结构
104
-
105
- ```javascript
106
- {
107
- status: 'pass' | 'fail', // 审查状态
108
- base: string, // git base commit hash(完整 SHA)
109
- head: string, // git head commit hash(完整 SHA)
110
- report: string, // 审查报告文件路径(相对于 change 目录)
111
- tests?: { // 可选的测试统计(v0.13 §51.2)
112
- total: number, // 测试总数
113
- passed: number, // 通过数
114
- failed: number // 失败数
115
- },
116
- plan_hash: string, // 关联的执行计划哈希
117
- plan_revision: number, // 关联的执行计划修订版本
118
- recorded_at: string // 记录时间(ISO 格式)
119
- }
120
- ```
121
-
122
- ### Receipt 存储位置
123
- ```
124
- <change-dir>/.superpowers/sdd/reviews/<base64url-encoded-wave-id>.json
125
- ```
126
-
127
- ### Receipt 校验逻辑 (execution-plan.mjs:133-177)
128
-
129
- ```javascript
130
- export function recordReview(changeDir, waveId, receipt) {
131
- // 1. 验证计划有效性
132
- const plan = readPlan(changeDir);
133
- const validation = validatePlan(changeDir, plan);
134
- if (!validation.valid) throw new Error(...);
135
-
136
- // 2. 验证 wave 是否存在于计划中
137
- const wave = plan.waves.find(candidate => candidate?.id === waveId);
138
- if (!wave) throw new Error(`Review receipt references unknown wave '${waveId}'`);
139
-
140
- // 3. 检查依赖是否已通过(阻塞依赖检查)
141
- const blockedBy = blockedDependencies(changeDir, plan, wave);
142
- if (blockedBy.length > 0) {
143
- throw new Error(`Wave '${waveId}' cannot be reviewed before dependencies have passing receipts: ${blockedBy.join(', ')}`);
144
- }
145
-
146
- // 4. 验证 status
147
- if (!REVIEW_STATUSES.has(receipt?.status)) {
148
- throw new Error("Review receipt status must be 'pass' or 'fail'");
149
- }
150
-
151
- // 5. 验证 base 和 head
152
- for (const field of ['base', 'head']) requireText(receipt?.[field], `receipt.${field}`);
153
-
154
- // 6. 验证 report 文件
155
- const report = validateReviewReportEvidence(changeDir, receipt?.report);
156
-
157
- // 7. 验证 git 范围(禁止空 diff)
158
- const { base, head } = validateReviewRange(changeDir, receipt.base, receipt.head);
159
- // 关键校验:base !== head(禁止 base==head 空 diff review)
160
- if (resolvedBase === resolvedHead) {
161
- throw new Error('Review receipt base must differ from head...');
162
- }
163
-
164
- // 8. 验证 base 是 head 的祖先
165
- execFileSync('git', ['-C', gitRoot, 'merge-base', '--is-ancestor', resolvedBase, resolvedHead]);
166
-
167
- // 9. 保存 receipt
168
- const savedReceipt = {
169
- status: receipt.status,
170
- base, head, report,
171
- ...(tests ? { tests } : {}),
172
- plan_hash: plan.hash,
173
- plan_revision: plan.revision,
174
- recorded_at: new Date().toISOString(),
175
- };
176
- atomicWrite(join(paths.reviews, `${safeFileName(waveId)}.json`), JSON.stringify(savedReceipt));
177
- }
178
- ```
179
-
180
- ### 读取当前 Receipt (execution-plan.mjs:183-200)
181
-
182
- ```javascript
183
- export function readCurrentReview(changeDir, waveId, plan = readPlan(changeDir)) {
184
- // 1. 检查 receipt 文件是否存在
185
- // 2. 验证 plan_hash 和 plan_revision 匹配当前计划
186
- // 3. 验证 base/head 范围仍然有效
187
- // 4. 对于 passing receipt,验证 report 文件仍然安全可读
188
- if (receipt?.status === 'pass') validateReviewReportEvidence(changeDir, receipt.report);
189
- return receipt;
190
- }
191
- ```
192
-
193
- ---
194
-
195
- ## 3. state-loader.mjs 中的字段
196
-
197
- ### 核心文件路径
198
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/lib/state-loader.mjs`
199
-
200
- ### BUILTIN_DEFAULTS 中的相关字段
201
-
202
- ```javascript
203
- const BUILTIN_DEFAULTS = {
204
- // 核心状态
205
- state: 'exploring',
206
- workflow: 'auto',
207
- revision: null,
208
-
209
- // 哈希校验
210
- artifacts_hash: null,
211
- contract_hash: null,
212
-
213
- // 执行进度(与 wave/batch/execution 相关)
214
- execution_mode: null, // 执行模式:'inline' | 'batch-inline' | 'sdd'
215
- execution_plan_hash: null, // 执行计划哈希
216
- execution_plan_revision: null, // 执行计划修订版本
217
- batches_completed: 0, // 已完成的批次数量
218
- test_result: null, // 测试结果
219
- spec_merged: false, // 规格是否已合并
220
-
221
- // 其他字段...
222
- };
223
- ```
224
-
225
- ### 关键代码片段
226
-
227
- **写入状态 (state-loader.mjs:92-188)**
228
- ```javascript
229
- export function writeState(changeDir, state) {
230
- // 序列化到 .team-flow.yaml
231
- lines.push('# === Execution progress ===');
232
- lines.push(`execution_mode: ${state.execution_mode ?? 'null'}`);
233
- lines.push(`execution_plan_hash: ${state.execution_plan_hash ?? 'null'}`);
234
- lines.push(`execution_plan_revision: ${state.execution_plan_revision ?? 'null'}`);
235
- lines.push(`batches_completed: ${state.batches_completed ?? 0}`);
236
- lines.push(`test_result: ${state.test_result ?? 'null'}`);
237
- lines.push(`spec_merged: ${state.spec_merged ?? false}`);
238
- }
239
- ```
240
-
241
- ---
242
-
243
- ## 4. guard.mjs 中的 Wave 门控逻辑
244
-
245
- ### 核心文件路径
246
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/guard/guard.mjs`
247
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/guard/checks/execution-plan-ready.mjs`
248
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/guard/checks/execution-reviews-passed.mjs`
249
-
250
- ### 门控转换矩阵
251
-
252
- ```javascript
253
- // guard.mjs 中定义的转换检查维度
254
- const TRANSITION_CHECKS = {
255
- 'approved-for-build:executing': [
256
- 'artifacts-exist',
257
- 'contract-fresh',
258
- 'dp-gate-passed',
259
- 'execution-plan-ready', // ★ 执行计划就绪检查
260
- 'test-matrix-ready'
261
- ],
262
- 'executing:closing': [
263
- 'tasks-complete',
264
- 'tests-passing',
265
- 'specs-merged',
266
- 'execution-plan-ready', // ★ 执行计划就绪检查
267
- 'execution-reviews-passed', // ★ 所有 wave receipt 通过检查
268
- 'compound-captured',
269
- 'test-matrix-complete',
270
- 'arch-snapshot'
271
- ],
272
- 'debugging:executing': [
273
- 'contract-fresh',
274
- 'execution-plan-ready' // ★ 从 debugging 返回时也检查
275
- ],
276
- };
277
-
278
- // Workflow 特定检查
279
- const WORKFLOW_TRANSITION_CHECKS = {
280
- hotfix: {
281
- 'approved-for-build:executing': ['contract-current', 'dp3-approved', 'execution-plan-ready'],
282
- 'executing:closing': ['tasks-complete', 'tests-passing', 'specs-merged', 'execution-plan-ready', 'execution-reviews-passed', 'compound-captured'],
283
- },
284
- tweak: {
285
- // Tweak 豁免 execution-plan 和 review receipt 检查
286
- 'approved-for-build:executing': ['artifacts-exist', 'contract-fresh', 'dp-gate-passed'],
287
- 'executing:closing': ['tasks-complete', 'tests-passing', 'specs-merged'],
288
- },
289
- };
290
- ```
291
-
292
- ### execution-plan-ready 检查逻辑 (execution-plan-ready.mjs)
293
-
294
- ```javascript
295
- export function checkExecutionPlanReady(changeDir) {
296
- // 1. 检查执行计划是否存在
297
- const plan = readPlan(changeDir);
298
- if (!plan) {
299
- return { pass: false, failures: ['execution plan is missing...'] };
300
- }
301
-
302
- // 2. 验证计划有效性
303
- const validation = validatePlan(changeDir, plan);
304
- if (!validation.valid) {
305
- return { pass: false, failures: validation.failures };
306
- }
307
-
308
- // 3. 验证 DP-4 引用了当前计划修订版本
309
- const state = readState(changeDir);
310
- const revisionReference = new RegExp(`\\bplan revision\\s+${plan.revision}\\b`, 'i');
311
- if (!revisionReference.test(decision)) {
312
- return { pass: false, failures: [`DP-4 must precisely reference current plan revision...`] };
313
- }
314
-
315
- return { pass: true, failures: [] };
316
- }
317
- ```
318
-
319
- ### execution-reviews-passed 检查逻辑 (execution-reviews-passed.mjs)
320
-
321
- ```javascript
322
- export function checkExecutionReviewsPassed(changeDir) {
323
- // 1. 读取执行计划
324
- const plan = readPlan(changeDir);
325
- if (!plan) return { pass: true, failures: [] }; // tweak 豁免
326
-
327
- // 2. 验证计划有效性
328
- const validation = validatePlan(changeDir, plan);
329
- if (!validation.valid) return { pass: false, failures: validation.failures };
330
-
331
- // 3. 遍历所有 wave,检查 receipt
332
- const failures = [];
333
- for (const wave of plan.waves) {
334
- const receipt = readCurrentReview(changeDir, wave.id, plan);
335
- if (!receipt) {
336
- failures.push(`review receipt missing for planned wave '${wave.id}'`);
337
- continue;
338
- }
339
- if (receipt?.status !== 'pass') {
340
- failures.push(`review receipt for planned wave '${wave.id}' has status '${receipt?.status}'`);
341
- }
342
- }
343
-
344
- return { pass: failures.length === 0, failures };
345
- }
346
- ```
347
-
348
- ---
349
-
350
- ## 5. depends_on 和拓扑相关实现
351
-
352
- ### 核心文件路径
353
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/scripts/lib/execution-plan.mjs`
354
-
355
- ### 依赖验证逻辑 (execution-plan.mjs:381-433)
356
-
357
- ```javascript
358
- function validateStructure(plan) {
359
- // ...
360
-
361
- // 验证每个 wave 的 depends_on
362
- for (const [index, wave] of plan.waves.entries()) {
363
- // 1. depends_on 必须是数组
364
- if (!Array.isArray(wave.depends_on)) failures.push(`${label} depends_on must be an array`);
365
-
366
- // 2. 依赖项必须是非空字符串
367
- else if (wave.depends_on.some(id => !isNonEmptyText(id))) failures.push(`${label} dependencies must be non-empty strings`);
368
- }
369
-
370
- // 3. 验证依赖引用的有效性
371
- for (const wave of plan.waves.filter(isObject)) {
372
- for (const dependency of wave.depends_on) {
373
- // 不能自依赖
374
- if (dependency === wave.id) failures.push(`wave '${wave.id}' cannot depend on itself`);
375
- // 不能依赖不存在的 wave
376
- else if (!ids.has(dependency)) failures.push(`wave '${wave.id}' depends on unknown wave '${dependency}'`);
377
- }
378
- }
379
-
380
- // 4. 检测循环依赖
381
- if (canCheckCycles && hasDependencyCycle(plan.waves)) {
382
- failures.push('execution plan waves contain a dependency cycle');
383
- }
384
- }
385
- ```
386
-
387
- ### 循环依赖检测算法 (execution-plan.mjs:436-452)
388
-
389
- ```javascript
390
- function hasDependencyCycle(waves) {
391
- // 使用 DFS 检测有向图中的环
392
- const dependencies = new Map(waves.map(wave => [wave.id, wave.depends_on]));
393
- const visiting = new Set(); // 当前正在访问的节点(用于检测后向边)
394
- const visited = new Set(); // 已完成访问的节点
395
-
396
- const visit = id => {
397
- if (visiting.has(id)) return true; // 发现环!
398
- if (visited.has(id)) return false; // 已经检查过,无环
399
- visiting.add(id);
400
- for (const dependency of dependencies.get(id) || []) {
401
- if (visit(dependency)) return true;
402
- }
403
- visiting.delete(id);
404
- visited.add(id);
405
- return false;
406
- };
407
-
408
- return [...dependencies.keys()].some(visit);
409
- }
410
- ```
411
-
412
- ### 阻塞依赖检查 (execution-plan.mjs:324-327)
413
-
414
- ```javascript
415
- function blockedDependencies(changeDir, plan, wave) {
416
- if (!Array.isArray(wave?.depends_on)) return [];
417
- // 返回所有未通过的依赖 wave
418
- return wave.depends_on.filter(dependency =>
419
- readCurrentReview(changeDir, dependency, plan)?.status !== 'pass'
420
- );
421
- }
422
- ```
423
-
424
- ### Wave 可执行性判断 (execution-plan.mjs:207-224)
425
-
426
- ```javascript
427
- export function describeWaves(changeDir, plan = readPlan(changeDir)) {
428
- return plan.waves.map(wave => {
429
- const receipt = readCurrentReview(changeDir, wave.id, plan);
430
- const blockers = blockedDependencies(changeDir, plan, wave);
431
- const retryable = receipt?.status === 'fail';
432
- return {
433
- id: wave.id,
434
- strategy: wave.strategy,
435
- tasks: wave.tasks,
436
- depends_on: wave.depends_on,
437
- eligible: (receipt === null || retryable) && blockers.length === 0, // 可执行条件
438
- retryable,
439
- receipt,
440
- blockers,
441
- };
442
- });
443
- }
444
- ```
445
-
446
- ---
447
-
448
- ## 6. 测试文件中的示例
449
-
450
- ### 核心测试文件路径
451
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/tests/lib/execution-plan.test.mjs`
452
- - `/Users/litong/Documents/work/code/practice/team-flow-workspace/team-flow/tests/lib/guard.test.mjs`
453
-
454
- ### Wave 定义示例
455
-
456
- ```javascript
457
- // 单 wave,无依赖
458
- waves: [{ id: 'wave-1', strategy: 'serial', tasks: ['1.1'], depends_on: [] }]
459
-
460
- // 多 wave,有依赖
461
- waves: [
462
- { id: 'wave-1', strategy: 'parallel', tasks: ['1.1', '1.2'], depends_on: [] },
463
- { id: 'wave-2', strategy: 'serial', tasks: ['2.1'], depends_on: ['wave-1'] }
464
- ]
465
-
466
- // 循环依赖(会被拒绝)
467
- waves: [
468
- { id: 'wave-1', strategy: 'serial', tasks: ['1.1'], depends_on: ['wave-2'] },
469
- { id: 'wave-2', strategy: 'serial', tasks: ['1.2'], depends_on: ['wave-1'] }
470
- ]
471
-
472
- // 自依赖(会被拒绝)
473
- waves: [{ id: 'wave-1', strategy: 'parallel', tasks: ['1.1'], depends_on: ['wave-1'] }]
474
-
475
- // 依赖不存在的 wave(会被拒绝)
476
- waves: [{ id: 'wave-1', strategy: 'parallel', tasks: ['1.1'], depends_on: ['missing'] }]
477
- ```
478
-
479
- ### Receipt 记录示例
480
-
481
- ```javascript
482
- // 记录通过的 receipt
483
- const receipt = recordReview(changeDir, 'wave-1', {
484
- status: 'pass',
485
- base: gitRefs.base, // git base commit
486
- head: gitRefs.head, // git head commit
487
- report: reportPath, // 审查报告路径
488
- tests: { // 可选测试统计
489
- total: 12,
490
- passed: 11,
491
- failed: 1
492
- }
493
- });
494
-
495
- // 记录失败的 receipt
496
- const receipt = recordReview(changeDir, 'wave-2', {
497
- status: 'fail',
498
- base: gitRefs.base,
499
- head: gitRefs.head,
500
- report: reportPath
501
- });
502
- ```
503
-
504
- ### Guard 测试示例
505
-
506
- ```javascript
507
- // 测试:所有 wave 必须有 passing receipt 才能 closing
508
- it('blocks closing until every planned wave has a passing review receipt', () => {
509
- // 1. 创建计划(wave-1 和 wave-2)
510
- createCurrentPlan();
511
-
512
- // 2. 尝试 closing,应该失败(没有 receipt)
513
- let result = run('executing', 'closing');
514
- assert.equal(result.exitCode, 1);
515
- assert.match(reviewCheck.failures.join('\n'), /wave-1|receipt/i);
516
-
517
- // 3. 记录 wave-1 passing,wave-2 failing
518
- runNodeScript(CLI_PATH, ['execution', 'review', dir, '--wave', 'wave-1', ...]);
519
- runNodeScript(CLI_PATH, ['execution', 'review', dir, '--wave', 'wave-2', ..., '--verdict', 'fail']);
520
-
521
- // 4. 尝试 closing,应该失败(wave-2 failing)
522
- result = run('executing', 'closing');
523
- assert.match(reviewCheck.failures.join('\n'), /wave-2.*fail/i);
524
-
525
- // 5. 修复 wave-2 为 passing
526
- runNodeScript(CLI_PATH, ['execution', 'review', dir, '--wave', 'wave-2', ..., '--verdict', 'pass']);
527
-
528
- // 6. 尝试 closing,应该成功
529
- result = run('executing', 'closing');
530
- assert.equal(result.exitCode, 0);
531
- });
532
- ```
533
-
534
- ---
535
-
536
- ## 7. 关键设计要点总结
537
-
538
- ### Wave 设计
539
- 1. **Wave 是执行计划的基本单位**,每个 wave 包含一组任务和执行策略
540
- 2. **策略类型**:`serial`(顺序执行)和 `parallel`(并行执行)
541
- 3. **依赖关系**:通过 `depends_on` 字段定义 wave 之间的依赖
542
- 4. **拓扑约束**:禁止自依赖、禁止依赖不存在的 wave、禁止循环依赖
543
-
544
- ### Receipt 设计
545
- 1. **Receipt 是 wave 级别的审查证据**,记录在 `.superpowers/sdd/reviews/` 目录
546
- 2. **必须包含**:status、base、head、report
547
- 3. **可选包含**:tests(测试统计)
548
- 4. **关联性**:receipt 通过 plan_hash 和 plan_revision 关联到特定的执行计划版本
549
- 5. **有效性**:receipt 在计划变更后自动失效(hash 不匹配)
550
-
551
- ### 门控设计
552
- 1. **execution-plan-ready**:在进入 executing 和 closing 时检查
553
- 2. **execution-reviews-passed**:在 closing 时检查,要求所有 wave 都有 passing receipt
554
- 3. **依赖阻塞**:wave 的 receipt 记录依赖其所有 depends_on wave 的 receipt 先通过
555
- 4. **Workflow 豁免**:tweak workflow 豁免 execution-plan 和 review receipt 检查
556
-
557
- ### 状态持久化
558
- 1. **execution_mode**:记录选择的执行模式
559
- 2. **execution_plan_hash**:记录当前执行计划的哈希
560
- 3. **execution_plan_revision**:记录当前执行计划的修订版本
561
- 4. **batches_completed**:记录已完成的批次数量