@pixel-point/toolcraft 0.0.18 → 0.0.19

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 (384) hide show
  1. package/package.json +1 -1
  2. package/src/generate-demand-only-lifecycle.test.mjs +9 -1
  3. package/src/generate-performance-iteration-execution.test.mjs +3 -3
  4. package/src/generate-test-delivery-architecture-assertions.mjs +11 -73
  5. package/src/generate-test-demand-only-lifecycle.mjs +34 -36
  6. package/src/generate-test-dependency-sandbox.mjs +4 -1
  7. package/src/generate-test-doc-assertions.mjs +55 -53
  8. package/src/generate-test-doc-assertions.test.mjs +1 -1
  9. package/src/generate-test-doc-policy-assertions.mjs +1 -1
  10. package/src/generate-test-export-doc-assertions.mjs +53 -0
  11. package/src/generate-test-file-assertions.mjs +51 -8
  12. package/src/generate-test-integrity-assertions.mjs +5 -2
  13. package/src/generate-test-integrity-manifest-assertions.mjs +16 -5
  14. package/src/generate-test-integrity-ownership-assertions.mjs +36 -4
  15. package/src/generate-test-package-assertions.mjs +4 -0
  16. package/src/generate-test-product-fixture.mjs +1 -1
  17. package/src/generate-test-product-fixture.test.mjs +35 -38
  18. package/src/generate-test-product-iteration.mjs +0 -1
  19. package/src/generate-test-product-iteration.test.mjs +0 -1
  20. package/src/generate-test-runtime-boundary-assertions.mjs +20 -0
  21. package/src/generate-test-standalone-assertions.mjs +0 -16
  22. package/src/generate-test-standalone-delivery-stages.mjs +2 -86
  23. package/src/generate.test.mjs +4 -0
  24. package/src/generated-integrity-manifest.test.mjs +5 -2
  25. package/src/generated-source-policy.test.mjs +0 -4
  26. package/src/package-json.mjs +5 -0
  27. package/src/package-json.test.mjs +21 -0
  28. package/src/package-manager.mjs +2 -0
  29. package/src/package-manager.test.mjs +8 -0
  30. package/src/packaged-template-fallback-helpers.mjs +254 -0
  31. package/src/packaged-template-fallback.test.mjs +121 -46
  32. package/src/packaged-template-runtime-assertions.mjs +150 -0
  33. package/templates/runtime/contracts/component-contracts.choices.test.ts +18 -3
  34. package/templates/runtime/contracts/component-contracts.choices.ts +8 -3
  35. package/templates/runtime/contracts/component-contracts.inputs.ts +2 -1
  36. package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +18 -4
  37. package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +1 -1
  38. package/templates/runtime/contracts/component-contracts.runtime.ts +7 -4
  39. package/templates/runtime/contracts/component-contracts.visual.test.ts +20 -0
  40. package/templates/runtime/contracts/component-contracts.visual.ts +4 -0
  41. package/templates/runtime/contracts/decision-contracts.test.ts +18 -12
  42. package/templates/runtime/contracts/decision-contracts.ts +4 -4
  43. package/templates/runtime/contracts/performance-verification-policy.test.ts +12 -12
  44. package/templates/runtime/contracts/performance-verification-policy.ts +8 -8
  45. package/templates/runtime/export/artifact-download.ts +1 -0
  46. package/templates/runtime/export/artifact-frame-renderer.ts +2 -15
  47. package/templates/runtime/export/artifact-frame-state.ts +16 -0
  48. package/templates/runtime/export/artifact-scene-frame.test.ts +3 -3
  49. package/templates/runtime/export/artifact-scene-frame.ts +3 -3
  50. package/templates/runtime/export/export-error.ts +5 -0
  51. package/templates/runtime/export/export-renderer-coverage.ts +54 -0
  52. package/templates/runtime/export/image-artifact-export.ts +2 -2
  53. package/templates/runtime/export/index.ts +13 -0
  54. package/templates/runtime/export/product-export-renderer.test.ts +38 -4
  55. package/templates/runtime/export/product-export-renderer.ts +0 -41
  56. package/templates/runtime/export/product-svg-export-renderer.ts +21 -0
  57. package/templates/runtime/export/svg-artifact-export.test.ts +98 -0
  58. package/templates/runtime/export/svg-artifact-export.ts +120 -0
  59. package/templates/runtime/export/svg-document.test.ts +221 -0
  60. package/templates/runtime/export/svg-document.ts +400 -0
  61. package/templates/runtime/export/svg-policy.ts +47 -0
  62. package/templates/runtime/index.ts +1 -0
  63. package/templates/runtime/react/app-shell/runtime-public-api.test.tsx +10 -0
  64. package/templates/runtime/react/app-shell/settings-transfer.test.ts +21 -0
  65. package/templates/runtime/react/app-shell/toolcraft-app.scene-export.test.tsx +46 -1
  66. package/templates/runtime/react/app-shell/toolcraft-app.tsx +7 -2
  67. package/templates/runtime/react/canvas/canvas-shell-interactions.test.tsx +30 -0
  68. package/templates/runtime/react/canvas/canvas-shell-pinch-interactions.test.tsx +155 -0
  69. package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +1 -1
  70. package/templates/runtime/react/canvas/canvas-shell.tsx +16 -5
  71. package/templates/runtime/react/canvas/canvas-viewport-geometry.ts +133 -0
  72. package/templates/runtime/react/canvas/use-canvas-viewport-interactions.ts +285 -36
  73. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-applicability-layout.test.tsx +134 -0
  74. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-layout.test.tsx +16 -1
  75. package/templates/runtime/react/controls-panel/__tests__/controls-panel.render-isolation.test.tsx +2 -0
  76. package/templates/runtime/react/controls-panel/__tests__/controls-panel.scene-export-actions.test.tsx +39 -0
  77. package/templates/runtime/react/controls-panel/__tests__/controls-panel.setup-controls.test.tsx +3 -3
  78. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-collection.test.tsx +1 -4
  79. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-color-bank.test.tsx +2 -2
  80. package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-interaction.test.tsx +6 -6
  81. package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +2 -2
  82. package/templates/runtime/react/controls-panel/actions/export-action-runner.ts +40 -11
  83. package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +31 -2
  84. package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +4 -1
  85. package/templates/runtime/react/controls-panel/renderers/controls-panel-action-renderer.tsx +2 -1
  86. package/templates/runtime/react/controls-panel/renderers/controls-panel-basic-renderers.tsx +2 -52
  87. package/templates/runtime/react/controls-panel/values/controls-panel-color-values.ts +1 -9
  88. package/templates/runtime/react/controls-panel/values/controls-panel-spatial-values.ts +7 -2
  89. package/templates/runtime/react/orientation-gizmo/orientation-gizmo-math.ts +9 -69
  90. package/templates/runtime/schema/artifact-export-actions.test.ts +47 -0
  91. package/templates/runtime/schema/artifact-export-actions.ts +49 -0
  92. package/templates/runtime/schema/types.ts +1 -0
  93. package/templates/runtime/state/canvas-background-state.ts +1 -16
  94. package/templates/runtime/state/canvas-state.ts +32 -20
  95. package/templates/runtime/state/control-value-codecs.test.ts +98 -0
  96. package/templates/runtime/state/control-value-codecs.ts +700 -0
  97. package/templates/runtime/state/control-value-normalization.test.ts +1 -1
  98. package/templates/runtime/state/control-value-normalization.ts +127 -135
  99. package/templates/runtime/state/controls-reducer.ts +26 -3
  100. package/templates/runtime/state/create-template-state.test.ts +30 -0
  101. package/templates/runtime/state/create-template-state.ts +52 -31
  102. package/templates/runtime/state/orientation-pose.ts +80 -0
  103. package/templates/runtime/state/persistence-control-values.test.ts +59 -0
  104. package/templates/runtime/state/reducer-controls.test.ts +45 -0
  105. package/templates/runtime/state/reducer-media-reset.test.ts +1 -1
  106. package/templates/runtime/state/reducer-timeline.test.ts +70 -0
  107. package/templates/runtime/state/timeline-reducer.ts +40 -2
  108. package/templates/runtime/testing/performance-schema-queries.ts +2 -2
  109. package/templates/starter/AGENTS.md +21 -22
  110. package/templates/starter/docs/toolcraft/README.md +6 -6
  111. package/templates/starter/docs/toolcraft/acceptance-testing.md +20 -20
  112. package/templates/starter/docs/toolcraft/agent-worklog.md +88 -1
  113. package/templates/starter/docs/toolcraft/assembly-workflow.md +7 -6
  114. package/templates/starter/docs/toolcraft/component-rules.md +2 -2
  115. package/templates/starter/docs/toolcraft/core/layout.md +6 -1
  116. package/templates/starter/docs/toolcraft/core/media-upload.md +1 -1
  117. package/templates/starter/docs/toolcraft/core/performance.md +8 -10
  118. package/templates/starter/docs/toolcraft/core/reference-study.md +80 -19
  119. package/templates/starter/docs/toolcraft/core/runtime-boundary.md +2 -1
  120. package/templates/starter/docs/toolcraft/core/setup-export.md +43 -13
  121. package/templates/starter/docs/toolcraft/decision-contract.md +2 -2
  122. package/templates/starter/docs/toolcraft/performance.md +8 -10
  123. package/templates/starter/docs/toolcraft/renderer-technique.md +2 -2
  124. package/templates/starter/docs/toolcraft/schema-reference.md +8 -8
  125. package/templates/starter/docs/toolcraft/workflow.md +14 -14
  126. package/templates/starter/e2e/app-browser-infinity-canvas-evidence.spec.ts +38 -0
  127. package/templates/starter/e2e/app-browser-motion-reference-requirements.spec.ts +411 -0
  128. package/templates/starter/e2e/app-browser-proof-session.spec.ts +85 -0
  129. package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +62 -0
  130. package/templates/starter/e2e/app-browser-selection-scope-evidence.spec.ts +137 -0
  131. package/templates/starter/e2e/browser-infinity-canvas-svg-evidence.ts +42 -0
  132. package/templates/starter/e2e/browser-layer-evidence-helpers.ts +15 -36
  133. package/templates/starter/e2e/browser-product-raster-snapshot.ts +213 -0
  134. package/templates/starter/e2e/browser-proof-session.ts +43 -15
  135. package/templates/starter/e2e/browser-proof-surface-action.ts +79 -0
  136. package/templates/starter/e2e/browser-proof-types.ts +15 -0
  137. package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +22 -6
  138. package/templates/starter/e2e/browser-selection-scope-evidence.ts +269 -0
  139. package/templates/starter/e2e/browser-semantic-evidence-test-helpers.ts +97 -0
  140. package/templates/starter/e2e/browser-svg-export-evidence.spec.ts +79 -0
  141. package/templates/starter/e2e/browser-svg-export-evidence.ts +152 -0
  142. package/templates/starter/e2e/export-artifact-helpers.ts +70 -0
  143. package/templates/starter/e2e/product-observable-helpers.ts +8 -129
  144. package/templates/starter/e2e/svg-artifact-inspection.spec.ts +136 -0
  145. package/templates/starter/e2e/svg-artifact-inspection.ts +331 -0
  146. package/templates/starter/e2e/svg-download-test-fixtures.ts +34 -0
  147. package/templates/starter/e2e/toolcraft-delivery-catalog-reporter.ts +198 -15
  148. package/templates/starter/e2e/toolcraft-feature-verification-reporter.spec.ts +149 -0
  149. package/templates/starter/e2e/toolcraft-feature-verification-reporter.ts +223 -0
  150. package/templates/starter/package.json +2 -0
  151. package/templates/starter/scripts/check-toolcraft-docs.mjs +1 -0
  152. package/templates/starter/scripts/create-toolcraft-motion-reference-study.mjs +233 -0
  153. package/templates/starter/scripts/create-toolcraft-motion-reference-study.test.mjs +459 -0
  154. package/templates/starter/scripts/playwright-test-title-selection.d.mts +45 -0
  155. package/templates/starter/scripts/run-browser-performance-test-helpers.mjs +0 -27
  156. package/templates/starter/scripts/run-browser-performance.mjs +0 -6
  157. package/templates/starter/scripts/run-browser-performance.test.mjs +5 -13
  158. package/templates/starter/scripts/run-delivery-verification-test-helpers.mjs +0 -34
  159. package/templates/starter/scripts/run-delivery-verification.test.mjs +135 -31
  160. package/templates/starter/scripts/run-feature-verification.mjs +212 -0
  161. package/templates/starter/scripts/run-feature-verification.test.mjs +226 -0
  162. package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.mjs +21 -8
  163. package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.test.mjs +32 -92
  164. package/templates/starter/scripts/toolcraft-checkpoint-transaction.mjs +28 -6
  165. package/templates/starter/scripts/toolcraft-checkpoint-transaction.test.mjs +8 -63
  166. package/templates/starter/scripts/toolcraft-delivery-anchor.mjs +28 -8
  167. package/templates/starter/scripts/toolcraft-delivery-anchor.test.mjs +50 -61
  168. package/templates/starter/scripts/toolcraft-delivery-architecture-inventory.mjs +0 -4
  169. package/templates/starter/scripts/toolcraft-delivery-architecture-policy.mjs +0 -1
  170. package/templates/starter/scripts/toolcraft-delivery-evidence.test.mjs +2 -3
  171. package/templates/starter/scripts/toolcraft-delivery-executor.mjs +5 -1
  172. package/templates/starter/scripts/toolcraft-delivery-executor.test.mjs +5 -12
  173. package/templates/starter/scripts/toolcraft-delivery-functional-context.d.mts +1 -48
  174. package/templates/starter/scripts/toolcraft-delivery-functional-context.mjs +2 -30
  175. package/templates/starter/scripts/toolcraft-delivery-functional-context.test.mjs +4 -166
  176. package/templates/starter/scripts/toolcraft-delivery-functional-initial.test.mjs +4 -20
  177. package/templates/starter/scripts/toolcraft-delivery-lifecycle.mjs +43 -192
  178. package/templates/starter/scripts/toolcraft-delivery-performance-iteration-lifecycle.test.mjs +79 -440
  179. package/templates/starter/scripts/toolcraft-delivery-plan-authority.test.mjs +102 -297
  180. package/templates/starter/scripts/toolcraft-delivery-plan-construction.mjs +46 -97
  181. package/templates/starter/scripts/toolcraft-delivery-plan-test-helpers.mjs +125 -0
  182. package/templates/starter/scripts/toolcraft-delivery-plan-validation.test.mjs +58 -0
  183. package/templates/starter/scripts/toolcraft-delivery-plan.d.mts +19 -31
  184. package/templates/starter/scripts/toolcraft-delivery-plan.mjs +254 -252
  185. package/templates/starter/scripts/toolcraft-delivery-plan.test.mjs +29 -457
  186. package/templates/starter/scripts/toolcraft-delivery-receipt-performance.test.mjs +1 -1
  187. package/templates/starter/scripts/toolcraft-delivery-receipt-strictness.test.mjs +3 -72
  188. package/templates/starter/scripts/toolcraft-delivery-receipt-test-helpers.mjs +7 -36
  189. package/templates/starter/scripts/toolcraft-delivery-receipt.d.mts +3 -5
  190. package/templates/starter/scripts/toolcraft-delivery-receipt.mjs +15 -31
  191. package/templates/starter/scripts/toolcraft-delivery-receipt.test.mjs +28 -20
  192. package/templates/starter/scripts/toolcraft-delivery-receipt.types.test.mts +22 -30
  193. package/templates/starter/scripts/toolcraft-feature-verification-plan.d.mts +20 -0
  194. package/templates/starter/scripts/toolcraft-feature-verification-plan.mjs +146 -0
  195. package/templates/starter/scripts/toolcraft-feature-verification-plan.test.mjs +96 -0
  196. package/templates/starter/scripts/toolcraft-functional-proof-model.d.mts +3 -18
  197. package/templates/starter/scripts/toolcraft-functional-proof-model.mjs +39 -127
  198. package/templates/starter/scripts/toolcraft-functional-proof-model.test.mjs +25 -362
  199. package/templates/starter/scripts/toolcraft-functional-proof-model.types.test.mts +6 -83
  200. package/templates/starter/scripts/toolcraft-functional-proof-primitives.d.mts +11 -0
  201. package/templates/starter/scripts/toolcraft-functional-proof-primitives.mjs +61 -0
  202. package/templates/starter/scripts/toolcraft-functional-proof-primitives.test.mjs +43 -0
  203. package/templates/starter/scripts/toolcraft-integrity-policy.mjs +13 -0
  204. package/templates/starter/scripts/toolcraft-integrity-test-utils.mjs +1 -1
  205. package/templates/starter/scripts/toolcraft-layer-evidence-facade.test.mjs +58 -22
  206. package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.mjs +111 -0
  207. package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.test.mjs +116 -0
  208. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.d.mts +37 -0
  209. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.mjs +308 -0
  210. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.test.mjs +420 -0
  211. package/templates/starter/scripts/toolcraft-motion-reference-artifacts.types.test.mts +50 -0
  212. package/templates/starter/scripts/toolcraft-motion-reference-command-options.mjs +195 -0
  213. package/templates/starter/scripts/toolcraft-motion-reference-command-options.test.mjs +224 -0
  214. package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.mjs +122 -0
  215. package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.test.mjs +153 -0
  216. package/templates/starter/scripts/toolcraft-motion-reference-evidence-assembly.mjs +270 -0
  217. package/templates/starter/scripts/toolcraft-motion-reference-evidence.test.mjs +432 -0
  218. package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.mjs +275 -0
  219. package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.test.mjs +294 -0
  220. package/templates/starter/scripts/toolcraft-motion-reference-group-inventory.mjs +148 -0
  221. package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.mjs +101 -0
  222. package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.test.mjs +124 -0
  223. package/templates/starter/scripts/toolcraft-motion-reference-image-source.mjs +259 -0
  224. package/templates/starter/scripts/toolcraft-motion-reference-image-source.test.mjs +338 -0
  225. package/templates/starter/scripts/toolcraft-motion-reference-image-timing.mjs +96 -0
  226. package/templates/starter/scripts/toolcraft-motion-reference-image-timing.test.mjs +81 -0
  227. package/templates/starter/scripts/toolcraft-motion-reference-lock-recovery.test.mjs +144 -0
  228. package/templates/starter/scripts/toolcraft-motion-reference-media-source.mjs +165 -0
  229. package/templates/starter/scripts/toolcraft-motion-reference-media-source.test.mjs +299 -0
  230. package/templates/starter/scripts/toolcraft-motion-reference-publication-discovery.test.mjs +142 -0
  231. package/templates/starter/scripts/toolcraft-motion-reference-publication-isolation.test.mjs +234 -0
  232. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-schema.mjs +122 -0
  233. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.mjs +89 -0
  234. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.test.mjs +74 -0
  235. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.mjs +264 -0
  236. package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.test.mjs +377 -0
  237. package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.mjs +254 -0
  238. package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.test.mjs +130 -0
  239. package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.mjs +128 -0
  240. package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.test.mjs +209 -0
  241. package/templates/starter/scripts/toolcraft-motion-reference-publication.fixtures.mjs +88 -0
  242. package/templates/starter/scripts/toolcraft-motion-reference-publication.mjs +249 -0
  243. package/templates/starter/scripts/toolcraft-motion-reference-publication.test.mjs +433 -0
  244. package/templates/starter/scripts/toolcraft-motion-reference-review-output.mjs +38 -0
  245. package/templates/starter/scripts/toolcraft-motion-reference-review-output.test.mjs +29 -0
  246. package/templates/starter/scripts/toolcraft-motion-reference-root-safety.test.mjs +84 -0
  247. package/templates/starter/scripts/toolcraft-motion-reference-roots.mjs +83 -0
  248. package/templates/starter/scripts/toolcraft-motion-reference-sampling.mjs +283 -0
  249. package/templates/starter/scripts/toolcraft-motion-reference-sampling.test.mjs +480 -0
  250. package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.mjs +39 -0
  251. package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.test.mjs +59 -0
  252. package/templates/starter/scripts/toolcraft-motion-reference-stage.mjs +71 -0
  253. package/templates/starter/scripts/toolcraft-motion-reference-stage.test.mjs +61 -0
  254. package/templates/starter/scripts/toolcraft-motion-review-numeric.mjs +74 -0
  255. package/templates/starter/scripts/toolcraft-motion-review-numeric.test.mjs +65 -0
  256. package/templates/starter/scripts/toolcraft-motion-review-partitioning.mjs +268 -0
  257. package/templates/starter/scripts/toolcraft-motion-review-partitioning.test.mjs +329 -0
  258. package/templates/starter/scripts/toolcraft-motion-review-protected-units.mjs +120 -0
  259. package/templates/starter/scripts/toolcraft-motion-review-protected-units.test.mjs +111 -0
  260. package/templates/starter/scripts/toolcraft-performance-escalation-policy.test.mjs +77 -345
  261. package/templates/starter/scripts/toolcraft-performance-receipt-validation.test.mjs +19 -21
  262. package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +1 -1
  263. package/templates/starter/scripts/toolcraft-product-export-boundary.mjs +10 -1
  264. package/templates/starter/scripts/toolcraft-product-export-boundary.test.mjs +5 -1
  265. package/templates/starter/scripts/toolcraft-product-observable-facade.test.mjs +46 -1
  266. package/templates/starter/scripts/toolcraft-receipt-boundary.test.mjs +0 -1
  267. package/templates/starter/scripts/toolcraft-source-inventory.d.mts +5 -0
  268. package/templates/starter/scripts/toolcraft-source-inventory.mjs +25 -14
  269. package/templates/starter/scripts/toolcraft-source-inventory.test.mjs +48 -0
  270. package/templates/starter/scripts/toolcraft-source-ownership.mjs +0 -1
  271. package/templates/starter/scripts/toolcraft-source-ownership.test.mjs +30 -5
  272. package/templates/starter/scripts/toolcraft-verification-receipt-test-helpers.mjs +5 -26
  273. package/templates/starter/scripts/toolcraft-verification-receipt.d.mts +0 -7
  274. package/templates/starter/scripts/toolcraft-verification-receipt.mjs +3 -47
  275. package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +6 -87
  276. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.d.mts +19 -0
  277. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.mjs +107 -0
  278. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.test.mjs +114 -0
  279. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.mjs +13 -2
  280. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.test.mjs +110 -0
  281. package/templates/starter/src/app/acceptance/artifact-export-intent.ts +51 -20
  282. package/templates/starter/src/app/acceptance/canvas-coverage.ts +1 -0
  283. package/templates/starter/src/app/acceptance/color-bank-labels.ts +11 -15
  284. package/templates/starter/src/app/acceptance/color-row-grouping.ts +33 -0
  285. package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +0 -11
  286. package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +2 -3
  287. package/templates/starter/src/app/acceptance/control-component-rules.ts +0 -10
  288. package/templates/starter/src/app/acceptance/control-labels.ts +30 -1
  289. package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +18 -0
  290. package/templates/starter/src/app/acceptance/export-artifact-coverage.ts +25 -17
  291. package/templates/starter/src/app/acceptance/feature-verification-selection.test.ts +295 -0
  292. package/templates/starter/src/app/acceptance/feature-verification-selection.ts +161 -0
  293. package/templates/starter/src/app/acceptance/infinity-canvas.ts +10 -0
  294. package/templates/starter/src/app/acceptance/interaction-ownership-intent.ts +19 -1
  295. package/templates/starter/src/app/acceptance/interaction-ownership.ts +18 -2
  296. package/templates/starter/src/app/acceptance/motion-reference-evidence-validation.mjs +65 -0
  297. package/templates/starter/src/app/acceptance/motion-reference-evidence-windows.mjs +301 -0
  298. package/templates/starter/src/app/acceptance/motion-reference-evidence.d.mts +11 -0
  299. package/templates/starter/src/app/acceptance/motion-reference-evidence.mjs +145 -0
  300. package/templates/starter/src/app/acceptance/motion-reference-study-behaviors.ts +162 -0
  301. package/templates/starter/src/app/acceptance/motion-reference-study-coverage.ts +206 -0
  302. package/templates/starter/src/app/acceptance/motion-reference-study-identity.ts +129 -0
  303. package/templates/starter/src/app/acceptance/motion-reference-study-partitions.ts +186 -0
  304. package/templates/starter/src/app/acceptance/motion-reference-study.ts +90 -0
  305. package/templates/starter/src/app/acceptance/output-export-actions.test.ts +9 -1
  306. package/templates/starter/src/app/acceptance/output-export-actions.ts +14 -22
  307. package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +5 -1
  308. package/templates/starter/src/app/acceptance/output-export-model.ts +4 -0
  309. package/templates/starter/src/app/acceptance/output-export.ts +4 -1
  310. package/templates/starter/src/app/acceptance/reference-study-types.ts +167 -17
  311. package/templates/starter/src/app/acceptance/runtime-coverage.ts +6 -1
  312. package/templates/starter/src/app/acceptance/selection-scope.test.ts +200 -0
  313. package/templates/starter/src/app/acceptance/selection-scope.ts +151 -0
  314. package/templates/starter/src/app/acceptance/transfer-mode-types.ts +114 -0
  315. package/templates/starter/src/app/acceptance/types.ts +43 -118
  316. package/templates/starter/src/app/acceptance/validate-coverage.ts +14 -3
  317. package/templates/starter/src/app/starter-acceptance-data.ts +1 -0
  318. package/templates/starter/src/app/starter-acceptance.animation-intent.test.ts +3 -0
  319. package/templates/starter/src/app/starter-acceptance.artifact-export-intent.test.ts +81 -8
  320. package/templates/starter/src/app/starter-acceptance.background-export.test.ts +2 -0
  321. package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +2 -0
  322. package/templates/starter/src/app/starter-acceptance.color-row-grouping.test.ts +118 -0
  323. package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +1 -1
  324. package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +1 -0
  325. package/templates/starter/src/app/starter-acceptance.control-applicability.test.ts +1 -0
  326. package/templates/starter/src/app/starter-acceptance.control-label-context.test.ts +1 -0
  327. package/templates/starter/src/app/starter-acceptance.control-labels.test.ts +78 -3
  328. package/templates/starter/src/app/starter-acceptance.control-naming-rules.test.ts +77 -1
  329. package/templates/starter/src/app/starter-acceptance.custom-control-fit-check.test.ts +1 -1
  330. package/templates/starter/src/app/starter-acceptance.export-artifact.test.ts +74 -3
  331. package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +5 -1
  332. package/templates/starter/src/app/starter-acceptance.image-export-settings.test.ts +2 -0
  333. package/templates/starter/src/app/starter-acceptance.interaction-ownership.test.ts +19 -3
  334. package/templates/starter/src/app/starter-acceptance.layers.test.ts +2 -1
  335. package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +28 -0
  336. package/templates/starter/src/app/starter-acceptance.motion-reference-evidence.test.ts +17 -0
  337. package/templates/starter/src/app/starter-acceptance.motion-reference-identity.test.ts +163 -0
  338. package/templates/starter/src/app/starter-acceptance.motion-reference-mapping.test.ts +133 -0
  339. package/templates/starter/src/app/starter-acceptance.motion-reference-ownership.test.ts +121 -0
  340. package/templates/starter/src/app/starter-acceptance.motion-reference-partitions.test.ts +210 -0
  341. package/templates/starter/src/app/starter-acceptance.motion-reference-test-utils.ts +313 -0
  342. package/templates/starter/src/app/starter-acceptance.output-export-intent.test.ts +78 -4
  343. package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +6 -1
  344. package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +18 -1
  345. package/templates/starter/src/app/starter-acceptance.product-worklog.test.ts +123 -2
  346. package/templates/starter/src/app/starter-acceptance.reference-custom-timeline.test.ts +2 -0
  347. package/templates/starter/src/app/starter-acceptance.reference-foundation.test.ts +8 -0
  348. package/templates/starter/src/app/starter-acceptance.reference-timeline.test.ts +7 -0
  349. package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +2 -0
  350. package/templates/starter/src/app/starter-acceptance.timeline-playback.test.ts +5 -0
  351. package/templates/starter/src/app/starter-acceptance.ts +34 -8
  352. package/templates/starter/src/app/starter-acceptance.video-export-settings.test.ts +2 -0
  353. package/templates/starter/src/app/starter-acceptance.video-reference-study.test.ts +34 -236
  354. package/templates/starter/src/app/starter-acceptance.view-interaction.test.ts +4 -0
  355. package/templates/starter/src/app/starter-acceptance.worklog-test-utils.ts +122 -6
  356. package/templates/starter/src/app/starter-acceptance.worklog.test.ts +152 -16
  357. package/templates/starter/src/app/starter-performance.gates.test.ts +20 -18
  358. package/templates/starter/src/app/starter-performance.lifecycle.test.ts +22 -6
  359. package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +3 -0
  360. package/templates/starter/tsconfig.json +1 -0
  361. package/templates/starter/scripts/toolcraft-browser-impact-selection.mjs +0 -26
  362. package/templates/starter/scripts/toolcraft-delivery-framework-refresh.test.mjs +0 -141
  363. package/templates/starter/scripts/toolcraft-delivery-functional-changed.test.mjs +0 -468
  364. package/templates/starter/scripts/toolcraft-delivery-functional-model-lifecycle.test.mjs +0 -254
  365. package/templates/starter/scripts/toolcraft-delivery-functional-semantic-regression.test.mjs +0 -135
  366. package/templates/starter/scripts/toolcraft-delivery-performance-iteration-durability.test.mjs +0 -329
  367. package/templates/starter/scripts/toolcraft-delivery-plan-errors.test.mjs +0 -430
  368. package/templates/starter/scripts/toolcraft-delivery-plan-functional-model.test.mjs +0 -358
  369. package/templates/starter/scripts/toolcraft-functional-proof-regression-fixtures.mjs +0 -298
  370. package/templates/starter/scripts/toolcraft-verification-impact-inventory.d.mts +0 -62
  371. package/templates/starter/scripts/toolcraft-verification-impact-inventory.mjs +0 -344
  372. package/templates/starter/scripts/toolcraft-verification-impact-inventory.test.mjs +0 -204
  373. package/templates/starter/scripts/toolcraft-verification-impact-performance-candidates.test.mjs +0 -210
  374. package/templates/starter/scripts/toolcraft-verification-impact-resolution.mjs +0 -344
  375. package/templates/starter/scripts/toolcraft-verification-impact-resolution.test.mjs +0 -270
  376. package/templates/starter/scripts/toolcraft-verification-impact-semantic-resolution.test.mjs +0 -449
  377. package/templates/starter/scripts/toolcraft-verification-impact-support-resolution.test.mjs +0 -195
  378. package/templates/starter/scripts/toolcraft-verification-impact.d.mts +0 -132
  379. package/templates/starter/scripts/toolcraft-verification-impact.mjs +0 -169
  380. package/templates/starter/scripts/toolcraft-verification-impact.test.mjs +0 -300
  381. package/templates/starter/scripts/toolcraft-verification-input-roles.mjs +0 -197
  382. package/templates/starter/scripts/toolcraft-verification-input-roles.test.mjs +0 -225
  383. package/templates/starter/src/app/acceptance/video-reference-study.ts +0 -217
  384. package/templates/starter/src/app/starter-verification-impact.json +0 -15
@@ -3,6 +3,10 @@ import {
3
3
  } from "./playwright-test-title-selection.mjs";
4
4
  import {
5
5
  createToolcraftCanonicalJsonHash,
6
+ deepFreezeToolcraftValue,
7
+ hasToolcraftExactRecordKeys,
8
+ isToolcraftCanonicalTargetArray,
9
+ isToolcraftDeeplyFrozen,
6
10
  serializeToolcraftCanonicalJson,
7
11
  } from "./toolcraft-functional-proof-primitives.mjs";
8
12
  import {
@@ -14,325 +18,323 @@ import {
14
18
  constructToolcraftDeliveryPlan,
15
19
  } from "./toolcraft-delivery-plan-construction.mjs";
16
20
  import {
17
- createToolcraftFunctionalProofModelHash,
18
21
  getToolcraftFunctionalProofModelError,
19
22
  } from "./toolcraft-functional-proof-model.mjs";
20
23
  import {
21
24
  getToolcraftPerformanceRequestAuthorityError,
22
25
  } from "./toolcraft-performance-authority-policy.mjs";
23
- import { createToolcraftTargetedPerformanceComparisonHash, getToolcraftTargetedPerformanceReportError } from "./toolcraft-targeted-performance-report.mjs";
24
- import { getToolcraftChangedVerificationFiles, getToolcraftVerificationInventoryError } from "./toolcraft-verification-inventory.mjs";
25
- export const TOOLCRAFT_DELIVERY_PLAN_VERSION = 4;
26
+ import {
27
+ createToolcraftTargetedPerformanceComparisonHash,
28
+ getToolcraftTargetedPerformanceReportError,
29
+ } from "./toolcraft-targeted-performance-report.mjs";
30
+ import {
31
+ getToolcraftVerificationInventoryError,
32
+ } from "./toolcraft-verification-inventory.mjs";
33
+
34
+ export const TOOLCRAFT_DELIVERY_PLAN_VERSION = 6;
35
+
26
36
  const hashPattern = /^[a-f0-9]{64}$/u;
27
37
  const managers = new Set(["npm", "pnpm", "yarn", "bun"]);
28
- const stepOrder = ["dependencies", "docs", "code-health", "product-tests", "build", "browser-functional", "browser-performance"];
29
- const changeFlags = [
30
- "dependencyChanged",
31
- "docsChanged",
32
- "frameworkChanged",
33
- "platformChanged",
34
- "productInputsChanged",
38
+ const stepOrder = [
39
+ "docs",
40
+ "code-health",
41
+ "product-tests",
42
+ "build",
43
+ "browser-functional",
44
+ "browser-performance",
45
+ ];
46
+ const inputKeys = [
47
+ "allProductTestFiles",
48
+ "authority",
49
+ "catalog",
50
+ "currentFunctionalProofModel",
51
+ "currentInventory",
52
+ "initialProof",
53
+ "integrity",
54
+ "packageManager",
55
+ "previousLifecycle",
56
+ "previousPerformance",
35
57
  ];
36
- const inputKeys = ["allProductTestFiles", "authority", "catalog", "changeSet",
37
- "comparisonInventory", "currentFunctionalProofModel", "currentInventory",
38
- "integrity", "packageManager", "previousFunctionalProofModel",
39
- "previousLifecycle", "previousPerformance"];
40
- const impactKeys = ["acceptanceIds", "browserTestNames", "buildRequired",
41
- "performanceCandidates", "productTestFiles"];
42
- const performanceCandidateKeys = ["passIds", "pathIds", "testNames"];
43
58
  const stepKeys = {
44
- dependencies: ["kind", "packageManager"], docs: ["kind"],
45
- "code-health": ["kind"], "product-tests": ["kind", "files"], build: ["kind"],
46
- "browser-functional": ["kind", "testNames"], "browser-performance": ["kind", "testNames", "pathIds", "passIds"],
59
+ docs: ["kind"],
60
+ "code-health": ["kind"],
61
+ "product-tests": ["acceptanceIds", "files", "kind"],
62
+ build: ["kind"],
63
+ "browser-functional": ["kind", "testNames"],
64
+ "browser-performance": ["kind", "passIds", "pathIds", "testNames"],
47
65
  };
48
66
  const planKeys = {
49
- functional: ["basis", "functionalProofModelHash", "kind", "lifecycle",
50
- "sourceHash", "manifestHash", "steps"],
51
- "performance-iteration": ["basis", "functionalProofModelHash", "kind",
52
- "sourceHash", "lifecycle", "manifestHash", "requestAuthorityHash",
53
- "performanceComparison", "steps"],
54
- };
55
- const record = (value) => {
56
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
57
- return false;
58
- }
59
- const prototype = Object.getPrototypeOf(value);
60
- return prototype === Object.prototype || prototype === null;
67
+ functional: [
68
+ "basis",
69
+ "functionalProofModelHash",
70
+ "kind",
71
+ "lifecycle",
72
+ "manifestHash",
73
+ "sourceHash",
74
+ "steps",
75
+ ],
76
+ "performance-iteration": [
77
+ "basis",
78
+ "functionalProofModelHash",
79
+ "kind",
80
+ "lifecycle",
81
+ "manifestHash",
82
+ "performanceComparison",
83
+ "requestAuthorityHash",
84
+ "sourceHash",
85
+ "steps",
86
+ ],
61
87
  };
62
- const exact = (value, keys) => {
63
- if (!record(value)) return false;
64
- const ownKeys = Reflect.ownKeys(value);
65
- return ownKeys.length === keys.length &&
66
- ownKeys.every((key) =>
67
- typeof key === "string" &&
68
- keys.includes(key) &&
69
- Object.prototype.propertyIsEnumerable.call(value, key)
70
- );
71
- };
72
- const compare = (left, right) => left < right ? -1 : left > right ? 1 : 0;
73
- function denseExactArray(value) {
74
- if (!Array.isArray(value) || Reflect.ownKeys(value).length !== value.length + 1)
75
- return false;
76
- return Array.from(
77
- { length: value.length },
78
- (_, index) => Object.hasOwn(value, index),
79
- ).every(Boolean);
80
- }
81
- function canonicalPath(value) {
82
- return typeof value === "string" && value.length > 0 && value.trim() === value &&
83
- !value.includes("\\") && !value.startsWith("/") && !/^[A-Za-z]:\//u.test(value) &&
84
- value.split("/").every((part) => part && part !== "." && part !== "..");
85
- }
86
- function targets(value, { empty = false, paths = false } = {}) {
87
- return denseExactArray(value) && (empty || value.length > 0) &&
88
- value.every((item) => paths ? canonicalPath(item) : typeof item === "string" &&
89
- item.length > 0 && item.trim() === item) &&
90
- value.every((item, index) => index === 0 || compare(value[index - 1], item) < 0);
91
- }
88
+
92
89
  const same = (left, right) => JSON.stringify(left) === JSON.stringify(right);
93
90
  const canonicallySame = (left, right) =>
94
91
  serializeToolcraftCanonicalJson(left) ===
95
92
  serializeToolcraftCanonicalJson(right);
96
- function deepFreeze(value) {
97
- if (value && typeof value === "object" && !Object.isFrozen(value)) { Object.values(value).forEach(deepFreeze); Object.freeze(value); }
98
- return value;
99
- }
100
- const deeplyFrozen = (value) => !(value && typeof value === "object") || (Object.isFrozen(value) &&
101
- Object.values(value).every(deeplyFrozen));
93
+
102
94
  function inventoryError(value, label) {
103
- if (!exact(value, ["entries", "sourceHash"]) ||
104
- !denseExactArray(value.entries) ||
105
- !value.entries.every((entry) => exact(entry, ["path", "sha256"])))
95
+ if (
96
+ !hasToolcraftExactRecordKeys(value, ["entries", "sourceHash"]) ||
97
+ !Array.isArray(value.entries) ||
98
+ !value.entries.every((entry) =>
99
+ hasToolcraftExactRecordKeys(entry, ["path", "sha256"]),
100
+ )
101
+ ) {
106
102
  return `${label} is malformed.`;
107
- return getToolcraftVerificationInventoryError(
108
- { entries: value.entries, label, sourceHash: value.sourceHash });
109
- }
110
- function impactError(impact, catalog, allTests) {
111
- if (!exact(impact, impactKeys) ||
112
- !exact(impact.performanceCandidates, performanceCandidateKeys) ||
113
- typeof impact.buildRequired !== "boolean")
114
- return "Verification impact is malformed.";
115
- for (const key of ["acceptanceIds", "browserTestNames", "productTestFiles"])
116
- if (!targets(impact[key], { empty: true, paths: key === "productTestFiles" }))
117
- return `Verification impact ${key} is not canonical.`;
118
- for (const key of performanceCandidateKeys)
119
- if (!targets(impact.performanceCandidates[key], { empty: true }))
120
- return `Verification impact performanceCandidates.${key} is not canonical.`;
121
- if (!impact.productTestFiles.every((file) => allTests.includes(file)))
122
- return "Verification impact contains an unknown product test.";
123
- const acceptance = catalog.acceptance.filter((row) =>
124
- impact.acceptanceIds.includes(row.acceptanceId));
125
- const performance = catalog.performance.filter((row) =>
126
- impact.performanceCandidates.pathIds.includes(row.pathId));
127
- if (!impact.browserTestNames.length && !impact.productTestFiles.length &&
128
- !impact.performanceCandidates.pathIds.length)
129
- return "Verification impact does not select functional or performance proof.";
130
- if (acceptance.length !== impact.acceptanceIds.length ||
131
- !same(acceptance.map((row) => row.testName).sort(compare), impact.browserTestNames) ||
132
- performance.length !== impact.performanceCandidates.pathIds.length ||
133
- !same(performance.map((row) => row.testName).sort(compare),
134
- impact.performanceCandidates.testNames) ||
135
- !same([...new Set(performance.flatMap((row) => row.passIds))].sort(compare),
136
- impact.performanceCandidates.passIds))
137
- return "Verification impact does not match the delivery catalog.";
103
+ }
104
+ return getToolcraftVerificationInventoryError({
105
+ entries: value.entries,
106
+ label,
107
+ sourceHash: value.sourceHash,
108
+ });
138
109
  }
110
+
139
111
  function authorityError(authority, catalog) {
140
- const authorityProblem =
141
- getToolcraftPerformanceRequestAuthorityError(authority);
142
- if (authorityProblem) return authorityProblem;
112
+ const error = getToolcraftPerformanceRequestAuthorityError(authority);
113
+ if (error) return error;
143
114
  const knownPathIds = catalog.performance.map(({ pathId }) => pathId);
144
- if (!authority.pathIds.every((pathId) => knownPathIds.includes(pathId)))
115
+ if (!authority.pathIds.every((pathId) => knownPathIds.includes(pathId))) {
145
116
  return "Performance iteration authority selects an unknown path.";
117
+ }
118
+ return undefined;
146
119
  }
120
+
147
121
  function inputError(inputs) {
148
- if (!exact(inputs, inputKeys)) return "Delivery planning inputs are malformed.";
149
- if (!targets(inputs.allProductTestFiles, { paths: true }))
122
+ if (!hasToolcraftExactRecordKeys(inputs, inputKeys)) {
123
+ return "Delivery planning inputs are malformed.";
124
+ }
125
+ if (!isToolcraftCanonicalTargetArray(inputs.allProductTestFiles, {
126
+ paths: true,
127
+ })) {
150
128
  return "Product test inventory is malformed.";
129
+ }
151
130
  const checkedCatalog = validateToolcraftDeliveryCatalog(inputs.catalog);
152
- if (checkedCatalog.errors.length) return checkedCatalog.errors.join("\n");
153
- if (!canonicallySame(inputs.catalog, checkedCatalog.catalog))
131
+ if (checkedCatalog.errors.length > 0) {
132
+ return checkedCatalog.errors.join("\n");
133
+ }
134
+ if (!canonicallySame(inputs.catalog, checkedCatalog.catalog)) {
154
135
  return "Delivery catalog must already be canonical.";
155
- const currentModelProblem = getToolcraftFunctionalProofModelError(
136
+ }
137
+ const modelError = getToolcraftFunctionalProofModelError(
156
138
  inputs.currentFunctionalProofModel,
157
139
  );
158
- if (currentModelProblem) {
159
- return `Current functional proof model is invalid: ${currentModelProblem}`;
160
- }
140
+ if (modelError) return `Current functional proof model is invalid: ${modelError}`;
161
141
  if (!same(
162
142
  inputs.currentFunctionalProofModel.acceptance,
163
143
  checkedCatalog.catalog.acceptance,
164
144
  )) {
165
145
  return "Current functional proof model does not match the delivery catalog.";
166
146
  }
167
- if (!exact(inputs.changeSet, [...changeFlags.slice(0, 2), "impact",
168
- ...changeFlags.slice(2)]) ||
169
- !changeFlags.every((key) =>
170
- typeof inputs.changeSet[key] === "boolean"))
171
- return "Delivery change set is malformed.";
172
- const currentProblem = inventoryError(inputs.currentInventory, "Current inventory");
173
- if (currentProblem) return currentProblem;
174
- if (!exact(inputs.integrity, ["manifestHash", "sourceHash"]) ||
175
- !hashPattern.test(inputs.integrity.manifestHash) ||
147
+ const currentInventoryError = inventoryError(
148
+ inputs.currentInventory,
149
+ "Current inventory",
150
+ );
151
+ if (currentInventoryError) return currentInventoryError;
152
+ if (
153
+ !hasToolcraftExactRecordKeys(inputs.integrity, ["manifestHash", "sourceHash"]) ||
154
+ !hashPattern.test(inputs.integrity.manifestHash ?? "") ||
176
155
  inputs.integrity.sourceHash !== inputs.currentInventory.sourceHash ||
177
- !managers.has(inputs.packageManager))
156
+ !managers.has(inputs.packageManager)
157
+ ) {
178
158
  return "Delivery integrity or package-manager policy is invalid.";
179
- const previousProblem = getToolcraftPreviousPerformanceError(inputs.previousPerformance);
180
- if (previousProblem) return previousProblem;
181
- const lifecycleProblem = getToolcraftDeliveryLifecyclePlanningError({
182
- authority: inputs.authority, hasComparison: inputs.comparisonInventory !== null,
183
- previous: inputs.previousLifecycle });
184
- if (lifecycleProblem) return lifecycleProblem;
185
- const authorityProblem = inputs.authority && authorityError(inputs.authority, inputs.catalog);
186
- if (authorityProblem) return authorityProblem;
187
- if (inputs.comparisonInventory === null) {
188
- if (inputs.authority !== null)
189
- return "Toolcraft first delivery must be functional; performance authority requires a previous successful delivery.";
190
- if (inputs.changeSet.impact !== null ||
191
- Object.entries(inputs.changeSet).some(([key, value]) => key !== "impact" && value) ||
192
- inputs.previousPerformance.kind !== "none")
193
- return "Initial planning inputs contain changed-delivery state.";
194
- if (inputs.previousFunctionalProofModel !== null)
195
- return "Initial planning inputs must not contain a previous functional proof model.";
196
- return;
197
159
  }
198
- const previousModelProblem = getToolcraftFunctionalProofModelError(
199
- inputs.previousFunctionalProofModel,
160
+ const performanceError = getToolcraftPreviousPerformanceError(
161
+ inputs.previousPerformance,
200
162
  );
201
- if (previousModelProblem) {
202
- return `Changed planning inputs require a valid previous functional proof model: ${previousModelProblem}`;
163
+ if (performanceError) return performanceError;
164
+ const hasInitialProof = inputs.initialProof !== null;
165
+ const lifecycleError = getToolcraftDeliveryLifecyclePlanningError({
166
+ authority: inputs.authority,
167
+ hasComparison: hasInitialProof,
168
+ previous: inputs.previousLifecycle,
169
+ });
170
+ if (lifecycleError) return lifecycleError;
171
+ if (!hasInitialProof) {
172
+ if (inputs.authority !== null) {
173
+ return "Toolcraft first delivery must be functional.";
174
+ }
175
+ return inputs.previousPerformance.kind === "none"
176
+ ? undefined
177
+ : "Initial planning inputs cannot contain prior performance evidence.";
178
+ }
179
+ if (
180
+ !hasToolcraftExactRecordKeys(inputs.initialProof, [
181
+ "functionalProofModelHash",
182
+ "sourceHash",
183
+ ]) ||
184
+ !hashPattern.test(inputs.initialProof.functionalProofModelHash ?? "") ||
185
+ !hashPattern.test(inputs.initialProof.sourceHash ?? "")
186
+ ) {
187
+ return "Initial product proof identity is malformed.";
203
188
  }
204
- const comparisonProblem = inventoryError(inputs.comparisonInventory, "Comparison inventory");
205
- if (comparisonProblem) return comparisonProblem;
206
- const changed = getToolcraftChangedVerificationFiles(
207
- inputs.comparisonInventory.entries, inputs.currentInventory.entries);
208
- if (!changed.length ||
209
- inputs.comparisonInventory.sourceHash === inputs.currentInventory.sourceHash)
210
- return "Delivery planning requires actual changed files.";
211
- if (!changeFlags.some((key) => inputs.changeSet[key]))
212
- return "Changed files are not represented by the trusted change set.";
213
- if (inputs.changeSet.productInputsChanged !== (inputs.changeSet.impact !== null))
214
- return "Product input changes require explicit verification impact.";
215
- const impactProblem = inputs.changeSet.impact && impactError(
216
- inputs.changeSet.impact, inputs.catalog, inputs.allProductTestFiles);
217
- if (impactProblem) return impactProblem;
218
- if (inputs.authority !== null &&
219
- (!inputs.changeSet.productInputsChanged ||
220
- !inputs.authority.pathIds.every((pathId) =>
221
- inputs.changeSet.impact?.performanceCandidates.pathIds.includes(pathId)
222
- )))
223
- return "Performance iteration authority is missing or incompatible.";
189
+ if (inputs.authority === null) {
190
+ return "A proven product does not create later functional delivery plans.";
191
+ }
192
+ return authorityError(inputs.authority, inputs.catalog);
224
193
  }
194
+
225
195
  function stepError(step) {
226
196
  const keys = stepKeys[step?.kind];
227
- if (!keys || !exact(step, keys)) return "Delivery proof step is malformed.";
228
- if (step.kind === "dependencies" && !managers.has(step.packageManager))
229
- return "Dependency proof has an invalid package manager.";
230
- const badTarget = ["files", "testNames", "pathIds", "passIds"].find((key) =>
231
- Object.hasOwn(step, key) && !targets(step[key], {
232
- empty: step.kind === "browser-performance" && key === "passIds",
233
- paths: key === "files",
234
- }));
235
- if (badTarget)
236
- return `Delivery proof ${badTarget} must be nonempty, sorted, and unique.`;
197
+ if (!keys || !hasToolcraftExactRecordKeys(step, keys)) {
198
+ return "Delivery proof step is malformed.";
199
+ }
200
+ if (
201
+ step.kind === "product-tests" &&
202
+ step.acceptanceIds !== null
203
+ ) {
204
+ return "Initial product proof requires complete product-test selection.";
205
+ }
206
+ const badTarget = ["files", "testNames", "pathIds", "passIds"].find(
207
+ (key) => Object.hasOwn(step, key) &&
208
+ !isToolcraftCanonicalTargetArray(step[key], {
209
+ empty: step.kind === "browser-performance" && key === "passIds",
210
+ paths: key === "files",
211
+ }),
212
+ );
213
+ return badTarget
214
+ ? `Delivery proof ${badTarget} must be nonempty, sorted, and unique.`
215
+ : undefined;
216
+ }
217
+
218
+ function performanceComparisonError(plan, performanceStep) {
219
+ const comparison = plan.performanceComparison;
220
+ if (
221
+ hasToolcraftExactRecordKeys(comparison, ["kind"]) &&
222
+ comparison.kind === "none"
223
+ ) {
224
+ return undefined;
225
+ }
226
+ if (
227
+ !hasToolcraftExactRecordKeys(comparison, [
228
+ "comparisonHash",
229
+ "kind",
230
+ "report",
231
+ ]) ||
232
+ comparison.kind !== "compatible-targeted-report" ||
233
+ !hashPattern.test(comparison.comparisonHash ?? "") ||
234
+ getToolcraftTargetedPerformanceReportError(comparison.report) ||
235
+ createToolcraftTargetedPerformanceComparisonHash(comparison.report) !==
236
+ comparison.comparisonHash ||
237
+ comparison.report.sourceHash !== plan.sourceHash ||
238
+ comparison.report.fixtureResolutionMode !== "strict-development" ||
239
+ !same(comparison.report.performancePathIds, performanceStep.pathIds) ||
240
+ !same(comparison.report.performancePassIds, performanceStep.passIds) ||
241
+ !same(comparison.report.testNames, performanceStep.testNames)
242
+ ) {
243
+ return "Performance comparison is malformed or incompatible.";
244
+ }
245
+ return undefined;
237
246
  }
238
- const fullProof = (kinds) => ["docs", "code-health", "product-tests", "build", "browser-functional"].every((kind) => kinds.includes(kind));
247
+
239
248
  export function getToolcraftDeliveryPlanError(plan) {
240
- if (!deeplyFrozen(plan)) return "Toolcraft delivery plans must be deeply immutable.";
249
+ if (!isToolcraftDeeplyFrozen(plan)) {
250
+ return "Toolcraft delivery plans must be deeply immutable.";
251
+ }
241
252
  const keys = planKeys[plan?.kind];
242
- if (!keys || !exact(plan, keys) || !hashPattern.test(plan.sourceHash ?? "") ||
253
+ if (
254
+ !keys ||
255
+ !hasToolcraftExactRecordKeys(plan, keys) ||
256
+ !hashPattern.test(plan.sourceHash ?? "") ||
243
257
  !hashPattern.test(plan.functionalProofModelHash ?? "") ||
244
258
  !hashPattern.test(plan.manifestHash ?? "") ||
245
- !denseExactArray(plan.steps) ||
246
- !plan.steps.length) return "Toolcraft delivery plan is malformed.";
247
- if (!(exact(plan.basis, ["kind"]) && plan.basis.kind === "initial")) {
248
- if (!exact(plan.basis, ["changedFiles",
249
- "comparisonFunctionalProofModelHash", "comparisonInventory", "kind"]) ||
250
- plan.basis.kind !== "changed") return "Delivery plan basis is malformed.";
251
- const basisProblem = inventoryError(
252
- plan.basis.comparisonInventory, "Plan comparison inventory");
253
- if (basisProblem ||
254
- !hashPattern.test(plan.basis.comparisonFunctionalProofModelHash ?? "") ||
255
- !targets(plan.basis.changedFiles, { paths: true }) ||
256
- plan.basis.comparisonInventory.sourceHash === plan.sourceHash)
257
- return basisProblem ??
258
- "Changed delivery plan comparison functional proof model hash or provenance is invalid.";
259
+ !Array.isArray(plan.steps) ||
260
+ plan.steps.length === 0
261
+ ) {
262
+ return "Toolcraft delivery plan is malformed.";
259
263
  }
260
- if (plan.kind === "performance-iteration" &&
261
- plan.basis.kind !== "changed")
262
- return "Performance iteration requires a previous successful delivery.";
263
- const lifecycleProblem = getToolcraftDeliveryPlanLifecycleError(plan);
264
- if (lifecycleProblem) return lifecycleProblem;
265
- const kinds = plan.steps.map((step) => step.kind);
264
+ const lifecycleError = getToolcraftDeliveryPlanLifecycleError(plan);
265
+ if (lifecycleError) return lifecycleError;
266
+ const kinds = plan.steps.map(({ kind }) => kind);
266
267
  const stepProblem = plan.steps.map(stepError).find(Boolean);
267
268
  if (stepProblem) return stepProblem;
268
- if (new Set(kinds).size !== kinds.length ||
269
- kinds.some((kind, index) => index &&
270
- stepOrder.indexOf(kinds[index - 1]) >= stepOrder.indexOf(kind))) {
269
+ if (
270
+ new Set(kinds).size !== kinds.length ||
271
+ kinds.some((kind, index) => index > 0 &&
272
+ stepOrder.indexOf(kinds[index - 1]) >= stepOrder.indexOf(kind))
273
+ ) {
271
274
  return "Delivery proof steps are duplicate or out of canonical order.";
272
275
  }
273
276
  const buildIndex = kinds.indexOf("build");
274
- if (kinds.some((kind, index) => kind.startsWith("browser-") &&
275
- (buildIndex < 0 || buildIndex > index)))
277
+ if (kinds.some((kind, index) =>
278
+ kind.startsWith("browser-") && (buildIndex < 0 || buildIndex > index),
279
+ )) {
276
280
  return "Browser proof requires a preceding build.";
277
- if (kinds.includes("browser-performance") &&
278
- !kinds.includes("browser-functional"))
279
- return "Browser performance proof requires functional browser proof.";
280
- if (plan.basis.kind === "initial" &&
281
- (!fullProof(kinds) || kinds.includes("dependencies")))
282
- return "Initial delivery proof is not the fixed complete functional proof.";
283
- if (plan.basis.kind === "changed" && kinds.includes("dependencies") &&
284
- !fullProof(kinds))
285
- return "Dependency delivery proof cannot be weakened.";
286
- if (plan.kind === "functional")
287
- return kinds.includes("browser-performance")
288
- ? "Functional delivery plans cannot include browser performance proof."
289
- : undefined;
290
- if (!hashPattern.test(plan.requestAuthorityHash) ||
291
- !kinds.includes("browser-performance"))
292
- return "Performance iteration authority or proof is invalid.";
293
- const comparison = plan.performanceComparison;
294
- if (exact(comparison, ["kind"]) && comparison.kind === "none") return;
295
- if (!exact(comparison, ["comparisonHash", "kind", "report"]) ||
296
- comparison.kind !== "compatible-targeted-report" ||
297
- !hashPattern.test(comparison.comparisonHash) ||
298
- comparison.report?.version !== 3 ||
299
- getToolcraftTargetedPerformanceReportError(comparison.report) ||
300
- createToolcraftTargetedPerformanceComparisonHash(
301
- comparison.report,
302
- ) !== comparison.comparisonHash)
303
- return "Performance comparison is malformed or implicit.";
304
- const performance = plan.steps.find((step) => step.kind === "browser-performance");
305
- if (comparison.report.fixtureResolutionMode !== "strict-development" ||
306
- comparison.report.requestAuthorityHash === plan.requestAuthorityHash ||
307
- comparison.report.sourceHash !== plan.basis.comparisonInventory.sourceHash ||
308
- !same(comparison.report.performancePathIds, performance.pathIds) ||
309
- !same(comparison.report.performancePassIds, performance.passIds) ||
310
- !same(comparison.report.testNames, performance.testNames))
311
- return "Previous targeted report is not compatible with the plan.";
281
+ }
282
+ if (plan.kind === "functional") {
283
+ const expected = [
284
+ "docs",
285
+ "code-health",
286
+ "product-tests",
287
+ "build",
288
+ "browser-functional",
289
+ ];
290
+ if (
291
+ !hasToolcraftExactRecordKeys(plan.basis, ["kind"]) ||
292
+ plan.basis.kind !== "initial" ||
293
+ !same(kinds, expected)
294
+ ) {
295
+ return "Initial delivery proof is not the fixed complete functional proof.";
296
+ }
297
+ return undefined;
298
+ }
299
+ if (
300
+ !hasToolcraftExactRecordKeys(plan.basis, [
301
+ "initialFunctionalProofModelHash",
302
+ "initialSourceHash",
303
+ "kind",
304
+ ]) ||
305
+ plan.basis.kind !== "performance-request" ||
306
+ !hashPattern.test(plan.basis.initialFunctionalProofModelHash ?? "") ||
307
+ !hashPattern.test(plan.basis.initialSourceHash ?? "") ||
308
+ !hashPattern.test(plan.requestAuthorityHash ?? "") ||
309
+ !same(kinds, ["build", "browser-performance"])
310
+ ) {
311
+ return "Performance iteration plan is malformed or expands beyond exact performance work.";
312
+ }
313
+ return performanceComparisonError(
314
+ plan,
315
+ plan.steps.find(({ kind }) => kind === "browser-performance"),
316
+ );
312
317
  }
318
+
313
319
  export function createToolcraftDeliveryPlan(inputs) {
314
320
  const problem = inputError(inputs);
315
321
  if (problem) throw new Error(problem);
316
- const plan = constructToolcraftDeliveryPlan(inputs);
317
- const frozen = deepFreeze(JSON.parse(JSON.stringify(plan)));
318
- const planProblem = getToolcraftDeliveryPlanError(frozen);
322
+ const plan = deepFreezeToolcraftValue(
323
+ JSON.parse(JSON.stringify(constructToolcraftDeliveryPlan(inputs))),
324
+ );
325
+ const planProblem = getToolcraftDeliveryPlanError(plan);
319
326
  if (planProblem) throw new Error(planProblem);
320
- return frozen;
327
+ return plan;
321
328
  }
329
+
322
330
  export function createToolcraftDeliveryPlanHash(plan) {
323
331
  const problem = getToolcraftDeliveryPlanError(plan);
324
332
  if (problem) throw new Error(problem);
325
333
  return createToolcraftCanonicalJsonHash(plan);
326
334
  }
335
+
327
336
  export function getToolcraftDeliveryDiagnosticTier(plan) {
328
337
  const problem = getToolcraftDeliveryPlanError(plan);
329
338
  if (problem) throw new Error(problem);
330
- const kinds = new Set(plan.steps.map((step) => step.kind));
331
- if (plan.basis.kind === "initial") return 4;
332
- if (plan.kind === "performance-iteration") return 3;
333
- if (kinds.has("dependencies")) return 4;
334
- if (kinds.has("browser-functional")) return 2;
335
- if (kinds.has("code-health") || kinds.has("product-tests") ||
336
- kinds.has("build")) return 1;
337
- return 0;
339
+ return plan.kind === "functional" ? 4 : 3;
338
340
  }