@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
@@ -0,0 +1,411 @@
1
+ import { expect, test } from "@playwright/test";
2
+ import type {
3
+ FullConfig,
4
+ FullResult,
5
+ Suite,
6
+ } from "@playwright/test/reporter";
7
+ import fs from "node:fs/promises";
8
+ import os from "node:os";
9
+ import path from "node:path";
10
+
11
+ import {
12
+ createMotionReferenceBehavior,
13
+ motionReferenceAcceptance,
14
+ createMotionReferenceInput,
15
+ createTimedMotionReferenceStudy,
16
+ } from "../src/app/starter-acceptance.motion-reference-test-utils";
17
+ import {
18
+ createToolcraftMotionReferenceId,
19
+ createToolcraftMotionReferenceStudyId,
20
+ } from "../scripts/toolcraft-motion-reference-artifacts.mjs";
21
+ import {
22
+ starterAcceptance,
23
+ starterControlSectionInventory,
24
+ starterProductReadiness,
25
+ starterTransferMode,
26
+ type ToolcraftComponentAcceptance,
27
+ type ToolcraftMotionReferenceEvidence,
28
+ type ToolcraftMotionReferenceStudy,
29
+ type ToolcraftTransferMode,
30
+ } from "../src/app/starter-acceptance";
31
+ import { writeCanonicalToolcraftMotionReferenceEvidence } from "../src/app/acceptance/motion-reference-evidence.mjs";
32
+ import { starterSchema } from "../src/app/starter-schema";
33
+ import { deriveToolcraftBrowserRuntimeRequirements } from "./browser-runtime-evidence-requirements";
34
+ import ToolcraftDeliveryCatalogReporter, {
35
+ validateToolcraftDeliveryCatalogReferences,
36
+ } from "./toolcraft-delivery-catalog-reporter";
37
+
38
+ const motionReferenceId =
39
+ "motion-reference-v1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" as const;
40
+
41
+ const invalidReferenceTransferMode: ToolcraftTransferMode = {
42
+ ...starterTransferMode,
43
+ referenceInputs: [
44
+ {
45
+ behaviors: [],
46
+ kind: "motion-reference",
47
+ referenceId: motionReferenceId,
48
+ studies: [],
49
+ },
50
+ ],
51
+ };
52
+
53
+ const validationFixture = {
54
+ acceptance: starterAcceptance,
55
+ productReadiness: starterProductReadiness,
56
+ rootDir: process.cwd(),
57
+ schema: starterSchema,
58
+ sectionInventory: starterControlSectionInventory,
59
+ transferMode: invalidReferenceTransferMode,
60
+ };
61
+
62
+ function createCanonicalMotionReferenceFixture() {
63
+ const authoredStudy = createTimedMotionReferenceStudy();
64
+ if (authoredStudy.evidence.timingMode !== "seconds") {
65
+ throw new Error("Timed motion fixture must use seconds timing.");
66
+ }
67
+ const frameIdByAuthoredId = new Map(
68
+ authoredStudy.evidence.reviewedFrames.map((frame) => [
69
+ frame.frameId,
70
+ `source-frame:${frame.sourceFrameIndex}`,
71
+ ]),
72
+ );
73
+ const reviewedFrames = authoredStudy.evidence.reviewedFrames.map((frame) => ({
74
+ ...frame,
75
+ frameId: frameIdByAuthoredId.get(frame.frameId)!,
76
+ }));
77
+ const detectedEvents = authoredStudy.evidence.detectedEvents.map((event) => {
78
+ const windowFrameIds = event.windowFrameIds.map(
79
+ (frameId) => frameIdByAuthoredId.get(frameId)!,
80
+ );
81
+ return {
82
+ ...event,
83
+ afterFrameId: frameIdByAuthoredId.get(event.afterFrameId)!,
84
+ beforeFrameId: frameIdByAuthoredId.get(event.beforeFrameId)!,
85
+ eventId: `motion-event:${event.kind}:${windowFrameIds
86
+ .map((frameId) => frameId.slice("source-frame:".length))
87
+ .join("-")}`,
88
+ peakFrameId: frameIdByAuthoredId.get(event.peakFrameId)!,
89
+ windowFrameIds,
90
+ };
91
+ });
92
+ const evidenceSeed = {
93
+ ...authoredStudy.evidence,
94
+ detectedEvents,
95
+ overviewFrameIds: authoredStudy.evidence.overviewFrameIds.map(
96
+ (frameId) => frameIdByAuthoredId.get(frameId)!,
97
+ ),
98
+ reviewedFrames,
99
+ };
100
+ const studyId = createToolcraftMotionReferenceStudyId(evidenceSeed);
101
+ const evidence: ToolcraftMotionReferenceEvidence = {
102
+ ...evidenceSeed,
103
+ contactSheet: {
104
+ ...evidenceSeed.contactSheet,
105
+ path: `src/app/reference-studies/${studyId}/contact-sheet.png` as const,
106
+ },
107
+ studyId,
108
+ };
109
+ const study: ToolcraftMotionReferenceStudy = {
110
+ ...authoredStudy,
111
+ evidence,
112
+ evidencePath: `src/app/reference-studies/${studyId}/evidence.json` as const,
113
+ events: authoredStudy.events.map((event, index) => ({
114
+ ...event,
115
+ evidenceEventId: detectedEvents[index].eventId,
116
+ })),
117
+ phases: authoredStudy.phases.map((phase) => ({
118
+ ...phase,
119
+ fromFrameId: frameIdByAuthoredId.get(phase.fromFrameId)!,
120
+ toFrameId: frameIdByAuthoredId.get(phase.toFrameId)!,
121
+ })),
122
+ studyId,
123
+ };
124
+ const referenceId = createToolcraftMotionReferenceId(evidence);
125
+ const behavior = createMotionReferenceBehavior({
126
+ timingClaims: [{ claim: "duration", studyId }],
127
+ });
128
+ const input = createMotionReferenceInput({
129
+ behaviors: [behavior],
130
+ referenceId,
131
+ studies: [study],
132
+ });
133
+ const acceptance = {
134
+ ...motionReferenceAcceptance,
135
+ motionReferenceCoverage: [
136
+ { behaviorId: behavior.id, referenceId },
137
+ ],
138
+ };
139
+ return { acceptance, input, study };
140
+ }
141
+
142
+ function createAcceptance(
143
+ overrides: Partial<ToolcraftComponentAcceptance> = {},
144
+ ): ToolcraftComponentAcceptance {
145
+ return {
146
+ automated: true,
147
+ automatedTestName: "matches the reference retarget behavior",
148
+ browser: true,
149
+ browserTestName: "browser: matches the reference retarget behavior",
150
+ componentType: "custom-renderer",
151
+ evidence: "product-output",
152
+ expectedObservable: "The renderer preserves the delayed retarget behavior.",
153
+ fixture: "motion reference behavior",
154
+ id: "reference.delayed-retarget",
155
+ kind: "runtime",
156
+ target: "renderer.anchor-state",
157
+ userAction: "Compare the running renderer with the inspected reference event.",
158
+ ...overrides,
159
+ };
160
+ }
161
+
162
+ function createReporterFixture(projectRoot: string) {
163
+ const browserRoot = path.join(projectRoot, "e2e");
164
+ const fileSuite = {
165
+ location: { file: path.join(browserRoot, "app-persistence.spec.ts") },
166
+ parent: undefined,
167
+ type: "file",
168
+ };
169
+ const suite = {
170
+ allTests: () => [
171
+ {
172
+ parent: fileSuite,
173
+ title: starterAcceptance[0].browserTestName,
174
+ },
175
+ ],
176
+ } as unknown as Suite;
177
+ const config = {
178
+ configFile: path.join(projectRoot, "playwright.config.ts"),
179
+ rootDir: browserRoot,
180
+ } as FullConfig;
181
+ const result = { status: "passed" } as FullResult;
182
+ return { browserRoot, config, result, suite };
183
+ }
184
+
185
+ test("mapped motion behavior requires output-change and reference-parity evidence", () => {
186
+ const requirements = deriveToolcraftBrowserRuntimeRequirements([
187
+ createAcceptance({
188
+ motionReferenceCoverage: [
189
+ { behaviorId: "delayed-retarget", referenceId: motionReferenceId },
190
+ ],
191
+ }),
192
+ ]);
193
+
194
+ expect(requirements.map(({ evidenceType }) => evidenceType)).toEqual([
195
+ "product-observable-change",
196
+ "reference-parity",
197
+ ]);
198
+ });
199
+
200
+ test("ordinary output change does not acquire motion reference parity", () => {
201
+ const requirements = deriveToolcraftBrowserRuntimeRequirements([
202
+ createAcceptance(),
203
+ ]);
204
+
205
+ expect(requirements.map(({ evidenceType }) => evidenceType)).toEqual([
206
+ "product-observable-change",
207
+ ]);
208
+ });
209
+
210
+ test("delivery catalog validation rejects semantic study errors before catalog work", async () => {
211
+ await expect(
212
+ validateToolcraftDeliveryCatalogReferences(validationFixture, async () => []),
213
+ ).rejects.toThrow(/Toolcraft reference validation failed:[\s\S]*study/iu);
214
+ });
215
+
216
+ test("delivery catalog validation rejects a tampered contact sheet", async () => {
217
+ const rootDir = await fs.mkdtemp(
218
+ path.join(os.tmpdir(), "toolcraft-catalog-tampered-sheet-"),
219
+ );
220
+ const { acceptance, input, study } = createCanonicalMotionReferenceFixture();
221
+ const evidencePath = path.join(rootDir, study.evidencePath);
222
+ const contactSheetPath = path.join(rootDir, study.evidence.contactSheet.path);
223
+ await fs.mkdir(path.dirname(evidencePath), { recursive: true });
224
+ await fs.mkdir(path.join(rootDir, "e2e"));
225
+ await fs.writeFile(
226
+ evidencePath,
227
+ writeCanonicalToolcraftMotionReferenceEvidence(study.evidence),
228
+ );
229
+ await fs.writeFile(contactSheetPath, "tampered-contact-sheet");
230
+
231
+ try {
232
+ await expect(
233
+ validateToolcraftDeliveryCatalogReferences({
234
+ ...validationFixture,
235
+ acceptance: [starterAcceptance[0], acceptance],
236
+ rootDir: path.join(rootDir, "e2e"),
237
+ transferMode: {
238
+ ...starterTransferMode,
239
+ referenceInputs: [input],
240
+ },
241
+ }),
242
+ ).rejects.toThrow(/could not be read/iu);
243
+ await expect(
244
+ validateToolcraftDeliveryCatalogReferences({
245
+ ...validationFixture,
246
+ acceptance: [starterAcceptance[0], acceptance],
247
+ rootDir,
248
+ transferMode: {
249
+ ...starterTransferMode,
250
+ referenceInputs: [input],
251
+ },
252
+ }),
253
+ ).rejects.toThrow(/contact sheet[\s\S]*SHA-256/iu);
254
+ } finally {
255
+ await fs.rm(rootDir, { force: true, recursive: true });
256
+ }
257
+ });
258
+
259
+ test("no-reference reporter lifecycle skips artifact and process-selection work", async () => {
260
+ const projectRoot = path.join(os.tmpdir(), "toolcraft-reporter-no-reference");
261
+ const { config, result, suite } = createReporterFixture(projectRoot);
262
+ let artifactValidationCalls = 0;
263
+ const reporter = new ToolcraftDeliveryCatalogReporter({
264
+ createCatalog: () => ({ acceptance: [], performance: [], version: 2 }),
265
+ validateReferences: (input) =>
266
+ validateToolcraftDeliveryCatalogReferences(input, async () => {
267
+ artifactValidationCalls += 1;
268
+ throw new Error(
269
+ "Artifact or process selection must not run without references.",
270
+ );
271
+ }),
272
+ writeError: (source) => {
273
+ throw new Error(`Unexpected reporter error: ${source}`);
274
+ },
275
+ writeOutput: () => {},
276
+ });
277
+
278
+ reporter.onBegin(config, suite);
279
+ await expect(reporter.onEnd(result)).resolves.toBeUndefined();
280
+ expect(artifactValidationCalls).toBe(0);
281
+ });
282
+
283
+ test("reporter validates the project root at awaited onEnd before publishing JSON", async () => {
284
+ const projectRoot = path.join(os.tmpdir(), "toolcraft-reporter-project");
285
+ const { config, result, suite } = createReporterFixture(projectRoot);
286
+ const output: string[] = [];
287
+ const validatedRoots: string[] = [];
288
+ const lifecycle: string[] = [];
289
+ const reporter = new ToolcraftDeliveryCatalogReporter({
290
+ createCatalog: () => {
291
+ lifecycle.push("catalog");
292
+ return { acceptance: [], performance: [], version: 2 };
293
+ },
294
+ validateReferences: async ({ rootDir }) => {
295
+ lifecycle.push("validation:start");
296
+ await Promise.resolve();
297
+ validatedRoots.push(rootDir);
298
+ lifecycle.push("validation:end");
299
+ },
300
+ writeError: (source) => {
301
+ throw new Error(`Unexpected reporter error: ${source}`);
302
+ },
303
+ writeOutput: (source) => {
304
+ output.push(source);
305
+ },
306
+ });
307
+
308
+ expect(reporter.onBegin(config, suite)).toBeUndefined();
309
+ expect(output).toEqual([]);
310
+ await expect(reporter.onEnd(result)).resolves.toBeUndefined();
311
+ expect(validatedRoots).toEqual([projectRoot]);
312
+ expect(lifecycle).toEqual(["validation:start", "validation:end", "catalog"]);
313
+ expect(output).toHaveLength(1);
314
+ expect(JSON.parse(output[0])).toMatchObject({ version: 2 });
315
+ });
316
+
317
+ test("awaited semantic and artifact failures suppress JSON and fail Playwright", async () => {
318
+ const projectRoot = path.join(os.tmpdir(), "toolcraft-reporter-invalid");
319
+ const { config, result, suite } = createReporterFixture(projectRoot);
320
+ for (const validationError of [
321
+ "semantic motion reference study is incomplete",
322
+ "tampered motion reference contact sheet",
323
+ ]) {
324
+ const errors: string[] = [];
325
+ const output: string[] = [];
326
+ let catalogCalls = 0;
327
+ const reporter = new ToolcraftDeliveryCatalogReporter({
328
+ createCatalog: () => {
329
+ catalogCalls += 1;
330
+ throw new Error("Catalog creation must not run after reference failure.");
331
+ },
332
+ validateReferences: async () => {
333
+ await Promise.resolve();
334
+ throw new Error(validationError);
335
+ },
336
+ writeError: (source) => {
337
+ errors.push(source);
338
+ },
339
+ writeOutput: (source) => {
340
+ output.push(source);
341
+ },
342
+ });
343
+
344
+ expect(reporter.onBegin(config, suite)).toBeUndefined();
345
+ await expect(reporter.onEnd(result)).resolves.toEqual({ status: "failed" });
346
+ expect(catalogCalls).toBe(0);
347
+ expect(output).toEqual([]);
348
+ expect(errors.join("\n")).toContain(validationError);
349
+ }
350
+ });
351
+
352
+ test("atomic preparation failure masks validation and preserves stack plus cause", async () => {
353
+ const projectRoot = path.join(os.tmpdir(), "toolcraft-reporter-preparation");
354
+ const { config, result } = createReporterFixture(projectRoot);
355
+ const cause = new Error("containing suite cause");
356
+ const preparationError = new Error("containing suite failed", { cause });
357
+ preparationError.stack = "PREPARATION_STACK_MARKER";
358
+ cause.stack = "PREPARATION_CAUSE_MARKER";
359
+ const errors: string[] = [];
360
+ let catalogCalls = 0;
361
+ let validationCalls = 0;
362
+ const reporter = new ToolcraftDeliveryCatalogReporter({
363
+ createCatalog: () => {
364
+ catalogCalls += 1;
365
+ return { acceptance: [], performance: [], version: 2 };
366
+ },
367
+ validateReferences: async () => {
368
+ validationCalls += 1;
369
+ throw new Error("reference validation must remain hidden");
370
+ },
371
+ writeError: (source) => {
372
+ errors.push(source);
373
+ },
374
+ writeOutput: () => {
375
+ throw new Error("Preparation failure must suppress output.");
376
+ },
377
+ });
378
+ const failingSuite = {
379
+ allTests: () => {
380
+ throw preparationError;
381
+ },
382
+ } as unknown as Suite;
383
+
384
+ reporter.onBegin(config, failingSuite);
385
+ await expect(reporter.onEnd(result)).resolves.toEqual({ status: "failed" });
386
+ expect(validationCalls).toBe(0);
387
+ expect(catalogCalls).toBe(0);
388
+ expect(errors.join("\n")).toContain("PREPARATION_STACK_MARKER");
389
+ expect(errors.join("\n")).toContain("PREPARATION_CAUSE_MARKER");
390
+ expect(errors.join("\n")).not.toContain("reference validation must remain hidden");
391
+ });
392
+
393
+ test("idle reporter state fails with an explicit lifecycle error", async () => {
394
+ const errors: string[] = [];
395
+ let validationCalls = 0;
396
+ const reporter = new ToolcraftDeliveryCatalogReporter({
397
+ validateReferences: async () => {
398
+ validationCalls += 1;
399
+ },
400
+ writeError: (source) => {
401
+ errors.push(source);
402
+ },
403
+ writeOutput: () => {},
404
+ });
405
+
406
+ await expect(
407
+ reporter.onEnd({ status: "passed" } as FullResult),
408
+ ).resolves.toEqual({ status: "failed" });
409
+ expect(validationCalls).toBe(0);
410
+ expect(errors.join("\n")).toMatch(/complete onBegin lifecycle/iu);
411
+ });
@@ -2,6 +2,7 @@ import { expect, test } from "@playwright/test";
2
2
 
3
3
  import {
4
4
  createToolcraftBrowserProofSession,
5
+ getToolcraftBrowserActionSurface,
5
6
  getToolcraftBrowserActionTarget,
6
7
  runToolcraftBrowserAction,
7
8
  runToolcraftBrowserValueAction,
@@ -133,6 +134,7 @@ test("target-scoped actions resolve the exact field inside a grouped control", a
133
134
  });
134
135
 
135
136
  expect(getToolcraftBrowserActionTarget(action)).toBe("appearance.stroke");
137
+ expect(getToolcraftBrowserActionSurface(action)).toBe("panel");
136
138
  await runToolcraftBrowserAction(action);
137
139
  await expect(
138
140
  page.locator('button[data-target="appearance.stroke"]'),
@@ -170,6 +172,89 @@ test("target-scoped actions resolve the exact field inside a grouped control", a
170
172
  );
171
173
  });
172
174
 
175
+ test("surface actions verify Canvas and Panel locator provenance", async ({
176
+ page,
177
+ }) => {
178
+ await page.goto("/");
179
+ const session = await createToolcraftBrowserProofSession(page);
180
+ await page.locator(TOOLCRAFT_APP_ROOT_SELECTOR).evaluate((root) => {
181
+ const canvas = root.querySelector('[data-slot="toolcraft-runtime-canvas"]');
182
+ const panel = root.querySelector("[data-toolcraft-controls-panel-shell]");
183
+ if (!canvas || !panel) {
184
+ throw new Error("Missing runtime surfaces for proof-session fixture.");
185
+ }
186
+ for (const [owner, id] of [
187
+ [canvas, "surface-canvas"],
188
+ [panel, "surface-panel"],
189
+ ] as const) {
190
+ const button = document.createElement("button");
191
+ button.id = id;
192
+ button.type = "button";
193
+ button.textContent = id;
194
+ if (id === "surface-canvas") {
195
+ Object.assign(button.style, {
196
+ left: "16px",
197
+ position: "absolute",
198
+ top: "16px",
199
+ zIndex: "50",
200
+ });
201
+ }
202
+ button.addEventListener("click", () => {
203
+ button.dataset.clicked = "true";
204
+ });
205
+ button.addEventListener("pointerdown", (event) => {
206
+ event.stopPropagation();
207
+ });
208
+ owner.append(button);
209
+ }
210
+ });
211
+
212
+ const canvasAction = session.surfaceAction("selection.active", {
213
+ selector: "#surface-canvas",
214
+ surface: "canvas",
215
+ });
216
+ const panelAction = session.surfaceAction("selection.active", {
217
+ selector: "#surface-panel",
218
+ surface: "panel",
219
+ });
220
+ expect(getToolcraftBrowserActionSurface(canvasAction)).toBe("canvas");
221
+ expect(getToolcraftBrowserActionSurface(panelAction)).toBe("panel");
222
+ await runToolcraftBrowserAction(canvasAction);
223
+ await runToolcraftBrowserAction(panelAction);
224
+ await expect(page.locator("#surface-canvas")).toHaveAttribute(
225
+ "data-clicked",
226
+ "true",
227
+ );
228
+ await expect(page.locator("#surface-panel")).toHaveAttribute(
229
+ "data-clicked",
230
+ "true",
231
+ );
232
+
233
+ await expect(
234
+ runToolcraftBrowserAction(
235
+ session.surfaceAction("selection.active", {
236
+ selector: "#surface-panel",
237
+ surface: "canvas",
238
+ }),
239
+ ),
240
+ ).rejects.toThrow(/declared canvas runtime surface/u);
241
+ await expect(
242
+ runToolcraftBrowserAction(
243
+ session.surfaceAction("selection.active", {
244
+ selector: "#missing-surface",
245
+ surface: "canvas",
246
+ }),
247
+ ),
248
+ ).rejects.toThrow(/resolve exactly once/u);
249
+ expect(() =>
250
+ session.surfaceAction("selection.active", {
251
+ position: { x: -1, y: 0 },
252
+ selector: "#surface-canvas",
253
+ surface: "canvas",
254
+ }),
255
+ ).toThrow(/finite nonnegative coordinates/u);
256
+ });
257
+
173
258
  test("proof sessions reject pages without the Toolcraft app identity", async ({ page }) => {
174
259
  await page.setContent('<main data-slot="toolcraft-runtime-app"></main>');
175
260
 
@@ -198,6 +198,56 @@ test("typed background coverage derives dedicated semantic evidence", () => {
198
198
  );
199
199
  });
200
200
 
201
+ test("typed SVG coverage derives only protected SVG artifact evidence", () => {
202
+ const requirements = deriveToolcraftBrowserRuntimeRequirements([
203
+ {
204
+ browser: true,
205
+ browserTestName: "browser: SVG export",
206
+ evidence: "exported-bytes",
207
+ exportArtifactCoverage: "all-required-svg-export-behavior",
208
+ id: "actions.svg",
209
+ target: "actions.output",
210
+ },
211
+ ]);
212
+
213
+ expect(requirements).toEqual([
214
+ {
215
+ evidenceType: "svg-export-artifact",
216
+ requirementId: "actions.svg",
217
+ target: "actions.output",
218
+ testName: "browser: SVG export",
219
+ },
220
+ ]);
221
+ });
222
+
223
+ test("selected-entity coverage adds protected selection isolation evidence", () => {
224
+ const requirements = deriveToolcraftBrowserRuntimeRequirements([
225
+ {
226
+ browser: true,
227
+ browserTestName: "browser: selected shape fill",
228
+ evidence: "product-output",
229
+ id: "shape.selected-fill",
230
+ selectionScopeCoverage: "two-entity-isolation",
231
+ target: "selectedShape.fill",
232
+ },
233
+ ]);
234
+
235
+ expect(requirements).toEqual([
236
+ {
237
+ evidenceType: "product-observable-change",
238
+ requirementId: "shape.selected-fill",
239
+ target: "selectedShape.fill",
240
+ testName: "browser: selected shape fill",
241
+ },
242
+ {
243
+ evidenceType: "selection-scoped-control",
244
+ requirementId: "shape.selected-fill",
245
+ target: "selectedShape.fill",
246
+ testName: "browser: selected shape fill",
247
+ },
248
+ ]);
249
+ });
250
+
201
251
  test("typed Infinity canvas coverage derives dedicated semantic evidence", () => {
202
252
  const requirements = deriveToolcraftBrowserRuntimeRequirements([
203
253
  {
@@ -216,6 +266,14 @@ test("typed Infinity canvas coverage derives dedicated semantic evidence", () =>
216
266
  infinityCanvasCoverage: "scene-bounds-image-export",
217
267
  target: "actions.output",
218
268
  },
269
+ {
270
+ browser: true,
271
+ browserTestName: "browser: Infinity canvas SVG export",
272
+ evidence: "exported-bytes",
273
+ id: "canvas.infinity.svgExport",
274
+ infinityCanvasCoverage: "scene-bounds-svg-export",
275
+ target: "actions.output",
276
+ },
219
277
  ]);
220
278
 
221
279
  expect(
@@ -233,6 +291,10 @@ test("typed Infinity canvas coverage derives dedicated semantic evidence", () =>
233
291
  evidenceType: "infinity-scene-bounds-image-export",
234
292
  requirementId: "canvas.infinity.imageExport",
235
293
  },
294
+ {
295
+ evidenceType: "infinity-scene-bounds-svg-export",
296
+ requirementId: "canvas.infinity.svgExport",
297
+ },
236
298
  ]),
237
299
  );
238
300
  });