@pixel-point/toolcraft 0.0.14 → 0.0.15

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 (577) hide show
  1. package/README.md +13 -2
  2. package/package.json +1 -1
  3. package/scripts/prepare-pack.mjs +2 -28
  4. package/src/cli-io.mjs +174 -0
  5. package/src/cli-package-manager-flow.test.mjs +206 -0
  6. package/src/cli.mjs +7 -495
  7. package/src/cli.test.mjs +34 -177
  8. package/src/create-command.mjs +152 -0
  9. package/src/create-options.mjs +194 -0
  10. package/src/generate-test-assertions.mjs +27 -0
  11. package/src/generate-test-doc-assertions.mjs +162 -0
  12. package/src/generate-test-file-assertions.mjs +251 -0
  13. package/src/generate-test-fs-utils.mjs +59 -0
  14. package/src/generate-test-integrity-assertions.mjs +30 -0
  15. package/src/generate-test-integrity-framework-assertions.mjs +222 -0
  16. package/src/generate-test-integrity-manifest-assertions.mjs +150 -0
  17. package/src/generate-test-integrity-ownership-assertions.mjs +127 -0
  18. package/src/generate-test-integrity-test-utils.mjs +102 -0
  19. package/src/generate-test-package-assertions.mjs +75 -0
  20. package/src/generate-test-product-fixture.mjs +84 -0
  21. package/src/generate-test-product-fixture.test.mjs +73 -0
  22. package/src/generate-test-standalone-assertions.mjs +209 -0
  23. package/src/generate-transactional.test.mjs +151 -0
  24. package/src/generate.mjs +182 -102
  25. package/src/generate.test.mjs +242 -338
  26. package/src/generated-integrity-manifest.mjs +127 -0
  27. package/src/generated-integrity-manifest.test.mjs +151 -0
  28. package/src/generated-source-policy.mjs +22 -0
  29. package/src/generated-source-policy.test.mjs +35 -0
  30. package/src/generated-target-policy.mjs +55 -0
  31. package/src/generation-transaction.mjs +135 -0
  32. package/src/generation-transaction.test.mjs +74 -0
  33. package/src/package-json.mjs +18 -1
  34. package/src/package-json.test.mjs +38 -5
  35. package/src/package-manager.mjs +2 -0
  36. package/src/package-manager.test.mjs +5 -1
  37. package/src/packaged-template-fallback.test.mjs +126 -0
  38. package/src/prepare-pack-templates.mjs +34 -0
  39. package/templates/runtime/contracts/component-contract-builders.ts +95 -0
  40. package/templates/runtime/contracts/component-contracts.choices.test.ts +293 -0
  41. package/templates/runtime/contracts/component-contracts.choices.ts +322 -0
  42. package/templates/runtime/contracts/component-contracts.inputs.test.ts +210 -0
  43. package/templates/runtime/contracts/component-contracts.inputs.ts +252 -0
  44. package/templates/runtime/contracts/component-contracts.media-custom.test.ts +116 -0
  45. package/templates/runtime/contracts/component-contracts.media-custom.ts +144 -0
  46. package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +229 -0
  47. package/templates/runtime/contracts/component-contracts.runtime-labels.test.ts +76 -0
  48. package/templates/runtime/contracts/component-contracts.runtime-panels.test.ts +135 -0
  49. package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +148 -0
  50. package/templates/runtime/contracts/component-contracts.runtime.ts +361 -0
  51. package/templates/runtime/contracts/component-contracts.test.ts +39 -1458
  52. package/templates/runtime/contracts/component-contracts.ts +44 -1505
  53. package/templates/runtime/contracts/component-contracts.visual.test.ts +316 -0
  54. package/templates/runtime/contracts/component-contracts.visual.ts +385 -0
  55. package/templates/runtime/contracts/contract-manifest.test.ts +64 -0
  56. package/templates/runtime/contracts/decision-contracts.test.ts +29 -4
  57. package/templates/runtime/contracts/decision-contracts.ts +38 -1
  58. package/templates/runtime/index.ts +1 -0
  59. package/templates/runtime/react/{runtime-public-api.test.tsx → app-shell/runtime-public-api.test.tsx} +29 -7
  60. package/templates/runtime/react/{settings-transfer.test.ts → app-shell/settings-transfer.test.ts} +4 -4
  61. package/templates/runtime/react/{settings-transfer.ts → app-shell/settings-transfer.ts} +3 -3
  62. package/templates/runtime/react/{toolbar-panel.test.tsx → app-shell/toolbar-panel.test.tsx} +2 -2
  63. package/templates/runtime/react/{toolbar-panel.tsx → app-shell/toolbar-panel.tsx} +3 -3
  64. package/templates/runtime/react/{toolcraft-app.integration.test.tsx → app-shell/toolcraft-app.integration.test.tsx} +6 -6
  65. package/templates/runtime/react/{toolcraft-app.test.tsx → app-shell/toolcraft-app.test.tsx} +3 -3
  66. package/templates/runtime/react/{toolcraft-app.tsx → app-shell/toolcraft-app.tsx} +11 -8
  67. package/templates/runtime/react/{toolcraft-root.test.tsx → app-shell/toolcraft-root.test.tsx} +1 -1
  68. package/templates/runtime/react/{toolcraft-root.tsx → app-shell/toolcraft-root.tsx} +5 -5
  69. package/templates/runtime/react/{use-toolcraft.ts → app-shell/use-toolcraft.ts} +1 -1
  70. package/templates/runtime/react/canvas/canvas-default-media-layer.tsx +81 -0
  71. package/templates/runtime/react/canvas/canvas-media-transform.ts +33 -0
  72. package/templates/runtime/react/canvas/canvas-shell-interactions.test.tsx +156 -0
  73. package/templates/runtime/react/canvas/canvas-shell-media-rendering.test.tsx +87 -0
  74. package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +102 -0
  75. package/templates/runtime/react/canvas/canvas-shell-test-utils.tsx +108 -0
  76. package/templates/runtime/react/canvas/canvas-shell-upload.test.tsx +106 -0
  77. package/templates/runtime/react/canvas/canvas-shell.tsx +146 -0
  78. package/templates/runtime/react/canvas/canvas-upload-routing.ts +84 -0
  79. package/templates/runtime/react/{media-file.ts → canvas/media-file.ts} +1 -1
  80. package/templates/runtime/react/canvas/use-canvas-drop-import.ts +145 -0
  81. package/templates/runtime/react/canvas/use-canvas-viewport-interactions.ts +227 -0
  82. package/templates/runtime/react/controls-panel/__tests__/control-conditions.test.ts +89 -0
  83. package/templates/runtime/react/{controls-panel-filedrop-reorder.test.tsx → controls-panel/__tests__/controls-panel-filedrop-reorder.test.tsx} +4 -4
  84. package/templates/runtime/react/controls-panel/__tests__/controls-panel.actions-layout.test.tsx +91 -0
  85. package/templates/runtime/react/controls-panel/__tests__/controls-panel.collection-actions.test.tsx +213 -0
  86. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-layout.test.tsx +366 -0
  87. package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-picker-models.test.tsx +169 -0
  88. package/templates/runtime/react/controls-panel/__tests__/controls-panel.compound-layout.test.tsx +160 -0
  89. package/templates/runtime/react/controls-panel/__tests__/controls-panel.control-visibility.test.tsx +352 -0
  90. package/templates/runtime/react/controls-panel/__tests__/controls-panel.curves.test.tsx +226 -0
  91. package/templates/runtime/react/controls-panel/__tests__/controls-panel.floating-shell.test.tsx +13 -0
  92. package/templates/runtime/react/controls-panel/__tests__/controls-panel.font-picker.test.tsx +302 -0
  93. package/templates/runtime/react/controls-panel/__tests__/controls-panel.footer-actions.test.tsx +401 -0
  94. package/templates/runtime/react/controls-panel/__tests__/controls-panel.gradient-control.test.tsx +139 -0
  95. package/templates/runtime/react/controls-panel/__tests__/controls-panel.help-policy.test.tsx +103 -0
  96. package/templates/runtime/react/controls-panel/__tests__/controls-panel.image-picker.test.tsx +16 -0
  97. package/templates/runtime/react/controls-panel/__tests__/controls-panel.inline-layout.test.tsx +290 -0
  98. package/templates/runtime/react/controls-panel/__tests__/controls-panel.keyframes.test.tsx +175 -0
  99. package/templates/runtime/react/controls-panel/__tests__/controls-panel.media-upload-files.test.tsx +121 -0
  100. package/templates/runtime/react/controls-panel/__tests__/controls-panel.media-upload-image.test.tsx +363 -0
  101. package/templates/runtime/react/controls-panel/__tests__/controls-panel.media-upload-multi-image.test.tsx +105 -0
  102. package/templates/runtime/react/controls-panel/__tests__/controls-panel.range-slider-editing.test.tsx +149 -0
  103. package/templates/runtime/react/controls-panel/__tests__/controls-panel.section-shell.test.tsx +138 -0
  104. package/templates/runtime/react/controls-panel/__tests__/controls-panel.select-layout.test.tsx +148 -0
  105. package/templates/runtime/react/controls-panel/__tests__/controls-panel.setup-controls.test.tsx +189 -0
  106. package/templates/runtime/react/controls-panel/__tests__/controls-panel.slider-rendering.test.tsx +317 -0
  107. package/templates/runtime/react/controls-panel/__tests__/controls-panel.state-reset.test.tsx +137 -0
  108. package/templates/runtime/react/controls-panel/__tests__/controls-panel.structure.test.tsx +66 -0
  109. package/templates/runtime/react/controls-panel/__tests__/controls-panel.text-input.test.tsx +205 -0
  110. package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-interaction.test.tsx +388 -0
  111. package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-layout.test.tsx +155 -0
  112. package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +172 -0
  113. package/templates/runtime/react/{control-conditions.ts → controls-panel/conditions/control-conditions.ts} +26 -3
  114. package/templates/runtime/react/{control-renderers.ts → controls-panel/control-renderers.ts} +2 -2
  115. package/templates/runtime/react/controls-panel/controls-panel.tsx +250 -0
  116. package/templates/runtime/react/controls-panel/keyframes/controls-panel-keyframes.tsx +265 -0
  117. package/templates/runtime/react/controls-panel/layout/controls-panel-collapse-storage.ts +131 -0
  118. package/templates/runtime/react/controls-panel/layout/controls-panel-help.tsx +132 -0
  119. package/templates/runtime/react/controls-panel/layout/controls-panel-inline-layout.tsx +311 -0
  120. package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +216 -0
  121. package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +401 -0
  122. package/templates/runtime/react/controls-panel/renderers/controls-panel-action-renderer.tsx +137 -0
  123. package/templates/runtime/react/controls-panel/renderers/controls-panel-basic-renderers.tsx +421 -0
  124. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-renderer.tsx +286 -0
  125. package/templates/runtime/react/controls-panel/renderers/controls-panel-compound-renderers.tsx +366 -0
  126. package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.tsx +173 -0
  127. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.test.ts +23 -0
  128. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.ts +55 -0
  129. package/templates/runtime/react/controls-panel/renderers/controls-panel-settings-transfer-renderer.tsx +45 -0
  130. package/templates/runtime/react/controls-panel/testing/controls-panel-test-utils.tsx +300 -0
  131. package/templates/runtime/react/controls-panel/values/controls-panel-aspect-ratio-values.ts +94 -0
  132. package/templates/runtime/react/controls-panel/values/controls-panel-collection-values.ts +87 -0
  133. package/templates/runtime/react/controls-panel/values/controls-panel-color-values.ts +82 -0
  134. package/templates/runtime/react/controls-panel/values/controls-panel-font-values.ts +69 -0
  135. package/templates/runtime/react/controls-panel/values/controls-panel-spatial-values.ts +64 -0
  136. package/templates/runtime/react/controls-panel/values/controls-panel-value-labels.ts +93 -0
  137. package/templates/runtime/react/controls-panel/values/controls-panel-value-primitives.ts +30 -0
  138. package/templates/runtime/react/controls-panel/values/controls-panel-values.ts +7 -0
  139. package/templates/runtime/react/index.ts +13 -13
  140. package/templates/runtime/react/{layer-tree.ts → layers/layer-tree.ts} +1 -1
  141. package/templates/runtime/react/layers/layers-panel-drag-drop.test.tsx +190 -0
  142. package/templates/runtime/react/layers/layers-panel-editing.test.tsx +41 -0
  143. package/templates/runtime/react/layers/layers-panel-insert-targets.test.ts +87 -0
  144. package/templates/runtime/react/layers/layers-panel-insert-targets.ts +254 -0
  145. package/templates/runtime/react/layers/layers-panel-model.ts +15 -0
  146. package/templates/runtime/react/layers/layers-panel-rendering.test.tsx +43 -0
  147. package/templates/runtime/react/layers/layers-panel-reorder.ts +148 -0
  148. package/templates/runtime/react/layers/layers-panel-row.tsx +475 -0
  149. package/templates/runtime/react/layers/layers-panel-test-utils.tsx +135 -0
  150. package/templates/runtime/react/layers/layers-panel-visibility.test.tsx +126 -0
  151. package/templates/runtime/react/layers/layers-panel.tsx +349 -0
  152. package/templates/runtime/react/layers/use-layers-panel-drag-controller.ts +327 -0
  153. package/templates/runtime/react/{panel-host-types.ts → panel-host/panel-host-types.ts} +2 -2
  154. package/templates/runtime/react/{panel-host.test.tsx → panel-host/panel-host.test.tsx} +3 -3
  155. package/templates/runtime/react/{panel-host.tsx → panel-host/panel-host.tsx} +1 -1
  156. package/templates/runtime/react/timeline/timeline-easing-editor.tsx +409 -0
  157. package/templates/runtime/react/timeline/timeline-easing-geometry.ts +42 -0
  158. package/templates/runtime/react/timeline/timeline-easing-icons.tsx +135 -0
  159. package/templates/runtime/react/timeline/timeline-easing-model.test.ts +87 -0
  160. package/templates/runtime/react/timeline/timeline-easing-model.ts +271 -0
  161. package/templates/runtime/react/timeline/timeline-easing-popover-content.tsx +227 -0
  162. package/templates/runtime/react/timeline/timeline-easing-popover-layout.ts +69 -0
  163. package/templates/runtime/react/timeline/timeline-easing-popover.tsx +60 -0
  164. package/templates/runtime/react/timeline/timeline-event-targets.ts +19 -0
  165. package/templates/runtime/react/timeline/timeline-expanded-content.tsx +299 -0
  166. package/templates/runtime/react/timeline/timeline-icon-button.tsx +51 -0
  167. package/templates/runtime/react/timeline/timeline-keyframe-row.tsx +360 -0
  168. package/templates/runtime/react/timeline/timeline-keyframes.ts +23 -0
  169. package/templates/runtime/react/timeline/timeline-panel-floating-layout.test.tsx +328 -0
  170. package/templates/runtime/react/timeline/timeline-panel-header.tsx +404 -0
  171. package/templates/runtime/react/timeline/timeline-panel-keyframes.test.tsx +90 -0
  172. package/templates/runtime/react/timeline/timeline-panel-layout.ts +30 -0
  173. package/templates/runtime/react/timeline/timeline-panel-responsive-layout.ts +182 -0
  174. package/templates/runtime/react/timeline/timeline-panel-test-utils.tsx +88 -0
  175. package/templates/runtime/react/timeline/timeline-panel-transport.test.tsx +202 -0
  176. package/templates/runtime/react/timeline/timeline-panel-upload.test.tsx +53 -0
  177. package/templates/runtime/react/timeline/timeline-panel.tsx +449 -0
  178. package/templates/runtime/react/timeline/timeline-playback-hooks.ts +254 -0
  179. package/templates/runtime/schema/assembly-contract.ts +271 -0
  180. package/templates/runtime/schema/control-schema-normalization.ts +55 -0
  181. package/templates/runtime/schema/controls-panel-actions.ts +141 -0
  182. package/templates/runtime/schema/controls-panel-layout-groups.ts +144 -0
  183. package/templates/runtime/schema/controls-panel-normalization.ts +19 -0
  184. package/templates/runtime/schema/controls-panel-section-layout.ts +140 -0
  185. package/templates/runtime/schema/controls-panel-section-titles.ts +161 -0
  186. package/templates/runtime/schema/define-toolcraft-test-utils.ts +18 -0
  187. package/templates/runtime/schema/define-toolcraft.actions.test.ts +182 -0
  188. package/templates/runtime/schema/define-toolcraft.assembly.test.ts +246 -0
  189. package/templates/runtime/schema/define-toolcraft.canvas.test.ts +150 -0
  190. package/templates/runtime/schema/define-toolcraft.control-layout.test.ts +345 -0
  191. package/templates/runtime/schema/define-toolcraft.control-sections.test.ts +304 -0
  192. package/templates/runtime/schema/define-toolcraft.setup-canvas.test.ts +69 -0
  193. package/templates/runtime/schema/define-toolcraft.setup-persistence.test.ts +66 -0
  194. package/templates/runtime/schema/define-toolcraft.setup-render-scale-timeline.test.ts +116 -0
  195. package/templates/runtime/schema/define-toolcraft.setup-settings-transfer.test.ts +291 -0
  196. package/templates/runtime/schema/define-toolcraft.ts +24 -1449
  197. package/templates/runtime/schema/panels-schema-normalization.ts +49 -0
  198. package/templates/runtime/schema/runtime-section-titles.ts +1 -0
  199. package/templates/runtime/schema/runtime-setup-section.ts +282 -0
  200. package/templates/runtime/schema/schema-resolvers.ts +168 -0
  201. package/templates/runtime/schema/types.ts +17 -0
  202. package/templates/runtime/state/canvas-reducer.ts +106 -0
  203. package/templates/runtime/state/canvas-state.ts +209 -0
  204. package/templates/runtime/state/controls-reducer.ts +277 -0
  205. package/templates/runtime/state/history-patches.ts +174 -0
  206. package/templates/runtime/state/layer-state.ts +12 -0
  207. package/templates/runtime/state/layers-reducer.ts +318 -0
  208. package/templates/runtime/state/media-reducer.ts +283 -0
  209. package/templates/runtime/state/media-state.ts +105 -0
  210. package/templates/runtime/state/panels-reducer.ts +58 -0
  211. package/templates/runtime/state/persistence-merge.ts +53 -0
  212. package/templates/runtime/state/persistence-reader-canvas.ts +27 -0
  213. package/templates/runtime/state/persistence-reader-layers.ts +73 -0
  214. package/templates/runtime/state/persistence-reader-media.ts +82 -0
  215. package/templates/runtime/state/persistence-reader-panels.ts +56 -0
  216. package/templates/runtime/state/persistence-reader-primitives.ts +27 -0
  217. package/templates/runtime/state/persistence-reader-timeline.ts +145 -0
  218. package/templates/runtime/state/persistence-reader-values.ts +40 -0
  219. package/templates/runtime/state/persistence-readers.ts +72 -0
  220. package/templates/runtime/state/persistence-shared.ts +23 -0
  221. package/templates/runtime/state/persistence-snapshot.ts +57 -0
  222. package/templates/runtime/state/persistence.ts +16 -581
  223. package/templates/runtime/state/reducer-canvas-panels.test.ts +324 -0
  224. package/templates/runtime/state/reducer-controls.test.ts +158 -0
  225. package/templates/runtime/state/reducer-layers.test.ts +306 -0
  226. package/templates/runtime/state/reducer-media-import-sizing.test.ts +197 -0
  227. package/templates/runtime/state/reducer-media-reorder-history.test.ts +116 -0
  228. package/templates/runtime/state/reducer-media-reset.test.ts +249 -0
  229. package/templates/runtime/state/reducer-media-test-utils.ts +40 -0
  230. package/templates/runtime/state/reducer-media-transform.test.ts +52 -0
  231. package/templates/runtime/state/reducer-test-utils.ts +30 -0
  232. package/templates/runtime/state/reducer-timeline.test.ts +242 -0
  233. package/templates/runtime/state/reducer.ts +57 -1785
  234. package/templates/runtime/state/timeline-reducer.ts +412 -0
  235. package/templates/runtime/state/timeline-values.test.ts +45 -0
  236. package/templates/runtime/state/timeline-values.ts +45 -0
  237. package/templates/runtime/testing/performance-browser-policy.test.ts +81 -0
  238. package/templates/runtime/testing/performance-browser-policy.ts +102 -0
  239. package/templates/runtime/testing/performance-budget-validation.ts +84 -0
  240. package/templates/runtime/testing/performance-control-classification.test.ts +106 -0
  241. package/templates/runtime/testing/performance-control-classification.ts +101 -0
  242. package/templates/runtime/testing/performance-coverage-context.ts +44 -0
  243. package/templates/runtime/testing/performance-coverage-renderer-policy.ts +221 -0
  244. package/templates/runtime/testing/performance-coverage-scenario-policy.ts +147 -0
  245. package/templates/runtime/testing/performance-coverage-target-policy.ts +121 -0
  246. package/templates/runtime/testing/performance-coverage-validator.ts +34 -0
  247. package/templates/runtime/testing/performance-export-coverage.test.ts +234 -0
  248. package/templates/runtime/testing/performance-fixture-load-profile.test.ts +360 -0
  249. package/templates/runtime/testing/performance-fixture-media.test.ts +80 -0
  250. package/templates/runtime/testing/performance-fixture-stress.test.ts +314 -0
  251. package/templates/runtime/testing/performance-fixture-validation.ts +255 -0
  252. package/templates/runtime/testing/performance-fixture-values.ts +275 -0
  253. package/templates/runtime/testing/performance-fixture-workload.test.ts +140 -0
  254. package/templates/runtime/testing/performance-load-profile-validation.ts +467 -0
  255. package/templates/runtime/testing/performance-renderer-coverage.test.ts +325 -0
  256. package/templates/runtime/testing/performance-renderer-pipeline-coverage.test.ts +115 -0
  257. package/templates/runtime/testing/performance-renderer-pipeline-interactions.test.ts +201 -0
  258. package/templates/runtime/testing/performance-renderer-pipeline-passes.test.ts +247 -0
  259. package/templates/runtime/testing/performance-renderer-pipeline-validation.ts +360 -0
  260. package/templates/runtime/testing/performance-renderer-technique-validation.ts +329 -0
  261. package/templates/runtime/testing/performance-renderer-technique.test.ts +275 -0
  262. package/templates/runtime/testing/performance-renderer-validation.ts +2 -0
  263. package/templates/runtime/testing/performance-scenario-coverage.test.ts +303 -0
  264. package/templates/runtime/testing/performance-scenario-validation.ts +49 -0
  265. package/templates/runtime/testing/performance-schema-derived-workloads.test.ts +231 -0
  266. package/templates/runtime/testing/performance-schema-queries.ts +181 -0
  267. package/templates/runtime/testing/performance-test-fixtures/index.ts +4 -0
  268. package/templates/runtime/testing/performance-test-fixtures/renderer-pipelines.ts +322 -0
  269. package/templates/runtime/testing/performance-test-fixtures/scenarios.ts +172 -0
  270. package/templates/runtime/testing/performance-test-fixtures/schemas.ts +151 -0
  271. package/templates/runtime/testing/performance-test-fixtures/stress-fixtures.ts +133 -0
  272. package/templates/runtime/testing/performance-test-fixtures.ts +1 -0
  273. package/templates/runtime/testing/performance-types.ts +338 -0
  274. package/templates/runtime/testing/performance.ts +15 -2485
  275. package/templates/starter/AGENTS.md +41 -26
  276. package/templates/starter/LICENSE.md +18 -95
  277. package/templates/starter/NOTICE.md +3 -3
  278. package/templates/starter/docs/toolcraft/README.md +5 -5
  279. package/templates/starter/docs/toolcraft/acceptance-testing.md +36 -8
  280. package/templates/starter/docs/toolcraft/assembly-workflow.md +12 -15
  281. package/templates/starter/docs/toolcraft/component-rules.md +6 -2
  282. package/templates/starter/docs/toolcraft/core/layout.md +1 -0
  283. package/templates/starter/docs/toolcraft/core/performance.md +7 -4
  284. package/templates/starter/docs/toolcraft/core/runtime-boundary.md +11 -4
  285. package/templates/starter/docs/toolcraft/core/timeline-animation.md +1 -0
  286. package/templates/starter/docs/toolcraft/custom-controls.md +8 -1
  287. package/templates/starter/docs/toolcraft/decision-contract.md +26 -22
  288. package/templates/starter/docs/toolcraft/performance.md +42 -16
  289. package/templates/starter/docs/toolcraft/schema-reference.md +34 -23
  290. package/templates/starter/docs/toolcraft/workflow.md +25 -17
  291. package/templates/starter/e2e/app-browser-acceptance-evidence.spec.ts +111 -0
  292. package/templates/starter/e2e/app-browser-control-coverage.spec.ts +118 -0
  293. package/templates/starter/e2e/app-browser-performance-evidence.spec.ts +217 -0
  294. package/templates/starter/e2e/app-browser-performance-probe.spec.ts +322 -0
  295. package/templates/starter/e2e/app-browser-proof-session.spec.ts +196 -0
  296. package/templates/starter/e2e/app-browser-runtime-evidence.spec.ts +9 -0
  297. package/templates/starter/e2e/app-browser-runtime-provenance.spec.ts +240 -0
  298. package/templates/starter/e2e/app-browser-runtime-reporter.spec.ts +180 -0
  299. package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +310 -0
  300. package/templates/starter/e2e/app-browser-semantic-evidence.spec.ts +432 -0
  301. package/templates/starter/e2e/app-browser-shell.spec.ts +171 -0
  302. package/templates/starter/e2e/app-browser-timeline-layers-reference.spec.ts +70 -0
  303. package/templates/starter/e2e/app-performance.spec.ts +0 -491
  304. package/templates/starter/e2e/browser-acceptance-outcome-helpers.ts +97 -0
  305. package/templates/starter/e2e/browser-acceptance-transition-helpers.ts +74 -0
  306. package/templates/starter/e2e/browser-conditional-output-evidence-helpers.ts +230 -0
  307. package/templates/starter/e2e/browser-control-target-helpers.ts +109 -0
  308. package/templates/starter/e2e/browser-layer-evidence-helpers.ts +229 -0
  309. package/templates/starter/e2e/browser-proof-session.ts +392 -0
  310. package/templates/starter/e2e/browser-runtime-evidence-reporter.ts +136 -0
  311. package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +290 -0
  312. package/templates/starter/e2e/browser-runtime-evidence.ts +27 -0
  313. package/templates/starter/e2e/browser-state-evidence-helpers.ts +205 -0
  314. package/templates/starter/e2e/browser-timeline-evidence-helpers.ts +319 -0
  315. package/templates/starter/e2e/canvas-handle-helpers.ts +86 -4
  316. package/templates/starter/e2e/export-artifact-helpers.ts +132 -0
  317. package/templates/starter/e2e/performance-budget-helpers.ts +159 -0
  318. package/templates/starter/e2e/performance-canvas-helpers.ts +123 -0
  319. package/templates/starter/e2e/performance-control-helpers.ts +3 -0
  320. package/templates/starter/e2e/performance-control-layout-helpers.ts +161 -0
  321. package/templates/starter/e2e/performance-fixture-helpers.ts +217 -0
  322. package/templates/starter/e2e/performance-frame-probe.ts +247 -0
  323. package/templates/starter/e2e/performance-helpers.ts +6 -854
  324. package/templates/starter/e2e/performance-interaction-measurement.ts +251 -0
  325. package/templates/starter/e2e/performance-measurement-evidence.ts +72 -0
  326. package/templates/starter/e2e/performance-output-action-helpers.spec.ts +43 -0
  327. package/templates/starter/e2e/performance-output-action-helpers.ts +109 -0
  328. package/templates/starter/e2e/performance-probe-helpers.ts +12 -0
  329. package/templates/starter/e2e/performance-render-scale-helpers.ts +55 -0
  330. package/templates/starter/e2e/performance-slider-helpers.ts +271 -0
  331. package/templates/starter/e2e/product-observable-helpers.ts +72 -17
  332. package/templates/starter/e2e/stable-outcome-helpers.ts +208 -0
  333. package/templates/starter/package.json +10 -5
  334. package/templates/starter/playwright.config.ts +5 -2
  335. package/templates/starter/scripts/check-ai-skills.mjs +14 -8
  336. package/templates/starter/scripts/check-ai-skills.test.mjs +64 -0
  337. package/templates/starter/scripts/check-toolcraft-code-health.mjs +108 -0
  338. package/templates/starter/scripts/check-toolcraft-code-health.test.mjs +213 -0
  339. package/templates/starter/scripts/check-toolcraft-docs.mjs +47 -34
  340. package/templates/starter/scripts/check-toolcraft-integrity.mjs +141 -144
  341. package/templates/starter/scripts/run-browser-performance.mjs +118 -0
  342. package/templates/starter/scripts/run-browser-performance.test.mjs +53 -0
  343. package/templates/starter/scripts/toolcraft-code-health-core.mjs +297 -0
  344. package/templates/starter/scripts/toolcraft-contract-doc-integrity.mjs +77 -0
  345. package/templates/starter/scripts/toolcraft-contract-doc-integrity.test.mjs +81 -0
  346. package/templates/starter/scripts/toolcraft-contract-manifest.json +113 -0
  347. package/templates/starter/scripts/toolcraft-contract-manifest.mjs +128 -0
  348. package/templates/starter/scripts/toolcraft-contract-manifest.test.mjs +72 -0
  349. package/templates/starter/scripts/toolcraft-integrity-manifest.mjs +172 -0
  350. package/templates/starter/scripts/toolcraft-integrity-policy.mjs +60 -0
  351. package/templates/starter/scripts/toolcraft-product-boundary-ast-utils.mjs +23 -0
  352. package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +264 -0
  353. package/templates/starter/scripts/toolcraft-product-boundary-test-fixtures.mjs +16 -0
  354. package/templates/starter/scripts/toolcraft-product-boundary.mjs +243 -0
  355. package/templates/starter/scripts/toolcraft-product-boundary.test.mjs +289 -0
  356. package/templates/starter/scripts/toolcraft-product-dependency-graph.mjs +176 -0
  357. package/templates/starter/scripts/toolcraft-product-dependency-graph.test.mjs +196 -0
  358. package/templates/starter/scripts/toolcraft-product-dependency-resolution.mjs +279 -0
  359. package/templates/starter/scripts/toolcraft-product-evidence-boundary-ast.mjs +91 -0
  360. package/templates/starter/scripts/toolcraft-product-evidence-boundary.test.mjs +138 -0
  361. package/templates/starter/scripts/toolcraft-product-style-boundary.mjs +219 -0
  362. package/templates/starter/scripts/toolcraft-source-inventory.d.mts +46 -0
  363. package/templates/starter/scripts/toolcraft-source-inventory.mjs +187 -0
  364. package/templates/starter/scripts/toolcraft-source-inventory.test.mjs +132 -0
  365. package/templates/starter/scripts/toolcraft-source-ownership.mjs +167 -0
  366. package/templates/starter/scripts/toolcraft-source-ownership.test.mjs +113 -0
  367. package/templates/starter/scripts/toolcraft-static-string.mjs +104 -0
  368. package/templates/starter/scripts/toolcraft-verification-inventory.mjs +123 -0
  369. package/templates/starter/scripts/toolcraft-verification-receipt.d.mts +19 -0
  370. package/templates/starter/scripts/toolcraft-verification-receipt.mjs +284 -0
  371. package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +282 -0
  372. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.d.mts +32 -0
  373. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.mjs +88 -0
  374. package/templates/starter/scripts/toolcraft-vitest-runtime-contract.test.mjs +87 -0
  375. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.mjs +109 -0
  376. package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.test.mjs +111 -0
  377. package/templates/starter/scripts/toolcraft-workflow-routes.mjs +314 -0
  378. package/templates/starter/scripts/toolcraft-workflow-routes.test.mjs +204 -0
  379. package/templates/starter/src/app/acceptance/actions.ts +30 -0
  380. package/templates/starter/src/app/acceptance/animation-intent.ts +184 -0
  381. package/templates/starter/src/app/acceptance/canvas-handle-acceptance.ts +70 -0
  382. package/templates/starter/src/app/acceptance/color-bank-labels.ts +164 -0
  383. package/templates/starter/src/app/acceptance/conditions.ts +80 -0
  384. package/templates/starter/src/app/acceptance/control-acceptance-context.ts +70 -0
  385. package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +271 -0
  386. package/templates/starter/src/app/acceptance/control-acceptance-kind-rules.ts +149 -0
  387. package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +189 -0
  388. package/templates/starter/src/app/acceptance/control-acceptance.ts +70 -0
  389. package/templates/starter/src/app/acceptance/control-component-rules.ts +277 -0
  390. package/templates/starter/src/app/acceptance/control-labels.ts +223 -0
  391. package/templates/starter/src/app/acceptance/control-layout-dependency-rules.ts +107 -0
  392. package/templates/starter/src/app/acceptance/control-layout-entity-rules.ts +104 -0
  393. package/templates/starter/src/app/acceptance/control-layout-model.ts +159 -0
  394. package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +164 -0
  395. package/templates/starter/src/app/acceptance/control-layout.ts +45 -0
  396. package/templates/starter/src/app/acceptance/control-order.ts +123 -0
  397. package/templates/starter/src/app/acceptance/control-parts.ts +47 -0
  398. package/templates/starter/src/app/acceptance/control-section-inventory.ts +183 -0
  399. package/templates/starter/src/app/acceptance/controls.ts +27 -0
  400. package/templates/starter/src/app/acceptance/coverage.ts +81 -0
  401. package/templates/starter/src/app/acceptance/custom-controls.ts +140 -0
  402. package/templates/starter/src/app/acceptance/inline-layout.ts +192 -0
  403. package/templates/starter/src/app/acceptance/media-upload.ts +55 -0
  404. package/templates/starter/src/app/acceptance/output-background-rules.ts +135 -0
  405. package/templates/starter/src/app/acceptance/output-export-actions.test.ts +76 -0
  406. package/templates/starter/src/app/acceptance/output-export-actions.ts +34 -0
  407. package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +46 -0
  408. package/templates/starter/src/app/acceptance/output-export-model.ts +146 -0
  409. package/templates/starter/src/app/acceptance/output-export.ts +45 -0
  410. package/templates/starter/src/app/acceptance/output-image-export-rules.ts +87 -0
  411. package/templates/starter/src/app/acceptance/reference-runtime-coverage.ts +96 -0
  412. package/templates/starter/src/app/acceptance/reference-runtime-feature-inventory.ts +171 -0
  413. package/templates/starter/src/app/acceptance/reference-runtime-study.ts +73 -0
  414. package/templates/starter/src/app/acceptance/reference-runtime-timeline.ts +291 -0
  415. package/templates/starter/src/app/acceptance/reference-runtime.ts +99 -0
  416. package/templates/starter/src/app/acceptance/runtime-coverage.ts +290 -0
  417. package/templates/starter/src/app/acceptance/runtime-setup.ts +117 -0
  418. package/templates/starter/src/app/acceptance/section-title-rules.ts +8 -0
  419. package/templates/starter/src/app/acceptance/sections.ts +6 -0
  420. package/templates/starter/src/app/acceptance/semantic.ts +63 -0
  421. package/templates/starter/src/app/acceptance/timeline-loop.ts +21 -0
  422. package/templates/starter/src/app/acceptance/types.ts +363 -0
  423. package/templates/starter/src/app/acceptance/validate-coverage.ts +217 -0
  424. package/templates/starter/src/app/acceptance/validation-pipeline.test.ts +56 -0
  425. package/templates/starter/src/app/acceptance/validation-pipeline.ts +60 -0
  426. package/templates/starter/src/app/acceptance/video-reference-study.ts +217 -0
  427. package/templates/starter/src/app/starter-acceptance-data.ts +21 -0
  428. package/templates/starter/src/app/starter-acceptance.animation-intent.test.ts +383 -0
  429. package/templates/starter/src/app/starter-acceptance.background-export.test.ts +349 -0
  430. package/templates/starter/src/app/starter-acceptance.base-coverage.test.ts +47 -0
  431. package/templates/starter/src/app/starter-acceptance.canvas-handles.test.ts +71 -0
  432. package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +199 -0
  433. package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +244 -0
  434. package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +63 -0
  435. package/templates/starter/src/app/starter-acceptance.control-label-context.test.ts +172 -0
  436. package/templates/starter/src/app/starter-acceptance.control-labels.test.ts +387 -0
  437. package/templates/starter/src/app/starter-acceptance.control-naming-rules.test.ts +215 -0
  438. package/templates/starter/src/app/starter-acceptance.control-order.test.ts +274 -0
  439. package/templates/starter/src/app/starter-acceptance.control-state.test.ts +275 -0
  440. package/templates/starter/src/app/starter-acceptance.curves-rules.test.ts +184 -0
  441. package/templates/starter/src/app/starter-acceptance.custom-control-collections.test.ts +200 -0
  442. package/templates/starter/src/app/starter-acceptance.custom-control-coverage.test.ts +111 -0
  443. package/templates/starter/src/app/starter-acceptance.custom-control-fit-check.test.ts +135 -0
  444. package/templates/starter/src/app/starter-acceptance.custom-control-valid.test.ts +74 -0
  445. package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +107 -0
  446. package/templates/starter/src/app/starter-acceptance.framework-boundary.test.ts +327 -0
  447. package/templates/starter/src/app/starter-acceptance.image-video-export-settings.test.ts +328 -0
  448. package/templates/starter/src/app/starter-acceptance.keyframes.test.ts +242 -0
  449. package/templates/starter/src/app/starter-acceptance.layers.test.ts +203 -0
  450. package/templates/starter/src/app/starter-acceptance.media-upload.fixtures.ts +110 -0
  451. package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +153 -0
  452. package/templates/starter/src/app/starter-acceptance.output-export-rules.test.ts +97 -0
  453. package/templates/starter/src/app/starter-acceptance.persistence-coverage.test.ts +134 -0
  454. package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +202 -0
  455. package/templates/starter/src/app/starter-acceptance.product-readiness-rules.test.ts +14 -0
  456. package/templates/starter/src/app/starter-acceptance.product-readiness-test-utils.ts +25 -0
  457. package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +50 -0
  458. package/templates/starter/src/app/starter-acceptance.product-worklog.test.ts +27 -0
  459. package/templates/starter/src/app/starter-acceptance.range-slider-rules.test.ts +147 -0
  460. package/templates/starter/src/app/starter-acceptance.reference-custom-timeline.test.ts +197 -0
  461. package/templates/starter/src/app/starter-acceptance.reference-foundation.test.ts +304 -0
  462. package/templates/starter/src/app/starter-acceptance.reference-test-utils.ts +102 -0
  463. package/templates/starter/src/app/starter-acceptance.reference-timeline.test.ts +267 -0
  464. package/templates/starter/src/app/starter-acceptance.schema-test-utils.ts +116 -0
  465. package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +373 -0
  466. package/templates/starter/src/app/starter-acceptance.section-dependencies.test.ts +260 -0
  467. package/templates/starter/src/app/starter-acceptance.section-titles.test.ts +180 -0
  468. package/templates/starter/src/app/starter-acceptance.setup-readiness.test.ts +205 -0
  469. package/templates/starter/src/app/starter-acceptance.slider-rules.test.ts +470 -0
  470. package/templates/starter/src/app/starter-acceptance.slider-unit-rules.test.ts +61 -0
  471. package/templates/starter/src/app/starter-acceptance.source-test-utils.ts +43 -0
  472. package/templates/starter/src/app/starter-acceptance.test-utils.ts +21 -0
  473. package/templates/starter/src/app/starter-acceptance.text-control-kind.test.ts +89 -0
  474. package/templates/starter/src/app/starter-acceptance.timeline-playback.test.ts +264 -0
  475. package/templates/starter/src/app/starter-acceptance.timeline-test-utils.ts +56 -0
  476. package/templates/starter/src/app/starter-acceptance.toggle-pair-layout.test.ts +200 -0
  477. package/templates/starter/src/app/starter-acceptance.toggle-parameter-layout.test.ts +277 -0
  478. package/templates/starter/src/app/starter-acceptance.ts +151 -4576
  479. package/templates/starter/src/app/starter-acceptance.video-export-test-utils.ts +37 -0
  480. package/templates/starter/src/app/starter-acceptance.video-reference-study.test.ts +262 -0
  481. package/templates/starter/src/app/starter-acceptance.worklog-test-utils.ts +428 -0
  482. package/templates/starter/src/app/starter-acceptance.worklog.test.ts +283 -0
  483. package/templates/starter/src/app/starter-automated-runtime-evidence.test.ts +34 -0
  484. package/templates/starter/src/app/starter-composition.tsx +7 -0
  485. package/templates/starter/src/app/starter-performance-test-utils.ts +275 -0
  486. package/templates/starter/src/app/starter-performance.budgets.test.ts +374 -0
  487. package/templates/starter/src/app/starter-performance.gates.test.ts +128 -0
  488. package/templates/starter/src/app/starter-performance.renderer-source.test.ts +136 -0
  489. package/templates/starter/src/app/starter-performance.renderer-technique.test.ts +291 -0
  490. package/templates/starter/src/app/starter-performance.scenarios.test.ts +355 -0
  491. package/templates/starter/src/app/test-evidence/browser-runtime-contract.test.ts +253 -0
  492. package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +243 -0
  493. package/templates/starter/src/routes/index.tsx +11 -2
  494. package/templates/starter/vite.config.ts +8 -0
  495. package/templates/ui/components/controls/color/color-control-types.ts +38 -0
  496. package/templates/ui/components/controls/color/color-control.tsx +19 -437
  497. package/templates/ui/components/controls/color/color-footer.tsx +272 -0
  498. package/templates/ui/components/controls/color/color-model-slider.tsx +271 -0
  499. package/templates/ui/components/controls/color/color-opacity-input.tsx +94 -0
  500. package/templates/ui/components/controls/color/color-surface.tsx +194 -0
  501. package/templates/ui/components/controls/color/color-value-control.tsx +159 -0
  502. package/templates/ui/components/controls/color/color-value-utils.ts +170 -0
  503. package/templates/ui/components/controls/color/index.ts +10 -3
  504. package/templates/ui/components/controls/color/palette-control-controller.ts +407 -0
  505. package/templates/ui/components/controls/color/palette-control-layout.ts +14 -0
  506. package/templates/ui/components/controls/color/palette-control-types.ts +50 -0
  507. package/templates/ui/components/controls/color/palette-control-view.tsx +174 -0
  508. package/templates/ui/components/controls/color/palette-control.tsx +6 -544
  509. package/templates/ui/components/controls/color/style-guide-color-picker-color-utils.ts +39 -0
  510. package/templates/ui/components/controls/color/style-guide-color-picker-controller.ts +370 -0
  511. package/templates/ui/components/controls/color/style-guide-color-picker-hue-handlers.ts +66 -0
  512. package/templates/ui/components/controls/color/style-guide-color-picker-interaction-state.ts +49 -0
  513. package/templates/ui/components/controls/color/style-guide-color-picker-interactions.ts +2 -2
  514. package/templates/ui/components/controls/color/style-guide-color-picker-model.ts +125 -0
  515. package/templates/ui/components/controls/color/style-guide-color-picker-parts.tsx +10 -707
  516. package/templates/ui/components/controls/color/style-guide-color-picker-surface-drag.ts +93 -0
  517. package/templates/ui/components/controls/color/style-guide-color-picker-surface-geometry.ts +114 -0
  518. package/templates/ui/components/controls/color/style-guide-color-picker-surface-preview.ts +45 -0
  519. package/templates/ui/components/controls/color/style-guide-color-picker-types.ts +84 -0
  520. package/templates/ui/components/controls/color/style-guide-color-picker-view.tsx +69 -0
  521. package/templates/ui/components/controls/color/style-guide-color-picker.tsx +6 -495
  522. package/templates/ui/components/controls/curves/curves-control.tsx +4 -3
  523. package/templates/ui/components/controls/file-drop/file-drop-control.tsx +39 -515
  524. package/templates/ui/components/controls/file-drop/file-drop-empty-state.tsx +35 -0
  525. package/templates/ui/components/controls/file-drop/file-drop-file-list.tsx +160 -0
  526. package/templates/ui/components/controls/file-drop/file-drop-image-grid.tsx +175 -0
  527. package/templates/ui/components/controls/file-drop/file-drop-model.tsx +170 -0
  528. package/templates/ui/components/controls/file-drop/file-drop-single-preview.tsx +63 -0
  529. package/templates/ui/components/controls/file-drop/file-drop-types.ts +48 -0
  530. package/templates/ui/components/controls/file-drop/index.ts +2 -2
  531. package/templates/ui/components/controls/font-picker/font-picker-control.tsx +133 -906
  532. package/templates/ui/components/controls/font-picker/font-picker-footer.tsx +116 -0
  533. package/templates/ui/components/controls/font-picker/font-picker-list.tsx +194 -0
  534. package/templates/ui/components/controls/font-picker/font-picker-popover-content.tsx +191 -0
  535. package/templates/ui/components/controls/font-picker/font-picker-value.ts +222 -0
  536. package/templates/ui/components/controls/font-picker/index.ts +4 -1
  537. package/templates/ui/components/controls/font-picker/use-font-picker-preview-pipeline.ts +163 -0
  538. package/templates/ui/components/controls/font-picker/use-font-picker-virtual-list.ts +293 -0
  539. package/templates/ui/components/controls/gradient/gradient-control-utils.ts +2 -25
  540. package/templates/ui/components/controls/gradient/gradient-control.tsx +4 -464
  541. package/templates/ui/components/controls/gradient/gradient-stops-controller.ts +332 -0
  542. package/templates/ui/components/controls/gradient/gradient-stops-track.tsx +159 -0
  543. package/templates/ui/components/controls/vector/vector-control-types.ts +26 -0
  544. package/templates/ui/components/controls/vector/vector-control.tsx +10 -486
  545. package/templates/ui/components/controls/vector/vector-pad-field.tsx +211 -0
  546. package/templates/ui/components/controls/vector/vector-pad-geometry.ts +61 -0
  547. package/templates/ui/components/controls/vector/vector-pad-parts.tsx +72 -0
  548. package/templates/ui/components/controls/vector/vector-pad-variants.ts +20 -0
  549. package/templates/ui/components/controls/vector/vector-size-field.tsx +104 -0
  550. package/templates/ui/components/controls/vector/vector-value.ts +46 -0
  551. package/templates/ui/components/primitives/slider/slider-discrete-state.ts +181 -0
  552. package/templates/ui/components/primitives/slider/slider-marker-policy.ts +52 -0
  553. package/templates/ui/components/primitives/slider/slider-pointer-dragging.ts +87 -0
  554. package/templates/ui/components/primitives/slider/slider-runtime.ts +109 -0
  555. package/templates/ui/components/primitives/slider/slider-types.ts +21 -0
  556. package/templates/ui/components/primitives/slider/slider.tsx +2 -403
  557. package/templates/runtime/react/canvas-shell.test.tsx +0 -554
  558. package/templates/runtime/react/canvas-shell.tsx +0 -585
  559. package/templates/runtime/react/controls-panel.test.tsx +0 -5446
  560. package/templates/runtime/react/controls-panel.tsx +0 -3220
  561. package/templates/runtime/react/layers-panel.test.tsx +0 -487
  562. package/templates/runtime/react/layers-panel.tsx +0 -1348
  563. package/templates/runtime/react/timeline-panel.test.tsx +0 -751
  564. package/templates/runtime/react/timeline-panel.tsx +0 -3078
  565. package/templates/runtime/schema/define-toolcraft.test.ts +0 -1742
  566. package/templates/runtime/state/reducer.test.ts +0 -1703
  567. package/templates/runtime/testing/performance.test.ts +0 -3081
  568. package/templates/starter/e2e/app-browser-acceptance.spec.ts +0 -785
  569. package/templates/starter/src/app/starter-acceptance.test.ts +0 -10068
  570. package/templates/starter/src/app/starter-performance.test.ts +0 -1583
  571. package/templates/ui/components/controls/color/style-guide-color-picker-logic.ts +0 -490
  572. /package/templates/runtime/react/{storage-key-migration.ts → app-shell/storage-key-migration.ts} +0 -0
  573. /package/templates/runtime/react/{theme-runtime.tsx → app-shell/theme-runtime.tsx} +0 -0
  574. /package/templates/runtime/react/{curve-geometry.test.ts → controls-panel/__tests__/curve-geometry.test.ts} +0 -0
  575. /package/templates/runtime/react/{panel-host-config.ts → panel-host/panel-host-config.ts} +0 -0
  576. /package/templates/runtime/react/{panel-host-geometry.test.ts → panel-host/panel-host-geometry.test.ts} +0 -0
  577. /package/templates/runtime/react/{panel-host-geometry.ts → panel-host/panel-host-geometry.ts} +0 -0
@@ -16,18 +16,21 @@ After the first working version, feature loops do not run the full performance s
16
16
  - Tier 0-1: targeted docs/typecheck/unit plus focused browser when visual.
17
17
  - Tier 2: `pnpm verify:quick` plus relevant browser acceptance.
18
18
  - Tier 3: `pnpm verify:quick`, targeted browser acceptance, and targeted performance scenarios for touched workload/viewport/export paths.
19
- - Tier 4: `pnpm verify:final`; for the first working product version also run and pass a browser performance checkpoint with the current AI agent's controlled browser when available, using `pnpm verify:perf` only as fallback.
19
+ - Tier 4: for the first working product version, run and receipt the browser performance checkpoint first, then run `pnpm verify:final` against the current receipt.
20
20
 
21
21
  Record skipped full performance runs and reason in the verification note or worklog.
22
22
 
23
23
  ## Workload Fixtures
24
24
 
25
25
  - Performance scenarios declare `stressFixture` for the tested control value.
26
- - Browser perf tests use `getToolcraftPerformanceStressValue(appPerformance, scenarioId)` so heavy-case tests cannot use toy values.
26
+ - `export-copy` scenarios declare the exact `panelActions` `actionValue`, visible `controlLabel`, and `completionEvidence` (`download` or `clipboard`). Their browser test uses the matching protected output-action helper with `scenarioId`; the helper owns the click and real download/clipboard completion. The signed reporter rejects missing completion evidence, skipped/failed tests, and evidence from failed retries.
27
+ - Browser perf tests apply scalar values with `applyToolcraftPerformanceStressValue` / `applyToolcraftPerformanceWorkloadValue` and object fixtures with `applyToolcraftPerformanceStressFixture` / `applyToolcraftPerformanceWorkloadFixture`. Every fixture mapping supplies `applyValue` plus `observeValue`; evidence attaches only after the observed UI/runtime value exactly matches the declared fixture.
28
+ - Mutating measurements pass a structured-cloneable `observeOutcome`. Generic change evidence first proves that its baseline stays stable before the action, timestamps the first live changed response, then requires the final post-action outcome to remain changed through the stability window. Autonomous or animated output uses `expectedOutcome` with a stable semantic observation, or the test fixes playback to a deterministic phase; an incidental next frame cannot satisfy the interaction. The immutable result stays bound to the same `scenarioId` as its budget. `durationMs` uses a runner monotonic clock from interaction start to the first changed or expected response; required frame sampling survives document navigation, and settle/stability checks still finish before evidence is emitted without replacing product-response latency with action completion or inflating it with the post-change window. Non-mutating measurements end at action completion.
27
29
  - When the tested control is not itself the whole heavy source, declare `workloadFixture` and apply it first.
28
- - Numeric maximums, density, item counts, canvas/media size, and combined heavy states declare `loadProfile` with `hardLimit`, `smoothTarget`, and `smoothTargetRatio`.
30
+ - Numeric control ranges and hard limits come from schema; scenarios may omit duplicated `values`, and any supplied values must match schema exactly. A bounded numeric control cannot switch to `metric: "custom"` to avoid its min/max.
31
+ - Numeric maximums, density, item counts, canvas/media size, and combined heavy states declare `loadProfile` with `hardLimit`, `smoothTarget`, and `smoothTargetRatio`. `many-items` applies at least 10 real items; lowering an authored `minCount` is not evidence.
29
32
  - Try the hard limit first.
30
- - Lower the guaranteed smooth target only in 10 percent steps with failed-measurement and optimization evidence.
33
+ - Lower the guaranteed smooth target only in 10 percent steps with failed-measurement and optimization evidence. Every entry names the exact `attemptedRatio`, schema-reachable `attemptedTarget`, scenario id, and target for that step.
31
34
  - Ranges above `smoothTarget` are experimental, not silently guaranteed.
32
35
 
33
36
  ## Media And Pixel Workloads
@@ -8,12 +8,12 @@ Read this module before changing app assembly, routes, runtime surfaces, custom
8
8
  - Render through `ToolcraftApp`.
9
9
  - Read `appSchema.assembly` before adding custom JSX. It lists the enabled runtime surfaces, capabilities, commands, and assumptions for the current app.
10
10
  - Keep app state in the Toolcraft runtime schema and runtime commands.
11
- - Keep route files thin: routes compose the schema-backed Toolcraft app and product renderers.
11
+ - Keep product assembly in typed `src/app/app-composition.tsx`; the signed route only hosts `ToolcraftApp`.
12
12
  - Do not replace Toolcraft with copied reference UI, route-local panels, standalone forms, or hand-built editor chrome.
13
13
 
14
14
  ## Allowed Extension Points
15
15
 
16
- Use only these app-specific extension points unless you are intentionally changing the shared Toolcraft runtime:
16
+ Use only these app-specific extension points. Shared runtime changes happen upstream and reach generated apps through regeneration:
17
17
 
18
18
  - schema controls;
19
19
  - schema `canvas`, `panels`, `toolbar`, `panelActions`, `persistence`, `media`, `assembly`, and transfer-mode metadata;
@@ -48,6 +48,13 @@ Use only these app-specific extension points unless you are intentionally changi
48
48
 
49
49
  ## Generated App Source Boundary
50
50
 
51
- - Generated applications keep their public editing surface in `src/app/app-schema.ts` and app-specific files under `src/app` and `src/routes`.
52
- - Do not edit `src/toolcraft` in one generated app unless the task is intentionally changing the local copied runtime. Prefer fixing the monorepo runtime and regenerating or syncing.
51
+ - Generated applications keep their public entry surface in `src/app/app-composition.tsx` and `src/app/app-schema.ts`. Supporting product modules may live anywhere under `src`; every product production module is discovered by the same source inventory and checked by the same AST boundary.
52
+ - The signed framework bootstrap includes `index.html`, `src/main.tsx`, `src/router.tsx`, `src/routes/index.tsx`, `src/routes/root.tsx`, and `src/styles.css`. Do not edit or replace those host files in a generated app.
53
+ - Product styling is local by construction: use locally imported `*.module.css` files only. Every selector starts with a compound containing a local class. A first-compound `:is()` or `:where()` remains local only when every branch is locally anchored; `:not()` and `:has()` do not create a local anchor. Descendants may style product-owned children, but `:global`, bare/root selectors, host-attribute selectors, sibling escapes, CSS `@import`, package CSS imports, and product-created global `<style>`/`CSSStyleSheet` injection are rejected because they cross the product/runtime boundary.
54
+ - Product `import()` and `require()` specifiers must be statically resolvable from literals, same-file constants, templates, or string concatenation. Production and test source share this rule, so computed module loading cannot hide a runtime/control import or a protected evidence channel.
55
+ - Product production modules must not import product tests, test-support modules, or protected browser-evidence internals, directly or through a product bridge. Runtime evidence is emitted only by the protected public acceptance/performance helpers after their assertions pass; product-owned source must not import, re-export, assemble, or forge the reserved evidence module names and payload identifiers.
56
+ - Product production modules must form an acyclic dependency graph. The code-health gate resolves relative imports, directory `index.*` modules, configured TypeScript path aliases, and local package exports. Type-only imports, external packages, tests, and copied Toolcraft framework internals do not create product dependency edges. When a cycle exists, the gate prints the complete shortest cycle so the ownership boundary can be corrected directly.
57
+ - Imported product source remains under `src`. Code health and product-boundary analysis consume the same canonical source-inventory semantics instead of maintaining independent recursive walkers. The signed Vitest reporter uses the canonical framework-ownership policy to distinguish product-owned runner results, while acceptance and performance requirements derive from typed app configuration.
58
+ - Do not edit `src/toolcraft` in a generated app. It is an immutable signed copy of the shared runtime. Fix the monorepo runtime and regenerate the app.
59
+ - Generated integrity protects the copied runtime, signed host/bootstrap, framework validators/tests, `AGENTS.md`, local contract docs under `docs/toolcraft`, `LICENSE.md`, `NOTICE.md`, TypeScript/Vite/Vitest/Playwright root configuration, and the commands of the original package scripts. Alternate root config files in those verification families are rejected instead of silently creating a second test path. `docs/toolcraft/agent-worklog.md` is the explicit editable documentation exception; every other file added under `docs/toolcraft` is rejected as unrecorded contract input. Product dependencies, unrelated product scripts, product source, and the worklog remain editable, but all product production modules are AST-checked for host-surface and built-in-control bypasses. Added `pre*` or `post*` lifecycle hooks for a protected script are rejected because they can execute across a verification boundary. Run the checker directly before the final gate; `pnpm test` must fail when any protected file changes, or when the copied runtime tree or its signed integrity manifest is missing, changed, or contains unrecorded source.
53
60
  - Generated apps must not contain monorepo app/package folders, workspace-protocol dependencies, or workspace package imports.
@@ -37,6 +37,7 @@ Use no timeline only when the motion is explicitly autonomous decoration with no
37
37
  - Use `getToolcraftTimelineLoopTime` or `getToolcraftTimelineLoopProgress` in playback renderers instead of local wall-clock or fixed-duration phase math.
38
38
  - When the loop period is known or product-derived, set `panels.timeline.defaultDurationSeconds` to that period and record the evidence in animation or reference timeline metadata.
39
39
  - Runtime/template fallback `8s` is not evidence for loop duration.
40
+ - Playback acceptance with loop coverage declares typed `timelineLoopProof`: forward-only direction, reverse playback forbidden, first/last frame seam match, and reproof after a duration edit. This declaration never replaces browser sampling of the real renderer.
40
41
 
41
42
  ## Duration Changes
42
43
 
@@ -33,6 +33,13 @@ Custom control schemas still need:
33
33
 
34
34
  ```ts
35
35
  builtInFitCheck: {
36
+ capabilities: [
37
+ "collection",
38
+ "reorder",
39
+ "selection",
40
+ "commands",
41
+ "custom-value-model",
42
+ ],
36
43
  checkedBuiltIns: ["fileDrop", "collectionActions", "imagePicker"],
37
44
  closestBuiltIn: "fileDrop",
38
45
  whyInsufficient:
@@ -42,7 +49,7 @@ builtInFitCheck: {
42
49
  }
43
50
  ```
44
51
 
45
- `checkedBuiltIns` must name real Toolcraft built-in controls. `closestBuiltIn` must be one of those checked controls or `"none"` when no built-in is meaningfully close. `whyInsufficient` explains the missing interaction. `productObservable` names the output or side effect that proves the custom control is necessary.
52
+ `capabilities` is required and uses broad behavior facts: `collection`, `reorder`, `selection`, `commands`, `custom-interaction`, `custom-value-model`, or `custom-visualization`. At least one of the three `custom-*` capabilities must explain why built-ins cannot own the interaction. `checkedBuiltIns` must name real Toolcraft built-in controls. `closestBuiltIn` must be one of those checked controls or `"none"` when no built-in is meaningfully close. `whyInsufficient` explains the missing interaction. `productObservable` names the output or side effect that proves the custom control is necessary.
46
53
 
47
54
  If the custom control owns a growable, removable, selectable, or reorderable runtime item set, `checkedBuiltIns` must include both `collectionActions` and `actions`. Decide this from the value model and workflow, such as arrays, `{ items: [...] }` objects, selected-item state, or add/remove/reorder behavior, not from entity names like masks or glyphs. This applies even when the empty state visually looks like a few icon buttons: the fit check must prove why `collectionActions` cannot own the runtime list and why `actions` alone cannot represent the collection state.
48
55
 
@@ -16,7 +16,7 @@ Use this before writing a schema, spec, or implementation plan. It separates har
16
16
 
17
17
  | Area | Decision Type | Summary |
18
18
  | --- | --- | --- |
19
- | Runtime shell | Invariant | Use `defineToolcraft` and `ToolcraftApp` |
19
+ | Runtime shell | Invariant | Use `defineToolcraft` and `ToolcraftAppComposition`; the signed host renders `ToolcraftApp` |
20
20
  | Canvas | Mixed | No app UI in `canvasContent`; handles are product-dependent |
21
21
  | Panels | Mixed | Panel mechanics are hard; panel presence is product-dependent |
22
22
  | Layers | Heuristic, then invariant | Enable only for real layer behavior; fully test when enabled |
@@ -28,35 +28,39 @@ Use this before writing a schema, spec, or implementation plan. It separates har
28
28
  | Acceptance | Invariant | Prove product observables, not only runtime mutation |
29
29
  | Performance | Mixed | Workload controls need workload budgets; ordinary controls need responsiveness coverage; animated previews yield to viewport interactions |
30
30
  | Persistence | Default, then invariant | State persistence must be explicit; localStorage apps must prove reload restoration |
31
- | Workflow | Invariant | Use required skills and browser verification |
31
+ | Workflow | Invariant | Follow signed local workflow, use available skills, and run browser verification |
32
32
 
33
- The runtime shell invariant means product routes render `ToolcraftApp` directly. Do not hand-compose `ToolcraftRoot`, `CanvasShell`, `ControlsPanel`, `TimelinePanel`, `LayersPanel`, or `ToolbarPanel`; those surfaces are shared runtime design, not app-specific implementation details. App-specific source also must not render built-in control components directly; schema controls and `controlRenderers` are the allowed control extension points.
33
+ The runtime shell invariant means product code exports the typed composition and does not edit the signed route. The host renders `ToolcraftApp`; product modules must not hand-compose `ToolcraftRoot`, `CanvasShell`, `ControlsPanel`, `TimelinePanel`, `LayersPanel`, or `ToolbarPanel`. App-specific source also must not render built-in control components directly; schema controls and `controlRenderers` are the allowed control extension points.
34
34
 
35
35
  ## Rule Catalog
36
36
 
37
37
  This catalog mirrors `TOOLCRAFT_DECISION_CONTRACT`. If runtime adds or renames a rule id, this page and `AGENTS.md` must list the same id.
38
38
 
39
+ [//]: # (toolcraft-contract:decision-rule-table:start)
39
40
  | Rule ID | Level | Area |
40
41
  | --- | --- | --- |
41
- | `runtime-shell-required` | Invariant | Runtime shell |
42
- | `canvas-no-app-ui` | Invariant | Canvas |
43
- | `canvas-surface-preserved` | Invariant | Canvas |
44
- | `canvas-handle-placement` | Heuristic | Canvas |
45
- | `panel-host-behavior` | Invariant | Panels |
46
- | `layers-enable-only-when-needed` | Heuristic | Layers |
47
- | `layers-enabled-behavior` | Invariant | Layers |
48
- | `timeline-mode-choice` | Heuristic | Timeline |
49
- | `timeline-enabled-behavior` | Invariant | Timeline |
50
- | `controls-product-coverage` | Invariant | Controls |
51
- | `output-export-required` | Invariant | Controls |
52
- | `controls-layout-heuristics` | Heuristic | Controls |
53
- | `renderer-technique-inventory` | Default | Renderer |
54
- | `video-reference-analysis` | Invariant | Reference analysis |
55
- | `reference-clone-source-of-truth` | Invariant | Reference clone |
56
- | `acceptance-product-observable` | Invariant | Acceptance |
57
- | `performance-coverage-levels` | Invariant | Performance |
58
- | `persistence-policy-explicit` | Default | Persistence |
59
- | `workflow-required` | Invariant | Workflow |
42
+ | `runtime-shell-required` | invariant | runtime-shell |
43
+ | `canvas-no-app-ui` | invariant | canvas |
44
+ | `canvas-surface-preserved` | invariant | canvas |
45
+ | `canvas-handle-placement` | heuristic | canvas |
46
+ | `panel-host-behavior` | invariant | panels |
47
+ | `layers-enable-only-when-needed` | heuristic | layers |
48
+ | `layers-enabled-behavior` | invariant | layers |
49
+ | `timeline-mode-choice` | heuristic | timeline |
50
+ | `timeline-enabled-behavior` | invariant | timeline |
51
+ | `controls-product-coverage` | invariant | controls |
52
+ | `output-export-required` | invariant | controls |
53
+ | `controls-section-inventory-required` | invariant | controls |
54
+ | `controls-component-layout-invariants` | invariant | controls |
55
+ | `controls-layout-heuristics` | heuristic | controls |
56
+ | `renderer-technique-inventory` | default | renderer |
57
+ | `reference-clone-source-of-truth` | invariant | reference-clone |
58
+ | `video-reference-analysis` | invariant | reference-analysis |
59
+ | `acceptance-product-observable` | invariant | acceptance |
60
+ | `performance-coverage-levels` | invariant | performance |
61
+ | `persistence-policy-explicit` | default | persistence |
62
+ | `workflow-required` | invariant | workflow |
63
+ [//]: # (toolcraft-contract:decision-rule-table:end)
60
64
 
61
65
  ## Enforcement
62
66
 
@@ -9,7 +9,9 @@ Performance coverage has two levels:
9
9
  - workload coverage for controls that change render cost;
10
10
  - responsiveness coverage for ordinary controls that still must not freeze input or break the viewport.
11
11
 
12
- The preferred browser performance runner is the current AI agent's controlled browser. Use `pnpm verify:perf` only as the Playwright fallback when no agent-controlled browser is available or in CI/non-agent automation.
12
+ `maxInteractionMs` measures user action start through the first verified product-output/state response for mutating interactions, not merely pointer completion. Generic change measurements first prove a stable pre-action baseline. A live drag may then cross that baseline while the gesture continues: the first changed response sets latency, then the final post-action outcome must remain different through its stability window before evidence is emitted. Autonomous or animated products use a stable semantic `expectedOutcome` or a deterministic fixed playback phase; the next unrelated frame cannot count as response. Settle/stability time after the first response is not charged as first-response latency. The helper uses one runner monotonic clock and restarts frame sampling after document navigation. Non-mutating interactions use action completion.
13
+
14
+ The preferred runner for targeted browser diagnosis is the current AI agent's controlled browser. The protected `pnpm verify:perf` Playwright checkpoint is the sole final machine authority that can record a passed current-source performance receipt.
13
15
 
14
16
  `app-performance.ts` must keep this policy:
15
17
 
@@ -21,7 +23,7 @@ browserCheckPolicy: {
21
23
  }
22
24
  ```
23
25
 
24
- Do not change the preferred runner to Playwright to make local automation easier; that reverses the contract. Playwright is portable fallback evidence, not the primary agent workflow.
26
+ Do not change the preferred runner to Playwright merely to avoid agent-controlled diagnosis; that policy governs targeted investigation. It does not authorize a manual passed receipt: final performance proof comes only from the protected `pnpm verify:perf` checkpoint.
25
27
 
26
28
  ## Workload Coverage
27
29
 
@@ -51,9 +53,9 @@ Both fixture types must include:
51
53
  - `reason`: why this value is the heaviest useful product case;
52
54
  - `value`: the actual value the browser performance check will apply.
53
55
 
54
- Fixtures that represent numeric maximums, density, item counts, canvas/media size, or custom combined heavy states also declare `loadProfile`. This separates the product `hardLimit` from the `smoothTarget` that the browser performance checkpoint guarantees. `hardLimit` is the largest product range or tier the app exposes; `smoothTarget` is the value the browser performance check applies and must match `stressFixture.value` or `workloadFixture.value`.
56
+ Fixtures that represent numeric maximums, density, item counts, canvas/media size, or custom combined heavy states also declare `loadProfile`. This separates the product `hardLimit` from the `smoothTarget` that the browser performance checkpoint guarantees. For bounded numeric controls, min/default/max and the hard limit are derived from schema; omit duplicated scenario `values`, or use `requireToolcraftSchemaPerformanceValues` when another fixture needs the same range. Supplied values must match schema exactly, and `metric: "custom"` cannot replace a numeric boundary. `smoothTarget` is the value the browser performance check applies and must match `stressFixture.value` or `workloadFixture.value`. A `many-items` fixture must apply at least 10 real items; an authored `minCount` cannot redefine a token fixture as heavy.
55
57
 
56
- Default to `smoothTargetRatio: 1`, which means the full hard limit must pass budgets. If the hard limit cannot pass after reasonable renderer and pipeline optimizations, lower the smooth target only in 10 percent steps (`0.9`, then `0.8`, and so on). Every lower step must include `loadProfile.evidence` with the failed higher target, measured result, optimization attempted, and decision. When `smoothTargetRatio < 1`, set `userFacingRange: "experimental-above-smooth"` so the range above the smooth target is not silently presented as guaranteed.
58
+ Default to `smoothTargetRatio: 1`, which means the full hard limit must pass budgets. If the hard limit cannot pass after reasonable renderer and pipeline optimizations, lower the smooth target only in 10 percent steps (`0.9`, then `0.8`, and so on). Every skipped higher step has exactly one `loadProfile.evidence` entry with the exact `attemptedRatio`, schema-reachable `attemptedTarget`, matching scenario id and target, measured result, optimization attempted, and decision. When `smoothTargetRatio < 1`, set `userFacingRange: "experimental-above-smooth"` so the range above the smooth target is not silently presented as guaranteed.
57
59
 
58
60
  For multiline text, prompt, code, JSON, CSS, shader, script, or template workload controls, use `kind: "large-text"`. The fixture must contain at least `50_000` characters and `1_000` lines unless the product has a stricter real-world maximum.
59
61
 
@@ -61,17 +63,24 @@ For uploaded images, videos, source media, and image-processing workloads, use `
61
63
 
62
64
  Choose heavy fixtures from this app's real controls, not from generic examples. Derive the workload from four app-specific sources: schema controls and `performanceRole`, `rendererTechnique`, `rendererPipeline`, and real product stress values such as large text, source media dimensions, `canvas.renderScale`, canvas size, export resolution, animation speed, viewport interactions, and effect strength. Try the product hard limit first, then use a documented smooth target only when measured evidence shows the hard limit cannot be made smooth without changing product scope.
63
65
 
64
- Browser performance tests for workload and stress scenarios must read the scenario value through:
66
+ Every `automatedTestName` and `browserTestName` must match exactly one product-owned test selected by the real Vitest or Playwright runner, and that test must finish passed. Comments, strings, local fake runners, focused/skipped tests, runtime skip/fixme/fail annotations, conditional declarations, and uncalled registration functions are not performance evidence.
67
+
68
+ Browser slider stress tests apply the declared value through the protected helper:
65
69
 
66
70
  ```ts
67
- getToolcraftPerformanceStressValue(appPerformance, "scenario-id")
71
+ await dragToolcraftSliderToPerformanceStressValue(
72
+ page,
73
+ "Control label",
74
+ appPerformance,
75
+ "scenario-id",
76
+ )
68
77
  ```
69
78
 
70
- For workload sliders, the fallback Playwright test uses `dragToolcraftSliderToPerformanceStressValue(page, label, appPerformance, "scenario-id")` so the test applies the exact numeric value through the real slider min/max range. Agent-browser checks must apply the same value from `app-performance.ts`. Do not divide a stress value by the slider max, type a separate short value, or hardcode a runner-local ratio. If a browser check uses a toy value while `app-performance.ts` claims a heavy fixture, the performance checkpoint must fail.
79
+ For non-slider scalar values, use `applyToolcraftPerformanceStressValue` with `{ applyValue, observeValue }`. The helper reads the exact scenario value and emits stress evidence only after `observeValue` equals that declared value. Agent-browser checks must apply the same value from `app-performance.ts`. Do not divide a stress value by the slider max, type a separate short value, hardcode a runner-local ratio, or claim application without observing the resulting UI/runtime state.
71
80
 
72
81
  Slider and range slider performance scenarios must preserve live product feedback. The browser test should drag the real thumb and verify the canvas/product output changes during drag. If that drag misses budget, keep the live control semantics and optimize the renderer path first: cache expensive inputs, update uniforms or stable buffers, coalesce preview work to `requestAnimationFrame`, cancel stale async renders, move work off React renders, reuse GPU resources, or change renderer strategy. Do not pass performance by making the slider update only after pointer release or Apply.
73
82
 
74
- When a scenario declares `workloadFixture`, apply it first with `getToolcraftPerformanceWorkloadValue` or `applyToolcraftPerformanceWorkloadFixture`, then apply `stressFixture`, then measure. A control-drag scenario that only sets its own slider value while leaving the source media, text, item count, render scale, or dense scene at defaults is invalid.
83
+ When a scenario declares `workloadFixture`, apply it first with `applyToolcraftPerformanceWorkloadValue` or `applyToolcraftPerformanceWorkloadFixture`, then apply `stressFixture`, then measure. A control-drag scenario that only sets its own slider value while leaving the source media, text, item count, render scale, or dense scene at defaults is invalid.
75
84
 
76
85
  For combined worst cases, put every relevant independent baseline value in `workloadFixture.value` for control scenarios, such as `{ sourceMedia: { width: 3840, height: 2160 }, renderScale: 2 }`, and put the tested control value in `stressFixture.value`. For preview, zoom, drag, animation, or export scenarios that stress the entire state instead of one control, use `stressFixture.value`, such as `{ detail: 96, scale: 0.6, renderScale: 2 }`. Testing workload controls one-by-one is not enough when the product exposes combinations that multiply render cost.
77
86
 
@@ -79,16 +88,24 @@ Use `kind: "custom"` only for combined object fixtures. Single numeric/string he
79
88
 
80
89
  ```ts
81
90
  await applyToolcraftPerformanceStressFixture(page, appPerformance, "scenario-id", {
82
- detail: async (value) => {
83
- await dragToolcraftSliderToValue(page, "Detail", Number(value));
91
+ detail: {
92
+ applyValue: async (value) => {
93
+ await dragToolcraftSliderToValue(page, "Detail", Number(value));
94
+ },
95
+ observeValue: async () =>
96
+ Number(await page.getByRole("slider", { name: "Detail" }).getAttribute("aria-valuenow")),
84
97
  },
85
- scale: async (value) => {
86
- await dragToolcraftSliderToValue(page, "Scale", Number(value));
98
+ scale: {
99
+ applyValue: async (value) => {
100
+ await dragToolcraftSliderToValue(page, "Scale", Number(value));
101
+ },
102
+ observeValue: async () =>
103
+ Number(await page.getByRole("slider", { name: "Scale" }).getAttribute("aria-valuenow")),
87
104
  },
88
105
  });
89
106
  ```
90
107
 
91
- The applier object must contain exactly one entry for each key in `stressFixture.value`. Missing keys and stale extra keys are test failures, so every heavy-state part is intentionally mapped through the real UI before measurement.
108
+ The applier object contains exactly one entry for each key in `stressFixture.value`, and each entry provides both `applyValue` and `observeValue`. Missing keys, stale extra keys, or an observed value that differs from the declared fixture are test failures, so every heavy-state part is proved through the real UI before measurement.
92
109
 
93
110
  For `workloadFixture.value` object fixtures, use `applyToolcraftPerformanceWorkloadFixture` with the same exact-key rule. `workloadFixture` is the app baseline; `stressFixture` is the action under test.
94
111
 
@@ -155,6 +172,15 @@ Use real interactions for:
155
172
  - `viewport-zoom-stress` for detail-heavy or animated custom renderers;
156
173
  - `viewport-stability`.
157
174
 
175
+ Every `export-copy` scenario declares `actionValue` with the exact `panelActions`
176
+ value, `controlLabel` for its visible button, and `completionEvidence` set to
177
+ `download` or `clipboard`. Its browser test uses the corresponding protected
178
+ `measureToolcraftDownloadActionByLabel` or
179
+ `measureToolcraftClipboardActionByLabel` helper with `scenarioId`. The helper
180
+ owns the real click and completion event; the signed runtime-evidence reporter
181
+ rejects missing completion, skipped/failed tests, and evidence from failed
182
+ retries.
183
+
158
184
  For `slider` and `rangeSlider`, the required performance scenario is `control-drag`. A `control-change` scenario can cover selects, inputs, toggles, and other non-drag controls, but it does not prove live canvas feedback or drag smoothness for sliders.
159
185
 
160
186
  Animated custom renderers also need `animation-viewport-drag`. Animation-only frame sampling and viewport-only stability are not enough: the browser test must sample frames while physically dragging or panning the canvas viewport. If SVG/DOM cannot pass that combined budget, choose a different renderer strategy from evidence instead of loosening the budget.
@@ -167,16 +193,16 @@ During canvas drag, pan, pinch, zoom, and radar/center interactions, animated pr
167
193
 
168
194
  Animation checks should sample enough frames to catch jank. Interaction budgets must match scenario type rather than using one universal number.
169
195
 
170
- Use `app-performance.ts` as the single budget and fixture source. Browser performance tests must call `getToolcraftPerformanceStressValue(appPerformance, scenarioId)` for workload values and `expectToolcraftScenarioPerformanceBudget(..., appPerformance, scenarioId)` for budgets.
196
+ Use `app-performance.ts` as the single budget and fixture source. Mutating measurements pass `scenarioId` and a structured-cloneable `observeOutcome`; generic change mode proves a stable baseline before the action, its first changed response sets latency, and its final post-action outcome must remain different through the stability window. For autonomous output, pass `expectedOutcome` and observe a stable semantic state, or fix playback to a deterministic phase; latency is measured to that expected result. Scalar fixtures are applied and observed through `applyToolcraftPerformanceStressValue` / `applyToolcraftPerformanceWorkloadValue`; object fixtures use `applyToolcraftPerformanceStressFixture` / `applyToolcraftPerformanceWorkloadFixture`, apply every declared key, then re-observe the complete final state before evidence can attach. Budget checks await `expectToolcraftScenarioPerformanceBudget`. Completed measurements are frozen and branded for one scenario, so a mutable literal or another scenario's result cannot satisfy the gate.
171
197
 
172
- Run targeted performance scenarios for Tier 3 performance-sensitive edits when they directly exercise the touched workload, viewport, or export path. The default `pnpm test:browser` / `pnpm verify:ui` gate excludes every Playwright test whose name contains `browser perf:`, including the performance audit and budget scenarios. The full performance checkpoint prefers the current AI agent's controlled browser. `pnpm verify:perf` is the Playwright fallback suite; it runs every `browser perf:` scenario with one worker so budget failures are not hidden or created by unrelated parallel browser tests.
198
+ Run targeted performance scenarios for Tier 3 performance-sensitive edits when they directly exercise the touched workload, viewport, or export path. The default `pnpm test:browser` / `pnpm verify:ui` gate excludes every Playwright test whose name contains `browser perf:`, including the performance audit and budget scenarios. Use the current AI agent's controlled browser for targeted diagnosis. `pnpm verify:perf` is the protected final Playwright checkpoint; it builds the current production bundle, serves it through Vite preview, and runs every `browser perf:` scenario with one worker so budgets measure shipped runtime work instead of dev-server transformation and are not distorted by unrelated parallel browser tests.
173
199
 
174
200
  Run a full performance checkpoint only when:
175
201
 
176
202
  - the first working version of the app exists;
177
203
  - the user explicitly asks to optimize performance, fix lag, remove jank, speed up animation, stabilize drag/zoom, or otherwise complains about performance.
178
204
 
179
- For the first working product app, this checkpoint is mandatory: the app is not complete until `pnpm verify:final` and the browser performance checkpoint have both passed and the worklog records the runner as `agent-browser` or `playwright-fallback`. Use `pnpm verify:perf` only as the fallback when no agent-controlled browser is available or in CI/non-agent automation.
205
+ For the first working product app, this checkpoint is mandatory and runs before `pnpm verify:final`. Run `pnpm verify:perf`; its protected Playwright runner records the current-source machine receipt automatically. Agent-controlled browser checks remain preferred for quick diagnosis and visual investigation, but they cannot mint or replace the final receipt. The final gate rejects a missing or stale receipt. Worklog prose remains decision context and cannot substitute for the structured receipt. A post-first-working non-performance exemption must use `pnpm verify:perf:record-exemption -- --tier=<0|1|2>` and requires a prior passed receipt.
180
206
 
181
207
  Performance fixes must preserve selected output and preview quality. Do not pass budgets by lowering image quality, selected `canvas.renderScale`, export resolution, source media fidelity, or canvas backing pixels unless the user explicitly chooses that lower-quality value through a visible control. Prefer coalescing slider updates, caching expensive inputs, moving work off the React render path, reusing GPU resources, or changing renderer strategy over reducing visual fidelity.
182
208
 
@@ -87,6 +87,10 @@ Common control fields:
87
87
  | `description` | Product-specific help text only when it adds meaning beyond the label. |
88
88
  | `visibleWhen` | Mode/type/source/include/variant/count visibility. Hidden values are preserved. |
89
89
  | `orderRole` | Makes section order testable. |
90
+ | `semanticGroup` | Language-independent product sub-entity/workflow grouping, required on every control in sections larger than seven controls. |
91
+ | `sliderValueKind` | `slider` intent: `"continuous"` or `"discrete"`. |
92
+ | `textValueKind` | `text`/`code` intent: `"single-line"`, `"multiline"`, or `"structured"`. |
93
+ | `curveIntent` | `curves` composition: `"single-value-map"` or `"color-channels"`. |
90
94
  | `performanceRole` | `"workload"` or `"responsiveness"` for coverage derivation. |
91
95
  | `performanceReason` | Why the role fits this app. |
92
96
  | `commitMode` | `text` controls: `"content"` applies while typing, `"setting"` commits on blur/Enter. |
@@ -101,30 +105,35 @@ Reserved runtime targets include `runtime.settingsTransfer`, `canvas.aspectRatio
101
105
 
102
106
  ## Built-In Control Types
103
107
 
104
- | `type` | Renders |
108
+ [//]: # (toolcraft-contract:built-in-control-table:start)
109
+ | `type` | Runtime visual owner |
105
110
  | --- | --- |
106
- | `actions` | Local section commands in 50% button cells. |
107
- | `anchorGrid` | Anchor picker. |
108
- | `channelMixer` | RGB channel mixer. |
109
- | `checkbox` | Checkbox field. |
110
- | `collectionActions` | Add/remove controls for growable runtime-backed item lists. |
111
- | `code` | Multiline editor for long or structured content. |
112
- | `color` | Hex color picker. |
113
- | `colorOpacity` | Hex color plus opacity. |
114
- | `curves` | Single or RGB curve editor. |
115
- | `fileDrop` | Image/file upload, multiple upload, sorting, and image transforms. |
116
- | `fontPicker` | Atomic typography block: font, weight, size, case, color/opacity, letter spacing, line height. |
117
- | `gradient` | Gradient type, angle, track, stops. |
118
- | `imagePicker` | Visual option picker. |
119
- | `palette` | Design-token palette family + shade. |
120
- | `rangeInput` | Two compact text values. |
121
- | `rangeSlider` | Two-thumb slider. |
122
- | `segmented` | Full-width compact finite choice. |
123
- | `select` | Dropdown. |
124
- | `slider` | Single-value slider. |
125
- | `switch` | Binary switch. |
126
- | `text` | Single-line input. |
127
- | `vector` | X/Y vector pad and fields. |
111
+ | `aspectRatio` | `CanvasAspectRatioControl` |
112
+ | `slider` | `Slider` |
113
+ | `rangeSlider` | `RangeSlider` |
114
+ | `text` | `TextInput` |
115
+ | `rangeInput` | `RangeInput` |
116
+ | `code` | `CodeTextarea` |
117
+ | `select` | `Select` |
118
+ | `segmented` | `Segmented` |
119
+ | `switch` | `Switch` |
120
+ | `checkbox` | `Checkbox` |
121
+ | `actions` | `Actions` |
122
+ | `collectionActions` | `CollectionActions` |
123
+ | `panelActions` | `PanelActions` |
124
+ | `colorOpacity` | `ColorOpacity` |
125
+ | `palette` | `Palette` |
126
+ | `vector` | `Vector` |
127
+ | `color` | `Color` |
128
+ | `gradient` | `Gradient` |
129
+ | `fontPicker` | `FontPicker` |
130
+ | `curves` | `Curves` |
131
+ | `anchorGrid` | `AnchorGrid` |
132
+ | `channelMixer` | `ChannelMixer` |
133
+ | `fileDrop` | `FileDrop` |
134
+ | `imagePicker` | `ImagePicker` |
135
+ | `settingsTransfer` | `SettingsTransfer` |
136
+ [//]: # (toolcraft-contract:built-in-control-table:end)
128
137
 
129
138
  Use `component-rules.md` for component-specific fit, labels, variants, units, parser behavior, and exceptions. Use `core/control-selection.md` before deciding a custom control is needed.
130
139
 
@@ -146,6 +155,8 @@ export const starterControlSectionInventory = [
146
155
 
147
156
  Every product control target appears exactly once in the inventory. Runtime `Setup`, sticky footer `Export`, settings transfer, and runtime canvas sizing targets do not need entries.
148
157
 
158
+ For sections larger than seven controls, each control also declares `semanticGroup`. Controls editing one tightly scoped product sub-entity share the same value; mixed groups make a broad section fail and should be split. This fact is structural and may not be inferred from English labels.
159
+
149
160
  ## Transfer Metadata
150
161
 
151
162
  Reference and motion metadata lives in `starterTransferMode`.
@@ -17,24 +17,30 @@ Before planning or editing app code, runtime code, controls, canvas, panels, ren
17
17
 
18
18
  Do not edit implementation files until this preflight is complete.
19
19
 
20
- Core modules are required reading when listed by the routing table. Read each listed module fully. Do not rely on a truncated terminal excerpt; reopen the specific module or use a narrower range when a tool output is clipped.
20
+ ## Local Contract Authority
21
+
22
+ The signed local `AGENTS.md` plus `docs/toolcraft/*` are sufficient and mandatory workflow input for a standalone generated app. External workflow skills should be used when available, but missing skills never invalidate `--no-skills` generation and never justify skipping the equivalent local spec, plan, debugging, browser, or verification requirement. `pnpm ai:check` enforces local code health and reports missing external skills as actionable guidance rather than a build failure.
23
+
24
+ Core modules are required reading when listed by the routing table. Read each listed module fully, one phase at a time. Open exactly one listed document per terminal or tool read, even when several documents belong to the same route and phase. Do not concatenate documents or rely on a truncated excerpt; finish the current phase, then open the next phase when the work reaches it. The signed host and runtime validators enforce platform boundaries, while product organization remains open inside those boundaries.
21
25
 
22
26
  ## Task Routing
23
27
 
24
- Use the smallest reading set that covers the changed surface. If a task touches multiple surfaces, combine every matching row instead of picking only the closest one.
25
-
26
- | Task type | Read before editing |
27
- | --- | --- |
28
- | App assembly, route structure, generated app porting | `core/runtime-boundary.md`, `assembly-workflow.md`, `decision-contract.md` |
29
- | Reference app study, audit, or port | `core/reference-study.md`, `core/runtime-boundary.md`, `assembly-workflow.md`, `schema-reference.md`, `acceptance-testing.md`, `decision-contract.md` |
30
- | Schema, controls, defaults, persistence, actions | `core/control-selection.md`, `core/layout.md`, `schema-reference.md`, `component-rules.md`, `acceptance-testing.md` |
31
- | Custom controls | `core/control-selection.md`, `core/layout.md`, `custom-controls.md`, `component-rules.md`, `acceptance-testing.md` |
32
- | Renderer, canvas output, visual technique | `core/runtime-boundary.md`, `core/performance.md`, `renderer-technique.md`, `performance.md`, `acceptance-testing.md` |
33
- | Timeline, keyframes, animation transport | `core/timeline-animation.md`, `core/performance.md`, `decision-contract.md`, `component-rules.md`, `acceptance-testing.md` |
34
- | Layers | `core/runtime-boundary.md`, `core/layout.md`, `decision-contract.md`, `component-rules.md`, `acceptance-testing.md` |
35
- | Export, copy, media, background | `core/setup-export.md`, `core/media-upload.md`, `schema-reference.md`, `component-rules.md`, `acceptance-testing.md`, `performance.md` |
36
- | Broken control, visual mismatch, failed build, export bug, performance issue | `decision-contract.md`, the relevant `core/*` module, the relevant component/runtime doc, and the failing test/log first |
37
- | Figma implementation | Use Figma MCP/design context, then `core/reference-study.md`, `core/runtime-boundary.md`, `assembly-workflow.md`, and the relevant component docs |
28
+ Use the smallest route set that covers the changed surface. When a task matches multiple routes, process them sequentially inside the phase currently in progress and skip documents already read in that phase; open each document separately and never concatenate route documents into one terminal output. Read Plan documents before the spec or implementation plan, Implementation documents immediately before code, and Verification documents immediately before writing or running proof. A broken behavior still starts with the failing test, log, or reproduction before its Plan documents; a Figma task still starts with Figma MCP/design context.
29
+
30
+ [//]: # (toolcraft-workflow-routes:start)
31
+ | Task route | Plan phase | Implementation phase | Verification phase |
32
+ | --- | --- | --- | --- |
33
+ | App assembly, route structure, generated app porting | `core/runtime-boundary.md`<br>`assembly-workflow.md` | `decision-contract.md` | `acceptance-testing.md` |
34
+ | Reference app study, audit, or port | `core/reference-study.md`<br>`core/runtime-boundary.md`<br>`assembly-workflow.md` | `schema-reference.md`<br>`decision-contract.md` | `acceptance-testing.md` |
35
+ | Schema, controls, defaults, persistence, actions | `core/control-selection.md`<br>`core/layout.md` | `schema-reference.md`<br>`component-rules.md` | `acceptance-testing.md` |
36
+ | Custom controls | `core/control-selection.md`<br>`core/layout.md` | `custom-controls.md`<br>`component-rules.md` | `acceptance-testing.md` |
37
+ | Renderer, canvas output, visual technique | `core/runtime-boundary.md`<br>`core/performance.md` | `renderer-technique.md`<br>`performance.md` | `acceptance-testing.md` |
38
+ | Timeline, keyframes, animation transport | `core/timeline-animation.md`<br>`core/performance.md` | `decision-contract.md`<br>`component-rules.md` | `acceptance-testing.md` |
39
+ | Layers | `core/runtime-boundary.md`<br>`core/layout.md` | `decision-contract.md`<br>`component-rules.md` | `acceptance-testing.md` |
40
+ | Export, copy, media, background | `core/setup-export.md`<br>`core/media-upload.md` | `schema-reference.md`<br>`component-rules.md` | `acceptance-testing.md`<br>`performance.md` |
41
+ | Broken control, visual mismatch, failed build, export bug, performance issue | `decision-contract.md`<br>`core/runtime-boundary.md` | `component-rules.md`<br>`renderer-technique.md` | `acceptance-testing.md`<br>`performance.md` |
42
+ | Figma implementation | `core/reference-study.md`<br>`core/runtime-boundary.md`<br>`assembly-workflow.md` | `schema-reference.md`<br>`component-rules.md` | `acceptance-testing.md` |
43
+ [//]: # (toolcraft-workflow-routes:end)
38
44
 
39
45
  ## Worklog Gate
40
46
 
@@ -70,6 +76,8 @@ Use the runtime extension points described in the current contracts:
70
76
 
71
77
  Do not recreate controls, panels, toolbar, timeline, layers, canvas shell, or runtime surfaces by hand. If a shared behavior is wrong, fix the shared runtime/template source and regenerate when needed.
72
78
 
79
+ Browser verification is outcome-based. Protected helpers attach versioned evidence only after a persistent observable change, an observed fixture application, a decoded non-empty export inspection, a completed output action, an immutable scenario measurement, and its matching budget check. The signed reporter derives required evidence from acceptance and performance config and fails skipped, missing, duplicate, transient, unmeasured, or unbudgeted scenarios.
80
+
73
81
  ## Verification Gate
74
82
 
75
83
  Choose the tier from `AGENTS.md` before editing. Use the tier to decide checks.
@@ -77,7 +85,7 @@ Choose the tier from `AGENTS.md` before editing. Use the tier to decide checks.
77
85
  - Tier 0-1: targeted docs/typecheck/unit plus focused browser when visual.
78
86
  - Tier 2: `pnpm verify:quick` plus relevant browser acceptance.
79
87
  - Tier 3: `pnpm verify:quick`, targeted browser acceptance, and targeted performance scenarios only for touched workload/viewport/export paths.
80
- - Tier 4: `pnpm verify:final`; for the first working product version also run and pass a browser performance checkpoint with the current AI agent's controlled browser when available, using `pnpm verify:perf` only as fallback, then start `pnpm dev` for the local URL.
88
+ - Tier 4: run `node scripts/check-toolcraft-integrity.mjs` directly. For the first working product version, run the browser performance checkpoint and record its current-source receipt first, then run `pnpm verify:final`, then start `pnpm dev` for the local URL.
81
89
 
82
90
  Run a full performance checkpoint only when:
83
91
 
@@ -86,4 +94,4 @@ Run a full performance checkpoint only when:
86
94
 
87
95
  Fast feature loops after the first working version do not run the full performance suite by default. Renderer, canvas, animation, export, timeline, layers, `canvas.renderScale`, bug fixes, and performance-sensitive controls still need targeted functional/browser checks first, plus targeted performance scenarios only when they directly exercise the touched path. Record any skipped full performance run and reason in the worklog.
88
96
 
89
- The app is not complete when required checks are failed, incomplete, pending, blocked, or listed as skipped. First working product delivery must record `pnpm verify:final` and the browser performance checkpoint as passed in the worklog, including runner `agent-browser` or `playwright-fallback`. After the first working version, skipping the full performance suite is valid only when the worklog explicitly says the full performance checkpoint is not required for a post-first-working non-performance edit.
97
+ The app is not complete when required checks are failed, incomplete, pending, blocked, or listed as skipped. Run the integrity checker directly before the final gate so verification does not depend only on mutable package-script dispatch. First working product delivery runs `pnpm verify:perf` before `pnpm verify:final`; the protected Playwright checkpoint records the machine receipt, while agent-controlled browser work remains targeted diagnostic evidence. `verify:final` rejects missing or stale receipts. After the first working version, use the typed `pnpm verify:perf:record-exemption -- --tier=<0|1|2>` path only for a post-first-working non-performance edit backed by a prior passed receipt.
@@ -0,0 +1,111 @@
1
+ import { expect, test, type TestInfo } from "@playwright/test";
2
+
3
+ import { expectToolcraftAcceptanceOutcome, expectToolcraftExportedArtifact } from "./browser-acceptance-outcome-helpers";
4
+
5
+ test("acceptance outcome rejects a return to its baseline during stability sampling", async () => {
6
+ let actionStarted = false;
7
+ let postActionObservations = 0;
8
+
9
+ await expect(
10
+ expectToolcraftAcceptanceOutcome(
11
+ async () => {
12
+ if (!actionStarted) return "before";
13
+ postActionObservations += 1;
14
+ return postActionObservations === 1 ? "after" : "before";
15
+ },
16
+ async () => {
17
+ actionStarted = true;
18
+ },
19
+ {
20
+ evidenceType: "command-side-effect",
21
+ requirementId: "command.delayed-transient",
22
+ stabilityIntervalMs: 0,
23
+ },
24
+ ),
25
+ ).rejects.toThrow(/stability window/i);
26
+ });
27
+
28
+ test("acceptance outcome snapshots a reused mutable observation", async ({}) => {
29
+ const outcome = { value: "before" };
30
+
31
+ await expect(
32
+ expectToolcraftAcceptanceOutcome(
33
+ async () => outcome,
34
+ async () => {
35
+ outcome.value = "after";
36
+ },
37
+ {
38
+ evidenceType: "command-side-effect",
39
+ requirementId: "command.mutable-observation",
40
+ stabilityIntervalMs: 0,
41
+ },
42
+ ),
43
+ ).resolves.toEqual({ value: "after" });
44
+ });
45
+
46
+ test("generic acceptance outcomes cannot claim specialized runtime evidence", async ({
47
+ page,
48
+ }) => {
49
+ await page.setContent('<div id="outcome">before</div>');
50
+
51
+ await expect(
52
+ expectToolcraftAcceptanceOutcome(
53
+ () => page.locator("#outcome").textContent(),
54
+ () =>
55
+ page.locator("#outcome").evaluate((node) => {
56
+ node.textContent = "after";
57
+ }),
58
+ {
59
+ evidenceType: "timeline-duration" as never,
60
+ requirementId: "timeline.duration",
61
+ },
62
+ ),
63
+ ).rejects.toThrow(/specialized evidence/i);
64
+ });
65
+
66
+ test("export evidence requires a typed positive artifact inspection", async ({}, testInfo: TestInfo) => {
67
+ const attachmentCount = testInfo.attachments.length;
68
+
69
+ await expect(
70
+ expectToolcraftExportedArtifact(
71
+ async () => new Uint8Array([1, 2, 3]),
72
+ async () => ({ ok: true }),
73
+ { requirementId: "export.nominal-object" },
74
+ ),
75
+ ).rejects.toThrow(/byteLength/i);
76
+ await expect(
77
+ expectToolcraftExportedArtifact(
78
+ async () => new Uint8Array([1, 2, 3]),
79
+ async () => ({ byteLength: 0 }),
80
+ { requirementId: "export.zero-bytes" },
81
+ ),
82
+ ).rejects.toThrow(/positive byteLength/i);
83
+ await expect(
84
+ expectToolcraftExportedArtifact(
85
+ async () => new Uint8Array([1, 2, 3]),
86
+ async () => ({ byteLength: 2.5 }),
87
+ { requirementId: "export.fractional-bytes" },
88
+ ),
89
+ ).rejects.toThrow(/byteLength integer/i);
90
+ await expect(
91
+ expectToolcraftExportedArtifact(
92
+ async () => new Uint8Array([1, 2, 3]),
93
+ async () => ({ byteLength: 3, width: 1.5 }),
94
+ { requirementId: "export.fractional-width" },
95
+ ),
96
+ ).rejects.toThrow(/width integer/i);
97
+ expect(testInfo.attachments).toHaveLength(attachmentCount);
98
+
99
+ await expectToolcraftExportedArtifact(
100
+ async () => new Uint8Array([1, 2, 3]),
101
+ async (artifact) => ({
102
+ byteLength: artifact.byteLength,
103
+ contentHash: "pixel-hash",
104
+ height: 1,
105
+ mediaType: "image/png",
106
+ width: 1,
107
+ }),
108
+ { requirementId: "export.valid-inspection" },
109
+ );
110
+ expect(testInfo.attachments).toHaveLength(attachmentCount + 1);
111
+ });