@hunter-harness/workflow-harness 0.2.42 → 0.2.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/contracts/build-profile-v3.schema.json +156 -1
  3. package/harness/bundles/general/claude-code/contracts/fixtures/managed-execution.json +341 -0
  4. package/harness/bundles/general/claude-code/contracts/process-identity.schema.json +132 -0
  5. package/harness/bundles/general/claude-code/contracts/run-session.schema.json +142 -0
  6. package/harness/bundles/general/claude-code/contracts/service-retirement-receipt.schema.json +85 -0
  7. package/harness/bundles/general/claude-code/contracts/service-session.schema.json +147 -0
  8. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
  9. package/harness/bundles/general/claude-code/harness-archive/reference.md +1 -0
  10. package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +8 -0
  11. package/harness/bundles/general/claude-code/harness-archive/templates/summary-data-template.json +28 -0
  12. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
  13. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  14. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  15. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
  16. package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
  17. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  18. package/harness/bundles/general/claude-code/harness-run/reference.md +6 -1
  19. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
  20. package/harness/bundles/general/claude-code/harness-submit/checklist.md +12 -0
  21. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
  22. package/harness/bundles/general/claude-code/harness-test/SKILL.md +8 -2
  23. package/harness/bundles/general/claude-code/protocols/execution-session-protocol.md +52 -0
  24. package/harness/bundles/general/claude-code/protocols/state-layout-protocol.md +24 -1
  25. package/harness/bundles/general/claude-code/protocols/verification-graph-protocol.md +6 -0
  26. package/harness/bundles/general/claude-code/scripts/harness_archive.py +271 -22
  27. package/harness/bundles/general/claude-code/scripts/harness_change.py +137 -2
  28. package/harness/bundles/general/claude-code/scripts/harness_efficiency.py +443 -0
  29. package/harness/bundles/general/claude-code/scripts/harness_environment.py +760 -46
  30. package/harness/bundles/general/claude-code/scripts/harness_execution_contracts.py +596 -0
  31. package/harness/bundles/general/claude-code/scripts/harness_fixback.py +742 -0
  32. package/harness/bundles/general/claude-code/scripts/harness_integration.py +289 -52
  33. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +5 -0
  34. package/harness/bundles/general/claude-code/scripts/harness_orchestration.py +344 -0
  35. package/harness/bundles/general/claude-code/scripts/harness_process.py +1065 -0
  36. package/harness/bundles/general/claude-code/scripts/harness_profile.py +278 -4
  37. package/harness/bundles/general/claude-code/scripts/harness_runtime.py +1576 -3
  38. package/harness/bundles/general/claude-code/scripts/harness_service.py +1528 -177
  39. package/harness/bundles/general/claude-code/scripts/harness_test_runner.py +224 -146
  40. package/harness/bundles/general/claude-code/scripts/harness_verification.py +487 -8
  41. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  42. package/harness/bundles/general/codebuddy/contracts/build-profile-v3.schema.json +156 -1
  43. package/harness/bundles/general/codebuddy/contracts/fixtures/managed-execution.json +341 -0
  44. package/harness/bundles/general/codebuddy/contracts/process-identity.schema.json +132 -0
  45. package/harness/bundles/general/codebuddy/contracts/run-session.schema.json +142 -0
  46. package/harness/bundles/general/codebuddy/contracts/service-retirement-receipt.schema.json +85 -0
  47. package/harness/bundles/general/codebuddy/contracts/service-session.schema.json +147 -0
  48. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
  49. package/harness/bundles/general/codebuddy/harness-archive/reference.md +1 -0
  50. package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +8 -0
  51. package/harness/bundles/general/codebuddy/harness-archive/templates/summary-data-template.json +28 -0
  52. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
  53. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  54. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  55. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
  56. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
  57. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  58. package/harness/bundles/general/codebuddy/harness-run/reference.md +6 -1
  59. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
  60. package/harness/bundles/general/codebuddy/harness-submit/checklist.md +12 -0
  61. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
  62. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +8 -2
  63. package/harness/bundles/general/codebuddy/protocols/execution-session-protocol.md +52 -0
  64. package/harness/bundles/general/codebuddy/protocols/state-layout-protocol.md +24 -1
  65. package/harness/bundles/general/codebuddy/protocols/verification-graph-protocol.md +6 -0
  66. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +271 -22
  67. package/harness/bundles/general/codebuddy/scripts/harness_change.py +137 -2
  68. package/harness/bundles/general/codebuddy/scripts/harness_efficiency.py +443 -0
  69. package/harness/bundles/general/codebuddy/scripts/harness_environment.py +760 -46
  70. package/harness/bundles/general/codebuddy/scripts/harness_execution_contracts.py +596 -0
  71. package/harness/bundles/general/codebuddy/scripts/harness_fixback.py +742 -0
  72. package/harness/bundles/general/codebuddy/scripts/harness_integration.py +289 -52
  73. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +5 -0
  74. package/harness/bundles/general/codebuddy/scripts/harness_orchestration.py +344 -0
  75. package/harness/bundles/general/codebuddy/scripts/harness_process.py +1065 -0
  76. package/harness/bundles/general/codebuddy/scripts/harness_profile.py +278 -4
  77. package/harness/bundles/general/codebuddy/scripts/harness_runtime.py +1576 -3
  78. package/harness/bundles/general/codebuddy/scripts/harness_service.py +1528 -177
  79. package/harness/bundles/general/codebuddy/scripts/harness_test_runner.py +224 -146
  80. package/harness/bundles/general/codebuddy/scripts/harness_verification.py +487 -8
  81. package/harness/bundles/general/codex/.harness-build.json +1 -1
  82. package/harness/bundles/general/codex/contracts/build-profile-v3.schema.json +156 -1
  83. package/harness/bundles/general/codex/contracts/fixtures/managed-execution.json +341 -0
  84. package/harness/bundles/general/codex/contracts/process-identity.schema.json +132 -0
  85. package/harness/bundles/general/codex/contracts/run-session.schema.json +142 -0
  86. package/harness/bundles/general/codex/contracts/service-retirement-receipt.schema.json +85 -0
  87. package/harness/bundles/general/codex/contracts/service-session.schema.json +147 -0
  88. package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
  89. package/harness/bundles/general/codex/harness-archive/reference.md +1 -0
  90. package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +8 -0
  91. package/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +28 -0
  92. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
  93. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
  94. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  95. package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
  96. package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
  97. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  98. package/harness/bundles/general/codex/harness-run/reference.md +6 -1
  99. package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
  100. package/harness/bundles/general/codex/harness-submit/checklist.md +12 -0
  101. package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
  102. package/harness/bundles/general/codex/harness-test/SKILL.md +8 -2
  103. package/harness/bundles/general/codex/protocols/execution-session-protocol.md +52 -0
  104. package/harness/bundles/general/codex/protocols/state-layout-protocol.md +24 -1
  105. package/harness/bundles/general/codex/protocols/verification-graph-protocol.md +6 -0
  106. package/harness/bundles/general/codex/scripts/harness_archive.py +271 -22
  107. package/harness/bundles/general/codex/scripts/harness_change.py +137 -2
  108. package/harness/bundles/general/codex/scripts/harness_efficiency.py +443 -0
  109. package/harness/bundles/general/codex/scripts/harness_environment.py +760 -46
  110. package/harness/bundles/general/codex/scripts/harness_execution_contracts.py +596 -0
  111. package/harness/bundles/general/codex/scripts/harness_fixback.py +742 -0
  112. package/harness/bundles/general/codex/scripts/harness_integration.py +289 -52
  113. package/harness/bundles/general/codex/scripts/harness_ledger.py +5 -0
  114. package/harness/bundles/general/codex/scripts/harness_orchestration.py +344 -0
  115. package/harness/bundles/general/codex/scripts/harness_process.py +1065 -0
  116. package/harness/bundles/general/codex/scripts/harness_profile.py +278 -4
  117. package/harness/bundles/general/codex/scripts/harness_runtime.py +1576 -3
  118. package/harness/bundles/general/codex/scripts/harness_service.py +1528 -177
  119. package/harness/bundles/general/codex/scripts/harness_test_runner.py +224 -146
  120. package/harness/bundles/general/codex/scripts/harness_verification.py +487 -8
  121. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  122. package/harness/bundles/general/cursor/contracts/build-profile-v3.schema.json +156 -1
  123. package/harness/bundles/general/cursor/contracts/fixtures/managed-execution.json +341 -0
  124. package/harness/bundles/general/cursor/contracts/process-identity.schema.json +132 -0
  125. package/harness/bundles/general/cursor/contracts/run-session.schema.json +142 -0
  126. package/harness/bundles/general/cursor/contracts/service-retirement-receipt.schema.json +85 -0
  127. package/harness/bundles/general/cursor/contracts/service-session.schema.json +147 -0
  128. package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
  129. package/harness/bundles/general/cursor/harness-archive/reference.md +1 -0
  130. package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +8 -0
  131. package/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +28 -0
  132. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
  133. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  134. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  135. package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
  136. package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
  137. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  138. package/harness/bundles/general/cursor/harness-run/reference.md +6 -1
  139. package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
  140. package/harness/bundles/general/cursor/harness-submit/checklist.md +12 -0
  141. package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
  142. package/harness/bundles/general/cursor/harness-test/SKILL.md +8 -2
  143. package/harness/bundles/general/cursor/protocols/execution-session-protocol.md +52 -0
  144. package/harness/bundles/general/cursor/protocols/state-layout-protocol.md +24 -1
  145. package/harness/bundles/general/cursor/protocols/verification-graph-protocol.md +6 -0
  146. package/harness/bundles/general/cursor/scripts/harness_archive.py +271 -22
  147. package/harness/bundles/general/cursor/scripts/harness_change.py +137 -2
  148. package/harness/bundles/general/cursor/scripts/harness_efficiency.py +443 -0
  149. package/harness/bundles/general/cursor/scripts/harness_environment.py +760 -46
  150. package/harness/bundles/general/cursor/scripts/harness_execution_contracts.py +596 -0
  151. package/harness/bundles/general/cursor/scripts/harness_fixback.py +742 -0
  152. package/harness/bundles/general/cursor/scripts/harness_integration.py +289 -52
  153. package/harness/bundles/general/cursor/scripts/harness_ledger.py +5 -0
  154. package/harness/bundles/general/cursor/scripts/harness_orchestration.py +344 -0
  155. package/harness/bundles/general/cursor/scripts/harness_process.py +1065 -0
  156. package/harness/bundles/general/cursor/scripts/harness_profile.py +278 -4
  157. package/harness/bundles/general/cursor/scripts/harness_runtime.py +1576 -3
  158. package/harness/bundles/general/cursor/scripts/harness_service.py +1528 -177
  159. package/harness/bundles/general/cursor/scripts/harness_test_runner.py +224 -146
  160. package/harness/bundles/general/cursor/scripts/harness_verification.py +487 -8
  161. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  162. package/harness/bundles/java/claude-code/contracts/build-profile-v3.schema.json +156 -1
  163. package/harness/bundles/java/claude-code/contracts/fixtures/managed-execution.json +341 -0
  164. package/harness/bundles/java/claude-code/contracts/process-identity.schema.json +132 -0
  165. package/harness/bundles/java/claude-code/contracts/run-session.schema.json +142 -0
  166. package/harness/bundles/java/claude-code/contracts/service-retirement-receipt.schema.json +85 -0
  167. package/harness/bundles/java/claude-code/contracts/service-session.schema.json +147 -0
  168. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  169. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
  170. package/harness/bundles/java/claude-code/harness-archive/reference.md +1 -0
  171. package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +8 -0
  172. package/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +28 -0
  173. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
  174. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
  175. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  176. package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
  177. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
  178. package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
  179. package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
  180. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
  181. package/harness/bundles/java/claude-code/harness-submit/checklist.md +12 -0
  182. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
  183. package/harness/bundles/java/claude-code/harness-test/SKILL.md +8 -2
  184. package/harness/bundles/java/claude-code/protocols/execution-session-protocol.md +52 -0
  185. package/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +24 -1
  186. package/harness/bundles/java/claude-code/protocols/verification-graph-protocol.md +6 -0
  187. package/harness/bundles/java/claude-code/scripts/harness_archive.py +271 -22
  188. package/harness/bundles/java/claude-code/scripts/harness_change.py +137 -2
  189. package/harness/bundles/java/claude-code/scripts/harness_efficiency.py +443 -0
  190. package/harness/bundles/java/claude-code/scripts/harness_environment.py +760 -46
  191. package/harness/bundles/java/claude-code/scripts/harness_execution_contracts.py +596 -0
  192. package/harness/bundles/java/claude-code/scripts/harness_fixback.py +742 -0
  193. package/harness/bundles/java/claude-code/scripts/harness_integration.py +289 -52
  194. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +5 -0
  195. package/harness/bundles/java/claude-code/scripts/harness_orchestration.py +344 -0
  196. package/harness/bundles/java/claude-code/scripts/harness_process.py +1065 -0
  197. package/harness/bundles/java/claude-code/scripts/harness_profile.py +278 -4
  198. package/harness/bundles/java/claude-code/scripts/harness_runtime.py +1576 -3
  199. package/harness/bundles/java/claude-code/scripts/harness_service.py +1528 -177
  200. package/harness/bundles/java/claude-code/scripts/harness_test_runner.py +224 -146
  201. package/harness/bundles/java/claude-code/scripts/harness_verification.py +487 -8
  202. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  203. package/harness/bundles/java/codebuddy/contracts/build-profile-v3.schema.json +156 -1
  204. package/harness/bundles/java/codebuddy/contracts/fixtures/managed-execution.json +341 -0
  205. package/harness/bundles/java/codebuddy/contracts/process-identity.schema.json +132 -0
  206. package/harness/bundles/java/codebuddy/contracts/run-session.schema.json +142 -0
  207. package/harness/bundles/java/codebuddy/contracts/service-retirement-receipt.schema.json +85 -0
  208. package/harness/bundles/java/codebuddy/contracts/service-session.schema.json +147 -0
  209. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  210. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
  211. package/harness/bundles/java/codebuddy/harness-archive/reference.md +1 -0
  212. package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +8 -0
  213. package/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +28 -0
  214. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
  215. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
  216. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  217. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
  218. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
  219. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
  220. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
  221. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
  222. package/harness/bundles/java/codebuddy/harness-submit/checklist.md +12 -0
  223. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
  224. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +8 -2
  225. package/harness/bundles/java/codebuddy/protocols/execution-session-protocol.md +52 -0
  226. package/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +24 -1
  227. package/harness/bundles/java/codebuddy/protocols/verification-graph-protocol.md +6 -0
  228. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +271 -22
  229. package/harness/bundles/java/codebuddy/scripts/harness_change.py +137 -2
  230. package/harness/bundles/java/codebuddy/scripts/harness_efficiency.py +443 -0
  231. package/harness/bundles/java/codebuddy/scripts/harness_environment.py +760 -46
  232. package/harness/bundles/java/codebuddy/scripts/harness_execution_contracts.py +596 -0
  233. package/harness/bundles/java/codebuddy/scripts/harness_fixback.py +742 -0
  234. package/harness/bundles/java/codebuddy/scripts/harness_integration.py +289 -52
  235. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +5 -0
  236. package/harness/bundles/java/codebuddy/scripts/harness_orchestration.py +344 -0
  237. package/harness/bundles/java/codebuddy/scripts/harness_process.py +1065 -0
  238. package/harness/bundles/java/codebuddy/scripts/harness_profile.py +278 -4
  239. package/harness/bundles/java/codebuddy/scripts/harness_runtime.py +1576 -3
  240. package/harness/bundles/java/codebuddy/scripts/harness_service.py +1528 -177
  241. package/harness/bundles/java/codebuddy/scripts/harness_test_runner.py +224 -146
  242. package/harness/bundles/java/codebuddy/scripts/harness_verification.py +487 -8
  243. package/harness/bundles/java/codex/.harness-build.json +1 -1
  244. package/harness/bundles/java/codex/contracts/build-profile-v3.schema.json +156 -1
  245. package/harness/bundles/java/codex/contracts/fixtures/managed-execution.json +341 -0
  246. package/harness/bundles/java/codex/contracts/process-identity.schema.json +132 -0
  247. package/harness/bundles/java/codex/contracts/run-session.schema.json +142 -0
  248. package/harness/bundles/java/codex/contracts/service-retirement-receipt.schema.json +85 -0
  249. package/harness/bundles/java/codex/contracts/service-session.schema.json +147 -0
  250. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  251. package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
  252. package/harness/bundles/java/codex/harness-archive/reference.md +1 -0
  253. package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +8 -0
  254. package/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +28 -0
  255. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
  256. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
  257. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  258. package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
  259. package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
  260. package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
  261. package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
  262. package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
  263. package/harness/bundles/java/codex/harness-submit/checklist.md +12 -0
  264. package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
  265. package/harness/bundles/java/codex/harness-test/SKILL.md +8 -2
  266. package/harness/bundles/java/codex/protocols/execution-session-protocol.md +52 -0
  267. package/harness/bundles/java/codex/protocols/state-layout-protocol.md +24 -1
  268. package/harness/bundles/java/codex/protocols/verification-graph-protocol.md +6 -0
  269. package/harness/bundles/java/codex/scripts/harness_archive.py +271 -22
  270. package/harness/bundles/java/codex/scripts/harness_change.py +137 -2
  271. package/harness/bundles/java/codex/scripts/harness_efficiency.py +443 -0
  272. package/harness/bundles/java/codex/scripts/harness_environment.py +760 -46
  273. package/harness/bundles/java/codex/scripts/harness_execution_contracts.py +596 -0
  274. package/harness/bundles/java/codex/scripts/harness_fixback.py +742 -0
  275. package/harness/bundles/java/codex/scripts/harness_integration.py +289 -52
  276. package/harness/bundles/java/codex/scripts/harness_ledger.py +5 -0
  277. package/harness/bundles/java/codex/scripts/harness_orchestration.py +344 -0
  278. package/harness/bundles/java/codex/scripts/harness_process.py +1065 -0
  279. package/harness/bundles/java/codex/scripts/harness_profile.py +278 -4
  280. package/harness/bundles/java/codex/scripts/harness_runtime.py +1576 -3
  281. package/harness/bundles/java/codex/scripts/harness_service.py +1528 -177
  282. package/harness/bundles/java/codex/scripts/harness_test_runner.py +224 -146
  283. package/harness/bundles/java/codex/scripts/harness_verification.py +487 -8
  284. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  285. package/harness/bundles/java/cursor/contracts/build-profile-v3.schema.json +156 -1
  286. package/harness/bundles/java/cursor/contracts/fixtures/managed-execution.json +341 -0
  287. package/harness/bundles/java/cursor/contracts/process-identity.schema.json +132 -0
  288. package/harness/bundles/java/cursor/contracts/run-session.schema.json +142 -0
  289. package/harness/bundles/java/cursor/contracts/service-retirement-receipt.schema.json +85 -0
  290. package/harness/bundles/java/cursor/contracts/service-session.schema.json +147 -0
  291. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  292. package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
  293. package/harness/bundles/java/cursor/harness-archive/reference.md +1 -0
  294. package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +8 -0
  295. package/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +28 -0
  296. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
  297. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
  298. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  299. package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
  300. package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
  301. package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
  302. package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
  303. package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
  304. package/harness/bundles/java/cursor/harness-submit/checklist.md +12 -0
  305. package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
  306. package/harness/bundles/java/cursor/harness-test/SKILL.md +8 -2
  307. package/harness/bundles/java/cursor/protocols/execution-session-protocol.md +52 -0
  308. package/harness/bundles/java/cursor/protocols/state-layout-protocol.md +24 -1
  309. package/harness/bundles/java/cursor/protocols/verification-graph-protocol.md +6 -0
  310. package/harness/bundles/java/cursor/scripts/harness_archive.py +271 -22
  311. package/harness/bundles/java/cursor/scripts/harness_change.py +137 -2
  312. package/harness/bundles/java/cursor/scripts/harness_efficiency.py +443 -0
  313. package/harness/bundles/java/cursor/scripts/harness_environment.py +760 -46
  314. package/harness/bundles/java/cursor/scripts/harness_execution_contracts.py +596 -0
  315. package/harness/bundles/java/cursor/scripts/harness_fixback.py +742 -0
  316. package/harness/bundles/java/cursor/scripts/harness_integration.py +289 -52
  317. package/harness/bundles/java/cursor/scripts/harness_ledger.py +5 -0
  318. package/harness/bundles/java/cursor/scripts/harness_orchestration.py +344 -0
  319. package/harness/bundles/java/cursor/scripts/harness_process.py +1065 -0
  320. package/harness/bundles/java/cursor/scripts/harness_profile.py +278 -4
  321. package/harness/bundles/java/cursor/scripts/harness_runtime.py +1576 -3
  322. package/harness/bundles/java/cursor/scripts/harness_service.py +1528 -177
  323. package/harness/bundles/java/cursor/scripts/harness_test_runner.py +224 -146
  324. package/harness/bundles/java/cursor/scripts/harness_verification.py +487 -8
  325. package/harness/manifests/general/claude-code.json +76 -31
  326. package/harness/manifests/general/codebuddy.json +76 -31
  327. package/harness/manifests/general/codex.json +76 -31
  328. package/harness/manifests/general/cursor.json +76 -31
  329. package/harness/manifests/java/claude-code.json +77 -32
  330. package/harness/manifests/java/codebuddy.json +77 -32
  331. package/harness/manifests/java/codex.json +77 -32
  332. package/harness/manifests/java/cursor.json +77 -32
  333. package/hunter-workflow-family.json +6 -4
  334. package/package.json +1 -1
@@ -0,0 +1,52 @@
1
+ ---
2
+ description: 长时命令、验证调度、环境复用与 fixback 的可恢复执行协议。
3
+ ---
4
+
5
+ # Execution Session Protocol
6
+
7
+ ## 受管运行会话
8
+
9
+ 可能超过交互窗口的命令必须通过 `harness_runtime.py run-start` 创建受管会话,而不是依赖调用方进程持续在线。会话状态位于:
10
+
11
+ ```text
12
+ runtime/run-sessions/<session-id>/
13
+ ├── session.json
14
+ ├── stdout.log
15
+ ├── stderr.log
16
+ └── worker.log
17
+ ```
18
+
19
+ `session.json` 只持久化脱敏身份:命令哈希、环境哈希、产品身份、验证目标、阶段、资源锁、进程身份、心跳、进度、超时和原因码。原始环境变量和敏感 argv 不得写入回执。
20
+
21
+ - `run-status` 可由新进程重连;心跳丢失超过 grace period 才标记 `INCOMPLETE`。
22
+ - `run-log --cursor` 按字节游标增量读取 UTF-8 日志,返回下一游标。
23
+ - `run-cancel` 只终止身份完全匹配的进程树;身份不确定时 fail closed。
24
+ - launcher 尚未启动子进程时失败,状态为 `INCOMPLETE/LAUNCHER_FAILED`;子进程非零退出为 `FAIL/CHILD_EXIT_NONZERO`;超时为 `CANCELLED/TIMEOUT`。
25
+ - `resourceLocks` 通过 `runtime/resource-locks/<lock-hash>.json` 原子独占;冲突会在启动测试进程前返回 `INCOMPLETE/RESOURCE_LOCK_BUSY`,终态写入前必须释放持有的锁。
26
+ - Windows 使用 shell-free argv 和 kill-on-close Job Object;Job Object 绑定失败时必须终止已验证的子进程并返回 `PROCESS_TREE_ISOLATION_UNAVAILABLE`,不得降级为无隔离运行。
27
+
28
+ ## 验证调度
29
+
30
+ `harness_verification.py plan` 对验证 DAG 做拓扑调度。每个目标声明 `dependsOn`、`resourceLocks`、identity 与复用策略。
31
+
32
+ - 只有资源锁不相交的 ready 目标可进入同一 wave。
33
+ - 未声明资源锁且预计大于等于 60 秒的目标自动使用 `harness:unclassified-heavy`,因此默认串行。
34
+ - 冻结后的产品 identity 发生变化时返回 `FROZEN_IDENTITY_DRIFT`,禁止继续执行或复用。
35
+ - 复用和跳过必须记录 `decision`、`reasonCode` 与人类可读 `explanation`;无证据不得返回 `REUSE`。
36
+
37
+ ## 环境会话
38
+
39
+ 环境租约支持两种模式:
40
+
41
+ - `change-session`:同一 change、stack、内容指纹和通过的 canary 可复用。
42
+ - `ephemeral`:每次 acquire 都创建新 session;替换既有 session 前必须提供匹配 stack/environment identity 的 provider reset 回执。
43
+
44
+ 租约获取通过注册锁原子串行化,跨 change 的 writable volume 永不共享。`change-session` 只有在内容指纹非空、environment hash、owner identity、expiry、mode、volume 和 canary 全部匹配时才可复用。内容指纹漂移标记 `STALE_CONTENT`;过期租约不可写。prepare/reuse 写入事实回执;reset/cleanup 只有在 provider operation evidence 为 `OK` 时才可如此命名。单纯释放租约只能记录 `release`,不得声称已清理外部环境。回执写入 change 的 `runtime/environment-receipts/`,文件名使用 stack hash,且不包含凭据明文。
45
+
46
+ ## Fixback 批次
47
+
48
+ Review/Test 回灌通过 `harness_fixback.py` 形成批次。一个批次可包含多条相关问题,但每条问题必须保留可读取的 JSON RED/GREEN 证据。证据必须位于项目或 change state 内,包含 evidence id、状态和产品 identity,并在批次中固定 SHA-256;RED 必须为 `FAIL`,GREEN 必须为 `PASS/OK`。affected verification 与 review 回执必须绑定最终产品 identity,其 `passedGates` 合集覆盖风险扩展后的全部门禁。`freeze-readiness` 会重新校验证据摘要;开放问题、证据漂移或缺门禁均阻止 code freeze。
49
+
50
+ ## 效率摘要
51
+
52
+ `harness_efficiency.py summary` 从运行会话、环境回执和失效回执生成事实型指标:墙钟区间并集、累计活动/资源等待、execution/launcher/verification 尝试、失败分类、环境 prepare/reuse/reset/cleanup、重复且没有新 result digest 的命令和人工 wrapper 数。reset/cleanup 只统计带有效 provider evidence 的回执。归档摘要自动包含该结构;指标不得归责个人,也不得在历史样本不足时虚构 ETA。
@@ -60,7 +60,14 @@ description: harness .harness 状态目录分层协议。用于减少根目录
60
60
  ├── sqls/
61
61
  ├── scripts/
62
62
  ├── runtime/
63
- └── service-session.json
63
+ ├── service-session.json
64
+ │ ├── run-sessions/<session-id>/
65
+ │ │ ├── session.json
66
+ │ │ ├── stdout.log
67
+ │ │ └── stderr.log
68
+ │ ├── environment-receipts/
69
+ │ ├── invalidations/
70
+ │ └── fixback/batches/
64
71
  └── backups/
65
72
  └── uncommitted-tests/
66
73
  ```
@@ -73,6 +80,10 @@ description: harness .harness 状态目录分层协议。用于减少根目录
73
80
 
74
81
  `build-profile.json` 的 `serviceStart.inputFiles`(glob 列表,相对 project 展开)是 `moduleInputsHash` 的来源。`harness_service.py ensure` 取 CLI `--files` ∪ `serviceStart.inputFiles` 计算依赖闭包;**空输入被拒绝**(exit 非 0),**不得生成可复用的空指纹**。通用项目 detect 无法猜 module 源,`inputFiles` 默认空数组,须人工配置。
75
82
 
83
+ 过期的 service session 只有在进程身份明确不匹配时才允许由 `retire-stale` 移入
84
+ `runtime/retired-service-sessions/`;该动作保留原始回执且不终止进程。受管命令、
85
+ 环境会话和 fixback 的完整合同见 `execution-session-protocol.md`。
86
+
76
87
  ## knowledge maintenance-outbox(§8)
77
88
 
78
89
  归档 close 不再同步执行知识维护;它写一个 pending outbox 项即返回:
@@ -179,3 +190,15 @@ Harness skill 读取的项目级配置(不提交 git)。缺失时使用下
179
190
  | `knowledge.manualReview` | boolean | `false` | `true` 时 knowledge-ingest promote 等高价值操作需人工确认;`false` 时按 skill 默认策略 |
180
191
 
181
192
  读取顺序:`.harness/config/harness.json` → 缺失则默认值。plan 阶段 5 设计审批包须读取 `defaultWorktree` 作为 worktree 选项的推荐值。
193
+
194
+ ## 可恢复文件事务
195
+
196
+ schema v3 事务在本地 `transactions/<transaction-id>/` 保存 journal、before snapshot、staged payload、after manifest 和小型 status 投影。journal 固定 project identity、执行器版本、目标 Bundle identity、ownership manifest hash、plan hash 与 snapshot digest。
197
+
198
+ 未完成事务同时镜像到用户级恢复根:
199
+
200
+ ```text
201
+ ${HUNTER_HARNESS_RECOVERY_ROOT:-~/.hunter-harness/recovery}/<project-path-hash>/transactions/<transaction-id>/
202
+ ```
203
+
204
+ 因此项目内 `.harness` 局部丢失后,`status` 仍可只读发现恢复项。`resume` 仅在 plan/snapshot/staged digest 与已完成操作的当前文件状态全部匹配时继续 pending operations;任一不匹配均 fail closed。`rollback` 在写回 before snapshot 前重新校验 snapshot digest。事务提交或回滚成功后删除用户级镜像;本地 committed 事务仍按保留策略提供显式回滚。
@@ -11,6 +11,9 @@ Build Profile v3 用 `verificationGraph` 取代账本内的固定验证目标清
11
11
  - `requiredCoverage`:`incremental/module-am/module`;
12
12
  - `candidate`:是否为发布候选门禁;
13
13
  - `requiredCapabilities`:执行环境必须具备的能力。
14
+ - `resourceLocks`:目标独占或共享的数据库、端口、浏览器、容器等资源身份;
15
+ - `estimatedDurationSeconds`:供默认串行策略和进度显示使用,不作为虚构 ETA 的依据;
16
+ - `reusePolicy`:允许复用时必须匹配的产品、环境、命令与覆盖身份。
14
17
 
15
18
  `candidateTarget` 必须引用已声明目标。未知目标、未知依赖、循环依赖、命令缺失都 fail closed。
16
19
 
@@ -22,5 +25,8 @@ Build Profile v3 用 `verificationGraph` 取代账本内的固定验证目标清
22
25
  4. 未进入闭包的目标是 `omitted`,与“执行失败”或“因能力阻断”分开报告。
23
26
  5. 账本记录目标定义的规范化 identity;依赖、覆盖度或能力声明变化后,旧证据必须失效。
24
27
  6. 候选目标即使自身命令可运行,也必须等待所有依赖和能力满足。
28
+ 7. ready 目标按 `resourceLocks` 分 wave;锁相交的目标不得并行。预计 ≥60 秒且未声明锁的目标默认归入 `harness:unclassified-heavy` 串行队列。
29
+ 8. code freeze 后产品 identity 漂移必须返回 `FROZEN_IDENTITY_DRIFT`;禁止在旧候选上补跑后声称覆盖新候选。
30
+ 9. 每个 `RUN / REUSE / SKIP / BLOCKED` 决策都必须带稳定 `reasonCode` 和解释;`REUSE` 还必须绑定现有证据 identity。
25
31
 
26
32
  JSON 合同见 `contracts/build-profile-v3.schema.json`;通用选择器为 `@hunter-harness/core` 的 `selectVerificationTargets`。
@@ -70,12 +70,14 @@ if str(SCRIPTS_DIR) not in sys.path:
70
70
  sys.path.insert(0, str(SCRIPTS_DIR))
71
71
 
72
72
  import harness_events as he # noqa: E402
73
+ import harness_efficiency as heff # noqa: E402
73
74
  import harness_gate as hgate # noqa: E402
74
75
  import harness_ledger as hl # noqa: E402
75
76
  import harness_paths as hp # noqa: E402
76
77
  import harness_phase as hphase # noqa: E402
77
78
  import harness_report_model as hrm # noqa: E402
78
79
  import harness_review as hr # noqa: E402
80
+ import harness_runtime as hruntime # noqa: E402
79
81
 
80
82
 
81
83
  # ---------------------------------------------------------------------------
@@ -1956,6 +1958,131 @@ def check_archive_exact_byte_policy(project_root: Path) -> dict[str, Any]:
1956
1958
  }
1957
1959
 
1958
1960
 
1961
+ def validate_sensitive_evidence_publication_gate(
1962
+ change_dir: Path,
1963
+ *,
1964
+ copy_root: Path | None = None,
1965
+ require_receipt: bool = False,
1966
+ ) -> dict[str, Any]:
1967
+ """Fail closed before freeze/copy when plaintext evidence is unresolved.
1968
+
1969
+ The receipt is deliberately self-excluded from the tree digest. It may
1970
+ therefore bind the exact publishable bytes without creating a recursive
1971
+ digest. Private quarantine paths are evidence metadata only and must be
1972
+ outside both the project/copy roots.
1973
+ """
1974
+ change_dir = change_dir.expanduser().resolve()
1975
+ copy_root = (copy_root or change_dir).expanduser().resolve()
1976
+ receipt_path = hruntime.sensitive_evidence_receipt_path(change_dir)
1977
+ candidates = hruntime.sensitive_evidence_candidates(change_dir)
1978
+ if candidates:
1979
+ return {
1980
+ "ok": False,
1981
+ "reasonCode": "SENSITIVE_EVIDENCE_UNQUARANTINED",
1982
+ "receiptPath": str(receipt_path),
1983
+ "unresolvedFailures": candidates,
1984
+ "nextAction": "Quarantine the original bytes before archive publication.",
1985
+ }
1986
+ if not receipt_path.is_file():
1987
+ if require_receipt:
1988
+ return {
1989
+ "ok": False,
1990
+ "reasonCode": "SECRET_SCAN_RECEIPT_MISSING",
1991
+ "receiptPath": str(receipt_path),
1992
+ "unresolvedFailures": [],
1993
+ }
1994
+ return {
1995
+ "ok": True,
1996
+ "reasonCode": "SECRET_SCAN_NOT_APPLICABLE",
1997
+ "receiptPath": str(receipt_path),
1998
+ "receiptRequired": False,
1999
+ "unresolvedFailures": [],
2000
+ }
2001
+ try:
2002
+ receipt = read_json(receipt_path)
2003
+ except (OSError, json.JSONDecodeError, TypeError) as exc:
2004
+ return {
2005
+ "ok": False,
2006
+ "reasonCode": "SECRET_SCAN_RECEIPT_INVALID",
2007
+ "receiptPath": str(receipt_path),
2008
+ "error": str(exc),
2009
+ }
2010
+ if not isinstance(receipt, dict):
2011
+ return {
2012
+ "ok": False,
2013
+ "reasonCode": "SECRET_SCAN_RECEIPT_INVALID",
2014
+ "receiptPath": str(receipt_path),
2015
+ "error": "receipt must be an object",
2016
+ }
2017
+ issues: list[dict[str, Any]] = []
2018
+ if receipt.get("schemaVersion") != 1:
2019
+ issues.append({"code": "SECRET_SCAN_SCHEMA_INVALID"})
2020
+ if receipt.get("rulesVersion") != hruntime.SECRET_SCAN_RULES_VERSION:
2021
+ issues.append({"code": "SECRET_SCAN_RULES_MISMATCH"})
2022
+ if receipt.get("changeId") != change_dir.name:
2023
+ issues.append({"code": "SECRET_SCAN_CHANGE_ID_MISMATCH"})
2024
+ if str(receipt.get("status") or "").upper() not in {"OK", "QUARANTINED"}:
2025
+ issues.append({"code": "SENSITIVE_EVIDENCE_QUARANTINE_FAILED"})
2026
+ unresolved = receipt.get("unresolvedFailures")
2027
+ if isinstance(unresolved, list) and unresolved:
2028
+ issues.append({"code": "SENSITIVE_EVIDENCE_QUARANTINE_FAILED", "count": len(unresolved)})
2029
+ elif unresolved not in (None, []):
2030
+ issues.append({"code": "SECRET_SCAN_UNRESOLVED_INVALID"})
2031
+ try:
2032
+ actual_digest = hruntime.publishable_tree_digest(change_dir)
2033
+ except OSError as exc:
2034
+ actual_digest = None
2035
+ issues.append({"code": "SECRET_SCAN_TREE_UNREADABLE", "error": str(exc)})
2036
+ if actual_digest is not None and receipt.get("publishableTreeDigest") != actual_digest:
2037
+ issues.append({
2038
+ "code": "SECRET_SCAN_TREE_DIGEST_MISMATCH",
2039
+ "expected": receipt.get("publishableTreeDigest"),
2040
+ "actual": actual_digest,
2041
+ })
2042
+ if receipt.get("publicationExcluded") is not True:
2043
+ issues.append({"code": "SECRET_SCAN_PUBLICATION_NOT_EXCLUDED"})
2044
+ project_root = find_project_root(change_dir)
2045
+ for entry in receipt.get("entries") or []:
2046
+ if not isinstance(entry, dict):
2047
+ issues.append({"code": "SECRET_SCAN_ENTRY_INVALID"})
2048
+ continue
2049
+ private_raw = entry.get("privatePath")
2050
+ if not isinstance(private_raw, str) or not private_raw.strip():
2051
+ issues.append({"code": "SECRET_SCAN_PRIVATE_PATH_MISSING"})
2052
+ continue
2053
+ private_path = Path(private_raw).expanduser().resolve()
2054
+ if (
2055
+ _path_is_within(private_path, copy_root)
2056
+ or _path_is_within(private_path, project_root)
2057
+ or _path_is_within(private_path, change_dir)
2058
+ ):
2059
+ issues.append({
2060
+ "code": "SECRET_SCAN_PRIVATE_PATH_IN_COPY_ROOT",
2061
+ "privatePath": str(private_path),
2062
+ })
2063
+ if not private_path.is_file():
2064
+ issues.append({
2065
+ "code": "SECRET_SCAN_PRIVATE_PATH_MISSING",
2066
+ "privatePath": str(private_path),
2067
+ })
2068
+ source_raw = entry.get("sourcePath")
2069
+ if isinstance(source_raw, str) and source_raw.strip():
2070
+ source_path = (change_dir / source_raw).resolve()
2071
+ if _path_is_within(source_path, change_dir) and source_path.exists():
2072
+ issues.append({
2073
+ "code": "SENSITIVE_EVIDENCE_SOURCE_REMAINS",
2074
+ "sourcePath": source_raw,
2075
+ })
2076
+ return {
2077
+ "ok": not issues,
2078
+ "reasonCode": "SECRET_SCAN_GATE_SATISFIED" if not issues else "SECRET_SCAN_GATE_BLOCKED",
2079
+ "receiptPath": str(receipt_path),
2080
+ "receipt": receipt,
2081
+ "issues": issues,
2082
+ "treeDigest": actual_digest,
2083
+ }
2084
+
2085
+
1959
2086
  # ---------------------------------------------------------------------------
1960
2087
  # status
1961
2088
  # ---------------------------------------------------------------------------
@@ -2000,6 +2127,22 @@ def check_status(
2000
2127
  }
2001
2128
  )
2002
2129
 
2130
+ sensitive_gate = validate_sensitive_evidence_publication_gate(
2131
+ change_dir,
2132
+ copy_root=change_dir,
2133
+ require_receipt=False,
2134
+ )
2135
+ checks["sensitive_evidence_publication"] = sensitive_gate
2136
+ if not sensitive_gate.get("ok"):
2137
+ blockers.append({
2138
+ "code": str(sensitive_gate.get("reasonCode") or "SECRET_SCAN_GATE_BLOCKED"),
2139
+ "message": str(
2140
+ sensitive_gate.get("nextAction")
2141
+ or sensitive_gate.get("error")
2142
+ or "sensitive evidence publication gate failed"
2143
+ ),
2144
+ })
2145
+
2003
2146
  # --- H-4 formal-layer minimum set ---
2004
2147
  plans_dir = change_dir / "plans"
2005
2148
  plan_files = (
@@ -2245,6 +2388,14 @@ def check_status(
2245
2388
  except Exception as exc: # noqa: BLE001 — preflight must not crash status
2246
2389
  preflight = {"ok": False, "items": [], "blocking": [], "error": str(exc)}
2247
2390
  checks["artifact_preflight"] = preflight
2391
+ if preflight.get("ok") is not True and not preflight.get("blocking"):
2392
+ blockers.append({
2393
+ "code": "artifact-preflight-invalid",
2394
+ "message": str(
2395
+ preflight.get("error")
2396
+ or "artifact event projection or preflight validation failed"
2397
+ ),
2398
+ })
2248
2399
  for item in preflight.get("blocking") or []:
2249
2400
  blockers.append({
2250
2401
  "code": "artifact-path-blocking",
@@ -3890,12 +4041,15 @@ def collect_summary_data(
3890
4041
  "retention",
3891
4042
  "archiveDurability",
3892
4043
  "remoteCost",
4044
+ "efficiency",
3893
4045
  "projection",
3894
4046
  ):
3895
4047
  if key in existing:
3896
4048
  data[key] = _deepcopy_json(existing[key])
3897
4049
  if not for_replay or not isinstance(data.get("remoteCost"), dict):
3898
4050
  data["remoteCost"] = remote_cost
4051
+ if not for_replay or not isinstance(data.get("efficiency"), dict):
4052
+ data["efficiency"] = heff.collect_efficiency_summary(change_dir)
3899
4053
 
3900
4054
  event_summary = he.build_summary(change_dir, events) if events else {
3901
4055
  "ok": True,
@@ -6461,12 +6615,9 @@ def artifact_preflight(change_dir: Path) -> dict[str, Any]:
6461
6615
  return {"ok": True, "items": [], "blocking": []}
6462
6616
  change_id = change_dir.name
6463
6617
  project_root = find_project_root(change_dir)
6464
- for line in events_p.read_text(encoding="utf-8").splitlines():
6465
- try:
6466
- event = json.loads(line)
6467
- except json.JSONDecodeError:
6468
- continue
6469
- if not isinstance(event, dict) or event.get("type") != "artifact":
6618
+ events = he.apply_event_corrections(he.load_events(events_p))
6619
+ for event in events:
6620
+ if event.get("type") != "artifact":
6470
6621
  continue
6471
6622
  path = str(event.get("path") or "").strip()
6472
6623
  kind = str(event.get("kind") or "").strip()
@@ -6653,9 +6804,19 @@ def evaluate_artifact_budget(change_dir: Path) -> dict[str, Any]:
6653
6804
  except (OSError, ValueError, json.JSONDecodeError) as exc:
6654
6805
  return {
6655
6806
  "ok": False,
6656
- "code": "ARTIFACT_POLICY_INVALID",
6807
+ "code": "ARTIFACT_PREFLIGHT_INVALID",
6657
6808
  "message": str(exc),
6658
6809
  }
6810
+ if preflight.get("ok") is not True:
6811
+ return {
6812
+ "ok": False,
6813
+ "code": "ARTIFACT_PREFLIGHT_INVALID",
6814
+ "message": str(
6815
+ preflight.get("error")
6816
+ or "artifact event projection or preflight validation failed"
6817
+ ),
6818
+ "preflightBlocking": preflight.get("blocking") or [],
6819
+ }
6659
6820
  excluded_parts = {
6660
6821
  "node_modules",
6661
6822
  ".venv",
@@ -6693,7 +6854,7 @@ def evaluate_artifact_budget(change_dir: Path) -> dict[str, Any]:
6693
6854
  oversized = [
6694
6855
  item for item in entries if int(item["bytes"]) > max_file
6695
6856
  ]
6696
- ok = total <= max_total and not oversized and bool(preflight.get("ok"))
6857
+ ok = total <= max_total and not oversized
6697
6858
  return {
6698
6859
  "ok": ok,
6699
6860
  "code": (
@@ -6722,6 +6883,13 @@ def materialize_repository_artifacts(change_dir: Path) -> dict[str, Any]:
6722
6883
  change_dir = change_dir.resolve()
6723
6884
  project_root = find_project_root(change_dir)
6724
6885
  preflight = artifact_preflight(change_dir)
6886
+ if preflight.get("ok") is not True:
6887
+ raise ValueError(
6888
+ str(
6889
+ preflight.get("error")
6890
+ or "artifact event projection or preflight validation failed"
6891
+ )
6892
+ )
6725
6893
  copied: list[str] = []
6726
6894
  objects: list[dict[str, Any]] = []
6727
6895
  bytes_added = 0
@@ -7295,6 +7463,32 @@ def cmd_finalize(
7295
7463
  payload["error"] = f"archive target already exists: {archive_dir}"
7296
7464
  return 1, payload
7297
7465
 
7466
+ source_sensitive_gate = validate_sensitive_evidence_publication_gate(
7467
+ original_change_dir,
7468
+ copy_root=original_change_dir,
7469
+ require_receipt=False,
7470
+ )
7471
+ payload["steps"]["sensitive_evidence_source_gate"] = source_sensitive_gate
7472
+ if not source_sensitive_gate.get("ok"):
7473
+ payload["error"] = str(
7474
+ source_sensitive_gate.get("nextAction")
7475
+ or source_sensitive_gate.get("error")
7476
+ or "sensitive evidence publication gate failed"
7477
+ )
7478
+ payload["issues"] = [
7479
+ {
7480
+ "code": str(
7481
+ source_sensitive_gate.get("reasonCode")
7482
+ or "SECRET_SCAN_GATE_BLOCKED"
7483
+ ),
7484
+ "severity": "error",
7485
+ "message": payload["error"],
7486
+ }
7487
+ ]
7488
+ payload["original_preserved"] = original_change_dir.is_dir()
7489
+ payload["finalStatus"] = "FAIL"
7490
+ return 1, payload
7491
+
7298
7492
  exact_byte = check_archive_exact_byte_policy(project_root)
7299
7493
  payload["steps"]["archive_exact_byte"] = exact_byte
7300
7494
  if not exact_byte["ok"]:
@@ -7303,7 +7497,13 @@ def cmd_finalize(
7303
7497
  artifact_budget = evaluate_artifact_budget(original_change_dir)
7304
7498
  payload["steps"]["artifact_budget"] = artifact_budget
7305
7499
  if not artifact_budget.get("ok"):
7306
- payload["error"] = "artifact budget exceeded before staging"
7500
+ if artifact_budget.get("code") == "ARTIFACT_PREFLIGHT_INVALID":
7501
+ payload["error"] = str(
7502
+ artifact_budget.get("message")
7503
+ or "artifact validation failed before staging"
7504
+ )
7505
+ else:
7506
+ payload["error"] = "artifact budget exceeded before staging"
7307
7507
  payload["issues"] = [
7308
7508
  {
7309
7509
  "code": str(
@@ -7376,6 +7576,38 @@ def cmd_finalize(
7376
7576
  work_dir = operation_temp_dir
7377
7577
  before_manifest: dict[str, Any] | None = None
7378
7578
 
7579
+ # A source tree without sensitive evidence still receives a digest-bound
7580
+ # receipt in the isolated staging tree. This keeps legacy archives
7581
+ # compatible while making every published archive auditable.
7582
+ try:
7583
+ staged_receipt = hruntime.sensitive_evidence_receipt_path(work_dir)
7584
+ if not staged_receipt.is_file():
7585
+ hruntime.ensure_sensitive_evidence_scan_receipt(work_dir)
7586
+ staged_sensitive_gate = validate_sensitive_evidence_publication_gate(
7587
+ work_dir,
7588
+ copy_root=work_dir,
7589
+ require_receipt=True,
7590
+ )
7591
+ payload["steps"]["sensitive_evidence_publication"] = staged_sensitive_gate
7592
+ if not staged_sensitive_gate.get("ok"):
7593
+ payload["error"] = "sensitive evidence publication gate failed before freeze"
7594
+ payload["issues"] = [
7595
+ {
7596
+ "code": str(
7597
+ staged_sensitive_gate.get("reasonCode")
7598
+ or "SECRET_SCAN_GATE_BLOCKED"
7599
+ ),
7600
+ "severity": "error",
7601
+ "message": payload["error"],
7602
+ }
7603
+ ]
7604
+ _restore_finalize_failure()
7605
+ return 1, payload
7606
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
7607
+ payload["error"] = f"sensitive evidence publication gate failed: {exc}"
7608
+ _restore_finalize_failure()
7609
+ return 1, payload
7610
+
7379
7611
  if split_state_dir is not None and split_state_dir.is_dir():
7380
7612
  _merge_runtime_state(split_state_dir, work_dir)
7381
7613
  payload["steps"]["split_state_merge"] = {
@@ -7474,19 +7706,36 @@ def cmd_finalize(
7474
7706
  "blockingCount": len(preflight.get("blocking") or []),
7475
7707
  "itemsCount": len(preflight.get("items") or []),
7476
7708
  }
7477
- if preflight.get("blocking"):
7478
- payload["error"] = (
7479
- f"artifact preflight blocking: "
7480
- f"{len(preflight['blocking'])} path(s) cannot be archived"
7481
- )
7482
- payload["issues"] = [
7483
- {
7484
- "code": "ARTIFACT_PATH_BLOCKING",
7485
- "severity": "error",
7486
- "message": f"{item.get('path', '')}: {item.get('reason', 'blocking')}",
7487
- }
7488
- for item in preflight["blocking"]
7489
- ]
7709
+ if preflight.get("ok") is not True:
7710
+ blocking_paths = preflight.get("blocking") or []
7711
+ if blocking_paths:
7712
+ payload["error"] = (
7713
+ f"artifact preflight blocking: "
7714
+ f"{len(blocking_paths)} path(s) cannot be archived"
7715
+ )
7716
+ payload["issues"] = [
7717
+ {
7718
+ "code": "ARTIFACT_PATH_BLOCKING",
7719
+ "severity": "error",
7720
+ "message": f"{item.get('path', '')}: {item.get('reason', 'blocking')}",
7721
+ }
7722
+ for item in blocking_paths
7723
+ ]
7724
+ else:
7725
+ payload["error"] = (
7726
+ "artifact preflight invalid: "
7727
+ + str(
7728
+ preflight.get("error")
7729
+ or "artifact event projection or preflight validation failed"
7730
+ )
7731
+ )
7732
+ payload["issues"] = [
7733
+ {
7734
+ "code": "ARTIFACT_PREFLIGHT_INVALID",
7735
+ "severity": "error",
7736
+ "message": payload["error"],
7737
+ }
7738
+ ]
7490
7739
  _restore_finalize_failure()
7491
7740
  payload["warnings"] = warnings
7492
7741
  payload["ok"] = False