@hunter-harness/workflow-harness 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) 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 +1 -1
  6. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  7. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  8. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +2 -1
  9. package/harness/bundles/general/claude-code/harness-review/SKILL.md +5 -1
  10. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  11. package/harness/bundles/general/claude-code/harness-run/checklist.md +1 -1
  12. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +2 -2
  13. package/harness/bundles/general/claude-code/harness-submit/checklist.md +30 -6
  14. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
  15. package/harness/bundles/general/claude-code/harness-test/SKILL.md +2 -2
  16. package/harness/bundles/general/claude-code/harness-test/checklist.md +1 -1
  17. package/harness/bundles/general/claude-code/harness-test/pitfalls.md +16 -0
  18. package/harness/bundles/general/claude-code/harness-test/scripts/runtime-helpers.mjs +216 -0
  19. package/harness/bundles/general/claude-code/protocols/archive-report-protocol.md +1 -1
  20. package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +55 -2
  21. package/harness/bundles/general/claude-code/protocols/report-pipeline-protocol.md +1 -8
  22. package/harness/bundles/general/claude-code/protocols/sensitive-info-protocol.md +13 -0
  23. package/harness/bundles/general/claude-code/protocols/state-layout-protocol.md +24 -0
  24. package/harness/bundles/general/claude-code/scripts/harness_archive.py +31 -14
  25. package/harness/bundles/general/claude-code/scripts/harness_check_gate.py +111 -0
  26. package/harness/bundles/general/claude-code/scripts/harness_deploy.py +179 -4
  27. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +269 -3
  28. package/harness/bundles/general/claude-code/scripts/harness_preflight.py +72 -382
  29. package/harness/bundles/general/claude-code/scripts/harness_profile.py +742 -0
  30. package/harness/bundles/general/claude-code/scripts/harness_service.py +99 -2
  31. package/harness/bundles/general/claude-code/scripts/harness_state.py +179 -0
  32. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  33. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
  34. package/harness/bundles/general/codebuddy/harness-archive/reference.md +2 -8
  35. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +2 -1
  36. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  37. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  38. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  39. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +2 -1
  40. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +5 -1
  41. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  42. package/harness/bundles/general/codebuddy/harness-run/checklist.md +1 -1
  43. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +2 -2
  44. package/harness/bundles/general/codebuddy/harness-submit/checklist.md +30 -6
  45. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
  46. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +2 -2
  47. package/harness/bundles/general/codebuddy/harness-test/checklist.md +1 -1
  48. package/harness/bundles/general/codebuddy/harness-test/pitfalls.md +16 -0
  49. package/harness/bundles/general/codebuddy/harness-test/scripts/runtime-helpers.mjs +216 -0
  50. package/harness/bundles/general/codebuddy/protocols/archive-report-protocol.md +1 -1
  51. package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +55 -2
  52. package/harness/bundles/general/codebuddy/protocols/report-pipeline-protocol.md +1 -8
  53. package/harness/bundles/general/codebuddy/protocols/sensitive-info-protocol.md +13 -0
  54. package/harness/bundles/general/codebuddy/protocols/state-layout-protocol.md +24 -0
  55. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +31 -14
  56. package/harness/bundles/general/codebuddy/scripts/harness_check_gate.py +111 -0
  57. package/harness/bundles/general/codebuddy/scripts/harness_deploy.py +179 -4
  58. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +269 -3
  59. package/harness/bundles/general/codebuddy/scripts/harness_preflight.py +72 -382
  60. package/harness/bundles/general/codebuddy/scripts/harness_profile.py +742 -0
  61. package/harness/bundles/general/codebuddy/scripts/harness_service.py +99 -2
  62. package/harness/bundles/general/codebuddy/scripts/harness_state.py +179 -0
  63. package/harness/bundles/general/codex/.harness-build.json +1 -1
  64. package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
  65. package/harness/bundles/general/codex/harness-archive/reference.md +2 -8
  66. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +2 -1
  67. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
  68. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  69. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  70. package/harness/bundles/general/codex/harness-plan/SKILL.md +2 -1
  71. package/harness/bundles/general/codex/harness-review/SKILL.md +5 -1
  72. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  73. package/harness/bundles/general/codex/harness-run/checklist.md +1 -1
  74. package/harness/bundles/general/codex/harness-submit/SKILL.md +2 -2
  75. package/harness/bundles/general/codex/harness-submit/checklist.md +30 -6
  76. package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
  77. package/harness/bundles/general/codex/harness-test/SKILL.md +2 -2
  78. package/harness/bundles/general/codex/harness-test/checklist.md +1 -1
  79. package/harness/bundles/general/codex/harness-test/pitfalls.md +16 -0
  80. package/harness/bundles/general/codex/harness-test/scripts/runtime-helpers.mjs +216 -0
  81. package/harness/bundles/general/codex/protocols/archive-report-protocol.md +1 -1
  82. package/harness/bundles/general/codex/protocols/ledger-protocol.md +55 -2
  83. package/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +1 -8
  84. package/harness/bundles/general/codex/protocols/sensitive-info-protocol.md +13 -0
  85. package/harness/bundles/general/codex/protocols/state-layout-protocol.md +24 -0
  86. package/harness/bundles/general/codex/scripts/harness_archive.py +31 -14
  87. package/harness/bundles/general/codex/scripts/harness_check_gate.py +111 -0
  88. package/harness/bundles/general/codex/scripts/harness_deploy.py +179 -4
  89. package/harness/bundles/general/codex/scripts/harness_ledger.py +269 -3
  90. package/harness/bundles/general/codex/scripts/harness_preflight.py +72 -382
  91. package/harness/bundles/general/codex/scripts/harness_profile.py +742 -0
  92. package/harness/bundles/general/codex/scripts/harness_service.py +99 -2
  93. package/harness/bundles/general/codex/scripts/harness_state.py +179 -0
  94. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  95. package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
  96. package/harness/bundles/general/cursor/harness-archive/reference.md +2 -8
  97. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +2 -1
  98. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  99. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  100. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  101. package/harness/bundles/general/cursor/harness-plan/SKILL.md +2 -1
  102. package/harness/bundles/general/cursor/harness-review/SKILL.md +5 -1
  103. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  104. package/harness/bundles/general/cursor/harness-run/checklist.md +1 -1
  105. package/harness/bundles/general/cursor/harness-submit/SKILL.md +2 -2
  106. package/harness/bundles/general/cursor/harness-submit/checklist.md +30 -6
  107. package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
  108. package/harness/bundles/general/cursor/harness-test/SKILL.md +2 -2
  109. package/harness/bundles/general/cursor/harness-test/checklist.md +1 -1
  110. package/harness/bundles/general/cursor/harness-test/pitfalls.md +16 -0
  111. package/harness/bundles/general/cursor/harness-test/scripts/runtime-helpers.mjs +216 -0
  112. package/harness/bundles/general/cursor/protocols/archive-report-protocol.md +1 -1
  113. package/harness/bundles/general/cursor/protocols/ledger-protocol.md +55 -2
  114. package/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +1 -8
  115. package/harness/bundles/general/cursor/protocols/sensitive-info-protocol.md +13 -0
  116. package/harness/bundles/general/cursor/protocols/state-layout-protocol.md +24 -0
  117. package/harness/bundles/general/cursor/scripts/harness_archive.py +31 -14
  118. package/harness/bundles/general/cursor/scripts/harness_check_gate.py +111 -0
  119. package/harness/bundles/general/cursor/scripts/harness_deploy.py +179 -4
  120. package/harness/bundles/general/cursor/scripts/harness_ledger.py +269 -3
  121. package/harness/bundles/general/cursor/scripts/harness_preflight.py +72 -382
  122. package/harness/bundles/general/cursor/scripts/harness_profile.py +742 -0
  123. package/harness/bundles/general/cursor/scripts/harness_service.py +99 -2
  124. package/harness/bundles/general/cursor/scripts/harness_state.py +179 -0
  125. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  126. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  127. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
  128. package/harness/bundles/java/claude-code/harness-archive/reference.md +2 -8
  129. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +2 -1
  130. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  131. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  132. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  133. package/harness/bundles/java/claude-code/harness-package/SKILL.md +3 -3
  134. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +2 -1
  135. package/harness/bundles/java/claude-code/harness-review/SKILL.md +5 -1
  136. package/harness/bundles/java/claude-code/harness-run/SKILL.md +4 -4
  137. package/harness/bundles/java/claude-code/harness-run/checklist.md +3 -1
  138. package/harness/bundles/java/claude-code/harness-run/reference.md +6 -0
  139. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +3 -3
  140. package/harness/bundles/java/claude-code/harness-submit/checklist.md +30 -6
  141. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
  142. package/harness/bundles/java/claude-code/harness-test/SKILL.md +5 -5
  143. package/harness/bundles/java/claude-code/harness-test/checklist.md +3 -1
  144. package/harness/bundles/java/claude-code/harness-test/pitfalls.md +16 -0
  145. package/harness/bundles/java/claude-code/harness-test/reference.md +2 -0
  146. package/harness/bundles/java/claude-code/harness-test/scripts/runtime-helpers.mjs +216 -0
  147. package/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +1 -1
  148. package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +55 -2
  149. package/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +1 -8
  150. package/harness/bundles/java/claude-code/protocols/sensitive-info-protocol.md +13 -0
  151. package/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +24 -0
  152. package/harness/bundles/java/claude-code/scripts/harness_archive.py +31 -14
  153. package/harness/bundles/java/claude-code/scripts/harness_check_gate.py +111 -0
  154. package/harness/bundles/java/claude-code/scripts/harness_deploy.py +179 -4
  155. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +269 -3
  156. package/harness/bundles/java/claude-code/scripts/harness_preflight.py +72 -382
  157. package/harness/bundles/java/claude-code/scripts/harness_profile.py +742 -0
  158. package/harness/bundles/java/claude-code/scripts/harness_service.py +99 -2
  159. package/harness/bundles/java/claude-code/scripts/harness_state.py +179 -0
  160. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  161. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  162. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
  163. package/harness/bundles/java/codebuddy/harness-archive/reference.md +2 -8
  164. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +2 -1
  165. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  166. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  167. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  168. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +3 -3
  169. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +2 -1
  170. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +5 -1
  171. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +4 -4
  172. package/harness/bundles/java/codebuddy/harness-run/checklist.md +3 -1
  173. package/harness/bundles/java/codebuddy/harness-run/reference.md +6 -0
  174. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +3 -3
  175. package/harness/bundles/java/codebuddy/harness-submit/checklist.md +30 -6
  176. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
  177. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +5 -5
  178. package/harness/bundles/java/codebuddy/harness-test/checklist.md +3 -1
  179. package/harness/bundles/java/codebuddy/harness-test/pitfalls.md +16 -0
  180. package/harness/bundles/java/codebuddy/harness-test/reference.md +2 -0
  181. package/harness/bundles/java/codebuddy/harness-test/scripts/runtime-helpers.mjs +216 -0
  182. package/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +1 -1
  183. package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +55 -2
  184. package/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +1 -8
  185. package/harness/bundles/java/codebuddy/protocols/sensitive-info-protocol.md +13 -0
  186. package/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +24 -0
  187. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +31 -14
  188. package/harness/bundles/java/codebuddy/scripts/harness_check_gate.py +111 -0
  189. package/harness/bundles/java/codebuddy/scripts/harness_deploy.py +179 -4
  190. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +269 -3
  191. package/harness/bundles/java/codebuddy/scripts/harness_preflight.py +72 -382
  192. package/harness/bundles/java/codebuddy/scripts/harness_profile.py +742 -0
  193. package/harness/bundles/java/codebuddy/scripts/harness_service.py +99 -2
  194. package/harness/bundles/java/codebuddy/scripts/harness_state.py +179 -0
  195. package/harness/bundles/java/codex/.harness-build.json +1 -1
  196. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  197. package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
  198. package/harness/bundles/java/codex/harness-archive/reference.md +2 -8
  199. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +2 -1
  200. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
  201. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  202. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  203. package/harness/bundles/java/codex/harness-package/SKILL.md +3 -3
  204. package/harness/bundles/java/codex/harness-plan/SKILL.md +2 -1
  205. package/harness/bundles/java/codex/harness-review/SKILL.md +5 -1
  206. package/harness/bundles/java/codex/harness-run/SKILL.md +4 -4
  207. package/harness/bundles/java/codex/harness-run/checklist.md +3 -1
  208. package/harness/bundles/java/codex/harness-run/reference.md +6 -0
  209. package/harness/bundles/java/codex/harness-submit/SKILL.md +3 -3
  210. package/harness/bundles/java/codex/harness-submit/checklist.md +30 -6
  211. package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
  212. package/harness/bundles/java/codex/harness-test/SKILL.md +5 -5
  213. package/harness/bundles/java/codex/harness-test/checklist.md +3 -1
  214. package/harness/bundles/java/codex/harness-test/pitfalls.md +16 -0
  215. package/harness/bundles/java/codex/harness-test/reference.md +2 -0
  216. package/harness/bundles/java/codex/harness-test/scripts/runtime-helpers.mjs +216 -0
  217. package/harness/bundles/java/codex/protocols/archive-report-protocol.md +1 -1
  218. package/harness/bundles/java/codex/protocols/ledger-protocol.md +55 -2
  219. package/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +1 -8
  220. package/harness/bundles/java/codex/protocols/sensitive-info-protocol.md +13 -0
  221. package/harness/bundles/java/codex/protocols/state-layout-protocol.md +24 -0
  222. package/harness/bundles/java/codex/scripts/harness_archive.py +31 -14
  223. package/harness/bundles/java/codex/scripts/harness_check_gate.py +111 -0
  224. package/harness/bundles/java/codex/scripts/harness_deploy.py +179 -4
  225. package/harness/bundles/java/codex/scripts/harness_ledger.py +269 -3
  226. package/harness/bundles/java/codex/scripts/harness_preflight.py +72 -382
  227. package/harness/bundles/java/codex/scripts/harness_profile.py +742 -0
  228. package/harness/bundles/java/codex/scripts/harness_service.py +99 -2
  229. package/harness/bundles/java/codex/scripts/harness_state.py +179 -0
  230. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  231. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  232. package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
  233. package/harness/bundles/java/cursor/harness-archive/reference.md +2 -8
  234. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +2 -1
  235. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  236. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +474 -122
  237. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  238. package/harness/bundles/java/cursor/harness-package/SKILL.md +3 -3
  239. package/harness/bundles/java/cursor/harness-plan/SKILL.md +2 -1
  240. package/harness/bundles/java/cursor/harness-review/SKILL.md +5 -1
  241. package/harness/bundles/java/cursor/harness-run/SKILL.md +4 -4
  242. package/harness/bundles/java/cursor/harness-run/checklist.md +3 -1
  243. package/harness/bundles/java/cursor/harness-run/reference.md +6 -0
  244. package/harness/bundles/java/cursor/harness-submit/SKILL.md +3 -3
  245. package/harness/bundles/java/cursor/harness-submit/checklist.md +30 -6
  246. package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
  247. package/harness/bundles/java/cursor/harness-test/SKILL.md +5 -5
  248. package/harness/bundles/java/cursor/harness-test/checklist.md +3 -1
  249. package/harness/bundles/java/cursor/harness-test/pitfalls.md +16 -0
  250. package/harness/bundles/java/cursor/harness-test/reference.md +2 -0
  251. package/harness/bundles/java/cursor/harness-test/scripts/runtime-helpers.mjs +216 -0
  252. package/harness/bundles/java/cursor/protocols/archive-report-protocol.md +1 -1
  253. package/harness/bundles/java/cursor/protocols/ledger-protocol.md +55 -2
  254. package/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +1 -8
  255. package/harness/bundles/java/cursor/protocols/sensitive-info-protocol.md +13 -0
  256. package/harness/bundles/java/cursor/protocols/state-layout-protocol.md +24 -0
  257. package/harness/bundles/java/cursor/scripts/harness_archive.py +31 -14
  258. package/harness/bundles/java/cursor/scripts/harness_check_gate.py +111 -0
  259. package/harness/bundles/java/cursor/scripts/harness_deploy.py +179 -4
  260. package/harness/bundles/java/cursor/scripts/harness_ledger.py +269 -3
  261. package/harness/bundles/java/cursor/scripts/harness_preflight.py +72 -382
  262. package/harness/bundles/java/cursor/scripts/harness_profile.py +742 -0
  263. package/harness/bundles/java/cursor/scripts/harness_service.py +99 -2
  264. package/harness/bundles/java/cursor/scripts/harness_state.py +179 -0
  265. package/harness/manifests/general/claude-code.json +44 -28
  266. package/harness/manifests/general/codebuddy.json +44 -28
  267. package/harness/manifests/general/codex.json +44 -28
  268. package/harness/manifests/general/cursor.json +44 -28
  269. package/harness/manifests/java/claude-code.json +48 -32
  270. package/harness/manifests/java/codebuddy.json +48 -32
  271. package/harness/manifests/java/codex.json +48 -32
  272. package/harness/manifests/java/cursor.json +48 -32
  273. package/hunter-workflow-family.json +2 -2
  274. package/package.json +1 -1
@@ -24,14 +24,7 @@ python <skills-root>/scripts/harness_archive.py replay --archive-dir ".harness/a
24
24
  python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase "<phase>" --type <type> [--note "..."]
25
25
  ```
26
26
 
27
- 若项目安装 Hunter-Harness CLIcollect/validate 亦可使用(与 finalize 内嵌步骤等价):
28
-
29
- ```powershell
30
- powershell.exe -NoProfile -Command "npx hunter-harness report collect --change-id '<change-name>' --json"
31
- powershell.exe -NoProfile -Command "npx hunter-harness report validate --change-id '<change-name>' --json"
32
- ```
33
-
34
- CLI 不可用时,agent 仍必须按本协议生成等价的 `summary-data.json` 并执行一致性校验,不得退回手写汇总。
27
+ 归档报告流水线只有两个入口,均由 `harness_archive.py` 提供:`collect`/`render`/`validate` 是 `finalize` 的内嵌同进程步骤,**不再作为独立 CLI 暴露**(不存在 `report collect`/`report validate` 子命令)。`summary-data.json` 只能由 `finalize`(归档时)或 `replay`(回放时)生成;**禁止 agent 临场手写或拼装等价的 `summary-data.json`**。`harness_archive.py` 不可用时归档失败退出,不得退回手写汇总。
35
28
 
36
29
  ## events.ndjson
37
30
 
@@ -90,3 +90,16 @@ spring:
90
90
  - API 测试报告的持久化记录中
91
91
 
92
92
  > 对于 API 测试中获取的 token,在测试执行过程中可临时使用(如 Playwright 请求),但测试报告中必须用 `<TOKEN_REDACTED>` 替换。
93
+
94
+ ## 6. profile / 规则 / Markdown 凭据扫描
95
+
96
+ profile `build-profile.json`、规则文档、Skill Markdown **不得包含凭据明文值**(spec §3.4 凭据边界:配置只含 env key、cache path、角色,不含值)。发布前用 `harness-test/scripts/runtime-helpers.mjs` 的 `findCredentialValues(text)` 扫描:
97
+
98
+ - 命中 `password/token/secret/accessKey/Authorization: Bearer/jdbc password=` 等明文值 → ❌FAIL,必须改为占位符 `<*_REDACTED>` 或 env 引用 `${ENV}` / `$ENV`。
99
+ - 占位符 `<TOKEN_REDACTED>` 与 env 引用 `${TEST_TOKEN}` / `$DB_PASSWORD` 不报(credential 配置允许 env key)。
100
+
101
+ ```js
102
+ import { findCredentialValues } from '<skills-root>/harness-test/scripts/runtime-helpers.mjs';
103
+ const findings = findCredentialValues(fs.readFileSync('build-profile.json', 'utf8'));
104
+ if (findings.length > 0) { /* ❌FAIL: 列出 line/code/snippet,改为 env key 或占位符 */ }
105
+ ```
@@ -98,6 +98,30 @@ description: harness .harness 状态目录分层协议。用于减少根目录
98
98
 
99
99
  后续阶段应优先从该文件读取路径,避免手拼 change-name 导致路径拼写错误。
100
100
 
101
+ ## state-snapshot.json(cluster 3 §3.6)
102
+
103
+ `meta/state-snapshot.json`(由 `harness_state.py` 写入)集中记录 project/worktree root、HEAD/base、profile/rules/map/knowledge/diff 各段指纹与相关文件。plan/run/test/review/submit 读取该快照;失效时由脚本刷新,**不得仅凭缓存跳过代码或验证门禁**。
104
+
105
+ schema:
106
+
107
+ ```json
108
+ {
109
+ "schemaVersion": 1,
110
+ "generatedAt": "<iso>",
111
+ "changeName": "<change-name>",
112
+ "project": {"root": "<abs>"},
113
+ "worktree": {"root": "<abs>"},
114
+ "git": {"base": "<sha>", "head": "<sha>"},
115
+ "segments": {
116
+ "<segment>": {"fingerprint": "sha256:...", "files": ["..."], "capturedAt": "<iso>"}
117
+ }
118
+ }
119
+ ```
120
+
121
+ 各段独立失效:`is_segment_stale(snapshot, segment, current_fingerprint)` 比较单段指纹;段不存在 → stale(需采集)。`refresh_segments(..., segments=["profile"])` 只重采受影响段,其他段保留原 capturedAt/fingerprint(缓存失效只重采受影响段)。
122
+
123
+ segment 的文件集由调用方(各 skill)决定:`capture_snapshot(..., segment_files={"profile": [...], "rules": [...]})`。snapshot 只负责采集 + 比对 + 失效,不负责发现文件。git 段记录 base/head;diff 段指纹由调用方按需用 `harness_ledger.compute_diff_hash` 采集后填入 segment_files。
124
+
101
125
  ## archive 结构
102
126
 
103
127
  archive 后保持同样分层结构,不把 `.bak`、脚本、manifest、HTML 全部放在 archive 根目录。
@@ -102,11 +102,15 @@ def read_json(path: Path) -> Any:
102
102
 
103
103
  def write_json(path: Path, data: Any) -> None:
104
104
  path.parent.mkdir(parents=True, exist_ok=True)
105
- path.write_text(
106
- json.dumps(data, ensure_ascii=False, indent=2) + "\n",
107
- encoding="utf-8",
108
- newline="\n",
109
- )
105
+ text = json.dumps(data, ensure_ascii=False, indent=2) + "\n"
106
+ # 强制 LF,UTF-8 无 BOM;原子写 temp+os.replace(与 runtime-helpers.mjs 一致)。
107
+ tmp = path.with_name(f".{path.name}.{os.getpid()}.tmp")
108
+ try:
109
+ tmp.write_text(text, encoding="utf-8", newline="\n")
110
+ os.replace(tmp, path)
111
+ except BaseException:
112
+ tmp.unlink(missing_ok=True)
113
+ raise
110
114
 
111
115
 
112
116
  def sha256_file(path: Path) -> str:
@@ -490,16 +494,29 @@ def check_status(change_dir: Path) -> dict[str, Any]:
490
494
  if head_hash.startswith(expected_hash) or expected_hash.startswith(head_hash[:7]):
491
495
  checks["final_hash_match"] = True
492
496
  else:
493
- checks["final_hash_match"] = False
494
- blockers.append(
495
- {
496
- "code": "final-hash-mismatch",
497
- "message": (
498
- f"HEAD={head_hash} != expected={expected_hash} "
499
- f"(source={hash_source})"
500
- ),
501
- }
497
+ # main may have advanced since this change merged (a later change
498
+ # merged on top); the change's final hash is still pushed as long as
499
+ # it is an ancestor of HEAD. Strict == would block archiving whenever
500
+ # the repo moved on, which is the normal case in a multi-change
501
+ # workflow.
502
+ anc_code, _, _ = git_run(
503
+ project, "merge-base", "--is-ancestor", expected_hash, head_hash
502
504
  )
505
+ if anc_code == 0:
506
+ checks["final_hash_match"] = True
507
+ checks["final_hash_ancestor"] = True
508
+ else:
509
+ checks["final_hash_match"] = False
510
+ blockers.append(
511
+ {
512
+ "code": "final-hash-mismatch",
513
+ "message": (
514
+ f"HEAD={head_hash} != expected={expected_hash} "
515
+ f"(source={hash_source}) and expected is not an ancestor "
516
+ f"of HEAD (not pushed?)"
517
+ ),
518
+ }
519
+ )
503
520
  elif head_hash and expected_hash is None:
504
521
  warnings.append(
505
522
  {
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env python3
2
+ """Pre-push gate: skip `npm run check` when a recent check-ok marker matches
3
+ the tree of the commit being pushed.
4
+
5
+ Triple check (all must pass to skip, else exit 1 → hook runs npm run check):
6
+ 1. marker exists and its `ts` is within MAX_AGE_S (10 min) of now
7
+ 2. marker `command` == EXPECTED_CMD ("npm run check")
8
+ 3. current `git rev-parse HEAD^{tree}` == marker `treeHash`
9
+
10
+ The marker is written by harness-submit M5 after a green `npm run check` and
11
+ records `git write-tree`. This remains valid after commit because the new HEAD
12
+ has the same tree. Any mismatch (no marker, stale, command or tree changed)
13
+ forces a full re-run — the safe default. This is a local convenience only;
14
+ non-harness pushes have no marker and always run the check.
15
+
16
+ Exit 0 = skip (recent verified), exit 1 = run npm run check.
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import subprocess
22
+ import sys
23
+ import time
24
+ from pathlib import Path
25
+
26
+ ROOT = Path(__file__).resolve().parents[2] # harness/scripts/../.. = repo root
27
+ MARKER = ROOT / ".harness" / "check-ok.marker"
28
+ MAX_AGE_S = 600 # 10 minutes
29
+ EXPECTED_CMD = "npm run check"
30
+
31
+
32
+ def _git_output(args: list[str]) -> str | None:
33
+ try:
34
+ r = subprocess.run(
35
+ ["git", *args],
36
+ cwd=str(ROOT),
37
+ capture_output=True,
38
+ text=True,
39
+ timeout=5,
40
+ )
41
+ except (OSError, subprocess.SubprocessError):
42
+ return None
43
+ return r.stdout.strip() if r.returncode == 0 else None
44
+
45
+
46
+ def _current_index_tree() -> str | None:
47
+ return _git_output(["write-tree"])
48
+
49
+
50
+ def _current_head_tree() -> str | None:
51
+ return _git_output(["rev-parse", "HEAD^{tree}"])
52
+
53
+
54
+ def write_marker() -> int:
55
+ """Record the verified index tree so the marker survives the next commit."""
56
+ tree = _current_index_tree()
57
+ if tree is None:
58
+ return 1
59
+ MARKER.parent.mkdir(parents=True, exist_ok=True)
60
+ payload = {"ts": time.time(), "treeHash": tree, "command": EXPECTED_CMD}
61
+ MARKER.write_text(
62
+ json.dumps(payload, ensure_ascii=False) + "\n",
63
+ encoding="utf-8",
64
+ newline="\n",
65
+ )
66
+ print(f"check-ok marker written for tree {tree[:7]}")
67
+ return 0
68
+
69
+
70
+ def main(argv: list[str] | None = None) -> int:
71
+ import argparse
72
+
73
+ ap = argparse.ArgumentParser(description="pre-push check gate")
74
+ ap.add_argument(
75
+ "--write",
76
+ action="store_true",
77
+ help="write a check-ok marker for current HEAD (harness-submit M5)",
78
+ )
79
+ args = ap.parse_args(argv)
80
+ if args.write:
81
+ return write_marker()
82
+ if not MARKER.is_file():
83
+ return 1
84
+ try:
85
+ data = json.loads(MARKER.read_text(encoding="utf-8-sig"))
86
+ except (OSError, json.JSONDecodeError):
87
+ return 1
88
+ if not isinstance(data, dict):
89
+ return 1
90
+ ts = data.get("ts")
91
+ if not isinstance(ts, (int, float)) or time.time() - ts > MAX_AGE_S:
92
+ return 1
93
+ if data.get("command") != EXPECTED_CMD:
94
+ return 1
95
+ marker_tree = data.get("treeHash")
96
+ if not isinstance(marker_tree, str):
97
+ return 1
98
+ tree = _current_head_tree()
99
+ if tree is None or tree != marker_tree:
100
+ return 1
101
+ # All three checks passed: a green npm run check ran on this exact HEAD
102
+ # within the last 10 minutes. Safe to skip.
103
+ print(
104
+ f"pre-push: skipping npm run check (verified {int(time.time() - ts)}s ago "
105
+ f"for tree {tree[:7]})"
106
+ )
107
+ return 0
108
+
109
+
110
+ if __name__ == "__main__":
111
+ sys.exit(main())
@@ -14,6 +14,7 @@ import json
14
14
  import os
15
15
  import re
16
16
  import shutil
17
+ import subprocess
17
18
  import sys
18
19
  import uuid
19
20
  from pathlib import Path
@@ -33,6 +34,25 @@ HEADING_RE = re.compile(r"^(#{2,6})\s+(.+?)\s*$")
33
34
  FRAGMENT_HINT_RE = re.compile(r"^>\s*片段:\[\[shared/[^\]]+\]\]\s*.*$")
34
35
 
35
36
  BUILD_MARKER = ".harness-build.json"
37
+ # Install-side managed manifests record which files a prior install owned, so a
38
+ # later conservative install can delete removed managed files while preserving
39
+ # user-owned files (design §3.8 要点4). Skills manifest lives in the skills
40
+ # target dir; agents manifest lives in .claude/agents.
41
+ MANIFEST_NAME = ".harness-managed.json"
42
+ AGENTS_MANAGED_NAME = ".harness-managed-agents.json"
43
+ INSTALL_METADATA = frozenset({MANIFEST_NAME, AGENTS_MANAGED_NAME})
44
+
45
+
46
+ def _read_managed_set(path: Path) -> set[str]:
47
+ """Return the ``managedFiles`` set from a prior install manifest, or empty."""
48
+ if not path.is_file():
49
+ return set()
50
+ try:
51
+ data = json.loads(path.read_text(encoding="utf-8"))
52
+ except (json.JSONDecodeError, ValueError):
53
+ return set()
54
+ files = data.get("managedFiles") if isinstance(data, dict) else None
55
+ return set(files) if isinstance(files, list) else set()
36
56
 
37
57
  SKIP_DIR_NAMES = {
38
58
  "__pycache__",
@@ -270,6 +290,48 @@ def validate_build_paths(skills_root: Path, out_dir: Path) -> tuple[Path, Path]:
270
290
  return skills_root, out_dir
271
291
 
272
292
 
293
+ def _git_repo_root(start: Path) -> Path | None:
294
+ """Return the git toplevel containing ``start``, or None if not a git repo."""
295
+ try:
296
+ r = subprocess.run(
297
+ ["git", "rev-parse", "--show-toplevel"],
298
+ cwd=str(start),
299
+ capture_output=True,
300
+ text=True,
301
+ timeout=5,
302
+ )
303
+ except (OSError, subprocess.SubprocessError):
304
+ return None
305
+ if r.returncode != 0 or not r.stdout.strip():
306
+ return None
307
+ return Path(r.stdout.strip())
308
+
309
+
310
+ def _git_blob_sha(path: Path, repo_root: Path) -> str | None:
311
+ """Return the git blob sha for a tracked file (CRLF-normalized by .gitattributes),
312
+ or None if untracked / git unavailable. Caller falls back to working-copy sha256
313
+ for untracked build inputs (deterministic enough outside git's normalization)."""
314
+ try:
315
+ rel = path.resolve().relative_to(repo_root.resolve())
316
+ except ValueError:
317
+ return None
318
+ try:
319
+ r = subprocess.run(
320
+ ["git", "ls-files", "-s", "--", rel.as_posix()],
321
+ cwd=str(repo_root),
322
+ capture_output=True,
323
+ text=True,
324
+ timeout=5,
325
+ )
326
+ except (OSError, subprocess.SubprocessError):
327
+ return None
328
+ if r.returncode != 0 or not r.stdout.strip():
329
+ return None
330
+ # format: "<mode> <sha> <stage>\t<path>"
331
+ parts = r.stdout.strip().splitlines()[0].split()
332
+ return parts[1] if len(parts) >= 2 else None
333
+
334
+
273
335
  def core_content_hash(
274
336
  skills_root: Path,
275
337
  overlay_dir: Path | None,
@@ -298,11 +360,18 @@ def core_content_hash(
298
360
  files.extend(p for p in overlay_dir.rglob("*") if p.is_file())
299
361
  if agent_overlay_dir and agent_overlay_dir.is_dir():
300
362
  files.extend(p for p in agent_overlay_dir.rglob("*") if p.is_file())
363
+ skills_root_resolved = skills_root.resolve()
364
+ repo_root = _git_repo_root(skills_root_resolved)
301
365
  for f in sorted(set(files)):
302
- rel = f.resolve().relative_to(skills_root.resolve()).as_posix()
366
+ rel = f.resolve().relative_to(skills_root_resolved).as_posix()
303
367
  h.update(rel.encode("utf-8"))
304
368
  h.update(b"\0")
305
- h.update(sha256_file(f).encode("ascii"))
369
+ # Prefer the git blob sha: .gitattributes eol=lf normalization makes the
370
+ # hash independent of working-copy CRLF state (the CRLF working-copy drift
371
+ # that previously caused core hash mismatches across main/worktree). Fall
372
+ # back to working-tree bytes for untracked build inputs (templates, etc.).
373
+ blob = _git_blob_sha(f, repo_root) if repo_root else None
374
+ h.update((blob or sha256_file(f)).encode("ascii"))
306
375
  h.update(b"\0")
307
376
  return h.hexdigest()[:16]
308
377
 
@@ -560,10 +629,37 @@ def cmd_install(build_out: Path, project: Path, target: Path | None) -> dict[str
560
629
  dest = (target or project / ".claude" / "skills").resolve()
561
630
  if not (build_out / BUILD_MARKER).is_file():
562
631
  raise ValueError(f"install source is not a marked harness build: {build_out}")
632
+
633
+ # Managed set = real files in the build (exclude build marker). Recorded so a
634
+ # later conservative install can delete removed managed files and preserve
635
+ # user-owned files (design §3.8 要点4). Paths are relative to dest, which
636
+ # mirrors build_out (agents/ included because copy_tree keeps it there).
637
+ managed_new = {p for p in collect_files(build_out) if p != BUILD_MARKER}
638
+ managed_agents_new = {
639
+ p[len("agents/"):]
640
+ for p in managed_new
641
+ if p.startswith("agents/") and "/" not in p[len("agents/"):]
642
+ }
643
+
563
644
  backup: str | None = None
564
645
  staging = dest.parent / f".{dest.name}.staging-{uuid.uuid4().hex[:8]}"
565
646
  shutil.copytree(build_out, staging)
566
647
  if dest.exists() and any(dest.iterdir()):
648
+ managed_old = _read_managed_set(dest / MANIFEST_NAME)
649
+ # Preserve user-owned files: anything in dest that was NOT managed by a
650
+ # prior install is copied into staging (never overwriting managed files
651
+ # that staging already carries from build_out). Removed managed files
652
+ # (in managed_old but not managed_new) are simply not carried over.
653
+ for rel in collect_files(dest):
654
+ if rel in (BUILD_MARKER, MANIFEST_NAME) or rel in INSTALL_METADATA:
655
+ continue
656
+ if rel in managed_old:
657
+ continue
658
+ dst = staging / rel
659
+ if dst.exists():
660
+ continue
661
+ dst.parent.mkdir(parents=True, exist_ok=True)
662
+ shutil.copy2(dest / rel, dst)
567
663
  stamp = dt.datetime.now().strftime("%Y%m%d-%H%M%S")
568
664
  backup_path = dest.parent / f"skills-backup-{stamp}"
569
665
  os.replace(dest, backup_path)
@@ -576,12 +672,41 @@ def cmd_install(build_out: Path, project: Path, target: Path | None) -> dict[str
576
672
  os.replace(Path(backup), dest)
577
673
  raise
578
674
 
675
+ # Record the managed set so the next conservative install can distinguish
676
+ # managed vs user-owned files.
677
+ (dest / MANIFEST_NAME).write_text(
678
+ json.dumps(
679
+ {"schemaVersion": 1, "managedFiles": sorted(managed_new)},
680
+ ensure_ascii=False,
681
+ indent=2,
682
+ )
683
+ + "\n",
684
+ encoding="utf-8",
685
+ newline="\n",
686
+ )
687
+
579
688
  agents_src = build_out / "agents"
580
689
  agents_dest = project / ".claude" / "agents"
581
690
  if agents_src.is_dir():
582
691
  agents_dest.mkdir(parents=True, exist_ok=True)
692
+ agents_old = _read_managed_set(agents_dest / AGENTS_MANAGED_NAME)
693
+ # Delete managed agents removed since the prior install; user agents
694
+ # (never in a managed set) are left untouched.
695
+ for name in list(agents_old):
696
+ if name not in managed_agents_new:
697
+ (agents_dest / name).unlink(missing_ok=True)
583
698
  for agent in agents_src.glob("*.md"):
584
699
  shutil.copy2(agent, agents_dest / agent.name)
700
+ (agents_dest / AGENTS_MANAGED_NAME).write_text(
701
+ json.dumps(
702
+ {"schemaVersion": 1, "managedFiles": sorted(managed_agents_new)},
703
+ ensure_ascii=False,
704
+ indent=2,
705
+ )
706
+ + "\n",
707
+ encoding="utf-8",
708
+ newline="\n",
709
+ )
585
710
 
586
711
  return {
587
712
  "ok": True,
@@ -613,11 +738,14 @@ def cmd_diff(build_out: Path, project: Path, target: Path | None) -> dict[str, A
613
738
  current = collect_files(installed)
614
739
  outdated = [p for p, h in built.items() if p in current and current[p] != h]
615
740
  missing = [p for p in built if p not in current]
616
- extra = [p for p in current if p not in built]
741
+ # extra includes install-side managed manifests only as metadata, so they
742
+ # are excluded from the extra set; every other untracked file is a real
743
+ # extra and must mark the install stale (design §3.8 要点3).
744
+ extra = [p for p in current if p not in built and p not in INSTALL_METADATA]
617
745
  return {
618
746
  "ok": True,
619
747
  "action": "diff",
620
- "stale": bool(outdated or missing),
748
+ "stale": bool(outdated or missing or extra),
621
749
  "outdated": sorted(outdated),
622
750
  "missing": sorted(missing),
623
751
  "extra": sorted(extra),
@@ -625,6 +753,35 @@ def cmd_diff(build_out: Path, project: Path, target: Path | None) -> dict[str, A
625
753
  }
626
754
 
627
755
 
756
+ def cmd_validate_manifest(
757
+ bundle_dir: Path, manifest_entries: list[dict[str, Any]]
758
+ ) -> dict[str, Any]:
759
+ """Compare a bundle directory's actual file set against the manifest's
760
+ declared set. Both missing (declared but absent) and extra (present but
761
+ undeclared) fail validation (design §3.8 要点2)."""
762
+ bundle_dir = bundle_dir.resolve()
763
+ actual = collect_files(bundle_dir)
764
+ declared: dict[str, str] = {}
765
+ for entry in manifest_entries:
766
+ path = entry.get("path")
767
+ sha = entry.get("sha256")
768
+ if isinstance(path, str) and isinstance(sha, str):
769
+ declared[path] = sha
770
+ missing = sorted(p for p in declared if p not in actual)
771
+ extra = sorted(p for p in actual if p not in declared)
772
+ hash_mismatch = sorted(
773
+ p for p in declared if p in actual and actual[p] != declared[p]
774
+ )
775
+ return {
776
+ "ok": not (missing or extra or hash_mismatch),
777
+ "action": "validate-manifest",
778
+ "missing": missing,
779
+ "extra": extra,
780
+ "hashMismatch": hash_mismatch,
781
+ "comparedAt": now_iso(),
782
+ }
783
+
784
+
628
785
  def build_parser() -> argparse.ArgumentParser:
629
786
  p = argparse.ArgumentParser(description="Harness skills deploy (build/install/diff)")
630
787
  sub = p.add_subparsers(dest="command", required=True)
@@ -647,6 +804,13 @@ def build_parser() -> argparse.ArgumentParser:
647
804
  d.add_argument("--project", type=Path, required=True)
648
805
  d.add_argument("--target", type=Path)
649
806
  d.add_argument("--json", action="store_true")
807
+
808
+ v = sub.add_parser(
809
+ "validate-manifest", help="Validate bundle dir vs manifest (missing/extra/hash)"
810
+ )
811
+ v.add_argument("--bundle", type=Path, required=True)
812
+ v.add_argument("--manifest", type=Path, required=True)
813
+ v.add_argument("--json", action="store_true")
650
814
  return p
651
815
 
652
816
 
@@ -662,6 +826,17 @@ def main(argv: list[str] | None = None) -> int:
662
826
  if args.command == "diff":
663
827
  result = cmd_diff(args.from_dir, args.project, args.target)
664
828
  return emit_json(result) if args.json else 0
829
+ if args.command == "validate-manifest":
830
+ manifest_data = json.loads(args.manifest.read_text(encoding="utf-8"))
831
+ entries = (
832
+ manifest_data.get("files", [])
833
+ if isinstance(manifest_data, dict)
834
+ else []
835
+ )
836
+ result = cmd_validate_manifest(args.bundle, entries)
837
+ if args.json:
838
+ return emit_json(result)
839
+ return 0 if result["ok"] else 1
665
840
  except (FileNotFoundError, KeyError, RuntimeError, ValueError) as exc:
666
841
  if getattr(args, "json", False):
667
842
  return emit_json({"ok": False, "error": str(exc)}, ok=False)