@hunter-harness/workflow-harness 0.2.5 → 0.2.7

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 (270) 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 +169 -0
  3. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +7 -2
  4. package/harness/bundles/general/claude-code/harness-archive/reference.md +1 -1
  5. package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +78 -155
  6. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +4 -2
  7. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +5 -3
  8. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  9. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  10. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +6 -2
  11. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +8 -3
  12. package/harness/bundles/general/claude-code/harness-review/SKILL.md +8 -3
  13. package/harness/bundles/general/claude-code/harness-run/SKILL.md +13 -7
  14. package/harness/bundles/general/claude-code/harness-run/checklist.md +2 -2
  15. package/harness/bundles/general/claude-code/harness-run/reference.md +6 -3
  16. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +11 -6
  17. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +5 -3
  18. package/harness/bundles/general/claude-code/harness-test/SKILL.md +12 -3
  19. package/harness/bundles/general/claude-code/harness-test/reference.md +1 -1
  20. package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +1 -1
  21. package/harness/bundles/general/claude-code/protocols/report-pipeline-protocol.md +11 -4
  22. package/harness/bundles/general/claude-code/scripts/harness_apidoc.py +53 -0
  23. package/harness/bundles/general/claude-code/scripts/harness_archive.py +231 -48
  24. package/harness/bundles/general/claude-code/scripts/harness_change.py +854 -0
  25. package/harness/bundles/general/claude-code/scripts/harness_events.py +134 -40
  26. package/harness/bundles/general/claude-code/scripts/harness_gate.py +1038 -0
  27. package/harness/bundles/general/claude-code/scripts/harness_preflight.py +46 -3
  28. package/harness/bundles/general/claude-code/scripts/harness_profile.py +2 -2
  29. package/harness/bundles/general/claude-code/scripts/harness_service.py +34 -1
  30. package/harness/bundles/general/claude-code/scripts/harness_state.py +148 -0
  31. package/harness/bundles/general/claude-code/scripts/harness_test_guard.py +210 -14
  32. package/harness/bundles/general/claude-code/scripts/harness_workflow_policy.py +160 -0
  33. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  34. package/harness/bundles/general/codebuddy/contracts/workflow-policy.json +169 -0
  35. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +7 -2
  36. package/harness/bundles/general/codebuddy/harness-archive/reference.md +1 -1
  37. package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +78 -155
  38. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +4 -2
  39. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +5 -3
  40. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  41. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  42. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +6 -2
  43. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +8 -3
  44. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +8 -3
  45. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +13 -7
  46. package/harness/bundles/general/codebuddy/harness-run/checklist.md +2 -2
  47. package/harness/bundles/general/codebuddy/harness-run/reference.md +6 -3
  48. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +11 -6
  49. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +5 -3
  50. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +12 -3
  51. package/harness/bundles/general/codebuddy/harness-test/reference.md +1 -1
  52. package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +1 -1
  53. package/harness/bundles/general/codebuddy/protocols/report-pipeline-protocol.md +11 -4
  54. package/harness/bundles/general/codebuddy/scripts/harness_apidoc.py +53 -0
  55. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +231 -48
  56. package/harness/bundles/general/codebuddy/scripts/harness_change.py +854 -0
  57. package/harness/bundles/general/codebuddy/scripts/harness_events.py +134 -40
  58. package/harness/bundles/general/codebuddy/scripts/harness_gate.py +1038 -0
  59. package/harness/bundles/general/codebuddy/scripts/harness_preflight.py +46 -3
  60. package/harness/bundles/general/codebuddy/scripts/harness_profile.py +2 -2
  61. package/harness/bundles/general/codebuddy/scripts/harness_service.py +34 -1
  62. package/harness/bundles/general/codebuddy/scripts/harness_state.py +148 -0
  63. package/harness/bundles/general/codebuddy/scripts/harness_test_guard.py +210 -14
  64. package/harness/bundles/general/codebuddy/scripts/harness_workflow_policy.py +160 -0
  65. package/harness/bundles/general/codex/.harness-build.json +1 -1
  66. package/harness/bundles/general/codex/contracts/workflow-policy.json +169 -0
  67. package/harness/bundles/general/codex/harness-archive/SKILL.md +7 -2
  68. package/harness/bundles/general/codex/harness-archive/reference.md +1 -1
  69. package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +78 -155
  70. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +4 -2
  71. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +5 -3
  72. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  73. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  74. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +6 -2
  75. package/harness/bundles/general/codex/harness-plan/SKILL.md +8 -3
  76. package/harness/bundles/general/codex/harness-review/SKILL.md +7 -2
  77. package/harness/bundles/general/codex/harness-run/SKILL.md +13 -7
  78. package/harness/bundles/general/codex/harness-run/checklist.md +2 -2
  79. package/harness/bundles/general/codex/harness-run/reference.md +6 -3
  80. package/harness/bundles/general/codex/harness-submit/SKILL.md +11 -6
  81. package/harness/bundles/general/codex/harness-sync/SKILL.md +5 -3
  82. package/harness/bundles/general/codex/harness-test/SKILL.md +12 -3
  83. package/harness/bundles/general/codex/harness-test/reference.md +1 -1
  84. package/harness/bundles/general/codex/protocols/ledger-protocol.md +1 -1
  85. package/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +11 -4
  86. package/harness/bundles/general/codex/scripts/harness_apidoc.py +53 -0
  87. package/harness/bundles/general/codex/scripts/harness_archive.py +231 -48
  88. package/harness/bundles/general/codex/scripts/harness_change.py +854 -0
  89. package/harness/bundles/general/codex/scripts/harness_events.py +134 -40
  90. package/harness/bundles/general/codex/scripts/harness_gate.py +1038 -0
  91. package/harness/bundles/general/codex/scripts/harness_preflight.py +46 -3
  92. package/harness/bundles/general/codex/scripts/harness_profile.py +2 -2
  93. package/harness/bundles/general/codex/scripts/harness_service.py +34 -1
  94. package/harness/bundles/general/codex/scripts/harness_state.py +148 -0
  95. package/harness/bundles/general/codex/scripts/harness_test_guard.py +210 -14
  96. package/harness/bundles/general/codex/scripts/harness_workflow_policy.py +160 -0
  97. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  98. package/harness/bundles/general/cursor/contracts/workflow-policy.json +169 -0
  99. package/harness/bundles/general/cursor/harness-archive/SKILL.md +7 -2
  100. package/harness/bundles/general/cursor/harness-archive/reference.md +1 -1
  101. package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +78 -155
  102. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +4 -2
  103. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +5 -3
  104. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  105. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  106. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +6 -2
  107. package/harness/bundles/general/cursor/harness-plan/SKILL.md +8 -3
  108. package/harness/bundles/general/cursor/harness-review/SKILL.md +7 -2
  109. package/harness/bundles/general/cursor/harness-run/SKILL.md +13 -7
  110. package/harness/bundles/general/cursor/harness-run/checklist.md +2 -2
  111. package/harness/bundles/general/cursor/harness-run/reference.md +6 -3
  112. package/harness/bundles/general/cursor/harness-submit/SKILL.md +11 -6
  113. package/harness/bundles/general/cursor/harness-sync/SKILL.md +5 -3
  114. package/harness/bundles/general/cursor/harness-test/SKILL.md +12 -3
  115. package/harness/bundles/general/cursor/harness-test/reference.md +1 -1
  116. package/harness/bundles/general/cursor/protocols/ledger-protocol.md +1 -1
  117. package/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +11 -4
  118. package/harness/bundles/general/cursor/scripts/harness_apidoc.py +53 -0
  119. package/harness/bundles/general/cursor/scripts/harness_archive.py +231 -48
  120. package/harness/bundles/general/cursor/scripts/harness_change.py +854 -0
  121. package/harness/bundles/general/cursor/scripts/harness_events.py +134 -40
  122. package/harness/bundles/general/cursor/scripts/harness_gate.py +1038 -0
  123. package/harness/bundles/general/cursor/scripts/harness_preflight.py +46 -3
  124. package/harness/bundles/general/cursor/scripts/harness_profile.py +2 -2
  125. package/harness/bundles/general/cursor/scripts/harness_service.py +34 -1
  126. package/harness/bundles/general/cursor/scripts/harness_state.py +148 -0
  127. package/harness/bundles/general/cursor/scripts/harness_test_guard.py +210 -14
  128. package/harness/bundles/general/cursor/scripts/harness_workflow_policy.py +160 -0
  129. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  130. package/harness/bundles/java/claude-code/contracts/workflow-policy.json +169 -0
  131. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +11 -2
  132. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +7 -2
  133. package/harness/bundles/java/claude-code/harness-archive/reference.md +1 -1
  134. package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +78 -155
  135. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +4 -2
  136. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +5 -3
  137. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  138. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  139. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +6 -2
  140. package/harness/bundles/java/claude-code/harness-package/SKILL.md +10 -4
  141. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +8 -3
  142. package/harness/bundles/java/claude-code/harness-review/SKILL.md +8 -3
  143. package/harness/bundles/java/claude-code/harness-run/SKILL.md +13 -7
  144. package/harness/bundles/java/claude-code/harness-run/reference.md +1 -1
  145. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +11 -6
  146. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +5 -3
  147. package/harness/bundles/java/claude-code/harness-test/SKILL.md +12 -3
  148. package/harness/bundles/java/claude-code/harness-test/reference.md +1 -1
  149. package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +1 -1
  150. package/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +11 -4
  151. package/harness/bundles/java/claude-code/scripts/harness_apidoc.py +53 -0
  152. package/harness/bundles/java/claude-code/scripts/harness_archive.py +231 -48
  153. package/harness/bundles/java/claude-code/scripts/harness_change.py +854 -0
  154. package/harness/bundles/java/claude-code/scripts/harness_events.py +134 -40
  155. package/harness/bundles/java/claude-code/scripts/harness_gate.py +1038 -0
  156. package/harness/bundles/java/claude-code/scripts/harness_preflight.py +46 -3
  157. package/harness/bundles/java/claude-code/scripts/harness_profile.py +2 -2
  158. package/harness/bundles/java/claude-code/scripts/harness_service.py +34 -1
  159. package/harness/bundles/java/claude-code/scripts/harness_state.py +148 -0
  160. package/harness/bundles/java/claude-code/scripts/harness_test_guard.py +210 -14
  161. package/harness/bundles/java/claude-code/scripts/harness_workflow_policy.py +160 -0
  162. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  163. package/harness/bundles/java/codebuddy/contracts/workflow-policy.json +169 -0
  164. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +11 -2
  165. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +7 -2
  166. package/harness/bundles/java/codebuddy/harness-archive/reference.md +1 -1
  167. package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +78 -155
  168. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +4 -2
  169. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +5 -3
  170. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  171. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  172. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +6 -2
  173. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +10 -4
  174. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +8 -3
  175. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +8 -3
  176. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +13 -7
  177. package/harness/bundles/java/codebuddy/harness-run/reference.md +1 -1
  178. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +11 -6
  179. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +5 -3
  180. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +12 -3
  181. package/harness/bundles/java/codebuddy/harness-test/reference.md +1 -1
  182. package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +1 -1
  183. package/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +11 -4
  184. package/harness/bundles/java/codebuddy/scripts/harness_apidoc.py +53 -0
  185. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +231 -48
  186. package/harness/bundles/java/codebuddy/scripts/harness_change.py +854 -0
  187. package/harness/bundles/java/codebuddy/scripts/harness_events.py +134 -40
  188. package/harness/bundles/java/codebuddy/scripts/harness_gate.py +1038 -0
  189. package/harness/bundles/java/codebuddy/scripts/harness_preflight.py +46 -3
  190. package/harness/bundles/java/codebuddy/scripts/harness_profile.py +2 -2
  191. package/harness/bundles/java/codebuddy/scripts/harness_service.py +34 -1
  192. package/harness/bundles/java/codebuddy/scripts/harness_state.py +148 -0
  193. package/harness/bundles/java/codebuddy/scripts/harness_test_guard.py +210 -14
  194. package/harness/bundles/java/codebuddy/scripts/harness_workflow_policy.py +160 -0
  195. package/harness/bundles/java/codex/.harness-build.json +1 -1
  196. package/harness/bundles/java/codex/contracts/workflow-policy.json +169 -0
  197. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +11 -2
  198. package/harness/bundles/java/codex/harness-archive/SKILL.md +7 -2
  199. package/harness/bundles/java/codex/harness-archive/reference.md +1 -1
  200. package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +78 -155
  201. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +4 -2
  202. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +5 -3
  203. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  204. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  205. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +6 -2
  206. package/harness/bundles/java/codex/harness-package/SKILL.md +10 -4
  207. package/harness/bundles/java/codex/harness-plan/SKILL.md +8 -3
  208. package/harness/bundles/java/codex/harness-review/SKILL.md +7 -2
  209. package/harness/bundles/java/codex/harness-run/SKILL.md +13 -7
  210. package/harness/bundles/java/codex/harness-run/reference.md +1 -1
  211. package/harness/bundles/java/codex/harness-submit/SKILL.md +11 -6
  212. package/harness/bundles/java/codex/harness-sync/SKILL.md +5 -3
  213. package/harness/bundles/java/codex/harness-test/SKILL.md +12 -3
  214. package/harness/bundles/java/codex/harness-test/reference.md +1 -1
  215. package/harness/bundles/java/codex/protocols/ledger-protocol.md +1 -1
  216. package/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +11 -4
  217. package/harness/bundles/java/codex/scripts/harness_apidoc.py +53 -0
  218. package/harness/bundles/java/codex/scripts/harness_archive.py +231 -48
  219. package/harness/bundles/java/codex/scripts/harness_change.py +854 -0
  220. package/harness/bundles/java/codex/scripts/harness_events.py +134 -40
  221. package/harness/bundles/java/codex/scripts/harness_gate.py +1038 -0
  222. package/harness/bundles/java/codex/scripts/harness_preflight.py +46 -3
  223. package/harness/bundles/java/codex/scripts/harness_profile.py +2 -2
  224. package/harness/bundles/java/codex/scripts/harness_service.py +34 -1
  225. package/harness/bundles/java/codex/scripts/harness_state.py +148 -0
  226. package/harness/bundles/java/codex/scripts/harness_test_guard.py +210 -14
  227. package/harness/bundles/java/codex/scripts/harness_workflow_policy.py +160 -0
  228. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  229. package/harness/bundles/java/cursor/contracts/workflow-policy.json +169 -0
  230. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +11 -2
  231. package/harness/bundles/java/cursor/harness-archive/SKILL.md +7 -2
  232. package/harness/bundles/java/cursor/harness-archive/reference.md +1 -1
  233. package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +78 -155
  234. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +4 -2
  235. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +5 -3
  236. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
  237. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
  238. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +6 -2
  239. package/harness/bundles/java/cursor/harness-package/SKILL.md +10 -4
  240. package/harness/bundles/java/cursor/harness-plan/SKILL.md +8 -3
  241. package/harness/bundles/java/cursor/harness-review/SKILL.md +7 -2
  242. package/harness/bundles/java/cursor/harness-run/SKILL.md +13 -7
  243. package/harness/bundles/java/cursor/harness-run/reference.md +1 -1
  244. package/harness/bundles/java/cursor/harness-submit/SKILL.md +11 -6
  245. package/harness/bundles/java/cursor/harness-sync/SKILL.md +5 -3
  246. package/harness/bundles/java/cursor/harness-test/SKILL.md +12 -3
  247. package/harness/bundles/java/cursor/harness-test/reference.md +1 -1
  248. package/harness/bundles/java/cursor/protocols/ledger-protocol.md +1 -1
  249. package/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +11 -4
  250. package/harness/bundles/java/cursor/scripts/harness_apidoc.py +53 -0
  251. package/harness/bundles/java/cursor/scripts/harness_archive.py +231 -48
  252. package/harness/bundles/java/cursor/scripts/harness_change.py +854 -0
  253. package/harness/bundles/java/cursor/scripts/harness_events.py +134 -40
  254. package/harness/bundles/java/cursor/scripts/harness_gate.py +1038 -0
  255. package/harness/bundles/java/cursor/scripts/harness_preflight.py +46 -3
  256. package/harness/bundles/java/cursor/scripts/harness_profile.py +2 -2
  257. package/harness/bundles/java/cursor/scripts/harness_service.py +34 -1
  258. package/harness/bundles/java/cursor/scripts/harness_state.py +148 -0
  259. package/harness/bundles/java/cursor/scripts/harness_test_guard.py +210 -14
  260. package/harness/bundles/java/cursor/scripts/harness_workflow_policy.py +160 -0
  261. package/harness/manifests/general/claude-code.json +48 -28
  262. package/harness/manifests/general/codebuddy.json +48 -28
  263. package/harness/manifests/general/codex.json +48 -28
  264. package/harness/manifests/general/cursor.json +48 -28
  265. package/harness/manifests/java/claude-code.json +49 -29
  266. package/harness/manifests/java/codebuddy.json +49 -29
  267. package/harness/manifests/java/codex.json +49 -29
  268. package/harness/manifests/java/cursor.json +49 -29
  269. package/hunter-workflow-family.json +2 -2
  270. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  """Harness events.ndjson writer and execution-log renderer (D2).
3
3
 
4
4
  Subcommands:
5
- append — append one schema_version 2 event, then auto-render execution-log.md
5
+ append — append one schema_version 3 event, then auto-render execution-log.md
6
6
  render — full re-render of logs/execution-log.md from events.ndjson
7
7
  summary — phase durations, event counts, and issue list (JSON)
8
8
 
@@ -42,7 +42,7 @@ EVENT_TYPES = frozenset(
42
42
  }
43
43
  )
44
44
 
45
- SCHEMA_VERSION = 2
45
+ SCHEMA_VERSION = 3
46
46
  HEADER_LINE = (
47
47
  "本文件由 harness_events.py 自动渲染,请勿手工编辑;事实源为 events.ndjson"
48
48
  )
@@ -62,6 +62,13 @@ OPTIONAL_FIELDS = (
62
62
  "message",
63
63
  "decision",
64
64
  "reason",
65
+ "run_id",
66
+ "attempt",
67
+ "executor_tool",
68
+ "executor_agent",
69
+ "executor_model",
70
+ "handoff_from_tool",
71
+ "handoff_reason",
65
72
  )
66
73
 
67
74
 
@@ -120,7 +127,7 @@ def duration_ms_between(start: Any, end: Any) -> int | None:
120
127
 
121
128
 
122
129
  def normalize_event(raw: dict[str, Any]) -> dict[str, Any]:
123
- """Normalize schema_version 1/2 events for rendering and summary."""
130
+ """Normalize schema_version 1/2/3 events for rendering and summary."""
124
131
  event = dict(raw)
125
132
  version = event.get("schema_version", 1)
126
133
  try:
@@ -273,6 +280,15 @@ def build_event(args: argparse.Namespace, existing: list[dict[str, Any]]) -> dic
273
280
  if value is None:
274
281
  continue
275
282
  event[field] = value
283
+ environment_defaults = {
284
+ "run_id": "HUNTER_HARNESS_RUN_ID",
285
+ "executor_tool": "HUNTER_HARNESS_TOOL",
286
+ "executor_agent": "HUNTER_HARNESS_AGENT",
287
+ "executor_model": "HUNTER_HARNESS_MODEL",
288
+ }
289
+ for field, env_name in environment_defaults.items():
290
+ if field not in event and os.environ.get(env_name):
291
+ event[field] = os.environ[env_name]
276
292
  if "note" not in event:
277
293
  event["note"] = ""
278
294
  return event
@@ -333,6 +349,46 @@ def group_events_by_phase(events: list[dict[str, Any]]) -> list[tuple[str, list[
333
349
  return [(phase, buckets[phase]) for phase in order]
334
350
 
335
351
 
352
+ def split_phase_attempts(phase_events: list[dict[str, Any]]) -> list[dict[str, Any]]:
353
+ """Split repeated starts into attempts and flag legacy events written after end."""
354
+ attempts: list[dict[str, Any]] = []
355
+ current: dict[str, Any] | None = None
356
+ next_attempt = 1
357
+ for event in phase_events:
358
+ if event.get("type") == "phase.start":
359
+ if current is not None:
360
+ current["warnings"].append("new phase.start before prior phase.end")
361
+ attempts.append(current)
362
+ raw_attempt = event.get("attempt")
363
+ attempt = raw_attempt if isinstance(raw_attempt, int) and raw_attempt > 0 else next_attempt
364
+ next_attempt = max(next_attempt, attempt + 1)
365
+ current = {"attempt": attempt, "events": [event], "warnings": []}
366
+ continue
367
+ if current is None:
368
+ if attempts:
369
+ prior_type = attempts[-1]["events"][-1].get("type")
370
+ attempts[-1]["events"].append(event)
371
+ if prior_type == "phase.end":
372
+ attempts[-1]["warnings"].append("event recorded after phase.end")
373
+ continue
374
+ raw_attempt = event.get("attempt")
375
+ attempt = raw_attempt if isinstance(raw_attempt, int) and raw_attempt > 0 else next_attempt
376
+ next_attempt = max(next_attempt, attempt + 1)
377
+ current = {
378
+ "attempt": attempt,
379
+ "events": [event],
380
+ "warnings": ["missing phase.start"],
381
+ }
382
+ else:
383
+ current["events"].append(event)
384
+ if event.get("type") == "phase.end":
385
+ attempts.append(current)
386
+ current = None
387
+ if current is not None:
388
+ attempts.append(current)
389
+ return attempts
390
+
391
+
336
392
  def phase_start_time(phase_events: list[dict[str, Any]]) -> str:
337
393
  for event in phase_events:
338
394
  if event.get("type") == "phase.start":
@@ -352,7 +408,9 @@ def phase_duration_ms(phase_events: list[dict[str, Any]]) -> int | None:
352
408
  elif etype == "phase.end":
353
409
  end_ts = event.get("timestamp")
354
410
  if start_ts and end_ts:
355
- return duration_ms_between(start_ts, end_ts)
411
+ stamps = [e.get("timestamp") for e in phase_events if e.get("timestamp")]
412
+ effective_end = stamps[-1] if stamps else end_ts
413
+ return duration_ms_between(start_ts, effective_end)
356
414
  # Fallback: first to last timestamp in the phase bucket.
357
415
  stamps = [e.get("timestamp") for e in phase_events if e.get("timestamp")]
358
416
  if len(stamps) >= 2:
@@ -400,7 +458,15 @@ def render_event_line(event: dict[str, Any]) -> list[str]:
400
458
  if etype == "phase.start":
401
459
  note = str(event.get("note") or "").strip()
402
460
  suffix = f" — {note}" if note else ""
403
- return [f"- phase.start @ {event.get('timestamp', '')}{suffix}"]
461
+ lines = [f"- phase.start @ {event.get('timestamp', '')}{suffix}"]
462
+ tool = str(event.get("executor_tool") or "").strip()
463
+ agent = str(event.get("executor_agent") or "").strip()
464
+ handoff = str(event.get("handoff_from_tool") or "").strip()
465
+ if handoff and tool:
466
+ lines.append(f"- 工具交接: {handoff} → {tool}")
467
+ elif tool:
468
+ lines.append(f"- 执行来源: {tool}" + (f" / {agent}" if agent else ""))
469
+ return lines
404
470
  if etype == "phase.end":
405
471
  note = str(event.get("note") or "").strip()
406
472
  suffix = f" — {note}" if note else ""
@@ -445,29 +511,34 @@ def render_execution_log(events: list[dict[str, Any]]) -> str:
445
511
  return "\n".join(lines)
446
512
 
447
513
  for phase, phase_events in group_events_by_phase(events):
448
- start = phase_start_time(phase_events) or "—"
449
- duration = phase_duration_ms(phase_events)
450
- lines.append(f"## {phase} — {start}")
451
- lines.append("")
452
- if duration is not None:
453
- lines.append(f"- 阶段耗时: {format_duration(duration)}")
454
- # Collapse consecutive commands into one table.
455
- buffer: list[dict[str, Any]] = []
456
-
457
- def flush_commands() -> None:
458
- nonlocal buffer
459
- if buffer:
460
- lines.extend(render_command_block(buffer))
461
- buffer = []
462
-
463
- for event in phase_events:
464
- if event.get("type") == "command":
465
- buffer.append(event)
466
- continue
514
+ attempts = split_phase_attempts(phase_events)
515
+ for attempt_record in attempts:
516
+ attempt_events = attempt_record["events"]
517
+ start = phase_start_time(attempt_events) or ""
518
+ duration = phase_duration_ms(attempt_events)
519
+ label = f"{phase}(尝试 {attempt_record['attempt']}" if len(attempts) > 1 else phase
520
+ lines.append(f"## {label} {start}")
521
+ lines.append("")
522
+ if duration is not None:
523
+ lines.append(f"- 阶段耗时: {format_duration(duration)}")
524
+ for warning in attempt_record["warnings"]:
525
+ lines.append(f"- 生命周期警告: {warning}")
526
+ buffer: list[dict[str, Any]] = []
527
+
528
+ def flush_commands() -> None:
529
+ nonlocal buffer
530
+ if buffer:
531
+ lines.extend(render_command_block(buffer))
532
+ buffer = []
533
+
534
+ for event in attempt_events:
535
+ if event.get("type") == "command":
536
+ buffer.append(event)
537
+ continue
538
+ flush_commands()
539
+ lines.extend(render_event_line(event))
467
540
  flush_commands()
468
- lines.extend(render_event_line(event))
469
- flush_commands()
470
- lines.append("")
541
+ lines.append("")
471
542
 
472
543
  return "\n".join(lines).rstrip() + "\n"
473
544
 
@@ -485,21 +556,37 @@ def build_summary(change_dir: Path, events: list[dict[str, Any]]) -> dict[str, A
485
556
  issues: list[dict[str, Any]] = []
486
557
 
487
558
  for phase, phase_events in group_events_by_phase(events):
488
- start_ts = None
489
- end_ts = None
490
- for event in phase_events:
491
- if event.get("type") == "phase.start" and start_ts is None:
492
- start_ts = event.get("timestamp")
493
- elif event.get("type") == "phase.end":
494
- end_ts = event.get("timestamp")
495
- duration = None
496
- if start_ts and end_ts:
497
- duration = duration_ms_between(start_ts, end_ts)
559
+ attempt_records: list[dict[str, Any]] = []
560
+ for record in split_phase_attempts(phase_events):
561
+ attempt_events = record["events"]
562
+ starts = [e for e in attempt_events if e.get("type") == "phase.start"]
563
+ ends = [e for e in attempt_events if e.get("type") == "phase.end"]
564
+ start_ts = starts[0].get("timestamp") if starts else None
565
+ end_ts = ends[-1].get("timestamp") if ends else None
566
+ provenance = starts[0] if starts else (attempt_events[0] if attempt_events else {})
567
+ attempt_records.append({
568
+ "attempt": record["attempt"],
569
+ "event_count": len(attempt_events),
570
+ "started_at": start_ts,
571
+ "ended_at": end_ts,
572
+ "duration_ms": phase_duration_ms(attempt_events),
573
+ "status": ends[-1].get("status") if ends else None,
574
+ "run_id": provenance.get("run_id"),
575
+ "executor_tool": provenance.get("executor_tool"),
576
+ "executor_agent": provenance.get("executor_agent"),
577
+ "handoff_from_tool": provenance.get("handoff_from_tool"),
578
+ "warnings": record["warnings"],
579
+ })
580
+ durations = [a["duration_ms"] for a in attempt_records if a["duration_ms"] is not None]
581
+ first = attempt_records[0] if attempt_records else {}
582
+ last = attempt_records[-1] if attempt_records else {}
498
583
  phases[phase] = {
499
584
  "event_count": len(phase_events),
500
- "started_at": start_ts,
501
- "ended_at": end_ts,
502
- "duration_ms": duration,
585
+ "started_at": first.get("started_at"),
586
+ "ended_at": last.get("ended_at"),
587
+ "duration_ms": sum(durations) if durations else None,
588
+ "status": last.get("status"),
589
+ "attempts": attempt_records,
503
590
  }
504
591
 
505
592
  for event in events:
@@ -649,6 +736,13 @@ def build_parser() -> argparse.ArgumentParser:
649
736
  p_append.add_argument("--message", default=None)
650
737
  p_append.add_argument("--decision", default=None)
651
738
  p_append.add_argument("--reason", default=None)
739
+ p_append.add_argument("--run-id", default=None)
740
+ p_append.add_argument("--attempt", type=int, default=None)
741
+ p_append.add_argument("--executor-tool", default=None)
742
+ p_append.add_argument("--executor-agent", default=None)
743
+ p_append.add_argument("--executor-model", default=None)
744
+ p_append.add_argument("--handoff-from-tool", default=None)
745
+ p_append.add_argument("--handoff-reason", default=None)
652
746
  p_append.set_defaults(func=cmd_append)
653
747
 
654
748
  p_render = sub.add_parser(