@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
@@ -3,22 +3,20 @@ import {
3
3
  createToolcraftCanonicalJsonHash,
4
4
  serializeToolcraftCanonicalJson,
5
5
  } from "./toolcraft-functional-proof-primitives.mjs";
6
- import {
7
- TOOLCRAFT_VERIFICATION_IMPACT_VERSION,
8
- normalizeToolcraftVerificationImpactOwners,
9
- } from "./toolcraft-verification-impact-inventory.mjs";
10
6
 
11
7
  export {
12
8
  createToolcraftAcceptanceContractHash,
13
9
  deriveToolcraftAcceptanceDomainId,
14
10
  } from "./toolcraft-functional-proof-primitives.mjs";
15
11
 
16
- export const TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION = 1;
12
+ export const TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION = 2;
13
+
14
+ const compareCodeUnits = (left, right) =>
15
+ left < right ? -1 : left > right ? 1 : 0;
17
16
 
18
- const compareCodeUnits = (left, right) => left < right ? -1 : left > right ? 1 : 0;
19
- const isRecord = (value) =>
20
- typeof value === "object" && value !== null && !Array.isArray(value);
21
- const sorted = (values) => [...values].sort(compareCodeUnits);
17
+ function isRecord(value) {
18
+ return typeof value === "object" && value !== null && !Array.isArray(value);
19
+ }
22
20
 
23
21
  function exactKeysError(value, expected, label) {
24
22
  if (!isRecord(value)) return `${label} must be an object.`;
@@ -27,24 +25,18 @@ function exactKeysError(value, expected, label) {
27
25
  return `${label} must be a plain object.`;
28
26
  }
29
27
  const expectedSet = new Set(expected);
30
- const unknown = sorted(
31
- Reflect.ownKeys(value)
32
- .filter((key) => typeof key !== "string" || !expectedSet.has(key))
33
- .map(String),
34
- );
28
+ const unknown = Reflect.ownKeys(value)
29
+ .filter((key) => typeof key !== "string" || !expectedSet.has(key))
30
+ .map(String)
31
+ .sort(compareCodeUnits);
35
32
  const missing = expected.filter(
36
33
  (key) => !Object.prototype.hasOwnProperty.call(value, key),
37
34
  );
38
- if (unknown.length > 0) return `${label} contains unknown fields: ${unknown.join(", ")}.`;
39
- if (missing.length > 0) return `${label} is missing required fields: ${missing.join(", ")}.`;
40
- return undefined;
41
- }
42
-
43
- function duplicateOrOrderError(rows, key, label) {
44
- for (let index = 1; index < rows.length; index += 1) {
45
- const comparison = compareCodeUnits(rows[index - 1][key], rows[index][key]);
46
- if (comparison === 0) return `${label} "${rows[index][key]}" must be unique.`;
47
- if (comparison > 0) return `${label} rows must be sorted by ${key}.`;
35
+ if (unknown.length > 0) {
36
+ return `${label} contains unknown fields: ${unknown.join(", ")}.`;
37
+ }
38
+ if (missing.length > 0) {
39
+ return `${label} is missing required fields: ${missing.join(", ")}.`;
48
40
  }
49
41
  return undefined;
50
42
  }
@@ -53,15 +45,25 @@ function deeplyFrozen(value, ancestors = new Set()) {
53
45
  if (!(value && typeof value === "object")) return true;
54
46
  if (!Object.isFrozen(value) || ancestors.has(value)) return false;
55
47
  ancestors.add(value);
56
- const frozen = Object.values(value).every((entry) => deeplyFrozen(entry, ancestors));
48
+ const frozen = Object.values(value).every((entry) =>
49
+ deeplyFrozen(entry, ancestors),
50
+ );
57
51
  ancestors.delete(value);
58
52
  return frozen;
59
53
  }
60
54
 
55
+ function deepFreeze(value) {
56
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
57
+ Object.values(value).forEach(deepFreeze);
58
+ Object.freeze(value);
59
+ }
60
+ return value;
61
+ }
62
+
61
63
  export function getToolcraftFunctionalProofModelError(value) {
62
64
  const shapeError = exactKeysError(
63
65
  value,
64
- ["acceptance", "owners", "version"],
66
+ ["acceptance", "version"],
65
67
  "Toolcraft functional proof model",
66
68
  );
67
69
  if (shapeError) return shapeError;
@@ -76,78 +78,28 @@ export function getToolcraftFunctionalProofModelError(value) {
76
78
  if (value.version !== TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION) {
77
79
  return `Toolcraft functional proof model.version must be ${TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION}.`;
78
80
  }
79
- if (!Array.isArray(value.acceptance) || !Array.isArray(value.owners)) {
80
- return "Toolcraft functional proof model acceptance and owners must be arrays.";
81
+ if (!Array.isArray(value.acceptance)) {
82
+ return "Toolcraft functional proof model acceptance must be an array.";
81
83
  }
82
- const catalogValidation = validateToolcraftDeliveryCatalog({
84
+ const validation = validateToolcraftDeliveryCatalog({
83
85
  acceptance: value.acceptance,
84
86
  performance: [],
85
87
  version: 2,
86
88
  });
87
- if (catalogValidation.errors.length > 0) return catalogValidation.errors[0];
88
- const acceptanceOrderError = duplicateOrOrderError(
89
- value.acceptance,
90
- "acceptanceId",
91
- "Functional proof model acceptance id",
92
- );
93
- if (acceptanceOrderError) return acceptanceOrderError;
94
- const ownerValidation = normalizeToolcraftVerificationImpactOwners(
95
- value.owners,
96
- {
97
- acceptanceIds: value.acceptance.map(({ acceptanceId }) => acceptanceId),
98
- requireCanonical: true,
99
- },
100
- );
101
- return ownerValidation.errors[0];
89
+ return validation.errors[0];
102
90
  }
103
91
 
104
- function deepFreeze(value) {
105
- if (value && typeof value === "object" && !Object.isFrozen(value)) {
106
- Object.values(value).forEach(deepFreeze);
107
- Object.freeze(value);
108
- }
109
- return value;
110
- }
111
-
112
- export function createToolcraftFunctionalProofModel({ catalog, inventory }) {
113
- const catalogValidation = validateToolcraftDeliveryCatalog(catalog);
114
- if (catalogValidation.errors.length > 0) {
115
- throw new Error(`Invalid delivery catalog: ${catalogValidation.errors.join("\n")}`);
116
- }
117
- const inventoryError = exactKeysError(
118
- inventory,
119
- ["owners", "version"],
120
- "Verification impact inventory input",
121
- );
122
- if (inventoryError) throw new Error(inventoryError);
123
- if (inventory.version !== TOOLCRAFT_VERIFICATION_IMPACT_VERSION) {
124
- throw new Error(
125
- `Verification impact inventory.version must be ${TOOLCRAFT_VERIFICATION_IMPACT_VERSION}.`,
126
- );
127
- }
128
- const acceptance = catalogValidation.catalog.acceptance.map((row) => ({
129
- acceptanceId: row.acceptanceId,
130
- contractHash: row.contractHash,
131
- domainId: row.domainId,
132
- file: row.file,
133
- testName: row.testName,
134
- }));
135
- const ownerValidation = normalizeToolcraftVerificationImpactOwners(
136
- inventory.owners,
137
- {
138
- acceptanceIds: acceptance.map(({ acceptanceId }) => acceptanceId),
139
- },
140
- );
141
- if (ownerValidation.errors.length > 0) {
142
- throw new Error(ownerValidation.errors.join("\n"));
92
+ export function createToolcraftFunctionalProofModel({ catalog }) {
93
+ const validation = validateToolcraftDeliveryCatalog(catalog);
94
+ if (validation.errors.length > 0) {
95
+ throw new Error(`Invalid delivery catalog: ${validation.errors.join("\n")}`);
143
96
  }
144
97
  const model = deepFreeze({
145
- acceptance,
146
- owners: ownerValidation.owners,
98
+ acceptance: validation.catalog.acceptance,
147
99
  version: TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION,
148
100
  });
149
- const modelError = getToolcraftFunctionalProofModelError(model);
150
- if (modelError) throw new Error(modelError);
101
+ const error = getToolcraftFunctionalProofModelError(model);
102
+ if (error) throw new Error(error);
151
103
  return model;
152
104
  }
153
105
 
@@ -156,43 +108,3 @@ export function createToolcraftFunctionalProofModelHash(model) {
156
108
  if (error) throw new Error(`Invalid Toolcraft functional proof model: ${error}`);
157
109
  return createToolcraftCanonicalJsonHash(model);
158
110
  }
159
-
160
- export function diffToolcraftFunctionalProofModels({ current, previous }) {
161
- for (const [label, model] of [["Current", current], ["Previous", previous]]) {
162
- const error = getToolcraftFunctionalProofModelError(model);
163
- if (error) throw new Error(`${label} Toolcraft functional proof model is invalid: ${error}`);
164
- }
165
- const currentRows = new Map(current.acceptance.map((row) => [row.acceptanceId, row]));
166
- const previousRows = new Map(previous.acceptance.map((row) => [row.acceptanceId, row]));
167
- const currentOwners = new Map(current.owners.map((owner) => [owner.path, owner]));
168
- const previousOwners = new Map(previous.owners.map((owner) => [owner.path, owner]));
169
- const acceptanceIds = new Set();
170
- for (const [acceptanceId, row] of currentRows) {
171
- const prior = previousRows.get(acceptanceId);
172
- if (!prior || prior.contractHash !== row.contractHash) acceptanceIds.add(acceptanceId);
173
- }
174
- const changedOwnerPaths = [];
175
- for (const ownerPath of sorted(new Set([...currentOwners.keys(), ...previousOwners.keys()]))) {
176
- const currentOwner = currentOwners.get(ownerPath);
177
- const previousOwner = previousOwners.get(ownerPath);
178
- if (
179
- !currentOwner || !previousOwner ||
180
- serializeToolcraftCanonicalJson(currentOwner) !==
181
- serializeToolcraftCanonicalJson(previousOwner)
182
- ) {
183
- changedOwnerPaths.push(ownerPath);
184
- for (const owner of [previousOwner, currentOwner]) {
185
- for (const acceptanceId of owner?.acceptanceIds ?? []) {
186
- acceptanceIds.add(acceptanceId);
187
- }
188
- }
189
- }
190
- }
191
- return deepFreeze({
192
- acceptanceIds: sorted(acceptanceIds),
193
- changedOwnerPaths,
194
- removedAcceptanceIds: sorted(
195
- [...previousRows.keys()].filter((acceptanceId) => !currentRows.has(acceptanceId)),
196
- ),
197
- });
198
- }
@@ -5,10 +5,9 @@ import test from "node:test";
5
5
  import {
6
6
  TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION,
7
7
  createToolcraftAcceptanceContractHash,
8
- createToolcraftFunctionalProofModel as createFunctionalProofModel,
8
+ createToolcraftFunctionalProofModel,
9
9
  createToolcraftFunctionalProofModelHash,
10
10
  deriveToolcraftAcceptanceDomainId,
11
- diffToolcraftFunctionalProofModels,
12
11
  getToolcraftFunctionalProofModelError,
13
12
  } from "./toolcraft-functional-proof-model.mjs";
14
13
 
@@ -20,18 +19,8 @@ const acceptanceRow = (acceptanceId, contractHash = hash("a")) => ({
20
19
  file: `${acceptanceId.split(".")[0]}.spec.ts`,
21
20
  testName: `browser: ${acceptanceId}`,
22
21
  });
23
- const catalog = (acceptance) => ({
24
- acceptance,
25
- performance: [],
26
- version: 2,
27
- });
28
- const inventory = (owners) => ({ owners, version: 3 });
29
- const owner = (ownerPath, acceptanceIds, extra = {}) => ({
30
- acceptanceIds,
31
- kind: "functional",
32
- path: ownerPath,
33
- ...extra,
34
- });
22
+ const catalog = (acceptance) => ({ acceptance, performance: [], version: 2 });
23
+
35
24
  function deepFreeze(value) {
36
25
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
37
26
  Object.values(value).forEach(deepFreeze);
@@ -39,42 +28,18 @@ function deepFreeze(value) {
39
28
  }
40
29
  return value;
41
30
  }
42
- function createModel(input) {
43
- const model = createFunctionalProofModel(input);
44
- assert.match(createToolcraftFunctionalProofModelHash(model), /^[a-f0-9]{64}$/u);
45
- return model;
46
- }
47
- function withSymbol(value) {
48
- value[Symbol("unexpected")] = true;
49
- return value;
50
- }
51
31
 
52
- test("acceptance contract hashing uses one strict canonical JSON representation", () => {
53
- const left = {
54
- nested: { z: null, a: [true, 2, "2"] },
55
- title: "material",
56
- };
57
- const right = {
58
- title: "material",
59
- nested: { a: [true, 2, "2"], z: null },
60
- };
32
+ test("acceptance contract hashing uses canonical JSON", () => {
33
+ const left = { nested: { z: null, a: [true, 2, "2"] }, title: "material" };
34
+ const right = { title: "material", nested: { a: [true, 2, "2"], z: null } };
61
35
  const expected = createHash("sha256")
62
36
  .update('{"nested":{"a":[true,2,"2"],"z":null},"title":"material"}')
63
37
  .digest("hex");
64
-
65
38
  assert.equal(createToolcraftAcceptanceContractHash(left), expected);
66
39
  assert.equal(createToolcraftAcceptanceContractHash(right), expected);
67
- assert.notEqual(
68
- createToolcraftAcceptanceContractHash({ nested: { a: ["2", 2, true], z: null }, title: "material" }),
69
- expected,
70
- );
71
- const primitiveHashes = [null, true, false, 0, 1, "1"].map((value) =>
72
- createToolcraftAcceptanceContractHash({ value })
73
- );
74
- assert.equal(new Set(primitiveHashes).size, primitiveHashes.length);
75
40
  });
76
41
 
77
- test("acceptance contract hashing rejects every non-JSON-safe value", () => {
42
+ test("acceptance contract hashing rejects non-JSON values", () => {
78
43
  const cyclic = {};
79
44
  cyclic.self = cyclic;
80
45
  for (const value of [
@@ -82,9 +47,7 @@ test("acceptance contract hashing rejects every non-JSON-safe value", () => {
82
47
  { value() {} },
83
48
  { value: Symbol("value") },
84
49
  { value: Number.NaN },
85
- { value: Number.POSITIVE_INFINITY },
86
50
  cyclic,
87
- { value: new Date(0) },
88
51
  ]) {
89
52
  assert.throws(
90
53
  () => createToolcraftAcceptanceContractHash(value),
@@ -96,358 +59,58 @@ test("acceptance contract hashing rejects every non-JSON-safe value", () => {
96
59
  test("acceptance domains use the first stable namespace segment", () => {
97
60
  assert.equal(deriveToolcraftAcceptanceDomainId("material.donut.shape"), "material");
98
61
  assert.equal(deriveToolcraftAcceptanceDomainId("canvas"), "canvas");
99
- for (const invalid of ["", " material.shape", ".material", undefined]) {
100
- assert.throws(
101
- () => deriveToolcraftAcceptanceDomainId(invalid),
102
- /acceptance id/iu,
103
- );
104
- }
62
+ assert.throws(() => deriveToolcraftAcceptanceDomainId(""), /acceptance id/iu);
105
63
  });
106
64
 
107
- test("creates one sorted, duplicate-free, deeply frozen functional proof model", () => {
108
- const model = createModel({
65
+ test("functional proof model contains only the complete canonical acceptance catalog", () => {
66
+ const model = createToolcraftFunctionalProofModel({
109
67
  catalog: catalog([
110
68
  acceptanceRow("material.shape", hash("b")),
111
69
  acceptanceRow("export.image"),
112
70
  ]),
113
- inventory: inventory([
114
- {
115
- acceptanceIds: ["material.shape", "export.image"],
116
- kind: "performance",
117
- passIds: ["source", "composite"],
118
- path: "src/output.ts",
119
- },
120
- owner("src/app-schema.ts", ["export.image"]),
121
- ]),
122
71
  });
123
72
 
124
- assert.equal(TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION, 1);
73
+ assert.equal(TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION, 2);
125
74
  assert.deepEqual(model, {
126
75
  acceptance: [
127
76
  acceptanceRow("export.image"),
128
77
  acceptanceRow("material.shape", hash("b")),
129
78
  ],
130
- owners: [
131
- owner("src/app-schema.ts", ["export.image"]),
132
- {
133
- acceptanceIds: ["export.image", "material.shape"],
134
- kind: "performance",
135
- passIds: ["composite", "source"],
136
- path: "src/output.ts",
137
- },
138
- ],
139
- version: 1,
79
+ version: 2,
140
80
  });
141
81
  assert.equal(getToolcraftFunctionalProofModelError(model), undefined);
142
82
  assert.equal(Object.isFrozen(model), true);
143
- assert.equal(Object.isFrozen(model.acceptance[0]), true);
144
- assert.equal(Object.isFrozen(model.owners[1].acceptanceIds), true);
145
- assert.equal(Object.isFrozen(model.owners[1].passIds), true);
83
+ assert.equal(Object.isFrozen(model.acceptance), true);
146
84
  assert.match(createToolcraftFunctionalProofModelHash(model), /^[a-f0-9]{64}$/u);
147
85
  });
148
86
 
149
- test("proof model validation is exact-key, canonical, and closed over acceptance ids", () => {
150
- const model = createModel({
87
+ test("functional proof model rejects extra and noncanonical fields", () => {
88
+ const model = createToolcraftFunctionalProofModel({
151
89
  catalog: catalog([acceptanceRow("material.shape")]),
152
- inventory: inventory([owner("src/output.ts", ["material.shape"])]),
153
90
  });
154
- const malformedModels = [
155
- [{ ...model, extra: true }, /model.*unknown fields: extra/iu],
156
- [
157
- { ...model, acceptance: [{ ...model.acceptance[0], extra: true }] },
158
- /acceptance row.*unknown fields: extra/iu,
159
- ],
160
- [
161
- { ...model, owners: [{ ...model.owners[0], passIds: ["source"] }] },
162
- /owner.*unknown fields: passIds/iu,
163
- ],
164
- [
165
- { ...model, acceptance: [...model.acceptance, model.acceptance[0]] },
166
- /duplicate acceptance id/iu,
167
- ],
168
- [
169
- { ...model, owners: [...model.owners, model.owners[0]] },
170
- /owner path.*must be unique/iu,
171
- ],
172
- [
173
- {
174
- ...model,
175
- owners: [owner("src/output.ts", ["missing.acceptance"])],
176
- },
177
- /unknown acceptance id "missing\.acceptance"/iu,
178
- ],
179
- ].map(([malformed, expectedError]) => [
180
- deepFreeze(malformed),
181
- expectedError,
182
- ]);
183
- for (const [malformed, expectedError] of malformedModels) {
184
- assert.match(getToolcraftFunctionalProofModelError(malformed), expectedError);
185
- assert.throws(
186
- () => createToolcraftFunctionalProofModelHash(malformed),
187
- expectedError,
188
- );
189
- }
91
+ const malformed = deepFreeze({ ...model, owners: [] });
92
+ assert.match(
93
+ getToolcraftFunctionalProofModelError(malformed),
94
+ /unknown fields: owners/iu,
95
+ );
190
96
  assert.throws(
191
- () => createFunctionalProofModel({
192
- catalog: catalog([acceptanceRow("material.shape")]),
193
- inventory: inventory([{
194
- ...owner("src/output.ts", ["material.shape"]),
195
- unknown: true,
196
- }]),
197
- }),
198
- /unknown fields/iu,
97
+ () => createToolcraftFunctionalProofModelHash(malformed),
98
+ /unknown fields: owners/iu,
199
99
  );
200
100
  });
201
101
 
202
- test("model hash is independent of source ordering after canonical construction", () => {
102
+ test("functional proof model hash is stable after canonical construction", () => {
203
103
  const rows = [
204
104
  acceptanceRow("material.shape", hash("b")),
205
105
  acceptanceRow("export.image"),
206
106
  ];
207
- const owners = [
208
- owner("src/output.ts", ["material.shape"]),
209
- owner("src/app-schema.ts", ["export.image"]),
210
- ];
211
- const first = createModel({
212
- catalog: catalog(rows),
213
- inventory: inventory(owners),
214
- });
215
- const second = createModel({
107
+ const first = createToolcraftFunctionalProofModel({ catalog: catalog(rows) });
108
+ const second = createToolcraftFunctionalProofModel({
216
109
  catalog: catalog([...rows].reverse()),
217
- inventory: inventory([...owners].reverse()),
218
110
  });
219
-
220
111
  assert.deepEqual(first, second);
221
112
  assert.equal(
222
113
  createToolcraftFunctionalProofModelHash(first),
223
114
  createToolcraftFunctionalProofModelHash(second),
224
115
  );
225
116
  });
226
-
227
- test("validation and hashing reject mutable models at every object depth", () => {
228
- const model = createModel({
229
- catalog: catalog([acceptanceRow("material.shape")]),
230
- inventory: inventory([owner("src/output.ts", ["material.shape"])]),
231
- });
232
- const mutableRoot = structuredClone(model);
233
- const mutableRow = Object.freeze({
234
- ...model,
235
- acceptance: Object.freeze([{ ...model.acceptance[0] }]),
236
- });
237
- const mutableOwnerIds = Object.freeze({
238
- ...model,
239
- owners: Object.freeze([
240
- Object.freeze({
241
- ...model.owners[0],
242
- acceptanceIds: [...model.owners[0].acceptanceIds],
243
- }),
244
- ]),
245
- });
246
-
247
- for (const mutable of [mutableRoot, mutableRow, mutableOwnerIds]) {
248
- assert.match(
249
- getToolcraftFunctionalProofModelError(mutable),
250
- /deeply frozen/iu,
251
- );
252
- assert.throws(
253
- () => createToolcraftFunctionalProofModelHash(mutable),
254
- /deeply frozen/iu,
255
- );
256
- }
257
- });
258
-
259
- test("diff ignores catalog metadata relocation when contract hash is unchanged", () => {
260
- const previous = createModel({
261
- catalog: catalog([acceptanceRow("material.shape")]),
262
- inventory: inventory([owner("src/output.ts", ["material.shape"])]),
263
- });
264
- const relocatedRow = {
265
- ...acceptanceRow("material.shape"),
266
- file: "material-relocated.spec.ts",
267
- };
268
- const current = createModel({
269
- catalog: catalog([relocatedRow]),
270
- inventory: inventory([owner("src/output.ts", ["material.shape"])]),
271
- });
272
-
273
- assert.deepEqual(diffToolcraftFunctionalProofModels({ current, previous }), {
274
- acceptanceIds: [],
275
- changedOwnerPaths: [],
276
- removedAcceptanceIds: [],
277
- });
278
- });
279
-
280
- test("diff selects semantic row and owner deltas while reporting removed ids separately", () => {
281
- const previous = createModel({
282
- catalog: catalog([
283
- acceptanceRow("export.old"),
284
- acceptanceRow("material.color"),
285
- acceptanceRow("scene.light"),
286
- ]),
287
- inventory: inventory([
288
- owner("src/export.ts", ["export.old"]),
289
- owner("src/material.ts", ["material.color"]),
290
- owner("src/scene.ts", ["scene.light"]),
291
- ]),
292
- });
293
- const current = createModel({
294
- catalog: catalog([
295
- acceptanceRow("material.color", hash("b")),
296
- acceptanceRow("material.shape"),
297
- acceptanceRow("scene.light"),
298
- ]),
299
- inventory: inventory([
300
- owner("src/material.ts", ["material.shape", "material.color"]),
301
- owner("src/scene.ts", ["scene.light"]),
302
- owner("src/shape.ts", ["material.shape"]),
303
- ]),
304
- });
305
-
306
- assert.deepEqual(diffToolcraftFunctionalProofModels({ current, previous }), {
307
- acceptanceIds: ["export.old", "material.color", "material.shape"],
308
- changedOwnerPaths: ["src/export.ts", "src/material.ts", "src/shape.ts"],
309
- removedAcceptanceIds: ["export.old"],
310
- });
311
- });
312
-
313
- test("diff preserves all coverage of an additive owner delta", () => {
314
- const rows = [
315
- acceptanceRow("material.color"),
316
- acceptanceRow("material.emission"),
317
- ];
318
- const previous = createModel({
319
- catalog: catalog(rows),
320
- inventory: inventory([
321
- owner("src/material.ts", ["material.color"]),
322
- owner("src/emission.ts", ["material.emission"]),
323
- ]),
324
- });
325
- const current = createModel({
326
- catalog: catalog(rows),
327
- inventory: inventory([
328
- owner(
329
- "src/material.ts",
330
- ["material.color", "material.emission"],
331
- ),
332
- owner("src/emission.ts", ["material.emission"]),
333
- ]),
334
- });
335
-
336
- assert.deepEqual(diffToolcraftFunctionalProofModels({ current, previous }), {
337
- acceptanceIds: ["material.color", "material.emission"],
338
- changedOwnerPaths: ["src/material.ts"],
339
- removedAcceptanceIds: [],
340
- });
341
- });
342
-
343
- test("diff keeps functional coverage when only owner classification changes", () => {
344
- const rows = [acceptanceRow("material.color")];
345
- const previous = createModel({
346
- catalog: catalog(rows),
347
- inventory: inventory([
348
- owner("src/material.ts", ["material.color"]),
349
- ]),
350
- });
351
- const current = createModel({
352
- catalog: catalog(rows),
353
- inventory: inventory([
354
- owner("src/material.ts", ["material.color"], {
355
- kind: "performance",
356
- passIds: ["preview"],
357
- }),
358
- ]),
359
- });
360
-
361
- assert.deepEqual(diffToolcraftFunctionalProofModels({ current, previous }), {
362
- acceptanceIds: ["material.color"],
363
- changedOwnerPaths: ["src/material.ts"],
364
- removedAcceptanceIds: [],
365
- });
366
- });
367
-
368
- test("construction uses current catalog and impact validation without partial acceptance", () => {
369
- const row = acceptanceRow("material.shape");
370
- const validInventory = inventory([owner("src/output.ts", ["material.shape"])]);
371
- const malformedPathId = "performance-path:not-json";
372
- assert.throws(
373
- () => createFunctionalProofModel({
374
- catalog: {
375
- ...catalog([row]),
376
- performance: [{
377
- passIds: [],
378
- pathId: malformedPathId,
379
- testName: `browser perf: toolcraft path ${malformedPathId}`,
380
- }],
381
- },
382
- inventory: validInventory,
383
- }),
384
- /invalid delivery catalog.*malformed canonical path/iu,
385
- );
386
- assert.throws(
387
- () => createFunctionalProofModel({
388
- catalog: catalog([row]),
389
- inventory: { ...validInventory, version: 999 },
390
- }),
391
- /inventory.*version must be 3/iu,
392
- );
393
- });
394
-
395
- test("symbol fields are rejected at model, catalog, inventory, and owner boundaries", () => {
396
- const model = createModel({
397
- catalog: catalog([acceptanceRow("material.shape")]),
398
- inventory: inventory([owner("src/output.ts", ["material.shape"])]),
399
- });
400
- const acceptanceArray = withSymbol([...model.acceptance]);
401
- const ownersArray = withSymbol([...model.owners]);
402
- const malformedModels = [
403
- withSymbol({ ...model }),
404
- { ...model, acceptance: [withSymbol({ ...model.acceptance[0] })] },
405
- { ...model, owners: [withSymbol({ ...model.owners[0] })] },
406
- { ...model, acceptance: acceptanceArray },
407
- { ...model, owners: ownersArray },
408
- {
409
- ...model,
410
- owners: [{
411
- ...model.owners[0],
412
- acceptanceIds: withSymbol([...model.owners[0].acceptanceIds]),
413
- }],
414
- },
415
- ].map(deepFreeze);
416
- for (const malformed of malformedModels) {
417
- assert.match(getToolcraftFunctionalProofModelError(malformed), /symbol/iu);
418
- }
419
-
420
- const row = acceptanceRow("material.shape");
421
- const validOwner = owner("src/output.ts", ["material.shape"]);
422
- for (const input of [
423
- {
424
- catalog: withSymbol(catalog([row])),
425
- inventory: inventory([validOwner]),
426
- },
427
- {
428
- catalog: catalog([withSymbol({ ...row })]),
429
- inventory: inventory([validOwner]),
430
- },
431
- {
432
- catalog: catalog([row]),
433
- inventory: withSymbol(inventory([validOwner])),
434
- },
435
- {
436
- catalog: catalog([row]),
437
- inventory: inventory(withSymbol([validOwner])),
438
- },
439
- {
440
- catalog: catalog([row]),
441
- inventory: inventory([withSymbol({ ...validOwner })]),
442
- },
443
- {
444
- catalog: catalog([row]),
445
- inventory: inventory([{
446
- ...validOwner,
447
- acceptanceIds: withSymbol([...validOwner.acceptanceIds]),
448
- }]),
449
- },
450
- ]) {
451
- assert.throws(() => createFunctionalProofModel(input), /symbol/iu);
452
- }
453
- });