@hunter-harness/workflow-harness 0.2.4 → 0.2.6

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 (242) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +5 -2
  3. package/harness/bundles/general/claude-code/harness-archive/reference.md +1 -1
  4. package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +78 -155
  5. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +4 -2
  6. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +5 -3
  7. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  8. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +4 -2
  9. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +6 -3
  10. package/harness/bundles/general/claude-code/harness-review/SKILL.md +6 -3
  11. package/harness/bundles/general/claude-code/harness-run/SKILL.md +19 -4
  12. package/harness/bundles/general/claude-code/harness-run/checklist.md +7 -3
  13. package/harness/bundles/general/claude-code/harness-run/reference.md +4 -10
  14. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +9 -4
  15. package/harness/bundles/general/claude-code/harness-submit/checklist.md +10 -1
  16. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +5 -3
  17. package/harness/bundles/general/claude-code/harness-test/SKILL.md +18 -3
  18. package/harness/bundles/general/claude-code/harness-test/checklist.md +4 -0
  19. package/harness/bundles/general/claude-code/harness-test/reference.md +5 -5
  20. package/harness/bundles/general/claude-code/protocols/archive-report-protocol.md +2 -4
  21. package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +8 -16
  22. package/harness/bundles/general/claude-code/protocols/report-pipeline-protocol.md +11 -4
  23. package/harness/bundles/general/claude-code/scripts/harness_archive.py +190 -32
  24. package/harness/bundles/general/claude-code/scripts/harness_events.py +134 -40
  25. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +111 -5
  26. package/harness/bundles/general/claude-code/scripts/harness_preflight.py +46 -3
  27. package/harness/bundles/general/claude-code/scripts/harness_profile.py +31 -3
  28. package/harness/bundles/general/claude-code/scripts/harness_state.py +148 -0
  29. package/harness/bundles/general/claude-code/scripts/harness_test_guard.py +502 -0
  30. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  31. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +5 -2
  32. package/harness/bundles/general/codebuddy/harness-archive/reference.md +1 -1
  33. package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +78 -155
  34. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +4 -2
  35. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +5 -3
  36. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  37. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +4 -2
  38. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +6 -3
  39. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +6 -3
  40. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +19 -4
  41. package/harness/bundles/general/codebuddy/harness-run/checklist.md +7 -3
  42. package/harness/bundles/general/codebuddy/harness-run/reference.md +4 -10
  43. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +9 -4
  44. package/harness/bundles/general/codebuddy/harness-submit/checklist.md +10 -1
  45. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +5 -3
  46. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +18 -3
  47. package/harness/bundles/general/codebuddy/harness-test/checklist.md +4 -0
  48. package/harness/bundles/general/codebuddy/harness-test/reference.md +5 -5
  49. package/harness/bundles/general/codebuddy/protocols/archive-report-protocol.md +2 -4
  50. package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +8 -16
  51. package/harness/bundles/general/codebuddy/protocols/report-pipeline-protocol.md +11 -4
  52. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +190 -32
  53. package/harness/bundles/general/codebuddy/scripts/harness_events.py +134 -40
  54. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +111 -5
  55. package/harness/bundles/general/codebuddy/scripts/harness_preflight.py +46 -3
  56. package/harness/bundles/general/codebuddy/scripts/harness_profile.py +31 -3
  57. package/harness/bundles/general/codebuddy/scripts/harness_state.py +148 -0
  58. package/harness/bundles/general/codebuddy/scripts/harness_test_guard.py +502 -0
  59. package/harness/bundles/general/codex/.harness-build.json +1 -1
  60. package/harness/bundles/general/codex/harness-archive/SKILL.md +5 -2
  61. package/harness/bundles/general/codex/harness-archive/reference.md +1 -1
  62. package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +78 -155
  63. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +4 -2
  64. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +5 -3
  65. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  66. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +4 -2
  67. package/harness/bundles/general/codex/harness-plan/SKILL.md +6 -3
  68. package/harness/bundles/general/codex/harness-review/SKILL.md +5 -2
  69. package/harness/bundles/general/codex/harness-run/SKILL.md +19 -4
  70. package/harness/bundles/general/codex/harness-run/checklist.md +7 -3
  71. package/harness/bundles/general/codex/harness-run/reference.md +4 -10
  72. package/harness/bundles/general/codex/harness-submit/SKILL.md +9 -4
  73. package/harness/bundles/general/codex/harness-submit/checklist.md +10 -1
  74. package/harness/bundles/general/codex/harness-sync/SKILL.md +5 -3
  75. package/harness/bundles/general/codex/harness-test/SKILL.md +18 -3
  76. package/harness/bundles/general/codex/harness-test/checklist.md +4 -0
  77. package/harness/bundles/general/codex/harness-test/reference.md +5 -5
  78. package/harness/bundles/general/codex/protocols/archive-report-protocol.md +2 -4
  79. package/harness/bundles/general/codex/protocols/ledger-protocol.md +8 -16
  80. package/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +11 -4
  81. package/harness/bundles/general/codex/scripts/harness_archive.py +190 -32
  82. package/harness/bundles/general/codex/scripts/harness_events.py +134 -40
  83. package/harness/bundles/general/codex/scripts/harness_ledger.py +111 -5
  84. package/harness/bundles/general/codex/scripts/harness_preflight.py +46 -3
  85. package/harness/bundles/general/codex/scripts/harness_profile.py +31 -3
  86. package/harness/bundles/general/codex/scripts/harness_state.py +148 -0
  87. package/harness/bundles/general/codex/scripts/harness_test_guard.py +502 -0
  88. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  89. package/harness/bundles/general/cursor/harness-archive/SKILL.md +5 -2
  90. package/harness/bundles/general/cursor/harness-archive/reference.md +1 -1
  91. package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +78 -155
  92. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +4 -2
  93. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +5 -3
  94. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  95. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +4 -2
  96. package/harness/bundles/general/cursor/harness-plan/SKILL.md +6 -3
  97. package/harness/bundles/general/cursor/harness-review/SKILL.md +5 -2
  98. package/harness/bundles/general/cursor/harness-run/SKILL.md +19 -4
  99. package/harness/bundles/general/cursor/harness-run/checklist.md +7 -3
  100. package/harness/bundles/general/cursor/harness-run/reference.md +4 -10
  101. package/harness/bundles/general/cursor/harness-submit/SKILL.md +9 -4
  102. package/harness/bundles/general/cursor/harness-submit/checklist.md +10 -1
  103. package/harness/bundles/general/cursor/harness-sync/SKILL.md +5 -3
  104. package/harness/bundles/general/cursor/harness-test/SKILL.md +18 -3
  105. package/harness/bundles/general/cursor/harness-test/checklist.md +4 -0
  106. package/harness/bundles/general/cursor/harness-test/reference.md +5 -5
  107. package/harness/bundles/general/cursor/protocols/archive-report-protocol.md +2 -4
  108. package/harness/bundles/general/cursor/protocols/ledger-protocol.md +8 -16
  109. package/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +11 -4
  110. package/harness/bundles/general/cursor/scripts/harness_archive.py +190 -32
  111. package/harness/bundles/general/cursor/scripts/harness_events.py +134 -40
  112. package/harness/bundles/general/cursor/scripts/harness_ledger.py +111 -5
  113. package/harness/bundles/general/cursor/scripts/harness_preflight.py +46 -3
  114. package/harness/bundles/general/cursor/scripts/harness_profile.py +31 -3
  115. package/harness/bundles/general/cursor/scripts/harness_state.py +148 -0
  116. package/harness/bundles/general/cursor/scripts/harness_test_guard.py +502 -0
  117. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  118. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +5 -2
  119. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +5 -2
  120. package/harness/bundles/java/claude-code/harness-archive/reference.md +1 -1
  121. package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +78 -155
  122. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +4 -2
  123. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +5 -3
  124. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  125. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +4 -2
  126. package/harness/bundles/java/claude-code/harness-package/SKILL.md +5 -2
  127. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +6 -3
  128. package/harness/bundles/java/claude-code/harness-review/SKILL.md +6 -3
  129. package/harness/bundles/java/claude-code/harness-run/SKILL.md +22 -5
  130. package/harness/bundles/java/claude-code/harness-run/reference.md +1 -1
  131. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +9 -4
  132. package/harness/bundles/java/claude-code/harness-submit/checklist.md +10 -1
  133. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +5 -3
  134. package/harness/bundles/java/claude-code/harness-test/SKILL.md +20 -3
  135. package/harness/bundles/java/claude-code/harness-test/reference.md +1 -1
  136. package/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +2 -4
  137. package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +8 -16
  138. package/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +11 -4
  139. package/harness/bundles/java/claude-code/scripts/harness_archive.py +190 -32
  140. package/harness/bundles/java/claude-code/scripts/harness_events.py +134 -40
  141. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +111 -5
  142. package/harness/bundles/java/claude-code/scripts/harness_preflight.py +46 -3
  143. package/harness/bundles/java/claude-code/scripts/harness_profile.py +31 -3
  144. package/harness/bundles/java/claude-code/scripts/harness_state.py +148 -0
  145. package/harness/bundles/java/claude-code/scripts/harness_test_guard.py +502 -0
  146. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  147. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +5 -2
  148. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +5 -2
  149. package/harness/bundles/java/codebuddy/harness-archive/reference.md +1 -1
  150. package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +78 -155
  151. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +4 -2
  152. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +5 -3
  153. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  154. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +4 -2
  155. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +5 -2
  156. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +6 -3
  157. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +6 -3
  158. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +22 -5
  159. package/harness/bundles/java/codebuddy/harness-run/reference.md +1 -1
  160. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +9 -4
  161. package/harness/bundles/java/codebuddy/harness-submit/checklist.md +10 -1
  162. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +5 -3
  163. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +20 -3
  164. package/harness/bundles/java/codebuddy/harness-test/reference.md +1 -1
  165. package/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +2 -4
  166. package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +8 -16
  167. package/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +11 -4
  168. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +190 -32
  169. package/harness/bundles/java/codebuddy/scripts/harness_events.py +134 -40
  170. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +111 -5
  171. package/harness/bundles/java/codebuddy/scripts/harness_preflight.py +46 -3
  172. package/harness/bundles/java/codebuddy/scripts/harness_profile.py +31 -3
  173. package/harness/bundles/java/codebuddy/scripts/harness_state.py +148 -0
  174. package/harness/bundles/java/codebuddy/scripts/harness_test_guard.py +502 -0
  175. package/harness/bundles/java/codex/.harness-build.json +1 -1
  176. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +5 -2
  177. package/harness/bundles/java/codex/harness-archive/SKILL.md +5 -2
  178. package/harness/bundles/java/codex/harness-archive/reference.md +1 -1
  179. package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +78 -155
  180. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +4 -2
  181. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +5 -3
  182. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  183. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +4 -2
  184. package/harness/bundles/java/codex/harness-package/SKILL.md +5 -2
  185. package/harness/bundles/java/codex/harness-plan/SKILL.md +6 -3
  186. package/harness/bundles/java/codex/harness-review/SKILL.md +5 -2
  187. package/harness/bundles/java/codex/harness-run/SKILL.md +22 -5
  188. package/harness/bundles/java/codex/harness-run/reference.md +1 -1
  189. package/harness/bundles/java/codex/harness-submit/SKILL.md +9 -4
  190. package/harness/bundles/java/codex/harness-submit/checklist.md +10 -1
  191. package/harness/bundles/java/codex/harness-sync/SKILL.md +5 -3
  192. package/harness/bundles/java/codex/harness-test/SKILL.md +20 -3
  193. package/harness/bundles/java/codex/harness-test/reference.md +1 -1
  194. package/harness/bundles/java/codex/protocols/archive-report-protocol.md +2 -4
  195. package/harness/bundles/java/codex/protocols/ledger-protocol.md +8 -16
  196. package/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +11 -4
  197. package/harness/bundles/java/codex/scripts/harness_archive.py +190 -32
  198. package/harness/bundles/java/codex/scripts/harness_events.py +134 -40
  199. package/harness/bundles/java/codex/scripts/harness_ledger.py +111 -5
  200. package/harness/bundles/java/codex/scripts/harness_preflight.py +46 -3
  201. package/harness/bundles/java/codex/scripts/harness_profile.py +31 -3
  202. package/harness/bundles/java/codex/scripts/harness_state.py +148 -0
  203. package/harness/bundles/java/codex/scripts/harness_test_guard.py +502 -0
  204. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  205. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +5 -2
  206. package/harness/bundles/java/cursor/harness-archive/SKILL.md +5 -2
  207. package/harness/bundles/java/cursor/harness-archive/reference.md +1 -1
  208. package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +78 -155
  209. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +4 -2
  210. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +5 -3
  211. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +83 -6
  212. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +4 -2
  213. package/harness/bundles/java/cursor/harness-package/SKILL.md +5 -2
  214. package/harness/bundles/java/cursor/harness-plan/SKILL.md +6 -3
  215. package/harness/bundles/java/cursor/harness-review/SKILL.md +5 -2
  216. package/harness/bundles/java/cursor/harness-run/SKILL.md +22 -5
  217. package/harness/bundles/java/cursor/harness-run/reference.md +1 -1
  218. package/harness/bundles/java/cursor/harness-submit/SKILL.md +9 -4
  219. package/harness/bundles/java/cursor/harness-submit/checklist.md +10 -1
  220. package/harness/bundles/java/cursor/harness-sync/SKILL.md +5 -3
  221. package/harness/bundles/java/cursor/harness-test/SKILL.md +20 -3
  222. package/harness/bundles/java/cursor/harness-test/reference.md +1 -1
  223. package/harness/bundles/java/cursor/protocols/archive-report-protocol.md +2 -4
  224. package/harness/bundles/java/cursor/protocols/ledger-protocol.md +8 -16
  225. package/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +11 -4
  226. package/harness/bundles/java/cursor/scripts/harness_archive.py +190 -32
  227. package/harness/bundles/java/cursor/scripts/harness_events.py +134 -40
  228. package/harness/bundles/java/cursor/scripts/harness_ledger.py +111 -5
  229. package/harness/bundles/java/cursor/scripts/harness_preflight.py +46 -3
  230. package/harness/bundles/java/cursor/scripts/harness_profile.py +31 -3
  231. package/harness/bundles/java/cursor/scripts/harness_state.py +148 -0
  232. package/harness/bundles/java/cursor/scripts/harness_test_guard.py +502 -0
  233. package/harness/manifests/general/claude-code.json +33 -29
  234. package/harness/manifests/general/codebuddy.json +33 -29
  235. package/harness/manifests/general/codex.json +33 -29
  236. package/harness/manifests/general/cursor.json +33 -29
  237. package/harness/manifests/java/claude-code.json +33 -29
  238. package/harness/manifests/java/codebuddy.json +33 -29
  239. package/harness/manifests/java/codex.json +33 -29
  240. package/harness/manifests/java/cursor.json +33 -29
  241. package/hunter-workflow-family.json +2 -2
  242. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  name: harness-run
3
3
  description: 按变更簇执行 TDD 编码循环(RED→GREEN→REFACTOR→编译验证),逐变更簇实现计划中的任务。使用场景:开始编码、实现功能、写代码、TDD 编码
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=ab1182505b44093f; overlay=none; agent=codex; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=7e031c982caba51d; overlay=none; agent=codex; do not edit -->
6
6
  # harness-run — 需求编码
7
7
 
8
8
  ## Purpose
@@ -44,6 +44,7 @@ description: 按变更簇执行 TDD 编码循环(RED→GREEN→REFACTOR→编
44
44
  6. **implementation-detail** — 自适应执行参考;legacy 缺失 🟡WARN,不阻断
45
45
  7. **test-scenarios** — 测试真相源:`plans/<change>-test-scenarios.md`
46
46
  8. **禁止读取 `docs/superpowers/` 作为正式输入** — 旧草稿仅人工线索
47
+ 9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/knowledge/change/code 指纹,不再重复跑全量 `harness-sync`、知识重建或代码库扫描。只有对应 segment 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
47
48
 
48
49
  状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
49
50
 
@@ -56,7 +57,7 @@ description: 按变更簇执行 TDD 编码循环(RED→GREEN→REFACTOR→编
56
57
  0. 加载上下文(change-name、spec/plan/detail/scenarios/ledger/run-task-status/worktree;`--fixback` 读 fixback)→ append `phase.start`
57
58
  0.5. **测试基础设施探测**(先写 `CHECKING`,四项证据齐备后再结论)→ `reference.md` Step 0.5
58
59
  1. **变更簇 TDD** — `protocols.md` `run-tdd-protocol`;批量 RED/GREEN;按需 `change-cluster-review-protocol`(高风险 + reviewer 预检可用)
59
- 2. 构建验证 + 写 ledger(diffHash 三部分合并,`reference.md` Step 2c)
60
+ 2. 构建验证 + 写 ledger(`harness_ledger.py diff-hash --change-dir` 纳入 ignored tests,`reference.md` Step 2c)
60
61
  3. **场景覆盖检查**(场景表映射,禁止用用例数冒充场景数)
61
62
  4. **关门检查**(10 项)+ 计划状态持久化
62
63
 
@@ -78,12 +79,24 @@ description: 按变更簇执行 TDD 编码循环(RED→GREEN→REFACTOR→编
78
79
  | **变更簇 TDD** | 一簇一次 RED/GREEN;低价值项豁免;新分支必须 RED |
79
80
  | **RED/GREEN** | RED 须有效;静态验证 ≠ 测试通过;greenfield 大重写豁免见 reference |
80
81
  | **Mapper/DB** | 纯 Mock 不得宣称 DB 验证通过;迁移脚本**永不自动执行** |
81
- | **探测/ledger** | 基础设施先探测;每次构建/测试写 ledger;三部分 diffHash |
82
+ | **探测/ledger** | 基础设施先探测;每次构建/测试写 ledger;用 canonical `diff-hash --change-dir` |
82
83
  | **预存变更** | 保留 → baseline 隔离;存在则最终 ≥ 🟡WARN |
83
84
  | **关门/状态** | 10 项关门检查;持久化 run-task-status;P0 静态-only 不得建议 submit |
84
85
  | **Worktree** | `requested=true` 时代码只写 worktree |
85
86
  | **PowerShell** | 所有 git/构建经 `powershell.exe -NoProfile -Command` |
86
87
 
88
+ ### 陈旧测试安全修复与精确跟踪
89
+
90
+ 测试编译或 RED/GREEN 失败时,先区分当前实现缺陷、测试基础设施故障与陈旧测试。只有同时满足以下条件才允许自动修复陈旧测试:当前生产代码、已批准计划或可验证的历史变更能唯一确定新契约;修改范围仅限测试文件;修复后会立即重跑该测试及本变更目标测试。符合时以 `stale-test-repair` 记录:
91
+
92
+ ```text
93
+ python <skills-root>/scripts/harness_test_guard.py record --project . --change-dir ".harness/changes/<change-name>" --files "<精确测试文件路径,逗号分隔>" --reason stale-test-repair --json
94
+ ```
95
+
96
+ 新建或正常更新测试分别使用 `tdd-created` / `test-updated`。若预期行为存在业务歧义,停止测试修复并记录 `BLOCKED_PREEXISTING`,不得猜测新断言。
97
+
98
+ **禁止临时排除测试**:不得将测试改名为 `.bak`、移出测试目录、删除、添加 `@Disabled`/`@Ignore`、修改 Surefire/Gradle exclude 或跳过测试来制造绿色结果;也不得仅为满足陈旧测试而修改生产代码。`.gitignore` 中的测试只能通过 manifest 的精确路径闭环处理,禁止全局放宽 ignore。
99
+
87
100
  ## Output Format
88
101
 
89
102
  变更文件表 + 构建/测试证据 + 场景覆盖摘要 + 最终状态(✅OK / 🟡WARN / ❌FAIL)。→ `reference.md`
@@ -102,7 +115,7 @@ description: 按变更簇执行 TDD 编码循环(RED→GREEN→REFACTOR→编
102
115
 
103
116
  ## 执行日志
104
117
 
105
- `events.ndjson` 为唯一事实源(schema_version 2,`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
118
+ `events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
106
119
 
107
120
  ```powershell
108
121
  python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
@@ -111,3 +124,5 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
111
124
  > **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
112
125
 
113
126
  > **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
127
+
128
+ 每次阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`;重试同一阶段时增加 `--attempt <n>`,不得覆盖或伪装成一次执行。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
@@ -57,6 +57,9 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
57
57
  - [ ] 探测 4:目标模块测试基础设施是否可用(按技术栈,如 Java 的 `mvn test-compile -pl <module> -o -q` 验证测试可编译,或测试枚举/秒级 smoke;**禁止完整模块测试**,spec §3.3)
58
58
  - [ ] 四项证据收集完毕 → 写结论:✅ 测试基础设施可用 / 🟡 测试基础设施部分可用 / ❌ 测试基础设施不可用
59
59
  - [ ] 如果 ❌ 不可用 → 记录 TDD 降级原因(必须引用具体证据,如"模块 X 无测试目录(如 Java 的 src/test/java)")
60
+ - [ ] 若探测失败来自具体陈旧测试,先执行「陈旧测试安全修复」判定:当前代码/批准计划/可验证历史唯一确定契约 + 仅改测试 + 立即重跑;满足才修复,否则记录 `BLOCKED_PREEXISTING`
61
+ - [ ] 修复/新增/更新的精确测试路径已用 `harness_test_guard.py record` 记录为 `stale-test-repair` / `tdd-created` / `test-updated`
62
+ - [ ] **禁止临时排除测试**:未使用 `.bak`/改名/移目录/删除/禁用注解/build exclude/skip-tests 绕过失败
60
63
 
61
64
  ## 步骤 0.2:预存变更检测与隔离
62
65
 
@@ -147,7 +150,7 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
147
150
  - [ ] 判断是否需要全量测试:改了公共模块/数据访问层/数据库迁移/权限认证/接口层/数据契约,或用户要求 full-run-validation → 执行测试命令(按技术栈,如 Java 的 `mvn test -pl <module> -o`);否则跳过全量测试
148
151
  - [ ] 构建失败 → 先分析错误类型(见 reference.md 构建失败策略表)
149
152
  - [ ] **写入 verification-ledger.json**:`compile` 项必写(status/command/scope/evidence/时间戳/durationMs);若执行了测试命令则 `unitTest` 项必写(testsRun/failures/errors/skipped/evidence);未执行时标记 `NOT_RUN_BY_RUN`
150
- - [ ] 顶层写入 `diffHash` / `currentHead` / `module` / `profile`;`diffHash` **必须用三部分合并命令**(inline reference 步骤 2c,与 ledger-protocol 五一致),**禁止仅用 `git diff` 未提交**;`currentHead`=`git rev-parse HEAD`
153
+ - [ ] 顶层写入 `diffHash` / `currentHead` / `module` / `profile`;`diffHash` 必须执行 `harness_ledger.py diff-hash --repo . --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json`,纳入 test-tracking manifest 中的 ignored tests;`currentHead`=`git rev-parse HEAD`
151
154
  - [ ] test/submit/package 阶段如果 diffHash 一致,可复用 run 的 compile/unitTest 结果
152
155
 
153
156
  ## 步骤 3:场景覆盖检查
@@ -215,7 +218,8 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
215
218
  - [ ] 生成变更摘要:`git diff --stat` + `git diff --stat --cached`
216
219
  - [ ] 构建 commit message:`wip(<scope>): <change-name> 编码完成 — N任务/M文件变更`
217
220
  - [ ] **⚠️ 强制阻断**:用 AskUserQuestion 展示变更列表 + commit message,等待用户确认
218
- - [ ] 用户确认 → 执行 `git add -A` + `git commit`(不用 --no-verify、--no-gpg-sign)
221
+ - [ ] 用户确认 → 精确暂存业务文件;若存在 test-tracking manifest,先执行 `harness_test_guard.py stage --project . --change-dir ".harness/changes/<change-name>" --json`;禁止 `git add -A` 与目录级 force-add
222
+ - [ ] `git diff --cached --name-only` 包含 manifest 的全部精确测试路径后再 `git commit`(不用 --no-verify、--no-gpg-sign)
219
223
  - [ ] 用户拒绝 → 记录 `❌用户拒绝`,继续后续流程
220
224
  - [ ] 记录 checkpoint commit hash 到执行日志
221
225
 
@@ -250,7 +254,7 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
250
254
  - [ ] 包含 currentHead/baseCommit/diffHash/module/profile
251
255
  - [ ] 包含 validations.compile 与 validations.unitTest
252
256
  - [ ] 缺字段时标记 `ledgerReusable=false`,后续阶段不得复用
253
- - [ ] diffHash 必须用三部分合并命令(inline 见 reference 步骤 2c;commit 前 `baseCommit..HEAD` 部分为空也**必须保留**),`currentHead`=`git rev-parse HEAD`;禁止仅用 `git diff` 未提交——省略第一部分会导致 commit 后 diffHash 变化、run→test 复用链断裂
257
+ - [ ] diffHash 必须由 `harness_ledger.py diff-hash --change-dir` 生成;manifest hash 漂移或路径越界时硬停止,禁止绕过后复用 ledger
254
258
 
255
259
  ## 新筛选参数非法值行为检查
256
260
 
@@ -518,19 +518,13 @@ powershell.exe -Command "<测试命令> <模块定位参数>"
518
518
  - 顶层写入 `diffHash` / `currentHead` / `baseCommit` / `module` / `profile`
519
519
  - `baseCommit`:merge-base 或计划起点(worktree 分支从主分支分出点,由 harness-plan 写入、run 读取复用;缺失时用 `git merge-base HEAD <默认分支>` 兜底)
520
520
  - `currentHead`:`git rev-parse HEAD`(步骤 2c 在 Step 5 checkpoint commit 之前执行,此时 HEAD==baseCommit;commit 后 HEAD 前移到 checkpoint commit,由 ledger-protocol reuse 规则 #2「currentHead 可前移」容忍,**不需为它改时序**)
521
- - `diffHash`:**必须用 ledger-protocol「五、真实 diffHash」的 commit-invariant 三部分合并命令**(与 harness-test 重算命令逐字一致),**禁止仅用 `git diff`(未提交)**。命令如下(经 `Bash(powershell.exe:*)` 通道时外层用单引号防 `$base` 展开,见 ledger-protocol L177):
521
+ - `diffHash`:必须由 ledger v2 commit-invariant 内容变更集算法生成,并通过 `--change-dir` 纳入 test-tracking manifest 中被 `.gitignore` 忽略的测试;禁止自行拼接 Git 输出或仅使用某一段 diff:
522
522
 
523
523
  ```powershell
524
- 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"
524
+ python <skills-root>/scripts/harness_ledger.py diff-hash --repo . --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json
525
525
  ```
526
526
 
527
- > ⚠️ **commit 前时序陷阱(真实教训)**:步骤 2c 在 Step 5 checkpoint commit **之前**执行,此时 `git diff $base HEAD` 部分为空(HEAD==baseCommit),只有"未提交 + 未跟踪"是全量。**即使第一部分为空也必须保留三部分合并**——commit 后第一部分被填充、未提交/未跟踪变空,两者内容相同 → diffHash 一致。若省略第一部分只用未提交 diff,commit 后未提交变空 diffHash 变化 run→test 复用链断裂(真实日志:run 产出非规范 `8a94c874` 即因此,test 重算 `b4c580fc` 不一致,被迫重跑全量单元测试 13.65s)
528
-
529
- > ⚠️ **禁止任何单部分简化(堵字面空子)**:上述教训只点了"仅用未提交 diff"。实际还有两种等价违规简化,均**禁止**:
530
- > - `git diff <base> HEAD --binary`(仅已提交部分):commit 后工作树 clean 时结果偶然与三部分合并一致,但 commit 前算会漏未提交+未跟踪,且方法本身违反"三部分合并"要求。
531
- > - `node -e "...crypto.createHash('sha256')..."` 自算:绕过 PowerShell 三部分合并命令,且无法捕获未跟踪文件内容。
532
- >
533
- > 无论 commit 前后、无论工作树是否 clean,**必须**用三部分合并命令。"commit 后 clean 致单部分偶然等价"不得作为省略三部分的依据——时序或工作树状态一旦变化即复现复用链断裂。
527
+ > `content-changeset-2` 同时读取 tracked diff、标准 untracked 文件和 manifest 的精确测试路径。manifest 缺失时保持普通行为;manifest 存在但路径越界、内容 hash 漂移或结构非法时命令失败,ledger 不可复用。checkpoint commit 不改变各路径的工作树内容,因此提交前后 hash 保持一致。
534
528
 
535
529
  > 这样 harness-test 的 Phase 1 可读取 ledger 判断是否复用 run 的 unitTest(diffHash commit-invariant + reuse 规则 #2 允许 HEAD 前移 → run 的 checkpoint commit 不破坏复用),submit 也可复用 compile 结果。详见 `../protocols/ledger-protocol.md`。
536
530
 
@@ -805,7 +799,7 @@ powershell.exe -Command "git -C '<project-path>' diff --check"
805
799
 
806
800
  ## 执行日志记录
807
801
 
808
- `/harness-run` 只向 `events.ndjson` 追加事件(schema_version 2);`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]] 与 SKILL.md `## 执行日志`。
802
+ `/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]] 与 SKILL.md `## 执行日志`。
809
803
 
810
804
  关键 `note` / `decision` 须覆盖:测试基础设施探测(CHECKING→结论)、预存变更、run-tdd-protocol RED 类型、变更簇 RED/GREEN、批量构建 exit code、关门检查 10 项、计划状态持久化路径。
811
805
 
@@ -3,7 +3,7 @@ name: harness-submit
3
3
  description: 最终提交封装:验证→中文 commit→提交/推送;worktree 模式含 --no-ff
4
4
  合并回主分支。使用场景:提交代码、commit、push、合并分支、merge to main、完成开发
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=ab1182505b44093f; overlay=none; agent=codex; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=7e031c982caba51d; overlay=none; agent=codex; do not edit -->
7
7
  # harness-submit — 最终提交(含 worktree 合并)
8
8
 
9
9
  ## Purpose
@@ -40,6 +40,7 @@ description: 最终提交封装:验证→中文 commit→提交/推送;workt
40
40
  6. **implementation-detail** — 自适应执行参考;legacy 缺失 🟡WARN,不阻断
41
41
  7. **test-scenarios** — 测试真相源:`plans/<change>-test-scenarios.md`
42
42
  8. **禁止读取 `docs/superpowers/` 作为正式输入** — 旧草稿仅人工线索
43
+ 9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/knowledge/change/code 指纹,不再重复跑全量 `harness-sync`、知识重建或代码库扫描。只有对应 segment 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
43
44
 
44
45
  状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
45
46
 
@@ -53,10 +54,10 @@ description: 最终提交封装:验证→中文 commit→提交/推送;workt
53
54
 
54
55
  ### 提交流程(步骤 0–7)
55
56
 
56
- 0. **启动准备** — 确定变更名;读 ledger + 计算 diffHash + post-test 7 类分类;append `phase.start`
57
+ 0. **启动准备** — 确定变更名;读 ledger,以 `harness_ledger.py diff-hash --repo . --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json` 计算 diffHash + post-test 7 类分类;append `phase.start`
57
58
  1. **合并最新代码** — 主目录:`stash` → `pull --rebase` → `stash pop`;**worktree:N/A**(远端同步在合并段主分支完成)
58
59
  2. **最终验证** — ledger 复用优先;**提交前最终门禁只调 `can-reuse`**(删除与 coverage 冲突的二次全量门禁):`harness_ledger.py can-reuse --verification unitTestFull --scope module --project . --profile-input unitTestFull --command <resolved commands.unitTestFull.command>`。`--command` **按 profile key resolve**:读 `build-profile.json` 的 `commands.unitTestFull.command`(v2),或 `harness_profile.py resolve --project . --key unitTestFull --json` 取 resolved command,**不复制示例模块名**(文档示例只展示 key)。`--profile-input unitTestFull` 从 `verificationInputs.unitTestFull`(v2 由 `commands.unitTestFull.inputs` 派生)展开依赖闭包,**禁止用仅含 staged 文件的 `--files` 快捷方式**冒充全量闭包。`reuse=true` → 不再执行二次全量测试;仅 `reuse=false` 时执行**同一 resolved verification**(profile `unitTestFull` 命令),成功后用同一文件集、command、`scope=module` 写回 ledger `unitTestFull` 项。增量 `unitTest` 永远不能冒充 `unitTestFull` 门禁。
59
- 3. **.gitignore + 暂存** ⚠️ — 检查 `.harness/` 在 `.gitignore`;**禁止 `git add -A`**
60
+ 3. **.gitignore + 精确暂存** ⚠️ — 检查 `.harness/` 在 `.gitignore`;**禁止 `git add -A`**。若存在 `evidence/test-tracking.json`,先执行 `python <skills-root>/scripts/harness_test_guard.py stage --project . --change-dir ".harness/changes/<change-name>" --json`;失败即硬停止。无 manifest 时不使用 `-f`。manifest 之外的文件按精确业务路径正常暂存,**禁止全局 force-add**。
60
61
  4. **提交方式** — 主目录:AskUserQuestion 三选项(commit+push / 仅本地 / 取消);**worktree:固定仅本地 commit**
61
62
  5. **commit-message.txt** ⚠️ — 展示 staged、diff stat、完整中文 message;用户确认
62
63
  6. **commit / push** — `git commit -F`;主目录按选项 push(push 前 fetch 检查远端);**worktree:只 commit,记录 local hash**
@@ -98,6 +99,8 @@ commit+push / 仅本地 commit / 取消;**不调用 Superpowers 呈现 PR/丢
98
99
 
99
100
  见 `checklist.md` 与 `../protocols/ledger-protocol.md`、`../protocols/submit-protocol.md`。
100
101
 
102
+ test-tracking manifest 是 ignored test 的唯一强制暂存授权:只允许 `harness_test_guard.py stage` 暂存 manifest 中已校验路径,禁止 `git add -f .`、目录级 `git add -f` 或全局修改 `.gitignore`。worktree commit 前须确认 manifest 路径全部进入 cached diff;合并回主分支后、删除 worktree 前须确认这些路径已由目标 commit 跟踪,否则停止清理。
103
+
101
104
  ### 四、worktree 合并硬规则
102
105
 
103
106
  - **push 只在主分支**;worktree 分支不 push
@@ -131,7 +134,7 @@ git 经 PowerShell;commit/报告不得含明文密钥。遵循 `../protocols/s
131
134
 
132
135
  ## 执行日志
133
136
 
134
- `events.ndjson` 为唯一事实源(schema_version 2,`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
137
+ `events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
135
138
 
136
139
  ```powershell
137
140
  python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
@@ -140,3 +143,5 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
140
143
  > **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
141
144
 
142
145
  > **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
146
+
147
+ 每次阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`;重试同一阶段时增加 `--attempt <n>`,不得覆盖或伪装成一次执行。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
@@ -25,7 +25,7 @@ description: harness-submit 的8 步工作流详细步骤和执行日志记录
25
25
  **读取 verification-ledger + post-test 变更分类**:
26
26
 
27
27
  1. 读取 `.harness/changes/<change-name>/evidence/verification-ledger.json`,记录 `diffHash` / `currentHead` / `unitTest` / `apiTest` 状态
28
- 2. 计算当前 diff diffHash,与 ledger 比对
28
+ 2. 执行 `harness_ledger.py diff-hash --repo . --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json` 计算当前 diffHash;manifest 校验失败即停止,不得绕过后与 ledger 比对
29
29
  3. 若 test 之后有代码变更(当前 diffHash ≠ test 完成时的 diffHash),按 7 类对 post-test diff 分类(见 `../protocols/ledger-protocol.md` 第六章),写入 ledger 的 `postTestClassification`
30
30
  4. 行为性变更(BEHAVIORAL_SERVICE_CHANGE / API_CONTRACT_CHANGE / SQL_OR_MAPPER_CHANGE / SECURITY_OR_PERMISSION_CHANGE)→ **停止 submit**,提示先重跑 `/harness-test` 相关场景
31
31
  5. 非行为性变更(NON_BEHAVIORAL_CLEANUP / COMMENT_ONLY / TEST_ONLY)→ 可继续 submit,但后续验证按复用规则处理
@@ -116,6 +116,13 @@ python <skills-root>/scripts/harness_ledger.py can-reuse `
116
116
 
117
117
  ## 步骤 3:.gitignore 检查 + 暂存业务文件 ⚠️ 强制阻断
118
118
 
119
+ ### Ignored test 精确暂存
120
+
121
+ - [ ] 检查 `.harness/changes/<change-name>/evidence/test-tracking.json` 是否存在
122
+ - [ ] 存在时先执行 `python <skills-root>/scripts/harness_test_guard.py stage --project . --change-dir ".harness/changes/<change-name>" --json`;任一 manifest/path/hash/index 校验失败立即停止
123
+ - [ ] 用 `git diff --cached --name-only` 验证 manifest 中每个精确路径均已暂存,且没有 guard 引入的额外路径
124
+ - [ ] 无 manifest 时禁止使用 `git add -f`;有 manifest 时也只允许 guard 内部的 exact force-add,**禁止全局 force-add**、目录级 force-add 和全局修改 `.gitignore`
125
+
119
126
  提交前**强制检查 `.gitignore`** 是否包含 `.harness/`:
120
127
 
121
128
  ```powershell
@@ -406,6 +413,8 @@ powershell.exe -Command "git -C '<项目路径>' push"
406
413
 
407
414
  ### 步骤 M7:清理 worktree
408
415
 
416
+ 若存在 test-tracking manifest,删除 worktree 前必须逐一确认 manifest 路径已包含在 worktree commit 中,且合并后的主分支可用 `git ls-files --error-unmatch -- <exact-path>` 找到;任一路径缺失即停止清理并报告,防止 ignored test 随 worktree 被永久删除。
417
+
409
418
  ```powershell
410
419
  powershell.exe -Command "git -C '<项目路径>' worktree remove '<worktree-path>' --force"
411
420
  powershell.exe -Command "git -C '<项目路径>' branch -D worktree/<change-name>"
@@ -2,7 +2,7 @@
2
2
  name: harness-sync
3
3
  description: 检查并更新项目AI元数据(CodeGraph索引、harness-codebase-map分析、CLAUDE.md、AGENTS.md、.harness/完整性),确保Claude对代码库的理解与最新代码一致。当用户说'同步/更新索引/刷新元数据/检查一致性'时使用
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=ab1182505b44093f; overlay=none; agent=codex; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=7e031c982caba51d; overlay=none; agent=codex; do not edit -->
6
6
  # harness-sync — 元数据同步
7
7
 
8
8
  ## Purpose
@@ -22,7 +22,7 @@ description: 检查并更新项目AI元数据(CodeGraph索引、harness-codeba
22
22
  | 2 | CodeGraph 索引是否需重建 |
23
23
  | 3 | `.harness/codebase/map/` 是否过期 → 报告建议 `/harness-codebase-map` |
24
24
  | 3.5 | `harness_knowledge.py sync`;可 `sync --update`;失败不得假装可用。**知识闭环主入口**是 `/harness-knowledge-ingest auto`(含 Agent judge),sync 不重复列人工知识待办 |
25
- | 3.6 | 扫描 `.harness/knowledge/maintenance-outbox/{pending,failed}`;对每项运行 `harness_knowledge.py maintain --project . --archive-id <id> --json`(§8.2:archive close 只 enqueue,sync 异步推进 outbox 到 completed/completed_rules_pending_judge) |
25
+ | 3.6 | 单次运行 `harness_knowledge.py maintain --project . --drain --json`,有界推进全部 `.harness/knowledge/maintenance-outbox/{pending,failed}`;不得为每个条目重复启动 Python/重建索引(§8.2:archive close 只 enqueue,sync 异步推进 outbox 到 completed/pending-judge) |
26
26
  | 4 | CLAUDE.md 完整性/行数 → 超限 AskUserQuestion 瘦身 |
27
27
  | 5 | AGENTS.md 与 CLAUDE.md 一致 |
28
28
  | 6 | `.harness/` 结构(init 规程 → `reference.md` 第 6 步);可选 `harness_deploy.py diff` 检查已装 skill 是否过期 |
@@ -54,7 +54,7 @@ description: 检查并更新项目AI元数据(CodeGraph索引、harness-codeba
54
54
 
55
55
  ## 执行日志
56
56
 
57
- `events.ndjson` 为唯一事实源(schema_version 2,`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
57
+ `events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
58
58
 
59
59
  ```powershell
60
60
  python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
@@ -63,3 +63,5 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
63
63
  > **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
64
64
 
65
65
  > **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
66
+
67
+ 每次阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`;重试同一阶段时增加 `--attempt <n>`,不得覆盖或伪装成一次执行。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
@@ -2,7 +2,7 @@
2
2
  name: harness-test
3
3
  description: 测试执行:读取场景表,执行单元测试+API接口测试+数据兼容验证,输出测试报告。当用户说'跑测试/验证/跑用例/接口测试/单元测试'时使用
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=ab1182505b44093f; overlay=none; agent=codex; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=7e031c982caba51d; overlay=none; agent=codex; do not edit -->
6
6
  # harness-test — 测试执行
7
7
 
8
8
  ## Purpose
@@ -36,6 +36,7 @@ description: 测试执行:读取场景表,执行单元测试+API接口测试
36
36
  6. **implementation-detail** — 自适应执行参考;legacy 缺失 🟡WARN,不阻断
37
37
  7. **test-scenarios** — 测试真相源:`plans/<change>-test-scenarios.md`
38
38
  8. **禁止读取 `docs/superpowers/` 作为正式输入** — 旧草稿仅人工线索
39
+ 9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/knowledge/change/code 指纹,不再重复跑全量 `harness-sync`、知识重建或代码库扫描。只有对应 segment 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
39
40
 
40
41
  状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
41
42
 
@@ -99,12 +100,24 @@ description: 测试执行:读取场景表,执行单元测试+API接口测试
99
100
 
100
101
  ### 四、单元测试复用 + 写入 ledger
101
102
 
102
- Phase 1 前先读 `.harness/changes/<change-name>/evidence/verification-ledger.json`:run 的 unitTest 满足(diffHash 一致 + module/profile 一致 + scope 一致或更严格 + run 后无行为性修改 + run 跑了全量测试)则复用,否则按 **profile key resolve** 执行测试命令(`python <skills-root>/scripts/harness_profile.py resolve --project . --key unitTest|unitTestFull --json`,**不复制示例 `-pl` 命令**)。Phase 1/2 完成后必须写回 ledger:执行增量测试类 → 记 `unitTest`(scope=incremental);执行 profile 模块全量命令 → 记 `unitTestFull`(scope=module,可供 submit 复用);接口测试 → 记 `apiTest`。详见 `checklist.md`「单元测试复用」、`../protocols/ledger-protocol.md`。
103
+ Phase 1 前先读 `.harness/changes/<change-name>/evidence/verification-ledger.json`,并用 `harness_ledger.py diff-hash --repo . --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json` 重算真实指纹:run 的 unitTest 满足(diffHash 一致 + module/profile 一致 + scope 一致或更严格 + run 后无行为性修改 + run 跑了全量测试)则复用,否则按 **profile key resolve** 执行测试命令(`python <skills-root>/scripts/harness_profile.py resolve --project . --key unitTest|unitTestFull --json`,**不复制示例 `-pl` 命令**)。Phase 1/2 完成后必须写回 ledger:执行增量测试类 → 记 `unitTest`(scope=incremental);执行 profile 模块全量命令 → 记 `unitTestFull`(scope=module,可供 submit 复用);接口测试 → 记 `apiTest`。详见 `checklist.md`「单元测试复用」、`../protocols/ledger-protocol.md`。
103
104
 
104
105
  ### 五、命令与请求超时治理
105
106
 
106
107
  所有命令必须有「预期时长 + 超时上限」,超过预期必须输出一次状态行,**不得静默等待**。`durationMs > 10000` → 🟡 SLOW,`> 30000` → ❌ TIMEOUT_RISK。详见 `reference.md`「命令与请求超时治理」。
107
108
 
109
+ ### 五-A、陈旧测试安全修复
110
+
111
+ 若测试编译或执行明确指向已移除/改名 API 的陈旧测试,且当前生产代码、已批准计划或可验证历史能唯一确定新契约,可仅修改测试并立即重跑该测试与目标测试,然后记录:
112
+
113
+ ```text
114
+ python <skills-root>/scripts/harness_test_guard.py record --project . --change-dir ".harness/changes/<change-name>" --files "<精确测试文件路径,逗号分隔>" --reason stale-test-repair --json
115
+ ```
116
+
117
+ 普通新增/更新测试使用 `tdd-created` / `test-updated`。存在业务歧义或修复会触及生产代码时,记录 `BLOCKED_PREEXISTING` 并停止复用该验证,不得猜测或绕过。
118
+
119
+ **禁止临时排除测试**:禁止 `.bak`/改名、移出测试目录、删除、禁用注解、构建 exclude、`skipTests`/`maven.test.skip` 充当测试通过证据;服务启动可在单元测试已独立通过后使用 `-Dmaven.test.skip=true` 避免重复编译测试,但不得据此声明测试通过。所有本轮新增、更新或安全修复且被忽略的测试必须写入 test-tracking manifest;仅执行、未修改的只读 ignored test 不获得 force-track 授权。
120
+
108
121
  ### 六、服务启动 + 生命周期管理
109
122
 
110
123
  启动等待状态机:0–30s 每 2s 探测、30–120s 每 5s 探测、>120s 读日志判定;遇启动失败特征立即停。**Service Gate**:`harness_service.py ensure` 返回 `action=needs-user-decision`(用户自启服务占端口)时 **才** AskUserQuestion;AI 托管服务或端口空闲则自动继续,不询问。服务指纹(`moduleInputsHash`,来自 CLI `--files` ∪ `serviceStart.inputFiles`)+ `startCommandHash` + `profile` + `overlayPath` + 进程身份任一变化即 restart;**空输入被拒绝**,不生成可复用空指纹。测试结束默认清理 AI 启动的服务。详见 `reference.md`「服务决策门」。
@@ -149,7 +162,7 @@ Phase 1 前先读 `.harness/changes/<change-name>/evidence/verification-ledger.j
149
162
 
150
163
  ## 执行日志
151
164
 
152
- `events.ndjson` 为唯一事实源(schema_version 2,`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
165
+ `events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
153
166
 
154
167
  ```powershell
155
168
  python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
@@ -158,3 +171,5 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
158
171
  > **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
159
172
 
160
173
  > **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
174
+
175
+ 每次阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`;重试同一阶段时增加 `--attempt <n>`,不得覆盖或伪装成一次执行。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
@@ -252,6 +252,10 @@ powershell.exe -NoProfile -Command "try { (Invoke-WebRequest -Uri 'http://127.0.
252
252
  - [ ] 判断是否复用 run 的 unitTest:diffHash 一致 + module/profile 一致 + scope 一致或更严格 + run 后无行为性修改 + run 实际跑了全量测试
253
253
  - [ ] 复用 → 跳过重跑,标记"✅ 复用 harness-run 单元测试结果"
254
254
  - [ ] 不复用 → 按 profile key resolve 重跑测试命令(`harness_profile.py resolve --key unitTest`,不复制示例 `-pl` 命令),结果写回 ledger 的 `unitTest` 项
255
+ - [ ] 复用判断前以 `harness_ledger.py diff-hash --repo . --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json` 重算指纹;test-tracking manifest 无效或 hash 漂移即停止
256
+ - [ ] 测试失败若明确为陈旧测试,仅在当前代码/批准计划/可验证历史唯一确定新契约且只改测试时自动修复;否则记录 `BLOCKED_PREEXISTING`
257
+ - [ ] 自动修复后立即重跑该测试与目标测试,并以 `harness_test_guard.py record ... --reason stale-test-repair` 记录精确路径
258
+ - [ ] **禁止临时排除测试**:未使用 `.bak`/改名/移目录/删除/禁用注解/build exclude/skip-tests 制造通过;服务启动的 `maven.test.skip` 不作为测试证据
255
259
 
256
260
  ### 批量执行器(强制单次 PowerShell + 执行器绝对路径执行)
257
261
 
@@ -767,10 +767,10 @@ TEST_<change-name>_<timestamp>_<short-random>
767
767
 
768
768
  > diffHash 与 ledger 复用规则遵循 `../protocols/ledger-protocol.md`。
769
769
 
770
- 后续复用 ledger 前必须生成真实 SHA-256 diffHash,且**必须 commit-invariant**(含 `git diff baseCommit..HEAD` 已提交部分)。否则 run 的 Step 5 checkpoint commit 后工作树干净、`git diff` 为空,harness-test 会误判"diffHash 变化"而重跑 run 已跑过的全量测试,复用链断裂。`<baseCommit>` 从 ledger 读取(plan 阶段写入),缺失时用 `git merge-base HEAD <默认分支>`:
770
+ 后续复用 ledger 前必须生成真实 SHA-256 diffHash,且必须同时覆盖 tracked/untracked 变化和 test-tracking manifest 中被忽略的测试。`<baseCommit>` 从 ledger 读取(plan 阶段写入),缺失时用 `git merge-base HEAD <默认分支>`:
771
771
 
772
772
  ```powershell
773
- 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"
773
+ python <skills-root>/scripts/harness_ledger.py diff-hash --repo . --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json
774
774
  ```
775
775
 
776
776
  写入 `.harness/changes/<change>/evidence/verification-ledger.json`:
@@ -778,14 +778,14 @@ powershell.exe -NoProfile -Command "$base = '<baseCommit>'; $patch = '.harness/c
778
778
  ```json
779
779
  {
780
780
  "diffHash": "sha256:<real_hash>",
781
- "diffPatchFile": ".harness/changes/<change>/runtime/current-diff.patch"
781
+ "algorithmVersion": "content-changeset-2"
782
782
  }
783
783
  ```
784
784
 
785
- 禁止使用 `3files-84plus-5minus` 这类描述性 diffHash 作为复用依据。**禁止仅用 `git diff`(未提交)计算 diffHash**——commit 后工作树干净致指纹变空,断裂 run→test 复用链。**同样禁止** `git diff <base> HEAD` 已提交单部分或 `node -e` 自算 SHA-256——commit 后 clean 致单部分偶然等价不得作为依据,无论时序必须三部分合并。
785
+ 禁止使用描述性字符串、单段 `git diff` 或自写 hash 替代脚本。manifest 无效、路径越界或 hash 漂移时必须停止,不得删除 manifest 后继续复用旧 ledger。
786
786
 
787
787
  ## 执行日志记录
788
788
 
789
- `/harness-test` 只向 `events.ndjson` 追加事件(schema_version 2);`logs/execution-log.md` 由 `harness_events.py append` 自动渲染。Phase 0 之前 append `phase.start`;各阶段写入 `command` / `verification` / `decision` / `issue` / `artifact`,人类可读摘要放 `note`。事件类型与脚本用法见 [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]] 与 SKILL.md `## 执行日志`。
789
+ `/harness-test` 只向 `events.ndjson` 追加事件(schema_version 3,兼容读取 v1/v2);`logs/execution-log.md` 由 `harness_events.py append` 自动渲染。Phase 0 之前 append `phase.start`;各阶段写入 `command` / `verification` / `decision` / `issue` / `artifact`,人类可读摘要放 `note`。事件类型与脚本用法见 [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]] 与 SKILL.md `## 执行日志`。
790
790
 
791
791
  关键 `note` / 事件须覆盖:0.1 命令执行模式、fallback 执行器、serviceState、凭证策略、单元测试复用、批量执行器、verification-ledger 写入、关门检查、API 状态(不得把 PARTIAL 写成 NOT_RUN)。
@@ -168,8 +168,6 @@ CONDITIONAL_OK
168
168
 
169
169
  ## 未提交测试证据
170
170
 
171
- 如果 run/test 使用了被 `.gitignore` 忽略或未提交的测试文件作为验证证据,必须:
171
+ run/test 本轮新增、更新或安全修复且被 `.gitignore` 忽略的测试,必须先由 `test-tracking.json` + `harness_test_guard.py stage` 精确提交;这类测试不得继续作为“未提交证据”收尾,也不得计入可复用 P0 验证后随 worktree 删除。
172
172
 
173
- 1. 归档到 `backups/uncommitted-tests/`;
174
- 2. 在 `summary-data.json.uncommittedTestEvidence[]` 中记录文件名、验证了什么、是否随 commit 提交;
175
- 3. final-summary 明确展示(`uncommittedTestEvidence` 非空时渲染"🧪 未提交测试证据"卡片),避免维护者误以为仓库包含该回归测试;无此类证据时不渲染该卡。
173
+ `uncommittedTestEvidence` 只兼容历史归档或明确只读的外部证据:归档到 `backups/uncommitted-tests/`,记录文件名、验证范围与未提交原因,并在 final-summary 展示风险。若它是本轮可修改的回归测试,则 archive 必须阻断并要求先走精确跟踪流程。
@@ -86,7 +86,7 @@ verification-ledger 把每次验证(compile / unit test / api test / package
86
86
  },
87
87
  "package": {
88
88
  "status": "OK",
89
- "command": "<打包命令(按技术栈:Java=mvn package -pl <module> -am -DskipTests;前端=npm run build;Python=python -m build)>",
89
+ "command": "<打包命令(按技术栈:Java=mvn clean package -pl <module> -am -DskipTests;前端=npm run build;Python=python -m build)>",
90
90
  "baseCommit": "<final pushed hash>",
91
91
  "deployArtifact": "<构建产物路径(Java=<module>/target/<artifact>.jar;前端=<module>/dist/;Python=<module>/dist/)>",
92
92
  "sha256": "<artifact sha256>",
@@ -199,33 +199,25 @@ profile key 缺失 / glob 无匹配 / 结果为空 → `insufficient-evidence`
199
199
 
200
200
  ## 五、真实 diffHash
201
201
 
202
- 必须基于真实 diff 计算 SHA-256,且**必须是 commit-invariant 的**——覆盖本变更集相对 `baseCommit` 的全部内容变更(已提交 + 未提交 + 未跟踪),使 checkpoint commit 前后指纹一致,保证 run→test 复用链不断。
202
+ 必须基于真实内容变更集计算 SHA-256,且**必须是 commit-invariant 的**——覆盖本变更集相对 `baseCommit` tracked 变化、标准 untracked 文件,以及 `test-tracking.json` 明确记录的 ignored tests,使 checkpoint commit 前后指纹一致,保证 run→test→submit 复用链不断。
203
203
 
204
204
  `<baseCommit>` 从 ledger 读取(harness-plan 阶段写入);缺失时用 `git merge-base HEAD <默认分支>` 兜底。
205
205
 
206
206
  **canonical 命令(cluster 2 起脚本化,推荐)**:
207
207
 
208
208
  ```text
209
- harness_ledger.py diff-hash --repo <projectRoot> --base <baseCommit> --json
209
+ harness_ledger.py diff-hash --repo <projectRoot> --base <baseCommit> --change-dir ".harness/changes/<change-name>" --json
210
210
  ```
211
211
 
212
- `diff-hash` 用 subprocess 直接捕获 Git bytes,基于**内容变更集**计算 SHA-256:working tree 相对 base 的所有变化文件 + 未跟踪文件,按 repo-relative path 排序、长度 framing(`path-len | path | exists | content-len | content`),独立于 shell/控制台编码/BOM/系统换行,且 **commit-invariant**(checkpoint commit 不改 working tree → 指纹不变,UT-011)。算法版本 `content-changeset-1`,输出 `diffHash`/`algorithmVersion`/`fileCount`/`base`/`head`。
212
+ `diff-hash` 用 subprocess 直接捕获 Git bytes,按 repo-relative path 排序并进行长度 framing(`path-len | path | exists | content-len | content`),独立于 shell/控制台编码/BOM/系统换行。算法版本 `content-changeset-2`,输出 `diffHash`/`algorithmVersion`/`fileCount`/`base`/`head`/`trackedTestFileCount`/`testTrackingManifest`。
213
213
 
214
- > v1 PowerShell 拼接命令(下方)已废弃:依赖文本编码,且未跟踪文件提交后表示从 framed-content 切换为 diff-format 会破坏 commit-invariance。仅作历史参考。
215
-
216
- ```powershell
217
- 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"
218
- ```
219
-
220
- - 命令为模板:`<baseCommit>`/`<change>` 需替换;经 `powershell.exe -Command "..."` 从 PowerShell/Bash 调用时外层会展开 `$` 变量,建议直接用 PowerShell 工具执行去外壳脚本,或外层用单引号/`--%` 防展开
221
- - 三部分合并:`git diff $base HEAD`(已提交变更)+ `git diff`(未提交 tracked)+ 未跟踪新文件内容(`git ls-files --others --exclude-standard`);`& { }` 必须带 `&` 才执行 scriptblock(bare `{ } | Out-File` 只写脚本块字符串,不执行)
222
- - commit 前:`$base..HEAD` 为空 + 未提交 24 文件 + 未跟踪 9 文件 = 全量;commit 后:`$base..HEAD` 24 文件 + 未提交空 + 未跟踪空 = 同内容 → 指纹一致 ✅
214
+ - `--change-dir` 可选以兼容普通调用;run/test/submit 对正式 change 必须传入。manifest 不存在时贡献 0 个额外路径。
215
+ - manifest 存在时必须严格验证 schema/mode/projectRoot、精确相对路径、文件存在性与 SHA-256;结构非法、路径越界或 hash 漂移均非零退出,旧 ledger 不得复用。
216
+ - ignored test 在 checkpoint 前由 manifest 加入内容集;经 guard force-stage/commit 后由 Git diff 加入同一路径,集合去重,因此 hash 保持不变。
223
217
  - diffHash 只用于"内容是否变化"判断,不等于 commit hash
224
218
  - 账本中 `currentHead`(验证时 HEAD)与 `diffHash` 分开记录;reuse 规则 #2 允许 HEAD 前移(如 harness-run Step 5 checkpoint commit),因 diffHash 已 commit-invariant,HEAD 前移不改变指纹
225
219
  - **禁止**使用类似 `3files-84plus-5minus` 的描述性字符串作为复用依据
226
- - **禁止**仅用 `git diff`(未提交)计算 diffHash——checkpoint commit 后工作树干净会致指纹变空,断裂 run→test 复用链
227
- - **禁止**任何单部分简化:含 `git diff <base> HEAD`(仅已提交部分)、`git diff`(仅未提交)、`node -e`/`crypto.createHash` 自算 SHA-256。无论 commit 前后、无论工作树是否 clean,必须用上述三部分合并命令。commit 后 clean 致单部分偶然等价不得作为省略依据——时序或工作树状态变化即复现复用链断裂
228
- - **commit 前时序说明**:harness-run 步骤 2c 在 Step 5 checkpoint commit **之前**写 ledger,此时 `git diff baseCommit..HEAD` 部分为空(HEAD==baseCommit),只有"未提交 + 未跟踪"是全量。**即使第一部分为空也必须保留三部分合并命令**——commit 后第一部分被填充、未提交/未跟踪变空,两者内容相同 → diffHash 一致。省略第一部分只用未提交 diff,commit 后未提交变空 → diffHash 变化 → 复用链断裂(真实教训:run 产出非规范 `8a94c874`,test 重算 `b4c580fc` 不一致被迫重跑全量单元测试)。harness-run 步骤 2c 已 inline 完整三部分命令,执行者直接跑 verbatim,不得自行省略
220
+ - **禁止**删除/忽略 test-tracking manifest 后继续复用,也禁止用手写 Git/Node/PowerShell hash 替代 canonical 命令。
229
221
 
230
222
  ## 六、Post-test 变更分类
231
223
 
@@ -43,11 +43,11 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
43
43
 
44
44
  `append` 写入契约(Task 4 §6.1):普通 append = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex`);仅 `--type phase.end` append 成功后渲染一次 `logs/execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。人类可读摘要(触发指令、降级原因、阶段结论)写入事件的 `note` 字段;阶段开始/结束、命令、验证、artifact、问题、决策各写对应 `type` 事件。旧 archive 缺少 events 可回放兼容;新变更不得以 execution-log 已存在为理由跳过 events。
45
45
 
46
- 基础事件结构(schema_version 2):
46
+ 基础事件结构(schema_version 3;兼容读取 v1/v2):
47
47
 
48
48
  ```json
49
49
  {
50
- "schema_version": 2,
50
+ "schema_version": 3,
51
51
  "id": "evt-...",
52
52
  "timestamp": "2026-07-02T00:00:00.000Z",
53
53
  "phase": "run",
@@ -55,6 +55,13 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
55
55
  "command": "npm test",
56
56
  "exit_code": 0,
57
57
  "duration_ms": 42100,
58
+ "run_id": "run-...",
59
+ "attempt": 1,
60
+ "executor_tool": "codex",
61
+ "executor_agent": "main",
62
+ "executor_model": "gpt-5",
63
+ "handoff_from_tool": "claude-code",
64
+ "handoff_reason": "continue implementation",
58
65
  "note": "可选:触发指令、降级原因、阶段摘要"
59
66
  }
60
67
  ```
@@ -64,7 +71,7 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
64
71
  | type | 必填/常用字段 | 用途 |
65
72
  |---|---|---|
66
73
  | `phase.start` | phase, timestamp | 阶段开始 |
67
- | `phase.end` | phase, timestamp | 阶段结束,计算耗时 |
74
+ | `phase.end` | phase, timestamp, status | 阶段结束并记录 `OK/WARN/FAIL/BLOCKED`;计算当前 attempt 耗时 |
68
75
  | `command` | command, exit_code, duration_ms | 命令事实 |
69
76
  | `verification` | name, status, command | 验证事实 |
70
77
  | `artifact` | path, kind | 报告、包、manifest 等产物 |
@@ -79,7 +86,7 @@ summary-data 必须保留原 archive final report 维度,并增加事件层摘
79
86
  {
80
87
  "schemaVersion": "2.2",
81
88
  "reportPipeline": {
82
- "schema_version": 2,
89
+ "schema_version": 1,
83
90
  "generated_at": "2026-07-02T00:00:00.000Z",
84
91
  "event_count": 0,
85
92
  "sources": ["events.ndjson", "evidence/verification-ledger.json"],