@hunter-harness/workflow-harness 0.2.73 → 0.2.74
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/harness/bundles/general/claude-code/.harness-build.json +1 -1
- package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +2 -2
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +3 -2
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +2 -2
- package/harness/bundles/general/claude-code/harness-test/checklist.md +2 -0
- package/harness/bundles/general/claude-code/scripts/harness_archive.py +82 -1
- package/harness/bundles/general/claude-code/scripts/harness_ledger.py +25 -4
- package/harness/bundles/general/claude-code/scripts/harness_profile.py +45 -0
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +2 -2
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +3 -2
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +2 -2
- package/harness/bundles/general/codebuddy/harness-test/checklist.md +2 -0
- package/harness/bundles/general/codebuddy/scripts/harness_archive.py +82 -1
- package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +25 -4
- package/harness/bundles/general/codebuddy/scripts/harness_profile.py +45 -0
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-run/SKILL.md +2 -2
- package/harness/bundles/general/codex/harness-submit/SKILL.md +3 -2
- package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-test/SKILL.md +2 -2
- package/harness/bundles/general/codex/harness-test/checklist.md +2 -0
- package/harness/bundles/general/codex/scripts/harness_archive.py +82 -1
- package/harness/bundles/general/codex/scripts/harness_ledger.py +25 -4
- package/harness/bundles/general/codex/scripts/harness_profile.py +45 -0
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-run/SKILL.md +2 -2
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +3 -2
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-test/SKILL.md +2 -2
- package/harness/bundles/general/cursor/harness-test/checklist.md +2 -0
- package/harness/bundles/general/cursor/scripts/harness_archive.py +82 -1
- package/harness/bundles/general/cursor/scripts/harness_ledger.py +25 -4
- package/harness/bundles/general/cursor/scripts/harness_profile.py +45 -0
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +2 -2
- package/harness/bundles/java/claude-code/harness-run/reference.md +348 -348
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +3 -2
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +2 -2
- package/harness/bundles/java/claude-code/scripts/harness_archive.py +82 -1
- package/harness/bundles/java/claude-code/scripts/harness_ledger.py +25 -4
- package/harness/bundles/java/claude-code/scripts/harness_profile.py +45 -0
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +2 -2
- package/harness/bundles/java/codebuddy/harness-run/reference.md +348 -348
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +3 -2
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +2 -2
- package/harness/bundles/java/codebuddy/scripts/harness_archive.py +82 -1
- package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +25 -4
- package/harness/bundles/java/codebuddy/scripts/harness_profile.py +45 -0
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-run/SKILL.md +2 -2
- package/harness/bundles/java/codex/harness-run/reference.md +348 -348
- package/harness/bundles/java/codex/harness-submit/SKILL.md +3 -2
- package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-test/SKILL.md +2 -2
- package/harness/bundles/java/codex/scripts/harness_archive.py +82 -1
- package/harness/bundles/java/codex/scripts/harness_ledger.py +25 -4
- package/harness/bundles/java/codex/scripts/harness_profile.py +45 -0
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-run/SKILL.md +2 -2
- package/harness/bundles/java/cursor/harness-run/reference.md +348 -348
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +3 -2
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-test/SKILL.md +2 -2
- package/harness/bundles/java/cursor/scripts/harness_archive.py +82 -1
- package/harness/bundles/java/cursor/scripts/harness_ledger.py +25 -4
- package/harness/bundles/java/cursor/scripts/harness_profile.py +45 -0
- package/harness/manifests/general/claude-code.json +18 -18
- package/harness/manifests/general/codebuddy.json +18 -18
- package/harness/manifests/general/codex.json +18 -18
- package/harness/manifests/general/cursor.json +18 -18
- package/harness/manifests/java/claude-code.json +20 -20
- package/harness/manifests/java/codebuddy.json +20 -20
- package/harness/manifests/java/codex.json +20 -20
- package/harness/manifests/java/cursor.json +20 -20
- package/hunter-workflow-family.json +3 -3
- package/package.json +1 -1
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: harness-run 的编译失败策略表、TDD
|
|
2
|
+
description: harness-run 的编译失败策略表、TDD循环详细步骤和编码约束。仅在编码执行遇到编译问题或需要参考详细规则时读取。
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# harness-run
|
|
5
|
+
# harness-run 参考 — 详细规则
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 为什么走变更簇 TDD 而不是逐任务 TDD
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
1. **Maven 反复启动**——每个小任务(如新增一个错误码)都单独启动 Maven,耗时 30-60
|
|
11
|
-
2.
|
|
12
|
-
3.
|
|
9
|
+
逐任务 TDD 有三个严重效率问题:
|
|
10
|
+
1. **Maven 反复启动**——每个小任务(如新增一个错误码)都单独启动 Maven,耗时 30-60 秒 × N 个任务,累计浪费大量时间
|
|
11
|
+
2. **测试碎片化**——每个小任务单独建测试类,mock 重复配置,测试之间缺乏关联
|
|
12
|
+
3. **上下文切换**——RED→GREEN→REFACTOR 每个小任务独立循环,打断编码思路
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
变更簇 TDD 将围绕同一业务行为的多个任务合并为一个变更簇,一次 RED、一次 GREEN 验证。每个变更簇 2-5 分钟,Maven 只启动必要次数。
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
- updateRule status 联动 + activateVersion status 联动 + enabledList activeFlag 过滤
|
|
16
|
+
**变更簇示例**:
|
|
17
|
+
- 错误码 + Mapper 查询 + Service 校验 + create/update/copy 调用 → 归为一个"ruleCode+version 唯一性"变更簇
|
|
18
|
+
- updateRule status 联动 + activateVersion status 联动 + enabledList activeFlag 过滤 → 归为一个"status/activeFlag 一致性"变更簇
|
|
19
19
|
|
|
20
20
|
## 前置条件
|
|
21
21
|
|
|
22
|
-
-
|
|
23
|
-
- `.harness/changes/<change-name>/plans/<change-name>-plan.md` 存在(含完整 frontmatter
|
|
22
|
+
- 设计文档存在:`plans/<change-name>-design.md`(v2)或 `spec/<change-name>-design.md`(legacy,含完整 frontmatter),按 `shared/read-protocol.md` 的顺序取第一个
|
|
23
|
+
- `.harness/changes/<change-name>/plans/<change-name>-plan.md` 存在(含完整 frontmatter)
|
|
24
24
|
- `.harness/changes/<change-name>/plans/<change-name>-test-scenarios.md` 存在
|
|
25
25
|
- `.harness/changes/<change-name>/plans/<change-name>-implementation-detail.md`(如存在,补充读取)
|
|
26
26
|
- 用户已审批通过计划
|
|
27
|
-
-
|
|
27
|
+
- 如果在 worktree 中,已切换到 worktree 目录
|
|
28
28
|
|
|
29
29
|
## 步骤 0:加载上下文
|
|
30
30
|
|
|
31
|
-
## Worktree
|
|
31
|
+
## Worktree 创建与切换详细规则
|
|
32
32
|
|
|
33
|
-
`harness-run`
|
|
33
|
+
`harness-run` 必须把 `worktree.json` 当作唯一决策源。
|
|
34
34
|
|
|
35
35
|
### 状态机
|
|
36
36
|
|
|
@@ -59,15 +59,15 @@ powershell.exe -NoProfile -Command "git worktree add '.worktrees/<change-name>'
|
|
|
59
59
|
powershell.exe -NoProfile -Command "git worktree add '.worktrees/<change-name>' 'harness/<change-name>'"
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
验证:
|
|
63
63
|
|
|
64
64
|
```powershell
|
|
65
65
|
powershell.exe -NoProfile -Command "Test-Path '.worktrees/<change-name>/.git'"
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
###
|
|
68
|
+
### 状态目录写入
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
即使代码在 worktree 中修改,`.harness/changes/<change-name>/` 仍是主项目下的状态真相源。run 必须记录:
|
|
71
71
|
|
|
72
72
|
```json
|
|
73
73
|
{
|
|
@@ -79,37 +79,37 @@ powershell.exe -NoProfile -Command "Test-Path '.worktrees/<change-name>/.git'"
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
> ⚠️ **phase.start
|
|
83
|
-
> ⚠️
|
|
82
|
+
> ⚠️ **phase.start 前置**:步骤 0 第一件事是 `harness_events.py append --type phase.start`(见底部「执行日志记录」)。**任何代码修改前必须先记录**,不能等代码改完才补。
|
|
83
|
+
> ⚠️ **测试基础设施探测前置**:步骤 0 中必须首先执行"步骤 0.5 测试基础设施探测",探测完成前不得写任何 TDD 降级结论。
|
|
84
84
|
|
|
85
|
-
1.
|
|
86
|
-
2.
|
|
87
|
-
3. **读取计划文件(主任务源)**:`.harness/changes/<change-name>/plans/<change-name>-plan.md`
|
|
85
|
+
1. **确定变更名**:用 Glob 搜索 `.harness/changes/*/plans/*-plan.md`(**排除 `.harness/archive/*/`**),读取找到的 plan.md 的 YAML frontmatter,提取 `change-name`。默认最多一个未归档变更;如有多个,优先取最近修改的,或询问用户选择。
|
|
86
|
+
2. **读取并执行 worktree 决策**:读取 `.harness/changes/<change-name>/worktree.json`。如果 `requested=false`,在主目录执行;如果 `requested=true` 且 worktree 存在,必须 cd 到该 worktree;如果 `requested=true` 且 worktree 不存在,必须创建 worktree,创建失败则停止或询问用户是否改为主目录执行。禁止静默降级。
|
|
87
|
+
3. **读取计划文件(主任务源)**:`.harness/changes/<change-name>/plans/<change-name>-plan.md` → 获取任务列表和依赖关系
|
|
88
88
|
4. **读取详细计划(补充参考)**:`.harness/changes/<change-name>/plans/<change-name>-implementation-detail.md`(如存在)→ 获取详细执行说明
|
|
89
|
-
5. **读取设计文档**:`.harness/changes/<change-name>/spec/<change-name>-design.md
|
|
90
|
-
6.
|
|
89
|
+
5. **读取设计文档**:`.harness/changes/<change-name>/plans/<change-name>-design.md`(v2 发布产物)→ 不存在时回退 `spec/<change-name>-design.md`(legacy)→ 获取核心设计决策和不变项
|
|
90
|
+
6. **读取测试场景表**:`.harness/changes/<change-name>/plans/<change-name>-test-scenarios.md` → 获取测试真相源
|
|
91
91
|
7. **读取验证账本**:`通过共享状态目录解析器定位的 evidence/verification-ledger.json`(如存在)→ 复用已有 compile/unitTest 结果
|
|
92
|
-
8.
|
|
93
|
-
9. 确认 `项目规则(见 .harness/context-index.json
|
|
94
|
-
10. **执行测试基础设施探测**(见下方"步骤 0.5"
|
|
95
|
-
11. 确认编译环境正常(`powershell.exe -Command "mvn compile -pl <module> -o -q"
|
|
96
|
-
12.
|
|
97
|
-
13.
|
|
98
|
-
14.
|
|
92
|
+
8. **读取任务状态**:`.harness/changes/<change-name>/run-task-status.md`(如存在)→ 恢复上次运行状态
|
|
93
|
+
9. 确认 `项目规则(见 .harness/context-index.json)/` 规则已加载
|
|
94
|
+
10. **执行测试基础设施探测**(见下方"步骤 0.5")
|
|
95
|
+
11. 确认编译环境正常(`powershell.exe -Command "mvn compile -pl <module> -o -q"`)
|
|
96
|
+
12. **检查构建配置完整性**:如果在 worktree 中执行,确认构建配置文件(如 `.mvn/maven.config`、`settings.xml`、`gradle.properties` 等)存在。worktree 可能不包含主目录的构建配置,缺失时从主目录复制
|
|
97
|
+
13. **依赖模块预安装**:如果在 worktree 中执行,检查上游依赖模块是否已 `mvn install` 到本地仓库。缺失时先执行 `powershell.exe -Command "mvn install -pl <upstream-modules> -am -DskipTests -nsu"`
|
|
98
|
+
14. **代码探索优先用 codegraph_explore**:一次调用可获取多个相关符号的源码,替代逐个 Read 文件。违反 `项目 codegraph 规则` 规则逐个 Read 会浪费 3-5 分钟。仅在 codegraph 返回结果不完整时补充 Read
|
|
99
99
|
|
|
100
|
-
### Maven
|
|
100
|
+
### Maven 项目配置与重试预算
|
|
101
101
|
|
|
102
|
-
- 运行 Maven
|
|
103
|
-
-
|
|
104
|
-
-
|
|
102
|
+
- 运行 Maven 前先读取项目已有的 `.mvn/maven.config`;其中的 `-s`、`-o`、镜像和仓库设置视为项目契约,不在命令行重复追加或覆盖。
|
|
103
|
+
- 若项目配置已启用离线模式,依赖缺失只允许一次有明确原因的恢复尝试:仅在项目规则允许联网时临时执行非离线的 `-nsu` 命令;随后继续遵循项目配置,不得在离线/联网命令之间循环试错。
|
|
104
|
+
- 同一失败命令不得无分析地重复执行。先按“配置/依赖缺失、编译、测试、业务断言”分类,再决定修复或停止;每个变更簇仍遵守一次 RED、一次 GREEN 的 Maven 预算。
|
|
105
105
|
|
|
106
|
-
### 步骤 0.1:执行模式(默认 Inline
|
|
106
|
+
### 步骤 0.1:执行模式(默认 Inline)
|
|
107
107
|
|
|
108
|
-
默认 **Inline Execution**;仅 `--subagent` 强制 Subagent-Driven
|
|
108
|
+
默认 **Inline Execution**;仅 `--subagent` 强制 Subagent-Driven。**不询问**任务数/模块数(P1-5)。
|
|
109
109
|
|
|
110
|
-
### 步骤 0.5
|
|
110
|
+
### 步骤 0.5:测试基础设施探测(⚠️ 必须先于任何 TDD 降级结论)
|
|
111
111
|
|
|
112
|
-
>
|
|
112
|
+
> **核心原则**:探测完成前,执行日志中只能写 `**测试基础设施**: CHECKING`,不得写任何降级结论。证据不足时禁止写"项目无测试基础设施""RED 降级""TDD 降级"。
|
|
113
113
|
|
|
114
114
|
### 探测流程
|
|
115
115
|
|
|
@@ -117,26 +117,26 @@ powershell.exe -NoProfile -Command "Test-Path '.worktrees/<change-name>/.git'"
|
|
|
117
117
|
|
|
118
118
|
**探测 1:src/test/java 目录是否存在**
|
|
119
119
|
```text
|
|
120
|
-
#
|
|
120
|
+
# 用 Glob 或 Read 检查目标模块下是否有 src/test/java 目录
|
|
121
121
|
```
|
|
122
|
-
- 结果:✅ 存在 /
|
|
122
|
+
- 结果:✅ 存在 / ❌ 不存在
|
|
123
123
|
|
|
124
124
|
**探测 2:pom.xml 是否包含测试依赖**
|
|
125
125
|
检查目标模块的 `pom.xml`,搜索以下依赖:
|
|
126
126
|
- `spring-boot-starter-test`
|
|
127
127
|
- `junit` / `junit-jupiter`
|
|
128
128
|
- `mockito` / `mockito-core` / `mockito-junit-jupiter`
|
|
129
|
-
- 结果:✅ 包含关键测试依赖 / 🟡 部分包含 /
|
|
129
|
+
- 结果:✅ 包含关键测试依赖 / 🟡 部分包含 / ❌ 无测试依赖
|
|
130
130
|
|
|
131
|
-
**探测 3
|
|
132
|
-
|
|
133
|
-
- 结果:✅ 存在 N
|
|
131
|
+
**探测 3:是否存在已有测试文件**
|
|
132
|
+
用 Glob 搜索目标模块的 `src/test/java/**/*Test*.java` 或 `src/test/java/**/*Tests*.java`
|
|
133
|
+
- 结果:✅ 存在 N 个测试文件 / ❌ 无测试文件
|
|
134
134
|
|
|
135
135
|
**探测 4:测试命令是否可运行**
|
|
136
136
|
```powershell
|
|
137
137
|
powershell.exe -Command "mvn test -pl <module> -o -q"
|
|
138
138
|
```
|
|
139
|
-
- 结果:✅ BUILD SUCCESS /
|
|
139
|
+
- 结果:✅ BUILD SUCCESS / ❌ 编译失败(记录失败原因)
|
|
140
140
|
|
|
141
141
|
### 探测结论
|
|
142
142
|
|
|
@@ -144,240 +144,240 @@ powershell.exe -Command "mvn test -pl <module> -o -q"
|
|
|
144
144
|
|
|
145
145
|
```markdown
|
|
146
146
|
### 测试基础设施探测结果
|
|
147
|
-
- **src/test/java**:
|
|
148
|
-
- **测试依赖**:
|
|
149
|
-
- **已有测试文件**:
|
|
150
|
-
-
|
|
151
|
-
- **结论**:
|
|
147
|
+
- **src/test/java**: ✅ 存在 / ❌ 不存在
|
|
148
|
+
- **测试依赖**: ✅ spring-boot-starter-test + junit + mockito / 🟡 部分包含 / ❌ 无
|
|
149
|
+
- **已有测试文件**: ✅ N 个 / ❌ 无
|
|
150
|
+
- **测试命令可运行**: ✅ BUILD SUCCESS / ❌ 失败(原因)
|
|
151
|
+
- **结论**: ✅ 测试基础设施可用 / 🟡 测试基础设施部分可用 / ❌ 测试基础设施不可用
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
-
|
|
155
|
-
- 🟡 部分可用
|
|
156
|
-
-
|
|
154
|
+
- ✅ 可用 → 必须执行完整 TDD 流程
|
|
155
|
+
- 🟡 部分可用 → 记录可用的部分和不可用的部分,降级不可用部分
|
|
156
|
+
- ❌ 不可用 → TDD RED 降级为静态逻辑验证(见下方降级策略)
|
|
157
157
|
|
|
158
|
-
## RED
|
|
158
|
+
## RED:写测试(变更簇批量模式)
|
|
159
159
|
|
|
160
|
-
> **TDD
|
|
161
|
-
>
|
|
160
|
+
> **TDD 不可跳过。** 如果测试基础设施探测结果为 ✅ 可用,RED 阶段必须写测试。如果探测结果为 ❌ 不可用,按下方降级策略执行。
|
|
161
|
+
> **进入变更簇 RED 前必须执行原生 `run-tdd-protocol`**(详见 `../protocols.md#协议一run-tdd-protocol`),必须在写第一行测试代码或生产代码之前完成 RED 三态判定。
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
从场景表选取对应当前变更簇的测试用例:
|
|
164
164
|
|
|
165
|
-
- **单元测试**(优先):JUnit 5 + Mockito
|
|
166
|
-
- **接口测试**(必要时代码逻辑已覆盖即可,实际 HTTP 调用留给 `harness-test
|
|
167
|
-
-
|
|
165
|
+
- **单元测试**(优先):JUnit 5 + Mockito,命名 `{方法名}_{场景}_{预期结果}()`,用 AssertJ `assertThat`
|
|
166
|
+
- **接口测试**(必要时代码逻辑已覆盖即可,实际 HTTP 调用留给 `harness-test`)
|
|
167
|
+
- **多个测试类合并到一次 Maven 命令执行**:`mvn test -pl <module> -Dtest=TestA,TestB,TestC -o`
|
|
168
168
|
|
|
169
|
-
### RED 有效性判定(⚠️
|
|
169
|
+
### RED 有效性判定(⚠️ 必须逐项确认)
|
|
170
170
|
|
|
171
|
-
RED 不是"测试失败"即可通过,必须确认失败原因与目标 bug
|
|
171
|
+
RED 不是"测试失败"即可通过,必须确认失败原因与目标 bug/需求直接相关。
|
|
172
172
|
|
|
173
|
-
**有效 RED(✅ 允许进入 GREEN
|
|
173
|
+
**有效 RED(✅ 允许进入 GREEN)**:
|
|
174
174
|
- 测试编译通过
|
|
175
175
|
- 目标测试失败
|
|
176
|
-
- 失败断言指向目标业务行为(如 `assertThat(result.getEnabledIndicators()).isNotEmpty()`
|
|
177
|
-
-
|
|
176
|
+
- 失败断言指向目标业务行为(如 `assertThat(result.getEnabledIndicators()).isNotEmpty()` 失败)
|
|
177
|
+
- 失败信息能对应本次 bug 或需求(如"期望返回非空列表,但实际返回空列表")
|
|
178
178
|
|
|
179
|
-
**无效 RED(❌ 禁止进入 GREEN
|
|
179
|
+
**无效 RED(❌ 禁止进入 GREEN,必须先修测试)**:
|
|
180
180
|
- 测试编译失败(语法错误、import 缺失等)
|
|
181
181
|
- **测试直接调用 private 方法导致编译失败**
|
|
182
|
-
-
|
|
183
|
-
- mock/stubbing 错误(如 `UnnecessaryStubbingException`、`PotentialStubbingProblem
|
|
182
|
+
- **因 private 访问限制导致失败**
|
|
183
|
+
- mock/stubbing 错误(如 `UnnecessaryStubbingException`、`PotentialStubbingProblem`)
|
|
184
184
|
- `NoSuchBeanDefinitionException`(Spring 上下文加载失败)
|
|
185
|
-
- `NullPointerException`
|
|
186
|
-
-
|
|
187
|
-
- 依赖缺失(如测试依赖的类/method
|
|
188
|
-
-
|
|
189
|
-
-
|
|
185
|
+
- `NullPointerException` 来自测试搭建错误(如未 mock 依赖、未初始化测试数据)
|
|
186
|
+
- 不必要 stubbing
|
|
187
|
+
- 依赖缺失(如测试依赖的类/method 尚未创建)
|
|
188
|
+
- 测试数据非法导致前置校验失败(如必填字段为空、格式校验不通过)
|
|
189
|
+
- 失败原因与目标 bug 无关(如测试的是另一个方法的逻辑)
|
|
190
190
|
|
|
191
|
-
**RED 必须优先通过 public API / public service method / controller behavior 验证**。private 方法只作为实现细节,测试应通过 `createRule` / `updateRule` / `copyRule` / `activateVersion` / `getEnabledList`
|
|
191
|
+
**RED 必须优先通过 public API / public service method / controller behavior 验证**。private 方法只作为实现细节,测试应通过 `createRule` / `updateRule` / `copyRule` / `activateVersion` / `getEnabledList` 等公共行为间接验证。**不得把"访问 private 方法失败"记录为有效 RED。**
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
**判定流程**:
|
|
194
194
|
1. 运行测试
|
|
195
195
|
2. 查看失败输出
|
|
196
196
|
3. 逐条对照上述清单判定
|
|
197
|
-
4. 写入执行日志:`RED:
|
|
197
|
+
4. 写入执行日志:`RED: ✅有效 / 🟡部分有效 / ❌无效`
|
|
198
198
|
5. 记录失败原因
|
|
199
199
|
6. 记录是否允许进入 GREEN
|
|
200
200
|
|
|
201
|
-
**如果出现无效 RED
|
|
202
|
-
1. 必须先修复测试问题(补充 mock
|
|
201
|
+
**如果出现无效 RED**:
|
|
202
|
+
1. 必须先修复测试问题(补充 mock、修正 stub、修复测试数据等)
|
|
203
203
|
2. 重新运行测试确认 RED 有效
|
|
204
204
|
3. 只有有效 RED 后才允许进入 GREEN 阶段
|
|
205
|
-
4.
|
|
205
|
+
4. **禁止在无效 RED 后进入生产代码修改**
|
|
206
206
|
|
|
207
|
-
**greenfield 大重写的 RED
|
|
207
|
+
**greenfield 大重写的 RED 处理**:
|
|
208
208
|
|
|
209
|
-
当变更簇新建多个此前不存在的方法/类(典型:store/repository/service 大规模重写),新方法未实现时测试会抛 NullPointerException/NoSuchBeanDefinitionException
|
|
209
|
+
当变更簇新建多个此前不存在的方法/类(典型:store/repository/service 大规模重写),新方法未实现时测试会抛 NullPointerException/NoSuchBeanDefinitionException("依赖缺失"类无效 RED)。逐方法写"返回错误值的桩"以获得 clean 断言失败,在方法数多时成本过高且桩代码一次性丢弃。处理决策:
|
|
210
210
|
|
|
211
211
|
| 条件 | 处理 |
|
|
212
212
|
|---|---|
|
|
213
|
-
|
|
|
214
|
-
| 新方法多(如 10
|
|
213
|
+
| 新方法 ≤ 2-3 个,或簇内有部分已存在方法 | 仍须写桩,确保 RED 是 clean 断言失败(变更簇范式) |
|
|
214
|
+
| 新方法多(如 10+)、桩成本过高、**且有集成/端到端测试覆盖该簇行为** | 允许 `🟡RED-skip(原因)`,直接写测试+实现+GREEN 验证 |
|
|
215
215
|
|
|
216
|
-
允许 RED-skip
|
|
216
|
+
允许 RED-skip 时必须:① 执行日志记 `RED: 🟡RED-skip(greenfield 大重写,N 个新方法,由 <集成测试名> 覆盖)`;② GREEN 后必须跑该簇测试 + 集成测试全过;③ **不得用于"mock 复杂/配置麻烦"等非 greenfield 场景**(见下方"私有方法/mock 复杂降级决策表")。
|
|
217
217
|
|
|
218
|
-
###
|
|
218
|
+
### 低价值 TDD 豁免策略
|
|
219
219
|
|
|
220
|
-
以下变更**不得强制单独建立测试类并单独 Maven
|
|
220
|
+
以下变更**不得强制单独建立测试类并单独 Maven 验证**:
|
|
221
221
|
|
|
222
222
|
| 变更类型 | 验证方式 | 说明 |
|
|
223
223
|
|----------|----------|------|
|
|
224
|
-
| ErrorCode 常量 | compile 验证 +
|
|
225
|
-
| VO/DTO 字段 |
|
|
224
|
+
| ErrorCode 常量 | compile 验证 + 被高层测试间接覆盖 | 禁止为单个错误码新增独立测试类 |
|
|
225
|
+
| VO/DTO 字段 | 被 service/API 测试间接覆盖 | 字段赋值和序列化由上层测试保证 |
|
|
226
226
|
| 注释 | compile 验证 | 不影响运行时行为 |
|
|
227
227
|
| import 清理 | compile 验证 | 不影响运行时行为 |
|
|
228
|
-
|
|
|
229
|
-
| SQL 迁移脚本 |
|
|
230
|
-
| 配置模板 |
|
|
231
|
-
| 文档文件 |
|
|
228
|
+
| 格式化 | compile 验证 | 不影响运行时行为 |
|
|
229
|
+
| SQL 迁移脚本 | 静态审查 + harness-test DB 验证 | 不做 TDD,生成审查清单 |
|
|
230
|
+
| 配置模板 | 静态审查 | 部署时生效 |
|
|
231
|
+
| 文档文件 | 静态审查 | 不涉及代码 |
|
|
232
232
|
|
|
233
|
-
### 行为性修改不属豁免(新增逻辑分支必须 RED
|
|
233
|
+
### 行为性修改不属豁免(新增逻辑分支必须 RED)
|
|
234
234
|
|
|
235
|
-
正则/条件/分支逻辑变更新增的逻辑分支**不属上表豁免**,必须有对应 RED 验证该分支行为,不得仅靠现有测试覆盖省略。现有测试只证明"
|
|
235
|
+
正则/条件/分支逻辑变更新增的逻辑分支**不属上表豁免**,必须有对应 RED 验证该分支行为,不得仅靠现有测试覆盖省略。现有测试只证明"原有行为未回归",不替代"新分支有测试"。例:正则新增 UNC 拦截分支,须构造 UNC 路径先 RED(旧正则漏检)再 GREEN(新正则拦截),原有 `../` 测试覆盖不到新分支。详见 SKILL.md 规则七「行为性修改新分支必须 RED」。
|
|
236
236
|
|
|
237
237
|
### Mapper 查询条件验证规则
|
|
238
238
|
|
|
239
|
-
Mapper 查询条件、LambdaQueryWrapper、SQL/XML
|
|
239
|
+
Mapper 查询条件、LambdaQueryWrapper、SQL/XML 查询逻辑,**不得通过纯 Mock 返回值来宣称自动化测试通过**。
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
**低价值 Mock 测试(应标记为 🟡静态验证)**:
|
|
242
242
|
- Mock mapper 返回期望列表
|
|
243
|
-
-
|
|
243
|
+
- 测试只验证 service 返回了 mock 数据
|
|
244
244
|
- 没有验证实际 SQL / Wrapper 条件
|
|
245
|
-
- 无法证明 `.eq(activeFlag, true)`
|
|
245
|
+
- 无法证明 `.eq(activeFlag, true)` 等查询条件存在
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
1. run
|
|
247
|
+
**推荐验证方式**:
|
|
248
|
+
1. run 阶段标记为 🟡静态验证
|
|
249
249
|
2. test 阶段通过真实 DB / 接口验证
|
|
250
|
-
3. 如果必须自动化,使用真实 mapper(非 mock
|
|
250
|
+
3. 如果必须自动化,使用真实 mapper(非 mock)或可检查 wrapper 条件的测试方式
|
|
251
251
|
|
|
252
|
-
**禁止把纯 Mock Mapper 测试计入"Mapper 查询条件已自动化测试通过"
|
|
252
|
+
**禁止把纯 Mock Mapper 测试计入"Mapper 查询条件已自动化测试通过"。**
|
|
253
253
|
|
|
254
254
|
### 私有方法 / mock 复杂的降级决策表
|
|
255
255
|
|
|
256
|
-
>
|
|
256
|
+
> 私有方法不能直接测试,但必须优先寻找公共行为入口测试。"mock 复杂"不是直接跳过测试的充分理由。
|
|
257
257
|
|
|
258
|
-
|
|
258
|
+
跳过自动化测试前必须完成此决策表:
|
|
259
259
|
|
|
260
260
|
| 问题 | 结果 |
|
|
261
261
|
|---|---|
|
|
262
|
-
|
|
|
263
|
-
| 是否可通过 mapper/mock 构造? |
|
|
264
|
-
| 是否可通过 mockStatic 构造? |
|
|
265
|
-
|
|
|
266
|
-
|
|
|
267
|
-
|
|
|
262
|
+
| 是否存在公共方法可测? | 是/否 |
|
|
263
|
+
| 是否可通过 mapper/mock 构造? | 是/否 |
|
|
264
|
+
| 是否可通过 mockStatic 构造? | 是/否 |
|
|
265
|
+
| 是否可写轻量集成测试? | 是/否 |
|
|
266
|
+
| 跳过自动化测试的具体阻塞点 | ... |
|
|
267
|
+
| 后续必须由哪个阶段验证 | harness-test / 手工接口 / 部署验证 |
|
|
268
268
|
|
|
269
|
-
如果只是"配置麻烦"
|
|
269
|
+
如果只是"配置麻烦"或"mock 复杂",不得直接跳过。对 DTO 字段、分页返回、权限过滤、组织过滤等用户可见行为,必须优先写公共行为测试。
|
|
270
270
|
|
|
271
271
|
### TDD 降级策略
|
|
272
272
|
|
|
273
|
-
当项目无测试基础设施时,RED
|
|
273
|
+
当项目无测试基础设施时,RED 阶段降级为"静态逻辑验证":
|
|
274
274
|
|
|
275
|
-
1.
|
|
276
|
-
- 为什么降级(如:`TDD RED
|
|
277
|
-
-
|
|
275
|
+
1. **在执行日志中记录降级原因**:必须包含三项信息
|
|
276
|
+
- 为什么降级(如:`TDD RED 降级:模块 <module> 无 src/test/java 目录` 或 `pom.xml 缺少 spring-boot-starter-test 依赖`)
|
|
277
|
+
- 哪些场景只做了静态验证(列出场景编号清单)
|
|
278
278
|
- 哪些场景需要部署后验证(列出场景编号清单)
|
|
279
|
-
2.
|
|
279
|
+
2. 对每个任务,从场景表中选取相关场景,**在执行日志和覆盖报告中标注静态验证关系**(如 `执行日志:UT-001 通过静态验证 — 检查 IndicatorServiceImpl.getEnabledIndicators 已添加组织过滤逻辑`)。**不得在业务代码注释中标注覆盖关系**,避免污染业务代码
|
|
280
280
|
3. GREEN 阶段完成后,对照场景表逐条确认代码逻辑已覆盖(不运行测试,只做静态检查)
|
|
281
281
|
4. 在场景覆盖检查中标注三类状态:
|
|
282
|
-
-
|
|
282
|
+
- ✅ 已测试通过(仅在测试基础设施可用且测试已运行通过时使用)
|
|
283
283
|
- 🟡 静态验证通过,未真实测试(TDD 降级时使用)
|
|
284
|
-
-
|
|
285
|
-
5.
|
|
284
|
+
- ❌ 未覆盖 / 未验证(场景未对应代码逻辑或需端到端验证)
|
|
285
|
+
5. 输出必须明确写成:
|
|
286
286
|
- "🟡 静态逻辑验证通过"
|
|
287
|
-
- "
|
|
288
|
-
- "
|
|
289
|
-
6.
|
|
290
|
-
7.
|
|
287
|
+
- "未执行真实单元测试"
|
|
288
|
+
- "待测试基础设施补齐后运行 harness-test"
|
|
289
|
+
6. **禁止写成**:"测试全部通过"、"测试通过 N/N"、"覆盖率 100%"等含暗示真实测试已运行的表述
|
|
290
|
+
7. 提示用户在测试基础设施就绪后补充运行 `harness-test`
|
|
291
291
|
|
|
292
292
|
## GREEN:最简实现
|
|
293
293
|
|
|
294
294
|
写最少代码让测试通过。关键约束:
|
|
295
|
-
- Controller
|
|
296
|
-
- Service
|
|
295
|
+
- Controller 只做参数校验和路由
|
|
296
|
+
- Service 是唯一业务逻辑层
|
|
297
297
|
- 统一返回 `Result<T>`
|
|
298
|
-
-
|
|
299
|
-
-
|
|
300
|
-
-
|
|
298
|
+
- 集合返回空集合,不返回 null
|
|
299
|
+
- 日志用 Slf4j,不用 System.out
|
|
300
|
+
- 新增字段允许为空(兼容旧数据)
|
|
301
301
|
|
|
302
|
-
## REFACTOR
|
|
302
|
+
## REFACTOR:重构
|
|
303
303
|
|
|
304
304
|
在测试保护下重构代码结构。关键约束:
|
|
305
305
|
- 重构后重新运行测试确认全部通过
|
|
306
|
-
-
|
|
307
|
-
-
|
|
306
|
+
- 清理过程性注释(如 `// 修复分页查询缺项目类型 Bug`),改写为稳定业务规则描述或删除
|
|
307
|
+
- 检查代码注释污染:生产代码中不得保留解释"本次 bug 修复"的临时注释
|
|
308
308
|
|
|
309
309
|
## GREEN 后反模式自检(内置清单)
|
|
310
310
|
|
|
311
|
-
> 如果 `run-tdd-protocol` 已按真实 RED 执行,此步骤可跳过(已包含在 TDD
|
|
312
|
-
>
|
|
311
|
+
> 如果 `run-tdd-protocol` 已按真实 RED 执行,此步骤可跳过(已包含在 TDD 流程中)。
|
|
312
|
+
> 如果执行静态 RED 或降级,使用以下内置清单作为替代。
|
|
313
313
|
|
|
314
|
-
GREEN
|
|
314
|
+
GREEN 阶段完成后,对照以下反模式清单自检:
|
|
315
315
|
|
|
316
316
|
```
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
317
|
+
□ 测试不依赖网络或外部服务(应用 mock 替代)
|
|
318
|
+
□ 无断言链(一个测试方法只断言一个行为,不用多个 assert 串联)
|
|
319
|
+
□ 测试不验证实现细节(只验证公共行为,不验证私有方法调用)
|
|
320
|
+
□ 测试命名表达意图({方法名}_{场景}_{预期结果})
|
|
321
|
+
□ 每个测试方法独立,不依赖执行顺序
|
|
322
|
+
□ 测试数据自包含(不依赖其他测试创建的数据)
|
|
323
|
+
□ 无 sleep/硬编码等待(用 Awaitility 或条件判断替代)
|
|
324
|
+
□ 测试覆盖正常路径 + 异常路径 + 边界值
|
|
325
325
|
```
|
|
326
326
|
|
|
327
|
-
##
|
|
327
|
+
## 编译失败的处理策略
|
|
328
328
|
|
|
329
329
|
不是所有编译错误都需要修复。先判断是否与本次变更相关:
|
|
330
330
|
|
|
331
331
|
| 错误类型 | 判断方法 | 处理 |
|
|
332
332
|
|----------|----------|------|
|
|
333
|
-
| 找不到符号(新代码) |
|
|
334
|
-
|
|
|
335
|
-
| 依赖缺失 |
|
|
336
|
-
| settings.xml 乱码 | Maven
|
|
337
|
-
|
|
|
333
|
+
| 找不到符号(新代码) | 检查类路径和 import | 修复 |
|
|
334
|
+
| 找不到符号(已有代码) | 对比 git diff | 与本次变更无关 → 跳过 |
|
|
335
|
+
| 依赖缺失 | 如 import 了错误的包路径 | 修复导入路径 |
|
|
336
|
+
| settings.xml 乱码 | Maven 输出含乱码字符 | 改用相对路径 |
|
|
337
|
+
| 子模块 POM 无 parent | 非本模块的编译错误 | 用 `-pl` 跳过无关模块 |
|
|
338
338
|
|
|
339
|
-
>
|
|
339
|
+
> 关键是:不要因为一个不相关的模块编译失败就阻塞整个开发流程。
|
|
340
340
|
|
|
341
341
|
## Maven 批量验证策略
|
|
342
342
|
|
|
343
|
-
harness-run 必须减少 Maven
|
|
343
|
+
harness-run 必须减少 Maven 启动次数。
|
|
344
344
|
|
|
345
|
-
|
|
346
|
-
1.
|
|
347
|
-
2.
|
|
348
|
-
3.
|
|
349
|
-
4.
|
|
350
|
-
5. 如果前面已有 compile
|
|
345
|
+
**默认策略**:
|
|
346
|
+
1. 每个变更簇最多执行一次 RED Maven、一次 GREEN Maven
|
|
347
|
+
2. 多个测试类合并到一次 Maven 命令:`mvn test -pl <module> -Dtest=TestA,TestB,TestC -o`
|
|
348
|
+
3. 不得每新增一个测试类就立即单独跑一次 Maven
|
|
349
|
+
4. 最终 compile 只执行一次
|
|
350
|
+
5. 如果前面已有 compile 成功证据,最终 compile 可复用 verification-ledger
|
|
351
351
|
|
|
352
|
-
|
|
352
|
+
**禁止**:
|
|
353
353
|
```
|
|
354
|
-
TestA RED
|
|
354
|
+
TestA RED → TestA GREEN → TestB RED → TestB GREEN → TestC RED → TestC GREEN
|
|
355
355
|
```
|
|
356
|
-
|
|
356
|
+
**应改为**:
|
|
357
357
|
```
|
|
358
|
-
TestA+TestB+TestC RED
|
|
358
|
+
TestA+TestB+TestC RED → 实现相关代码 → TestA+TestB+TestC GREEN → 最终 compile
|
|
359
359
|
```
|
|
360
360
|
|
|
361
361
|
## Maven 证据规则
|
|
362
362
|
|
|
363
|
-
如果使用 `-q` quiet
|
|
363
|
+
如果使用 `-q` quiet 模式:
|
|
364
364
|
- 根据 exit code 0 判断命令成功
|
|
365
365
|
- 报告中必须写 `exitCode=0`
|
|
366
|
-
-
|
|
366
|
+
- **不得写"BUILD SUCCESS"**,除非输出中真实出现 BUILD SUCCESS
|
|
367
367
|
|
|
368
368
|
最终报告推荐格式:
|
|
369
|
-
- `mvn compile -q`:
|
|
370
|
-
- `mvn compile`:
|
|
369
|
+
- `mvn compile -q`: ✅ exitCode=0,无错误输出
|
|
370
|
+
- `mvn compile`: ✅ BUILD SUCCESS
|
|
371
371
|
|
|
372
|
-
|
|
372
|
+
最终 evidence 命令优先不用 `-q`,或者同时记录 exit code。
|
|
373
373
|
|
|
374
374
|
## 预存变更隔离
|
|
375
375
|
|
|
376
|
-
如果 harness-run
|
|
376
|
+
如果 harness-run 开始时检测到已有未提交变更,并且用户选择保留,必须创建 baseline。
|
|
377
377
|
|
|
378
378
|
### baseline 文件
|
|
379
379
|
|
|
380
|
-
**pre-existing-files.json
|
|
380
|
+
**pre-existing-files.json**:
|
|
381
381
|
```json
|
|
382
382
|
{
|
|
383
383
|
"detectedAt": "YYYY-MM-DD HH:mm:ss",
|
|
@@ -393,22 +393,22 @@ TestA+TestB+TestC RED
|
|
|
393
393
|
}
|
|
394
394
|
```
|
|
395
395
|
|
|
396
|
-
**pre-existing-diff.patch
|
|
396
|
+
**pre-existing-diff.patch**:完整 `git diff` 输出保存为 patch 文件。
|
|
397
397
|
|
|
398
398
|
### 变更来源区分
|
|
399
399
|
|
|
400
400
|
结束时必须在输出中区分:
|
|
401
401
|
|
|
402
|
-
| 文件 | 来源 |
|
|
402
|
+
| 文件 | 来源 | 是否计划内 | 是否允许提交 |
|
|
403
403
|
|---|---|---|---|
|
|
404
|
-
| A.java | 本次 run 修改 |
|
|
405
|
-
| B.java | run
|
|
404
|
+
| A.java | 本次 run 修改 | 是 | 是 |
|
|
405
|
+
| B.java | run 前预存变更 | 否/未知 | 需用户确认 |
|
|
406
406
|
|
|
407
|
-
如果存在预存变更,最终结果至少为 🟡WARN
|
|
407
|
+
如果存在预存变更,最终结果至少为 🟡WARN。
|
|
408
408
|
|
|
409
409
|
## SQL 迁移任务处理
|
|
410
410
|
|
|
411
|
-
SQL 迁移脚本不做 TDD
|
|
411
|
+
SQL 迁移脚本不做 TDD,也不自动执行。
|
|
412
412
|
|
|
413
413
|
### run 阶段处理
|
|
414
414
|
|
|
@@ -420,197 +420,197 @@ SQL 迁移脚本不做 TDD,也不自动执行
|
|
|
420
420
|
-- 生成时间: YYYY-MM-DD HH:mm
|
|
421
421
|
```
|
|
422
422
|
3. 生成 SQL 审查清单
|
|
423
|
-
4.
|
|
423
|
+
4. 在 run-task-status 中标记 NEEDS_DB_VALIDATION
|
|
424
424
|
|
|
425
425
|
### SQL 审查清单模板
|
|
426
426
|
|
|
427
427
|
| # | 检查项 | 结果 |
|
|
428
428
|
|:--:|--------|:---:|
|
|
429
|
-
| 1 | DROP INDEX 是否存在 IF EXISTS
|
|
430
|
-
| 2 |
|
|
431
|
-
| 3 |
|
|
432
|
-
| 4 | 是否包含 deleted_time |
|
|
433
|
-
| 5 | 是否兼容已有数据 |
|
|
434
|
-
| 6 | 是否包含历史数据修正 |
|
|
435
|
-
| 7 |
|
|
436
|
-
| 8 |
|
|
429
|
+
| 1 | DROP INDEX 是否存在 IF EXISTS 或等效检查 | ✅/❌ |
|
|
430
|
+
| 2 | 新索引名称 | <名称> |
|
|
431
|
+
| 3 | 新索引字段 | <字段列表> |
|
|
432
|
+
| 4 | 是否包含 deleted_time | 是/否 |
|
|
433
|
+
| 5 | 是否兼容已有数据 | 是/否/需验证 |
|
|
434
|
+
| 6 | 是否包含历史数据修正 | 是/否 |
|
|
435
|
+
| 7 | 是否需要备份 | 是/否 |
|
|
436
|
+
| 8 | 是否需要回滚 SQL | 是/否 |
|
|
437
437
|
|
|
438
|
-
SQL 相关任务状态:🟡 NEEDS_DB_VALIDATION
|
|
438
|
+
SQL 相关任务状态:🟡 NEEDS_DB_VALIDATION,**不得标记为完全自动化测试通过**。
|
|
439
439
|
|
|
440
|
-
##
|
|
440
|
+
## 最终状态分级
|
|
441
441
|
|
|
442
442
|
### ✅OK
|
|
443
443
|
- 所有计划内代码变更完成
|
|
444
444
|
- 关键 P0 场景已自动化测试通过
|
|
445
445
|
- compile 成功
|
|
446
|
-
-
|
|
446
|
+
- 无预存变更或预存变更已明确隔离
|
|
447
447
|
- 无非计划文件混入
|
|
448
|
-
-
|
|
448
|
+
- 无 P0 静态-only 场景
|
|
449
449
|
|
|
450
450
|
### 🟡WARN
|
|
451
451
|
- 存在 P0/P1 场景仅静态验证,需 harness-test
|
|
452
452
|
- 存在预存变更
|
|
453
453
|
- SQL 脚本需要人工执行或 DB 验证
|
|
454
|
-
- Mapper/SQL
|
|
455
|
-
-
|
|
454
|
+
- Mapper/SQL 查询只做静态验证
|
|
455
|
+
- 使用了低价值 Mock 替代真实验证
|
|
456
456
|
- compile/test 成功但仍需接口/DB 验证
|
|
457
457
|
|
|
458
458
|
### ❌FAIL
|
|
459
459
|
- compile 失败
|
|
460
460
|
- 有效测试失败
|
|
461
461
|
- RED 无法建立
|
|
462
|
-
-
|
|
462
|
+
- 非计划文件被修改且无法解释
|
|
463
463
|
- git diff --check 失败
|
|
464
464
|
|
|
465
|
-
如果存在 SQL 迁移、接口验证、DB 验证未完成,最终不得输出纯 ✅OK
|
|
466
|
-
🟡WARN:编码完成,需 harness-test 验证剩余 DB/API
|
|
465
|
+
如果存在 SQL 迁移、接口验证、DB 验证未完成,最终不得输出纯 ✅OK,应输出:
|
|
466
|
+
🟡WARN:编码完成,需 harness-test 验证剩余 DB/API 场景。
|
|
467
467
|
|
|
468
|
-
## 步骤 2:编译验证(默认轻量,按需全量 test
|
|
468
|
+
## 步骤 2:编译验证(默认轻量,按需全量 test)
|
|
469
469
|
|
|
470
|
-
> **轻量验证职责**:`/harness-run` 默认只做开发反馈,不默认跑全量 `mvn test`。是否跑全量 test
|
|
470
|
+
> **轻量验证职责**:`/harness-run` 默认只做开发反馈,不默认跑全量 `mvn test`。是否跑全量 test 按下方条件判断。
|
|
471
471
|
|
|
472
472
|
### 2a. 编译验证(始终执行)
|
|
473
473
|
|
|
474
474
|
```powershell
|
|
475
475
|
powershell.exe -Command "mvn compile -pl <module> -o"
|
|
476
476
|
```
|
|
477
|
-
优先不用 `-q`,以获取 BUILD SUCCESS
|
|
477
|
+
优先不用 `-q`,以获取 BUILD SUCCESS 证据。如果使用 `-q`,报告中写 `exitCode=0`。
|
|
478
478
|
|
|
479
|
-
### 2b. 全量 mvn test
|
|
479
|
+
### 2b. 全量 mvn test(仅当满足触发条件时执行)
|
|
480
480
|
|
|
481
|
-
默认**跳过**全量 `mvn test`,把完整单元测试留给 `/harness-test`。仅当满足以下任一条件时才在本阶段执行 `mvn test -pl <module> -o
|
|
481
|
+
默认**跳过**全量 `mvn test`,把完整单元测试留给 `/harness-test`。仅当满足以下任一条件时才在本阶段执行 `mvn test -pl <module> -o`:
|
|
482
482
|
|
|
483
|
-
-
|
|
484
|
-
-
|
|
485
|
-
-
|
|
486
|
-
-
|
|
483
|
+
- 修改了公共模块(被多模块依赖的 common/utils 等)
|
|
484
|
+
- 修改了 mapper / sql / xml
|
|
485
|
+
- 修改了权限 / 认证 / 组织过滤逻辑
|
|
486
|
+
- 修改了 controller / VO / DTO
|
|
487
487
|
- 用户要求 `full-run-validation`
|
|
488
|
-
-
|
|
488
|
+
- 用户不打算继续运行 `/harness-test`(run 需自证 P0 场景)
|
|
489
489
|
|
|
490
490
|
```powershell
|
|
491
491
|
powershell.exe -Command "mvn test -pl <module> -o"
|
|
492
492
|
```
|
|
493
493
|
|
|
494
|
-
|
|
495
|
-
- `mvn compile`(无 `-q
|
|
496
|
-
- `mvn compile -q
|
|
494
|
+
**编译/测试成功必须有明确证据**:
|
|
495
|
+
- `mvn compile`(无 `-q`)输出必须包含 `BUILD SUCCESS` 才能宣称"编译成功"
|
|
496
|
+
- `mvn compile -q`:根据 exit code 0 判断,报告中写 `✅ exitCode=0`
|
|
497
497
|
- `mvn test` 输出必须包含 `Tests run: N, Failures: 0, Errors: 0` 才能宣称"测试通过"
|
|
498
|
-
-
|
|
499
|
-
- 如果 exit code
|
|
500
|
-
-
|
|
498
|
+
- 如果命令被 hook 拒绝,**必须停止流程或切换 PowerShell 重试**,不得继续宣称"成功"
|
|
499
|
+
- 如果 exit code 非 0 或无有效 stdout,标记为 ❌ 编译失败 / 状态未知
|
|
500
|
+
- 如果是 TDD 降级(无测试基础设施),mvn test 步骤跳过,标记 🟡 静态验证
|
|
501
501
|
|
|
502
502
|
### 2c. 写入 verification-ledger
|
|
503
503
|
|
|
504
|
-
步骤 2
|
|
504
|
+
步骤 2 完成后**必须**写入/更新 `通过共享状态目录解析器定位的 evidence/verification-ledger.json`:
|
|
505
505
|
|
|
506
|
-
- `compile` 项:始终写入(status / command / scope / evidence /
|
|
507
|
-
- `unitTest` 项:仅当 2b
|
|
506
|
+
- `compile` 项:始终写入(status / command / scope / evidence / 时间戳 / durationMs)
|
|
507
|
+
- `unitTest` 项:仅当 2b 执行了全量 mvn test 时写入(testsRun / failures / errors / skipped / evidence);未执行时标记 `{"status": "NOT_RUN_BY_RUN", "note": "轻量验证,全量单元测试由 harness-test 执行"}`
|
|
508
508
|
- 顶层写入 `diffHash` / `currentHead` / `baseCommit` / `module` / `profile`
|
|
509
|
-
- `baseCommit`:merge-base 或计划起点(worktree
|
|
510
|
-
- `currentHead`:`git rev-parse HEAD
|
|
511
|
-
- `diffHash
|
|
509
|
+
- `baseCommit`:merge-base 或计划起点(worktree 分支从主分支分出点,由 harness-plan 写入、run 读取复用;缺失时用 `git merge-base HEAD <默认分支>` 兜底)
|
|
510
|
+
- `currentHead`:`git rev-parse HEAD`(步骤 2c 在 Step 5 checkpoint commit 之前执行,此时 HEAD==baseCommit;commit 后 HEAD 前移到 checkpoint commit,由 ledger-protocol reuse 规则 #2「currentHead 可前移」容忍,**不需为它改时序**)
|
|
511
|
+
- `diffHash`:**必须用 ledger-protocol「五、真实 diffHash」的 commit-invariant 三部分合并命令**(与 harness-test 重算命令逐字一致),**禁止仅用 `git diff`(未提交)**。命令如下(经 `Bash(powershell.exe:*)` 通道时外层用单引号防 `$base` 展开,见 ledger-protocol 五):
|
|
512
512
|
|
|
513
513
|
```powershell
|
|
514
514
|
powershell.exe -NoProfile -Command "$base = '<baseCommit>'; $patch = '.harness/changes/<change>/runtime/current-diff.patch'; & { git diff $base HEAD --binary; git diff --binary; git ls-files --others --exclude-standard | ForEach-Object { Get-Content -Raw -LiteralPath $_ } } | Out-File -Encoding utf8 $patch; (Get-FileHash $patch -Algorithm SHA256).Hash"
|
|
515
515
|
```
|
|
516
516
|
|
|
517
|
-
> ⚠️ **commit
|
|
517
|
+
> ⚠️ **commit 前时序陷阱(真实教训)**:步骤 2c 在 Step 5 checkpoint commit **之前**执行,此时 `git diff $base HEAD` 部分为空(HEAD==baseCommit),只有"未提交 + 未跟踪"是全量。**即使第一部分为空也必须保留三部分合并**——commit 后第一部分被填充、未提交/未跟踪变空,两者内容相同 → diffHash 一致。若省略第一部分只用未提交 diff,commit 后未提交变空 → diffHash 变化 → run→test 复用链断裂(真实日志:run 产出非规范 `8a94c874` 即因此,test 重算 `b4c580fc` 不一致,被迫重跑全量单元测试)。
|
|
518
518
|
|
|
519
|
-
> ⚠️ **禁止任何单部分简化(堵字面空子)**:上述教训只点了"
|
|
520
|
-
> - `git diff <base> HEAD --binary`(仅已提交部分):commit 后工作树 clean
|
|
521
|
-
> - `node -e "...crypto.createHash('sha256')..."`
|
|
519
|
+
> ⚠️ **禁止任何单部分简化(堵字面空子)**:上述教训只点了"仅用未提交 diff"。实际还有两种等价违规简化,均**禁止**:
|
|
520
|
+
> - `git diff <base> HEAD --binary`(仅已提交部分):commit 后工作树 clean 时结果偶然与三部分合并一致,但 commit 前算会漏未提交+未跟踪,且方法本身违反"三部分合并"要求。
|
|
521
|
+
> - `node -e "...crypto.createHash('sha256')..."` 自算:绕过 PowerShell 三部分合并命令,且无法捕获未跟踪文件内容。
|
|
522
522
|
>
|
|
523
|
-
> 无论 commit 前后、无论工作树是否 clean
|
|
523
|
+
> 无论 commit 前后、无论工作树是否 clean,**必须**用三部分合并命令。"commit 后 clean 致单部分偶然等价"不得作为省略三部分的依据——时序或工作树状态一旦变化即复现复用链断裂。
|
|
524
524
|
|
|
525
|
-
> 这样 harness-test
|
|
525
|
+
> 这样 harness-test 的 Phase 1 可读取 ledger 判断是否复用 run 的 unitTest(diffHash commit-invariant + reuse 规则 #2 允许 HEAD 前移 → run 的 checkpoint commit 不破坏复用),submit/package 也可复用 compile 结果。详见 `../protocols/ledger-protocol.md`。
|
|
526
526
|
|
|
527
|
-
## 步骤 3.5
|
|
527
|
+
## 步骤 3.5:权限/组织过滤类变更 — 安全矩阵
|
|
528
528
|
|
|
529
|
-
> 凡是修改了以下逻辑,必须强制生成安全矩阵。如果任一权限边界的预期不明确,不允许标记 harness-run
|
|
529
|
+
> 凡是修改了以下逻辑,必须强制生成安全矩阵。如果任一权限边界的预期不明确,不允许标记 harness-run 为 ✅OK。
|
|
530
530
|
|
|
531
531
|
### 触发条件
|
|
532
532
|
|
|
533
533
|
修改了以下任一逻辑即触发:
|
|
534
|
-
-
|
|
534
|
+
- 管理员 / 非管理员判断
|
|
535
535
|
- 组织编码 orgCode 过滤
|
|
536
536
|
- token 中的组织
|
|
537
537
|
- 请求参数中的组织
|
|
538
538
|
- 数据权限
|
|
539
539
|
- 越权异常
|
|
540
|
-
- public/common
|
|
540
|
+
- public/common 数据可见性
|
|
541
541
|
|
|
542
542
|
### 安全矩阵模板
|
|
543
543
|
|
|
544
|
-
| 角色 | token orgCode | 请求 orgCode | projectType | 预期结果 |
|
|
544
|
+
| 角色 | token orgCode | 请求 orgCode | projectType | 预期结果 | 覆盖状态 |
|
|
545
545
|
|---|---|---|---|---|---|
|
|
546
|
-
|
|
|
547
|
-
|
|
|
548
|
-
|
|
|
549
|
-
|
|
|
550
|
-
| 非管理员 |
|
|
551
|
-
| 非管理员 |
|
|
552
|
-
| 非管理员 |
|
|
553
|
-
| 非管理员 |
|
|
554
|
-
| 非管理员 |
|
|
555
|
-
| 非管理员 |
|
|
556
|
-
| 非管理员 |
|
|
557
|
-
| 非管理员 |
|
|
546
|
+
| 超级管理员 | 空 | 空 | 有 | 查全部 | ✅/🟡/❌ |
|
|
547
|
+
| 超级管理员 | 空 | 空 | 无 | 查全部 | ✅/🟡/❌ |
|
|
548
|
+
| 超级管理员 | 其他组织 | 指定组织 | 有 | 按请求组织查询 | ✅/🟡/❌ |
|
|
549
|
+
| 超级管理员 | 其他组织 | 指定组织 | 无 | 按请求组织查询 | ✅/🟡/❌ |
|
|
550
|
+
| 非管理员 | 本组织 | 本组织 | 有 | 允许 | ✅/🟡/❌ |
|
|
551
|
+
| 非管理员 | 本组织 | 本组织 | 无 | 允许 | ✅/🟡/❌ |
|
|
552
|
+
| 非管理员 | 本组织 | 其他组织 | 有 | 拒绝 | ✅/🟡/❌ |
|
|
553
|
+
| 非管理员 | 本组织 | 其他组织 | 无 | 拒绝 | ✅/🟡/❌ |
|
|
554
|
+
| 非管理员 | 空 | 指定组织 | 有 | 必须明确:拒绝/允许/依赖上游保证 | ✅/🟡/❌ |
|
|
555
|
+
| 非管理员 | 空 | 指定组织 | 无 | 必须明确:拒绝/允许/依赖上游保证 | ✅/🟡/❌ |
|
|
556
|
+
| 非管理员 | 本组织 | 空 | 有 | 按本组织过滤 | ✅/🟡/❌ |
|
|
557
|
+
| 非管理员 | 本组织 | 空 | 无 | 按本组织过滤 | ✅/🟡/❌ |
|
|
558
558
|
|
|
559
559
|
### 判定规则
|
|
560
560
|
|
|
561
|
-
- 如果任一权限边界的预期不明确(如"非管理员+token
|
|
562
|
-
-
|
|
561
|
+
- 如果任一权限边界的预期不明确(如"非管理员+token空+指定组织"场景未明确是拒绝还是允许),则必须标记为 ❌未验证,且不允许标记 harness-run 为 ✅OK
|
|
562
|
+
- 每个场景的覆盖状态必须真实标注:✅ 自动化测试通过 / 🟡 静态检查未真实测试 / ❌ 未验证
|
|
563
563
|
- 安全矩阵必须写入执行日志
|
|
564
564
|
|
|
565
565
|
## 步骤 4:关门检查(⚠️ 结束前强制执行)
|
|
566
566
|
|
|
567
|
-
|
|
567
|
+
在输出最终总结前,必须执行并展示以下 10 项检查:
|
|
568
568
|
|
|
569
569
|
### 1. git status --porcelain
|
|
570
570
|
```powershell
|
|
571
571
|
powershell.exe -Command "git -C '<project-path>' status --porcelain"
|
|
572
572
|
```
|
|
573
|
-
|
|
573
|
+
展示所有变更文件列表。
|
|
574
574
|
|
|
575
575
|
### 2. git diff --stat
|
|
576
576
|
```powershell
|
|
577
577
|
powershell.exe -Command "git -C '<project-path>' diff --stat"
|
|
578
578
|
```
|
|
579
|
-
|
|
579
|
+
展示变更统计。
|
|
580
580
|
|
|
581
581
|
### 3. git diff --check
|
|
582
582
|
```powershell
|
|
583
583
|
powershell.exe -Command "git -C '<project-path>' diff --check"
|
|
584
584
|
```
|
|
585
|
-
|
|
585
|
+
检查空白字符冲突。**如果此命令失败 → 最终结果必须是 ❌FAIL**。
|
|
586
586
|
|
|
587
587
|
### 4. 变更文件是否全部在计划范围内
|
|
588
|
-
对照 plan.md
|
|
588
|
+
对照 plan.md 的任务描述,确认每个变更文件都在计划范围内。
|
|
589
589
|
|
|
590
|
-
### 5.
|
|
591
|
-
|
|
590
|
+
### 5. 是否新增/修改了测试文件
|
|
591
|
+
如果探测到测试基础设施可用但未新增/修改测试文件,必须记录原因。
|
|
592
592
|
|
|
593
593
|
### 6. 是否误改 .harness/ 以外的非计划文件
|
|
594
|
-
如果有非计划文件变更
|
|
594
|
+
如果有非计划文件变更 → 至少 🟡WARN,并要求用户确认。
|
|
595
595
|
|
|
596
|
-
### 7. conflict marker
|
|
596
|
+
### 7. conflict marker 检查
|
|
597
597
|
搜索以下模式(用 Grep):
|
|
598
598
|
- `<<<<<<<`
|
|
599
599
|
- `=======`
|
|
600
600
|
- `>>>>>>>`
|
|
601
601
|
|
|
602
|
-
如果命中
|
|
602
|
+
如果命中 → 最终结果必须是 ❌FAIL。
|
|
603
603
|
|
|
604
|
-
### 8. 临时 debug
|
|
604
|
+
### 8. 临时 debug 检查
|
|
605
605
|
搜索以下模式(用 Grep):
|
|
606
606
|
- `System.out.println`
|
|
607
607
|
- `console.log`
|
|
608
608
|
- `debugger`
|
|
609
|
-
- 临时 `TODO` / `FIXME
|
|
609
|
+
- 临时 `TODO` / `FIXME`(不含计划中的 TODO)
|
|
610
610
|
|
|
611
|
-
如果命中
|
|
611
|
+
如果命中 → 在 REFACTOR 阶段清理。
|
|
612
612
|
|
|
613
|
-
### 9.
|
|
613
|
+
### 9. 敏感信息检查
|
|
614
614
|
搜索以下模式(用 Grep):
|
|
615
615
|
- `password`
|
|
616
616
|
- `token`
|
|
@@ -619,151 +619,151 @@ powershell.exe -Command "git -C '<project-path>' diff --check"
|
|
|
619
619
|
- 私有 IP 地址
|
|
620
620
|
- 内部 URL(如非必要不得新增)
|
|
621
621
|
|
|
622
|
-
如果命中且非必要
|
|
622
|
+
如果命中且非必要 → 必须清理后再标记完成。
|
|
623
623
|
|
|
624
|
-
### 10.
|
|
624
|
+
### 10. 代码注释污染检查
|
|
625
625
|
搜索以下模式(用 Grep):
|
|
626
626
|
- `// 修复` + `Bug`
|
|
627
627
|
- `// 本次` + `变更` / `修改`
|
|
628
628
|
- `// 新增` + `功能` / `字段`
|
|
629
|
-
- 其他解释"本次变更过程"
|
|
629
|
+
- 其他解释"本次变更过程"的临时注释
|
|
630
630
|
|
|
631
|
-
如果命中
|
|
631
|
+
如果命中 → 在 REFACTOR 阶段清理或改写为稳定业务规则描述。
|
|
632
632
|
|
|
633
|
-
###
|
|
633
|
+
### 关门检查结果模板
|
|
634
634
|
|
|
635
635
|
```markdown
|
|
636
|
-
##
|
|
637
|
-
- git status --porcelain:
|
|
638
|
-
- git diff --stat:
|
|
639
|
-
- git diff --check:
|
|
640
|
-
- 变更文件在计划内:
|
|
641
|
-
- 新增/修改测试文件:
|
|
642
|
-
-
|
|
643
|
-
- conflict marker: ✅无/❌有(❌
|
|
644
|
-
- 临时 debug:
|
|
645
|
-
- 敏感信息: ✅无/❌有(❌
|
|
646
|
-
- 代码注释污染:
|
|
636
|
+
## 关门检查结果
|
|
637
|
+
- git status --porcelain: ✅/❌
|
|
638
|
+
- git diff --stat: ✅/❌
|
|
639
|
+
- git diff --check: ✅/❌(❌ → 最终结果 ❌FAIL)
|
|
640
|
+
- 变更文件在计划内: ✅/❌
|
|
641
|
+
- 新增/修改测试文件: ✅/❌/🟡不适用(TDD降级)
|
|
642
|
+
- 非计划文件变更: ✅无/❌有(❌ → 🟡WARN)
|
|
643
|
+
- conflict marker: ✅无/❌有(❌ → ❌FAIL)
|
|
644
|
+
- 临时 debug: ✅无/🟡有已清理/❌有未清理
|
|
645
|
+
- 敏感信息: ✅无/❌有(❌ → 必须清理)
|
|
646
|
+
- 代码注释污染: ✅无/🟡有已清理/❌有未清理
|
|
647
647
|
```
|
|
648
648
|
|
|
649
649
|
## 步骤 5:计划状态持久化
|
|
650
650
|
|
|
651
|
-
如果 `.harness/changes/<change>/plans/*.md`
|
|
651
|
+
如果 `.harness/changes/<change>/plans/*.md` 是任务来源,则 harness-run 完成任务后必须持久化任务状态。
|
|
652
652
|
|
|
653
|
-
###
|
|
653
|
+
### 持久化方式
|
|
654
654
|
|
|
655
|
-
|
|
655
|
+
**方式一(推荐)**:更新 plan.md 中的任务状态
|
|
656
656
|
|
|
657
|
-
|
|
657
|
+
在 plan.md 的任务列表中,为每个任务追加状态标记:
|
|
658
658
|
|
|
659
659
|
```markdown
|
|
660
|
-
### Task 1:
|
|
661
|
-
-
|
|
660
|
+
### Task 1: 修复分页查询缺项目类型 Bug
|
|
661
|
+
- **状态**: ✅ DONE_AUTOMATED_TESTED
|
|
662
662
|
- **测试**: UT-001~005 已通过
|
|
663
663
|
```
|
|
664
664
|
|
|
665
|
-
|
|
665
|
+
**方式二**:新增 `run-task-status.md`
|
|
666
666
|
|
|
667
|
-
|
|
667
|
+
在 `.harness/changes/<change-name>/run-task-status.md` 中记录:
|
|
668
668
|
|
|
669
669
|
```markdown
|
|
670
|
-
# Run Task Status
|
|
670
|
+
# Run Task Status — <change-name>
|
|
671
671
|
## 执行时间: YYYY-MM-DD HH:MM
|
|
672
672
|
|
|
673
|
-
| 任务 |
|
|
673
|
+
| 任务 | 状态 | 测试场景 | 待验证 |
|
|
674
674
|
|------|------|----------|--------|
|
|
675
|
-
| Task 1 |
|
|
675
|
+
| Task 1 | ✅ DONE_AUTOMATED_TESTED | UT-001~005 | - |
|
|
676
676
|
| Task 2 | 🟡 DONE_STATIC_ONLY | UT-006~010 | harness-test |
|
|
677
677
|
| Task 3 | 🟡 DONE_NEEDS_INTERFACE_TEST | API-001~003 | harness-test |
|
|
678
678
|
|
|
679
|
-
##
|
|
679
|
+
## 待验证场景汇总
|
|
680
680
|
- UT-006~010: 静态验证通过,需 harness-test 接口验证
|
|
681
681
|
- API-001~003: 接口逻辑已覆盖,需 harness-test 真实 HTTP 验证
|
|
682
682
|
```
|
|
683
683
|
|
|
684
|
-
###
|
|
684
|
+
### 状态定义
|
|
685
685
|
|
|
686
|
-
-
|
|
686
|
+
- ✅ **DONE_AUTOMATED_TESTED**:自动化测试通过,mvn test 输出 Failures: 0
|
|
687
687
|
- 🟡 **DONE_STATIC_ONLY**:仅静态代码逻辑审查通过,未运行真实测试
|
|
688
|
-
- 🟡 **DONE_NEEDS_INTERFACE_TEST
|
|
689
|
-
-
|
|
688
|
+
- 🟡 **DONE_NEEDS_INTERFACE_TEST**:代码逻辑已实现,需接口级验证
|
|
689
|
+
- ❌ **FAILED**:编译失败或测试失败,需修复
|
|
690
690
|
|
|
691
691
|
### 规则
|
|
692
692
|
|
|
693
|
-
-
|
|
694
|
-
- 后续 harness-test
|
|
693
|
+
- 不允许只在对话里说"任务完成"但不写入任何持久化文件
|
|
694
|
+
- 后续 harness-test 和 harness-review 必须能从持久化状态识别哪些场景仍待验证
|
|
695
695
|
|
|
696
|
-
## 步骤 3
|
|
696
|
+
## 步骤 3:场景覆盖检查
|
|
697
697
|
|
|
698
|
-
|
|
698
|
+
对照场景表,逐条确认代码逻辑已覆盖,**并将覆盖结果展示给用户**。**状态必须三类标注**:
|
|
699
699
|
|
|
700
|
-
-
|
|
701
|
-
- 🟡 **静态检查通过,未真实测试**:TDD
|
|
702
|
-
-
|
|
700
|
+
- ✅ **已测试通过**:测试基础设施可用且测试已实际运行通过(mvn test 输出 Tests run + Failures: 0)
|
|
701
|
+
- 🟡 **静态检查通过,未真实测试**:TDD 降级,仅做代码逻辑静态检查。**不得计入"已测试通过"**
|
|
702
|
+
- ❌ **未覆盖 / 未验证**:场景未对应代码逻辑或需端到端验证
|
|
703
703
|
|
|
704
|
-
###
|
|
704
|
+
### 静态验证不等于测试覆盖(⚠️ 关键规则)
|
|
705
705
|
|
|
706
|
-
1. 🟡
|
|
707
|
-
2. 如果任一 P0
|
|
706
|
+
1. 🟡 静态检查 **不得计入"已测试通过"**
|
|
707
|
+
2. 如果任一 P0 场景仅静态验证,则 harness-run 最终结果必须是:
|
|
708
708
|
`🟡WARN:编码和编译完成,但存在 P0 场景未真实验证`
|
|
709
|
-
3.
|
|
709
|
+
3. 只有所有 P0 场景都有自动化测试或真实接口验证时,最终结果才能是:
|
|
710
710
|
`✅OK成功`
|
|
711
|
-
4. **最终摘要禁止写**:`5
|
|
712
|
-
5.
|
|
711
|
+
4. **最终摘要禁止写**:`5✅ + 17🟡 = 22/22`
|
|
712
|
+
5. **最终摘要必须写**:
|
|
713
713
|
```
|
|
714
714
|
自动化测试通过: 5
|
|
715
715
|
静态检查未真实验证: 17
|
|
716
|
-
|
|
717
|
-
harness-run 结果: 🟡WARN
|
|
716
|
+
未验证: 0
|
|
717
|
+
harness-run 结果: 🟡WARN,必须进入 harness-test 后才能 submit
|
|
718
718
|
```
|
|
719
719
|
|
|
720
|
-
>
|
|
720
|
+
> 展示格式示例:
|
|
721
721
|
> ```
|
|
722
|
-
> ###
|
|
723
|
-
> -
|
|
724
|
-
> - 🟡 UT-006~010: getIndicatorPage
|
|
725
|
-
> -
|
|
726
|
-
> -
|
|
727
|
-
> -
|
|
728
|
-
> - 🟡 INT-001~004:
|
|
722
|
+
> ### 场景覆盖检查
|
|
723
|
+
> - ✅ UT-001~005: getEnabledIndicators 正常/异常/边界场景已测试通过
|
|
724
|
+
> - 🟡 UT-006~010: getIndicatorPage 分页场景静态验证通过,待测试基础设施补齐后运行 harness-test
|
|
725
|
+
> - ❌ UT-011~015: getIndicatorByCode 场景未覆盖,需补充测试用例
|
|
726
|
+
> - ✅ API-001~005: enabled 接口场景代码逻辑已覆盖(接口测试待 harness-test 验证)
|
|
727
|
+
> - ✅ COM-001~005: SQL 迁移脚本覆盖
|
|
728
|
+
> - 🟡 INT-001~004: 需端到端部署验证
|
|
729
729
|
> ```
|
|
730
730
|
>
|
|
731
|
-
>
|
|
731
|
+
> **最终汇总**:
|
|
732
732
|
> ```
|
|
733
733
|
> 自动化测试通过: 5
|
|
734
734
|
> 静态检查未真实验证: 17
|
|
735
|
-
>
|
|
736
|
-
> harness-run 结果: 🟡WARN
|
|
735
|
+
> 未验证: 0
|
|
736
|
+
> harness-run 结果: 🟡WARN,必须进入 harness-test 后才能 submit
|
|
737
737
|
> ```
|
|
738
738
|
|
|
739
739
|
## 输出示例
|
|
740
740
|
|
|
741
741
|
```markdown
|
|
742
|
-
## 编码完成
|
|
742
|
+
## 编码完成 — <功能名>
|
|
743
743
|
|
|
744
|
-
### 变更文件 (N
|
|
744
|
+
### 变更文件 (N 个)
|
|
745
745
|
| 文件 | 类型 | 说明 |
|
|
746
746
|
|------|:----:|------|
|
|
747
747
|
| xxx.java | 新增 | ... |
|
|
748
748
|
| xxx.java | 修改 | ... |
|
|
749
749
|
|
|
750
750
|
### 编译验证
|
|
751
|
-
- mvn compile:
|
|
752
|
-
- mvn test:
|
|
751
|
+
- mvn compile: ✅ BUILD SUCCESS(如证据明确) / 🟡 静态验证 / ❌ 命令被拒绝/失败
|
|
752
|
+
- mvn test: ✅ N tests run, 0 failures(如证据明确) / 🟡 未执行真实测试,仅静态验证 / ❌ 命令被拒绝/失败
|
|
753
753
|
|
|
754
754
|
### 场景覆盖
|
|
755
755
|
- 自动化测试通过: K
|
|
756
756
|
- 静态检查未真实验证: M
|
|
757
|
-
-
|
|
758
|
-
- harness-run 结果: ✅OK成功 / 🟡WARN
|
|
759
|
-
|
|
760
|
-
###
|
|
761
|
-
- git status --porcelain:
|
|
762
|
-
- git diff --stat:
|
|
763
|
-
- git diff --check:
|
|
764
|
-
- 变更文件在计划内:
|
|
765
|
-
- 新增/修改测试文件:
|
|
766
|
-
-
|
|
757
|
+
- 未验证: P
|
|
758
|
+
- harness-run 结果: ✅OK成功 / 🟡WARN,必须进入 harness-test 后才能 submit
|
|
759
|
+
|
|
760
|
+
### 关门检查结果
|
|
761
|
+
- git status --porcelain: ✅/❌
|
|
762
|
+
- git diff --stat: ✅/❌
|
|
763
|
+
- git diff --check: ✅/❌
|
|
764
|
+
- 变更文件在计划内: ✅/❌
|
|
765
|
+
- 新增/修改测试文件: ✅/❌/🟡不适用
|
|
766
|
+
- 非计划文件变更: ✅无/❌有
|
|
767
767
|
- conflict marker: ✅无/❌有
|
|
768
768
|
- 临时 debug: ✅无/🟡有已清理
|
|
769
769
|
- 敏感信息: ✅无/❌有
|
|
@@ -772,31 +772,31 @@ powershell.exe -Command "git -C '<project-path>' diff --check"
|
|
|
772
772
|
### 计划状态持久化
|
|
773
773
|
- 状态已写入: `.harness/changes/<change-name>/run-task-status.md`
|
|
774
774
|
|
|
775
|
-
###
|
|
776
|
-
> ⚠️ 如果存在 P0
|
|
775
|
+
### 下一步
|
|
776
|
+
> ⚠️ 如果存在 P0 场景为 🟡静态验证,下一步必须且只能是 harness-test。
|
|
777
777
|
|
|
778
|
-
运行 `/harness-test` 验证剩余 P0
|
|
779
|
-
|
|
778
|
+
运行 `/harness-test` 验证剩余 P0 场景。
|
|
779
|
+
在 harness-test 通过前,不建议也不应进入 `/harness-submit`。
|
|
780
780
|
```
|
|
781
781
|
|
|
782
782
|
## 关键原则
|
|
783
783
|
|
|
784
|
-
- 增量编译优先:`powershell.exe -Command "mvn compile -pl <module> -o -q"
|
|
785
|
-
-
|
|
784
|
+
- 增量编译优先:`powershell.exe -Command "mvn compile -pl <module> -o -q"`(不用 clean,用离线模式加速)
|
|
785
|
+
- 编译失败不盲目重试:先分析错误类型,再针对性修复
|
|
786
786
|
- 与本次变更无关的编译错误记录但跳过,不要阻塞流程
|
|
787
|
-
- SQL
|
|
788
|
-
- 不在代码或日志中输出明文 Token
|
|
789
|
-
- **TDD
|
|
790
|
-
-
|
|
791
|
-
-
|
|
787
|
+
- SQL 变更只生成脚本,不自动执行;脚本保存到 `.harness/changes/<change-name>/sqls/`
|
|
788
|
+
- 不在代码或日志中输出明文 Token/密码(遵循 `../protocols/sensitive-info-protocol.md`)
|
|
789
|
+
- **TDD 降级时不得伪装为真实测试通过**(遵循 `../protocols/evidence-based-reporting-protocol.md`)
|
|
790
|
+
- **编译/测试结论必须有证据绑定**:BUILD SUCCESS / Tests run + 0 Failures / 实际文件存在 / exit code 0
|
|
791
|
+
- **长时间命令处理**:`mvn compile` 和 `mvn test` 可能需要 1-5 分钟。使用后台执行或等待完成,不要在等待中超时停顿要求用户发"继续"
|
|
792
792
|
|
|
793
793
|
## 执行日志记录
|
|
794
794
|
|
|
795
|
-
`/harness-run` 只向 `events.ndjson` 追加事件(schema_version 3
|
|
795
|
+
`/harness-run` 只向 `events.ndjson` 追加事件(schema_version 3,兼容读取 v1/v2);`logs/execution-log.md` 由 `harness_events.py append` 自动渲染。步骤 0 之前 append `phase.start`;各阶段写入 `command` / `verification` / `decision` / `issue`,人类可读摘要放 `note`。详见 [[../../protocols/report-pipeline-protocol.md|report-pipeline-protocol]] 与 core `harness-run/SKILL.md`。
|
|
796
796
|
|
|
797
|
-
## verification-ledger
|
|
797
|
+
## verification-ledger 可复用判定
|
|
798
798
|
|
|
799
|
-
|
|
799
|
+
后续阶段只有在以下字段齐全且匹配时才允许复用:
|
|
800
800
|
|
|
801
801
|
- `diffHash`
|
|
802
802
|
- `currentHead`
|
|
@@ -806,15 +806,15 @@ powershell.exe -Command "git -C '<project-path>' diff --check"
|
|
|
806
806
|
- `validations.<type>.status`
|
|
807
807
|
- 明确证据:`BUILD SUCCESS` / `Tests run: N, Failures: 0, Errors: 0` / `exitCode=0`
|
|
808
808
|
|
|
809
|
-
缺任一字段:`ledgerReusable=false
|
|
809
|
+
缺任一字段:`ledgerReusable=false`。
|
|
810
810
|
|
|
811
811
|
## Mapper @Select / JOIN / IPage 真实验证要求
|
|
812
812
|
|
|
813
|
-
`@Select`、JOIN、DISTINCT、IPage 分页、SQL/XML
|
|
813
|
+
`@Select`、JOIN、DISTINCT、IPage 分页、SQL/XML 变更在 run 阶段只能标记 🟡DONE_STATIC_ONLY,必须交给 harness-test 真实 DB/API 验证:
|
|
814
814
|
|
|
815
815
|
- SQL 可执行;
|
|
816
|
-
- total
|
|
817
|
-
- records
|
|
818
|
-
- orgCode
|
|
819
|
-
-
|
|
820
|
-
- pageNo/pageSize
|
|
816
|
+
- total 正确;
|
|
817
|
+
- records 正确;
|
|
818
|
+
- orgCode 条件与 scene 条件同时生效;
|
|
819
|
+
- 无场景关联指标不会误返回;
|
|
820
|
+
- pageNo/pageSize 分页正确。
|