@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
@@ -11,7 +11,7 @@ import type {
11
11
  ToolcraftFunctionalProofModel,
12
12
  } from "./toolcraft-functional-proof-model.mjs";
13
13
 
14
- export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION: 7;
14
+ export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION: 8;
15
15
 
16
16
  export type ToolcraftResolvedTestEvidence = Readonly<{
17
17
  fullTitle: string;
@@ -19,7 +19,6 @@ export type ToolcraftResolvedTestEvidence = Readonly<{
19
19
  }>;
20
20
 
21
21
  export type ToolcraftDeliveryStepEvidence =
22
- | Readonly<{ kind: "dependencies"; packageManager: "npm" | "pnpm" | "yarn" | "bun" }>
23
22
  | Readonly<{ kind: "docs" }>
24
23
  | Readonly<{ kind: "code-health" }>
25
24
  | Readonly<{ kind: "product-tests"; files: readonly string[] }>
@@ -49,12 +48,12 @@ export type ToolcraftDeliveryReceipt = Readonly<{
49
48
  files: readonly ToolcraftVerificationInventoryEntry[];
50
49
  functionalProofModel: ToolcraftFunctionalProofModel;
51
50
  functionalProofModelHash: string;
52
- kind: "delivery-verification";
51
+ kind: "delivery-verification" | "targeted-performance-verification";
53
52
  manifestHash: string;
54
53
  mode?: never;
55
54
  plan: ToolcraftDeliveryPlan;
56
55
  planHash: string;
57
- planVersion: 4;
56
+ planVersion: 6;
58
57
  runner: "protected-delivery";
59
58
  sourceHash: string;
60
59
  status: "passed";
@@ -78,6 +77,5 @@ export function readToolcraftDeliveryReceipt(rootDir: string): Promise<{
78
77
  }>;
79
78
 
80
79
  export function validateToolcraftDeliveryReceipt(options: {
81
- collectInventory?: (rootDir: string) => Promise<ToolcraftVerificationInventory>;
82
80
  rootDir: string;
83
81
  }): Promise<string[]>;
@@ -12,12 +12,10 @@ import {
12
12
  } from "./toolcraft-functional-proof-model.mjs";
13
13
  import { readToolcraftCheckpointBundle } from "./toolcraft-checkpoint-bundle.mjs";
14
14
  import {
15
- collectToolcraftVerificationInputs,
16
- getToolcraftChangedVerificationFiles,
17
15
  getToolcraftVerificationInventoryError,
18
16
  } from "./toolcraft-verification-inventory.mjs";
19
17
 
20
- export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION = 7;
18
+ export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION = 8;
21
19
 
22
20
  const receiptKeys = Object.freeze([
23
21
  "completedAt",
@@ -57,15 +55,6 @@ function hasExactKeys(value, expected) {
57
55
  );
58
56
  }
59
57
 
60
- function arraysEqual(left, right) {
61
- return (
62
- Array.isArray(left) &&
63
- Array.isArray(right) &&
64
- left.length === right.length &&
65
- left.every((item, index) => item === right[index])
66
- );
67
- }
68
-
69
58
  function deepFreeze(value) {
70
59
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
71
60
  Object.values(value).forEach(deepFreeze);
@@ -77,7 +66,10 @@ function deepFreeze(value) {
77
66
  function getCurrentReceiptCommonError(receipt) {
78
67
  if (
79
68
  !hasExactKeys(receipt, receiptKeys) ||
80
- receipt.kind !== "delivery-verification" ||
69
+ ![
70
+ "delivery-verification",
71
+ "targeted-performance-verification",
72
+ ].includes(receipt.kind) ||
81
73
  receipt.runner !== "protected-delivery" ||
82
74
  receipt.status !== "passed" ||
83
75
  receipt.version !== TOOLCRAFT_DELIVERY_RECEIPT_VERSION ||
@@ -104,6 +96,12 @@ export function getToolcraftDeliveryReceiptShapeError(receipt) {
104
96
  const functionalProofModel = deepFreeze(receipt.functionalProofModel);
105
97
  const planError = getToolcraftDeliveryPlanError(plan);
106
98
  if (planError) return planError;
99
+ const expectedKind = plan.kind === "functional"
100
+ ? "delivery-verification"
101
+ : "targeted-performance-verification";
102
+ if (receipt.kind !== expectedKind) {
103
+ return "Toolcraft protected receipt kind does not match its plan.";
104
+ }
107
105
  const modelError =
108
106
  getToolcraftFunctionalProofModelError(functionalProofModel);
109
107
  if (modelError) {
@@ -125,18 +123,6 @@ export function getToolcraftDeliveryReceiptShapeError(receipt) {
125
123
  if (createToolcraftDeliveryPlanHash(plan) !== receipt.planHash) {
126
124
  return "Toolcraft delivery receipt plan hash does not match its plan.";
127
125
  }
128
- if (
129
- plan.basis.kind === "changed" &&
130
- !arraysEqual(
131
- plan.basis.changedFiles,
132
- getToolcraftChangedVerificationFiles(
133
- plan.basis.comparisonInventory.entries,
134
- receipt.files,
135
- ),
136
- )
137
- ) {
138
- return "Toolcraft delivery receipt changed files do not exactly match its inventories.";
139
- }
140
126
  return getToolcraftExecutionEvidenceError({
141
127
  evidence: receipt.evidence,
142
128
  finalInventory: {
@@ -179,7 +165,9 @@ export function createToolcraftDeliveryReceipt({
179
165
  files: result?.finalInventory?.entries,
180
166
  functionalProofModel,
181
167
  functionalProofModelHash,
182
- kind: "delivery-verification",
168
+ kind: plan.kind === "functional"
169
+ ? "delivery-verification"
170
+ : "targeted-performance-verification",
183
171
  manifestHash: plan.manifestHash,
184
172
  plan,
185
173
  planHash,
@@ -203,14 +191,10 @@ export async function readToolcraftDeliveryReceipt(rootDir) {
203
191
  }
204
192
 
205
193
  export async function validateToolcraftDeliveryReceipt({
206
- collectInventory = collectToolcraftVerificationInputs,
207
194
  rootDir,
208
195
  }) {
209
196
  const loaded = await readToolcraftDeliveryReceipt(rootDir);
210
197
  if (loaded.missing) return ["Toolcraft delivery receipt is missing."];
211
198
  if (loaded.error) return [loaded.error];
212
- const inventory = await collectInventory(rootDir);
213
- return loaded.receipt.sourceHash === inventory.sourceHash
214
- ? []
215
- : ["Toolcraft delivery receipt is stale for the current source."];
199
+ return [];
216
200
  }
@@ -24,7 +24,7 @@ function assertDeeplyFrozen(value) {
24
24
  Object.values(value).forEach(assertDeeplyFrozen);
25
25
  }
26
26
 
27
- test("constructs the exact deeply frozen version 7 receipt", () => {
27
+ test("constructs the exact deeply frozen version 8 receipt", () => {
28
28
  const { functionalProofModel, plan, result } = createPlanReceiptFixture();
29
29
  const receipt = createToolcraftDeliveryReceipt({
30
30
  functionalProofModel,
@@ -32,9 +32,9 @@ test("constructs the exact deeply frozen version 7 receipt", () => {
32
32
  result,
33
33
  });
34
34
 
35
- assert.equal(TOOLCRAFT_DELIVERY_RECEIPT_VERSION, 7);
36
- assert.equal(receipt.planVersion, 4);
37
- assert.equal(receipt.version, 7);
35
+ assert.equal(TOOLCRAFT_DELIVERY_RECEIPT_VERSION, 8);
36
+ assert.equal(receipt.planVersion, 6);
37
+ assert.equal(receipt.version, 8);
38
38
  assert.deepEqual(Object.keys(receipt).sort(), [
39
39
  "completedAt",
40
40
  "evidence",
@@ -74,22 +74,40 @@ test("constructs initial functional proof with exact browser evidence", () => {
74
74
  );
75
75
  });
76
76
 
77
- test("rejects obsolete receipt 6 and plan 3 identities", () => {
77
+ test("receipt creation rejects an initial plan with an empty runtime selection", () => {
78
+ const fixture = createPlanReceiptFixture("functional-initial");
79
+ const plan = structuredClone(fixture.plan);
80
+ plan.steps.find(({ kind }) => kind === "product-tests").acceptanceIds = [];
81
+ const freeze = (value) => {
82
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
83
+ Object.values(value).forEach(freeze);
84
+ Object.freeze(value);
85
+ }
86
+ return value;
87
+ };
88
+
89
+ assert.throws(
90
+ () => createToolcraftDeliveryReceipt({ ...fixture, plan: freeze(plan) }),
91
+ /complete product-test selection/iu,
92
+ );
93
+ });
94
+
95
+ test("rejects obsolete receipt 7 and plan 5 identities", () => {
78
96
  const receipt = createToolcraftDeliveryReceipt(
79
- createPlanReceiptFixture("functional-changed"),
97
+ createPlanReceiptFixture("functional-initial"),
80
98
  );
81
99
 
82
100
  assert.match(
83
- getToolcraftDeliveryReceiptShapeError({ ...receipt, version: 6 }),
101
+ getToolcraftDeliveryReceiptShapeError({ ...receipt, version: 7 }),
84
102
  /malformed|unsupported/iu,
85
103
  );
86
104
  assert.match(
87
- getToolcraftDeliveryReceiptShapeError({ ...receipt, planVersion: 3 }),
105
+ getToolcraftDeliveryReceiptShapeError({ ...receipt, planVersion: 5 }),
88
106
  /malformed|unsupported/iu,
89
107
  );
90
108
  });
91
109
 
92
- test("validates only the current receipt source and ignores full-performance state", async (t) => {
110
+ test("validates historical initial proof without requiring later source freshness", async (t) => {
93
111
  const rootDir = await createReceiptFixture();
94
112
  t.after(() => fs.rm(rootDir, { force: true, recursive: true }));
95
113
  const { functionalProofModel, plan, result } = createPlanReceiptFixture();
@@ -106,17 +124,7 @@ test("validates only the current receipt source and ignores full-performance sta
106
124
  bundle.performanceBaseline = { malformed: true };
107
125
  await fs.writeFile(bundlePath, `${JSON.stringify(bundle)}\n`);
108
126
 
109
- assert.deepEqual(await validateToolcraftDeliveryReceipt({
110
- collectInventory: async () => result.finalInventory,
111
- rootDir,
112
- }), []);
113
- assert.deepEqual(await validateToolcraftDeliveryReceipt({
114
- collectInventory: async () => ({
115
- ...result.finalInventory,
116
- sourceHash: "0".repeat(64),
117
- }),
118
- rootDir,
119
- }), ["Toolcraft delivery receipt is stale for the current source."]);
127
+ assert.deepEqual(await validateToolcraftDeliveryReceipt({ rootDir }), []);
120
128
  });
121
129
 
122
130
  test("rejects a different valid model and every model/hash tamper", () => {
@@ -18,23 +18,12 @@ import type {
18
18
  } from "./toolcraft-functional-proof-model.mjs";
19
19
 
20
20
  const files = [{ path: "src/app/app-schema.ts", sha256: "a".repeat(64) }];
21
- const comparisonFiles = [
22
- { path: "src/app/app-schema.ts", sha256: "b".repeat(64) },
23
- ];
24
21
  const lifecycle: ToolcraftDeliveryLifecycleState = {
25
22
  consumedPerformanceRequestAuthorityHashes: ["e".repeat(64)],
26
23
  performanceEscalationOffered: true,
27
24
  };
28
25
  const plan: ToolcraftDeliveryPlan = {
29
- basis: {
30
- changedFiles: ["src/app/app-schema.ts"],
31
- comparisonFunctionalProofModelHash: "f".repeat(64),
32
- comparisonInventory: {
33
- entries: comparisonFiles,
34
- sourceHash: "b".repeat(64),
35
- },
36
- kind: "changed",
37
- },
26
+ basis: { kind: "initial" },
38
27
  functionalProofModelHash: "f".repeat(64),
39
28
  kind: "functional",
40
29
  lifecycle,
@@ -53,12 +42,7 @@ const functionalProofModel: ToolcraftFunctionalProofModel = {
53
42
  file: "app-controls.spec.ts",
54
43
  testName: "browser: focused acceptance",
55
44
  }],
56
- owners: [{
57
- acceptanceIds: ["canvas.focused"],
58
- kind: "functional",
59
- path: "src/app/app-schema.ts",
60
- }],
61
- version: 1,
45
+ version: 2,
62
46
  };
63
47
  const receipt: ToolcraftDeliveryReceipt = {
64
48
  completedAt: "2026-07-24T00:00:00.000Z",
@@ -70,11 +54,11 @@ const receipt: ToolcraftDeliveryReceipt = {
70
54
  manifestHash: plan.manifestHash,
71
55
  plan,
72
56
  planHash: "d".repeat(64),
73
- planVersion: 4,
57
+ planVersion: 6,
74
58
  runner: "protected-delivery",
75
59
  sourceHash: plan.sourceHash,
76
60
  status: "passed",
77
- version: 7,
61
+ version: 8,
78
62
  };
79
63
 
80
64
  const withLegacyMode = { ...receipt, mode: "ordinary" as const };
@@ -88,10 +72,10 @@ const withBaseline = {
88
72
  // @ts-expect-error Current delivery receipts cannot carry baseline linkage.
89
73
  const invalidBaseline: ToolcraftDeliveryReceipt = withBaseline;
90
74
  const withOldPlanVersion = { ...receipt, planVersion: 1 as const };
91
- // @ts-expect-error Current delivery receipts require plan version 4.
75
+ // @ts-expect-error Current delivery receipts require plan version 6.
92
76
  const invalidPlanVersion: ToolcraftDeliveryReceipt = withOldPlanVersion;
93
- const withOldReceiptVersion = { ...receipt, version: 6 as const };
94
- // @ts-expect-error Current delivery receipts require receipt version 7.
77
+ const withOldReceiptVersion = { ...receipt, version: 7 as const };
78
+ // @ts-expect-error Current delivery receipts require receipt version 8.
95
79
  const invalidReceiptVersion: ToolcraftDeliveryReceipt = withOldReceiptVersion;
96
80
  const { functionalProofModel: _model, ...withoutModel } = receipt;
97
81
  // @ts-expect-error Current delivery receipts require the canonical proof model.
@@ -114,6 +98,11 @@ const invalidFunctional: FunctionalDeliveryPlan = {
114
98
  };
115
99
  const invalidIteration: PerformanceIterationPlan = {
116
100
  ...plan,
101
+ basis: {
102
+ initialFunctionalProofModelHash: "f".repeat(64),
103
+ initialSourceHash: "a".repeat(64),
104
+ kind: "performance-request",
105
+ },
117
106
  kind: "performance-iteration",
118
107
  performanceComparison: { kind: "none" },
119
108
  requestAuthorityHash: "e".repeat(64),
@@ -129,14 +118,17 @@ const initialPerformanceCandidate = {
129
118
  performanceComparison: { kind: "none" as const },
130
119
  requestAuthorityHash: "e".repeat(64),
131
120
  sourceHash: "a".repeat(64),
132
- steps: [{
133
- kind: "browser-performance" as const,
134
- passIds: ["preview"],
135
- pathIds: ["path"],
136
- testNames: ["browser perf: path"],
137
- }] as const,
121
+ steps: [
122
+ { kind: "build" as const },
123
+ {
124
+ kind: "browser-performance" as const,
125
+ passIds: ["preview"],
126
+ pathIds: ["path"],
127
+ testNames: ["browser perf: path"],
128
+ },
129
+ ] as const,
138
130
  };
139
- // @ts-expect-error Performance iterations require a changed delivery basis.
131
+ // @ts-expect-error Performance iterations require a performance-request basis.
140
132
  const invalidInitialIteration: PerformanceIterationPlan =
141
133
  initialPerformanceCandidate;
142
134
  // @ts-expect-error Lifecycle authority history is immutable.
@@ -0,0 +1,20 @@
1
+ export const TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION: 1;
2
+
3
+ export type ToolcraftFeatureVerificationPlan = Readonly<{
4
+ acceptanceIds: readonly string[];
5
+ testNames: readonly string[];
6
+ version: 1;
7
+ }>;
8
+
9
+ export type ToolcraftFeatureVerificationPlanValidation = Readonly<{
10
+ errors: readonly string[];
11
+ plan?: ToolcraftFeatureVerificationPlan;
12
+ }>;
13
+
14
+ export function validateToolcraftFeatureVerificationPlan(
15
+ value: unknown,
16
+ ): ToolcraftFeatureVerificationPlanValidation;
17
+
18
+ export function parseToolcraftFeatureVerificationPlanOutput(
19
+ output: unknown,
20
+ ): ToolcraftFeatureVerificationPlan;
@@ -0,0 +1,146 @@
1
+ export const TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION = 1;
2
+
3
+ const compareCodeUnits = (left, right) =>
4
+ left < right ? -1 : left > right ? 1 : 0;
5
+
6
+ function isPlainObject(value) {
7
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
8
+ return false;
9
+ }
10
+ const prototype = Object.getPrototypeOf(value);
11
+ return prototype === Object.prototype || prototype === null;
12
+ }
13
+
14
+ function getExactKeyErrors(value, expected, label) {
15
+ if (!isPlainObject(value)) return [`${label} must be a plain object.`];
16
+ const expectedSet = new Set(expected);
17
+ const ownKeys = Reflect.ownKeys(value);
18
+ const unknown = ownKeys
19
+ .filter((key) => typeof key !== "string" || !expectedSet.has(key))
20
+ .map(String)
21
+ .sort(compareCodeUnits);
22
+ const missing = expected.filter(
23
+ (key) => !Object.prototype.hasOwnProperty.call(value, key),
24
+ );
25
+ return [
26
+ ...(unknown.length > 0
27
+ ? [`${label} contains unknown fields: ${unknown.join(", ")}.`]
28
+ : []),
29
+ ...(missing.length > 0
30
+ ? [`${label} is missing required fields: ${missing.join(", ")}.`]
31
+ : []),
32
+ ];
33
+ }
34
+
35
+ function validateCanonicalStringArray(value, label) {
36
+ if (!Array.isArray(value)) {
37
+ return [`Toolcraft feature verification plan.${label} must be an array.`];
38
+ }
39
+ if (Object.getOwnPropertySymbols(value).length > 0) {
40
+ return [
41
+ `Toolcraft feature verification plan.${label} contains symbol fields.`,
42
+ ];
43
+ }
44
+ const errors = [];
45
+ if (value.length === 0) {
46
+ errors.push(
47
+ `Toolcraft feature verification plan.${label} must be non-empty.`,
48
+ );
49
+ }
50
+ if (
51
+ !value.every(
52
+ (entry) =>
53
+ typeof entry === "string" &&
54
+ entry.length > 0 &&
55
+ entry.trim() === entry,
56
+ )
57
+ ) {
58
+ errors.push(
59
+ `Toolcraft feature verification plan.${label} must contain trimmed non-empty strings.`,
60
+ );
61
+ }
62
+ if (new Set(value).size !== value.length) {
63
+ errors.push(
64
+ `Toolcraft feature verification plan.${label} must contain unique values.`,
65
+ );
66
+ }
67
+ if (
68
+ value.every((entry) => typeof entry === "string") &&
69
+ value.some((entry, index) => entry !== [...value].sort(compareCodeUnits)[index])
70
+ ) {
71
+ errors.push(
72
+ `Toolcraft feature verification plan.${label} must be sorted by code unit.`,
73
+ );
74
+ }
75
+ return errors;
76
+ }
77
+
78
+ export function validateToolcraftFeatureVerificationPlan(value) {
79
+ const errors = getExactKeyErrors(
80
+ value,
81
+ ["acceptanceIds", "testNames", "version"],
82
+ "Toolcraft feature verification plan",
83
+ );
84
+ if (!isPlainObject(value)) return { errors };
85
+
86
+ if (value.version !== TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION) {
87
+ errors.push(
88
+ `Toolcraft feature verification plan.version must be ${TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION}.`,
89
+ );
90
+ }
91
+ errors.push(
92
+ ...validateCanonicalStringArray(value.acceptanceIds, "acceptanceIds"),
93
+ ...validateCanonicalStringArray(value.testNames, "testNames"),
94
+ );
95
+ if (
96
+ Array.isArray(value.acceptanceIds) &&
97
+ Array.isArray(value.testNames) &&
98
+ value.acceptanceIds.length !== value.testNames.length
99
+ ) {
100
+ errors.push(
101
+ "Toolcraft feature verification plan must contain one test name per acceptance id.",
102
+ );
103
+ }
104
+ if (errors.length > 0) return { errors };
105
+
106
+ return {
107
+ errors,
108
+ plan: Object.freeze({
109
+ acceptanceIds: Object.freeze([...value.acceptanceIds]),
110
+ testNames: Object.freeze([...value.testNames]),
111
+ version: TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION,
112
+ }),
113
+ };
114
+ }
115
+
116
+ export function parseToolcraftFeatureVerificationPlanOutput(output) {
117
+ if (typeof output !== "string") {
118
+ throw new Error(
119
+ "Toolcraft feature verification reporter must emit exactly one JSON line.",
120
+ );
121
+ }
122
+ const lines = output.split(/\r?\n/u);
123
+ if (lines.at(-1) === "") lines.pop();
124
+ if (lines.length !== 1 || lines[0].length === 0) {
125
+ throw new Error(
126
+ "Toolcraft feature verification reporter must emit exactly one JSON line.",
127
+ );
128
+ }
129
+
130
+ let value;
131
+ try {
132
+ value = JSON.parse(lines[0]);
133
+ } catch (error) {
134
+ throw new Error(
135
+ "Toolcraft feature verification reporter must emit valid JSON.",
136
+ { cause: error },
137
+ );
138
+ }
139
+ const validation = validateToolcraftFeatureVerificationPlan(value);
140
+ if (validation.errors.length > 0) {
141
+ throw new Error(
142
+ `Invalid Toolcraft feature verification plan:\n${validation.errors.join("\n")}`,
143
+ );
144
+ }
145
+ return validation.plan;
146
+ }
@@ -0,0 +1,96 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import {
5
+ TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION,
6
+ parseToolcraftFeatureVerificationPlanOutput,
7
+ validateToolcraftFeatureVerificationPlan,
8
+ } from "./toolcraft-feature-verification-plan.mjs";
9
+
10
+ const validPlan = () => ({
11
+ acceptanceIds: ["lighting.intensity", "material.layer"],
12
+ testNames: ["browser: lighting.intensity", "browser: material.layer"],
13
+ version: 1,
14
+ });
15
+
16
+ test("normalizes a canonical deeply frozen feature verification plan", () => {
17
+ const validation = validateToolcraftFeatureVerificationPlan(validPlan());
18
+
19
+ assert.deepEqual(validation.errors, []);
20
+ assert.deepEqual(validation.plan, validPlan());
21
+ assert.equal(TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION, 1);
22
+ assert.equal(Object.isFrozen(validation.plan), true);
23
+ assert.equal(Object.isFrozen(validation.plan.acceptanceIds), true);
24
+ assert.equal(Object.isFrozen(validation.plan.testNames), true);
25
+ });
26
+
27
+ test("rejects malformed top-level plan shapes", () => {
28
+ for (const [value, pattern] of [
29
+ [null, /must be a plain object/iu],
30
+ [Object.create({ version: 1 }), /must be a plain object/iu],
31
+ [{ ...validPlan(), extra: true }, /unknown fields: extra/iu],
32
+ [{ acceptanceIds: [], testNames: [] }, /missing required fields: version/iu],
33
+ [{ ...validPlan(), version: 2 }, /version must be 1/iu],
34
+ ]) {
35
+ assert.match(
36
+ validateToolcraftFeatureVerificationPlan(value).errors.join("\n"),
37
+ pattern,
38
+ );
39
+ }
40
+ });
41
+
42
+ test("rejects empty, untrimmed, duplicate, and noncanonical arrays", () => {
43
+ const symbolArray = ["material.layer"];
44
+ symbolArray[Symbol("hidden")] = true;
45
+ for (const [value, pattern] of [
46
+ [{ ...validPlan(), acceptanceIds: [] }, /acceptanceIds must be non-empty/iu],
47
+ [{ ...validPlan(), testNames: [] }, /testNames must be non-empty/iu],
48
+ [
49
+ { ...validPlan(), acceptanceIds: ["material.layer", "material.layer"] },
50
+ /acceptanceIds must contain unique/iu,
51
+ ],
52
+ [
53
+ { ...validPlan(), testNames: ["browser: layer", "browser: layer"] },
54
+ /testNames must contain unique/iu,
55
+ ],
56
+ [
57
+ { ...validPlan(), acceptanceIds: [" material.layer"] },
58
+ /acceptanceIds must contain trimmed/iu,
59
+ ],
60
+ [
61
+ { ...validPlan(), testNames: ["browser: layer "] },
62
+ /testNames must contain trimmed/iu,
63
+ ],
64
+ [
65
+ { ...validPlan(), acceptanceIds: ["material.layer", "lighting.intensity"] },
66
+ /acceptanceIds must be sorted/iu,
67
+ ],
68
+ [{ ...validPlan(), acceptanceIds: symbolArray }, /symbol fields/iu],
69
+ ]) {
70
+ assert.match(
71
+ validateToolcraftFeatureVerificationPlan(value).errors.join("\n"),
72
+ pattern,
73
+ );
74
+ }
75
+ });
76
+
77
+ test("parses exactly one JSON plan line", () => {
78
+ assert.deepEqual(
79
+ parseToolcraftFeatureVerificationPlanOutput(`${JSON.stringify(validPlan())}\n`),
80
+ validPlan(),
81
+ );
82
+ for (const [output, pattern] of [
83
+ ["", /exactly one JSON line/iu],
84
+ ["not-json\n", /valid JSON/iu],
85
+ [
86
+ `${JSON.stringify(validPlan())}\n${JSON.stringify(validPlan())}\n`,
87
+ /exactly one JSON line/iu,
88
+ ],
89
+ [JSON.stringify({ ...validPlan(), version: 2 }), /version must be 1/iu],
90
+ ]) {
91
+ assert.throws(
92
+ () => parseToolcraftFeatureVerificationPlanOutput(output),
93
+ pattern,
94
+ );
95
+ }
96
+ });
@@ -1,8 +1,6 @@
1
1
  import type {
2
2
  ToolcraftDeliveryCatalog,
3
- ToolcraftVerificationImpactInventory,
4
- ToolcraftVerificationImpactOwner,
5
- } from "./toolcraft-verification-impact-inventory.mjs";
3
+ } from "./playwright-test-title-selection.mjs";
6
4
 
7
5
  export type ToolcraftFunctionalProofAcceptance = Readonly<{
8
6
  acceptanceId: string;
@@ -12,16 +10,12 @@ export type ToolcraftFunctionalProofAcceptance = Readonly<{
12
10
  testName: string;
13
11
  }>;
14
12
 
15
- export type ToolcraftFunctionalProofOwner =
16
- ToolcraftVerificationImpactOwner;
17
-
18
13
  export type ToolcraftFunctionalProofModel = Readonly<{
19
14
  acceptance: readonly ToolcraftFunctionalProofAcceptance[];
20
- owners: readonly ToolcraftFunctionalProofOwner[];
21
- version: 1;
15
+ version: 2;
22
16
  }>;
23
17
 
24
- export const TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION: 1;
18
+ export const TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION: 2;
25
19
 
26
20
  export {
27
21
  createToolcraftAcceptanceContractHash,
@@ -29,7 +23,6 @@ export {
29
23
  } from "./toolcraft-functional-proof-primitives.mjs";
30
24
  export function createToolcraftFunctionalProofModel(input: {
31
25
  catalog: ToolcraftDeliveryCatalog;
32
- inventory: ToolcraftVerificationImpactInventory;
33
26
  }): ToolcraftFunctionalProofModel;
34
27
  export function createToolcraftFunctionalProofModelHash(
35
28
  model: ToolcraftFunctionalProofModel,
@@ -37,11 +30,3 @@ export function createToolcraftFunctionalProofModelHash(
37
30
  export function getToolcraftFunctionalProofModelError(
38
31
  value: unknown,
39
32
  ): string | undefined;
40
- export function diffToolcraftFunctionalProofModels(input: {
41
- current: ToolcraftFunctionalProofModel;
42
- previous: ToolcraftFunctionalProofModel;
43
- }): Readonly<{
44
- acceptanceIds: readonly string[];
45
- changedOwnerPaths: readonly string[];
46
- removedAcceptanceIds: readonly string[];
47
- }>;