@hunter-harness/workflow-harness 0.2.8 → 0.2.10

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 (334) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/contracts/workflow-policy.json +3 -3
  3. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +3 -3
  4. package/harness/bundles/general/claude-code/harness-archive/reference.md +30 -12
  5. package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +5 -1
  6. package/harness/bundles/general/claude-code/harness-archive/templates/summary-data-template.json +6 -2
  7. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
  8. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +3 -1
  9. package/harness/bundles/general/claude-code/harness-knowledge-ingest/reference.md +7 -0
  10. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  11. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  12. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
  13. package/harness/bundles/general/claude-code/harness-plan/checklist.md +6 -0
  14. package/harness/bundles/general/claude-code/harness-review/SKILL.md +3 -3
  15. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  16. package/harness/bundles/general/claude-code/harness-run/checklist.md +5 -0
  17. package/harness/bundles/general/claude-code/harness-run/reference.md +33 -1
  18. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +15 -10
  19. package/harness/bundles/general/claude-code/harness-submit/checklist.md +40 -76
  20. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +17 -2
  21. package/harness/bundles/general/claude-code/harness-sync/reference.md +2 -2
  22. package/harness/bundles/general/claude-code/harness-test/SKILL.md +1 -1
  23. package/harness/bundles/general/claude-code/harness-test/checklist.md +9 -0
  24. package/harness/bundles/general/claude-code/harness-test/pitfalls-java.md +14 -0
  25. package/harness/bundles/general/claude-code/harness-test/reference.md +38 -0
  26. package/harness/bundles/general/claude-code/protocols/archive-report-protocol.md +26 -4
  27. package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +38 -0
  28. package/harness/bundles/general/claude-code/protocols/powershell-protocol.md +16 -0
  29. package/harness/bundles/general/claude-code/protocols/report-pipeline-protocol.md +17 -0
  30. package/harness/bundles/general/claude-code/protocols/state-layout-protocol.md +15 -0
  31. package/harness/bundles/general/claude-code/scripts/harness_archive.py +1209 -170
  32. package/harness/bundles/general/claude-code/scripts/harness_change.py +18 -0
  33. package/harness/bundles/general/claude-code/scripts/harness_deploy.py +1 -44
  34. package/harness/bundles/general/claude-code/scripts/harness_events.py +174 -25
  35. package/harness/bundles/general/claude-code/scripts/harness_gate.py +203 -29
  36. package/harness/bundles/general/claude-code/scripts/harness_integration.py +878 -0
  37. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +457 -10
  38. package/harness/bundles/general/claude-code/scripts/harness_paths.py +315 -0
  39. package/harness/bundles/general/claude-code/scripts/harness_profile.py +45 -0
  40. package/harness/bundles/general/claude-code/scripts/harness_review.py +326 -0
  41. package/harness/bundles/general/claude-code/scripts/harness_sync.py +407 -0
  42. package/harness/bundles/general/claude-code/scripts/harness_test_guard.py +244 -49
  43. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  44. package/harness/bundles/general/codebuddy/contracts/workflow-policy.json +3 -3
  45. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +3 -3
  46. package/harness/bundles/general/codebuddy/harness-archive/reference.md +30 -12
  47. package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +5 -1
  48. package/harness/bundles/general/codebuddy/harness-archive/templates/summary-data-template.json +6 -2
  49. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
  50. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +3 -1
  51. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/reference.md +7 -0
  52. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  53. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  54. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
  55. package/harness/bundles/general/codebuddy/harness-plan/checklist.md +6 -0
  56. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +3 -3
  57. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  58. package/harness/bundles/general/codebuddy/harness-run/checklist.md +5 -0
  59. package/harness/bundles/general/codebuddy/harness-run/reference.md +33 -1
  60. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +15 -10
  61. package/harness/bundles/general/codebuddy/harness-submit/checklist.md +40 -76
  62. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +17 -2
  63. package/harness/bundles/general/codebuddy/harness-sync/reference.md +2 -2
  64. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +1 -1
  65. package/harness/bundles/general/codebuddy/harness-test/checklist.md +9 -0
  66. package/harness/bundles/general/codebuddy/harness-test/pitfalls-java.md +14 -0
  67. package/harness/bundles/general/codebuddy/harness-test/reference.md +38 -0
  68. package/harness/bundles/general/codebuddy/protocols/archive-report-protocol.md +26 -4
  69. package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +38 -0
  70. package/harness/bundles/general/codebuddy/protocols/powershell-protocol.md +16 -0
  71. package/harness/bundles/general/codebuddy/protocols/report-pipeline-protocol.md +17 -0
  72. package/harness/bundles/general/codebuddy/protocols/state-layout-protocol.md +15 -0
  73. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +1209 -170
  74. package/harness/bundles/general/codebuddy/scripts/harness_change.py +18 -0
  75. package/harness/bundles/general/codebuddy/scripts/harness_deploy.py +1 -44
  76. package/harness/bundles/general/codebuddy/scripts/harness_events.py +174 -25
  77. package/harness/bundles/general/codebuddy/scripts/harness_gate.py +203 -29
  78. package/harness/bundles/general/codebuddy/scripts/harness_integration.py +878 -0
  79. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +457 -10
  80. package/harness/bundles/general/codebuddy/scripts/harness_paths.py +315 -0
  81. package/harness/bundles/general/codebuddy/scripts/harness_profile.py +45 -0
  82. package/harness/bundles/general/codebuddy/scripts/harness_review.py +326 -0
  83. package/harness/bundles/general/codebuddy/scripts/harness_sync.py +407 -0
  84. package/harness/bundles/general/codebuddy/scripts/harness_test_guard.py +244 -49
  85. package/harness/bundles/general/codex/.harness-build.json +1 -1
  86. package/harness/bundles/general/codex/contracts/workflow-policy.json +3 -3
  87. package/harness/bundles/general/codex/harness-archive/SKILL.md +3 -3
  88. package/harness/bundles/general/codex/harness-archive/reference.md +30 -12
  89. package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +5 -1
  90. package/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +6 -2
  91. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
  92. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +3 -1
  93. package/harness/bundles/general/codex/harness-knowledge-ingest/reference.md +7 -0
  94. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  95. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  96. package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
  97. package/harness/bundles/general/codex/harness-plan/checklist.md +6 -0
  98. package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
  99. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  100. package/harness/bundles/general/codex/harness-run/checklist.md +5 -0
  101. package/harness/bundles/general/codex/harness-run/reference.md +33 -1
  102. package/harness/bundles/general/codex/harness-submit/SKILL.md +15 -10
  103. package/harness/bundles/general/codex/harness-submit/checklist.md +40 -76
  104. package/harness/bundles/general/codex/harness-sync/SKILL.md +17 -2
  105. package/harness/bundles/general/codex/harness-sync/reference.md +2 -2
  106. package/harness/bundles/general/codex/harness-test/SKILL.md +1 -1
  107. package/harness/bundles/general/codex/harness-test/checklist.md +9 -0
  108. package/harness/bundles/general/codex/harness-test/pitfalls-java.md +14 -0
  109. package/harness/bundles/general/codex/harness-test/reference.md +38 -0
  110. package/harness/bundles/general/codex/protocols/archive-report-protocol.md +26 -4
  111. package/harness/bundles/general/codex/protocols/ledger-protocol.md +38 -0
  112. package/harness/bundles/general/codex/protocols/powershell-protocol.md +16 -0
  113. package/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +17 -0
  114. package/harness/bundles/general/codex/protocols/state-layout-protocol.md +15 -0
  115. package/harness/bundles/general/codex/scripts/harness_archive.py +1209 -170
  116. package/harness/bundles/general/codex/scripts/harness_change.py +18 -0
  117. package/harness/bundles/general/codex/scripts/harness_deploy.py +1 -44
  118. package/harness/bundles/general/codex/scripts/harness_events.py +174 -25
  119. package/harness/bundles/general/codex/scripts/harness_gate.py +203 -29
  120. package/harness/bundles/general/codex/scripts/harness_integration.py +878 -0
  121. package/harness/bundles/general/codex/scripts/harness_ledger.py +457 -10
  122. package/harness/bundles/general/codex/scripts/harness_paths.py +315 -0
  123. package/harness/bundles/general/codex/scripts/harness_profile.py +45 -0
  124. package/harness/bundles/general/codex/scripts/harness_review.py +326 -0
  125. package/harness/bundles/general/codex/scripts/harness_sync.py +407 -0
  126. package/harness/bundles/general/codex/scripts/harness_test_guard.py +244 -49
  127. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  128. package/harness/bundles/general/cursor/contracts/workflow-policy.json +3 -3
  129. package/harness/bundles/general/cursor/harness-archive/SKILL.md +3 -3
  130. package/harness/bundles/general/cursor/harness-archive/reference.md +30 -12
  131. package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +5 -1
  132. package/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +6 -2
  133. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
  134. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +3 -1
  135. package/harness/bundles/general/cursor/harness-knowledge-ingest/reference.md +7 -0
  136. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  137. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  138. package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
  139. package/harness/bundles/general/cursor/harness-plan/checklist.md +6 -0
  140. package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
  141. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  142. package/harness/bundles/general/cursor/harness-run/checklist.md +5 -0
  143. package/harness/bundles/general/cursor/harness-run/reference.md +33 -1
  144. package/harness/bundles/general/cursor/harness-submit/SKILL.md +15 -10
  145. package/harness/bundles/general/cursor/harness-submit/checklist.md +40 -76
  146. package/harness/bundles/general/cursor/harness-sync/SKILL.md +17 -2
  147. package/harness/bundles/general/cursor/harness-sync/reference.md +2 -2
  148. package/harness/bundles/general/cursor/harness-test/SKILL.md +1 -1
  149. package/harness/bundles/general/cursor/harness-test/checklist.md +9 -0
  150. package/harness/bundles/general/cursor/harness-test/pitfalls-java.md +14 -0
  151. package/harness/bundles/general/cursor/harness-test/reference.md +38 -0
  152. package/harness/bundles/general/cursor/protocols/archive-report-protocol.md +26 -4
  153. package/harness/bundles/general/cursor/protocols/ledger-protocol.md +38 -0
  154. package/harness/bundles/general/cursor/protocols/powershell-protocol.md +16 -0
  155. package/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +17 -0
  156. package/harness/bundles/general/cursor/protocols/state-layout-protocol.md +15 -0
  157. package/harness/bundles/general/cursor/scripts/harness_archive.py +1209 -170
  158. package/harness/bundles/general/cursor/scripts/harness_change.py +18 -0
  159. package/harness/bundles/general/cursor/scripts/harness_deploy.py +1 -44
  160. package/harness/bundles/general/cursor/scripts/harness_events.py +174 -25
  161. package/harness/bundles/general/cursor/scripts/harness_gate.py +203 -29
  162. package/harness/bundles/general/cursor/scripts/harness_integration.py +878 -0
  163. package/harness/bundles/general/cursor/scripts/harness_ledger.py +457 -10
  164. package/harness/bundles/general/cursor/scripts/harness_paths.py +315 -0
  165. package/harness/bundles/general/cursor/scripts/harness_profile.py +45 -0
  166. package/harness/bundles/general/cursor/scripts/harness_review.py +326 -0
  167. package/harness/bundles/general/cursor/scripts/harness_sync.py +407 -0
  168. package/harness/bundles/general/cursor/scripts/harness_test_guard.py +244 -49
  169. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  170. package/harness/bundles/java/claude-code/contracts/workflow-policy.json +3 -3
  171. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  172. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +3 -3
  173. package/harness/bundles/java/claude-code/harness-archive/reference.md +30 -12
  174. package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +5 -1
  175. package/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +6 -2
  176. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
  177. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +3 -1
  178. package/harness/bundles/java/claude-code/harness-knowledge-ingest/reference.md +7 -0
  179. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  180. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  181. package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
  182. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
  183. package/harness/bundles/java/claude-code/harness-plan/checklist.md +6 -0
  184. package/harness/bundles/java/claude-code/harness-review/SKILL.md +3 -3
  185. package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
  186. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +15 -10
  187. package/harness/bundles/java/claude-code/harness-submit/checklist.md +40 -76
  188. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +17 -2
  189. package/harness/bundles/java/claude-code/harness-sync/reference.md +2 -2
  190. package/harness/bundles/java/claude-code/harness-test/SKILL.md +1 -1
  191. package/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +26 -4
  192. package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +38 -0
  193. package/harness/bundles/java/claude-code/protocols/powershell-protocol.md +16 -0
  194. package/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +17 -0
  195. package/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +15 -0
  196. package/harness/bundles/java/claude-code/scripts/harness_archive.py +1209 -170
  197. package/harness/bundles/java/claude-code/scripts/harness_change.py +18 -0
  198. package/harness/bundles/java/claude-code/scripts/harness_deploy.py +1 -44
  199. package/harness/bundles/java/claude-code/scripts/harness_events.py +174 -25
  200. package/harness/bundles/java/claude-code/scripts/harness_gate.py +203 -29
  201. package/harness/bundles/java/claude-code/scripts/harness_integration.py +878 -0
  202. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +457 -10
  203. package/harness/bundles/java/claude-code/scripts/harness_paths.py +315 -0
  204. package/harness/bundles/java/claude-code/scripts/harness_profile.py +45 -0
  205. package/harness/bundles/java/claude-code/scripts/harness_review.py +326 -0
  206. package/harness/bundles/java/claude-code/scripts/harness_sync.py +407 -0
  207. package/harness/bundles/java/claude-code/scripts/harness_test_guard.py +244 -49
  208. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  209. package/harness/bundles/java/codebuddy/contracts/workflow-policy.json +3 -3
  210. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  211. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +3 -3
  212. package/harness/bundles/java/codebuddy/harness-archive/reference.md +30 -12
  213. package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +5 -1
  214. package/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +6 -2
  215. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
  216. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +3 -1
  217. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/reference.md +7 -0
  218. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  219. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  220. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
  221. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
  222. package/harness/bundles/java/codebuddy/harness-plan/checklist.md +6 -0
  223. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +3 -3
  224. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
  225. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +15 -10
  226. package/harness/bundles/java/codebuddy/harness-submit/checklist.md +40 -76
  227. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +17 -2
  228. package/harness/bundles/java/codebuddy/harness-sync/reference.md +2 -2
  229. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +1 -1
  230. package/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +26 -4
  231. package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +38 -0
  232. package/harness/bundles/java/codebuddy/protocols/powershell-protocol.md +16 -0
  233. package/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +17 -0
  234. package/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +15 -0
  235. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +1209 -170
  236. package/harness/bundles/java/codebuddy/scripts/harness_change.py +18 -0
  237. package/harness/bundles/java/codebuddy/scripts/harness_deploy.py +1 -44
  238. package/harness/bundles/java/codebuddy/scripts/harness_events.py +174 -25
  239. package/harness/bundles/java/codebuddy/scripts/harness_gate.py +203 -29
  240. package/harness/bundles/java/codebuddy/scripts/harness_integration.py +878 -0
  241. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +457 -10
  242. package/harness/bundles/java/codebuddy/scripts/harness_paths.py +315 -0
  243. package/harness/bundles/java/codebuddy/scripts/harness_profile.py +45 -0
  244. package/harness/bundles/java/codebuddy/scripts/harness_review.py +326 -0
  245. package/harness/bundles/java/codebuddy/scripts/harness_sync.py +407 -0
  246. package/harness/bundles/java/codebuddy/scripts/harness_test_guard.py +244 -49
  247. package/harness/bundles/java/codex/.harness-build.json +1 -1
  248. package/harness/bundles/java/codex/contracts/workflow-policy.json +3 -3
  249. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  250. package/harness/bundles/java/codex/harness-archive/SKILL.md +3 -3
  251. package/harness/bundles/java/codex/harness-archive/reference.md +30 -12
  252. package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +5 -1
  253. package/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +6 -2
  254. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
  255. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +3 -1
  256. package/harness/bundles/java/codex/harness-knowledge-ingest/reference.md +7 -0
  257. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  258. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  259. package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
  260. package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
  261. package/harness/bundles/java/codex/harness-plan/checklist.md +6 -0
  262. package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
  263. package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
  264. package/harness/bundles/java/codex/harness-submit/SKILL.md +15 -10
  265. package/harness/bundles/java/codex/harness-submit/checklist.md +40 -76
  266. package/harness/bundles/java/codex/harness-sync/SKILL.md +17 -2
  267. package/harness/bundles/java/codex/harness-sync/reference.md +2 -2
  268. package/harness/bundles/java/codex/harness-test/SKILL.md +1 -1
  269. package/harness/bundles/java/codex/protocols/archive-report-protocol.md +26 -4
  270. package/harness/bundles/java/codex/protocols/ledger-protocol.md +38 -0
  271. package/harness/bundles/java/codex/protocols/powershell-protocol.md +16 -0
  272. package/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +17 -0
  273. package/harness/bundles/java/codex/protocols/state-layout-protocol.md +15 -0
  274. package/harness/bundles/java/codex/scripts/harness_archive.py +1209 -170
  275. package/harness/bundles/java/codex/scripts/harness_change.py +18 -0
  276. package/harness/bundles/java/codex/scripts/harness_deploy.py +1 -44
  277. package/harness/bundles/java/codex/scripts/harness_events.py +174 -25
  278. package/harness/bundles/java/codex/scripts/harness_gate.py +203 -29
  279. package/harness/bundles/java/codex/scripts/harness_integration.py +878 -0
  280. package/harness/bundles/java/codex/scripts/harness_ledger.py +457 -10
  281. package/harness/bundles/java/codex/scripts/harness_paths.py +315 -0
  282. package/harness/bundles/java/codex/scripts/harness_profile.py +45 -0
  283. package/harness/bundles/java/codex/scripts/harness_review.py +326 -0
  284. package/harness/bundles/java/codex/scripts/harness_sync.py +407 -0
  285. package/harness/bundles/java/codex/scripts/harness_test_guard.py +244 -49
  286. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  287. package/harness/bundles/java/cursor/contracts/workflow-policy.json +3 -3
  288. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  289. package/harness/bundles/java/cursor/harness-archive/SKILL.md +3 -3
  290. package/harness/bundles/java/cursor/harness-archive/reference.md +30 -12
  291. package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +5 -1
  292. package/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +6 -2
  293. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
  294. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +3 -1
  295. package/harness/bundles/java/cursor/harness-knowledge-ingest/reference.md +7 -0
  296. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +117 -0
  297. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  298. package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
  299. package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
  300. package/harness/bundles/java/cursor/harness-plan/checklist.md +6 -0
  301. package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
  302. package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
  303. package/harness/bundles/java/cursor/harness-submit/SKILL.md +15 -10
  304. package/harness/bundles/java/cursor/harness-submit/checklist.md +40 -76
  305. package/harness/bundles/java/cursor/harness-sync/SKILL.md +17 -2
  306. package/harness/bundles/java/cursor/harness-sync/reference.md +2 -2
  307. package/harness/bundles/java/cursor/harness-test/SKILL.md +1 -1
  308. package/harness/bundles/java/cursor/protocols/archive-report-protocol.md +26 -4
  309. package/harness/bundles/java/cursor/protocols/ledger-protocol.md +38 -0
  310. package/harness/bundles/java/cursor/protocols/powershell-protocol.md +16 -0
  311. package/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +17 -0
  312. package/harness/bundles/java/cursor/protocols/state-layout-protocol.md +15 -0
  313. package/harness/bundles/java/cursor/scripts/harness_archive.py +1209 -170
  314. package/harness/bundles/java/cursor/scripts/harness_change.py +18 -0
  315. package/harness/bundles/java/cursor/scripts/harness_deploy.py +1 -44
  316. package/harness/bundles/java/cursor/scripts/harness_events.py +174 -25
  317. package/harness/bundles/java/cursor/scripts/harness_gate.py +203 -29
  318. package/harness/bundles/java/cursor/scripts/harness_integration.py +878 -0
  319. package/harness/bundles/java/cursor/scripts/harness_ledger.py +457 -10
  320. package/harness/bundles/java/cursor/scripts/harness_paths.py +315 -0
  321. package/harness/bundles/java/cursor/scripts/harness_profile.py +45 -0
  322. package/harness/bundles/java/cursor/scripts/harness_review.py +326 -0
  323. package/harness/bundles/java/cursor/scripts/harness_sync.py +407 -0
  324. package/harness/bundles/java/cursor/scripts/harness_test_guard.py +244 -49
  325. package/harness/manifests/general/claude-code.json +58 -38
  326. package/harness/manifests/general/codebuddy.json +58 -38
  327. package/harness/manifests/general/codex.json +58 -38
  328. package/harness/manifests/general/cursor.json +58 -38
  329. package/harness/manifests/java/claude-code.json +52 -36
  330. package/harness/manifests/java/codebuddy.json +52 -36
  331. package/harness/manifests/java/codex.json +52 -36
  332. package/harness/manifests/java/cursor.json +52 -36
  333. package/hunter-workflow-family.json +2 -2
  334. package/package.json +1 -1
@@ -21,6 +21,12 @@ import time
21
21
  from pathlib import Path
22
22
  from typing import Any
23
23
 
24
+ SCRIPTS_DIR = Path(__file__).resolve().parent
25
+ if str(SCRIPTS_DIR) not in sys.path:
26
+ sys.path.insert(0, str(SCRIPTS_DIR))
27
+
28
+ import harness_paths # noqa: E402
29
+
24
30
  SCHEMA_VERSION = 1
25
31
  MODE = "force-track-touched"
26
32
  MANIFEST_REL = Path("evidence") / "test-tracking.json"
@@ -166,13 +172,18 @@ def _change_dir(project: Path, change_dir: Path | str) -> Path | None:
166
172
  return resolved if any(_inside(resolved, root) for root in allowed_roots) else None
167
173
 
168
174
 
175
+ def _state_root(change_root: Path) -> Path:
176
+ return Path(harness_paths.resolve_state_dir_for_contract(change_root))
177
+
178
+
169
179
  def _manifest_path(change_root: Path) -> Path | None:
170
- evidence = change_root / MANIFEST_REL.parent
171
- manifest = change_root / MANIFEST_REL
180
+ state_root = _state_root(change_root)
181
+ evidence = state_root / MANIFEST_REL.parent
182
+ manifest = state_root / MANIFEST_REL
172
183
  expected_evidence = evidence.absolute()
173
184
  resolved_evidence = evidence.resolve()
174
185
  if (
175
- not _inside(resolved_evidence, change_root.resolve())
186
+ not _inside(resolved_evidence, state_root.resolve())
176
187
  or os.path.normcase(str(resolved_evidence))
177
188
  != os.path.normcase(str(expected_evidence))
178
189
  ):
@@ -181,9 +192,10 @@ def _manifest_path(change_root: Path) -> Path | None:
181
192
 
182
193
 
183
194
  def _manifest_target_inside(change_root: Path, manifest: Path) -> bool:
195
+ state_root = _state_root(change_root)
184
196
  resolved = manifest.resolve()
185
197
  return (
186
- _inside(resolved, change_root.resolve())
198
+ _inside(resolved, state_root.resolve())
187
199
  and _inside(resolved, manifest.parent.absolute())
188
200
  )
189
201
 
@@ -267,6 +279,52 @@ def _validate_file(project: Path, raw: str) -> tuple[Path | None, str | None, st
267
279
  return resolved, rel, None
268
280
 
269
281
 
282
+ def _contract_is_v2(change_root: Path) -> bool:
283
+ try:
284
+ contract = harness_paths.load_change_contract(change_root)
285
+ except (OSError, ValueError):
286
+ return False
287
+ if harness_paths.contract_layout_kind(contract) == "split-v1":
288
+ return True
289
+ version = contract.get("schemaVersion")
290
+ return isinstance(version, int) and version >= 2
291
+
292
+
293
+ def _byte_hash(path: Path) -> str:
294
+ return "sha256:" + hashlib.sha256(path.read_bytes()).hexdigest()
295
+
296
+
297
+ def logical_file_hash(repo_root: Path, rel: str) -> str:
298
+ """Logical identity for a tracked file (RET-10).
299
+
300
+ Text files hash with git blob semantics (path filters/attributes applied,
301
+ so LF/CRLF spellings of one logical text agree). Binary files keep byte
302
+ hash. Indeterminate content falls back to byte hash.
303
+ """
304
+ path = repo_root / rel
305
+ content = path.read_bytes()
306
+ attr = _git(repo_root, "check-attr", "text", "--", rel)
307
+ attr_out = attr.stdout.strip() if attr.returncode == 0 else ""
308
+ if attr_out.endswith(": unset"):
309
+ return _byte_hash(path)
310
+ if b"\x00" in content:
311
+ return _byte_hash(path)
312
+ try:
313
+ content.decode("utf-8")
314
+ except UnicodeDecodeError:
315
+ return _byte_hash(path)
316
+ proc = subprocess.run(
317
+ ["git", "hash-object", "--path", rel, "--stdin"],
318
+ input=content,
319
+ capture_output=True,
320
+ cwd=str(repo_root),
321
+ check=False,
322
+ )
323
+ if proc.returncode != 0:
324
+ return _byte_hash(path)
325
+ return "gitblob:" + proc.stdout.decode("ascii").strip()
326
+
327
+
270
328
  def _entry_shape_valid(item: Any) -> bool:
271
329
  return (
272
330
  isinstance(item, dict)
@@ -280,6 +338,78 @@ def _entry_shape_valid(item: Any) -> bool:
280
338
  )
281
339
 
282
340
 
341
+ def _entry_shape_valid_v2(item: Any) -> bool:
342
+ if not isinstance(item, dict):
343
+ return False
344
+ if not isinstance(item.get("path"), str) or not item["path"]:
345
+ return False
346
+ logical = item.get("logicalHash")
347
+ binary = item.get("binaryHash")
348
+ logical_ok = isinstance(logical, str) and (
349
+ logical.startswith("gitblob:") or logical.startswith("sha256:")
350
+ )
351
+ binary_ok = binary is None or (
352
+ isinstance(binary, str) and binary.startswith("sha256:")
353
+ )
354
+ if not (logical_ok or binary_ok):
355
+ return False
356
+ if item.get("reason") not in REASONS:
357
+ return False
358
+ if type(item.get("ignored")) is not bool:
359
+ return False
360
+ if not isinstance(item.get("introducedBy"), str) or not item["introducedBy"]:
361
+ return False
362
+ touched = item.get("touchedBy")
363
+ if not isinstance(touched, list) or not all(isinstance(t, str) for t in touched):
364
+ return False
365
+ return item.get("commitScope") in ("current-change", "foreign-change")
366
+
367
+
368
+ def _validate_existing_manifest_v2(
369
+ project: Path,
370
+ manifest: Any,
371
+ *,
372
+ allow_hash_drift: set[str] | None = None,
373
+ require_files: bool,
374
+ ) -> tuple[str | None, dict[str, dict[str, Any]]]:
375
+ if (
376
+ not isinstance(manifest, dict)
377
+ or manifest.get("schemaVersion") != 2
378
+ or manifest.get("mode") != MODE
379
+ ):
380
+ return "MANIFEST_INVALID", {}
381
+ repository_id = manifest.get("repositoryId")
382
+ if not isinstance(repository_id, str) or not repository_id.startswith("sha256:"):
383
+ return "MANIFEST_INVALID", {}
384
+ if repository_id != harness_paths.repository_identity(project):
385
+ return "MANIFEST_PROJECT_MISMATCH", {}
386
+ entries = manifest.get("files")
387
+ if not isinstance(entries, list):
388
+ return "MANIFEST_INVALID", {}
389
+ if require_files and not entries:
390
+ return "EMPTY_MANIFEST", {}
391
+
392
+ allowed_drift = allow_hash_drift or set()
393
+ validated: dict[str, dict[str, Any]] = {}
394
+ for item in entries:
395
+ if not _entry_shape_valid_v2(item):
396
+ return "MANIFEST_INVALID", {}
397
+ rel = item["path"]
398
+ if rel in validated:
399
+ return "MANIFEST_INVALID", {}
400
+ path, normalized, error = _validate_file(project, rel)
401
+ if error or normalized != rel or path is None:
402
+ return error or "MANIFEST_INVALID", {}
403
+ expected = item.get("logicalHash") or item.get("binaryHash")
404
+ if expected != logical_file_hash(project, rel) and rel not in allowed_drift:
405
+ return "HASH_DRIFT" if require_files else "MANIFEST_INVALID", {}
406
+ ignored_now = _is_ignored(project, rel)
407
+ if item["ignored"] != ignored_now:
408
+ return "MANIFEST_INVALID", {}
409
+ validated[rel] = dict(item)
410
+ return None, validated
411
+
412
+
283
413
  def _validate_existing_manifest(
284
414
  project: Path,
285
415
  manifest: Any,
@@ -366,7 +496,12 @@ def record(
366
496
  return _result(
367
497
  False, action, "MANIFEST_INVALID", [], error=str(exc)
368
498
  )
369
- error, existing_files = _validate_existing_manifest(
499
+ validator = (
500
+ _validate_existing_manifest_v2
501
+ if isinstance(existing, dict) and existing.get("schemaVersion") == 2
502
+ else _validate_existing_manifest
503
+ )
504
+ error, existing_files = validator(
370
505
  project_root,
371
506
  existing,
372
507
  allow_hash_drift={rel for _, rel in validated},
@@ -375,25 +510,54 @@ def record(
375
510
  if error:
376
511
  return _result(False, action, error, [])
377
512
 
378
- for path, rel in validated:
379
- ignored = _is_ignored(project_root, rel)
380
- tracked = _git(
381
- project_root, "ls-files", "--error-unmatch", "--", rel
382
- ).returncode == 0
383
- existing_files[rel] = {
384
- "path": rel,
385
- "sha256": _sha256(path),
386
- "reason": reason,
387
- "ignored": ignored,
388
- "trackedBefore": tracked,
513
+ if _contract_is_v2(change_root):
514
+ change_id = change_root.name
515
+ for path, rel in validated:
516
+ ignored = _is_ignored(project_root, rel)
517
+ previous = existing_files.get(rel, {})
518
+ touched = [
519
+ item for item in previous.get("touchedBy", [])
520
+ if isinstance(item, str)
521
+ ]
522
+ if change_id not in touched:
523
+ touched.append(change_id)
524
+ digest = logical_file_hash(project_root, rel)
525
+ existing_files[rel] = {
526
+ "path": rel,
527
+ "logicalHash": digest,
528
+ "binaryHash": None if digest.startswith("gitblob:") else digest,
529
+ "reason": reason,
530
+ "ignored": ignored,
531
+ "introducedBy": previous.get("introducedBy", change_id),
532
+ "touchedBy": touched,
533
+ "commitScope": "current-change",
534
+ }
535
+ manifest = {
536
+ "schemaVersion": 2,
537
+ "repositoryId": harness_paths.repository_identity(project_root),
538
+ "mode": MODE,
539
+ "files": [existing_files[key] for key in sorted(existing_files)],
540
+ }
541
+ else:
542
+ for path, rel in validated:
543
+ ignored = _is_ignored(project_root, rel)
544
+ tracked = _git(
545
+ project_root, "ls-files", "--error-unmatch", "--", rel
546
+ ).returncode == 0
547
+ existing_files[rel] = {
548
+ "path": rel,
549
+ "sha256": _sha256(path),
550
+ "reason": reason,
551
+ "ignored": ignored,
552
+ "trackedBefore": tracked,
553
+ }
554
+
555
+ manifest = {
556
+ "schemaVersion": SCHEMA_VERSION,
557
+ "mode": MODE,
558
+ "projectRoot": str(project_root),
559
+ "files": [existing_files[key] for key in sorted(existing_files)],
389
560
  }
390
-
391
- manifest = {
392
- "schemaVersion": SCHEMA_VERSION,
393
- "mode": MODE,
394
- "projectRoot": str(project_root),
395
- "files": [existing_files[key] for key in sorted(existing_files)],
396
- }
397
561
  _write_json(manifest_path, manifest)
398
562
  except LockUnavailable:
399
563
  return _result(False, action, "MANIFEST_LOCKED", [])
@@ -412,12 +576,18 @@ def _stage_locked(
412
576
  return _result(False, action, "MANIFEST_MISSING", [])
413
577
  except (OSError, json.JSONDecodeError) as exc:
414
578
  return _result(False, action, "MANIFEST_INVALID", [], error=str(exc))
415
- error, entries = _validate_existing_manifest(
416
- project_root, manifest, require_files=True
417
- )
579
+ is_v2 = isinstance(manifest, dict) and manifest.get("schemaVersion") == 2
580
+ validator = _validate_existing_manifest_v2 if is_v2 else _validate_existing_manifest
581
+ error, entries = validator(project_root, manifest, require_files=True)
418
582
  if error:
419
583
  return _result(False, action, error, [])
420
- rels = list(entries)
584
+ rels = [
585
+ rel
586
+ for rel, entry in entries.items()
587
+ if not is_v2 or entry.get("commitScope") == "current-change"
588
+ ]
589
+ if not rels:
590
+ return _result(True, action, "STAGED", [])
421
591
 
422
592
  before_cached_result = _git(project_root, "diff", "--cached", "--name-only")
423
593
  if before_cached_result.returncode != 0:
@@ -467,15 +637,38 @@ def _stage_locked(
467
637
  temp_index.unlink(missing_ok=True)
468
638
 
469
639
 
470
- def _glob_files_for_pattern(base: Path, pattern: str) -> list[Path]:
471
- normalized = pattern.replace("\\", "/")
472
- if normalized.endswith("/**"):
473
- prefix = normalized[:-3].rstrip("/")
474
- root = base / prefix
475
- if not root.is_dir():
476
- return []
477
- return [path for path in root.rglob("*") if path.is_file()]
478
- return [path for path in base.glob(normalized) if path.is_file()]
640
+ def _path_is_excluded(rel: str, excluded_roots: list[str]) -> bool:
641
+ rel_parts = tuple(os.path.normcase(part) for part in rel.split("/") if part)
642
+ for excluded in excluded_roots:
643
+ excluded_parts = tuple(
644
+ os.path.normcase(part) for part in excluded.split("/") if part
645
+ )
646
+ if excluded_parts and rel_parts[: len(excluded_parts)] == excluded_parts:
647
+ return True
648
+ return False
649
+
650
+
651
+ def _walk_matching_files(
652
+ base: Path, patterns: list[str], excluded_roots: list[str]
653
+ ) -> list[Path]:
654
+ """Walk once and prune excluded roots before matching recursive globs."""
655
+ matches: list[Path] = []
656
+ for root_raw, dir_names, file_names in os.walk(base, followlinks=False):
657
+ root = Path(root_raw)
658
+ root_rel = root.relative_to(base).as_posix()
659
+ prefix = "" if root_rel == "." else root_rel + "/"
660
+ dir_names[:] = [
661
+ name
662
+ for name in dir_names
663
+ if not _path_is_excluded(prefix + name, excluded_roots)
664
+ ]
665
+ for name in file_names:
666
+ rel = prefix + name
667
+ if _path_is_excluded(rel, excluded_roots):
668
+ continue
669
+ if any(_matches_pattern(rel, pattern) for pattern in patterns):
670
+ matches.append(root / name)
671
+ return matches
479
672
 
480
673
 
481
674
  def _enumerate_allowed_test_files(project_root: Path) -> dict[str, str]:
@@ -484,20 +677,22 @@ def _enumerate_allowed_test_files(project_root: Path) -> dict[str, str]:
484
677
  config = _profile_config(project_root)
485
678
  if config is None:
486
679
  patterns = ["test/**", "tests/**", "src/test/**"]
680
+ excluded_roots = [
681
+ ".git", ".harness", "node_modules", "dist", "build", "__pycache__"
682
+ ]
487
683
  else:
488
- patterns, _excluded = config
684
+ patterns, excluded_roots = config
489
685
  base = project_root.resolve()
490
686
  seen: set[str] = set()
491
- for pattern in patterns:
492
- for match in _glob_files_for_pattern(base, pattern):
493
- resolved = match.resolve()
494
- if not _inside(resolved, base):
495
- continue
496
- rel = resolved.relative_to(base).as_posix()
497
- if rel in seen or not _allowed_test_path(project_root, rel):
498
- continue
499
- seen.add(rel)
500
- found[rel] = _sha256(resolved)
687
+ for match in _walk_matching_files(base, patterns, excluded_roots):
688
+ resolved = match.resolve()
689
+ if not _inside(resolved, base):
690
+ continue
691
+ rel = resolved.relative_to(base).as_posix()
692
+ if rel in seen or not _allowed_test_path(project_root, rel):
693
+ continue
694
+ seen.add(rel)
695
+ found[rel] = _sha256(resolved)
501
696
  return found
502
697
 
503
698
 
@@ -510,7 +705,7 @@ def begin(project: Path | str, change_dir: Path | str) -> dict[str, Any]:
510
705
  manifest_path = _manifest_path(change_root)
511
706
  if manifest_path is None:
512
707
  return _result(False, action, "MANIFEST_PATH_OUTSIDE_PROJECT", [])
513
- snapshot_path = change_root / SNAPSHOT_REL
708
+ snapshot_path = _state_root(change_root) / SNAPSHOT_REL
514
709
  if not _manifest_target_inside(change_root, snapshot_path):
515
710
  return _result(False, action, "SNAPSHOT_PATH_OUTSIDE_PROJECT", [])
516
711
 
@@ -542,7 +737,7 @@ def close(project: Path | str, change_dir: Path | str) -> dict[str, Any]:
542
737
  change_root = _change_dir(project_root, change_dir)
543
738
  if change_root is None:
544
739
  return _result(False, action, "CHANGE_DIR_OUTSIDE_PROJECT", [])
545
- snapshot_path = change_root / SNAPSHOT_REL
740
+ snapshot_path = _state_root(change_root) / SNAPSHOT_REL
546
741
  if not snapshot_path.is_file():
547
742
  return _result(False, action, "SNAPSHOT_MISSING", [])
548
743
  try:
@@ -2,5 +2,5 @@
2
2
  "schemaVersion": 1,
3
3
  "overlay": "java",
4
4
  "agent": "codebuddy",
5
- "coreHash": "b4f114b99a359f4d"
5
+ "coreHash": "1bf389ebc64b017d"
6
6
  }
@@ -2,21 +2,21 @@
2
2
  "schemaVersion": 1,
3
3
  "riskTiers": {
4
4
  "fast": {
5
- "description": "Low-risk docs/comments/non-behavioral config; no API/DB/security/concurrency.",
5
+ "description": "Low-risk docs/comments/non-behavioral config; no API/DB/security/concurrency. Policy notes: checkpointRules apply only when meta/implementation-checkpoints.json defines the entry for this change; missing file/entry = disabled (gate must not require --task).",
6
6
  "defaultPhases": ["plan", "run", "submit", "archive"],
7
7
  "requiredValidations": ["unitTest"],
8
8
  "conditionalStages": ["review", "package", "apidoc"],
9
9
  "upgradeTriggers": ["api-change", "security", "migration", "concurrency", "breaking-contract"]
10
10
  },
11
11
  "standard": {
12
- "description": "Ordinary production code and non-breaking API/features.",
12
+ "description": "Ordinary production code and non-breaking API/features. Policy notes: requiredValidations may close DEGRADED when ledger status=NOT_RUN and evidence starts with 'DEGRADED: <reason>' (close code CLOSED_DEGRADED, phase status <= WARN); do not fake OK with unrelated tests.",
13
13
  "defaultPhases": ["plan", "run", "test", "submit", "archive"],
14
14
  "requiredValidations": ["compile", "unitTest", "unitTestFull"],
15
15
  "conditionalStages": ["review", "package", "apidoc"],
16
16
  "upgradeTriggers": ["auth", "security", "delete", "migration", "concurrency", "artifact-protocol", "shared-state", "breaking-api"]
17
17
  },
18
18
  "full": {
19
- "description": "Auth/security/delete/migration/concurrency/service protocol/shared state/breaking contracts.",
19
+ "description": "Auth/security/delete/migration/concurrency/service protocol/shared state/breaking contracts. Policy notes: (1) DEGRADED close — ledger status=NOT_RUN and evidence 'DEGRADED: <reason>' → CLOSED_DEGRADED with phase <= WARN; never fake OK with unrelated tests. (2) checkpointRules — only when plan created meta/implementation-checkpoints.json entry; missing file/entry = not enabled, gate must not require --task.",
20
20
  "defaultPhases": ["plan", "run", "test", "review", "submit", "archive"],
21
21
  "requiredValidations": ["compile", "unitTest", "unitTestFull", "apiTest"],
22
22
  "conditionalStages": ["package", "apidoc"],
@@ -2,7 +2,7 @@
2
2
  name: harness-apidoc
3
3
  description: 从 Java 后端代码生成结构化前端 API 文档(Controller/VO/ErrorCode)。使用场景:接口文档、前端接口文档、API 文档生成
4
4
  ---
5
- <!-- generated by harness_deploy.py; core=b4f114b99a359f4d; overlay=java; agent=codebuddy; do not edit -->
5
+ <!-- generated by harness_deploy.py; core=1bf389ebc64b017d; overlay=java; agent=codebuddy; do not edit -->
6
6
  # harness-apidoc — 前端接口文档(Java overlay)
7
7
 
8
8
  ## Purpose
@@ -3,7 +3,7 @@ name: harness-archive
3
3
  description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档)到
4
4
  .harness/archive/,含归档元数据和可视化最终总结。使用场景:归档、完成归档、收尾、打包产出物
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=b4f114b99a359f4d; overlay=java; agent=codebuddy; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=1bf389ebc64b017d; overlay=java; agent=codebuddy; do not edit -->
7
7
  # harness-archive — 变更归档
8
8
 
9
9
  ## Purpose
@@ -86,8 +86,8 @@ AskUserQuestion 让用户确认归档操作。**用户拒绝 → 终止流程,
86
86
  ### Phase 3:执行归档
87
87
 
88
88
  1. 运行 `python <skills-root>/scripts/harness_archive.py status --change-dir ".harness/changes/<change-name>" --json` 前置检查。
89
- 2. 如需维护者结论,在移动前补全 `meta/archive-meta.md`;不得在 finalize 后修改已校验的归档文件。
90
- 3. 运行 `python <skills-root>/scripts/harness_archive.py finalize --change-dir ".harness/changes/<change-name>" --archive-root ".harness/archive" --json`;读 JSON(事件、移动、collect、render、validate、manifest 比对)。finalize 内部负责且仅负责一次 `phase.start` / `phase.end`,调用者不得重复追加。**finalize 不再同步执行知识维护**(§8.2):它写一个 `pending` maintenance-outbox 项即返回,`knowledgeMaintenance=QUEUED`;写 outbox 失败时 `NOT_QUEUED`(warning,不回滚 archive,总状态 CONDITIONAL)。后续由 `harness-sync` / `harness_knowledge.py maintain` 异步推进 outbox。**finalize 失败或 validate 报错时不删除原目录**。
89
+ 2. `meta/archive-meta.md` **由 `harness_archive.py finalize` 自动生成**(与 summary-data `finalStatus` 同源);**禁止 agent 手写**该文件,手写视为数据丢失。维护者结论写入 events(decision/issue)即可,finalize 会汇总到 summary / archive-meta。
90
+ 3. 运行 `python <skills-root>/scripts/harness_archive.py finalize --change-dir ".harness/changes/<change-name>" --archive-root ".harness/archive" --json`;读 JSON(cleanup、事件、移动、collect、render、validate、manifest 比对、archive-meta)。finalize 内部负责且仅负责一次 `phase.start` / `phase.end`,调用者不得重复追加。**finalize 不再同步执行知识维护**(§8.2):它写一个 `pending` maintenance-outbox 项即返回,`knowledgeMaintenance=QUEUED`;写 outbox 失败时 `NOT_QUEUED`(warning,不回滚 archive,总状态 CONDITIONAL)。后续由 `harness-sync` / `harness_knowledge.py maintain` 异步推进 outbox。**finalize 失败或 validate 报错时不删除原目录**。
91
91
 
92
92
  - **Read `reference.md`** — finalize 输出字段、archive-meta 格式、CONDITIONAL_OK 规则
93
93
  - **Read `templates/summary-data-template.json`** — summary-data 数据结构
@@ -11,8 +11,8 @@ description: harness-archive 的归档流程、manifest、summary-data、final-s
11
11
  - **Phase 2 确认归档(强制阻断)**:AskUserQuestion 确认,拒绝即终止。
12
12
  - **Phase 3 执行归档**:
13
13
  1. 运行 `python <skills-root>/scripts/harness_archive.py status --change-dir ... --json` 做前置检查。
14
- 2. 需要维护者结论时,在移动前补全 `meta/archive-meta.md` `maintenanceNotes` / `knownRisks` / `manualActions`;finalize 后不再修改归档内容。
15
- 3. 运行 `python <skills-root>/scripts/harness_archive.py finalize --change-dir ... --archive-root ".harness/archive" --json`;读 JSON 结果。finalize 内部负责且仅负责一次 `phase.start` / `phase.end`,调用者不得重复追加。**finalize 报错或 validate 失败时不删除原 changes 目录**。
14
+ 2. `meta/archive-meta.md` finalize 生成(与 summary `finalStatus` 同源);禁止手写。维护者结论写入 events 即可。finalize 在 before-manifest 前执行 cleanup(删除 lock/pid/launcher/credential,截断超大日志)。
15
+ 3. 运行 `python <skills-root>/scripts/harness_archive.py finalize --change-dir ... --archive-root ".harness/archive" --json`;读 JSON 结果。finalize 内部负责且仅负责一次 `phase.start` / `phase.end`,调用者不得重复追加。**finalize 报错或 validate 失败时不删除原 changes 目录**。finalize 为冻结优先(freeze-first):collect 前先 fsync 事件并写 `evidence/evidence-cutoff.json`,cutoff 后不再追加事件;随后依次执行 source consistency(层 1,写入 `reportPipeline.sourceConsistency`)→ render → renderer consistency(层 2),任一层失败即恢复原目录并非零退出。
16
16
  - **Phase 4 验证与提示**:见 `checklist.md` 归档后验证项。
17
17
 
18
18
  ## manifest 生成
@@ -39,7 +39,7 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "harness-skills/harness-
39
39
 
40
40
  ## summary-data.json 与 harness_archive.py
41
41
 
42
- `reports/final/summary-data.json` 只能由 `harness_archive.py finalize`(归档时)或 `replay`(回放时)生成/校验;**禁止 agent 临场手写或拼装等价数据**,也不存在独立的 `report collect`/`report validate` CLI(参见 `../protocols/report-pipeline-protocol.md` 与 `templates/summary-data-template.json` schemaVersion 2.2)。必须保留原 final report 维度。必须包含:
42
+ `reports/final/summary-data.json` 只能由 `harness_archive.py finalize`(归档时)或 `replay`(回放时)生成/校验;**禁止 agent 临场手写或拼装等价数据**,也不存在独立的 `report collect`/`report validate` CLI(参见 `../protocols/report-pipeline-protocol.md` 与 `templates/summary-data-template.json` schemaVersion 2.3)。必须保留原 final report 维度。必须包含:
43
43
 
44
44
  - `businessGoal`:本次变更为了做什么;
45
45
  - `stageStatus`:plan/run/test/review/submit/archive;
@@ -68,20 +68,38 @@ powershell.exe -NoProfile -Command "& '<node-path>' 'harness-skills/harness-arch
68
68
 
69
69
  `validate` 是 `harness_archive.py finalize` 的内嵌同进程步骤(不再作为独立 `report validate` CLI 调用)。finalize 在 validate error 存在时恢复原 `.harness/changes/<change>` 目录并 exit 非 0,绝不归档未通过校验的变更。
70
70
 
71
+ ## repair(归档后修复,不改写原版)
72
+
73
+ 归档后发现 source/renderer 不一致时,使用显式修复(`replay` 仍为只读):
74
+
75
+ ```powershell
76
+ python <skills-root>/scripts/harness_archive.py repair --archive-dir ".harness/archive/<archive-id>" --json
77
+ ```
78
+
79
+ repair 在 archive 外生成候选版本,两层 validator 通过后写入不可变 `derived/v<N>/`(summary-data.json + final-summary.html + repair-record.json),并更新 `derived/authoritative.json` pointer;原 summary、HTML、manifest 不覆盖。知识层仅从 authoritative pointer 且 hash 校验通过的版本提取。
80
+
71
81
  ## archive-meta.md 模板
72
82
 
83
+ 由 `harness_archive.py finalize` 生成(手写视为数据丢失)。frontmatter 与 summary-data 同源:
84
+
73
85
  ```markdown
74
- # Archive Meta — <change-name>
75
-
76
- - archivedAt: YYYY-MM-DD HH:mm
77
- - finalCommit: <hash>
78
- - sourceDir: .harness/changes/<change-name>
79
- - archiveDir: .harness/archive/YYYY-MM-DD-<change-name>
80
- - movedFiles: <from manifest>
81
- - generatedFiles: archive-meta.md, summary-data.json, final-summary.html, manifests
82
- - totalArchiveFiles: <from after manifest>
86
+ ---
87
+ archive-id: YYYY-MM-DD-<change-name>
88
+ change-name: <change-name>
89
+ archived-at: YYYY-MM-DD HH:mm
90
+ final-commit: <hash>
91
+ base-commit: <hash>
92
+ final-status: <OK|WARN|CONDITIONAL_OK|FAIL> # 与 summary-data.finalStatus 同源
93
+ source: harness-archive
94
+ ---
95
+ # 归档元数据 — <change-name>
96
+ ## 阶段状态
97
+ ## 变更文件
98
+ ## 已知风险
83
99
  ```
84
100
 
101
+ cleanup 步骤(before-manifest 前):删除 `events.ndjson.lock`、`runtime/*.pid`、launcher、credential/token/secret 文件名;截断 `logs/**/*.log` 超过 64KB 的尾部保留。
102
+
85
103
  ## 目录结构与最终状态规则
86
104
 
87
105
  - 默认渲染器:`templates/render-summary.mjs`,输入 `reports/final/summary-data.json`,输出 `reports/final/final-summary.html`。
@@ -56,6 +56,10 @@ const actions = list(data.manualActions);
56
56
  const files = list(data.changedFiles);
57
57
  const commands = list(record(data.reportPipeline).commands);
58
58
  const timeline = list(data.timeline);
59
+ const statusReasons = list(data.finalStatusReasons);
60
+ const reasonHtml = statusReasons.length
61
+ ? `<small>${statusReasons.map((item) => esc(item)).join(" · ")}</small>`
62
+ : "";
59
63
 
60
64
  const stageHtml = stages.map(([name, status]) => `<div class="row"><span>${esc(name)}</span>${pill(status)}</div>`).join("") || '<p class="empty">没有阶段状态记录</p>';
61
65
  const verificationHtml = [
@@ -81,7 +85,7 @@ const html = `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><met
81
85
  *{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:14px/1.5 Inter,"Segoe UI","Microsoft YaHei",sans-serif}main{width:min(1140px,calc(100% - 28px));margin:22px auto 44px}.hero,.card,.metric,details{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow)}.hero{padding:23px 25px;border-top:3px solid var(--blue)}.eyebrow{color:var(--blue);font-weight:750;letter-spacing:.08em}h1{font-size:27px;line-height:1.2;margin:5px 0 7px;overflow-wrap:anywhere}.goal,.empty,small{color:var(--muted)}.status{display:flex;align-items:center;gap:10px;margin-top:16px}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:11px;margin:11px 0}.metric{padding:14px 15px}.metric strong{display:block;font-size:19px;margin:4px 0}.grid{display:grid;grid-template-columns:1.12fr .88fr;gap:11px}.card{padding:17px;margin-bottom:11px}h2{font-size:16px;margin:0 0 10px}.row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--line)}.row:last-child{border:0}.row small{display:block;margin-top:2px}.pill{display:inline-flex;border-radius:999px;padding:3px 9px;font-size:11px;font-weight:750;white-space:nowrap}.pill.success{color:var(--good);background:color-mix(in srgb,var(--good) 13%,transparent)}.pill.warning{color:var(--warn);background:color-mix(in srgb,var(--warn) 14%,transparent)}.pill.danger{color:var(--bad);background:color-mix(in srgb,var(--bad) 13%,transparent)}.pill.neutral{color:var(--blue);background:color-mix(in srgb,var(--blue) 12%,transparent)}.duration{margin:11px 0}.duration>div{display:flex;justify-content:space-between;color:var(--muted);font-size:12px}.duration>div span:first-child{color:var(--text);font-weight:650}.duration i{display:block;height:7px;background:var(--soft);border-radius:99px;overflow:hidden;margin-top:6px}.duration b{display:block;height:100%;background:linear-gradient(90deg,var(--blue),#7c70ff)}.risk{display:grid;grid-template-columns:1fr 1fr;gap:10px}.risk>div{background:var(--soft);border-radius:10px;padding:11px}.risk h3{font-size:13px;margin:0 0 5px}.risk ul{padding-left:18px;margin:0;color:var(--muted)}details{margin:9px 0}summary{cursor:pointer;padding:13px 15px;font-weight:650}details>div{padding:0 15px 15px;overflow:auto}table{width:100%;border-collapse:collapse}th,td{text-align:left;padding:8px 9px;border-bottom:1px solid var(--line);vertical-align:top}th{color:var(--muted);font-size:11px;letter-spacing:.04em}code{font-family:"Cascadia Code",Consolas,monospace;color:var(--blue);overflow-wrap:anywhere}.plus{color:var(--good)}.minus{color:var(--bad)}dl{display:grid;grid-template-columns:145px 1fr;gap:7px 11px}dt{color:var(--muted)}dd{margin:0;overflow-wrap:anywhere}
82
86
  @media(max-width:800px){.metrics{grid-template-columns:1fr 1fr}.grid,.risk{grid-template-columns:1fr}}@media(max-width:480px){main{width:calc(100% - 18px);margin-top:9px}.metrics{grid-template-columns:1fr}.hero{padding:19px}h1{font-size:23px}dl{grid-template-columns:1fr}}
83
87
  </style></head><body><main>
84
- <section class="hero"><div class="eyebrow">HARNESS EXECUTION REPORT</div><h1>${esc(data.changeName || "未命名变更")}</h1><p class="goal">${esc(data.businessGoal || "未记录业务目标")}</p><div class="status">${pill(data.finalStatus)}<span>基于事件、验证账本与 Git 证据生成</span></div></section>
88
+ <section class="hero"><div class="eyebrow">HARNESS EXECUTION REPORT</div><h1>${esc(data.changeName || "未命名变更")}</h1><p class="goal">${esc(data.businessGoal || "未记录业务目标")}</p><div class="status">${pill(data.finalStatus)}<span>基于事件、验证账本与 Git 证据生成${data.riskTier ? ` · riskTier=${esc(data.riskTier)}` : ""}</span></div>${reasonHtml ? `<div class="status">${reasonHtml}</div>` : ""}</section>
85
89
  <section class="metrics"><article class="metric"><small>任务提交</small><strong><code title="${esc(data.finalCommit)}">${esc(shortHash(data.finalCommit))}</code></strong><small>${esc(data.finalCommitBranch || "未记录分支")}</small></article><article class="metric"><small>代码范围</small><strong>${number(diff.filesChanged)} 个文件</strong><small><span class="plus">+${number(diff.insertions)}</span> · <span class="minus">-${number(diff.deletions)}</span></small></article><article class="metric"><small>总耗时</small><strong>${esc(durations.totalLabel || duration(durations.totalMinutes))}</strong><small>${durationStages.length} 个阶段</small></article><article class="metric"><small>归档完整性</small><strong>${esc(record(data.archiveManifest).checksumStatus || "UNKNOWN")}</strong><small>${number(record(data.archiveManifest).totalArchiveFiles)} 个归档文件</small></article></section>
86
90
  <section class="grid"><div><article class="card"><h2>验证结论</h2>${verificationHtml}</article><article class="card"><h2>阶段耗时</h2>${durationHtml}</article></div><div><article class="card"><h2>阶段状态</h2>${stageHtml}</article><article class="card"><h2>风险与后续</h2><div class="risk"><div><h3>已知风险</h3><ul>${riskHtml}</ul></div><div><h3>人工动作</h3><ul>${actionHtml}</ul></div></div></article></div></section>
87
91
  <details><summary>变更文件(${files.length})</summary><div><table><thead><tr><th>文件</th><th>新增</th><th>删除</th></tr></thead><tbody>${fileRows}</tbody></table></div></details>
@@ -1,5 +1,5 @@
1
1
  {
2
- "schemaVersion": "2.2",
2
+ "schemaVersion": "2.3",
3
3
  "changeName": "<change-name>",
4
4
  "businessGoal": "本次变更为了做什么",
5
5
  "finalStatus": "OK | WARN | CONDITIONAL_OK | FAIL",
@@ -119,7 +119,11 @@
119
119
  "phase": "archive"
120
120
  }
121
121
  ],
122
- "validationIssues": []
122
+ "validationIssues": [],
123
+ "sourceConsistency": {
124
+ "ok": true,
125
+ "issues": []
126
+ }
123
127
  },
124
128
  "uncommittedTestEvidence": [],
125
129
  "maintenanceNotes": [],
@@ -3,7 +3,7 @@ name: harness-codebase-map
3
3
  description: 分析现有代码库并生成 .harness/codebase/map/
4
4
  下的结构化代码库地图。用于陌生项目理解、重大改造前梳理、harness-sync 提示 map 过期后的人工刷新。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=b4f114b99a359f4d; overlay=java; agent=codebuddy; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=1bf389ebc64b017d; overlay=java; agent=codebuddy; do not edit -->
7
7
  # harness-codebase-map — 代码库地图
8
8
 
9
9
  ## Purpose
@@ -3,7 +3,7 @@ name: harness-knowledge-ingest
3
3
  description: 从 .harness/archive 归档整理、同步和维护项目知识索引。适用场景:ingest knowledge、sync
4
4
  knowledge、rebuild knowledge index、promote knowledge、确认知识条目、检查知识库是否过期。
5
5
  ---
6
- <!-- generated by harness_deploy.py; core=b4f114b99a359f4d; overlay=java; agent=codebuddy; do not edit -->
6
+ <!-- generated by harness_deploy.py; core=1bf389ebc64b017d; overlay=java; agent=codebuddy; do not edit -->
7
7
  # harness-knowledge-ingest
8
8
 
9
9
  从 `.harness/archive/**/reports/final/summary-data.json` 抽取项目知识,生成并维护本地 `.harness/knowledge/` 索引。
@@ -136,6 +136,8 @@ powershell.exe -Command "python '<skill-dir>\scripts\harness_knowledge.py' sync
136
136
 
137
137
  仅在用户点名单条、或 `manualReview=true` 需人工确认时使用 `promote` / `demote`。日常归档后不要逐条人工复核。
138
138
 
139
+ **发布门禁**:promote / judge apply / autoPromote 会校验来源归档——`reportPipeline.sourceConsistency` 缺失或失败、authoritative pointer /hash 不通过的归档,其条目带 `lifecycle.publishBlocked`,只能停留在 quarantined candidate。先 `harness_archive.py repair` 修复并重新 ingest,再 promote(详见 `reference.md`「发布门禁」)。
140
+
139
141
  ### Phase 6:解释同步结果
140
142
 
141
143
  回复用户或交给后续 skill 前,应说明:
@@ -145,6 +145,13 @@ powershell.exe -Command "python '<skill-dir>\scripts\harness_knowledge.py' sugge
145
145
  powershell.exe -Command "python '<skill-dir>\scripts\harness_knowledge.py' promote --project '<project-root>' --id '<entry-id>' --note '<人工确认说明>'"
146
146
  ```
147
147
 
148
+ **发布门禁(archive publication gate)**:promote / judge apply / autoPromote 只处理来自**已验证归档**的条目。以下来源归档会被阻断并在条目上标记 `lifecycle.publishBlocked`(ingest 仍可生成 quarantined candidate,但不得 active/promote):
149
+
150
+ - 归档 summary 缺少 `reportPipeline.sourceConsistency`(source consistency 未运行)或 `ok=false`;
151
+ - `derived/authoritative.json` pointer 缺失、版本目录不可读,或 repair record / pointer 的 summary hash 不匹配(DEGRADED)。
152
+
153
+ 修复路径:先运行 `harness_archive.py repair` 生成通过两层 validator 的新 derived version,再重新 ingest(旧错误条目标记 superseded),之后 promote 才放行。
154
+
148
155
  将一条 `candidate` 提升为 `active`,写入:
149
156
 
150
157
  ```text