@michaelxwb/code-flow 0.6.2 → 0.6.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.
- package/package.json +1 -1
- package/src/adapters/claude/commands/cf-task/archive.md +5 -5
- package/src/adapters/claude/commands/cf-task/block.md +15 -9
- package/src/adapters/claude/commands/cf-task/graph.md +8 -1
- package/src/adapters/claude/commands/cf-task/note.md +1 -4
- package/src/adapters/claude/commands/cf-task/start.md +18 -17
- package/src/adapters/claude/commands/cf-task/verify-e2e.md +8 -9
- package/src/adapters/claude/commands/cf-validate.md +12 -13
- package/src/adapters/codex/skills/cf-task-archive/SKILL.md +5 -5
- package/src/adapters/codex/skills/cf-task-block/SKILL.md +15 -9
- package/src/adapters/codex/skills/cf-task-graph/SKILL.md +8 -1
- package/src/adapters/codex/skills/cf-task-note/SKILL.md +1 -4
- package/src/adapters/codex/skills/cf-task-start/SKILL.md +18 -17
- package/src/adapters/codex/skills/cf-task-verify-e2e/SKILL.md +106 -0
- package/src/adapters/codex/skills/cf-validate/SKILL.md +12 -13
- package/src/adapters/costrict/commands/cf-task/archive.md +5 -5
- package/src/adapters/costrict/commands/cf-task/block.md +15 -9
- package/src/adapters/costrict/commands/cf-task/graph.md +8 -1
- package/src/adapters/costrict/commands/cf-task/note.md +1 -4
- package/src/adapters/costrict/commands/cf-task/start.md +18 -17
- package/src/adapters/costrict/commands/cf-task/verify-e2e.md +8 -9
- package/src/adapters/costrict/commands/cf-validate.md +12 -13
- package/src/adapters/opencode/commands/cf-task/archive.md +5 -5
- package/src/adapters/opencode/commands/cf-task/block.md +15 -9
- package/src/adapters/opencode/commands/cf-task/graph.md +8 -1
- package/src/adapters/opencode/commands/cf-task/note.md +1 -4
- package/src/adapters/opencode/commands/cf-task/start.md +18 -17
- package/src/adapters/opencode/commands/cf-task/verify-e2e.md +8 -9
- package/src/adapters/opencode/commands/cf-validate.md +12 -13
- package/src/adapters/opencode/plugins/code-flow/index.js +50 -28
- package/src/cli.js +177 -63
- package/src/core/code-flow/scripts/cf_acceptance_evidence.py +100 -0
- package/src/core/code-flow/scripts/cf_acceptance_manifest.py +85 -36
- package/src/core/code-flow/scripts/cf_acceptance_runner.py +123 -38
- package/src/core/code-flow/scripts/cf_acceptance_schema.py +83 -0
- package/src/core/code-flow/scripts/cf_core.py +6 -0
- package/src/core/code-flow/scripts/cf_exec_base.py +112 -0
- package/src/core/code-flow/scripts/cf_pre_tool_hook.py +8 -4
- package/src/core/code-flow/scripts/cf_scan.py +8 -6
- package/src/core/code-flow/scripts/cf_spec_context.py +178 -54
- package/src/core/code-flow/scripts/cf_spec_resolver.py +7 -2
- package/src/core/code-flow/scripts/cf_spec_router.py +2 -0
- package/src/core/code-flow/scripts/cf_spec_session.py +3 -2
- package/src/core/code-flow/scripts/cf_spec_verify.py +42 -31
- package/src/core/code-flow/scripts/cf_stats.py +41 -9
- package/src/core/code-flow/scripts/cf_stop_hook.py +98 -59
- package/src/core/code-flow/scripts/cf_task_index.py +147 -0
- package/src/core/code-flow/scripts/cf_task_runtime.py +62 -27
- package/src/core/code-flow/scripts/cf_task_state.py +3 -0
- package/src/core/code-flow/scripts/cf_task_workflow.py +107 -0
- package/src/core/code-flow/scripts/cf_user_prompt_hook.py +9 -5
- package/src/core/code-flow/scripts/cf_validation.py +81 -0
- package/src/core/code-flow/scripts/cf_workflow_service.py +366 -0
- package/src/core/code-flow/scripts/cf_workflow_transaction.py +96 -0
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
1. 用 Read 读取匹配到的 task 文件
|
|
18
18
|
2. 提取所有 `## TASK-xxx` 段落的 Status
|
|
19
|
-
3. 检查是否所有子任务均为 `done`
|
|
19
|
+
3. 检查是否所有子任务均为 `verified`(E2E 终验后的终态;仍为 `done` 说明 verify-e2e 尚未执行,先跑它)
|
|
20
20
|
|
|
21
21
|
若有未完成子任务,拒绝归档并输出:
|
|
22
22
|
|
|
@@ -36,24 +36,24 @@
|
|
|
36
36
|
|
|
37
37
|
- 需求目录必须存在 `spec-context.yml`;执行 `python3 .code-flow/scripts/cf_spec_context.py refresh --task-dir <需求目录> --root "$PWD" --json`
|
|
38
38
|
- 执行 `python3 .code-flow/scripts/cf_spec_gate.py --task-dir <需求目录> --stage code --json`;required Rule 的 stale/pending/conflict/unverified 任一存在即 FAIL
|
|
39
|
-
- 若 `.code-flow/.active-task.json`
|
|
39
|
+
- 若 `.code-flow/.active-task.json` 仍指向本需求,先执行 `python3 .code-flow/scripts/cf_task_workflow.py finish --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json`,通过后再 verify-e2e;不得自报 gate_passed 或通过归档绕过 active 状态
|
|
40
40
|
- Context 与 Evidence 随需求目录一并归档,`_session` 仅是可重建投影,不是事实源
|
|
41
41
|
|
|
42
|
-
所有子任务
|
|
42
|
+
所有子任务 verified 后,执行四维校验:
|
|
43
43
|
|
|
44
44
|
**完整性**:
|
|
45
45
|
- 所有 Checklist 项已勾选
|
|
46
46
|
- 全文无残留的 `#NOTES` 标记
|
|
47
47
|
|
|
48
48
|
**正确性**:
|
|
49
|
-
-
|
|
49
|
+
- 执行 `python3 .code-flow/scripts/cf_validation.py --root "$PWD" --json`;归档时任务已无 marker,须补充本需求基线至当前的变更路径作为 `--files` 参数,不能把工作区干净误认为本需求无需验证
|
|
50
50
|
- 检查本次变更涉及的文件是否通过 lint/type check
|
|
51
51
|
|
|
52
52
|
**验收追溯**:
|
|
53
53
|
- 来源 design 含结构化 S-/E-/B- 场景时,逐项对照 `## Acceptance Coverage`,P0/P1 场景以及 RULE/高影响 RISK 映射场景必须全部存在且状态为 `verified`
|
|
54
54
|
- 每个负责任务的 `Acceptance-Refs`、`Acceptance Contract`、`Acceptance Evidence` 必须闭合,不得残留 `planned` / `pending` / `TBD`
|
|
55
55
|
- 测试层级不得低于 design;E2E 的真实边界和关键断言必须有文件/用例位置与 fixture/构造证据
|
|
56
|
-
-
|
|
56
|
+
- 先用 `cf_acceptance_manifest.py --task-file "<任务文件>" --output "<需求目录>/.acceptance-manifest.json" --verify-plan` 校验基线,再用 `cf_acceptance_runner.py --manifest "<需求目录>/.acceptance-manifest.json" --root "$PWD" --include-e2e --write-evidence` 统一复验。相同 argv、cwd、timeout 的命令在单次运行内复用结果;跨运行不复用,依赖步骤不跨状态屏障复用。测试未收集、未执行或失败均为 FAIL
|
|
57
57
|
- `manual` 场景必须有用户确认和可复核记录。旧 design 没有结构化场景时注明“不适用”,不得伪造覆盖
|
|
58
58
|
|
|
59
59
|
**一致性**:
|
|
@@ -14,17 +14,23 @@
|
|
|
14
14
|
|
|
15
15
|
1. 用 Glob 定位任务文件,Read 读取
|
|
16
16
|
2. 定位 `## TASK-001` 段落,检查当前 Status:
|
|
17
|
-
- `done` → 拒绝:`TASK-001 已完成,无法标记阻塞`
|
|
17
|
+
- `done` / `verified` → 拒绝:`TASK-001 已完成,无法标记阻塞`
|
|
18
18
|
- `blocked` → 提示:`TASK-001 已处于 blocked 状态`,仍追加新的阻塞原因
|
|
19
19
|
- `draft` / `in-progress` → 继续
|
|
20
|
-
3.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
3. 调用统一 workflow service 入口(与 active block 同一状态机),不要先编辑状态或 marker:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python3 .code-flow/scripts/cf_task_workflow.py block --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --reason "<阻塞原因>" --json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
命令同时更新 Status、阻塞原因、Log、Updated 和匹配的 marker;无 marker 的 draft 任务只改变任务文档。仅在返回成功后确认阻塞;其他需求的 marker 不得改动。
|
|
25
27
|
|
|
26
28
|
## 解除阻塞
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
先解决 Notes 或外部依赖,再执行:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
python3 .code-flow/scripts/cf_task_workflow.py resume --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
resume 会检查未解决的 #NOTES 和依赖,原子同步任务与 marker。未激活的 blocked 任务恢复 draft;已有匹配 marker 的任务恢复 in-progress。失败时保留阻塞状态,不通过手动改 Status 绕过。
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
## 执行步骤
|
|
15
15
|
|
|
16
|
+
### 0. 程序计算(推荐)
|
|
17
|
+
|
|
18
|
+
用 `python3 .code-flow/scripts/cf_task_index.py --task-file <file> --dag --json` 直接输出拓扑批次与独立分组,不要全文手算。单 worktree 一次仅激活一个 TASK:批次内“可并行”指可独立开发,而非可同时激活。
|
|
19
|
+
|
|
20
|
+
`batches` 是组内可独立开发的拓扑批次;`dependency_components` 是依赖连通分组,只保证组与组之间独立,组内仍有先后依赖。`independent_groups` 仅为后者的兼容别名,不要把它显示成组内并行。
|
|
21
|
+
|
|
16
22
|
### 1. 读取任务数据
|
|
17
23
|
|
|
18
24
|
- 指定文件:Glob 定位后 Read
|
|
@@ -65,7 +71,8 @@ Layer 2:
|
|
|
65
71
|
按子任务状态标注:
|
|
66
72
|
- `[draft]` — 待启动
|
|
67
73
|
- `[in-progress]` — 进行中
|
|
68
|
-
- `[done]` —
|
|
74
|
+
- `[done]` — 实现完成,E2E 可能仍待终验
|
|
75
|
+
- `[verified]` — 终验完成
|
|
69
76
|
- `[blocked]` — 被阻塞(附原因)
|
|
70
77
|
|
|
71
78
|
### 5. 多文件模式
|
|
@@ -134,10 +134,7 @@ TASK-002:
|
|
|
134
134
|
所有 `#NOTES` 讨论完毕后:
|
|
135
135
|
|
|
136
136
|
1. 再次扫描文件,确认无残留 `#NOTES` 标记
|
|
137
|
-
2. 如果子任务之前因 `#NOTES` 被标记为 `blocked
|
|
138
|
-
- 扫描 `### Log`,查找 `blocked` 记录中的原状态
|
|
139
|
-
- 用 Edit 恢复原状态
|
|
140
|
-
- 在 `### Log` 追加:`- [<当前日期>] unblocked (all #NOTES resolved, restored to <原状态>)`
|
|
137
|
+
2. 如果子任务之前因 `#NOTES` 被标记为 `blocked`,清除当前阻塞条目后调用 `python3 .code-flow/scripts/cf_task_workflow.py resume --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json`。命令检查依赖和残留 Notes,同步 marker 与任务状态;不得从历史 Log 猜测状态后只改 Markdown。失败保留 blocked 并报告原因。
|
|
141
138
|
3. 更新文件头 `Updated` 日期
|
|
142
139
|
|
|
143
140
|
### 6. 输出摘要
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
用 Read 读取任务文件,定位 `## TASK-xxx` 段落:
|
|
23
23
|
|
|
24
24
|
**状态检查**:Status 必须为 `draft`。若为其他状态:
|
|
25
|
-
- `in-progress` →
|
|
26
|
-
- `done` →
|
|
25
|
+
- `in-progress` → 校验现有 marker 的需求目录、TASK-ID 与 Context;匹配且为 active 才继续步骤 2,跳过重复 Start。paused/blocked 先解除原因并调用 resume;marker 缺失或不匹配先 doctor,不能仅改 Markdown。
|
|
26
|
+
- `done` / `verified` → 实现已完成;done 的 E2E 可为 e2e_deferred,转 verify-e2e 终验。发现缺口时报告并显式重新规划修复任务,不直接把终态改成 in-progress。
|
|
27
27
|
- `blocked` → 提示"任务被阻塞",列出 Notes 中的阻塞原因,结束
|
|
28
28
|
|
|
29
29
|
**#NOTES 检查**:扫描该子任务段落全文(Description、Checklist 等)
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
**依赖检查**:读取 `Depends` 字段
|
|
34
34
|
- 对每个依赖的 TASK-ID,在同文件中查找其 Status
|
|
35
|
-
- 所有依赖必须为 `done`
|
|
35
|
+
- 所有依赖必须为 `done` 或 `verified`
|
|
36
36
|
- 未满足 → 输出:`前置检查失败:以下依赖未完成\n- TASK-001: in-progress\n- TASK-003: draft`
|
|
37
37
|
|
|
38
38
|
**验收契约检查**:
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
|
|
61
61
|
在改状态或生产代码前,顺序固定且不得跳步:
|
|
62
62
|
|
|
63
|
-
1. 调用 `cf_spec_context.py start --task-dir ... --root ... --task ... --task-file ... --json`,由单个进程按 refresh → active start → session 顺序执行 Start Gate;stdin JSON 传入逐路径确认的 `owned_paths`。stale/
|
|
63
|
+
1. 调用 `cf_spec_context.py start --task-dir ... --root ... --task ... --task-file ... --json`,由单个进程按 refresh → active start → session 顺序执行 Start Gate;stdin JSON 传入逐路径确认的 `owned_paths`。stale/conflict、依赖未闭合、已有/损坏 marker、未归属 diff 或 hash 不一致立即阻断。禁止先 start 再 refresh,避免 active marker 在编码前自行漂移。前置硬门禁(blocked / #NOTES / 依赖)由 workflow service 在改状态前强制执行。用户已确认内容时,Design/Plan 的 pending 不单独阻止激活;不新增阶段状态门禁。
|
|
64
64
|
2. 从命令返回值读取 refresh 后的 Context hash、active 状态和 session 输出路径;该命令只根据当前 TASK 的 `Spec-Refs`、Source 与 Acceptance Contract 覆盖写入 `.code-flow/specs/_session/task-<name>.md`,禁止重新 catalog 或猜测规则。
|
|
65
|
-
3.
|
|
65
|
+
3. Start 返回成功时,workflow service 已通过可恢复事务同步 Status、started log 和 active marker;不要再手动改状态。失败保留原状态,按返回原因恢复。
|
|
66
66
|
4. 在修改任何生产代码前,为每个 Acceptance-Ref 填写测试文件、包含场景 ID 的测试用例名和可单独执行的命令
|
|
67
67
|
5. 先编写验收测试。E2E 测试必须经过契约声明的真实边界,不得用 mock 绕过 Store、Resolver、Builder、Renderer、Browser 等指定组件
|
|
68
68
|
6. 新功能或缺陷修复先执行一次测试并记录 RED:失败命令、失败用例和与预期缺陷对应的失败原因。纯重构或已有行为补测无法 RED 时,记录原因,不得伪造失败
|
|
@@ -83,11 +83,10 @@ RED 证据写入 `Acceptance Evidence`:
|
|
|
83
83
|
|
|
84
84
|
### 3.2 GREEN 与验收证据
|
|
85
85
|
|
|
86
|
-
1.
|
|
87
|
-
2.
|
|
88
|
-
3.
|
|
89
|
-
4.
|
|
90
|
-
5. 测试文件存在但未被测试框架收集、命令未实际执行、只有场景 ID 没有关键断言,都视为未验证
|
|
86
|
+
1. 执行 functional 验收和受影响范围的回归测试;E2E 已在编码前锁定场景、断言、真实边界和命令,完整 GREEN 留给 verify-e2e。
|
|
87
|
+
2. 对每个预期结果记录断言位置与 fixture/构造路径;环境未就绪的错误不得冒充有效 RED,明确记录尚未验证。
|
|
88
|
+
3. 由 runner 写入最新状态和运行历史;不要覆盖原契约、RED 证据或历史失败。functional 必须 verified,已登记的 E2E 在实现阶段允许 e2e_deferred。
|
|
89
|
+
4. 测试未收集、命令未实际执行或缺少关键断言,都不算验证完成。失败重跑必须使旧 verified 失效。
|
|
91
90
|
|
|
92
91
|
### 3.5 TASK-bound Spec Session
|
|
93
92
|
|
|
@@ -105,16 +104,18 @@ RED 证据写入 `Acceptance Evidence`:
|
|
|
105
104
|
|
|
106
105
|
只有同时满足以下条件才能自动完成:
|
|
107
106
|
- 所有 checklist 项均为 `[x]`
|
|
108
|
-
-
|
|
107
|
+
- functional/manual 在契约、证据和覆盖表中均为 `verified`;仅 E2E 可为 `e2e_deferred`,仍不得遗留未登记的 `planned` / `pending` / `TBD`
|
|
109
108
|
- 测试层级未低于 design,关键真实边界没有被 mock 绕过
|
|
110
|
-
-
|
|
109
|
+
- 每个预期结果都有具体断言位置,functional 验收命令和回归测试均已实际通过;E2E 留到终验执行
|
|
111
110
|
- `manual` 场景已有用户确认和可复核记录
|
|
112
111
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
满足后,执行唯一收尾入口:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python3 .code-flow/scripts/cf_task_workflow.py finish --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
该命令先校验完整任务身份与锁定 manifest,再执行 Done Gate;通过后以可恢复事务更新 done、Log、Updated 并清理 marker。只有 `decision=pass` 才输出完成并启动下一 TASK。禁止手动设置 done 或传入自报的 gate_passed 绕过验证。
|
|
118
119
|
|
|
119
120
|
任一验收条件不满足时保持 `in-progress`,明确列出缺口,不能标记为 `done`。
|
|
120
121
|
|
|
@@ -21,10 +21,10 @@ E2E 测试依赖外部环境(数据库、API、浏览器等),在编码阶
|
|
|
21
21
|
|
|
22
22
|
### 1. 检查前置条件
|
|
23
23
|
|
|
24
|
-
确认需求目录下所有子任务状态为 `done
|
|
24
|
+
确认需求目录下所有子任务状态为 `done`(实现完成)或 `verified`(终验已闭环):
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
rg "
|
|
27
|
+
rg "^- \*\*Status\*\*:" <需求目录>/*.md
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
如有 `in-progress` 或 `blocked` 任务,提示用户先完成。
|
|
@@ -53,20 +53,19 @@ E2E 场景需要以下环境:
|
|
|
53
53
|
用户确认后,执行:
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
-
python3 .code-flow/scripts/
|
|
57
|
-
--
|
|
58
|
-
--root . \
|
|
59
|
-
--include-e2e \
|
|
60
|
-
--write-evidence
|
|
56
|
+
python3 .code-flow/scripts/cf_task_workflow.py verify-e2e \
|
|
57
|
+
--task-dir "<需求目录>" --root "$PWD" --json
|
|
61
58
|
```
|
|
62
59
|
|
|
60
|
+
该入口重新检查所有 TASK、锁定 manifest 和 functional/manual 最新证据,内部以 `--only-e2e` 调用 runner;只有全通过才把任务提升为 verified。不得手动改状态。
|
|
61
|
+
|
|
63
62
|
### 4. 报告结果
|
|
64
63
|
|
|
65
64
|
解析执行结果:
|
|
66
65
|
|
|
67
66
|
```json
|
|
68
67
|
{
|
|
69
|
-
"decision": "
|
|
68
|
+
"decision": "block",
|
|
70
69
|
"results": [
|
|
71
70
|
{"id": "E-01", "kind": "e2e", "status": "passed"},
|
|
72
71
|
{"id": "E-02", "kind": "e2e", "status": "failed", "exit_code": 1}
|
|
@@ -79,7 +78,7 @@ python3 .code-flow/scripts/cf_acceptance_runner.py \
|
|
|
79
78
|
|
|
80
79
|
### 5. 更新任务状态
|
|
81
80
|
|
|
82
|
-
|
|
81
|
+
确认命令已将需求目录下所有任务 Status 更新为 `verified`,并保留原契约与运行历史。无需再次编辑状态。
|
|
83
82
|
|
|
84
83
|
## 失败处理
|
|
85
84
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 输入
|
|
6
6
|
|
|
7
|
-
- `/project:cf-validate` —
|
|
7
|
+
- `/project:cf-validate` — 自动获取任务基线或 Git 全部变更文件
|
|
8
8
|
- `/project:cf-validate src/Foo.tsx` — 验证指定文件
|
|
9
9
|
- `/project:cf-validate --files=src/a.ts,src/b.ts` — 验证多个文件
|
|
10
10
|
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
用 Bash 执行:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
18
|
+
python3 .code-flow/scripts/cf_validation.py --root "$PWD" --scope-only --json
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
有 active TASK 时使用冻结基线以来的全部任务变更(含已提交文件);无 active TASK 时包含暂存、未暂存和未跟踪文件。用户指定路径时用 `--files "src/a.py" "src/b.py"` 原样传递;若结果确实为空才输出“无变更需要验证”。
|
|
22
22
|
|
|
23
23
|
### 2. 读取验证规则
|
|
24
24
|
|
|
@@ -37,14 +37,13 @@ validators:
|
|
|
37
37
|
|
|
38
38
|
### 3. 匹配并执行验证
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
- 将 `trigger` glob 与变更文件列表做匹配
|
|
42
|
-
- 匹配到 → 用 Bash 执行 `command`
|
|
43
|
-
- 如果 command 包含 `{files}` → 替换为匹配到的文件路径列表,**每个路径用单引号包裹**(如 `'src/foo.ts' 'src/bar.ts'`)
|
|
44
|
-
- 如果 command 不含 `{files}` → 直接执行原命令(如 `npx tsc --noEmit` 本身就检查全局)
|
|
45
|
-
- 未匹配 → 跳过该规则
|
|
40
|
+
执行统一验证入口:
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
```bash
|
|
43
|
+
python3 .code-flow/scripts/cf_validation.py --root "$PWD" --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
显式范围追加 `--files "src/a.py" "src/b.py"`。程序匹配 trigger、解析 argv 并展开 `{files}`,不拼接 shell 命令;同一运行内相同 argv/cwd/timeout 去重,跨运行不复用。删除文件仍触发全局测试,但不传给文件级编译器。每条 timeout 仍按配置的毫秒值生效,总预算耗尽返回 incomplete/block。
|
|
48
47
|
|
|
49
48
|
### 4. 汇总结果
|
|
50
49
|
|
|
@@ -61,13 +60,13 @@ validators:
|
|
|
61
60
|
|
|
62
61
|
## 安全设计
|
|
63
62
|
|
|
64
|
-
-
|
|
65
|
-
-
|
|
63
|
+
- `{files}` 直接展开为 argv 参数;带空格、引号的路径仍是一个参数,不手工拼接引号或执行 shell
|
|
64
|
+
- 范围来自任务基线、Git 状态(包括 untracked)或用户显式指定的路径
|
|
66
65
|
- 用户指定的路径必须位于项目根目录内
|
|
67
66
|
|
|
68
67
|
## 异常处理
|
|
69
68
|
|
|
70
69
|
- validation.yml 不存在 → 尝试检测 package.json scripts 中的 test/lint 命令
|
|
71
70
|
- 命令执行超时 → 输出超时提示,建议增大 timeout 或缩小验证范围
|
|
72
|
-
-
|
|
71
|
+
- 命令不存在或配置无效 → 返回 block 并提示所缺依赖,不当作验证通过
|
|
73
72
|
- 无变更文件 → 输出"无变更需要验证"
|
|
@@ -17,7 +17,7 @@ description: Archive a completed task file after completeness, correctness, trac
|
|
|
17
17
|
|
|
18
18
|
1. 读取匹配到的 task 文件
|
|
19
19
|
2. 提取所有 `## TASK-xxx` 段落的 Status
|
|
20
|
-
3. 检查是否所有子任务均为 `done`
|
|
20
|
+
3. 检查是否所有子任务均为 `verified`(E2E 终验后的终态;仍为 `done` 说明 verify-e2e 尚未执行,先跑它)
|
|
21
21
|
|
|
22
22
|
若有未完成子任务,拒绝归档并输出:
|
|
23
23
|
|
|
@@ -37,24 +37,24 @@ description: Archive a completed task file after completeness, correctness, trac
|
|
|
37
37
|
|
|
38
38
|
- 需求目录必须存在 `spec-context.yml`;执行 `python3 .code-flow/scripts/cf_spec_context.py refresh --task-dir <需求目录> --root "$PWD" --json`
|
|
39
39
|
- 执行 `python3 .code-flow/scripts/cf_spec_gate.py --task-dir <需求目录> --stage code --json`;required Rule 的 stale/pending/conflict/unverified 任一存在即 FAIL
|
|
40
|
-
- 若 `.code-flow/.active-task.json`
|
|
40
|
+
- 若 `.code-flow/.active-task.json` 仍指向本需求,先执行 `python3 .code-flow/scripts/cf_task_workflow.py finish --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json`,通过后再 verify-e2e;不得自报 gate_passed 或通过归档绕过 active 状态
|
|
41
41
|
- Context 与 Evidence 随需求目录一并归档,`_session` 仅是可重建投影,不是事实源
|
|
42
42
|
|
|
43
|
-
所有子任务
|
|
43
|
+
所有子任务 verified 后,执行四维校验:
|
|
44
44
|
|
|
45
45
|
**完整性**:
|
|
46
46
|
- 所有 Checklist 项已勾选
|
|
47
47
|
- 全文无残留的 `#NOTES` 标记
|
|
48
48
|
|
|
49
49
|
**正确性**:
|
|
50
|
-
-
|
|
50
|
+
- 执行 `python3 .code-flow/scripts/cf_validation.py --root "$PWD" --json`;归档时任务已无 marker,须补充本需求基线至当前的变更路径作为 `--files` 参数,不能把工作区干净误认为本需求无需验证
|
|
51
51
|
- 检查本次变更涉及的文件是否通过 lint/type check
|
|
52
52
|
|
|
53
53
|
**验收追溯**:
|
|
54
54
|
- 来源 design 含结构化 S-/E-/B- 场景时,逐项对照 `## Acceptance Coverage`,P0/P1 场景以及 RULE/高影响 RISK 映射场景必须全部存在且状态为 `verified`
|
|
55
55
|
- 每个负责任务的 `Acceptance-Refs`、`Acceptance Contract`、`Acceptance Evidence` 必须闭合,不得残留 `planned` / `pending` / `TBD`
|
|
56
56
|
- 测试层级不得低于 design;E2E 的真实边界和关键断言必须有文件/用例位置与 fixture/构造证据
|
|
57
|
-
-
|
|
57
|
+
- 先用 `cf_acceptance_manifest.py --task-file "<任务文件>" --output "<需求目录>/.acceptance-manifest.json" --verify-plan` 校验基线,再用 `cf_acceptance_runner.py --manifest "<需求目录>/.acceptance-manifest.json" --root "$PWD" --include-e2e --write-evidence` 统一复验。相同 argv、cwd、timeout 的命令在单次运行内复用结果;跨运行不复用,依赖步骤不跨状态屏障复用。测试未收集、未执行或失败均为 FAIL
|
|
58
58
|
- `manual` 场景必须有用户确认和可复核记录。旧 design 没有结构化场景时注明“不适用”,不得伪造覆盖
|
|
59
59
|
|
|
60
60
|
**一致性**:
|
|
@@ -15,17 +15,23 @@ description: Mark a subtask as blocked with a reason. Use when a task cannot pro
|
|
|
15
15
|
|
|
16
16
|
1. 用 `rg --files` 或 `find` 定位任务文件,读取
|
|
17
17
|
2. 定位 `## TASK-001` 段落,检查当前 Status:
|
|
18
|
-
- `done` → 拒绝:`TASK-001 已完成,无法标记阻塞`
|
|
18
|
+
- `done` / `verified` → 拒绝:`TASK-001 已完成,无法标记阻塞`
|
|
19
19
|
- `blocked` → 提示:`TASK-001 已处于 blocked 状态`,仍追加新的阻塞原因
|
|
20
20
|
- `draft` / `in-progress` → 继续
|
|
21
|
-
3.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
3. 调用统一 workflow service 入口(与 active block 同一状态机),不要先编辑状态或 marker:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python3 .code-flow/scripts/cf_task_workflow.py block --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --reason "<阻塞原因>" --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
命令同时更新 Status、阻塞原因、Log、Updated 和匹配的 marker;无 marker 的 draft 任务只改变任务文档。仅在返回成功后确认阻塞;其他需求的 marker 不得改动。
|
|
26
28
|
|
|
27
29
|
## 解除阻塞
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
先解决 Notes 或外部依赖,再执行:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python3 .code-flow/scripts/cf_task_workflow.py resume --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
resume 会检查未解决的 #NOTES 和依赖,原子同步任务与 marker。未激活的 blocked 任务恢复 draft;已有匹配 marker 的任务恢复 in-progress。失败时保留阻塞状态,不通过手动改 Status 绕过。
|
|
@@ -14,6 +14,12 @@ description: Visualize task dependency DAG, identify parallelizable task groups
|
|
|
14
14
|
|
|
15
15
|
## 执行步骤
|
|
16
16
|
|
|
17
|
+
### 0. 程序计算(推荐)
|
|
18
|
+
|
|
19
|
+
用 `python3 .code-flow/scripts/cf_task_index.py --task-file <file> --dag --json` 直接输出拓扑批次与独立分组,不要全文手算。单 worktree 一次仅激活一个 TASK:批次内“可并行”指可独立开发,而非可同时激活。
|
|
20
|
+
|
|
21
|
+
`batches` 是组内可独立开发的拓扑批次;`dependency_components` 是依赖连通分组,只保证组与组之间独立,组内仍有先后依赖。`independent_groups` 仅为后者的兼容别名,不要把它显示成组内并行。
|
|
22
|
+
|
|
17
23
|
### 1. 读取任务数据
|
|
18
24
|
|
|
19
25
|
- 指定文件:用 `rg --files` 或 `find` 定位后读取
|
|
@@ -66,7 +72,8 @@ Layer 2:
|
|
|
66
72
|
按子任务状态标注:
|
|
67
73
|
- `[draft]` — 待启动
|
|
68
74
|
- `[in-progress]` — 进行中
|
|
69
|
-
- `[done]` —
|
|
75
|
+
- `[done]` — 实现完成,E2E 可能仍待终验
|
|
76
|
+
- `[verified]` — 终验完成
|
|
70
77
|
- `[blocked]` — 被阻塞(附原因)
|
|
71
78
|
|
|
72
79
|
### 5. 多文件模式
|
|
@@ -131,10 +131,7 @@ TASK-002:
|
|
|
131
131
|
所有 `#NOTES` 讨论完毕后:
|
|
132
132
|
|
|
133
133
|
1. 再次扫描文件,确认无残留 `#NOTES` 标记
|
|
134
|
-
2. 如果子任务之前因 `#NOTES` 被标记为 `blocked
|
|
135
|
-
- 扫描 `### Log`,查找 `blocked` 记录中的原状态
|
|
136
|
-
- 用 apply_patch 恢复原状态
|
|
137
|
-
- 在 `### Log` 追加:`- [<当前日期>] unblocked (all #NOTES resolved, restored to <原状态>)`
|
|
134
|
+
2. 如果子任务之前因 `#NOTES` 被标记为 `blocked`,清除当前阻塞条目后调用 `python3 .code-flow/scripts/cf_task_workflow.py resume --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json`。命令检查依赖和残留 Notes,同步 marker 与任务状态;不得从历史 Log 猜测状态后只改 Markdown。失败保留 blocked 并报告原因。
|
|
138
135
|
3. 更新文件头 `Updated` 日期
|
|
139
136
|
|
|
140
137
|
### 6. 输出摘要
|
|
@@ -23,8 +23,8 @@ description: Activate a subtask and begin coding. Runs pre-checks (status, #NOTE
|
|
|
23
23
|
读取任务文件,定位 `## TASK-xxx` 段落:
|
|
24
24
|
|
|
25
25
|
**状态检查**:Status 必须为 `draft`。若为其他状态:
|
|
26
|
-
- `in-progress` →
|
|
27
|
-
- `done` →
|
|
26
|
+
- `in-progress` → 校验现有 marker 的需求目录、TASK-ID 与 Context;匹配且为 active 才继续步骤 2,跳过重复 Start。paused/blocked 先解除原因并调用 resume;marker 缺失或不匹配先 doctor,不能仅改 Markdown。
|
|
27
|
+
- `done` / `verified` → 实现已完成;done 的 E2E 可为 e2e_deferred,转 verify-e2e 终验。发现缺口时报告并显式重新规划修复任务,不直接把终态改成 in-progress。
|
|
28
28
|
- `blocked` → 提示"任务被阻塞",列出 Notes 中的阻塞原因,结束
|
|
29
29
|
|
|
30
30
|
**#NOTES 检查**:扫描该子任务段落全文(Description、Checklist 等)
|
|
@@ -33,7 +33,7 @@ description: Activate a subtask and begin coding. Runs pre-checks (status, #NOTE
|
|
|
33
33
|
|
|
34
34
|
**依赖检查**:读取 `Depends` 字段
|
|
35
35
|
- 对每个依赖的 TASK-ID,在同文件中查找其 Status
|
|
36
|
-
- 所有依赖必须为 `done`
|
|
36
|
+
- 所有依赖必须为 `done` 或 `verified`
|
|
37
37
|
- 未满足 → 输出:`前置检查失败:以下依赖未完成\n- TASK-001: in-progress\n- TASK-003: draft`
|
|
38
38
|
|
|
39
39
|
**验收契约检查**:
|
|
@@ -61,9 +61,9 @@ description: Activate a subtask and begin coding. Runs pre-checks (status, #NOTE
|
|
|
61
61
|
|
|
62
62
|
在改状态或生产代码前,顺序固定且不得跳步:
|
|
63
63
|
|
|
64
|
-
1. 调用 `cf_spec_context.py start --task-dir ... --root ... --task ... --task-file ... --json`,由单个进程按 refresh → active start → session 顺序执行 Start Gate;stdin JSON 传入逐路径确认的 `owned_paths`。stale/
|
|
64
|
+
1. 调用 `cf_spec_context.py start --task-dir ... --root ... --task ... --task-file ... --json`,由单个进程按 refresh → active start → session 顺序执行 Start Gate;stdin JSON 传入逐路径确认的 `owned_paths`。stale/conflict、依赖未闭合、已有/损坏 marker、未归属 diff 或 hash 不一致立即阻断。禁止先 start 再 refresh,避免 active marker 在编码前自行漂移。前置硬门禁(blocked / #NOTES / 依赖)由 workflow service 在改状态前强制执行。用户已确认内容时,Design/Plan 的 pending 不单独阻止激活;不新增阶段状态门禁。
|
|
65
65
|
2. 从命令返回值读取 refresh 后的 Context hash、active 状态和 session 输出路径;该命令只根据当前 TASK 的 `Spec-Refs`、Source 与 Acceptance Contract 覆盖写入 `.code-flow/specs/_session/task-<name>.md`,禁止重新 catalog 或猜测规则。
|
|
66
|
-
3.
|
|
66
|
+
3. Start 返回成功时,workflow service 已通过可恢复事务同步 Status、started log 和 active marker;不要再手动改状态。失败保留原状态,按返回原因恢复。
|
|
67
67
|
4. 在修改任何生产代码前,为每个 Acceptance-Ref 填写测试文件、包含场景 ID 的测试用例名和可单独执行的命令
|
|
68
68
|
5. 先编写验收测试。E2E 测试必须经过契约声明的真实边界,不得用 mock 绕过 Store、Resolver、Builder、Renderer、Browser 等指定组件
|
|
69
69
|
6. 新功能或缺陷修复先执行一次测试并记录 RED:失败命令、失败用例和与预期缺陷对应的失败原因。纯重构或已有行为补测无法 RED 时,记录原因,不得伪造失败
|
|
@@ -84,11 +84,10 @@ RED 证据写入 `Acceptance Evidence`:
|
|
|
84
84
|
|
|
85
85
|
### 3.2 GREEN 与验收证据
|
|
86
86
|
|
|
87
|
-
1.
|
|
88
|
-
2.
|
|
89
|
-
3.
|
|
90
|
-
4.
|
|
91
|
-
5. 测试文件存在但未被测试框架收集、命令未实际执行、只有场景 ID 没有关键断言,都视为未验证
|
|
87
|
+
1. 执行 functional 验收和受影响范围的回归测试;E2E 已在编码前锁定场景、断言、真实边界和命令,完整 GREEN 留给 verify-e2e。
|
|
88
|
+
2. 对每个预期结果记录断言位置与 fixture/构造路径;环境未就绪的错误不得冒充有效 RED,明确记录尚未验证。
|
|
89
|
+
3. 由 runner 写入最新状态和运行历史;不要覆盖原契约、RED 证据或历史失败。functional 必须 verified,已登记的 E2E 在实现阶段允许 e2e_deferred。
|
|
90
|
+
4. 测试未收集、命令未实际执行或缺少关键断言,都不算验证完成。失败重跑必须使旧 verified 失效。
|
|
92
91
|
|
|
93
92
|
### 3.5 TASK-bound Spec Session
|
|
94
93
|
|
|
@@ -106,16 +105,18 @@ RED 证据写入 `Acceptance Evidence`:
|
|
|
106
105
|
|
|
107
106
|
只有同时满足以下条件才能自动完成:
|
|
108
107
|
- 所有 checklist 项均为 `[x]`
|
|
109
|
-
-
|
|
108
|
+
- functional/manual 在契约、证据和覆盖表中均为 `verified`;仅 E2E 可为 `e2e_deferred`,仍不得遗留未登记的 `planned` / `pending` / `TBD`
|
|
110
109
|
- 测试层级未低于 design,关键真实边界没有被 mock 绕过
|
|
111
|
-
-
|
|
110
|
+
- 每个预期结果都有具体断言位置,functional 验收命令和回归测试均已实际通过;E2E 留到终验执行
|
|
112
111
|
- `manual` 场景已有用户确认和可复核记录
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
满足后,执行唯一收尾入口:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
python3 .code-flow/scripts/cf_task_workflow.py finish --root "$PWD" --task-dir "<需求目录>" --task TASK-001 --json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
该命令先校验完整任务身份与锁定 manifest,再执行 Done Gate;通过后以可恢复事务更新 done、Log、Updated 并清理 marker。只有 `decision=pass` 才输出完成并启动下一 TASK。禁止手动设置 done 或传入自报的 gate_passed 绕过验证。
|
|
119
120
|
|
|
120
121
|
任一验收条件不满足时保持 `in-progress`,明确列出缺口,不能标记为 `done`。
|
|
121
122
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cf-task-verify-e2e
|
|
3
|
+
description: Execute deferred E2E scenarios after all functional tests pass
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## 使用场景
|
|
7
|
+
|
|
8
|
+
E2E 测试依赖外部环境(数据库、API、浏览器等),在编码阶段默认跳过(状态 `e2e_deferred`)。当所有子任务的 functional 测试通过后,使用此命令统一执行 E2E 验收。
|
|
9
|
+
|
|
10
|
+
## 调用方式
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
cf-task-verify-e2e <需求目录>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 执行步骤
|
|
17
|
+
|
|
18
|
+
### 1. 检查前置条件
|
|
19
|
+
|
|
20
|
+
确认需求目录下所有子任务状态为 `done`(实现完成)或 `verified`(终验已闭环):
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
rg "^- \*\*Status\*\*:" <需求目录>/*.md
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
如有 `in-progress` 或 `blocked` 任务,提示用户先完成。
|
|
27
|
+
|
|
28
|
+
### 2. 检查环境依赖
|
|
29
|
+
|
|
30
|
+
读取 `.acceptance-manifest.json` 中的 E2E 场景,提取所需的外部依赖(从 `boundary` 字段推断):
|
|
31
|
+
|
|
32
|
+
- `HTTP API` → 提示确认 API 服务运行中
|
|
33
|
+
- `Browser` → 提示确认浏览器驱动已安装
|
|
34
|
+
- `Database` → 提示确认测试数据库可访问
|
|
35
|
+
|
|
36
|
+
显示清单并询问:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
E2E 场景需要以下环境:
|
|
40
|
+
- 本地 API 服务 (http://localhost:3000)
|
|
41
|
+
- PostgreSQL 测试数据库
|
|
42
|
+
- Chrome WebDriver
|
|
43
|
+
|
|
44
|
+
环境已就绪?(y/N)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. 执行 E2E 场景
|
|
48
|
+
|
|
49
|
+
用户确认后,执行:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python3 .code-flow/scripts/cf_task_workflow.py verify-e2e \
|
|
53
|
+
--task-dir "<需求目录>" --root "$PWD" --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
该入口重新检查所有 TASK、锁定 manifest 和 functional/manual 最新证据,内部以 `--only-e2e` 调用 runner;只有全通过才把任务提升为 verified。不得手动改状态。
|
|
57
|
+
|
|
58
|
+
### 4. 报告结果
|
|
59
|
+
|
|
60
|
+
解析执行结果:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"decision": "block",
|
|
65
|
+
"results": [
|
|
66
|
+
{"id": "E-01", "kind": "e2e", "status": "passed"},
|
|
67
|
+
{"id": "E-02", "kind": "e2e", "status": "failed", "exit_code": 1}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- `decision=pass`:所有 E2E 场景通过,提示"E2E 验收完成"
|
|
73
|
+
- `decision=block`:有失败场景,列出失败的场景 ID 和错误信息
|
|
74
|
+
|
|
75
|
+
### 5. 更新任务状态
|
|
76
|
+
|
|
77
|
+
确认命令已将需求目录下所有任务 Status 更新为 `verified`,并保留原契约与运行历史。无需再次编辑状态。
|
|
78
|
+
|
|
79
|
+
## 失败处理
|
|
80
|
+
|
|
81
|
+
E2E 失败时:
|
|
82
|
+
|
|
83
|
+
1. 显示失败场景的完整命令和退出码
|
|
84
|
+
2. 提示查看 `.acceptance-manifest.json` 中的 `evidence` 字段
|
|
85
|
+
3. 不自动修改任务状态,等待用户修复后重新执行
|
|
86
|
+
|
|
87
|
+
## 示例
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
cf-task-verify-e2e .code-flow/tasks/2026-03-15/auth-module
|
|
91
|
+
|
|
92
|
+
> 检查子任务状态... 所有任务已完成
|
|
93
|
+
>
|
|
94
|
+
> E2E 场景需要以下环境:
|
|
95
|
+
> - 本地 API 服务 (http://localhost:3000)
|
|
96
|
+
> - PostgreSQL 测试数据库 (postgresql://localhost:5432/test)
|
|
97
|
+
>
|
|
98
|
+
> 环境已就绪?(y/N) y
|
|
99
|
+
>
|
|
100
|
+
> 执行 E2E 场景...
|
|
101
|
+
> ✓ E-01: 用户登录流程 (1.2s)
|
|
102
|
+
> ✓ E-02: 权限验证链路 (0.8s)
|
|
103
|
+
>
|
|
104
|
+
> E2E 验收完成!2/2 场景通过
|
|
105
|
+
> 已更新任务状态为 verified
|
|
106
|
+
```
|