project-tiny-context-harness 0.2.84 → 0.6.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 (361) hide show
  1. package/README.md +163 -428
  2. package/assets/README.md +283 -455
  3. package/assets/README.zh-CN.md +199 -123
  4. package/assets/agents/AGENTS_CORE.md +54 -67
  5. package/assets/context_templates/context.toml +3 -0
  6. package/assets/context_templates/global.md +6 -6
  7. package/assets/github/harness.yml +2 -2
  8. package/assets/skills/context_development_engineer/SKILL.md +91 -107
  9. package/assets/skills/context_product_plan/SKILL.md +18 -28
  10. package/assets/skills/context_surface_contract/SKILL.md +35 -38
  11. package/assets/skills/context_uiux_design/SKILL.md +31 -30
  12. package/assets/skills/long-task-workflow/SKILL.md +76 -0
  13. package/assets/skills/long-task-workflow/agents/openai.yaml +4 -0
  14. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +41 -0
  15. package/assets/skills/long-task-workflow/references/contract-authoring.md +62 -0
  16. package/assets/skills/long-task-workflow/references/evidence-design.md +45 -0
  17. package/assets/skills/normal-long-task/SKILL.md +12 -489
  18. package/assets/skills/source-plan-authoring/SKILL.md +379 -0
  19. package/assets/tools/validate_context.py +293 -127
  20. package/dist/cli.js +3 -1
  21. package/dist/commands/check-modularity.js +33 -10
  22. package/dist/commands/composite-campaign.d.ts +1 -0
  23. package/dist/commands/composite-campaign.js +8 -0
  24. package/dist/commands/composite-long-task.d.ts +1 -6
  25. package/dist/commands/composite-long-task.js +7 -157
  26. package/dist/commands/delivery-set.d.ts +1 -0
  27. package/dist/commands/delivery-set.js +8 -0
  28. package/dist/commands/disable.d.ts +1 -0
  29. package/dist/commands/disable.js +15 -0
  30. package/dist/commands/enable.d.ts +1 -0
  31. package/dist/commands/enable.js +14 -0
  32. package/dist/commands/export-context-args.js +13 -4
  33. package/dist/commands/export-context.js +18 -7
  34. package/dist/commands/index.js +42 -30
  35. package/dist/commands/init.js +12 -6
  36. package/dist/commands/long-task-authoring.d.ts +3 -0
  37. package/dist/commands/long-task-authoring.js +92 -0
  38. package/dist/commands/long-task-explain.d.ts +1 -0
  39. package/dist/commands/long-task-explain.js +52 -0
  40. package/dist/commands/long-task.d.ts +1 -0
  41. package/dist/commands/long-task.js +226 -0
  42. package/dist/commands/package-source.js +2 -2
  43. package/dist/commands/upgrade.js +10 -10
  44. package/dist/index.d.ts +11 -1
  45. package/dist/index.js +8 -0
  46. package/dist/lib/config.js +34 -8
  47. package/dist/lib/context-default-footprint.d.ts +16 -0
  48. package/dist/lib/context-default-footprint.js +107 -0
  49. package/dist/lib/context-export.js +105 -41
  50. package/dist/lib/context-graph-snapshot.d.ts +18 -0
  51. package/dist/lib/context-graph-snapshot.js +171 -0
  52. package/dist/lib/context-manifest-schema.d.ts +28 -0
  53. package/dist/lib/context-manifest-schema.js +150 -0
  54. package/dist/lib/context-manifest.js +28 -20
  55. package/dist/lib/context-templates.js +5 -5
  56. package/dist/lib/design-md.js +1 -1
  57. package/dist/lib/doctor.js +54 -1
  58. package/dist/lib/harness-root.js +25 -8
  59. package/dist/lib/init.js +6 -3
  60. package/dist/lib/legacy-managed-scan.js +23 -7
  61. package/dist/lib/legacy-sdlc-migration.js +21 -11
  62. package/dist/lib/long-task-acceptance-reference.d.ts +22 -0
  63. package/dist/lib/long-task-acceptance-reference.js +46 -0
  64. package/dist/lib/long-task-acceptance-shape.d.ts +5 -0
  65. package/dist/lib/long-task-acceptance-shape.js +131 -0
  66. package/dist/lib/long-task-activation-validation.d.ts +21 -0
  67. package/dist/lib/long-task-activation-validation.js +136 -0
  68. package/dist/lib/long-task-artifacts.d.ts +5 -0
  69. package/dist/lib/long-task-artifacts.js +34 -0
  70. package/dist/lib/long-task-assertions-v2.d.ts +22 -0
  71. package/dist/lib/long-task-assertions-v2.js +212 -0
  72. package/dist/lib/long-task-authoring-authority-preview.d.ts +5 -0
  73. package/dist/lib/long-task-authoring-authority-preview.js +85 -0
  74. package/dist/lib/long-task-authoring-preflight-diagnostics.d.ts +8 -0
  75. package/dist/lib/long-task-authoring-preflight-diagnostics.js +179 -0
  76. package/dist/lib/long-task-authoring-preflight-repair-order.d.ts +8 -0
  77. package/dist/lib/long-task-authoring-preflight-repair-order.js +95 -0
  78. package/dist/lib/long-task-authoring-preflight-types.d.ts +46 -0
  79. package/dist/lib/long-task-authoring-preflight-types.js +38 -0
  80. package/dist/lib/long-task-authoring-preflight.d.ts +3 -0
  81. package/dist/lib/long-task-authoring-preflight.js +44 -0
  82. package/dist/lib/long-task-authority-material-diff.d.ts +17 -0
  83. package/dist/lib/long-task-authority-material-diff.js +152 -0
  84. package/dist/lib/long-task-authority-materials.d.ts +7 -0
  85. package/dist/lib/long-task-authority-materials.js +83 -0
  86. package/dist/lib/long-task-authority-policy.d.ts +168 -0
  87. package/dist/lib/long-task-authority-policy.js +181 -0
  88. package/dist/lib/long-task-authority-revision-details.d.ts +19 -0
  89. package/dist/lib/long-task-authority-revision-details.js +192 -0
  90. package/dist/lib/long-task-authority-revision-enforcement.d.ts +3 -0
  91. package/dist/lib/long-task-authority-revision-enforcement.js +41 -0
  92. package/dist/lib/long-task-authority-revision-types.d.ts +50 -0
  93. package/dist/lib/long-task-authority-revision-types.js +1 -0
  94. package/dist/lib/long-task-authority-revision.d.ts +4 -0
  95. package/dist/lib/long-task-authority-revision.js +188 -0
  96. package/dist/lib/long-task-authority-transition-policy.d.ts +62 -0
  97. package/dist/lib/long-task-authority-transition-policy.js +62 -0
  98. package/dist/lib/long-task-authority-types.d.ts +96 -0
  99. package/dist/lib/long-task-authority-types.js +1 -0
  100. package/dist/lib/long-task-authority.d.ts +7 -0
  101. package/dist/lib/long-task-authority.js +142 -0
  102. package/dist/lib/long-task-boundary-check.d.ts +15 -0
  103. package/dist/lib/long-task-boundary-check.js +9 -0
  104. package/dist/lib/long-task-check-evidence-decoder.d.ts +3 -0
  105. package/dist/lib/long-task-check-evidence-decoder.js +74 -0
  106. package/dist/lib/long-task-check-execution-policy.d.ts +18 -0
  107. package/dist/lib/long-task-check-execution-policy.js +36 -0
  108. package/dist/lib/long-task-check-runner.d.ts +2 -0
  109. package/dist/lib/long-task-check-runner.js +181 -0
  110. package/dist/lib/long-task-check-shape.d.ts +2 -0
  111. package/dist/lib/long-task-check-shape.js +136 -0
  112. package/dist/lib/long-task-claim-definitions.d.ts +7 -0
  113. package/dist/lib/long-task-claim-definitions.js +78 -0
  114. package/dist/lib/long-task-claim-proof-policy.d.ts +4 -0
  115. package/dist/lib/long-task-claim-proof-policy.js +57 -0
  116. package/dist/lib/long-task-claims.d.ts +10 -0
  117. package/dist/lib/long-task-claims.js +187 -0
  118. package/dist/lib/long-task-context-authority-topology.d.ts +7 -0
  119. package/dist/lib/long-task-context-authority-topology.js +37 -0
  120. package/dist/lib/long-task-context-authority.d.ts +14 -0
  121. package/dist/lib/long-task-context-authority.js +66 -0
  122. package/dist/lib/long-task-contract-types.d.ts +203 -0
  123. package/dist/lib/long-task-contract-types.js +1 -0
  124. package/dist/lib/long-task-counterfactual-claim-policy.d.ts +10 -0
  125. package/dist/lib/long-task-counterfactual-claim-policy.js +57 -0
  126. package/dist/lib/long-task-counterfactual-sandbox.d.ts +6 -0
  127. package/dist/lib/long-task-counterfactual-sandbox.js +87 -0
  128. package/dist/lib/long-task-counterfactual-types.d.ts +24 -0
  129. package/dist/lib/long-task-counterfactual-types.js +1 -0
  130. package/dist/lib/long-task-delivery-compiler.d.ts +10 -0
  131. package/dist/lib/long-task-delivery-compiler.js +129 -0
  132. package/dist/lib/long-task-delivery-parser.d.ts +13 -0
  133. package/dist/lib/long-task-delivery-parser.js +90 -0
  134. package/dist/lib/long-task-delivery-preflight.d.ts +5 -0
  135. package/dist/lib/long-task-delivery-preflight.js +151 -0
  136. package/dist/lib/long-task-delivery-shape.d.ts +5 -0
  137. package/dist/lib/long-task-delivery-shape.js +5 -0
  138. package/dist/lib/long-task-delivery-types.d.ts +8 -0
  139. package/dist/lib/long-task-delivery-types.js +8 -0
  140. package/dist/lib/long-task-delivery-validation.d.ts +3 -0
  141. package/dist/lib/long-task-delivery-validation.js +175 -0
  142. package/dist/lib/long-task-evidence-adapter-policy.d.ts +4 -0
  143. package/dist/lib/long-task-evidence-adapter-policy.js +15 -0
  144. package/dist/lib/long-task-evidence-adapter-types.d.ts +1 -0
  145. package/dist/lib/long-task-evidence-adapter-types.js +1 -0
  146. package/dist/lib/long-task-evidence-findings.d.ts +5 -0
  147. package/dist/lib/long-task-evidence-findings.js +113 -0
  148. package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +4 -0
  149. package/dist/lib/long-task-evidence-sensitivity-policy.js +98 -0
  150. package/dist/lib/long-task-evidence-v2.d.ts +5 -0
  151. package/dist/lib/long-task-evidence-v2.js +226 -0
  152. package/dist/lib/long-task-explain-acceptance-link.d.ts +46 -0
  153. package/dist/lib/long-task-explain-acceptance-link.js +96 -0
  154. package/dist/lib/long-task-explain-claim-links.d.ts +45 -0
  155. package/dist/lib/long-task-explain-claim-links.js +88 -0
  156. package/dist/lib/long-task-explain-source-links.d.ts +93 -0
  157. package/dist/lib/long-task-explain-source-links.js +51 -0
  158. package/dist/lib/long-task-final-v2.d.ts +2 -0
  159. package/dist/lib/long-task-final-v2.js +124 -0
  160. package/dist/lib/long-task-finding-context.d.ts +3 -0
  161. package/dist/lib/long-task-finding-context.js +63 -0
  162. package/dist/lib/long-task-freshness.d.ts +3 -0
  163. package/dist/lib/long-task-freshness.js +80 -0
  164. package/dist/lib/long-task-hook-install.d.ts +9 -0
  165. package/dist/lib/long-task-hook-install.js +184 -0
  166. package/dist/lib/long-task-hook-preflight.d.ts +7 -0
  167. package/dist/lib/long-task-hook-preflight.js +58 -0
  168. package/dist/lib/long-task-observation-ownership.d.ts +2 -0
  169. package/dist/lib/long-task-observation-ownership.js +22 -0
  170. package/dist/lib/long-task-outcome-parser.d.ts +4 -0
  171. package/dist/lib/long-task-outcome-parser.js +100 -0
  172. package/dist/lib/long-task-paths.d.ts +49 -0
  173. package/dist/lib/long-task-paths.js +418 -0
  174. package/dist/lib/long-task-playwright-counterfactual-policy.d.ts +7 -0
  175. package/dist/lib/long-task-playwright-counterfactual-policy.js +125 -0
  176. package/dist/lib/long-task-playwright-evidence.d.ts +6 -0
  177. package/dist/lib/long-task-playwright-evidence.js +244 -0
  178. package/dist/lib/long-task-product-shape.d.ts +6 -0
  179. package/dist/lib/long-task-product-shape.js +73 -0
  180. package/dist/lib/long-task-progress.d.ts +4 -0
  181. package/dist/lib/long-task-progress.js +114 -0
  182. package/dist/lib/long-task-protected-files.d.ts +1 -0
  183. package/dist/lib/long-task-protected-files.js +30 -0
  184. package/dist/lib/long-task-required-proof-surfaces.d.ts +2 -0
  185. package/dist/lib/long-task-required-proof-surfaces.js +13 -0
  186. package/dist/lib/long-task-requirement-shape.d.ts +2 -0
  187. package/dist/lib/long-task-requirement-shape.js +18 -0
  188. package/dist/lib/long-task-risk-surfaces.d.ts +2 -0
  189. package/dist/lib/long-task-risk-surfaces.js +60 -0
  190. package/dist/lib/long-task-risk-types.d.ts +5 -0
  191. package/dist/lib/long-task-risk-types.js +12 -0
  192. package/dist/lib/long-task-risk.d.ts +9 -0
  193. package/dist/lib/long-task-risk.js +132 -0
  194. package/dist/lib/long-task-root-shape.d.ts +4 -0
  195. package/dist/lib/long-task-root-shape.js +86 -0
  196. package/dist/lib/long-task-runner-environment.d.ts +7 -0
  197. package/dist/lib/long-task-runner-environment.js +57 -0
  198. package/dist/lib/long-task-runner-files.d.ts +3 -0
  199. package/dist/lib/long-task-runner-files.js +39 -0
  200. package/dist/lib/long-task-runner-freeze.d.ts +2 -0
  201. package/dist/lib/long-task-runner-freeze.js +168 -0
  202. package/dist/lib/long-task-runtime-types.d.ts +214 -0
  203. package/dist/lib/long-task-runtime-types.js +1 -0
  204. package/dist/lib/long-task-shape-primitives.d.ts +17 -0
  205. package/dist/lib/long-task-shape-primitives.js +81 -0
  206. package/dist/lib/long-task-source-authority-types.d.ts +13 -0
  207. package/dist/lib/long-task-source-authority-types.js +1 -0
  208. package/dist/lib/long-task-source-claim-validation.d.ts +5 -0
  209. package/dist/lib/long-task-source-claim-validation.js +96 -0
  210. package/dist/lib/long-task-source-continuity.d.ts +4 -0
  211. package/dist/lib/long-task-source-continuity.js +57 -0
  212. package/dist/lib/long-task-source-inventory.d.ts +2 -0
  213. package/dist/lib/long-task-source-inventory.js +21 -0
  214. package/dist/lib/long-task-source-item-parser.d.ts +3 -0
  215. package/dist/lib/long-task-source-item-parser.js +112 -0
  216. package/dist/lib/long-task-source-shape.d.ts +2 -0
  217. package/dist/lib/long-task-source-shape.js +56 -0
  218. package/dist/lib/long-task-source-target-continuity.d.ts +4 -0
  219. package/dist/lib/long-task-source-target-continuity.js +80 -0
  220. package/dist/lib/long-task-source-target-index.d.ts +12 -0
  221. package/dist/lib/long-task-source-target-index.js +76 -0
  222. package/dist/lib/long-task-source-validation.d.ts +3 -0
  223. package/dist/lib/long-task-source-validation.js +46 -0
  224. package/dist/lib/long-task-state.d.ts +91 -0
  225. package/dist/lib/long-task-state.js +611 -0
  226. package/dist/lib/long-task-status-projection.d.ts +21 -0
  227. package/dist/lib/long-task-status-projection.js +116 -0
  228. package/dist/lib/long-task-status-v2.d.ts +37 -0
  229. package/dist/lib/long-task-status-v2.js +306 -0
  230. package/dist/lib/long-task-technical-shape.d.ts +3 -0
  231. package/dist/lib/long-task-technical-shape.js +44 -0
  232. package/dist/lib/long-task-verifier-authority.d.ts +12 -0
  233. package/dist/lib/long-task-verifier-authority.js +47 -0
  234. package/dist/lib/long-task-verifier-identity.d.ts +2 -0
  235. package/dist/lib/long-task-verifier-identity.js +55 -0
  236. package/dist/lib/long-task-verifier-v2.d.ts +13 -0
  237. package/dist/lib/long-task-verifier-v2.js +266 -0
  238. package/dist/lib/long-task-workspace-runtime-types.d.ts +23 -0
  239. package/dist/lib/long-task-workspace-runtime-types.js +1 -0
  240. package/dist/lib/long-task-workspace.d.ts +25 -0
  241. package/dist/lib/long-task-workspace.js +366 -0
  242. package/dist/lib/managed-file.js +20 -5
  243. package/dist/lib/migrations.js +156 -32
  244. package/dist/lib/modularity.d.ts +27 -1
  245. package/dist/lib/modularity.js +499 -23
  246. package/dist/lib/package-json-config.js +14 -5
  247. package/dist/lib/package-source.js +15 -3
  248. package/dist/lib/profiles.d.ts +13 -0
  249. package/dist/lib/profiles.js +66 -0
  250. package/dist/lib/schema-guard.js +4 -2
  251. package/dist/lib/source-files.js +14 -7
  252. package/dist/lib/source-pack-classify.js +91 -19
  253. package/dist/lib/source-pack-config.js +25 -8
  254. package/dist/lib/source-pack-export.js +84 -25
  255. package/dist/lib/source-pack-manifest.js +18 -6
  256. package/dist/lib/source-pack-records.js +35 -11
  257. package/dist/lib/source-pack-render.js +47 -18
  258. package/dist/lib/stable-json.d.ts +2 -0
  259. package/dist/lib/stable-json.js +21 -0
  260. package/dist/lib/strict-codec.d.ts +4 -0
  261. package/dist/lib/strict-codec.js +65 -0
  262. package/dist/lib/sync-engine.js +76 -24
  263. package/dist/lib/types.d.ts +8 -1
  264. package/dist/lib/upgrade.js +4 -3
  265. package/dist/lib/validators.js +218 -191
  266. package/dist/long-task-hook.d.ts +2 -0
  267. package/dist/long-task-hook.js +55 -0
  268. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +340 -0
  269. package/dist/schemas/long-task-delivery-v2/long-task-outcomes-v2.schema.json +18 -0
  270. package/migrations/README.md +8 -3
  271. package/package.json +17 -6
  272. package/source-mappings.yaml +0 -3
  273. package/assets/protected-harness-baseline.json +0 -20
  274. package/assets/skills/composite-long-task-workflow/SKILL.md +0 -244
  275. package/assets/skills/composite-long-task-workflow/assets/execution-binding.template.md +0 -57
  276. package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +0 -17
  277. package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +0 -675
  278. package/dist/commands/superpowers.d.ts +0 -1
  279. package/dist/commands/superpowers.js +0 -8
  280. package/dist/lib/composite-long-task-renderer.d.ts +0 -12
  281. package/dist/lib/composite-long-task-renderer.js +0 -109
  282. package/dist/lib/plan-acceptance-artifacts.d.ts +0 -1
  283. package/dist/lib/plan-acceptance-artifacts.js +0 -220
  284. package/dist/lib/plan-acceptance-evidence.d.ts +0 -2
  285. package/dist/lib/plan-acceptance-evidence.js +0 -108
  286. package/dist/lib/plan-acceptance-json.d.ts +0 -15
  287. package/dist/lib/plan-acceptance-json.js +0 -133
  288. package/dist/lib/plan-acceptance-validator.d.ts +0 -2
  289. package/dist/lib/plan-acceptance-validator.js +0 -209
  290. package/dist/lib/plan-contract-validator.d.ts +0 -2
  291. package/dist/lib/plan-contract-validator.js +0 -127
  292. package/dist/lib/plan-validator-common.d.ts +0 -24
  293. package/dist/lib/plan-validator-common.js +0 -196
  294. package/dist/lib/superpowers-task-ac010.d.ts +0 -6
  295. package/dist/lib/superpowers-task-ac010.js +0 -26
  296. package/dist/lib/superpowers-task-assertion-normalizers.d.ts +0 -3
  297. package/dist/lib/superpowers-task-assertion-normalizers.js +0 -74
  298. package/dist/lib/superpowers-task-assertions.d.ts +0 -20
  299. package/dist/lib/superpowers-task-assertions.js +0 -257
  300. package/dist/lib/superpowers-task-attempt.d.ts +0 -4
  301. package/dist/lib/superpowers-task-attempt.js +0 -102
  302. package/dist/lib/superpowers-task-command-run-correlation.d.ts +0 -8
  303. package/dist/lib/superpowers-task-command-run-correlation.js +0 -103
  304. package/dist/lib/superpowers-task-command-specs.d.ts +0 -3
  305. package/dist/lib/superpowers-task-command-specs.js +0 -52
  306. package/dist/lib/superpowers-task-compile-diagnostics.d.ts +0 -5
  307. package/dist/lib/superpowers-task-compile-diagnostics.js +0 -20
  308. package/dist/lib/superpowers-task-compile-guards.d.ts +0 -2
  309. package/dist/lib/superpowers-task-compile-guards.js +0 -66
  310. package/dist/lib/superpowers-task-compile.d.ts +0 -6
  311. package/dist/lib/superpowers-task-compile.js +0 -133
  312. package/dist/lib/superpowers-task-completion-output.d.ts +0 -52
  313. package/dist/lib/superpowers-task-completion-output.js +0 -228
  314. package/dist/lib/superpowers-task-conformance.d.ts +0 -2
  315. package/dist/lib/superpowers-task-conformance.js +0 -24
  316. package/dist/lib/superpowers-task-contradictions.d.ts +0 -6
  317. package/dist/lib/superpowers-task-contradictions.js +0 -126
  318. package/dist/lib/superpowers-task-current-evidence.d.ts +0 -3
  319. package/dist/lib/superpowers-task-current-evidence.js +0 -176
  320. package/dist/lib/superpowers-task-delivery.d.ts +0 -4
  321. package/dist/lib/superpowers-task-delivery.js +0 -96
  322. package/dist/lib/superpowers-task-derive.d.ts +0 -14
  323. package/dist/lib/superpowers-task-derive.js +0 -382
  324. package/dist/lib/superpowers-task-events.d.ts +0 -1
  325. package/dist/lib/superpowers-task-events.js +0 -13
  326. package/dist/lib/superpowers-task-evidence-kernel.d.ts +0 -19
  327. package/dist/lib/superpowers-task-evidence-kernel.js +0 -347
  328. package/dist/lib/superpowers-task-evidence-records.d.ts +0 -2
  329. package/dist/lib/superpowers-task-evidence-records.js +0 -55
  330. package/dist/lib/superpowers-task-evidence.d.ts +0 -10
  331. package/dist/lib/superpowers-task-evidence.js +0 -147
  332. package/dist/lib/superpowers-task-fields.d.ts +0 -22
  333. package/dist/lib/superpowers-task-fields.js +0 -276
  334. package/dist/lib/superpowers-task-final-card.d.ts +0 -3
  335. package/dist/lib/superpowers-task-final-card.js +0 -24
  336. package/dist/lib/superpowers-task-gates.d.ts +0 -12
  337. package/dist/lib/superpowers-task-gates.js +0 -155
  338. package/dist/lib/superpowers-task-harness-drift.d.ts +0 -11
  339. package/dist/lib/superpowers-task-harness-drift.js +0 -90
  340. package/dist/lib/superpowers-task-next-slices.d.ts +0 -1
  341. package/dist/lib/superpowers-task-next-slices.js +0 -12
  342. package/dist/lib/superpowers-task-protected-baseline.d.ts +0 -10
  343. package/dist/lib/superpowers-task-protected-baseline.js +0 -66
  344. package/dist/lib/superpowers-task-source-compile.d.ts +0 -5
  345. package/dist/lib/superpowers-task-source-compile.js +0 -226
  346. package/dist/lib/superpowers-task-source-parser.d.ts +0 -23
  347. package/dist/lib/superpowers-task-source-parser.js +0 -218
  348. package/dist/lib/superpowers-task-state-schema.d.ts +0 -440
  349. package/dist/lib/superpowers-task-state-schema.js +0 -66
  350. package/dist/lib/superpowers-task-state-shape.d.ts +0 -3
  351. package/dist/lib/superpowers-task-state-shape.js +0 -50
  352. package/dist/lib/superpowers-task-state.d.ts +0 -16
  353. package/dist/lib/superpowers-task-state.js +0 -246
  354. package/dist/lib/superpowers-task-status.d.ts +0 -2
  355. package/dist/lib/superpowers-task-status.js +0 -24
  356. package/dist/lib/superpowers-task-under-specified.d.ts +0 -7
  357. package/dist/lib/superpowers-task-under-specified.js +0 -61
  358. package/dist/lib/superpowers-task-unregistered-evidence.d.ts +0 -11
  359. package/dist/lib/superpowers-task-unregistered-evidence.js +0 -72
  360. package/dist/lib/superpowers-task-validator.d.ts +0 -5
  361. package/dist/lib/superpowers-task-validator.js +0 -290
@@ -0,0 +1,60 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { matchesRepoPattern } from "./long-task-paths.js";
4
+ import { parseStrictYaml } from "./strict-codec.js";
5
+ export async function validateActualRiskSurfaces(repository, changedPaths, contract) {
6
+ const inferred = new Set();
7
+ const surfaces = await readRiskSurfaces(repository);
8
+ for (const surface of surfaces)
9
+ if (changedPaths.some((changed) => surface.paths.some((pattern) => matchesRepoPattern(changed, pattern)))) {
10
+ if (surface.risk === "classification_required")
11
+ throw new Error("risk_classification_required");
12
+ inferred.add(surface.risk);
13
+ }
14
+ for (const fact of inferred)
15
+ if (contract.risk.facts[fact].length === 0)
16
+ throw new Error(`risk_fact_underdeclared:${fact}`);
17
+ }
18
+ async function readRiskSurfaces(repository) {
19
+ const file = path.join(repository, "project_context", "risk-surfaces.yaml");
20
+ let raw;
21
+ try {
22
+ raw = await readFile(file, "utf8");
23
+ }
24
+ catch (error) {
25
+ if (error.code === "ENOENT")
26
+ return [];
27
+ throw error;
28
+ }
29
+ const value = parseStrictYaml(raw);
30
+ if (!Array.isArray(value))
31
+ throw new Error("risk_surfaces_invalid:root");
32
+ const facts = new Set([
33
+ "public_api_or_schema_change",
34
+ "persistent_data_change",
35
+ "data_migration",
36
+ "security_boundary_change",
37
+ "permission_boundary_change",
38
+ "irreversible_external_effect",
39
+ "critical_user_path",
40
+ "full_population_operation",
41
+ "multi_repository_change",
42
+ "weak_observability",
43
+ "classification_required",
44
+ ]);
45
+ return value.map((item, index) => {
46
+ if (!item || typeof item !== "object" || Array.isArray(item))
47
+ throw new Error(`risk_surfaces_invalid:${index}`);
48
+ const row = item;
49
+ if (Object.keys(row).some((key) => !["risk", "paths"].includes(key)) ||
50
+ typeof row.risk !== "string" ||
51
+ !facts.has(row.risk) ||
52
+ !Array.isArray(row.paths) ||
53
+ row.paths.some((value) => typeof value !== "string" || !value))
54
+ throw new Error(`risk_surfaces_invalid:${index}`);
55
+ return {
56
+ risk: row.risk,
57
+ paths: row.paths,
58
+ };
59
+ });
60
+ }
@@ -0,0 +1,5 @@
1
+ export type RequestedRiskLevel = "auto" | "standard" | "strict";
2
+ export type EffectiveRiskLevel = "standard" | "strict";
3
+ export declare const RISK_FACT_NAMES: readonly ["public_api_or_schema_change", "persistent_data_change", "data_migration", "security_boundary_change", "permission_boundary_change", "irreversible_external_effect", "critical_user_path", "full_population_operation", "multi_repository_change", "weak_observability"];
4
+ export type RiskFactName = (typeof RISK_FACT_NAMES)[number];
5
+ export type LongTaskRiskFacts = Record<RiskFactName, string[]>;
@@ -0,0 +1,12 @@
1
+ export const RISK_FACT_NAMES = [
2
+ "public_api_or_schema_change",
3
+ "persistent_data_change",
4
+ "data_migration",
5
+ "security_boundary_change",
6
+ "permission_boundary_change",
7
+ "irreversible_external_effect",
8
+ "critical_user_path",
9
+ "full_population_operation",
10
+ "multi_repository_change",
11
+ "weak_observability",
12
+ ];
@@ -0,0 +1,9 @@
1
+ import type { DeliveryContractV2, EffectiveRiskLevel, RiskFactName } from "./long-task-delivery-types.js";
2
+ export interface RiskDecisionV2 {
3
+ effective_level: EffectiveRiskLevel;
4
+ minimum_level: EffectiveRiskLevel;
5
+ reasons: string[];
6
+ reasons_by_outcome: Record<string, RiskFactName[]>;
7
+ }
8
+ export declare function classifyLongTaskRisk(contract: DeliveryContractV2): RiskDecisionV2;
9
+ export declare function validateRiskProof(contract: DeliveryContractV2, decision: RiskDecisionV2): void;
@@ -0,0 +1,132 @@
1
+ const STRICT_FACTS = new Set([
2
+ "public_api_or_schema_change",
3
+ "persistent_data_change",
4
+ "data_migration",
5
+ "security_boundary_change",
6
+ "permission_boundary_change",
7
+ "irreversible_external_effect",
8
+ "full_population_operation",
9
+ "multi_repository_change",
10
+ ]);
11
+ export function classifyLongTaskRisk(contract) {
12
+ const outcomeKeys = new Set(contract.outcomes.map((outcome) => outcome.key));
13
+ const reasonsByOutcome = Object.fromEntries(contract.outcomes.map((outcome) => [outcome.key, []]));
14
+ for (const [fact, outcomes] of Object.entries(contract.risk.facts)) {
15
+ for (const outcome of outcomes) {
16
+ if (!outcomeKeys.has(outcome))
17
+ throw new Error(`risk_outcome_unknown:${fact}:${outcome}`);
18
+ reasonsByOutcome[outcome].push(fact);
19
+ }
20
+ }
21
+ if (contract.risk.facts.multi_repository_change.length)
22
+ throw new Error("multi_repository_delivery_not_supported_v2");
23
+ const reasons = Object.entries(reasonsByOutcome)
24
+ .flatMap(([outcome, facts]) => facts
25
+ .filter((fact) => STRICT_FACTS.has(fact))
26
+ .map((fact) => `${fact}:${outcome}`))
27
+ .concat(contract.outcomes
28
+ .filter((outcome) => contract.risk.facts.critical_user_path.includes(outcome.key) &&
29
+ contract.risk.facts.weak_observability.includes(outcome.key))
30
+ .map((outcome) => `critical_user_path_with_weak_observability:${outcome.key}`));
31
+ const minimum = reasons.length ? "strict" : "standard";
32
+ if (contract.risk.requested_level === "standard" && minimum === "strict")
33
+ throw new Error(`risk_level_below_required:${reasons.join(",")}`);
34
+ return {
35
+ minimum_level: minimum,
36
+ effective_level: contract.risk.requested_level === "strict" ? "strict" : minimum,
37
+ reasons,
38
+ reasons_by_outcome: reasonsByOutcome,
39
+ };
40
+ }
41
+ export function validateRiskProof(contract, decision) {
42
+ const errors = [];
43
+ if (!contract.outcomes.length)
44
+ errors.push("outcome_required");
45
+ for (const check of contract.global.acceptance.checks)
46
+ validateCheck(check, "global", errors);
47
+ for (const outcome of contract.outcomes)
48
+ validateOutcome(outcome, errors);
49
+ if (decision.effective_level === "strict")
50
+ validateStrict(contract, decision, errors);
51
+ if (errors.length)
52
+ throw new Error(`delivery_contract_preflight_failed:\n${errors.join("\n")}`);
53
+ }
54
+ function validateOutcome(outcome, errors) {
55
+ const checks = new Map(outcome.acceptance.checks.map((check) => [check.key, check]));
56
+ if (!checks.size)
57
+ errors.push(`outcome_without_executable_check:${outcome.key}`);
58
+ if (!outcome.technical.expected_change_paths.length)
59
+ errors.push(`expected_change_paths_empty:${outcome.key}`);
60
+ for (const check of checks.values())
61
+ validateCheck(check, outcome.key, errors);
62
+ if ((outcome.product.owner_surfaces.length ||
63
+ outcome.product.controls.length) &&
64
+ ![...checks.values()].some((check) => check.proof_surface === "ui_browser"))
65
+ errors.push(`ui_outcome_requires_ui_browser_proof:${outcome.key}`);
66
+ const referenced = [
67
+ ...(outcome.acceptance.population
68
+ ? [outcome.acceptance.population.check_key]
69
+ : []),
70
+ ...outcome.acceptance.counterfactual_controls.map((control) => control.check_key),
71
+ ...(outcome.technical.rollback_and_recovery?.verification_check_keys ?? []),
72
+ ...outcome.technical.bindings.flatMap((binding) => binding.verification_check_key ? [binding.verification_check_key] : []),
73
+ ];
74
+ for (const checkKey of referenced)
75
+ if (!checks.has(checkKey))
76
+ errors.push(`outcome_check_reference_unknown:${outcome.key}:${checkKey}`);
77
+ }
78
+ function validateStrict(contract, decision, errors) {
79
+ const explicitStrictWithoutFacts = contract.risk.requested_level === "strict" && decision.reasons.length === 0;
80
+ for (const outcome of contract.outcomes) {
81
+ const facts = new Set(decision.reasons_by_outcome[outcome.key]);
82
+ const checks = outcome.acceptance.checks;
83
+ const hasNegative = checks.some((check) => check.negative_assertions.length > 0);
84
+ const hasCounterfactual = outcome.acceptance.counterfactual_controls.length > 0;
85
+ if (explicitStrictWithoutFacts) {
86
+ if (!hasNegative)
87
+ errors.push(`strict_negative_assertion_required:${outcome.key}`);
88
+ if (!hasCounterfactual)
89
+ errors.push(`strict_counterfactual_control_required:${outcome.key}`);
90
+ }
91
+ if (facts.has("security_boundary_change") ||
92
+ facts.has("permission_boundary_change"))
93
+ requireStrictProof(outcome, "security_boundary", hasNegative, hasCounterfactual, errors);
94
+ if (facts.has("public_api_or_schema_change"))
95
+ requireStrictProof(outcome, "api_contract", hasNegative, hasCounterfactual, errors);
96
+ if (facts.has("persistent_data_change") || facts.has("data_migration")) {
97
+ requireStrictProof(outcome, "data_state", hasNegative, hasCounterfactual, errors);
98
+ if (!outcome.technical.rollback_and_recovery)
99
+ errors.push(`strict_rollback_and_recovery_required:${outcome.key}`);
100
+ }
101
+ if (facts.has("irreversible_external_effect") &&
102
+ !outcome.technical.rollback_and_recovery)
103
+ errors.push(`strict_rollback_and_recovery_required:${outcome.key}`);
104
+ if (facts.has("full_population_operation")) {
105
+ if (!checks.some((check) => check.proof_surface === "population_coverage"))
106
+ errors.push(`strict_population_coverage_proof_required:${outcome.key}`);
107
+ if (!outcome.acceptance.population)
108
+ errors.push(`strict_population_declaration_required:${outcome.key}`);
109
+ }
110
+ if (facts.has("critical_user_path") &&
111
+ facts.has("weak_observability") &&
112
+ !checks.some((check) => check.proof_surface === "ui_browser" ||
113
+ check.proof_surface === "runtime_behavior"))
114
+ errors.push(`strict_critical_path_observable_proof_required:${outcome.key}`);
115
+ }
116
+ }
117
+ function requireStrictProof(outcome, surface, hasNegative, hasCounterfactual, errors) {
118
+ if (!outcome.acceptance.checks.some((check) => check.proof_surface === surface))
119
+ errors.push(`strict_${surface}_proof_required:${outcome.key}`);
120
+ if (!hasNegative)
121
+ errors.push(`strict_negative_assertion_required:${outcome.key}`);
122
+ if (!hasCounterfactual)
123
+ errors.push(`strict_counterfactual_control_required:${outcome.key}`);
124
+ }
125
+ function validateCheck(check, owner, errors) {
126
+ if (!check.verification_inputs.length)
127
+ errors.push(`verification_inputs_empty:${owner}:${check.key}`);
128
+ if (check.runner.retry_policy === "transient_once" &&
129
+ (!check.runner.idempotent ||
130
+ !["read_only", "test_sandbox"].includes(check.runner.effect)))
131
+ errors.push(`unsafe_retry_policy:${owner}:${check.key}`);
132
+ }
@@ -0,0 +1,4 @@
1
+ import type { DeliveryContractV2 } from "./long-task-delivery-types.js";
2
+ export declare function parseTask(value: unknown): DeliveryContractV2["task"];
3
+ export declare function parseRisk(value: unknown): DeliveryContractV2["risk"];
4
+ export declare function parseGlobal(value: unknown): DeliveryContractV2["global"];
@@ -0,0 +1,86 @@
1
+ import { parseGlobalCounterfactuals } from "./long-task-acceptance-shape.js";
2
+ import { parseCheck } from "./long-task-check-shape.js";
3
+ import { array, key, literal, object, parseKeyedPaths, parseKeyedStatements, repositoryFiles, string, strings, } from "./long-task-delivery-shape.js";
4
+ const RISK_FACTS = [
5
+ "public_api_or_schema_change",
6
+ "persistent_data_change",
7
+ "data_migration",
8
+ "security_boundary_change",
9
+ "permission_boundary_change",
10
+ "irreversible_external_effect",
11
+ "critical_user_path",
12
+ "full_population_operation",
13
+ "multi_repository_change",
14
+ "weak_observability",
15
+ ];
16
+ export function parseTask(value) {
17
+ const row = object(value, "task", ["id", "title", "goal", "source_paths", "context_refs"], ["context_snapshot_mode"]);
18
+ return {
19
+ id: key(row.id, "task.id"),
20
+ title: string(row.title, "task.title"),
21
+ goal: string(row.goal, "task.goal"),
22
+ source_paths: repositoryFiles(row.source_paths, "task.source_paths"),
23
+ context_refs: repositoryFiles(row.context_refs, "task.context_refs"),
24
+ context_snapshot_mode: Object.hasOwn(row, "context_snapshot_mode")
25
+ ? literal(row.context_snapshot_mode, ["referenced", "full"], "task.context_snapshot_mode")
26
+ : "referenced",
27
+ };
28
+ }
29
+ export function parseRisk(value) {
30
+ const row = object(value, "risk", ["facts"], ["requested_level"]);
31
+ const facts = object(row.facts, "risk.facts", [], [...RISK_FACTS]);
32
+ return {
33
+ requested_level: Object.hasOwn(row, "requested_level")
34
+ ? literal(row.requested_level, ["auto", "standard", "strict"], "risk.requested_level")
35
+ : "auto",
36
+ facts: Object.fromEntries(RISK_FACTS.map((name) => [
37
+ name,
38
+ Object.hasOwn(facts, name)
39
+ ? strings(facts[name], `risk.facts.${name}`).map((item, index) => key(item, `risk.facts.${name}[${index}]`))
40
+ : [],
41
+ ])),
42
+ };
43
+ }
44
+ export function parseGlobal(value) {
45
+ const row = object(value, "global", [], ["product", "technical", "acceptance"]);
46
+ const product = object(Object.hasOwn(row, "product") ? row.product : {}, "global.product", [], ["non_goals"]);
47
+ const technical = object(Object.hasOwn(row, "technical") ? row.technical : {}, "global.technical", [], ["constraints", "forbidden_paths", "forbidden_shortcuts"]);
48
+ const acceptance = object(Object.hasOwn(row, "acceptance") ? row.acceptance : {}, "global.acceptance", [], ["checks", "counterfactual_controls", "external_confirmations"]);
49
+ return {
50
+ product: {
51
+ non_goals: Object.hasOwn(product, "non_goals")
52
+ ? parseKeyedStatements(product.non_goals, "global.product.non_goals")
53
+ : [],
54
+ },
55
+ technical: {
56
+ constraints: Object.hasOwn(technical, "constraints")
57
+ ? parseKeyedStatements(technical.constraints, "global.technical.constraints")
58
+ : [],
59
+ forbidden_paths: Object.hasOwn(technical, "forbidden_paths")
60
+ ? parseKeyedPaths(technical.forbidden_paths, "global.technical.forbidden_paths")
61
+ : [],
62
+ forbidden_shortcuts: Object.hasOwn(technical, "forbidden_shortcuts")
63
+ ? parseKeyedStatements(technical.forbidden_shortcuts, "global.technical.forbidden_shortcuts")
64
+ : [],
65
+ },
66
+ acceptance: {
67
+ checks: Object.hasOwn(acceptance, "checks")
68
+ ? array(acceptance.checks, "global.acceptance.checks").map((item, index) => parseCheck(item, `global.acceptance.checks[${index}]`))
69
+ : [],
70
+ counterfactual_controls: Object.hasOwn(acceptance, "counterfactual_controls")
71
+ ? parseGlobalCounterfactuals(acceptance.counterfactual_controls, "global.acceptance.counterfactual_controls")
72
+ : [],
73
+ external_confirmations: Object.hasOwn(acceptance, "external_confirmations")
74
+ ? array(acceptance.external_confirmations, "global.acceptance.external_confirmations").map((item, index) => {
75
+ const label = `global.acceptance.external_confirmations[${index}]`;
76
+ const entry = object(item, label, ["key", "description", "owner"]);
77
+ return {
78
+ key: key(entry.key, `${label}.key`),
79
+ description: string(entry.description, `${label}.description`),
80
+ owner: string(entry.owner, `${label}.owner`),
81
+ };
82
+ })
83
+ : [],
84
+ },
85
+ };
86
+ }
@@ -0,0 +1,7 @@
1
+ import type { EnvironmentRequirementV2 } from "./long-task-delivery-types.js";
2
+ export declare function runnerEnvironment(requirements: EnvironmentRequirementV2[]): NodeJS.ProcessEnv;
3
+ export declare function declaredEnvironmentValues(requirements: EnvironmentRequirementV2[]): string[];
4
+ export declare function outputContainsDeclaredEnvironmentValue(raw: {
5
+ stdout: Buffer;
6
+ stderr: Buffer;
7
+ }, values: string[]): boolean;
@@ -0,0 +1,57 @@
1
+ const BASE_ENVIRONMENT_KEYS = [
2
+ "PATH",
3
+ "PATHEXT",
4
+ "SystemRoot",
5
+ "WINDIR",
6
+ "ComSpec",
7
+ "TEMP",
8
+ "TMP",
9
+ "TMPDIR",
10
+ "HOME",
11
+ "USERPROFILE",
12
+ "HOMEDRIVE",
13
+ "HOMEPATH",
14
+ "APPDATA",
15
+ "LOCALAPPDATA",
16
+ "LANG",
17
+ "LC_ALL",
18
+ "TZ",
19
+ "CI",
20
+ "TERM",
21
+ "NO_COLOR",
22
+ "FORCE_COLOR",
23
+ ];
24
+ export function runnerEnvironment(requirements) {
25
+ const environment = {
26
+ TY_CONTEXT_CHECK_PROTOCOL: "long-task-check-result-v2",
27
+ };
28
+ for (const key of BASE_ENVIRONMENT_KEYS)
29
+ copyEnvironmentValue(environment, key);
30
+ for (const requirement of requirements)
31
+ if (requirement.kind === "env_var")
32
+ copyEnvironmentValue(environment, requirement.target);
33
+ return environment;
34
+ }
35
+ export function declaredEnvironmentValues(requirements) {
36
+ const values = [];
37
+ for (const requirement of requirements) {
38
+ if (requirement.kind !== "env_var")
39
+ continue;
40
+ const value = process.env[requirement.target];
41
+ if (value)
42
+ values.push(value);
43
+ }
44
+ return values;
45
+ }
46
+ export function outputContainsDeclaredEnvironmentValue(raw, values) {
47
+ if (!values.length)
48
+ return false;
49
+ const stdout = raw.stdout.toString("utf8");
50
+ const stderr = raw.stderr.toString("utf8");
51
+ return values.some((value) => stdout.includes(value) || stderr.includes(value));
52
+ }
53
+ function copyEnvironmentValue(environment, key) {
54
+ const value = process.env[key];
55
+ if (value !== undefined)
56
+ environment[key] = value;
57
+ }
@@ -0,0 +1,3 @@
1
+ export declare function nearestRunnerFile(start: string, repository: string, name: string): Promise<string | null>;
2
+ export declare function npmCliPath(): Promise<string>;
3
+ export declare function npxCliPath(): Promise<string>;
@@ -0,0 +1,39 @@
1
+ import { stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ export async function nearestRunnerFile(start, repository, name) {
4
+ let current = path.resolve(start);
5
+ const root = path.resolve(repository);
6
+ for (;;) {
7
+ const candidate = path.join(current, name);
8
+ if ((await stat(candidate).catch(() => null))?.isFile())
9
+ return candidate;
10
+ if (current === root)
11
+ return null;
12
+ const parent = path.dirname(current);
13
+ if (parent === current || !parent.startsWith(root))
14
+ return null;
15
+ current = parent;
16
+ }
17
+ }
18
+ export async function npmCliPath() {
19
+ const candidates = [
20
+ process.env.npm_execpath,
21
+ path.join(path.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js"),
22
+ ].filter((candidate) => Boolean(candidate));
23
+ for (const candidate of candidates)
24
+ if ((await stat(candidate).catch(() => null))?.isFile())
25
+ return candidate;
26
+ throw new Error("npm_cli_not_found_for_package_script_runner");
27
+ }
28
+ export async function npxCliPath() {
29
+ const candidates = [
30
+ process.env.npm_execpath
31
+ ? path.join(path.dirname(process.env.npm_execpath), "npx-cli.js")
32
+ : null,
33
+ path.join(path.dirname(process.execPath), "node_modules", "npm", "bin", "npx-cli.js"),
34
+ ].filter((candidate) => Boolean(candidate));
35
+ for (const candidate of candidates)
36
+ if ((await stat(candidate).catch(() => null))?.isFile())
37
+ return candidate;
38
+ throw new Error("npx_cli_not_found_for_playwright_runner");
39
+ }
@@ -0,0 +1,2 @@
1
+ import type { CompiledCheckV2, DeliveryCheckV2, WorkspaceManifestV2 } from "./long-task-delivery-types.js";
2
+ export declare function freezeDeliveryCheck(check: DeliveryCheckV2, outcomeKey: string | null, repository: string, baseline: WorkspaceManifestV2): Promise<CompiledCheckV2>;
@@ -0,0 +1,168 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { computeRawExecutionIdentity } from "./long-task-check-execution-policy.js";
4
+ import { assertRepositoryPattern, classifyRepositoryPatternOverlap, matchesRepoPattern, } from "./long-task-paths.js";
5
+ import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
6
+ import { nearestRunnerFile, npmCliPath, npxCliPath, } from "./long-task-runner-files.js";
7
+ import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
8
+ import { repoRelative, resolveInsideRepository, } from "./long-task-workspace.js";
9
+ import { evidenceAdapterForRunner } from "./long-task-evidence-adapter-policy.js";
10
+ export async function freezeDeliveryCheck(check, outcomeKey, repository, baseline) {
11
+ const prefix = outcomeKey ? `CHECK.${outcomeKey}` : "CHECK.GLOBAL";
12
+ const expectedOutputs = check.expected_output_paths.map((pattern, index) => assertRepositoryPattern(repository, pattern, `${check.key}.expected_output_paths[${index}]`));
13
+ for (const [index, pattern] of check.input_paths.entries()) {
14
+ const normalized = assertRepositoryPattern(repository, pattern, `${check.key}.input_paths[${index}]`);
15
+ if (!baseline.files.some((file) => matchesRepoPattern(file.path, normalized)) &&
16
+ !expectedOutputs.some((output) => classifyRepositoryPatternOverlap(output, normalized).status ===
17
+ "proven_overlap"))
18
+ throw new Error(`input_path_not_found:${check.key}:${pattern}`);
19
+ }
20
+ check.artifact_globs.forEach((pattern, index) => assertRepositoryPattern(repository, pattern, `${check.key}.artifact_globs[${index}]`));
21
+ const cwd = resolveInsideRepository(repository, check.runner.cwd, `${check.key}.cwd`);
22
+ if (!(await stat(cwd).catch(() => null))?.isDirectory())
23
+ throw new Error(`runner_cwd_not_found:${check.key}:${check.runner.cwd}`);
24
+ const target = await resolvedRunnerTarget(check, repository, cwd);
25
+ const verificationInputHashes = await freezeVerificationInputs(check, repository, baseline, cwd, target);
26
+ const compiled = {
27
+ ...check,
28
+ internal_id: `${prefix}.${check.key}`,
29
+ outcome_key: outcomeKey,
30
+ evidence_adapter: evidenceAdapterForRunner(check.runner.type),
31
+ runner: await freezeRunner(check, repository, cwd, target, verificationInputHashes),
32
+ verification_input_hashes: verificationInputHashes,
33
+ };
34
+ return {
35
+ ...compiled,
36
+ raw_execution_identity: computeRawExecutionIdentity(compiled),
37
+ };
38
+ }
39
+ async function resolvedRunnerTarget(check, repository, cwd) {
40
+ if (check.runner.type === "package_script") {
41
+ const packageFile = await nearestRunnerFile(cwd, repository, "package.json");
42
+ if (!packageFile)
43
+ throw new Error(`package_json_not_found:${check.key}:${check.runner.cwd}`);
44
+ return assertProtectedRepositoryFile(repository, packageFile, `${check.key}.package_json`);
45
+ }
46
+ const target = resolveInsideRepository(cwd, check.runner.target, `${check.key}.target`);
47
+ if (!(await stat(target).catch(() => null))?.isFile())
48
+ throw new Error(`${check.runner.type}_path_not_found:${check.key}:${check.runner.target}`);
49
+ const protectedTarget = await assertProtectedRepositoryFile(repository, target, `${check.key}.runner_target`);
50
+ repoRelative(repository, protectedTarget);
51
+ return protectedTarget;
52
+ }
53
+ async function freezeRunner(check, repository, cwd, target, verificationInputHashes) {
54
+ const runner = check.runner;
55
+ if (runner.argv.some((value) => value.includes("\0")))
56
+ throw new Error(`runner_argument_invalid:${check.key}`);
57
+ const resolvedCwd = repoRelative(repository, cwd);
58
+ const resolvedTarget = repoRelative(repository, target);
59
+ const frozenFiles = { ...verificationInputHashes };
60
+ let executable;
61
+ let prefix;
62
+ let packageScript = null;
63
+ if (runner.type === "package_script") {
64
+ const packageJson = JSON.parse(await readFile(target, "utf8"));
65
+ const script = packageJson.scripts?.[runner.target];
66
+ if (typeof script !== "string" || !script.trim())
67
+ throw new Error(`package_script_not_found:${check.key}:${runner.target}`);
68
+ packageScript = script;
69
+ executable = process.execPath;
70
+ prefix = [await npmCliPath(), "run", runner.target, "--"];
71
+ }
72
+ else {
73
+ const relativeFromCwd = path.relative(cwd, target).replace(/\\/gu, "/");
74
+ if (runner.type === "node_oracle") {
75
+ executable = process.execPath;
76
+ prefix = [relativeFromCwd];
77
+ }
78
+ else if (runner.type === "playwright_test") {
79
+ executable = process.execPath;
80
+ prefix = [
81
+ await npxCliPath(),
82
+ "--no-install",
83
+ "playwright",
84
+ "test",
85
+ relativeFromCwd,
86
+ "--reporter=json",
87
+ ];
88
+ }
89
+ else {
90
+ executable = resolvedTarget;
91
+ prefix = [];
92
+ }
93
+ }
94
+ const definition = sha256Hex(canonicalValueJson({
95
+ runner,
96
+ resolved_cwd: resolvedCwd,
97
+ resolved_target: resolvedTarget,
98
+ package_script: packageScript,
99
+ }));
100
+ return {
101
+ ...runner,
102
+ executable,
103
+ executable_argv_prefix: prefix,
104
+ resolved_cwd: resolvedCwd,
105
+ resolved_target: resolvedTarget,
106
+ definition_sha256: definition,
107
+ frozen_files: sortRecord(frozenFiles),
108
+ package_script: packageScript,
109
+ execution_identity: sha256Hex(canonicalValueJson({
110
+ runner,
111
+ executable,
112
+ prefix,
113
+ resolved_cwd: resolvedCwd,
114
+ resolved_target: resolvedTarget,
115
+ package_script: packageScript,
116
+ frozen_files: frozenFiles,
117
+ })),
118
+ };
119
+ }
120
+ async function freezeVerificationInputs(check, repository, manifest, cwd, target) {
121
+ const result = {};
122
+ for (const [index, source] of check.verification_inputs.entries()) {
123
+ const pattern = assertRepositoryPattern(repository, source, `${check.key}.verification_inputs[${index}]`);
124
+ const matches = manifest.files.filter((file) => matchesRepoPattern(file.path, pattern));
125
+ if (!matches.length)
126
+ throw new Error(`verification_input_not_found:${check.key}:${source}`);
127
+ for (const file of matches) {
128
+ const protectedFile = await assertProtectedRepositoryFile(repository, path.join(repository, ...file.path.split("/")), `${check.key}.verification_input`);
129
+ result[file.path] = sha256Hex(await readFile(protectedFile));
130
+ }
131
+ }
132
+ const automatic = new Set([repoRelative(repository, target)]);
133
+ const packageFile = await nearestRunnerFile(cwd, repository, "package.json");
134
+ if (packageFile)
135
+ automatic.add(repoRelative(repository, packageFile));
136
+ for (const name of [
137
+ "package-lock.json",
138
+ "npm-shrinkwrap.json",
139
+ "pnpm-lock.yaml",
140
+ "yarn.lock",
141
+ ]) {
142
+ const file = await nearestRunnerFile(cwd, repository, name);
143
+ if (file)
144
+ automatic.add(repoRelative(repository, file));
145
+ }
146
+ if (check.runner.type === "playwright_test")
147
+ for (const name of [
148
+ "playwright.config.ts",
149
+ "playwright.config.js",
150
+ "playwright.config.mjs",
151
+ "playwright.config.cjs",
152
+ ]) {
153
+ const file = await nearestRunnerFile(cwd, repository, name);
154
+ if (file)
155
+ automatic.add(repoRelative(repository, file));
156
+ }
157
+ for (const relative of automatic) {
158
+ const file = manifest.files.find((candidate) => candidate.path === relative);
159
+ if (!file)
160
+ throw new Error(`verification_input_not_found:${check.key}:${relative}`);
161
+ const protectedFile = await assertProtectedRepositoryFile(repository, path.join(repository, ...relative.split("/")), `${check.key}.automatic_verification_input`);
162
+ result[relative] = sha256Hex(await readFile(protectedFile));
163
+ }
164
+ return sortRecord(result);
165
+ }
166
+ function sortRecord(value) {
167
+ return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
168
+ }