@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
@@ -4,7 +4,9 @@ import { describe, expect, it } from "vitest";
4
4
  import { getToolcraftExportArtifactCoverageErrors } from "./acceptance/export-artifact-coverage";
5
5
  import type { ToolcraftComponentAcceptance } from "./acceptance/types";
6
6
 
7
- function createSchema(roles: readonly ("export-image" | "export-video")[]) {
7
+ function createSchema(
8
+ roles: readonly ("export-image" | "export-svg" | "export-video")[],
9
+ ) {
8
10
  return defineToolcraft({
9
11
  canvas: { enabled: true },
10
12
  panels: {
@@ -14,9 +16,19 @@ function createSchema(roles: readonly ("export-image" | "export-video")[]) {
14
16
  controls: {
15
17
  output: {
16
18
  actions: roles.map((role) => ({
17
- label: role === "export-image" ? "Export Image" : "Export Video",
19
+ label:
20
+ role === "export-image"
21
+ ? "Export Image"
22
+ : role === "export-svg"
23
+ ? "Export SVG"
24
+ : "Export Video",
18
25
  role,
19
- value: role === "export-image" ? "export.image" : "export.video",
26
+ value:
27
+ role === "export-image"
28
+ ? "export.image"
29
+ : role === "export-svg"
30
+ ? "export.svg"
31
+ : "export.video",
20
32
  })),
21
33
  target: "actions.output",
22
34
  type: "panelActions",
@@ -92,6 +104,65 @@ describe("Toolcraft export artifact acceptance", () => {
92
104
  ]);
93
105
  });
94
106
 
107
+ it("requires exact SVG exported-bytes coverage for a typed SVG action", () => {
108
+ const schema = createSchema(["export-svg"]);
109
+
110
+ expect(
111
+ getToolcraftExportArtifactCoverageErrors({
112
+ acceptance: [
113
+ createAcceptance({
114
+ actionCoverage: ["export.svg"],
115
+ exportArtifactCoverage: "all-required-svg-export-behavior",
116
+ }),
117
+ ],
118
+ schema,
119
+ }),
120
+ ).toEqual([]);
121
+ expect(
122
+ getToolcraftExportArtifactCoverageErrors({
123
+ acceptance: [
124
+ createAcceptance({
125
+ actionCoverage: ["export.svg"],
126
+ exportArtifactCoverage: "all-required-image-export-behavior",
127
+ }),
128
+ ],
129
+ schema,
130
+ }),
131
+ ).toEqual([
132
+ expect.stringContaining("without a matching typed export action"),
133
+ expect.stringContaining("all-required-svg-export-behavior"),
134
+ ]);
135
+ });
136
+
137
+ it("rejects typed export roles outside sticky panelActions", () => {
138
+ const schema = defineToolcraft({
139
+ canvas: { enabled: true },
140
+ panels: {
141
+ controls: {
142
+ sections: [
143
+ {
144
+ controls: {
145
+ local: {
146
+ actions: [{ role: "export-svg", value: "export.svg" }],
147
+ target: "local.actions",
148
+ type: "actions",
149
+ },
150
+ },
151
+ id: "local",
152
+ },
153
+ ],
154
+ title: "Controls",
155
+ },
156
+ },
157
+ });
158
+
159
+ expect(
160
+ getToolcraftExportArtifactCoverageErrors({ acceptance: [], schema }),
161
+ ).toContain(
162
+ 'Typed export-svg action "export.svg" must be declared in sticky panelActions.',
163
+ );
164
+ });
165
+
95
166
  it("requires exported bytes plus automated browser proof", () => {
96
167
  const errors = getToolcraftExportArtifactCoverageErrors({
97
168
  acceptance: [
@@ -11,7 +11,7 @@ export function makeExportSettingsProductReadiness(
11
11
  interactionOwnership: [],
12
12
  mode: "product",
13
13
  productName: "Export settings fixture",
14
- productSummary: "A synthetic product for image and video export settings.",
14
+ productSummary: "A synthetic product for image, SVG, and video export settings.",
15
15
  requestedBehavior: "Export the explicitly requested artifact types.",
16
16
  viewInteraction: {
17
17
  mode: "non-spatial",
@@ -127,3 +127,7 @@ export function textLooksLikePngExport(text: string): boolean {
127
127
  export function textLooksLikeVideoExport(text: string): boolean {
128
128
  return /\b(export|download)\b/i.test(text) && /\b(video|mp4|webm|mov)\b/i.test(text);
129
129
  }
130
+
131
+ export function textLooksLikeSvgExport(text: string): boolean {
132
+ return /\b(export|download)\b/i.test(text) && /\bsvg\b|\bvector\b/i.test(text);
133
+ }
@@ -11,11 +11,13 @@ import { makeControlAcceptance } from "./starter-acceptance.test-utils";
11
11
 
12
12
  const imageOnlyProductReadiness = makeExportSettingsProductReadiness({
13
13
  image: { mode: "toolcraft-default" },
14
+ svg: { mode: "not-requested" },
14
15
  video: { mode: "not-requested" },
15
16
  });
16
17
 
17
18
  const imageAndVideoProductReadiness = makeExportSettingsProductReadiness({
18
19
  image: { mode: "toolcraft-default" },
20
+ svg: { mode: "not-requested" },
19
21
  video: {
20
22
  evidence: "The user explicitly requested video delivery.",
21
23
  mode: "user-requested",
@@ -70,15 +70,15 @@ function ownership({
70
70
  source?: ToolcraftInteractionOwnershipEntry["evidence"]["source"];
71
71
  surface: ToolcraftInteractionSurface;
72
72
  }): ToolcraftInteractionOwnershipEntry {
73
- return {
73
+ const base = {
74
74
  alternative: {
75
75
  reason:
76
76
  surface === "canvas"
77
77
  ? "A panel copy would separate the same operation from visible output without adding a useful capability."
78
78
  : "A canvas copy would add output chrome without improving this non-spatial operation.",
79
- surface: surface === "canvas" ? "panel" : "canvas",
79
+ surface: (surface === "canvas" ? "panel" : "canvas") as
80
+ ToolcraftInteractionSurface,
80
81
  },
81
- capability,
82
82
  evidence: {
83
83
  detail:
84
84
  source === "reference"
@@ -94,6 +94,19 @@ function ownership({
94
94
  surface,
95
95
  target: "output.position",
96
96
  };
97
+
98
+ if (
99
+ capability === "precise-value-entry" ||
100
+ capability === "property-edit"
101
+ ) {
102
+ return {
103
+ ...base,
104
+ capability,
105
+ selectionScope: { mode: "global" },
106
+ };
107
+ }
108
+
109
+ return { ...base, capability };
97
110
  }
98
111
 
99
112
  function readiness(
@@ -102,6 +115,7 @@ function readiness(
102
115
  return {
103
116
  exportIntent: {
104
117
  image: { mode: "toolcraft-default" },
118
+ svg: { mode: "not-requested" },
105
119
  video: { mode: "not-requested" },
106
120
  },
107
121
  interactionOwnership,
@@ -157,6 +171,7 @@ describe("Toolcraft interaction surface ownership", () => {
157
171
  const productReadiness = {
158
172
  exportIntent: {
159
173
  image: { mode: "toolcraft-default" },
174
+ svg: { mode: "not-requested" },
160
175
  video: { mode: "not-requested" },
161
176
  },
162
177
  mode: "product",
@@ -182,6 +197,7 @@ describe("Toolcraft interaction surface ownership", () => {
182
197
  const productReadiness = {
183
198
  exportIntent: {
184
199
  image: { mode: "toolcraft-default" },
200
+ svg: { mode: "not-requested" },
185
201
  video: { mode: "not-requested" },
186
202
  },
187
203
  mode: "product",
@@ -196,7 +196,8 @@ describe("starter acceptance layers contract", () => {
196
196
  }),
197
197
  ).toEqual(
198
198
  expect.arrayContaining([
199
- 'Layer / opacity (selectedLayer.opacity) targets selectedLayer.* and must have acceptance layerCoverage "selected-layer-controls" proving the control edits the currently selected layer output.',
199
+ 'selectedLayer.opacity must declare selectionScopeCoverage "two-entity-isolation" proving edits stay on the selected entity.',
200
+ 'selectedLayer.opacity targets selectedLayer.* and must declare layerCoverage "selected-layer-controls" together with two-entity isolation.',
200
201
  ]),
201
202
  );
202
203
  });
@@ -17,6 +17,7 @@ import {
17
17
  const layeredMediaProductReadiness: ToolcraftProductReadiness = {
18
18
  exportIntent: {
19
19
  image: { mode: "toolcraft-default" },
20
+ svg: { mode: "not-requested" },
20
21
  video: { mode: "not-requested" },
21
22
  },
22
23
  interactionOwnership: [
@@ -38,6 +39,28 @@ const layeredMediaProductReadiness: ToolcraftProductReadiness = {
38
39
  surface: "panel",
39
40
  target: "media.sources",
40
41
  },
42
+ {
43
+ alternative: {
44
+ reason:
45
+ "Canvas transform buttons would duplicate precise actions already owned by Layers.",
46
+ surface: "canvas",
47
+ },
48
+ capability: "property-edit",
49
+ evidence: {
50
+ detail:
51
+ "The product requires transforms to apply only to the layer selected in Layers.",
52
+ source: "user-request",
53
+ },
54
+ id: "layers-selected-transform",
55
+ reason:
56
+ "The Layers property action remains bound to the explicitly selected image.",
57
+ selectionScope: {
58
+ mode: "selected-entity",
59
+ selectionInteractionId: "layers-media-management",
60
+ },
61
+ surface: "panel",
62
+ target: "selectedLayer.transform",
63
+ },
41
64
  ],
42
65
  mode: "product",
43
66
  productName: "Layered media fixture",
@@ -84,6 +107,10 @@ function createLayerAcceptance({
84
107
  kind: "runtime",
85
108
  layerCoverage,
86
109
  mediaLifecycleCoverage,
110
+ selectionScopeCoverage:
111
+ layerCoverage === "selected-layer-controls"
112
+ ? "two-entity-isolation"
113
+ : undefined,
87
114
  target,
88
115
  userAction: `Exercise ${id} through the runtime Layers panel.`,
89
116
  };
@@ -131,6 +158,7 @@ function createLayeredMediaAcceptance({
131
158
  ? [
132
159
  createLayerAcceptance({
133
160
  id: "layers.selected-transform",
161
+ interactionId: "layers-selected-transform",
134
162
  layerCoverage: "selected-layer-controls",
135
163
  mediaLifecycleCoverage: [
136
164
  "rotate",
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import {
4
+ defineToolcraftMotionReferenceEvidence,
5
+ } from "./acceptance/motion-reference-evidence.mjs";
6
+ import type { ToolcraftMotionReferenceEvidence } from "./acceptance/reference-study-types";
7
+
8
+ describe("Toolcraft motion reference evidence decoder", () => {
9
+ it("exposes an exact checked TypeScript boundary without a cast", () => {
10
+ const defineEvidence: (
11
+ value: unknown,
12
+ ) => ToolcraftMotionReferenceEvidence =
13
+ defineToolcraftMotionReferenceEvidence;
14
+
15
+ expect(() => defineEvidence({})).toThrow(/motion reference evidence/iu);
16
+ });
17
+ });
@@ -0,0 +1,163 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import {
4
+ alternateMotionReferenceId,
5
+ alternateMotionSourceSha256,
6
+ createMotionReferenceBehavior,
7
+ createMotionReferenceInput,
8
+ createOrdinalMotionReferenceStudy,
9
+ createPassiveMotionReferenceInput,
10
+ createTimedMotionReferenceStudy,
11
+ getMotionReferenceErrors,
12
+ motionReferenceId,
13
+ motionSourceSha256,
14
+ } from "./starter-acceptance.motion-reference-test-utils";
15
+
16
+ describe("Toolcraft motion reference identity", () => {
17
+ it("rejects duplicate semantic ids", () => {
18
+ const input = createMotionReferenceInput();
19
+ const study = input.studies[0];
20
+
21
+ expect(
22
+ getMotionReferenceErrors([
23
+ {
24
+ ...input,
25
+ studies: [
26
+ {
27
+ ...study,
28
+ phases: [
29
+ study.phases[0],
30
+ { ...study.phases[1], id: study.phases[0].id },
31
+ ],
32
+ },
33
+ ],
34
+ },
35
+ ]),
36
+ ).toContain(
37
+ 'motion reference study "study-main" phase id "phase-before" is duplicated.',
38
+ );
39
+ });
40
+
41
+ it("rejects duplicate reference ids even when source identities differ", () => {
42
+ expect(
43
+ getMotionReferenceErrors([
44
+ createMotionReferenceInput(),
45
+ createPassiveMotionReferenceInput({
46
+ referenceId: motionReferenceId,
47
+ sourceSha256: alternateMotionSourceSha256,
48
+ }),
49
+ ]),
50
+ ).toContain(`motion reference id "${motionReferenceId}" is duplicated.`);
51
+ });
52
+
53
+ it("reports mixed source identities canonically for every study permutation", () => {
54
+ const primary = createTimedMotionReferenceStudy();
55
+ const alternate = createTimedMotionReferenceStudy({
56
+ framePrefix: "alternate-",
57
+ pathId: "study-alternate",
58
+ sourceBasename: "alternate.mp4",
59
+ sourceSha256: alternateMotionSourceSha256,
60
+ studyId: "study-alternate",
61
+ });
62
+ const forward = getMotionReferenceErrors([
63
+ createMotionReferenceInput({ studies: [primary, alternate] }),
64
+ ]);
65
+ const reverse = getMotionReferenceErrors([
66
+ createMotionReferenceInput({ studies: [alternate, primary] }),
67
+ ]);
68
+
69
+ expect(forward).toEqual(reverse);
70
+ expect(forward).toContain(
71
+ `motion reference "${motionReferenceId}" studies must share one sourceSha256; found ${motionSourceSha256}, ${alternateMotionSourceSha256}.`,
72
+ );
73
+ });
74
+
75
+ it("rejects duplicate inputs for one source identity", () => {
76
+ expect(
77
+ getMotionReferenceErrors([
78
+ createMotionReferenceInput(),
79
+ createPassiveMotionReferenceInput({
80
+ referenceId: alternateMotionReferenceId,
81
+ }),
82
+ ]),
83
+ ).toContain(
84
+ `motion reference sourceSha256 "${motionSourceSha256}" is declared by multiple reference inputs; merge their studies under one input.`,
85
+ );
86
+ });
87
+
88
+ it("keeps duplicate study ids ambiguous in every input permutation", () => {
89
+ const timed = createTimedMotionReferenceStudy({ pathId: "timed-study" });
90
+ const ordinal = createOrdinalMotionReferenceStudy({
91
+ framePrefix: "ordinal-",
92
+ pathId: "ordinal-study",
93
+ });
94
+ const errors = [
95
+ getMotionReferenceErrors([
96
+ createMotionReferenceInput({ studies: [timed, ordinal] }),
97
+ ]),
98
+ getMotionReferenceErrors([
99
+ createMotionReferenceInput({ studies: [ordinal, timed] }),
100
+ ]),
101
+ ];
102
+
103
+ expect(errors[0]).toEqual(errors[1]);
104
+ expect(errors[0]).toContain(
105
+ 'motion reference behavior "delayed-retarget" timing claim "duration" studyId "study-main" resolves to 2 studies; expected exactly one.',
106
+ );
107
+ });
108
+
109
+ it("validates every duplicate behavior while relational uses remain ambiguous", () => {
110
+ const valid = createMotionReferenceBehavior();
111
+ const malformed = createMotionReferenceBehavior({ description: "" });
112
+ const errors = [
113
+ getMotionReferenceErrors([
114
+ createMotionReferenceInput({ behaviors: [valid, malformed] }),
115
+ ]),
116
+ getMotionReferenceErrors([
117
+ createMotionReferenceInput({ behaviors: [malformed, valid] }),
118
+ ]),
119
+ ];
120
+
121
+ expect(errors[0]).toEqual(errors[1]);
122
+ expect(errors[0]).toContain(
123
+ `motion reference "${motionReferenceId}" behavior id "delayed-retarget" is duplicated.`,
124
+ );
125
+ expect(errors[0]).toContain(
126
+ 'motion reference behavior "delayed-retarget" must include a non-empty description.',
127
+ );
128
+ expect(errors[0]).toContain(
129
+ 'motion reference study "study-main" phase "phase-before" cites ambiguous behaviorId "delayed-retarget" with 2 definitions.',
130
+ );
131
+ expect(errors[0]).toContain(
132
+ `acceptance "reference.anchor-retarget" motion reference coverage for "${motionReferenceId}" behavior "delayed-retarget" resolves to 2 behavior definitions; expected exactly one.`,
133
+ );
134
+ });
135
+
136
+ it("keeps control characters in timing study ids collision-proof", () => {
137
+ const controlStudyId = "study\u0000left";
138
+ const studies = [
139
+ createTimedMotionReferenceStudy({
140
+ framePrefix: "control-",
141
+ pathId: "control-study",
142
+ studyId: controlStudyId,
143
+ }),
144
+ createTimedMotionReferenceStudy({
145
+ framePrefix: "plain-",
146
+ pathId: "plain-study",
147
+ studyId: "study-right",
148
+ }),
149
+ ];
150
+ const behavior = createMotionReferenceBehavior({
151
+ timingClaims: [
152
+ { claim: "duration", studyId: controlStudyId },
153
+ { claim: "duration", studyId: "study-right" },
154
+ ],
155
+ });
156
+
157
+ expect(
158
+ getMotionReferenceErrors([
159
+ createMotionReferenceInput({ behaviors: [behavior], studies }),
160
+ ]),
161
+ ).toEqual([]);
162
+ });
163
+ });
@@ -0,0 +1,133 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import {
4
+ createMotionReferenceInput,
5
+ createOrdinalMotionReferenceStudy,
6
+ getMotionReferenceErrors,
7
+ } from "./starter-acceptance.motion-reference-test-utils";
8
+
9
+ describe("Toolcraft motion reference semantic coverage", () => {
10
+ it("accepts one normalized input with exact behavior and acceptance ownership", () => {
11
+ expect(getMotionReferenceErrors([createMotionReferenceInput()])).toEqual([]);
12
+ });
13
+
14
+ it("rejects phase gaps and overlaps across the ordered overview", () => {
15
+ const input = createMotionReferenceInput();
16
+ const study = input.studies[0];
17
+ const [firstPhase, secondPhase] = study.phases;
18
+
19
+ expect(
20
+ getMotionReferenceErrors([
21
+ {
22
+ ...input,
23
+ studies: [
24
+ {
25
+ ...study,
26
+ phases: [{ ...firstPhase, toFrameId: "f0" }, secondPhase],
27
+ },
28
+ ],
29
+ },
30
+ ]),
31
+ ).toContain(
32
+ 'motion reference study "study-main" phases must be contiguous; "phase-after" starts at overview index 2 after index 0.',
33
+ );
34
+
35
+ expect(
36
+ getMotionReferenceErrors([
37
+ {
38
+ ...input,
39
+ studies: [
40
+ {
41
+ ...study,
42
+ phases: [{ ...firstPhase, toFrameId: "f2" }, secondPhase],
43
+ },
44
+ ],
45
+ },
46
+ ]),
47
+ ).toContain(
48
+ 'motion reference study "study-main" phases must be contiguous; "phase-after" starts at overview index 2 after index 2.',
49
+ );
50
+ });
51
+
52
+ it("rejects machine events without exactly one authored classification", () => {
53
+ const input = createMotionReferenceInput();
54
+ const study = input.studies[0];
55
+
56
+ expect(
57
+ getMotionReferenceErrors([
58
+ { ...input, studies: [{ ...study, events: [] }] },
59
+ ]),
60
+ ).toContain(
61
+ 'motion reference study "study-main" evidence event "machine-retarget" must have exactly one authored event; found 0.',
62
+ );
63
+ });
64
+
65
+ it("requires a non-empty reason for every nonproduct event", () => {
66
+ const input = structuredClone(createMotionReferenceInput());
67
+ Object.defineProperties(input.studies[0].events[0], {
68
+ behaviorIds: { configurable: true, value: [] },
69
+ classification: { configurable: true, value: "irrelevant-change" },
70
+ reason: { configurable: true, value: " " },
71
+ });
72
+
73
+ expect(getMotionReferenceErrors([input])).toContain(
74
+ 'motion reference study "study-main" event "event-retarget" classification "irrelevant-change" requires a non-empty reason.',
75
+ );
76
+ });
77
+
78
+ it("requires every nonproduct event to have zero behavior ids", () => {
79
+ const input = structuredClone(createMotionReferenceInput());
80
+ Object.defineProperties(input.studies[0].events[0], {
81
+ behaviorIds: { configurable: true, value: ["delayed-retarget"] },
82
+ classification: { configurable: true, value: "irrelevant-change" },
83
+ reason: {
84
+ configurable: true,
85
+ value: "The event is outside product scope.",
86
+ },
87
+ });
88
+
89
+ expect(getMotionReferenceErrors([input])).toContain(
90
+ 'motion reference study "study-main" event "event-retarget" classification "irrelevant-change" must not cite behaviorIds.',
91
+ );
92
+ });
93
+
94
+ it("rejects product events that cite unknown behavior ids", () => {
95
+ const input = createMotionReferenceInput();
96
+ const study = input.studies[0];
97
+
98
+ expect(
99
+ getMotionReferenceErrors([
100
+ {
101
+ ...input,
102
+ studies: [
103
+ {
104
+ ...study,
105
+ events: [
106
+ {
107
+ behaviorIds: ["unknown-behavior"],
108
+ classification: "product-behavior",
109
+ evidenceEventId: "machine-retarget",
110
+ id: "event-retarget",
111
+ },
112
+ ],
113
+ },
114
+ ],
115
+ },
116
+ ]),
117
+ ).toContain(
118
+ 'motion reference study "study-main" event "event-retarget" cites unknown behaviorId "unknown-behavior".',
119
+ );
120
+ });
121
+
122
+ it("rejects timing claims owned by ordinal evidence", () => {
123
+ expect(
124
+ getMotionReferenceErrors([
125
+ createMotionReferenceInput({
126
+ studies: [createOrdinalMotionReferenceStudy()],
127
+ }),
128
+ ]),
129
+ ).toContain(
130
+ 'motion reference behavior "delayed-retarget" timing claim "duration" must name a seconds-timed study; "study-main" is ordinal.',
131
+ );
132
+ });
133
+ });