@hunter-harness/workflow-harness 0.2.0 → 0.2.2

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 (278) 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 +1 -1
  3. package/harness/bundles/general/claude-code/harness-archive/reference.md +2 -8
  4. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +2 -1
  5. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +35 -21
  6. package/harness/bundles/general/claude-code/harness-knowledge-ingest/reference.md +53 -7
  7. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  8. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  9. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  10. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +2 -1
  11. package/harness/bundles/general/claude-code/harness-review/SKILL.md +5 -1
  12. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  13. package/harness/bundles/general/claude-code/harness-run/checklist.md +1 -1
  14. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +2 -2
  15. package/harness/bundles/general/claude-code/harness-submit/checklist.md +30 -6
  16. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +2 -2
  17. package/harness/bundles/general/claude-code/harness-test/SKILL.md +2 -2
  18. package/harness/bundles/general/claude-code/harness-test/checklist.md +1 -1
  19. package/harness/bundles/general/claude-code/harness-test/pitfalls.md +16 -0
  20. package/harness/bundles/general/claude-code/harness-test/scripts/runtime-helpers.mjs +216 -0
  21. package/harness/bundles/general/claude-code/protocols/archive-report-protocol.md +1 -1
  22. package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +55 -2
  23. package/harness/bundles/general/claude-code/protocols/report-pipeline-protocol.md +1 -8
  24. package/harness/bundles/general/claude-code/protocols/sensitive-info-protocol.md +13 -0
  25. package/harness/bundles/general/claude-code/protocols/state-layout-protocol.md +24 -0
  26. package/harness/bundles/general/claude-code/scripts/harness_archive.py +31 -14
  27. package/harness/bundles/general/claude-code/scripts/harness_check_gate.py +103 -0
  28. package/harness/bundles/general/claude-code/scripts/harness_deploy.py +179 -4
  29. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +269 -3
  30. package/harness/bundles/general/claude-code/scripts/harness_preflight.py +72 -382
  31. package/harness/bundles/general/claude-code/scripts/harness_profile.py +742 -0
  32. package/harness/bundles/general/claude-code/scripts/harness_service.py +99 -2
  33. package/harness/bundles/general/claude-code/scripts/harness_state.py +179 -0
  34. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  35. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
  36. package/harness/bundles/general/codebuddy/harness-archive/reference.md +2 -8
  37. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +2 -1
  38. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +35 -21
  39. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/reference.md +53 -7
  40. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  41. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  42. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  43. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +2 -1
  44. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +5 -1
  45. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  46. package/harness/bundles/general/codebuddy/harness-run/checklist.md +1 -1
  47. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +2 -2
  48. package/harness/bundles/general/codebuddy/harness-submit/checklist.md +30 -6
  49. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +2 -2
  50. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +2 -2
  51. package/harness/bundles/general/codebuddy/harness-test/checklist.md +1 -1
  52. package/harness/bundles/general/codebuddy/harness-test/pitfalls.md +16 -0
  53. package/harness/bundles/general/codebuddy/harness-test/scripts/runtime-helpers.mjs +216 -0
  54. package/harness/bundles/general/codebuddy/protocols/archive-report-protocol.md +1 -1
  55. package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +55 -2
  56. package/harness/bundles/general/codebuddy/protocols/report-pipeline-protocol.md +1 -8
  57. package/harness/bundles/general/codebuddy/protocols/sensitive-info-protocol.md +13 -0
  58. package/harness/bundles/general/codebuddy/protocols/state-layout-protocol.md +24 -0
  59. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +31 -14
  60. package/harness/bundles/general/codebuddy/scripts/harness_check_gate.py +103 -0
  61. package/harness/bundles/general/codebuddy/scripts/harness_deploy.py +179 -4
  62. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +269 -3
  63. package/harness/bundles/general/codebuddy/scripts/harness_preflight.py +72 -382
  64. package/harness/bundles/general/codebuddy/scripts/harness_profile.py +742 -0
  65. package/harness/bundles/general/codebuddy/scripts/harness_service.py +99 -2
  66. package/harness/bundles/general/codebuddy/scripts/harness_state.py +179 -0
  67. package/harness/bundles/general/codex/.harness-build.json +1 -1
  68. package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
  69. package/harness/bundles/general/codex/harness-archive/reference.md +2 -8
  70. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +2 -1
  71. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +35 -21
  72. package/harness/bundles/general/codex/harness-knowledge-ingest/reference.md +53 -7
  73. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  74. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  75. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  76. package/harness/bundles/general/codex/harness-plan/SKILL.md +2 -1
  77. package/harness/bundles/general/codex/harness-review/SKILL.md +5 -1
  78. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  79. package/harness/bundles/general/codex/harness-run/checklist.md +1 -1
  80. package/harness/bundles/general/codex/harness-submit/SKILL.md +2 -2
  81. package/harness/bundles/general/codex/harness-submit/checklist.md +30 -6
  82. package/harness/bundles/general/codex/harness-sync/SKILL.md +2 -2
  83. package/harness/bundles/general/codex/harness-test/SKILL.md +2 -2
  84. package/harness/bundles/general/codex/harness-test/checklist.md +1 -1
  85. package/harness/bundles/general/codex/harness-test/pitfalls.md +16 -0
  86. package/harness/bundles/general/codex/harness-test/scripts/runtime-helpers.mjs +216 -0
  87. package/harness/bundles/general/codex/protocols/archive-report-protocol.md +1 -1
  88. package/harness/bundles/general/codex/protocols/ledger-protocol.md +55 -2
  89. package/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +1 -8
  90. package/harness/bundles/general/codex/protocols/sensitive-info-protocol.md +13 -0
  91. package/harness/bundles/general/codex/protocols/state-layout-protocol.md +24 -0
  92. package/harness/bundles/general/codex/scripts/harness_archive.py +31 -14
  93. package/harness/bundles/general/codex/scripts/harness_check_gate.py +103 -0
  94. package/harness/bundles/general/codex/scripts/harness_deploy.py +179 -4
  95. package/harness/bundles/general/codex/scripts/harness_ledger.py +269 -3
  96. package/harness/bundles/general/codex/scripts/harness_preflight.py +72 -382
  97. package/harness/bundles/general/codex/scripts/harness_profile.py +742 -0
  98. package/harness/bundles/general/codex/scripts/harness_service.py +99 -2
  99. package/harness/bundles/general/codex/scripts/harness_state.py +179 -0
  100. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  101. package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
  102. package/harness/bundles/general/cursor/harness-archive/reference.md +2 -8
  103. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +2 -1
  104. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +35 -21
  105. package/harness/bundles/general/cursor/harness-knowledge-ingest/reference.md +53 -7
  106. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  107. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  108. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  109. package/harness/bundles/general/cursor/harness-plan/SKILL.md +2 -1
  110. package/harness/bundles/general/cursor/harness-review/SKILL.md +5 -1
  111. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  112. package/harness/bundles/general/cursor/harness-run/checklist.md +1 -1
  113. package/harness/bundles/general/cursor/harness-submit/SKILL.md +2 -2
  114. package/harness/bundles/general/cursor/harness-submit/checklist.md +30 -6
  115. package/harness/bundles/general/cursor/harness-sync/SKILL.md +2 -2
  116. package/harness/bundles/general/cursor/harness-test/SKILL.md +2 -2
  117. package/harness/bundles/general/cursor/harness-test/checklist.md +1 -1
  118. package/harness/bundles/general/cursor/harness-test/pitfalls.md +16 -0
  119. package/harness/bundles/general/cursor/harness-test/scripts/runtime-helpers.mjs +216 -0
  120. package/harness/bundles/general/cursor/protocols/archive-report-protocol.md +1 -1
  121. package/harness/bundles/general/cursor/protocols/ledger-protocol.md +55 -2
  122. package/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +1 -8
  123. package/harness/bundles/general/cursor/protocols/sensitive-info-protocol.md +13 -0
  124. package/harness/bundles/general/cursor/protocols/state-layout-protocol.md +24 -0
  125. package/harness/bundles/general/cursor/scripts/harness_archive.py +31 -14
  126. package/harness/bundles/general/cursor/scripts/harness_check_gate.py +103 -0
  127. package/harness/bundles/general/cursor/scripts/harness_deploy.py +179 -4
  128. package/harness/bundles/general/cursor/scripts/harness_ledger.py +269 -3
  129. package/harness/bundles/general/cursor/scripts/harness_preflight.py +72 -382
  130. package/harness/bundles/general/cursor/scripts/harness_profile.py +742 -0
  131. package/harness/bundles/general/cursor/scripts/harness_service.py +99 -2
  132. package/harness/bundles/general/cursor/scripts/harness_state.py +179 -0
  133. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  134. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  135. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
  136. package/harness/bundles/java/claude-code/harness-archive/reference.md +2 -8
  137. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +2 -1
  138. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +35 -21
  139. package/harness/bundles/java/claude-code/harness-knowledge-ingest/reference.md +53 -7
  140. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  141. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  142. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  143. package/harness/bundles/java/claude-code/harness-package/SKILL.md +3 -3
  144. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +2 -1
  145. package/harness/bundles/java/claude-code/harness-review/SKILL.md +5 -1
  146. package/harness/bundles/java/claude-code/harness-run/SKILL.md +4 -4
  147. package/harness/bundles/java/claude-code/harness-run/checklist.md +1 -1
  148. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +3 -3
  149. package/harness/bundles/java/claude-code/harness-submit/checklist.md +30 -6
  150. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +2 -2
  151. package/harness/bundles/java/claude-code/harness-test/SKILL.md +5 -5
  152. package/harness/bundles/java/claude-code/harness-test/pitfalls.md +16 -0
  153. package/harness/bundles/java/claude-code/harness-test/scripts/runtime-helpers.mjs +216 -0
  154. package/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +1 -1
  155. package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +55 -2
  156. package/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +1 -8
  157. package/harness/bundles/java/claude-code/protocols/sensitive-info-protocol.md +13 -0
  158. package/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +24 -0
  159. package/harness/bundles/java/claude-code/scripts/harness_archive.py +31 -14
  160. package/harness/bundles/java/claude-code/scripts/harness_check_gate.py +103 -0
  161. package/harness/bundles/java/claude-code/scripts/harness_deploy.py +179 -4
  162. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +269 -3
  163. package/harness/bundles/java/claude-code/scripts/harness_preflight.py +72 -382
  164. package/harness/bundles/java/claude-code/scripts/harness_profile.py +742 -0
  165. package/harness/bundles/java/claude-code/scripts/harness_service.py +99 -2
  166. package/harness/bundles/java/claude-code/scripts/harness_state.py +179 -0
  167. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  168. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  169. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
  170. package/harness/bundles/java/codebuddy/harness-archive/reference.md +2 -8
  171. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +2 -1
  172. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +35 -21
  173. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/reference.md +53 -7
  174. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  175. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  176. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  177. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +3 -3
  178. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +2 -1
  179. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +5 -1
  180. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +4 -4
  181. package/harness/bundles/java/codebuddy/harness-run/checklist.md +1 -1
  182. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +3 -3
  183. package/harness/bundles/java/codebuddy/harness-submit/checklist.md +30 -6
  184. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +2 -2
  185. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +5 -5
  186. package/harness/bundles/java/codebuddy/harness-test/pitfalls.md +16 -0
  187. package/harness/bundles/java/codebuddy/harness-test/scripts/runtime-helpers.mjs +216 -0
  188. package/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +1 -1
  189. package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +55 -2
  190. package/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +1 -8
  191. package/harness/bundles/java/codebuddy/protocols/sensitive-info-protocol.md +13 -0
  192. package/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +24 -0
  193. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +31 -14
  194. package/harness/bundles/java/codebuddy/scripts/harness_check_gate.py +103 -0
  195. package/harness/bundles/java/codebuddy/scripts/harness_deploy.py +179 -4
  196. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +269 -3
  197. package/harness/bundles/java/codebuddy/scripts/harness_preflight.py +72 -382
  198. package/harness/bundles/java/codebuddy/scripts/harness_profile.py +742 -0
  199. package/harness/bundles/java/codebuddy/scripts/harness_service.py +99 -2
  200. package/harness/bundles/java/codebuddy/scripts/harness_state.py +179 -0
  201. package/harness/bundles/java/codex/.harness-build.json +1 -1
  202. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  203. package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
  204. package/harness/bundles/java/codex/harness-archive/reference.md +2 -8
  205. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +2 -1
  206. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +35 -21
  207. package/harness/bundles/java/codex/harness-knowledge-ingest/reference.md +53 -7
  208. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  209. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  210. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  211. package/harness/bundles/java/codex/harness-package/SKILL.md +3 -3
  212. package/harness/bundles/java/codex/harness-plan/SKILL.md +2 -1
  213. package/harness/bundles/java/codex/harness-review/SKILL.md +5 -1
  214. package/harness/bundles/java/codex/harness-run/SKILL.md +4 -4
  215. package/harness/bundles/java/codex/harness-run/checklist.md +1 -1
  216. package/harness/bundles/java/codex/harness-submit/SKILL.md +3 -3
  217. package/harness/bundles/java/codex/harness-submit/checklist.md +30 -6
  218. package/harness/bundles/java/codex/harness-sync/SKILL.md +2 -2
  219. package/harness/bundles/java/codex/harness-test/SKILL.md +5 -5
  220. package/harness/bundles/java/codex/harness-test/pitfalls.md +16 -0
  221. package/harness/bundles/java/codex/harness-test/scripts/runtime-helpers.mjs +216 -0
  222. package/harness/bundles/java/codex/protocols/archive-report-protocol.md +1 -1
  223. package/harness/bundles/java/codex/protocols/ledger-protocol.md +55 -2
  224. package/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +1 -8
  225. package/harness/bundles/java/codex/protocols/sensitive-info-protocol.md +13 -0
  226. package/harness/bundles/java/codex/protocols/state-layout-protocol.md +24 -0
  227. package/harness/bundles/java/codex/scripts/harness_archive.py +31 -14
  228. package/harness/bundles/java/codex/scripts/harness_check_gate.py +103 -0
  229. package/harness/bundles/java/codex/scripts/harness_deploy.py +179 -4
  230. package/harness/bundles/java/codex/scripts/harness_ledger.py +269 -3
  231. package/harness/bundles/java/codex/scripts/harness_preflight.py +72 -382
  232. package/harness/bundles/java/codex/scripts/harness_profile.py +742 -0
  233. package/harness/bundles/java/codex/scripts/harness_service.py +99 -2
  234. package/harness/bundles/java/codex/scripts/harness_state.py +179 -0
  235. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  236. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  237. package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
  238. package/harness/bundles/java/cursor/harness-archive/reference.md +2 -8
  239. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +2 -1
  240. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +35 -21
  241. package/harness/bundles/java/cursor/harness-knowledge-ingest/reference.md +53 -7
  242. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +521 -125
  243. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -2
  244. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  245. package/harness/bundles/java/cursor/harness-package/SKILL.md +3 -3
  246. package/harness/bundles/java/cursor/harness-plan/SKILL.md +2 -1
  247. package/harness/bundles/java/cursor/harness-review/SKILL.md +5 -1
  248. package/harness/bundles/java/cursor/harness-run/SKILL.md +4 -4
  249. package/harness/bundles/java/cursor/harness-run/checklist.md +1 -1
  250. package/harness/bundles/java/cursor/harness-submit/SKILL.md +3 -3
  251. package/harness/bundles/java/cursor/harness-submit/checklist.md +30 -6
  252. package/harness/bundles/java/cursor/harness-sync/SKILL.md +2 -2
  253. package/harness/bundles/java/cursor/harness-test/SKILL.md +5 -5
  254. package/harness/bundles/java/cursor/harness-test/pitfalls.md +16 -0
  255. package/harness/bundles/java/cursor/harness-test/scripts/runtime-helpers.mjs +216 -0
  256. package/harness/bundles/java/cursor/protocols/archive-report-protocol.md +1 -1
  257. package/harness/bundles/java/cursor/protocols/ledger-protocol.md +55 -2
  258. package/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +1 -8
  259. package/harness/bundles/java/cursor/protocols/sensitive-info-protocol.md +13 -0
  260. package/harness/bundles/java/cursor/protocols/state-layout-protocol.md +24 -0
  261. package/harness/bundles/java/cursor/scripts/harness_archive.py +31 -14
  262. package/harness/bundles/java/cursor/scripts/harness_check_gate.py +103 -0
  263. package/harness/bundles/java/cursor/scripts/harness_deploy.py +179 -4
  264. package/harness/bundles/java/cursor/scripts/harness_ledger.py +269 -3
  265. package/harness/bundles/java/cursor/scripts/harness_preflight.py +72 -382
  266. package/harness/bundles/java/cursor/scripts/harness_profile.py +742 -0
  267. package/harness/bundles/java/cursor/scripts/harness_service.py +99 -2
  268. package/harness/bundles/java/cursor/scripts/harness_state.py +179 -0
  269. package/harness/manifests/general/claude-code.json +46 -30
  270. package/harness/manifests/general/codebuddy.json +46 -30
  271. package/harness/manifests/general/codex.json +46 -30
  272. package/harness/manifests/general/cursor.json +46 -30
  273. package/harness/manifests/java/claude-code.json +47 -31
  274. package/harness/manifests/java/codebuddy.json +47 -31
  275. package/harness/manifests/java/codex.json +47 -31
  276. package/harness/manifests/java/cursor.json +47 -31
  277. package/hunter-workflow-family.json +2 -2
  278. package/package.json +1 -1
@@ -15,6 +15,7 @@ import argparse
15
15
  import datetime as dt
16
16
  import hashlib
17
17
  import json
18
+ import subprocess
18
19
  import sys
19
20
  from pathlib import Path
20
21
  from typing import Any
@@ -26,7 +27,7 @@ if hasattr(sys.stderr, "reconfigure"):
26
27
  sys.stderr.reconfigure(encoding="utf-8")
27
28
 
28
29
 
29
- VERIFICATIONS = frozenset({"compile", "unitTest", "unitTestFull", "apiTest", "install"})
30
+ VERIFICATIONS = frozenset({"compile", "unitTest", "unitTestFull", "apiTest", "install", "package"})
30
31
  STATUS_MAP = {
31
32
  "ok": "OK",
32
33
  "OK": "OK",
@@ -37,6 +38,24 @@ STATUS_MAP = {
37
38
  }
38
39
  BROAD_SCOPES = frozenset({"module", "module-am", "full"})
39
40
 
41
+ # --- Ledger v2 (cluster 2) ---
42
+ LEDGER_VERSION = "harness-ledger-2"
43
+ DIFF_HASH_VERSION = "content-changeset-1"
44
+ # Coverage lattice: a recorded verification's coverage rank must meet the
45
+ # verification's required rank. Prevents incremental evidence from satisfying
46
+ # a module/full gate (UT-015 / API-005).
47
+ COVERAGE_RANK = {"incremental": 0, "module": 1, "module-am": 2, "full": 3}
48
+ REQUIRED_COVERAGE = {
49
+ "unitTest": 0, # incremental suffices (scope checked separately)
50
+ "unitTestFull": 1, # module or broader
51
+ "compile": 1,
52
+ "apiTest": 1,
53
+ "install": 2, # module-am or broader
54
+ "package": 2,
55
+ }
56
+ # git empty-tree object id (used as base fallback when no commit exists).
57
+ _EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
58
+
40
59
 
41
60
  def now_iso() -> str:
42
61
  return dt.datetime.now().astimezone().isoformat(timespec="milliseconds")
@@ -51,6 +70,8 @@ def emit_json(payload: dict[str, Any], *, as_json: bool) -> None:
51
70
  reuse = payload.get("reuse")
52
71
  if reuse is not None:
53
72
  sys.stdout.write(f"reuse={reuse} reason={payload.get('reason')}\n")
73
+ elif "diffHash" in payload:
74
+ sys.stdout.write(f"{payload['diffHash']}\n")
54
75
  elif "inputsHash" in payload:
55
76
  sys.stdout.write(f"{payload['inputsHash']}\n")
56
77
  else:
@@ -111,6 +132,95 @@ def compute_inputs_hash(file_paths: list[str]) -> tuple[str, list[str]]:
111
132
  return f"sha256:{combined.hexdigest()}", resolved_files_sorted
112
133
 
113
134
 
135
+ def _git_bytes(args: list[str], cwd: Path) -> bytes:
136
+ """Run git, return raw stdout bytes. Raises RuntimeError on non-zero exit."""
137
+ proc = subprocess.run(["git", *args], cwd=str(cwd), capture_output=True)
138
+ if proc.returncode != 0:
139
+ msg = proc.stderr.decode("utf-8", "replace").strip()
140
+ raise RuntimeError(f"git {' '.join(args)} failed: {msg}")
141
+ return proc.stdout
142
+
143
+
144
+ def _root_commit(repo_root: Path) -> str | None:
145
+ out = _git_bytes(["rev-list", "--max-parents=0", "HEAD"], repo_root)
146
+ lines = [ln for ln in out.decode("utf-8", "replace").splitlines() if ln.strip()]
147
+ return lines[0] if lines else None
148
+
149
+
150
+ def _changed_paths(repo_root: Path, base: str | None) -> tuple[str, list[str]]:
151
+ """Commit-invariant change set: tracked files differing from base (working
152
+ tree) plus untracked files. Sorted by repo-relative path.
153
+
154
+ Working-tree content is unchanged by a checkpoint commit, so the change set
155
+ and its bytes are identical before/after commit (UT-011).
156
+ """
157
+ if not base:
158
+ base = _root_commit(repo_root) or _EMPTY_TREE
159
+ out = _git_bytes(["diff", "--name-only", "--no-renames", "-z", base], repo_root)
160
+ paths: set[str] = set()
161
+ for name in out.split(b"\x00"):
162
+ if name:
163
+ paths.add(name.decode("utf-8"))
164
+ out2 = _git_bytes(["ls-files", "--others", "--exclude-standard", "-z"], repo_root)
165
+ for name in out2.split(b"\x00"):
166
+ if name:
167
+ paths.add(name.decode("utf-8"))
168
+ return base, sorted(paths)
169
+
170
+
171
+ def compute_diff_hash(repo_root: Path, base: str | None = None) -> tuple[str, dict[str, Any]]:
172
+ """Byte-level, commit-invariant diff hash (cluster 2).
173
+
174
+ Content-based change set: every file whose working-tree content differs
175
+ from base, plus untracked files. Each entry is length-framed
176
+ (path-len | path | exists-flag | content-len | content) so the payload is
177
+ independent of shell, console encoding, BOM and system newlines. Stable
178
+ across a checkpoint commit because git does not mutate the working tree.
179
+ """
180
+ repo_root = Path(repo_root).resolve()
181
+ base, paths = _changed_paths(repo_root, base)
182
+ digest = hashlib.sha256()
183
+ digest.update(DIFF_HASH_VERSION.encode("utf-8"))
184
+ digest.update(b"\x00")
185
+ for rel in paths:
186
+ path_bytes = rel.encode("utf-8")
187
+ digest.update(len(path_bytes).to_bytes(4, "big"))
188
+ digest.update(path_bytes)
189
+ abs_path = repo_root / rel
190
+ if abs_path.is_file():
191
+ content = abs_path.read_bytes()
192
+ digest.update(b"\x01")
193
+ digest.update(len(content).to_bytes(8, "big"))
194
+ digest.update(content)
195
+ else:
196
+ # Deleted since base: record absence with no content.
197
+ digest.update(b"\x00")
198
+ digest.update((0).to_bytes(8, "big"))
199
+ try:
200
+ head = _git_bytes(["rev-parse", "HEAD"], repo_root).decode("utf-8", "replace").strip()
201
+ except RuntimeError:
202
+ head = ""
203
+ meta = {
204
+ "algorithmVersion": DIFF_HASH_VERSION,
205
+ "fileCount": len(paths),
206
+ "base": base,
207
+ "head": head or None,
208
+ }
209
+ return f"sha256:{digest.hexdigest()}", meta
210
+
211
+
212
+ def derive_coverage(verification: str, scope: str | None) -> str:
213
+ """Derive coverage lattice value from verification + scope (cluster 2)."""
214
+ s = str(scope).strip() if scope else ""
215
+ if verification == "unitTest":
216
+ return "module" if s in BROAD_SCOPES else "incremental"
217
+ if verification == "unitTestFull":
218
+ return "full" if s == "full" else "module"
219
+ if verification in ("install", "package"):
220
+ return "module-am"
221
+ return "module"
222
+
223
+
114
224
  def expand_profile_input_files(
115
225
  project: Path, profile_input: str
116
226
  ) -> tuple[list[str], str | None]:
@@ -275,6 +385,9 @@ def decide_can_reuse(
275
385
  files: list[str],
276
386
  requested_scope: str | None = None,
277
387
  requested_command: str | None = None,
388
+ requested_toolchain_hash: str | None = None,
389
+ requested_profile_hash: str | None = None,
390
+ requested_environment_hash: str | None = None,
278
391
  ) -> dict[str, Any]:
279
392
  ledger, ledger_path = load_ledger(change_dir)
280
393
  if ledger is None:
@@ -282,6 +395,7 @@ def decide_can_reuse(
282
395
  "ok": True,
283
396
  "reuse": False,
284
397
  "reason": "insufficient-evidence",
398
+ "code": "LEDGER_MISSING",
285
399
  "verification": verification,
286
400
  "detail": "ledger missing",
287
401
  }
@@ -292,6 +406,7 @@ def decide_can_reuse(
292
406
  "ok": True,
293
407
  "reuse": False,
294
408
  "reason": "insufficient-evidence",
409
+ "code": "VALIDATIONS_MISSING",
295
410
  "verification": verification,
296
411
  "detail": "validations missing",
297
412
  "ledger_path": str(ledger_path) if ledger_path else None,
@@ -303,6 +418,7 @@ def decide_can_reuse(
303
418
  "ok": True,
304
419
  "reuse": False,
305
420
  "reason": "insufficient-evidence",
421
+ "code": "VALIDATION_MISSING",
306
422
  "verification": verification,
307
423
  "detail": f"validation '{verification}' missing",
308
424
  "ledger_path": str(ledger_path) if ledger_path else None,
@@ -314,6 +430,17 @@ def decide_can_reuse(
314
430
  evidence = entry.get("evidence")
315
431
  command = entry.get("command")
316
432
  scope = entry.get("scope")
433
+ algorithm_version = entry.get("algorithmVersion")
434
+ coverage = entry.get("coverage")
435
+
436
+ # v2 fields: a v1 entry (no algorithmVersion/coverage) is conservatively
437
+ # invalidated once and must be re-recorded with v2 fields (COM-002). No
438
+ # silent upgrade of stale evidence.
439
+ v2_missing: list[str] = []
440
+ if not _nonempty_str(algorithm_version):
441
+ v2_missing.append("algorithmVersion")
442
+ if not (_nonempty_str(coverage) and str(coverage).strip() in COVERAGE_RANK):
443
+ v2_missing.append("coverage")
317
444
 
318
445
  missing: list[str] = []
319
446
  if not _nonempty_str(stored_hash):
@@ -341,22 +468,41 @@ def decide_can_reuse(
341
468
  if verification == "install" and not worktree_ready(ledger, change_dir):
342
469
  missing.append("worktree")
343
470
 
344
- if missing:
471
+ all_missing = v2_missing + missing
472
+ if all_missing:
345
473
  return {
346
474
  "ok": True,
347
475
  "reuse": False,
348
476
  "reason": "insufficient-evidence",
477
+ "code": "MISSING_V2_FIELDS" if v2_missing else "MISSING_FIELDS",
349
478
  "verification": verification,
350
- "detail": "missing or invalid: " + ", ".join(missing),
479
+ "detail": "missing or invalid: " + ", ".join(all_missing),
351
480
  "ledger_path": str(ledger_path) if ledger_path else None,
352
481
  }
353
482
 
483
+ # Coverage lattice: recorded coverage rank must meet the verification's
484
+ # required rank. Stops incremental evidence satisfying a module/full gate
485
+ # (UT-015 / API-005).
486
+ required = REQUIRED_COVERAGE.get(verification, 1)
487
+ if COVERAGE_RANK.get(str(coverage).strip(), -1) < required:
488
+ return {
489
+ "ok": True,
490
+ "reuse": False,
491
+ "reason": "insufficient-evidence",
492
+ "code": "COVERAGE_INSUFFICIENT",
493
+ "verification": verification,
494
+ "detail": f"coverage '{coverage}' below required rank {required} for {verification}",
495
+ "ledger_path": str(ledger_path) if ledger_path else None,
496
+ "stored_coverage": coverage,
497
+ }
498
+
354
499
  if requested_command is not None and str(requested_command).strip():
355
500
  if str(command).strip() != str(requested_command).strip():
356
501
  return {
357
502
  "ok": True,
358
503
  "reuse": False,
359
504
  "reason": "rerun",
505
+ "code": "COMMAND_CHANGED",
360
506
  "verification": verification,
361
507
  "detail": "command changed",
362
508
  "ledger_path": str(ledger_path) if ledger_path else None,
@@ -364,11 +510,39 @@ def decide_can_reuse(
364
510
  "requested_command": requested_command,
365
511
  }
366
512
 
513
+ # Toolchain / profile / environment hash drift -> structured rerun (UT-017).
514
+ # Only compared when both the stored entry and the request carry the field.
515
+ for field, requested, code_name in (
516
+ ("toolchainHash", requested_toolchain_hash, "TOOLCHAIN_CHANGED"),
517
+ ("profileHash", requested_profile_hash, "PROFILE_CHANGED"),
518
+ ("environmentHash", requested_environment_hash, "ENVIRONMENT_CHANGED"),
519
+ ):
520
+ stored = entry.get(field)
521
+ if (
522
+ requested
523
+ and str(requested).strip()
524
+ and _nonempty_str(stored)
525
+ and str(stored).strip() != str(requested).strip()
526
+ ):
527
+ return {
528
+ "ok": True,
529
+ "reuse": False,
530
+ "reason": "rerun",
531
+ "code": code_name,
532
+ "verification": verification,
533
+ "detail": f"{field} changed",
534
+ "ledger_path": str(ledger_path) if ledger_path else None,
535
+ "field": field,
536
+ "stored": stored,
537
+ "requested": requested,
538
+ }
539
+
367
540
  if verification == "unitTest" and not _scope_covers(scope, requested_scope):
368
541
  return {
369
542
  "ok": True,
370
543
  "reuse": False,
371
544
  "reason": "insufficient-evidence",
545
+ "code": "SCOPE_INSUFFICIENT",
372
546
  "verification": verification,
373
547
  "detail": "scope does not cover requested tests",
374
548
  "ledger_path": str(ledger_path) if ledger_path else None,
@@ -383,6 +557,7 @@ def decide_can_reuse(
383
557
  "ok": True,
384
558
  "reuse": False,
385
559
  "reason": "insufficient-evidence",
560
+ "code": "INPUT_FILE_MISSING",
386
561
  "verification": verification,
387
562
  "detail": str(exc),
388
563
  "ledger_path": str(ledger_path) if ledger_path else None,
@@ -393,6 +568,7 @@ def decide_can_reuse(
393
568
  "ok": True,
394
569
  "reuse": False,
395
570
  "reason": "rerun",
571
+ "code": "INPUTS_HASH_CHANGED",
396
572
  "verification": verification,
397
573
  "detail": "inputsHash changed",
398
574
  "ledger_path": str(ledger_path) if ledger_path else None,
@@ -405,6 +581,7 @@ def decide_can_reuse(
405
581
  "ok": True,
406
582
  "reuse": True,
407
583
  "reason": "reuse",
584
+ "code": "REUSED",
408
585
  "verification": verification,
409
586
  "ledger_path": str(ledger_path) if ledger_path else None,
410
587
  "inputsHash": stored_hash,
@@ -475,6 +652,9 @@ def cmd_can_reuse(args: argparse.Namespace) -> int:
475
652
  files=files,
476
653
  requested_scope=getattr(args, "scope", None),
477
654
  requested_command=getattr(args, "command", None),
655
+ requested_toolchain_hash=getattr(args, "toolchain_hash", None),
656
+ requested_profile_hash=getattr(args, "profile_hash", None),
657
+ requested_environment_hash=getattr(args, "environment_hash", None),
478
658
  )
479
659
  except (OSError, ValueError, json.JSONDecodeError) as exc:
480
660
  return emit_error(f"can-reuse failed: {exc}", as_json=as_json)
@@ -542,6 +722,32 @@ def cmd_record(args: argparse.Namespace) -> int:
542
722
  # would let can-reuse wrongly approve untested classes (D13 guardrail).
543
723
  # Missing scope → can-reuse treats unitTest as insufficient-evidence.
544
724
 
725
+ # v2 fields (cluster 2): algorithmVersion + coverage lattice + optional
726
+ # toolchain/profile/environment hashes. v1 entries missing these are
727
+ # conservatively invalidated by can-reuse (COM-002).
728
+ entry["algorithmVersion"] = LEDGER_VERSION
729
+ coverage = getattr(args, "coverage", None)
730
+ if not (_nonempty_str(coverage) and str(coverage).strip() in COVERAGE_RANK):
731
+ coverage = derive_coverage(verification, args.scope)
732
+ entry["coverage"] = coverage
733
+ for field, attr in (
734
+ ("toolchainHash", "toolchain_hash"),
735
+ ("profileHash", "profile_hash"),
736
+ ("environmentHash", "environment_hash"),
737
+ ):
738
+ val = getattr(args, attr, None)
739
+ if _nonempty_str(val):
740
+ entry[field] = str(val).strip()
741
+ # package verification: record build artifact + test-reuse provenance.
742
+ if verification == "package":
743
+ if _nonempty_str(getattr(args, "deploy_artifact", None)):
744
+ entry["deployArtifact"] = str(args.deploy_artifact).strip()
745
+ if _nonempty_str(getattr(args, "artifact_hash", None)):
746
+ entry["sha256"] = str(args.artifact_hash).strip()
747
+ entry["testsExecuted"] = bool(getattr(args, "tests_executed", False))
748
+ if _nonempty_str(getattr(args, "tests_reused_from", None)):
749
+ entry["testsReusedFrom"] = str(args.tests_reused_from).strip()
750
+
545
751
  ledger["validations"][verification] = entry
546
752
  if "changeName" not in ledger:
547
753
  ledger["changeName"] = change_dir.name
@@ -567,6 +773,21 @@ def cmd_record(args: argparse.Namespace) -> int:
567
773
  return 0
568
774
 
569
775
 
776
+ def cmd_diff_hash(args: argparse.Namespace) -> int:
777
+ as_json = bool(args.json)
778
+ repo_raw = getattr(args, "repo", None)
779
+ repo = Path(repo_raw).expanduser().resolve() if repo_raw else Path.cwd().resolve()
780
+ base = getattr(args, "base", None)
781
+ try:
782
+ diff_hash, meta = compute_diff_hash(repo, base=base)
783
+ except (OSError, RuntimeError) as exc:
784
+ return emit_error(str(exc), as_json=as_json)
785
+ payload = {"ok": True, "action": "diff-hash", "diffHash": diff_hash}
786
+ payload.update(meta)
787
+ emit_json(payload, as_json=as_json)
788
+ return 0
789
+
790
+
570
791
  def build_parser() -> argparse.ArgumentParser:
571
792
  parser = argparse.ArgumentParser(
572
793
  prog="harness_ledger.py",
@@ -630,6 +851,21 @@ def build_parser() -> argparse.ArgumentParser:
630
851
  default=None,
631
852
  help="optional command to compare against ledger entry",
632
853
  )
854
+ p_reuse.add_argument(
855
+ "--toolchain-hash",
856
+ default=None,
857
+ help="optional toolchain hash to compare against ledger entry (UT-017)",
858
+ )
859
+ p_reuse.add_argument(
860
+ "--profile-hash",
861
+ default=None,
862
+ help="optional profile hash to compare against ledger entry (UT-017)",
863
+ )
864
+ p_reuse.add_argument(
865
+ "--environment-hash",
866
+ default=None,
867
+ help="optional environment hash to compare against ledger entry (UT-017)",
868
+ )
633
869
  p_reuse.set_defaults(func=cmd_can_reuse)
634
870
 
635
871
  p_record = sub.add_parser("record", parents=[shared_json], help="write validation result into ledger")
@@ -656,8 +892,38 @@ def build_parser() -> argparse.ArgumentParser:
656
892
  default=None,
657
893
  help="optional scope (default module when absent on new entries)",
658
894
  )
895
+ p_record.add_argument(
896
+ "--coverage",
897
+ default=None,
898
+ help="optional coverage lattice value (incremental|module|module-am|full); derived when absent",
899
+ )
900
+ p_record.add_argument("--toolchain-hash", default=None)
901
+ p_record.add_argument("--profile-hash", default=None)
902
+ p_record.add_argument("--environment-hash", default=None)
903
+ p_record.add_argument("--deploy-artifact", default=None, help="package: built artifact path")
904
+ p_record.add_argument("--artifact-hash", default=None, help="package: artifact sha256")
905
+ p_record.add_argument(
906
+ "--tests-executed",
907
+ type=lambda v: str(v).lower() in ("1", "true", "yes", "y"),
908
+ default=False,
909
+ help="package: whether tests ran in this package lifecycle",
910
+ )
911
+ p_record.add_argument(
912
+ "--tests-reused-from",
913
+ default=None,
914
+ help="package: prior verifications reused when testsExecuted=false",
915
+ )
659
916
  p_record.set_defaults(func=cmd_record)
660
917
 
918
+ p_diff = sub.add_parser(
919
+ "diff-hash",
920
+ parents=[shared_json],
921
+ help="compute commit-invariant byte-level diff hash for a repo",
922
+ )
923
+ p_diff.add_argument("--repo", default=None, help="repo root (default: cwd)")
924
+ p_diff.add_argument("--base", default=None, help="base commit (default: root commit)")
925
+ p_diff.set_defaults(func=cmd_diff_hash)
926
+
661
927
  return parser
662
928
 
663
929