@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,37 @@
1
+ import type {
2
+ ToolcraftMotionReferenceEvidence,
3
+ ToolcraftReferenceInput,
4
+ } from "../src/app/acceptance/reference-study-types";
5
+
6
+ export type ToolcraftMotionReferenceStudyId = `motion-v1-${string}`;
7
+ export type ToolcraftMotionReferenceId = `motion-reference-v1-${string}`;
8
+ export type ToolcraftMotionReferenceGroupId = `motion-group-v1-${string}`;
9
+ export type ToolcraftMotionReferenceScope = Readonly<
10
+ | { endFrameExclusive: number; startFrameIndex: number }
11
+ | { endSeconds: number; startSeconds: number }
12
+ >;
13
+
14
+ export function createToolcraftSha256(bytes: Uint8Array): string;
15
+ export function createToolcraftMotionReferenceIdentitySha256(
16
+ value: unknown,
17
+ ): string;
18
+ export function createToolcraftMotionReferencePlanSha256(
19
+ evidences: readonly ToolcraftMotionReferenceEvidence[],
20
+ ): string;
21
+ export function createToolcraftMotionReferenceStudyId(
22
+ evidence: ToolcraftMotionReferenceEvidence,
23
+ ): ToolcraftMotionReferenceStudyId;
24
+ export function createToolcraftMotionReferenceId(
25
+ evidence: ToolcraftMotionReferenceEvidence,
26
+ ): ToolcraftMotionReferenceId;
27
+ export function createToolcraftMotionReferenceGroupId(
28
+ evidence: ToolcraftMotionReferenceEvidence,
29
+ scope: ToolcraftMotionReferenceScope,
30
+ ): ToolcraftMotionReferenceGroupId;
31
+ export function getToolcraftMotionReferenceEvidenceGroupErrors(
32
+ evidences: readonly ToolcraftMotionReferenceEvidence[],
33
+ ): string[];
34
+ export function getToolcraftMotionReferenceArtifactErrors(options: {
35
+ referenceInputs: readonly ToolcraftReferenceInput[];
36
+ rootDir: string;
37
+ }): Promise<string[]>;
@@ -0,0 +1,308 @@
1
+ import { createHash } from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+
4
+ import {
5
+ getToolcraftMotionReferenceEvidenceErrors,
6
+ writeCanonicalToolcraftMotionReferenceEvidence,
7
+ } from "../src/app/acceptance/motion-reference-evidence.mjs";
8
+ import { resolveToolcraftRootResourcePath } from "./toolcraft-source-inventory.mjs";
9
+
10
+ const encoder = new TextEncoder();
11
+
12
+ export function createToolcraftSha256(bytes) {
13
+ return createHash("sha256").update(bytes).digest("hex");
14
+ }
15
+ function sortJson(value) {
16
+ if (Array.isArray(value)) return value.map(sortJson);
17
+ if (value !== null && typeof value === "object") {
18
+ return Object.fromEntries(Object.keys(value).sort()
19
+ .map((key) => [key, sortJson(value[key])]));
20
+ }
21
+ return value;
22
+ }
23
+ function serializeIdentity(value) {
24
+ return JSON.stringify(sortJson(value));
25
+ }
26
+ export function createToolcraftMotionReferenceIdentitySha256(value) {
27
+ return createToolcraftSha256(encoder.encode(serializeIdentity(value)));
28
+ }
29
+ export function createToolcraftMotionReferencePlanSha256(evidences) {
30
+ const eventIds = [...new Set(evidences.flatMap(({ detectedEvents }) =>
31
+ detectedEvents.map(({ eventId }) => eventId)))].sort();
32
+ const focusIdentities = [...new Set(evidences.flatMap(({ focusWindows }) =>
33
+ focusWindows.map((focus) => serializeIdentity({
34
+ endSeconds: focus.endSeconds,
35
+ frameIds: focus.frameIds,
36
+ sourceFrameEndIndex: focus.sourceFrameEndIndex,
37
+ sourceFrameStartIndex: focus.sourceFrameStartIndex,
38
+ startSeconds: focus.startSeconds,
39
+ }))))].sort();
40
+ return createToolcraftMotionReferenceIdentitySha256({
41
+ eventIds,
42
+ focusWindows: focusIdentities.map((identity) => JSON.parse(identity)),
43
+ ranges: evidences.map(({ segment }) => segment),
44
+ reviewedMemberships: evidences.map(({ reviewedFrames }) =>
45
+ reviewedFrames.map(({ frameId, sourceFrameIndex, sourceSha256 }) => ({
46
+ frameId,
47
+ sourceFrameIndex,
48
+ sourceSha256,
49
+ }))),
50
+ });
51
+ }
52
+ function canonicalSourceIdentity(evidence) {
53
+ return {
54
+ evidenceVersion: evidence.evidenceVersion,
55
+ ...(evidence.sourceGrid === undefined ? {} : { sourceGrid: evidence.sourceGrid }),
56
+ sourceKind: evidence.sourceKind,
57
+ sourceSha256: evidence.sourceSha256,
58
+ ...(evidence.timingMode === "seconds" ? { timing: evidence.timing } : {}),
59
+ timingMode: evidence.timingMode,
60
+ };
61
+ }
62
+ function canonicalStudyIdentity(evidence) {
63
+ return {
64
+ ...canonicalSourceIdentity(evidence),
65
+ ...(evidence.segment === undefined ? {} : { segment: evidence.segment }),
66
+ };
67
+ }
68
+ export function createToolcraftMotionReferenceStudyId(evidence) {
69
+ return `motion-v1-${createToolcraftMotionReferenceIdentitySha256(canonicalStudyIdentity(evidence))}`;
70
+ }
71
+ export function createToolcraftMotionReferenceId(evidence) {
72
+ return `motion-reference-v1-${createToolcraftMotionReferenceIdentitySha256(canonicalSourceIdentity(evidence))}`;
73
+ }
74
+ export function createToolcraftMotionReferenceGroupId(evidence, scope) {
75
+ return `motion-group-v1-${createToolcraftMotionReferenceIdentitySha256({
76
+ ...canonicalSourceIdentity(evidence), scope,
77
+ })}`;
78
+ }
79
+ function describeError(error) {
80
+ return error instanceof Error ? error.message : String(error);
81
+ }
82
+ function validateStudyPaths(study, errors) {
83
+ const expectedEvidencePath =
84
+ `src/app/reference-studies/${study.studyId}/evidence.json`;
85
+ if (study.evidencePath !== expectedEvidencePath) {
86
+ errors.push(`Motion reference study "${study.studyId}" evidencePath must use its canonical study directory.`);
87
+ }
88
+ }
89
+ async function readRootResource(resourcePath, rootDir, label, errors) {
90
+ let absolutePath;
91
+ try {
92
+ absolutePath = resolveToolcraftRootResourcePath(resourcePath, rootDir);
93
+ } catch (error) {
94
+ errors.push(`${label} violates the Toolcraft root boundary: ${describeError(error)}`);
95
+ return;
96
+ }
97
+ try {
98
+ return await fs.readFile(absolutePath);
99
+ } catch (error) {
100
+ errors.push(`${label} could not be read: ${describeError(error)}`);
101
+ }
102
+ }
103
+ function validateIdentity(study, input, errors) {
104
+ const evidence = study.evidence;
105
+ const derivedStudyId = createToolcraftMotionReferenceStudyId(evidence);
106
+ if (study.studyId !== derivedStudyId || evidence.studyId !== derivedStudyId) {
107
+ errors.push(`Motion reference studyId must equal the canonical evidence identity ${derivedStudyId}; received study "${study.studyId}" and evidence "${String(evidence.studyId)}".`);
108
+ }
109
+ const derivedReferenceId = createToolcraftMotionReferenceId(evidence);
110
+ if (input.referenceId !== derivedReferenceId) {
111
+ errors.push(`Motion reference input referenceId must equal its canonical source identity ${derivedReferenceId}; received "${input.referenceId}".`);
112
+ }
113
+ return serializeIdentity(canonicalSourceIdentity(evidence));
114
+ }
115
+ async function validateEvidenceFile(study, rootDir, embeddedCanonical, errors) {
116
+ const label = `Motion reference study "${study.studyId}" evidence.json`;
117
+ const bytes = await readRootResource(study.evidencePath, rootDir, label, errors);
118
+ if (!bytes) return;
119
+ const raw = bytes.toString("utf8");
120
+ let fileEvidence;
121
+ try {
122
+ fileEvidence = JSON.parse(raw);
123
+ } catch {
124
+ errors.push(`${label} must contain valid JSON.`);
125
+ return;
126
+ }
127
+ const fileErrors = getToolcraftMotionReferenceEvidenceErrors(fileEvidence);
128
+ if (fileErrors.length > 0) {
129
+ errors.push(...fileErrors.map((error) => `${label}: ${error}`));
130
+ return;
131
+ }
132
+ const fileCanonical = writeCanonicalToolcraftMotionReferenceEvidence(fileEvidence);
133
+ if (embeddedCanonical !== undefined && fileCanonical !== embeddedCanonical) {
134
+ errors.push(`Motion reference study "${study.studyId}" embedded evidence must match evidence.json.`);
135
+ }
136
+ if (raw !== fileCanonical) {
137
+ errors.push(`${label} must use the canonical serialization.`);
138
+ }
139
+ const sheetLabel = `Motion reference study "${study.studyId}" contact sheet`;
140
+ const sheetBytes = await readRootResource(
141
+ fileEvidence.contactSheet.path, rootDir, sheetLabel, errors,
142
+ );
143
+ if (sheetBytes && createToolcraftSha256(sheetBytes) !==
144
+ fileEvidence.contactSheet.sha256) {
145
+ errors.push(`${sheetLabel} SHA-256 does not match evidence.json.`);
146
+ }
147
+ }
148
+ function sameRange(left, right) {
149
+ return left?.startSeconds === right?.startSeconds &&
150
+ left?.endSeconds === right?.endSeconds;
151
+ }
152
+ function validateGroupMembership(groupId, records, errors) {
153
+ const ordered = [...records].sort((left, right) =>
154
+ left.partition.index - right.partition.index);
155
+ const count = ordered[0].partition.count;
156
+ const actualIndices = ordered.map(({ partition }) => partition.index);
157
+ if (ordered.length !== count || actualIndices.some((value, index) =>
158
+ value !== index)) {
159
+ errors.push(`Motion reference partition "${groupId}" must contain indices 0..${count - 1} exactly.`);
160
+ }
161
+ const scope = ordered[0].partition.scope;
162
+ let previousEnd = scope.startSeconds;
163
+ for (const { evidence, partition } of ordered) {
164
+ if (partition.count !== count || !sameRange(partition.scope, scope)) {
165
+ errors.push(`Motion reference partition "${groupId}" must share one count and scope.`);
166
+ }
167
+ if (!evidence.segment || evidence.segment.startSeconds !== previousEnd ||
168
+ evidence.segment.endSeconds <= evidence.segment.startSeconds) {
169
+ errors.push(`Motion reference partition "${groupId}" segments must be ordered, contiguous, and non-overlapping.`);
170
+ }
171
+ previousEnd = evidence.segment?.endSeconds;
172
+ }
173
+ if (previousEnd !== scope.endSeconds) {
174
+ errors.push(`Motion reference partition "${groupId}" segments must cover the complete declared scope.`);
175
+ }
176
+ return ordered;
177
+ }
178
+ function validateReviewUnits(groupId, ordered, errors) {
179
+ const unitIds = new Set();
180
+ for (const { evidence } of ordered) {
181
+ for (const frame of evidence.reviewedFrames) {
182
+ const unitId = `frame:${frame.sourceFrameIndex}`;
183
+ if (unitIds.has(unitId)) errors.push(
184
+ `Motion reference partition "${groupId}" contains duplicate review unit ${unitId}.`,
185
+ );
186
+ unitIds.add(unitId);
187
+ }
188
+ for (const event of evidence.detectedEvents) {
189
+ const unitId = `event:${event.eventId}`;
190
+ if (unitIds.has(unitId)) errors.push(
191
+ `Motion reference partition "${groupId}" contains duplicate review unit ${unitId}.`,
192
+ );
193
+ unitIds.add(unitId);
194
+ }
195
+ for (const focus of evidence.focusWindows) {
196
+ const unitId = `focus:${serializeIdentity(focus)}`;
197
+ if (unitIds.has(unitId)) errors.push(
198
+ `Motion reference partition "${groupId}" contains duplicate review unit ${unitId}.`,
199
+ );
200
+ unitIds.add(unitId);
201
+ }
202
+ }
203
+ }
204
+ function validatePartitionGroups(records, errors) {
205
+ const groups = new Map();
206
+ for (const record of records) {
207
+ if (!record.partition) continue;
208
+ groups.set(record.partition.groupId, [
209
+ ...(groups.get(record.partition.groupId) ?? []), record,
210
+ ]);
211
+ }
212
+ for (const [groupId, group] of groups) {
213
+ const ordered = validateGroupMembership(groupId, group, errors);
214
+ const sourceIdentities = new Set(ordered.map(({ sourceIdentity }) => sourceIdentity));
215
+ if (sourceIdentities.size !== 1) {
216
+ errors.push(`Motion reference partition "${groupId}" must share one source identity.`);
217
+ }
218
+ const scope = ordered[0].partition.scope;
219
+ const expectedGroupId = createToolcraftMotionReferenceGroupId(
220
+ ordered[0].evidence, scope,
221
+ );
222
+ if (groupId !== expectedGroupId) {
223
+ errors.push(`Motion reference partition groupId must equal canonical source identity and scope ${expectedGroupId}.`);
224
+ }
225
+ validateReviewUnits(groupId, ordered, errors);
226
+ const planSha256 = createToolcraftMotionReferencePlanSha256(
227
+ ordered.map(({ evidence }) => evidence),
228
+ );
229
+ for (const { partition } of ordered) {
230
+ if (partition.planSha256 !== planSha256) {
231
+ errors.push(`Motion reference partition "${groupId}" planSha256 must match the canonical partition plan ${planSha256}.`);
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ export function getToolcraftMotionReferenceEvidenceGroupErrors(evidences) {
238
+ const errors = [];
239
+ const records = [];
240
+ const sourceIdentities = new Set();
241
+ for (const evidence of evidences) {
242
+ const evidenceErrors = getToolcraftMotionReferenceEvidenceErrors(evidence);
243
+ if (evidenceErrors.length > 0) {
244
+ errors.push(...evidenceErrors);
245
+ continue;
246
+ }
247
+ const derivedStudyId = createToolcraftMotionReferenceStudyId(evidence);
248
+ if (evidence.studyId !== derivedStudyId) {
249
+ errors.push(`Motion reference studyId must equal the canonical evidence identity ${derivedStudyId}.`);
250
+ }
251
+ const sourceIdentity = serializeIdentity(canonicalSourceIdentity(evidence));
252
+ sourceIdentities.add(sourceIdentity);
253
+ records.push({
254
+ evidence,
255
+ partition: evidence.reviewPartition,
256
+ sourceIdentity,
257
+ });
258
+ }
259
+ if (sourceIdentities.size > 1) {
260
+ errors.push("Motion reference evidence group must share one source identity.");
261
+ }
262
+ const partitionCount = records.filter(({ partition }) => partition).length;
263
+ if ((partitionCount > 0 && partitionCount !== records.length) ||
264
+ (partitionCount === 0 && records.length !== 1)) {
265
+ errors.push("Motion reference evidence group must be one unpartitioned study or one complete partition set.");
266
+ }
267
+ validatePartitionGroups(records, errors);
268
+ return errors;
269
+ }
270
+
271
+ export async function getToolcraftMotionReferenceArtifactErrors({
272
+ referenceInputs,
273
+ rootDir,
274
+ }) {
275
+ if (referenceInputs.length === 0) return [];
276
+ const errors = [];
277
+ for (const input of referenceInputs) {
278
+ const records = [];
279
+ const inputSourceIdentities = new Set();
280
+ for (const study of input.studies) {
281
+ validateStudyPaths(study, errors);
282
+ const embeddedErrors = getToolcraftMotionReferenceEvidenceErrors(study.evidence);
283
+ let embeddedCanonical;
284
+ if (embeddedErrors.length === 0) {
285
+ if (study.evidence.studyId !== study.studyId) {
286
+ errors.push(`Motion reference study "${study.studyId}" must match embedded evidence studyId "${study.evidence.studyId}".`);
287
+ }
288
+ const sourceIdentity = validateIdentity(study, input, errors);
289
+ inputSourceIdentities.add(sourceIdentity);
290
+ embeddedCanonical = writeCanonicalToolcraftMotionReferenceEvidence(study.evidence);
291
+ records.push({
292
+ evidence: study.evidence,
293
+ partition: study.evidence.reviewPartition,
294
+ sourceIdentity,
295
+ });
296
+ } else {
297
+ errors.push(...embeddedErrors.map((error) =>
298
+ `Motion reference study "${study.studyId}" embedded evidence: ${error}`));
299
+ }
300
+ await validateEvidenceFile(study, rootDir, embeddedCanonical, errors);
301
+ }
302
+ if (inputSourceIdentities.size > 1) {
303
+ errors.push(`Motion reference input "${input.referenceId}" studies must share one source identity.`);
304
+ }
305
+ validatePartitionGroups(records, errors);
306
+ }
307
+ return errors;
308
+ }