@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
@@ -2,22 +2,12 @@ import assert from "node:assert/strict";
2
2
  import test from "node:test";
3
3
 
4
4
  import {
5
- normalizeToolcraftDeliveryAnchor,
6
- } from "./toolcraft-delivery-anchor.mjs";
5
+ createToolcraftDeliveryLifecycleState,
6
+ } from "./toolcraft-delivery-lifecycle-state.mjs";
7
7
  import {
8
8
  createToolcraftDeliveryReceipt,
9
9
  } from "./toolcraft-delivery-receipt.mjs";
10
10
  import {
11
- createToolcraftDeliveryPlan,
12
- } from "./toolcraft-delivery-plan.mjs";
13
- import {
14
- EMPTY_TOOLCRAFT_DELIVERY_LIFECYCLE_STATE,
15
- } from "./toolcraft-delivery-lifecycle-state.mjs";
16
- import {
17
- createToolcraftFunctionalProofModel,
18
- } from "./toolcraft-functional-proof-model.mjs";
19
- import {
20
- createInventory,
21
11
  createPlanReceiptFixture,
22
12
  } from "./toolcraft-delivery-receipt-test-helpers.mjs";
23
13
  import {
@@ -25,369 +15,111 @@ import {
25
15
  getToolcraftPerformanceEscalationRecommendation,
26
16
  } from "./toolcraft-performance-escalation-policy.mjs";
27
17
  import {
28
- createToolcraftPerformanceRequestAuthorityHash,
29
- TOOLCRAFT_FULL_PERFORMANCE_VERIFICATION_COMMAND,
30
- } from "./toolcraft-performance-authority-policy.mjs";
31
- import {
32
- createToolcraftTargetedPerformanceReport,
18
+ createToolcraftTargetedPerformanceComparisonHash,
33
19
  createToolcraftTargetedPerformanceEvidenceHash,
20
+ createToolcraftTargetedPerformanceReport,
34
21
  } from "./toolcraft-targeted-performance-report.mjs";
35
- import {
36
- createTargetedMeasurementFixture,
37
- } from "./toolcraft-verification-receipt-test-helpers.mjs";
38
-
39
- const hash = (character) => character.repeat(64);
40
- const pathId =
41
- "performance-path:%5B%22interactive-discrete%22%2C%22control-change%22%2C%5B%22composite%22%5D%2C%5B%22main%22%5D%2C%5B%5D%5D";
42
- const performanceTestName = `browser perf: toolcraft path ${pathId}`;
43
- const functionalTestName = "browser: focused acceptance";
44
- const expectedRecommendation = {
45
- command: TOOLCRAFT_FULL_PERFORMANCE_VERIFICATION_COMMAND,
46
- kind: "offer-full-performance-audit",
47
- reason: "two-consecutive-compatible-performance-iterations",
48
- requiresExplicitUserConsent: true,
49
- };
50
-
51
- function deliveryCatalog(testName = functionalTestName) {
52
- return {
53
- acceptance: [{
54
- acceptanceId: "output.updates",
55
- contractHash: hash("b"),
56
- domainId: "output",
57
- file: "app-controls.spec.ts",
58
- testName,
59
- }],
60
- performance: [{
61
- passIds: ["composite"],
62
- pathId,
63
- testName: performanceTestName,
64
- }],
65
- version: 2,
66
- };
67
- }
68
-
69
- function functionalProofModel(catalog) {
70
- return createToolcraftFunctionalProofModel({
71
- catalog,
72
- inventory: {
73
- owners: [{
74
- acceptanceIds: ["output.updates"],
75
- kind: "performance",
76
- passIds: ["composite"],
77
- path: "src/app/app-schema.ts",
78
- }],
79
- version: 3,
80
- },
81
- });
82
- }
83
22
 
84
- function requestAuthority(heading, request) {
85
- const source = {
86
- heading,
87
- pathIds: [pathId],
88
- request,
89
- requestEvidence: request,
90
- };
91
- return {
92
- hash: createToolcraftPerformanceRequestAuthorityHash(source),
93
- ...source,
94
- };
23
+ function freeze(value) {
24
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
25
+ Object.values(value).forEach(freeze);
26
+ Object.freeze(value);
27
+ }
28
+ return value;
95
29
  }
96
30
 
97
- function createFirstPlannerReceipt() {
98
- const comparisonInventory = createInventory({
99
- "src/app/app-schema.ts": hash("1"),
100
- });
101
- const finalInventory = createInventory({
102
- "src/app/app-schema.ts": hash("2"),
103
- });
104
- const authority = requestAuthority(
105
- "Delivery 1 - Slow preview",
106
- "The preview is slow.",
107
- );
108
- const requestAuthorityHash = authority.hash;
109
- const catalog = deliveryCatalog();
110
- const model = functionalProofModel(catalog);
111
- const plan = createToolcraftDeliveryPlan({
112
- allProductTestFiles: ["src/app/app-schema.test.ts"],
113
- authority,
114
- catalog,
115
- changeSet: {
116
- dependencyChanged: false,
117
- docsChanged: false,
118
- frameworkChanged: false,
119
- impact: {
120
- acceptanceIds: ["output.updates"],
121
- browserTestNames: [functionalTestName],
122
- buildRequired: true,
123
- performanceCandidates: {
124
- passIds: ["composite"],
125
- pathIds: [pathId],
126
- testNames: [performanceTestName],
127
- },
128
- productTestFiles: [],
129
- },
130
- platformChanged: false,
131
- productInputsChanged: true,
132
- },
133
- comparisonInventory,
134
- currentFunctionalProofModel: model,
135
- currentInventory: finalInventory,
136
- integrity: {
137
- manifestHash: hash("a"),
138
- sourceHash: finalInventory.sourceHash,
139
- },
140
- packageManager: "pnpm",
141
- previousFunctionalProofModel: model,
142
- previousLifecycle: EMPTY_TOOLCRAFT_DELIVERY_LIFECYCLE_STATE,
143
- previousPerformance: { kind: "none" },
144
- });
145
- const testEvidence = [{
146
- fullTitle: `app-controls.spec.ts › ${performanceTestName}`,
147
- leafTitle: performanceTestName,
148
- }];
31
+ function createCompatiblePair() {
32
+ const firstFixture = createPlanReceiptFixture("performance-iteration");
33
+ const firstReceipt = createToolcraftDeliveryReceipt(firstFixture);
34
+ const firstEvidence = firstReceipt.evidence.at(-1);
35
+ const requestAuthorityHash = "e".repeat(64);
149
36
  const report = createToolcraftTargetedPerformanceReport({
150
- fixtureResolutionMode: "strict-development",
151
- fixtureSelector: "development",
152
- measurements: createTargetedMeasurementFixture([pathId]),
153
- nonce: "first-planner-receipt",
154
- performancePassIds: ["composite"],
155
- performancePathIds: [pathId],
37
+ ...firstEvidence.report,
38
+ nonce: "second-targeted-report",
156
39
  requestAuthorityHash,
157
- sourceHash: finalInventory.sourceHash,
158
- testNames: [performanceTestName],
159
40
  });
160
- return createToolcraftDeliveryReceipt({
161
- functionalProofModel: model,
162
- plan,
163
- result: {
164
- evidence: plan.steps.map((step) =>
165
- step.kind === "browser-performance"
166
- ? {
167
- ...step,
168
- evidenceHash: createToolcraftTargetedPerformanceEvidenceHash({
169
- report,
170
- testEvidence,
171
- }),
172
- report,
173
- testEvidence,
174
- }
175
- : { ...step }
41
+ const testEvidence = firstEvidence.testEvidence;
42
+ const plan = freeze({
43
+ ...firstReceipt.plan,
44
+ lifecycle: createToolcraftDeliveryLifecycleState({
45
+ performanceEscalationReached: true,
46
+ previous: firstReceipt.plan.lifecycle,
47
+ requestAuthorityHash,
48
+ }),
49
+ performanceComparison: {
50
+ comparisonHash: createToolcraftTargetedPerformanceComparisonHash(
51
+ firstEvidence.report,
176
52
  ),
177
- finalInventory,
53
+ kind: "compatible-targeted-report",
54
+ report: firstEvidence.report,
178
55
  },
179
- });
180
- }
181
-
182
- function createCompatibleReceipt(
183
- previousReceipt,
184
- requestMarker,
185
- inventoryCharacter,
186
- ) {
187
- const previousAnchor =
188
- normalizeToolcraftDeliveryAnchor(previousReceipt);
189
- const finalInventory = createInventory({
190
- "src/app/app-schema.ts": hash(inventoryCharacter),
191
- });
192
- const previousEvidence = previousReceipt.evidence.at(-1);
193
- const previousPerformanceStep = previousReceipt.plan.steps.find(
194
- ({ kind }) => kind === "browser-performance",
195
- );
196
- const previousFunctionalStep = previousReceipt.plan.steps.find(
197
- ({ kind }) => kind === "browser-functional",
198
- );
199
- const authority = requestAuthority(
200
- `Delivery ${requestMarker} - Slow preview`,
201
- `The preview is still slow after ${requestMarker}.`,
202
- );
203
- const requestAuthorityHash = authority.hash;
204
- const report = createToolcraftTargetedPerformanceReport({
205
- ...previousEvidence.report,
206
56
  requestAuthorityHash,
207
- sourceHash: finalInventory.sourceHash,
208
57
  });
209
- const evidenceHash = createToolcraftTargetedPerformanceEvidenceHash({
210
- report,
211
- testEvidence: previousEvidence.testEvidence,
212
- });
213
- const catalog = deliveryCatalog(
214
- previousFunctionalStep.testNames[0],
215
- );
216
- const model = previousReceipt.functionalProofModel;
217
- const plan = createToolcraftDeliveryPlan({
218
- allProductTestFiles: ["src/app/app-schema.test.ts"],
219
- authority,
220
- catalog,
221
- changeSet: {
222
- dependencyChanged: false,
223
- docsChanged: false,
224
- frameworkChanged: false,
225
- impact: {
226
- acceptanceIds: ["output.updates"],
227
- browserTestNames: previousFunctionalStep.testNames,
228
- buildRequired: true,
229
- performanceCandidates: {
230
- passIds: previousPerformanceStep.passIds,
231
- pathIds: previousPerformanceStep.pathIds,
232
- testNames: previousPerformanceStep.testNames,
58
+ const secondReceipt = createToolcraftDeliveryReceipt({
59
+ functionalProofModel: firstReceipt.functionalProofModel,
60
+ plan,
61
+ result: {
62
+ evidence: [
63
+ { kind: "build" },
64
+ {
65
+ ...firstEvidence,
66
+ evidenceHash: createToolcraftTargetedPerformanceEvidenceHash({
67
+ report,
68
+ testEvidence,
69
+ }),
70
+ report,
233
71
  },
234
- productTestFiles: [],
235
- },
236
- platformChanged: false,
237
- productInputsChanged: true,
238
- },
239
- comparisonInventory: {
240
- entries: previousReceipt.files,
241
- sourceHash: previousReceipt.sourceHash,
72
+ ],
73
+ finalInventory: firstFixture.result.finalInventory,
242
74
  },
243
- currentFunctionalProofModel: model,
244
- currentInventory: finalInventory,
245
- integrity: {
246
- manifestHash: previousReceipt.manifestHash,
247
- sourceHash: finalInventory.sourceHash,
248
- },
249
- packageManager: "pnpm",
250
- previousFunctionalProofModel:
251
- previousAnchor.functionalProofModel,
252
- previousLifecycle: previousAnchor.lifecycle,
253
- previousPerformance: previousAnchor.performance,
254
75
  });
255
- return createToolcraftDeliveryReceipt({
256
- functionalProofModel: model,
257
- plan,
258
- result: {
259
- evidence: plan.steps.map((step) =>
260
- step.kind === "browser-performance"
261
- ? {
262
- ...step,
263
- evidenceHash,
264
- report,
265
- testEvidence: previousEvidence.testEvidence,
266
- }
267
- : { ...step }
76
+ const previousAnchor = {
77
+ lifecycle: firstReceipt.plan.lifecycle,
78
+ performance: {
79
+ comparisonHash: createToolcraftTargetedPerformanceComparisonHash(
80
+ firstEvidence.report,
268
81
  ),
269
- finalInventory,
82
+ kind: "performance-iteration-report",
83
+ report: firstEvidence.report,
84
+ requestAuthorityHash: firstReceipt.plan.requestAuthorityHash,
270
85
  },
271
- });
272
- }
273
-
274
- function createCompatiblePair() {
275
- const firstReceipt = createFirstPlannerReceipt();
276
- const previousAnchor = normalizeToolcraftDeliveryAnchor(firstReceipt);
277
- const currentReceipt = createCompatibleReceipt(
278
- firstReceipt,
279
- "2",
280
- "3",
281
- );
282
- return { currentReceipt, previousAnchor };
86
+ };
87
+ return { firstReceipt, previousAnchor, secondReceipt };
283
88
  }
284
89
 
285
- test("does not recommend a full audit after the first performance iteration", () => {
286
- const currentReceipt = createToolcraftDeliveryReceipt(
90
+ test("first targeted performance iteration does not recommend a full audit", () => {
91
+ const firstReceipt = createToolcraftDeliveryReceipt(
287
92
  createPlanReceiptFixture("performance-iteration"),
288
93
  );
289
- const previousAnchor = normalizeToolcraftDeliveryAnchor(
290
- createToolcraftDeliveryReceipt(createPlanReceiptFixture("functional-changed")),
291
- );
292
- assert.equal(
293
- getToolcraftPerformanceEscalationRecommendation({
294
- currentReceipt,
295
- previousAnchor,
296
- }),
297
- null,
298
- );
299
- });
300
-
301
- test("recommends but never invokes a full audit after two compatible iterations", () => {
302
- const pair = createCompatiblePair();
303
- assert.deepEqual(
304
- getToolcraftPerformanceEscalationRecommendation(pair),
305
- expectedRecommendation,
306
- );
307
- const message = formatToolcraftPerformanceEscalationRecommendation(
308
- expectedRecommendation,
309
- );
310
- assert.match(message, /offer.*complete performance audit/iu);
311
- assert.match(
312
- message,
313
- new RegExp(
314
- `do not run ${TOOLCRAFT_FULL_PERFORMANCE_VERIFICATION_COMMAND.replace(
315
- /[.*+?^${}()|[\]\\]/gu,
316
- "\\$&",
317
- )} without explicit user consent`,
318
- "iu",
319
- ),
320
- );
321
- assert.equal(
322
- Object.hasOwn(expectedRecommendation, "execute"),
323
- false,
324
- );
325
- });
326
-
327
- test("three compatible iterations produce exactly one durable offer", () => {
328
- const second = createCompatiblePair();
329
- const thirdReceipt = createCompatibleReceipt(
330
- second.currentReceipt,
331
- "3",
332
- "4",
333
- );
334
- const third = {
335
- currentReceipt: thirdReceipt,
336
- previousAnchor: normalizeToolcraftDeliveryAnchor(
337
- second.currentReceipt,
338
- ),
339
- };
340
-
341
- assert.equal(
342
- second.previousAnchor.lifecycle.performanceEscalationOffered,
343
- false,
344
- );
345
- assert.equal(
346
- second.currentReceipt.plan.lifecycle.performanceEscalationOffered,
347
- true,
348
- );
349
- assert.equal(
350
- third.currentReceipt.plan.lifecycle.performanceEscalationOffered,
351
- true,
352
- );
353
- assert.deepEqual(
354
- getToolcraftPerformanceEscalationRecommendation(second),
355
- expectedRecommendation,
356
- );
357
- assert.equal(
358
- getToolcraftPerformanceEscalationRecommendation(third),
359
- null,
360
- );
361
- });
362
-
363
- test("rejects an evidence hash in place of the previous comparison hash", () => {
364
- const { currentReceipt, previousAnchor } = createCompatiblePair();
365
- const evidenceHash = createToolcraftTargetedPerformanceEvidenceHash({
366
- report: previousAnchor.performance.report,
367
- testEvidence: currentReceipt.evidence.at(-1).testEvidence,
368
- });
369
94
  assert.equal(
370
95
  getToolcraftPerformanceEscalationRecommendation({
371
- currentReceipt,
96
+ currentReceipt: firstReceipt,
372
97
  previousAnchor: {
373
- ...previousAnchor,
374
- performance: {
375
- ...previousAnchor.performance,
376
- comparisonHash: evidenceHash,
98
+ lifecycle: {
99
+ consumedPerformanceRequestAuthorityHashes: [],
100
+ performanceEscalationOffered: false,
377
101
  },
102
+ performance: { kind: "none" },
378
103
  },
379
104
  }),
380
105
  null,
381
106
  );
382
107
  });
383
108
 
384
- test("rejects malformed current receipts without interpreting legacy policy", () => {
385
- const { previousAnchor } = createCompatiblePair();
386
- assert.equal(
387
- getToolcraftPerformanceEscalationRecommendation({
388
- currentReceipt: { version: 4 },
389
- previousAnchor,
390
- }),
391
- null,
109
+ test("two compatible targeted iterations offer but never run full audit", () => {
110
+ const { previousAnchor, secondReceipt } = createCompatiblePair();
111
+ const recommendation = getToolcraftPerformanceEscalationRecommendation({
112
+ currentReceipt: secondReceipt,
113
+ previousAnchor,
114
+ });
115
+ assert.deepEqual(recommendation, {
116
+ command: "pnpm verify:perf",
117
+ kind: "offer-full-performance-audit",
118
+ reason: "two-consecutive-compatible-performance-iterations",
119
+ requiresExplicitUserConsent: true,
120
+ });
121
+ assert.match(
122
+ formatToolcraftPerformanceEscalationRecommendation(recommendation),
123
+ /do not run pnpm verify:perf without explicit user consent/iu,
392
124
  );
393
125
  });
@@ -125,7 +125,7 @@ test("rejects a receipt whose file inventory does not produce its source hash",
125
125
  await writeToolcraftCheckpointBundle({
126
126
  bundle: {
127
127
  ...loaded.bundle,
128
- currentPerformance: { ...loaded.bundle.currentPerformance, files: [] },
128
+ performanceBaseline: { ...loaded.bundle.performanceBaseline, files: [] },
129
129
  },
130
130
  rootDir,
131
131
  });
@@ -177,8 +177,8 @@ test("rejects malformed and non-passed receipts", async (t) => {
177
177
  await writeToolcraftCheckpointBundle({
178
178
  bundle: {
179
179
  ...loaded.bundle,
180
- currentPerformance: {
181
- ...loaded.bundle.currentPerformance,
180
+ performanceBaseline: {
181
+ ...loaded.bundle.performanceBaseline,
182
182
  status: "failed",
183
183
  },
184
184
  },
@@ -189,26 +189,24 @@ test("rejects malformed and non-passed receipts", async (t) => {
189
189
  assert.match(failedErrors[0], /passed/iu);
190
190
  });
191
191
 
192
- test("rejects unsupported current and baseline receipt versions", async (t) => {
192
+ test("rejects unsupported full baseline receipt versions", async (t) => {
193
193
  const rootDir = await createReceiptFixture();
194
194
  t.after(() => fs.rm(rootDir, { force: true, recursive: true }));
195
195
 
196
- for (const field of ["currentPerformance", "performanceBaseline"]) {
197
- await writePassedCheckpointFixture(rootDir);
198
- const loaded = await readToolcraftCheckpointBundle(rootDir);
199
- await writeToolcraftCheckpointBundle({
200
- bundle: {
201
- ...loaded.bundle,
202
- [field]: {
203
- ...loaded.bundle[field],
204
- version: 2,
205
- },
196
+ await writePassedCheckpointFixture(rootDir);
197
+ const loaded = await readToolcraftCheckpointBundle(rootDir);
198
+ await writeToolcraftCheckpointBundle({
199
+ bundle: {
200
+ ...loaded.bundle,
201
+ performanceBaseline: {
202
+ ...loaded.bundle.performanceBaseline,
203
+ version: 2,
206
204
  },
207
- rootDir,
208
- });
209
- assert.match(
210
- (await validateToolcraftPerformanceReceipt({ rootDir }))[0],
211
- /unsupported version/iu,
212
- );
213
- }
205
+ },
206
+ rootDir,
207
+ });
208
+ assert.match(
209
+ (await validateToolcraftPerformanceReceipt({ rootDir }))[0],
210
+ /unsupported version/iu,
211
+ );
214
212
  });
@@ -59,7 +59,7 @@ function getImportViolationKind(moduleKind, importedName) {
59
59
  function getViolationMessage(kind, subject, moduleSpecifier) {
60
60
  switch (kind) {
61
61
  case "runtime-export-ownership":
62
- return `Product source must not own artifact encoding, recording, or download mechanics${subject} from ${moduleSpecifier}. Declare exportRenderer and let runtime export actions encode and download the artifact.`;
62
+ return `Product source must not own artifact encoding, recording, or download mechanics${subject} from ${moduleSpecifier}. Declare exportRenderer for image/video or svgExportRenderer for SVG and let runtime export actions create and download the artifact.`;
63
63
  case "runtime-surface":
64
64
  return `Product source must not import or re-export host-owned runtime surface${subject} from ${moduleSpecifier}. Use ToolcraftAppComposition, schema, canvasContent, controlRenderers, onPanelAction, and runtime commands.`;
65
65
  case "runtime-model-presentation-ownership":
@@ -8,6 +8,7 @@ const forbiddenCanvasExportMethods = new Set([
8
8
  "toBlob",
9
9
  "toDataURL",
10
10
  ]);
11
+ const forbiddenGlobalExportFunctions = new Set(["showSaveFilePicker"]);
11
12
 
12
13
  export function getToolcraftProductExportModuleKind(
13
14
  normalizedSpecifier,
@@ -116,12 +117,20 @@ export function createToolcraftProductExportInspector({
116
117
  return {
117
118
  ...getNodeLocation(sourceFile, node),
118
119
  kind: "runtime-export-ownership",
119
- message: `Product source must not own ${subject}. Declare exportRenderer and let runtime export actions encode and download the artifact.`,
120
+ message: `Product source must not own ${subject}. Declare exportRenderer for image/video or svgExportRenderer for SVG and let runtime export actions create and download the artifact.`,
120
121
  repoPath,
121
122
  };
122
123
  }
123
124
 
124
125
  return (node) => {
126
+ if (
127
+ ts.isCallExpression(node) &&
128
+ ts.isIdentifier(node.expression) &&
129
+ forbiddenGlobalExportFunctions.has(node.expression.text) &&
130
+ !isLexicallyDeclared(node.expression)
131
+ ) {
132
+ return [violation(node, `${node.expression.text} artifact delivery`)];
133
+ }
125
134
  if (
126
135
  ts.isNewExpression(node) &&
127
136
  ts.isIdentifier(node.expression) &&
@@ -23,6 +23,7 @@ test("keeps artifact encoding and download mechanics runtime-owned", async (cont
23
23
  canvas.toBlob(() => undefined);
24
24
  canvas.toDataURL();
25
25
  URL.createObjectURL(new Blob());
26
+ showSaveFilePicker();
26
27
  void createAliasBackend;
27
28
  void exportToolcraftImageArtifact;
28
29
  void downloadToolcraftArtifact;
@@ -41,6 +42,7 @@ test("keeps artifact encoding and download mechanics runtime-owned", async (cont
41
42
  import type {
42
43
  ToolcraftExportFrame,
43
44
  ToolcraftProductExportRenderer,
45
+ ToolcraftProductSvgExportRenderer,
44
46
  } from "@/toolcraft/runtime";
45
47
  export const renderFrame = ({ context }) => context.fillRect(0, 0, 1, 1);
46
48
  void Runtime;
@@ -49,6 +51,8 @@ test("keeps artifact encoding and download mechanics runtime-owned", async (cont
49
51
  void validateToolcraftArtifactSize;
50
52
  void (null as unknown as ToolcraftExportFrame);
51
53
  void (null as unknown as ToolcraftProductExportRenderer);
54
+ void (null as unknown as ToolcraftProductSvgExportRenderer);
55
+ void new XMLSerializer();
52
56
  `,
53
57
  "src/features/shadowed-globals.ts": `
54
58
  export function localNames(MediaRecorder, VideoEncoder, URL) {
@@ -61,7 +65,7 @@ test("keeps artifact encoding and download mechanics runtime-owned", async (cont
61
65
 
62
66
  const result = await evaluateToolcraftProductBoundary({ rootDir });
63
67
 
64
- assert.equal(result.violations.length, 10);
68
+ assert.equal(result.violations.length, 11);
65
69
  assert.equal(
66
70
  result.violations.every(
67
71
  (violation) => violation.kind === "runtime-export-ownership",
@@ -20,7 +20,11 @@ async function loadProductObservableFacade(context) {
20
20
  .replaceAll('"@playwright/test"', '"./playwright.mjs"')
21
21
  .replaceAll('"./browser-runtime-evidence"', '"./evidence.mjs"')
22
22
  .replaceAll('"./browser-proof-session"', '"./proof-session.mjs"')
23
- .replaceAll('"./stable-outcome-helpers"', '"./stable-outcome.mjs"');
23
+ .replaceAll('"./stable-outcome-helpers"', '"./stable-outcome.mjs"')
24
+ .replaceAll(
25
+ '"./browser-product-raster-snapshot"',
26
+ '"./raster-snapshot.mjs"',
27
+ );
24
28
  const { outputText } = ts.transpileModule(source, {
25
29
  compilerOptions: {
26
30
  module: ts.ModuleKind.ESNext,
@@ -91,6 +95,47 @@ async function loadProductObservableFacade(context) {
91
95
  }
92
96
  `,
93
97
  ),
98
+ fs.writeFile(
99
+ path.join(outputDir, "raster-snapshot.mjs"),
100
+ `
101
+ const warmedPages = new WeakSet();
102
+ const screenshotOptions = {
103
+ animations: "disabled",
104
+ caret: "hide",
105
+ scale: "css",
106
+ type: "png",
107
+ };
108
+
109
+ export async function resolveToolcraftProductRasterProbe(page, probe) {
110
+ const locator = page.locator(probe.selector);
111
+ const bounds = await locator.boundingBox();
112
+ if (
113
+ !bounds ||
114
+ bounds.width <= 0 ||
115
+ bounds.height <= 0 ||
116
+ bounds.width > 4096 ||
117
+ bounds.height > 4096 ||
118
+ bounds.width * bounds.height > 8_388_608
119
+ ) {
120
+ throw new Error(
121
+ 'Raster probe exceeds the bounded visual proof limit.',
122
+ );
123
+ }
124
+ return {
125
+ bounds,
126
+ locator,
127
+ async capture() {
128
+ if (!warmedPages.has(page)) {
129
+ await locator.screenshot(screenshotOptions);
130
+ warmedPages.add(page);
131
+ }
132
+ const raster = await locator.screenshot(screenshotOptions);
133
+ return JSON.stringify(await page.evaluate(() => undefined, raster));
134
+ },
135
+ };
136
+ }
137
+ `,
138
+ ),
94
139
  ]);
95
140
 
96
141
  return import(`${pathToFileURL(outputPath).href}?test=${Date.now()}`);
@@ -35,7 +35,6 @@ const expectedVerificationReceiptExports = [
35
35
  "assertToolcraftVerificationInputsUnchanged",
36
36
  "collectToolcraftVerificationInputs",
37
37
  "readToolcraftDurablePerformanceBaseline",
38
- "validateToolcraftCurrentPerformanceImpactInventory",
39
38
  "validateToolcraftPerformanceReceipt",
40
39
  "validateToolcraftVerificationReceipt",
41
40
  ];