@hunter-harness/workflow-harness 0.2.40 → 0.2.42

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 (246) hide show
  1. package/harness/bundles/general/claude-code/.harness-build.json +1 -1
  2. package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
  3. package/harness/bundles/general/claude-code/harness-archive/checklist.md +3 -0
  4. package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +22 -0
  5. package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
  6. package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +42 -16
  7. package/harness/bundles/general/claude-code/harness-knowledge-ingest/reference.md +57 -6
  8. package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  9. package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
  10. package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
  11. package/harness/bundles/general/claude-code/harness-plan/reference.md +16 -16
  12. package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
  13. package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
  14. package/harness/bundles/general/claude-code/harness-run/reference.md +1 -1
  15. package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
  16. package/harness/bundles/general/claude-code/harness-sync/SKILL.md +16 -10
  17. package/harness/bundles/general/claude-code/harness-sync/reference.md +34 -14
  18. package/harness/bundles/general/claude-code/harness-test/SKILL.md +3 -1
  19. package/harness/bundles/general/claude-code/protocols/archive-report-protocol.md +10 -0
  20. package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +12 -0
  21. package/harness/bundles/general/claude-code/protocols/powershell-protocol.md +21 -0
  22. package/harness/bundles/general/claude-code/protocols/state-layout-protocol.md +11 -0
  23. package/harness/bundles/general/claude-code/scripts/harness_archive.py +413 -2
  24. package/harness/bundles/general/claude-code/scripts/harness_environment.py +556 -39
  25. package/harness/bundles/general/claude-code/scripts/harness_gate.py +145 -0
  26. package/harness/bundles/general/claude-code/scripts/harness_ledger.py +581 -55
  27. package/harness/bundles/general/claude-code/scripts/harness_plan_finalize.py +85 -6
  28. package/harness/bundles/general/claude-code/scripts/harness_service.py +291 -22
  29. package/harness/bundles/general/claude-code/scripts/harness_test_runner.py +405 -25
  30. package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
  31. package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
  32. package/harness/bundles/general/codebuddy/harness-archive/checklist.md +3 -0
  33. package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +22 -0
  34. package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
  35. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +41 -15
  36. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/reference.md +57 -6
  37. package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  38. package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  39. package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
  40. package/harness/bundles/general/codebuddy/harness-plan/reference.md +16 -16
  41. package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
  42. package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
  43. package/harness/bundles/general/codebuddy/harness-run/reference.md +1 -1
  44. package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
  45. package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +16 -10
  46. package/harness/bundles/general/codebuddy/harness-sync/reference.md +34 -14
  47. package/harness/bundles/general/codebuddy/harness-test/SKILL.md +3 -1
  48. package/harness/bundles/general/codebuddy/protocols/archive-report-protocol.md +10 -0
  49. package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +12 -0
  50. package/harness/bundles/general/codebuddy/protocols/powershell-protocol.md +21 -0
  51. package/harness/bundles/general/codebuddy/protocols/state-layout-protocol.md +11 -0
  52. package/harness/bundles/general/codebuddy/scripts/harness_archive.py +413 -2
  53. package/harness/bundles/general/codebuddy/scripts/harness_environment.py +556 -39
  54. package/harness/bundles/general/codebuddy/scripts/harness_gate.py +145 -0
  55. package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +581 -55
  56. package/harness/bundles/general/codebuddy/scripts/harness_plan_finalize.py +85 -6
  57. package/harness/bundles/general/codebuddy/scripts/harness_service.py +291 -22
  58. package/harness/bundles/general/codebuddy/scripts/harness_test_runner.py +405 -25
  59. package/harness/bundles/general/codex/.harness-build.json +1 -1
  60. package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
  61. package/harness/bundles/general/codex/harness-archive/checklist.md +3 -0
  62. package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +22 -0
  63. package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
  64. package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +41 -15
  65. package/harness/bundles/general/codex/harness-knowledge-ingest/reference.md +57 -6
  66. package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  67. package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
  68. package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
  69. package/harness/bundles/general/codex/harness-plan/reference.md +16 -16
  70. package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
  71. package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
  72. package/harness/bundles/general/codex/harness-run/reference.md +1 -1
  73. package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
  74. package/harness/bundles/general/codex/harness-sync/SKILL.md +16 -10
  75. package/harness/bundles/general/codex/harness-sync/reference.md +34 -14
  76. package/harness/bundles/general/codex/harness-test/SKILL.md +3 -1
  77. package/harness/bundles/general/codex/protocols/archive-report-protocol.md +10 -0
  78. package/harness/bundles/general/codex/protocols/ledger-protocol.md +12 -0
  79. package/harness/bundles/general/codex/protocols/powershell-protocol.md +21 -0
  80. package/harness/bundles/general/codex/protocols/state-layout-protocol.md +11 -0
  81. package/harness/bundles/general/codex/scripts/harness_archive.py +413 -2
  82. package/harness/bundles/general/codex/scripts/harness_environment.py +556 -39
  83. package/harness/bundles/general/codex/scripts/harness_gate.py +145 -0
  84. package/harness/bundles/general/codex/scripts/harness_ledger.py +581 -55
  85. package/harness/bundles/general/codex/scripts/harness_plan_finalize.py +85 -6
  86. package/harness/bundles/general/codex/scripts/harness_service.py +291 -22
  87. package/harness/bundles/general/codex/scripts/harness_test_runner.py +405 -25
  88. package/harness/bundles/general/cursor/.harness-build.json +1 -1
  89. package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
  90. package/harness/bundles/general/cursor/harness-archive/checklist.md +3 -0
  91. package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +22 -0
  92. package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
  93. package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +41 -15
  94. package/harness/bundles/general/cursor/harness-knowledge-ingest/reference.md +57 -6
  95. package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  96. package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
  97. package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
  98. package/harness/bundles/general/cursor/harness-plan/reference.md +16 -16
  99. package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
  100. package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
  101. package/harness/bundles/general/cursor/harness-run/reference.md +1 -1
  102. package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
  103. package/harness/bundles/general/cursor/harness-sync/SKILL.md +16 -10
  104. package/harness/bundles/general/cursor/harness-sync/reference.md +34 -14
  105. package/harness/bundles/general/cursor/harness-test/SKILL.md +3 -1
  106. package/harness/bundles/general/cursor/protocols/archive-report-protocol.md +10 -0
  107. package/harness/bundles/general/cursor/protocols/ledger-protocol.md +12 -0
  108. package/harness/bundles/general/cursor/protocols/powershell-protocol.md +21 -0
  109. package/harness/bundles/general/cursor/protocols/state-layout-protocol.md +11 -0
  110. package/harness/bundles/general/cursor/scripts/harness_archive.py +413 -2
  111. package/harness/bundles/general/cursor/scripts/harness_environment.py +556 -39
  112. package/harness/bundles/general/cursor/scripts/harness_gate.py +145 -0
  113. package/harness/bundles/general/cursor/scripts/harness_ledger.py +581 -55
  114. package/harness/bundles/general/cursor/scripts/harness_plan_finalize.py +85 -6
  115. package/harness/bundles/general/cursor/scripts/harness_service.py +291 -22
  116. package/harness/bundles/general/cursor/scripts/harness_test_runner.py +405 -25
  117. package/harness/bundles/java/claude-code/.harness-build.json +1 -1
  118. package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
  119. package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
  120. package/harness/bundles/java/claude-code/harness-archive/checklist.md +3 -0
  121. package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +22 -0
  122. package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
  123. package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +42 -16
  124. package/harness/bundles/java/claude-code/harness-knowledge-ingest/reference.md +57 -6
  125. package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  126. package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
  127. package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
  128. package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
  129. package/harness/bundles/java/claude-code/harness-plan/reference.md +16 -16
  130. package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
  131. package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
  132. package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
  133. package/harness/bundles/java/claude-code/harness-sync/SKILL.md +16 -10
  134. package/harness/bundles/java/claude-code/harness-sync/reference.md +34 -14
  135. package/harness/bundles/java/claude-code/harness-test/SKILL.md +3 -1
  136. package/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +10 -0
  137. package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +12 -0
  138. package/harness/bundles/java/claude-code/protocols/powershell-protocol.md +21 -0
  139. package/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +11 -0
  140. package/harness/bundles/java/claude-code/scripts/harness_archive.py +413 -2
  141. package/harness/bundles/java/claude-code/scripts/harness_environment.py +556 -39
  142. package/harness/bundles/java/claude-code/scripts/harness_gate.py +145 -0
  143. package/harness/bundles/java/claude-code/scripts/harness_ledger.py +581 -55
  144. package/harness/bundles/java/claude-code/scripts/harness_plan_finalize.py +85 -6
  145. package/harness/bundles/java/claude-code/scripts/harness_service.py +291 -22
  146. package/harness/bundles/java/claude-code/scripts/harness_test_runner.py +405 -25
  147. package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
  148. package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
  149. package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
  150. package/harness/bundles/java/codebuddy/harness-archive/checklist.md +3 -0
  151. package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +22 -0
  152. package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
  153. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +41 -15
  154. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/reference.md +57 -6
  155. package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  156. package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
  157. package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
  158. package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
  159. package/harness/bundles/java/codebuddy/harness-plan/reference.md +16 -16
  160. package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
  161. package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
  162. package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
  163. package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +16 -10
  164. package/harness/bundles/java/codebuddy/harness-sync/reference.md +34 -14
  165. package/harness/bundles/java/codebuddy/harness-test/SKILL.md +3 -1
  166. package/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +10 -0
  167. package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +12 -0
  168. package/harness/bundles/java/codebuddy/protocols/powershell-protocol.md +21 -0
  169. package/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +11 -0
  170. package/harness/bundles/java/codebuddy/scripts/harness_archive.py +413 -2
  171. package/harness/bundles/java/codebuddy/scripts/harness_environment.py +556 -39
  172. package/harness/bundles/java/codebuddy/scripts/harness_gate.py +145 -0
  173. package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +581 -55
  174. package/harness/bundles/java/codebuddy/scripts/harness_plan_finalize.py +85 -6
  175. package/harness/bundles/java/codebuddy/scripts/harness_service.py +291 -22
  176. package/harness/bundles/java/codebuddy/scripts/harness_test_runner.py +405 -25
  177. package/harness/bundles/java/codex/.harness-build.json +1 -1
  178. package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
  179. package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
  180. package/harness/bundles/java/codex/harness-archive/checklist.md +3 -0
  181. package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +22 -0
  182. package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
  183. package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +41 -15
  184. package/harness/bundles/java/codex/harness-knowledge-ingest/reference.md +57 -6
  185. package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  186. package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
  187. package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
  188. package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
  189. package/harness/bundles/java/codex/harness-plan/reference.md +16 -16
  190. package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
  191. package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
  192. package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
  193. package/harness/bundles/java/codex/harness-sync/SKILL.md +16 -10
  194. package/harness/bundles/java/codex/harness-sync/reference.md +34 -14
  195. package/harness/bundles/java/codex/harness-test/SKILL.md +3 -1
  196. package/harness/bundles/java/codex/protocols/archive-report-protocol.md +10 -0
  197. package/harness/bundles/java/codex/protocols/ledger-protocol.md +12 -0
  198. package/harness/bundles/java/codex/protocols/powershell-protocol.md +21 -0
  199. package/harness/bundles/java/codex/protocols/state-layout-protocol.md +11 -0
  200. package/harness/bundles/java/codex/scripts/harness_archive.py +413 -2
  201. package/harness/bundles/java/codex/scripts/harness_environment.py +556 -39
  202. package/harness/bundles/java/codex/scripts/harness_gate.py +145 -0
  203. package/harness/bundles/java/codex/scripts/harness_ledger.py +581 -55
  204. package/harness/bundles/java/codex/scripts/harness_plan_finalize.py +85 -6
  205. package/harness/bundles/java/codex/scripts/harness_service.py +291 -22
  206. package/harness/bundles/java/codex/scripts/harness_test_runner.py +405 -25
  207. package/harness/bundles/java/cursor/.harness-build.json +1 -1
  208. package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
  209. package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
  210. package/harness/bundles/java/cursor/harness-archive/checklist.md +3 -0
  211. package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +22 -0
  212. package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
  213. package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +41 -15
  214. package/harness/bundles/java/cursor/harness-knowledge-ingest/reference.md +57 -6
  215. package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +1097 -174
  216. package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
  217. package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
  218. package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
  219. package/harness/bundles/java/cursor/harness-plan/reference.md +16 -16
  220. package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
  221. package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
  222. package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
  223. package/harness/bundles/java/cursor/harness-sync/SKILL.md +16 -10
  224. package/harness/bundles/java/cursor/harness-sync/reference.md +34 -14
  225. package/harness/bundles/java/cursor/harness-test/SKILL.md +3 -1
  226. package/harness/bundles/java/cursor/protocols/archive-report-protocol.md +10 -0
  227. package/harness/bundles/java/cursor/protocols/ledger-protocol.md +12 -0
  228. package/harness/bundles/java/cursor/protocols/powershell-protocol.md +21 -0
  229. package/harness/bundles/java/cursor/protocols/state-layout-protocol.md +11 -0
  230. package/harness/bundles/java/cursor/scripts/harness_archive.py +413 -2
  231. package/harness/bundles/java/cursor/scripts/harness_environment.py +556 -39
  232. package/harness/bundles/java/cursor/scripts/harness_gate.py +145 -0
  233. package/harness/bundles/java/cursor/scripts/harness_ledger.py +581 -55
  234. package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +85 -6
  235. package/harness/bundles/java/cursor/scripts/harness_service.py +291 -22
  236. package/harness/bundles/java/cursor/scripts/harness_test_runner.py +405 -25
  237. package/harness/manifests/general/claude-code.json +34 -34
  238. package/harness/manifests/general/codebuddy.json +34 -34
  239. package/harness/manifests/general/codex.json +34 -34
  240. package/harness/manifests/general/cursor.json +34 -34
  241. package/harness/manifests/java/claude-code.json +35 -35
  242. package/harness/manifests/java/codebuddy.json +35 -35
  243. package/harness/manifests/java/codex.json +35 -35
  244. package/harness/manifests/java/cursor.json +35 -35
  245. package/hunter-workflow-family.json +10 -10
  246. package/package.json +1 -1
@@ -1666,6 +1666,38 @@ def _validate_scenario_coverage(change_dir: Path) -> dict[str, Any]:
1666
1666
  }
1667
1667
  if not required_ids:
1668
1668
  return {"ok": True, "code": "NO_LEDGER_REQUIRED_SCENARIOS"}
1669
+ raw_schema_version = (
1670
+ manifest.get("schemaVersion") if isinstance(manifest, dict) else None
1671
+ )
1672
+ if (
1673
+ not isinstance(raw_schema_version, int)
1674
+ or isinstance(raw_schema_version, bool)
1675
+ or raw_schema_version < 1
1676
+ ):
1677
+ return {
1678
+ "ok": False,
1679
+ "code": "SCENARIO_MANIFEST_INVALID",
1680
+ "message": "scenario-manifest.json schemaVersion must be a positive integer",
1681
+ }
1682
+ schema_version = raw_schema_version
1683
+ if schema_version >= 2:
1684
+ missing_mappings = sorted(
1685
+ str(s.get("id"))
1686
+ for s in scenarios
1687
+ if isinstance(s, dict)
1688
+ and str(s.get("id")) in required_ids
1689
+ and any(
1690
+ not str(s.get(field) or "").strip()
1691
+ for field in ("executableTestId", "testFile", "testTitle")
1692
+ )
1693
+ )
1694
+ if missing_mappings:
1695
+ return {
1696
+ "ok": False,
1697
+ "code": "SCENARIO_MANIFEST_INVALID",
1698
+ "message": "required scenarios are missing executable test identities",
1699
+ "missingMappings": missing_mappings,
1700
+ }
1669
1701
 
1670
1702
  try:
1671
1703
  ledger, ledger_path = hl.load_ledger(change_dir)
@@ -1683,6 +1715,119 @@ def _validate_scenario_coverage(change_dir: Path) -> dict[str, Any]:
1683
1715
  "message": "ledger missing; cannot verify required scenario coverage",
1684
1716
  "missing": sorted(required_ids),
1685
1717
  }
1718
+ if schema_version >= 2:
1719
+ coverage_sets: dict[str, set[str]] = {
1720
+ key: set()
1721
+ for key in (
1722
+ "declared",
1723
+ "selected",
1724
+ "collected",
1725
+ "executed",
1726
+ "passed",
1727
+ "skipped",
1728
+ "failed",
1729
+ )
1730
+ }
1731
+ bound: set[str] = set()
1732
+ attempts: dict[str, set[int]] = {}
1733
+ invalid_receipts: list[dict[str, str]] = []
1734
+ validations = ledger.get("validations") or {}
1735
+ if isinstance(validations, dict):
1736
+ for verification, entry in validations.items():
1737
+ if not isinstance(entry, dict):
1738
+ continue
1739
+ ids = entry.get("scenarioIds")
1740
+ if not isinstance(ids, list):
1741
+ continue
1742
+ entry_ids = sorted(
1743
+ {
1744
+ str(item).strip()
1745
+ for item in ids
1746
+ if str(item).strip() in required_ids
1747
+ }
1748
+ )
1749
+ if not entry_ids:
1750
+ continue
1751
+ bound.update(entry_ids)
1752
+ receipt = entry.get("scenarioReceipt")
1753
+ if not isinstance(receipt, dict):
1754
+ invalid_receipts.append(
1755
+ {
1756
+ "verification": str(verification),
1757
+ "code": "SCENARIO_RECEIPT_REQUIRED",
1758
+ }
1759
+ )
1760
+ continue
1761
+ result = hl.validate_scenario_execution_receipt(
1762
+ change_dir=change_dir,
1763
+ scenario_ids=entry_ids,
1764
+ receipt=receipt,
1765
+ )
1766
+ if not result.get("ok"):
1767
+ invalid_receipts.append(
1768
+ {
1769
+ "verification": str(verification),
1770
+ "code": str(
1771
+ result.get("code") or "SCENARIO_RECEIPT_INVALID"
1772
+ ),
1773
+ }
1774
+ )
1775
+ continue
1776
+ receipt_coverage = result["coverage"]
1777
+ for key in coverage_sets:
1778
+ if (
1779
+ key == "passed"
1780
+ and str(entry.get("status") or "").upper() != "OK"
1781
+ ):
1782
+ continue
1783
+ values = receipt_coverage.get(key)
1784
+ if isinstance(values, list):
1785
+ coverage_sets[key].update(
1786
+ str(item) for item in values if str(item) in required_ids
1787
+ )
1788
+ receipt_attempt = result["receipt"].get("attempt")
1789
+ if isinstance(receipt_attempt, int):
1790
+ for scenario_id in receipt_coverage.get("executed") or []:
1791
+ attempts.setdefault(str(scenario_id), set()).add(
1792
+ receipt_attempt
1793
+ )
1794
+
1795
+ passed = coverage_sets["passed"]
1796
+ missing = sorted(required_ids - bound)
1797
+ unexecuted = sorted(required_ids - passed)
1798
+ detail = {
1799
+ key: sorted(values & required_ids)
1800
+ for key, values in coverage_sets.items()
1801
+ }
1802
+ detail.update(
1803
+ {
1804
+ "missing": missing,
1805
+ "unexecuted": unexecuted,
1806
+ "attempts": {
1807
+ scenario_id: sorted(values)
1808
+ for scenario_id, values in sorted(attempts.items())
1809
+ },
1810
+ "invalidReceipts": invalid_receipts,
1811
+ "schemaVersion": schema_version,
1812
+ }
1813
+ )
1814
+ if unexecuted:
1815
+ return {
1816
+ "ok": False,
1817
+ "code": "REQUIRED_SCENARIO_NOT_EXECUTED",
1818
+ "message": (
1819
+ "required scenarios without exact passed execution receipts: "
1820
+ + ", ".join(unexecuted)
1821
+ ),
1822
+ **detail,
1823
+ }
1824
+ return {
1825
+ "ok": True,
1826
+ "code": "SCENARIO_COVERAGE_OK",
1827
+ "covered": sorted(passed),
1828
+ **detail,
1829
+ }
1830
+
1686
1831
  covered: set[str] = set()
1687
1832
  validations = ledger.get("validations") or {}
1688
1833
  if isinstance(validations, dict):