@hunter-harness/workflow-harness 0.2.85 → 0.3.0

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 (282) 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 +46 -17
  3. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +2 -2
  4. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +2 -2
  5. package/harness/bundles/general/claude-code/harness-execute/SKILL.md +189 -0
  6. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +2 -2
  7. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +2 -2
  8. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +10 -9
  9. package/harness/bundles/general/claude-code/harness-plan/checklist.md +19 -91
  10. package/harness/bundles/general/claude-code/harness-plan/protocols.md +3 -1
  11. package/harness/bundles/general/claude-code/harness-plan/reference.md +74 -83
  12. package/harness/bundles/general/claude-code/harness-pull/SKILL.md +1 -1
  13. package/harness/bundles/general/claude-code/harness-push/SKILL.md +1 -1
  14. package/harness/bundles/general/claude-code/harness-review/SKILL.md +3 -3
  15. package/harness/bundles/general/claude-code/harness-review/protocols.md +1 -1
  16. package/harness/bundles/general/claude-code/harness-run/SKILL.md +13 -5
  17. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +2 -2
  18. package/harness/bundles/general/claude-code/harness-submit/checklist.md +1 -1
  19. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
  20. package/harness/bundles/general/claude-code/harness-test/SKILL.md +11 -2
  21. package/harness/bundles/general/claude-code/scripts/harness_adoption_metrics.py +391 -0
  22. package/harness/bundles/general/claude-code/scripts/harness_archive.py +23 -14
  23. package/harness/bundles/general/claude-code/scripts/harness_change.py +25 -7
  24. package/harness/bundles/general/claude-code/scripts/harness_context.py +154 -60
  25. package/harness/bundles/general/claude-code/scripts/harness_events.py +1 -1
  26. package/harness/bundles/general/claude-code/scripts/harness_events_sync.py +1 -0
  27. package/harness/bundles/general/claude-code/scripts/harness_fixback.py +14 -10
  28. package/harness/bundles/general/claude-code/scripts/harness_gate.py +293 -90
  29. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +47 -2
  30. package/harness/bundles/general/claude-code/scripts/harness_paths.py +175 -0
  31. package/harness/bundles/general/claude-code/scripts/harness_phase.py +65 -23
  32. package/harness/bundles/general/claude-code/scripts/harness_plan_finalize.py +140 -874
  33. package/harness/bundles/general/claude-code/scripts/harness_review.py +25 -4
  34. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  35. package/harness/bundles/general/codebuddy/contracts/workflow-policy.json +46 -17
  36. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +2 -2
  37. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +2 -2
  38. package/harness/bundles/general/codebuddy/harness-execute/SKILL.md +170 -0
  39. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +2 -2
  40. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +2 -2
  41. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +10 -9
  42. package/harness/bundles/general/codebuddy/harness-plan/checklist.md +19 -91
  43. package/harness/bundles/general/codebuddy/harness-plan/protocols.md +3 -1
  44. package/harness/bundles/general/codebuddy/harness-plan/reference.md +74 -83
  45. package/harness/bundles/general/codebuddy/harness-pull/SKILL.md +1 -1
  46. package/harness/bundles/general/codebuddy/harness-push/SKILL.md +1 -1
  47. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +3 -3
  48. package/harness/bundles/general/codebuddy/harness-review/protocols.md +1 -1
  49. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +13 -5
  50. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +2 -2
  51. package/harness/bundles/general/codebuddy/harness-submit/checklist.md +1 -1
  52. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
  53. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +11 -2
  54. package/harness/bundles/general/codebuddy/scripts/harness_adoption_metrics.py +391 -0
  55. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +23 -14
  56. package/harness/bundles/general/codebuddy/scripts/harness_change.py +25 -7
  57. package/harness/bundles/general/codebuddy/scripts/harness_context.py +154 -60
  58. package/harness/bundles/general/codebuddy/scripts/harness_events.py +1 -1
  59. package/harness/bundles/general/codebuddy/scripts/harness_events_sync.py +1 -0
  60. package/harness/bundles/general/codebuddy/scripts/harness_fixback.py +14 -10
  61. package/harness/bundles/general/codebuddy/scripts/harness_gate.py +293 -90
  62. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +47 -2
  63. package/harness/bundles/general/codebuddy/scripts/harness_paths.py +175 -0
  64. package/harness/bundles/general/codebuddy/scripts/harness_phase.py +65 -23
  65. package/harness/bundles/general/codebuddy/scripts/harness_plan_finalize.py +140 -874
  66. package/harness/bundles/general/codebuddy/scripts/harness_review.py +25 -4
  67. package/harness/bundles/general/codex/.harness-build.json +1 -1
  68. package/harness/bundles/general/codex/contracts/workflow-policy.json +46 -17
  69. package/harness/bundles/general/codex/harness-archive/SKILL.md +2 -2
  70. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +2 -2
  71. package/harness/bundles/general/codex/harness-execute/SKILL.md +170 -0
  72. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +2 -2
  73. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +2 -2
  74. package/harness/bundles/general/codex/harness-plan/SKILL.md +10 -9
  75. package/harness/bundles/general/codex/harness-plan/checklist.md +19 -91
  76. package/harness/bundles/general/codex/harness-plan/protocols.md +3 -1
  77. package/harness/bundles/general/codex/harness-plan/reference.md +74 -83
  78. package/harness/bundles/general/codex/harness-pull/SKILL.md +1 -1
  79. package/harness/bundles/general/codex/harness-push/SKILL.md +1 -1
  80. package/harness/bundles/general/codex/harness-review/SKILL.md +3 -3
  81. package/harness/bundles/general/codex/harness-review/protocols.md +1 -1
  82. package/harness/bundles/general/codex/harness-run/SKILL.md +13 -5
  83. package/harness/bundles/general/codex/harness-submit/SKILL.md +2 -2
  84. package/harness/bundles/general/codex/harness-submit/checklist.md +1 -1
  85. package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
  86. package/harness/bundles/general/codex/harness-test/SKILL.md +11 -2
  87. package/harness/bundles/general/codex/scripts/harness_adoption_metrics.py +391 -0
  88. package/harness/bundles/general/codex/scripts/harness_archive.py +23 -14
  89. package/harness/bundles/general/codex/scripts/harness_change.py +25 -7
  90. package/harness/bundles/general/codex/scripts/harness_context.py +154 -60
  91. package/harness/bundles/general/codex/scripts/harness_events.py +1 -1
  92. package/harness/bundles/general/codex/scripts/harness_events_sync.py +1 -0
  93. package/harness/bundles/general/codex/scripts/harness_fixback.py +14 -10
  94. package/harness/bundles/general/codex/scripts/harness_gate.py +293 -90
  95. package/harness/bundles/general/codex/scripts/harness_ledger.py +47 -2
  96. package/harness/bundles/general/codex/scripts/harness_paths.py +175 -0
  97. package/harness/bundles/general/codex/scripts/harness_phase.py +65 -23
  98. package/harness/bundles/general/codex/scripts/harness_plan_finalize.py +140 -874
  99. package/harness/bundles/general/codex/scripts/harness_review.py +25 -4
  100. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  101. package/harness/bundles/general/cursor/contracts/workflow-policy.json +46 -17
  102. package/harness/bundles/general/cursor/harness-archive/SKILL.md +2 -2
  103. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +2 -2
  104. package/harness/bundles/general/cursor/harness-execute/SKILL.md +170 -0
  105. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +2 -2
  106. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +2 -2
  107. package/harness/bundles/general/cursor/harness-plan/SKILL.md +10 -9
  108. package/harness/bundles/general/cursor/harness-plan/checklist.md +19 -91
  109. package/harness/bundles/general/cursor/harness-plan/protocols.md +3 -1
  110. package/harness/bundles/general/cursor/harness-plan/reference.md +74 -83
  111. package/harness/bundles/general/cursor/harness-pull/SKILL.md +1 -1
  112. package/harness/bundles/general/cursor/harness-push/SKILL.md +1 -1
  113. package/harness/bundles/general/cursor/harness-review/SKILL.md +3 -3
  114. package/harness/bundles/general/cursor/harness-review/protocols.md +1 -1
  115. package/harness/bundles/general/cursor/harness-run/SKILL.md +13 -5
  116. package/harness/bundles/general/cursor/harness-submit/SKILL.md +2 -2
  117. package/harness/bundles/general/cursor/harness-submit/checklist.md +1 -1
  118. package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
  119. package/harness/bundles/general/cursor/harness-test/SKILL.md +11 -2
  120. package/harness/bundles/general/cursor/scripts/harness_adoption_metrics.py +391 -0
  121. package/harness/bundles/general/cursor/scripts/harness_archive.py +23 -14
  122. package/harness/bundles/general/cursor/scripts/harness_change.py +25 -7
  123. package/harness/bundles/general/cursor/scripts/harness_context.py +154 -60
  124. package/harness/bundles/general/cursor/scripts/harness_events.py +1 -1
  125. package/harness/bundles/general/cursor/scripts/harness_events_sync.py +1 -0
  126. package/harness/bundles/general/cursor/scripts/harness_fixback.py +14 -10
  127. package/harness/bundles/general/cursor/scripts/harness_gate.py +293 -90
  128. package/harness/bundles/general/cursor/scripts/harness_ledger.py +47 -2
  129. package/harness/bundles/general/cursor/scripts/harness_paths.py +175 -0
  130. package/harness/bundles/general/cursor/scripts/harness_phase.py +65 -23
  131. package/harness/bundles/general/cursor/scripts/harness_plan_finalize.py +140 -874
  132. package/harness/bundles/general/cursor/scripts/harness_review.py +25 -4
  133. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  134. package/harness/bundles/java/claude-code/contracts/workflow-policy.json +46 -17
  135. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +2 -2
  136. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +2 -2
  137. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +2 -2
  138. package/harness/bundles/java/claude-code/harness-execute/SKILL.md +189 -0
  139. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +2 -2
  140. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +2 -2
  141. package/harness/bundles/java/claude-code/harness-package/SKILL.md +2 -2
  142. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +10 -9
  143. package/harness/bundles/java/claude-code/harness-plan/checklist.md +19 -91
  144. package/harness/bundles/java/claude-code/harness-plan/protocols.md +3 -1
  145. package/harness/bundles/java/claude-code/harness-plan/reference.md +74 -83
  146. package/harness/bundles/java/claude-code/harness-pull/SKILL.md +1 -1
  147. package/harness/bundles/java/claude-code/harness-push/SKILL.md +1 -1
  148. package/harness/bundles/java/claude-code/harness-review/SKILL.md +3 -3
  149. package/harness/bundles/java/claude-code/harness-review/protocols.md +1 -1
  150. package/harness/bundles/java/claude-code/harness-run/SKILL.md +13 -5
  151. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +2 -2
  152. package/harness/bundles/java/claude-code/harness-submit/checklist.md +1 -1
  153. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
  154. package/harness/bundles/java/claude-code/harness-test/SKILL.md +11 -2
  155. package/harness/bundles/java/claude-code/scripts/harness_adoption_metrics.py +391 -0
  156. package/harness/bundles/java/claude-code/scripts/harness_archive.py +23 -14
  157. package/harness/bundles/java/claude-code/scripts/harness_change.py +25 -7
  158. package/harness/bundles/java/claude-code/scripts/harness_context.py +154 -60
  159. package/harness/bundles/java/claude-code/scripts/harness_events.py +1 -1
  160. package/harness/bundles/java/claude-code/scripts/harness_events_sync.py +1 -0
  161. package/harness/bundles/java/claude-code/scripts/harness_fixback.py +14 -10
  162. package/harness/bundles/java/claude-code/scripts/harness_gate.py +293 -90
  163. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +47 -2
  164. package/harness/bundles/java/claude-code/scripts/harness_paths.py +175 -0
  165. package/harness/bundles/java/claude-code/scripts/harness_phase.py +65 -23
  166. package/harness/bundles/java/claude-code/scripts/harness_plan_finalize.py +140 -874
  167. package/harness/bundles/java/claude-code/scripts/harness_review.py +25 -4
  168. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  169. package/harness/bundles/java/codebuddy/contracts/workflow-policy.json +46 -17
  170. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +2 -2
  171. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +2 -2
  172. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +2 -2
  173. package/harness/bundles/java/codebuddy/harness-execute/SKILL.md +170 -0
  174. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +2 -2
  175. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +2 -2
  176. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +2 -2
  177. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +10 -9
  178. package/harness/bundles/java/codebuddy/harness-plan/checklist.md +19 -91
  179. package/harness/bundles/java/codebuddy/harness-plan/protocols.md +3 -1
  180. package/harness/bundles/java/codebuddy/harness-plan/reference.md +74 -83
  181. package/harness/bundles/java/codebuddy/harness-pull/SKILL.md +1 -1
  182. package/harness/bundles/java/codebuddy/harness-push/SKILL.md +1 -1
  183. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +3 -3
  184. package/harness/bundles/java/codebuddy/harness-review/protocols.md +1 -1
  185. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +13 -5
  186. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +2 -2
  187. package/harness/bundles/java/codebuddy/harness-submit/checklist.md +1 -1
  188. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
  189. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +11 -2
  190. package/harness/bundles/java/codebuddy/scripts/harness_adoption_metrics.py +391 -0
  191. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +23 -14
  192. package/harness/bundles/java/codebuddy/scripts/harness_change.py +25 -7
  193. package/harness/bundles/java/codebuddy/scripts/harness_context.py +154 -60
  194. package/harness/bundles/java/codebuddy/scripts/harness_events.py +1 -1
  195. package/harness/bundles/java/codebuddy/scripts/harness_events_sync.py +1 -0
  196. package/harness/bundles/java/codebuddy/scripts/harness_fixback.py +14 -10
  197. package/harness/bundles/java/codebuddy/scripts/harness_gate.py +293 -90
  198. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +47 -2
  199. package/harness/bundles/java/codebuddy/scripts/harness_paths.py +175 -0
  200. package/harness/bundles/java/codebuddy/scripts/harness_phase.py +65 -23
  201. package/harness/bundles/java/codebuddy/scripts/harness_plan_finalize.py +140 -874
  202. package/harness/bundles/java/codebuddy/scripts/harness_review.py +25 -4
  203. package/harness/bundles/java/codex/.harness-build.json +1 -1
  204. package/harness/bundles/java/codex/contracts/workflow-policy.json +46 -17
  205. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +2 -2
  206. package/harness/bundles/java/codex/harness-archive/SKILL.md +2 -2
  207. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +2 -2
  208. package/harness/bundles/java/codex/harness-execute/SKILL.md +170 -0
  209. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +2 -2
  210. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +2 -2
  211. package/harness/bundles/java/codex/harness-package/SKILL.md +2 -2
  212. package/harness/bundles/java/codex/harness-plan/SKILL.md +10 -9
  213. package/harness/bundles/java/codex/harness-plan/checklist.md +19 -91
  214. package/harness/bundles/java/codex/harness-plan/protocols.md +3 -1
  215. package/harness/bundles/java/codex/harness-plan/reference.md +74 -83
  216. package/harness/bundles/java/codex/harness-pull/SKILL.md +1 -1
  217. package/harness/bundles/java/codex/harness-push/SKILL.md +1 -1
  218. package/harness/bundles/java/codex/harness-review/SKILL.md +3 -3
  219. package/harness/bundles/java/codex/harness-review/protocols.md +1 -1
  220. package/harness/bundles/java/codex/harness-run/SKILL.md +13 -5
  221. package/harness/bundles/java/codex/harness-submit/SKILL.md +2 -2
  222. package/harness/bundles/java/codex/harness-submit/checklist.md +1 -1
  223. package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
  224. package/harness/bundles/java/codex/harness-test/SKILL.md +11 -2
  225. package/harness/bundles/java/codex/scripts/harness_adoption_metrics.py +391 -0
  226. package/harness/bundles/java/codex/scripts/harness_archive.py +23 -14
  227. package/harness/bundles/java/codex/scripts/harness_change.py +25 -7
  228. package/harness/bundles/java/codex/scripts/harness_context.py +154 -60
  229. package/harness/bundles/java/codex/scripts/harness_events.py +1 -1
  230. package/harness/bundles/java/codex/scripts/harness_events_sync.py +1 -0
  231. package/harness/bundles/java/codex/scripts/harness_fixback.py +14 -10
  232. package/harness/bundles/java/codex/scripts/harness_gate.py +293 -90
  233. package/harness/bundles/java/codex/scripts/harness_ledger.py +47 -2
  234. package/harness/bundles/java/codex/scripts/harness_paths.py +175 -0
  235. package/harness/bundles/java/codex/scripts/harness_phase.py +65 -23
  236. package/harness/bundles/java/codex/scripts/harness_plan_finalize.py +140 -874
  237. package/harness/bundles/java/codex/scripts/harness_review.py +25 -4
  238. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  239. package/harness/bundles/java/cursor/contracts/workflow-policy.json +46 -17
  240. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +2 -2
  241. package/harness/bundles/java/cursor/harness-archive/SKILL.md +2 -2
  242. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +2 -2
  243. package/harness/bundles/java/cursor/harness-execute/SKILL.md +170 -0
  244. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +2 -2
  245. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +2 -2
  246. package/harness/bundles/java/cursor/harness-package/SKILL.md +2 -2
  247. package/harness/bundles/java/cursor/harness-plan/SKILL.md +10 -9
  248. package/harness/bundles/java/cursor/harness-plan/checklist.md +19 -91
  249. package/harness/bundles/java/cursor/harness-plan/protocols.md +3 -1
  250. package/harness/bundles/java/cursor/harness-plan/reference.md +74 -83
  251. package/harness/bundles/java/cursor/harness-pull/SKILL.md +1 -1
  252. package/harness/bundles/java/cursor/harness-push/SKILL.md +1 -1
  253. package/harness/bundles/java/cursor/harness-review/SKILL.md +3 -3
  254. package/harness/bundles/java/cursor/harness-review/protocols.md +1 -1
  255. package/harness/bundles/java/cursor/harness-run/SKILL.md +13 -5
  256. package/harness/bundles/java/cursor/harness-submit/SKILL.md +2 -2
  257. package/harness/bundles/java/cursor/harness-submit/checklist.md +1 -1
  258. package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
  259. package/harness/bundles/java/cursor/harness-test/SKILL.md +11 -2
  260. package/harness/bundles/java/cursor/scripts/harness_adoption_metrics.py +391 -0
  261. package/harness/bundles/java/cursor/scripts/harness_archive.py +23 -14
  262. package/harness/bundles/java/cursor/scripts/harness_change.py +25 -7
  263. package/harness/bundles/java/cursor/scripts/harness_context.py +154 -60
  264. package/harness/bundles/java/cursor/scripts/harness_events.py +1 -1
  265. package/harness/bundles/java/cursor/scripts/harness_events_sync.py +1 -0
  266. package/harness/bundles/java/cursor/scripts/harness_fixback.py +14 -10
  267. package/harness/bundles/java/cursor/scripts/harness_gate.py +293 -90
  268. package/harness/bundles/java/cursor/scripts/harness_ledger.py +47 -2
  269. package/harness/bundles/java/cursor/scripts/harness_paths.py +175 -0
  270. package/harness/bundles/java/cursor/scripts/harness_phase.py +65 -23
  271. package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +140 -874
  272. package/harness/bundles/java/cursor/scripts/harness_review.py +25 -4
  273. package/harness/manifests/general/claude-code.json +40 -32
  274. package/harness/manifests/general/codebuddy.json +40 -32
  275. package/harness/manifests/general/codex.json +40 -32
  276. package/harness/manifests/general/cursor.json +40 -32
  277. package/harness/manifests/java/claude-code.json +42 -34
  278. package/harness/manifests/java/codebuddy.json +42 -34
  279. package/harness/manifests/java/codex.json +42 -34
  280. package/harness/manifests/java/cursor.json +42 -34
  281. package/hunter-workflow-family.json +4 -4
  282. package/package.json +1 -1
@@ -28,6 +28,7 @@ if str(SCRIPTS_DIR) not in sys.path:
28
28
  sys.path.insert(0, str(SCRIPTS_DIR))
29
29
 
30
30
  import harness_paths # noqa: E402
31
+ import harness_plan_finalize as hpf # noqa: E402
31
32
  import harness_profile # noqa: E402
32
33
 
33
34
 
@@ -201,14 +202,16 @@ def frozen_ownership_check(change_dir: Path) -> dict[str, Any]:
201
202
  if not capsule_root.is_dir():
202
203
  return {"ok": True, "code": "OWNERSHIP_FREEZE_NOT_APPLICABLE"}
203
204
  capsules: list[dict[str, Any]] = []
204
- for path in capsule_root.glob("run-*.json"):
205
+ # capsule 文件名是 <phase>-<hash>.json;execute 合并(run/test→execute)后
206
+ # 新旧两批名字都可能躺在在途 change 里,按内容归一判定而不是按文件名。
207
+ for path in capsule_root.glob("*.json"):
205
208
  try:
206
209
  item = json.loads(path.read_text(encoding="utf-8-sig"))
207
210
  except (OSError, json.JSONDecodeError):
208
211
  continue
209
212
  if (
210
213
  isinstance(item, dict)
211
- and item.get("phase") == "run"
214
+ and harness_paths.resolve_phase_name(item.get("phase")) == "execute"
212
215
  and not item.get("closedAt")
213
216
  and _nonempty_str(item.get("ownershipHash"))
214
217
  ):
@@ -1629,6 +1632,24 @@ def _scenario_receipt_error(code: str, message: str) -> dict[str, Any]:
1629
1632
  return {"ok": False, "code": code, "error": message}
1630
1633
 
1631
1634
 
1635
+ def resolve_scenario_manifest(manifest: Any) -> dict[str, Any]:
1636
+ """把 v2 artifact 包装体解成 legacy 形状;legacy 输入原样返回。
1637
+
1638
+ 解包规则住在 harness_plan_finalize(它定义了 legacy manifest 的 schema),
1639
+ 门禁与本模块共用同一份,两边不会各推一套。
1640
+
1641
+ 此前这里只判包装体、一律 fail-closed;更早的时候连判都不判——cmd_record
1642
+ 的版本探测初值是 0,包装体探测不出 schemaVersion 就停在 0,
1643
+ `manifest_schema >= 2` 判假,--scenario-receipt-file 的强制要求被静默跳过。
1644
+
1645
+ 返回 ``{"ok": True, "manifest": ...}`` 或 ``{"ok": False, "code": ...}``。
1646
+ """
1647
+ unpacked = hpf.unpack_v2_scenario_manifest(manifest)
1648
+ if unpacked is None:
1649
+ return {"ok": True, "manifest": manifest}
1650
+ return unpacked
1651
+
1652
+
1632
1653
  def _resolve_receipt_path(
1633
1654
  raw: str, change_dir: Path
1634
1655
  ) -> tuple[Path | None, list[Path]]:
@@ -1694,6 +1715,12 @@ def validate_scenario_execution_receipt(
1694
1715
  )
1695
1716
  except (OSError, json.JSONDecodeError) as exc:
1696
1717
  return _scenario_receipt_error("SCENARIO_MANIFEST_INVALID", str(exc))
1718
+ resolved = resolve_scenario_manifest(manifest)
1719
+ if not resolved["ok"]:
1720
+ return _scenario_receipt_error(
1721
+ str(resolved["code"]), str(resolved.get("message") or "")
1722
+ )
1723
+ manifest = resolved["manifest"]
1697
1724
  if not isinstance(manifest, dict) or not isinstance(manifest.get("scenarios"), list):
1698
1725
  return _scenario_receipt_error(
1699
1726
  "SCENARIO_MANIFEST_INVALID",
@@ -2827,6 +2854,15 @@ def cmd_record(args: argparse.Namespace) -> int:
2827
2854
  as_json=as_json,
2828
2855
  error_code="SCENARIO_MANIFEST_INVALID",
2829
2856
  )
2857
+ resolved_probe = resolve_scenario_manifest(manifest_probe)
2858
+ if not resolved_probe["ok"]:
2859
+ return emit_error(
2860
+ str(resolved_probe.get("message") or ""),
2861
+ as_json=as_json,
2862
+ error_code=str(resolved_probe["code"]),
2863
+ extra={"artifactType": "scenario_manifest"},
2864
+ )
2865
+ manifest_probe = resolved_probe["manifest"]
2830
2866
  raw_schema = (
2831
2867
  manifest_probe.get("schemaVersion")
2832
2868
  if isinstance(manifest_probe, dict)
@@ -3064,6 +3100,15 @@ def cmd_scenario_receipt_template(args: argparse.Namespace) -> int:
3064
3100
  as_json=as_json,
3065
3101
  error_code="SCENARIO_MANIFEST_INVALID",
3066
3102
  )
3103
+ resolved = resolve_scenario_manifest(manifest)
3104
+ if not resolved["ok"]:
3105
+ return emit_error(
3106
+ str(resolved.get("message") or ""),
3107
+ as_json=as_json,
3108
+ error_code=str(resolved["code"]),
3109
+ extra={"artifactType": "scenario_manifest"},
3110
+ )
3111
+ manifest = resolved["manifest"]
3067
3112
  scenarios = manifest.get("scenarios") if isinstance(manifest, dict) else None
3068
3113
  if not isinstance(scenarios, list):
3069
3114
  return emit_error(
@@ -34,6 +34,67 @@ if hasattr(sys.stderr, "reconfigure"):
34
34
  LIFECYCLE_STATUSES = {"draft", "active", "superseded", "archived", "cancelled"}
35
35
  CHANGE_CONTEXT_REL = Path("meta") / "change-context.json"
36
36
 
37
+ # 工作流阶段的唯一权威清单。这里是叶子模块(不 import 任何 harness_*),所以
38
+ # harness_context 与 harness_phase 都能引它而不成环。
39
+ #
40
+ # 此前这份清单在两个模块各写一遍,靠约定保持同步——直到 harness_phase 少了一个
41
+ # merge,worktree 变更走到 merge 阶段就在 target_required_dag 里直接 raise
42
+ # "unsupported reconcile target phase"。同一份事实不该有两个副本。
43
+ WORKFLOW_PHASES = (
44
+ "plan",
45
+ "execute",
46
+ "review",
47
+ "package",
48
+ "apidoc",
49
+ "submit",
50
+ "merge",
51
+ "archive",
52
+ )
53
+
54
+ # 出现在阶段位置、但不是工作流阶段的名字。它们是真实存在的:
55
+ # workflow-policy.json 的 skills.*.phase 用 sync/codebase-map/knowledge-query 标注
56
+ # 技能归属,harness_gate.GATE_RELEASE_PHASES 含 release/deploy。把它们与"拼错的
57
+ # 阶段名"区分开,调用方才能既不误判也不硬崩。
58
+ KNOWN_NON_WORKFLOW_PHASES = frozenset({
59
+ "release",
60
+ "deploy",
61
+ "sync",
62
+ "codebase-map",
63
+ "knowledge-query",
64
+ "knowledge-ingest",
65
+ "push",
66
+ "pull",
67
+ })
68
+
69
+ # 旧阶段名 → 现阶段名。阶段合并/改名时在这里登记,读时映射即可让历史
70
+ # gate-policy.json、plannedPhases 与已落盘 transitions 继续可读,不必迁移
71
+ # 已落盘的 change。注意:映射只能用在哈希校验之后的业务比较层——对已哈希
72
+ # 的 receipt 先映射再重算会断 _payload_hash 链。
73
+ # 2026-08 run+test 合并为 execute(方案 c,review 保留独立阶段)。
74
+ LEGACY_PHASE_ALIASES: dict[str, str] = {"run": "execute", "test": "execute"}
75
+
76
+
77
+ def resolve_phase_name(phase: Any) -> str | None:
78
+ """把可能是旧名的阶段解析成当前的工作流阶段名;不是工作流阶段则返回 None。"""
79
+ name = str(phase or "").strip()
80
+ if name in WORKFLOW_PHASES:
81
+ return name
82
+ mapped = LEGACY_PHASE_ALIASES.get(name)
83
+ return mapped if mapped in WORKFLOW_PHASES else None
84
+
85
+
86
+ def classify_phase_name(phase: Any) -> str:
87
+ """三态判定:``workflow`` | ``non_workflow`` | ``unknown``。
88
+
89
+ 调用方需要区分这三者:``workflow`` 照常处理;``non_workflow`` 是别的子系统
90
+ 的标注,跳过而不是报错;只有 ``unknown`` 才是真的有问题,值得让人看见。
91
+ """
92
+ if resolve_phase_name(phase) is not None:
93
+ return "workflow"
94
+ if str(phase or "").strip() in KNOWN_NON_WORKFLOW_PHASES:
95
+ return "non_workflow"
96
+ return "unknown"
97
+
37
98
 
38
99
  def _git_text(cwd: Path, *args: str) -> str | None:
39
100
  proc = subprocess.run(
@@ -170,6 +231,120 @@ def load_change_contract(contract_dir: Path) -> dict[str, Any]:
170
231
  return data
171
232
 
172
233
 
234
+ def _unpack_v2_gate_policy(wrapper: Any) -> dict[str, Any] | None:
235
+ """meta/plan-profile.json(v2 包装体)→ Python schemaVersion:1 形状。
236
+
237
+ 门禁权威所需的四个字段(mode/planned_phases/required_gate_dag/
238
+ required_validations_by_phase)缺一即视为不完整快照(0.2.92-era 的发布
239
+ 没有门禁 overlay),调用方回退工作副本。返回 None 表示不可用作权威。
240
+ """
241
+ if not isinstance(wrapper, dict):
242
+ return None
243
+ if wrapper.get("artifact_type") != "gate_policy":
244
+ return None
245
+ content = wrapper.get("content")
246
+ if not isinstance(content, dict):
247
+ return None
248
+ planned = content.get("planned_phases")
249
+ dag = content.get("required_gate_dag")
250
+ by_phase = content.get("required_validations_by_phase")
251
+ if (
252
+ not isinstance(content.get("mode"), str)
253
+ or not (isinstance(planned, list) and all(isinstance(p, str) for p in planned))
254
+ or not isinstance(dag, dict)
255
+ or not isinstance(by_phase, dict)
256
+ ):
257
+ return None
258
+ policy: dict[str, Any] = {
259
+ "schemaVersion": 1,
260
+ "tier": content.get("tier"),
261
+ "source": content.get("source"),
262
+ "plannedPhases": list(planned),
263
+ "requiredValidations": list(content.get("required_validations") or []),
264
+ "requiredValidationsByPhase": dict(by_phase),
265
+ "requiredGateDag": dict(dag),
266
+ }
267
+ return policy
268
+
269
+
270
+ def load_change_gate_policy(change_dir: Path) -> dict[str, Any]:
271
+ """v2-first 的每 change 门禁策略加载(权威切换 2026-08)。
272
+
273
+ meta/plan-profile.json(v2 发布快照,门禁字段已哈希绑定)优先于
274
+ meta/gate-policy.json(classify 在 0.5 写的工作副本)。v2 快照不完整
275
+ 或缺失 → 回退工作副本。两者并存且 plannedPhases(canonical 归一去重
276
+ 后)不一致 → drift 报告,策略以 v2 为准(已审批定稿 > 工作副本;
277
+ 发布后改写工作副本本身就是异常)。
278
+
279
+ 返回 ``{"policy": <schemaVersion:1 dict 或 None>, "source":
280
+ "v2-plan-profile" | "gate-policy-json" | None, "drift": dict | None,
281
+ "working_error": bool}``——``working_error`` 区分"工作副本不存在"与
282
+ "存在但不可读"(`_phase_plan` 的 legacy:policy-unreadable 语义靠它)。
283
+ """
284
+ change_dir = Path(change_dir)
285
+ v2_policy: dict[str, Any] | None = None
286
+ v2_path = change_dir / "meta" / "plan-profile.json"
287
+ if v2_path.is_file():
288
+ try:
289
+ v2_policy = _unpack_v2_gate_policy(
290
+ json.loads(v2_path.read_text(encoding="utf-8-sig"))
291
+ )
292
+ except (OSError, ValueError, json.JSONDecodeError):
293
+ v2_policy = None
294
+
295
+ working: dict[str, Any] | None = None
296
+ working_error = False
297
+ working_path = change_dir / "meta" / "gate-policy.json"
298
+ if working_path.is_file():
299
+ try:
300
+ candidate = json.loads(working_path.read_text(encoding="utf-8-sig"))
301
+ # 工作副本保持与历史一致的宽松接受:任何 dict 都交给下游各自的
302
+ # 形状校验(effective_workflow_policy 查 schemaVersion,reconcile
303
+ # 查 requiredGateDag),加载器不提前收紧。
304
+ if isinstance(candidate, dict):
305
+ working = candidate
306
+ else:
307
+ working_error = True
308
+ except (OSError, ValueError, json.JSONDecodeError):
309
+ working_error = True
310
+
311
+ drift: dict[str, Any] | None = None
312
+ if v2_policy is not None and working is not None:
313
+ canonical = lambda names: sorted(
314
+ {name for raw in (names or []) if (name := resolve_phase_name(raw))}
315
+ )
316
+ v2_phases = canonical(v2_policy.get("plannedPhases"))
317
+ working_phases = canonical(working.get("plannedPhases"))
318
+ if v2_phases != working_phases:
319
+ drift = {
320
+ "kind": "plannedPhases",
321
+ "v2": v2_phases,
322
+ "gate_policy_json": working_phases,
323
+ "resolution": "v2-plan-profile wins (approved publication snapshot)",
324
+ }
325
+
326
+ if v2_policy is not None:
327
+ return {
328
+ "policy": v2_policy,
329
+ "source": "v2-plan-profile",
330
+ "drift": drift,
331
+ "working_error": working_error,
332
+ }
333
+ if working is not None:
334
+ return {
335
+ "policy": working,
336
+ "source": "gate-policy-json",
337
+ "drift": None,
338
+ "working_error": False,
339
+ }
340
+ return {
341
+ "policy": None,
342
+ "source": None,
343
+ "drift": None,
344
+ "working_error": working_error,
345
+ }
346
+
347
+
173
348
  def contract_layout_kind(contract: dict[str, Any]) -> str:
174
349
  """``split-v1`` when the contract declares a separate runtime root."""
175
350
  ownership = contract.get("stateOwnership")
@@ -33,14 +33,16 @@ import harness_paths as hpaths # noqa: E402
33
33
 
34
34
  SCHEMA_VERSION = 1
35
35
  CI_METRICS_SCHEMA_VERSION = 1
36
- PHASE_ORDER = ("plan", "run", "test", "review", "package", "apidoc", "submit", "archive")
36
+ # 唯一权威清单在 harness_paths,harness_context 引的是同一个对象。此前这里另有
37
+ # 一份拷贝,少了 merge,worktree 变更走到 merge 就在 target_required_dag 里硬 raise。
38
+ PHASE_ORDER = hpaths.WORKFLOW_PHASES
37
39
  VALIDATION_PHASES = {
38
- "compile": "run",
39
- "unitTest": "run",
40
- "unitTestFull": "test",
41
- "apiTest": "test",
42
- "browserTest": "test",
43
- "dbCompatibility": "test",
40
+ "compile": "execute",
41
+ "unitTest": "execute",
42
+ "unitTestFull": "execute",
43
+ "apiTest": "execute",
44
+ "browserTest": "execute",
45
+ "dbCompatibility": "execute",
44
46
  "package": "package",
45
47
  }
46
48
  FINAL_SEQUENCE_RECEIPTS_REL = (
@@ -74,10 +76,11 @@ def _write_json(path: Path, value: Any) -> None:
74
76
 
75
77
 
76
78
  def _final_sequence_contract(change_dir: Path) -> dict[str, Any] | None:
77
- policy_path = change_dir / "meta" / "gate-policy.json"
78
- if not policy_path.is_file():
79
+ # 权威切换(2026-08):v2 发布快照优先,classify 工作副本回退。
80
+ loaded = hpaths.load_change_gate_policy(change_dir)
81
+ policy = loaded.get("policy")
82
+ if policy is None:
79
83
  return None
80
- policy = _read_json(policy_path)
81
84
  declared = policy.get("finalSequence")
82
85
  if isinstance(declared, dict) and isinstance(declared.get("nodeIds"), list):
83
86
  return declared
@@ -700,8 +703,18 @@ def target_required_dag(policy: dict[str, Any], target_phase: str) -> dict[str,
700
703
  stage nodes for the target itself are deliberately excluded because their
701
704
  ``phase.end`` is the result of close, not evidence required before close.
702
705
  """
703
- if target_phase not in PHASE_ORDER:
704
- raise ValueError(f"unsupported reconcile target phase: {target_phase}")
706
+ # 未知阶段名先过读时映射:阶段改名后,历史 change gate-policy.json 与
707
+ # plannedPhases 里仍然是旧名,靠 LEGACY_PHASE_ALIASES 继续可读,不必迁移已落盘
708
+ # 的 change(本仓库没有 change 级 schema 迁移机制,硬 raise 等于让在途变更报废)。
709
+ resolved_target = hpaths.resolve_phase_name(target_phase)
710
+ if resolved_target is None:
711
+ raise ValueError(
712
+ f"unsupported reconcile target phase: {target_phase}; "
713
+ f"已知阶段 {', '.join(PHASE_ORDER)}。"
714
+ "若这是改名前的旧阶段,在 harness_paths.LEGACY_PHASE_ALIASES 登记映射;"
715
+ "若这份 gate-policy.json 本身过期,重跑 harness_gate.py classify 重建"
716
+ )
717
+ target_phase = resolved_target
705
718
  dag = policy.get("requiredGateDag")
706
719
  if not isinstance(dag, dict) or not isinstance(dag.get("nodes"), list):
707
720
  raise ValueError("gate policy missing requiredGateDag; run harness_gate.py classify")
@@ -718,9 +731,15 @@ def target_required_dag(policy: dict[str, Any], target_phase: str) -> dict[str,
718
731
  if node_kind == "validation"
719
732
  else node_name
720
733
  )
721
- node_phase = str(node.get("phase") or inferred_phase or "")
722
- if node_phase not in PHASE_ORDER:
723
- raise ValueError(f"requiredGateDag node has unsupported phase: {node_id}")
734
+ raw_phase = str(node.get("phase") or inferred_phase or "")
735
+ node_phase = hpaths.resolve_phase_name(raw_phase)
736
+ if node_phase is None:
737
+ raise ValueError(
738
+ f"requiredGateDag node has unsupported phase: {node_id} (phase={raw_phase!r});"
739
+ "旧阶段名在 harness_paths.LEGACY_PHASE_ALIASES 登记映射,"
740
+ "或重跑 harness_gate.py classify 重建这份 gate-policy.json"
741
+ )
742
+ node["phase"] = node_phase
724
743
  node_rank = PHASE_ORDER.index(node_phase)
725
744
  is_validation = node.get("kind") == "validation" or node_id.startswith(
726
745
  "validation:"
@@ -768,6 +787,13 @@ def select_phase_capsule(
768
787
  "message": f"invalid phase selector: {phase}",
769
788
  "remediation": "pass the phase name emitted by harness_gate.py begin",
770
789
  }
790
+ # 在途 change 的 capsule 可能按旧名(run/test)写入:归一后按 canonical
791
+ # 优先、旧名兜底查找。新写一律 canonical。
792
+ phase = hpaths.resolve_phase_name(phase) or phase
793
+ phase_names = [phase] + [
794
+ legacy for legacy, canonical in hpaths.LEGACY_PHASE_ALIASES.items()
795
+ if canonical == phase
796
+ ]
771
797
  state_dir = hpaths.resolve_state_dir_for_contract(change_dir, project_root)
772
798
  capsule_dir = state_dir / "runtime" / "phase-context"
773
799
  candidates = (
@@ -775,7 +801,7 @@ def select_phase_capsule(
775
801
  path
776
802
  for path in capsule_dir.iterdir()
777
803
  if path.is_file()
778
- and path.name.startswith(f"{phase}-")
804
+ and any(path.name.startswith(f"{name}-") for name in phase_names)
779
805
  and path.suffix == ".json"
780
806
  ]
781
807
  if capsule_dir.is_dir()
@@ -795,14 +821,20 @@ def select_phase_capsule(
795
821
  "message": f"{len(candidates)} capsule(s) exist for phase {phase}",
796
822
  "remediation": f"rerun reconcile with --phase {phase} --run-id <run-id>",
797
823
  }
798
- key = hashlib.sha256(f"{phase}\0{run_id}".encode("utf-8")).hexdigest()[:20]
799
- path = capsule_dir / f"{phase}-{key}.json"
800
- if not path.is_file():
824
+ path: Path | None = None
825
+ for name in phase_names:
826
+ key = hashlib.sha256(f"{name}\0{run_id}".encode("utf-8")).hexdigest()[:20]
827
+ candidate = capsule_dir / f"{name}-{key}.json"
828
+ if candidate.is_file():
829
+ path = candidate
830
+ break
831
+ if path is None:
832
+ key = hashlib.sha256(f"{phase}\0{run_id}".encode("utf-8")).hexdigest()[:20]
801
833
  return {
802
834
  "ok": False,
803
835
  "code": "PHASE_CAPSULE_NOT_FOUND",
804
836
  "message": f"no capsule for phase {phase} and run-id {run_id}",
805
- "expectedPath": str(path),
837
+ "expectedPath": str(capsule_dir / f"{phase}-{key}.json"),
806
838
  "remediation": f"begin/resume the phase or verify --phase {phase} --run-id {run_id}",
807
839
  }
808
840
  try:
@@ -815,7 +847,10 @@ def select_phase_capsule(
815
847
  "path": str(path),
816
848
  "remediation": f"repair or resume the capsule for --phase {phase} --run-id {run_id}",
817
849
  }
818
- if capsule.get("phase") != phase or capsule.get("runId") != run_id:
850
+ if (
851
+ hpaths.resolve_phase_name(capsule.get("phase")) != phase
852
+ or capsule.get("runId") != run_id
853
+ ):
819
854
  return {
820
855
  "ok": False,
821
856
  "code": "PHASE_CAPSULE_IDENTITY_MISMATCH",
@@ -1350,7 +1385,14 @@ def reconcile(
1350
1385
  ) -> dict[str, Any]:
1351
1386
  change_dir = change_dir.resolve()
1352
1387
  project_root = project_root.resolve()
1353
- policy = _read_json(change_dir / "meta" / "gate-policy.json")
1388
+ # 权威切换(2026-08):v2 发布快照优先,classify 工作副本回退。
1389
+ loaded = hpaths.load_change_gate_policy(change_dir)
1390
+ policy = loaded.get("policy")
1391
+ if policy is None:
1392
+ raise ValueError(
1393
+ "gate policy missing; run harness_gate.py classify "
1394
+ "or publish via plan finalize"
1395
+ )
1354
1396
  dag = (
1355
1397
  target_required_dag(policy, target_phase)
1356
1398
  if target_phase is not None
@@ -1615,7 +1657,7 @@ def build_parser() -> argparse.ArgumentParser:
1615
1657
  reconcile_parser.add_argument("--json", action="store_true")
1616
1658
  reconcile_parser.add_argument("--output")
1617
1659
  reconcile_parser.add_argument("--close", action="store_true")
1618
- reconcile_parser.add_argument("--phase", default="run")
1660
+ reconcile_parser.add_argument("--phase", default="execute")
1619
1661
  reconcile_parser.add_argument("--run-id")
1620
1662
  reconcile_parser.set_defaults(func=_cmd_reconcile)
1621
1663