@pixel-point/toolcraft 0.0.16 → 0.0.18

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 (313) hide show
  1. package/package.json +1 -1
  2. package/src/generate-performance-iteration-execution.test.mjs +2 -2
  3. package/src/generate-test-demand-only-lifecycle.mjs +14 -3
  4. package/src/generate-test-dependency-sandbox.mjs +42 -5
  5. package/src/generate-test-doc-assertions.mjs +109 -69
  6. package/src/generate-test-doc-assertions.test.mjs +65 -0
  7. package/src/generate-test-doc-policy-assertions.mjs +92 -0
  8. package/src/generate-test-file-assertions.mjs +36 -118
  9. package/src/generate-test-output-assertions.mjs +95 -0
  10. package/src/generate-test-package-assertions.mjs +6 -0
  11. package/src/generate-test-performance-boundary-assertions.mjs +45 -0
  12. package/src/generate-test-product-fixture.mjs +1 -0
  13. package/src/generate-test-product-fixture.test.mjs +18 -0
  14. package/src/generate-test-product-iteration.mjs +1 -0
  15. package/src/generate-test-product-iteration.test.mjs +18 -0
  16. package/src/generate-test-runtime-boundary-assertions.mjs +158 -0
  17. package/src/generate-test-standalone-assertions.mjs +10 -0
  18. package/src/generate-test-standalone-delivery-stages.mjs +14 -6
  19. package/src/generate.test.mjs +14 -0
  20. package/templates/runtime/contracts/component-contracts.choices.test.ts +59 -12
  21. package/templates/runtime/contracts/component-contracts.choices.ts +58 -12
  22. package/templates/runtime/contracts/component-contracts.inputs.test.ts +6 -6
  23. package/templates/runtime/contracts/component-contracts.inputs.ts +6 -6
  24. package/templates/runtime/contracts/component-contracts.media-custom.test.ts +8 -2
  25. package/templates/runtime/contracts/component-contracts.media-custom.ts +8 -2
  26. package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +21 -6
  27. package/templates/runtime/contracts/component-contracts.runtime-labels.test.ts +7 -1
  28. package/templates/runtime/contracts/component-contracts.runtime-panels.test.ts +4 -1
  29. package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +4 -1
  30. package/templates/runtime/contracts/component-contracts.runtime.ts +15 -10
  31. package/templates/runtime/contracts/component-contracts.test.ts +2 -0
  32. package/templates/runtime/contracts/decision-contracts.test.ts +43 -4
  33. package/templates/runtime/contracts/decision-contracts.ts +10 -10
  34. package/templates/runtime/contracts/performance-verification-policy.test.ts +59 -6
  35. package/templates/runtime/contracts/performance-verification-policy.ts +5 -2
  36. package/templates/runtime/export/artifact-download.test.ts +71 -0
  37. package/templates/runtime/export/artifact-download.ts +80 -0
  38. package/templates/runtime/export/artifact-export-request.ts +23 -0
  39. package/templates/runtime/export/artifact-export-settings.test.ts +75 -0
  40. package/templates/runtime/export/artifact-export-settings.ts +96 -0
  41. package/templates/runtime/export/artifact-frame-renderer.test.ts +107 -0
  42. package/templates/runtime/export/artifact-frame-renderer.ts +96 -0
  43. package/templates/runtime/export/artifact-frame-state.test.ts +54 -0
  44. package/templates/runtime/export/artifact-frame-state.ts +44 -0
  45. package/templates/runtime/export/artifact-scene-frame.test.ts +84 -0
  46. package/templates/runtime/export/artifact-scene-frame.ts +118 -0
  47. package/templates/runtime/export/export-background.ts +46 -0
  48. package/templates/runtime/export/export-error.ts +43 -0
  49. package/templates/runtime/export/export.test.ts +49 -226
  50. package/templates/runtime/export/image-artifact-export.test.ts +111 -0
  51. package/templates/runtime/export/image-artifact-export.ts +145 -0
  52. package/templates/runtime/export/index.ts +44 -3
  53. package/templates/runtime/export/product-export-renderer.test.ts +77 -0
  54. package/templates/runtime/export/product-export-renderer.ts +63 -0
  55. package/templates/runtime/export/video-artifact-export.test.ts +166 -0
  56. package/templates/runtime/export/video-artifact-export.ts +164 -0
  57. package/templates/runtime/export/video-encoding-backend.ts +124 -0
  58. package/templates/runtime/export/video-encoding-policy.test.ts +68 -0
  59. package/templates/runtime/export/video-encoding-policy.ts +86 -0
  60. package/templates/runtime/export/video-frame-schedule.test.ts +58 -0
  61. package/templates/runtime/export/video-frame-schedule.ts +42 -0
  62. package/templates/runtime/index.ts +3 -0
  63. package/templates/runtime/model-import/model-import-limits.ts +15 -4
  64. package/templates/runtime/react/app-shell/runtime-public-api-runtime.test.tsx +291 -0
  65. package/templates/runtime/react/app-shell/runtime-public-api-test-support.ts +21 -0
  66. package/templates/runtime/react/app-shell/runtime-public-api.test.tsx +15 -304
  67. package/templates/runtime/react/app-shell/toolcraft-app.scene-export.test.tsx +41 -27
  68. package/templates/runtime/react/app-shell/toolcraft-app.tsx +39 -11
  69. package/templates/runtime/react/app-shell/toolcraft-source-asset-context.test.tsx +16 -57
  70. package/templates/runtime/react/app-shell/toolcraft-source-asset-context.tsx +75 -434
  71. package/templates/runtime/react/app-shell/toolcraft-source-asset-owner.test.ts +194 -0
  72. package/templates/runtime/react/app-shell/toolcraft-source-asset-owner.ts +227 -0
  73. package/templates/runtime/react/app-shell/toolcraft-source-asset-provider-ownership.test.tsx +243 -0
  74. package/templates/runtime/react/app-shell/toolcraft-source-asset-test-support.ts +51 -0
  75. package/templates/runtime/react/app-shell/toolcraft-unavailable-resource-proof.test.ts +138 -0
  76. package/templates/runtime/react/app-shell/toolcraft-unavailable-resource-proof.ts +378 -0
  77. package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +76 -0
  78. package/templates/runtime/react/canvas/canvas-shell-test-utils.tsx +13 -1
  79. package/templates/runtime/react/canvas/canvas-shell.tsx +16 -1
  80. package/templates/runtime/react/canvas/product-scene-surface.test.tsx +195 -0
  81. package/templates/runtime/react/canvas/product-scene-surface.tsx +155 -0
  82. package/templates/runtime/react/canvas/runtime-scene-export.ts +1 -1
  83. package/templates/runtime/react/controls-panel/__tests__/control-conditions.test.ts +61 -0
  84. package/templates/runtime/react/controls-panel/__tests__/controls-panel.collection-actions.test.tsx +89 -0
  85. package/templates/runtime/react/controls-panel/__tests__/controls-panel.control-visibility.test.tsx +40 -19
  86. package/templates/runtime/react/controls-panel/__tests__/controls-panel.footer-actions.test.tsx +7 -12
  87. package/templates/runtime/react/controls-panel/__tests__/controls-panel.scene-export-actions.test.tsx +18 -84
  88. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-collection.test.tsx +62 -0
  89. package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-color-bank.test.tsx +67 -0
  90. package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +43 -87
  91. package/templates/runtime/react/controls-panel/actions/export-action-runner.ts +68 -0
  92. package/templates/runtime/react/controls-panel/conditions/control-conditions.ts +32 -119
  93. package/templates/runtime/react/controls-panel/layout/controls-panel-control-group.tsx +5 -2
  94. package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +10 -8
  95. package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +3 -3
  96. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-item-fields.test.tsx +63 -0
  97. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-item-fields.tsx +138 -0
  98. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-items.tsx +104 -0
  99. package/templates/runtime/react/controls-panel/renderers/controls-panel-collection-renderer.tsx +115 -236
  100. package/templates/runtime/react/controls-panel/renderers/controls-panel-file-drop-item-controls.test.tsx +95 -0
  101. package/templates/runtime/react/controls-panel/renderers/controls-panel-file-drop-item-controls.tsx +82 -0
  102. package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.test.tsx +73 -1
  103. package/templates/runtime/react/controls-panel/renderers/controls-panel-media-renderer.tsx +50 -1
  104. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.test.ts +1 -1
  105. package/templates/runtime/react/controls-panel/renderers/controls-panel-renderer-registry.ts +2 -1
  106. package/templates/runtime/react/controls-panel/values/controls-panel-collection-values.ts +38 -6
  107. package/templates/runtime/react/controls-panel/values/controls-panel-value-labels.ts +1 -0
  108. package/templates/runtime/react/index.ts +4 -0
  109. package/templates/runtime/react/model-rendering/model-export.ts +1 -1
  110. package/templates/runtime/react/orientation-gizmo/orientation-gizmo-selection.ts +5 -5
  111. package/templates/runtime/react/orientation-gizmo/use-toolcraft-orientation-control-selection.ts +2 -2
  112. package/templates/runtime/react/panel-host/panel-host-runtime-placement.test.tsx +30 -0
  113. package/templates/runtime/react/panel-host/panel-host.tsx +4 -0
  114. package/templates/runtime/scene/scene-bounds.test.ts +23 -0
  115. package/templates/runtime/scene/scene-bounds.ts +32 -19
  116. package/templates/runtime/schema/app-capabilities.test.ts +4 -0
  117. package/templates/runtime/schema/canvas-render-scale.ts +62 -0
  118. package/templates/runtime/schema/collection-item-controls.ts +29 -0
  119. package/templates/runtime/schema/control-applicability.test.ts +127 -0
  120. package/templates/runtime/schema/control-applicability.ts +433 -0
  121. package/templates/runtime/schema/control-schema-normalization.ts +177 -11
  122. package/templates/runtime/schema/controls-panel-actions.ts +2 -2
  123. package/templates/runtime/schema/controls-panel-section-id.test.ts +1 -1
  124. package/templates/runtime/schema/controls-panel-section-layout.ts +14 -9
  125. package/templates/runtime/schema/controls-panel-section-roundtrip.test.ts +62 -3
  126. package/templates/runtime/schema/define-toolcraft.collection-actions-item-controls.test.ts +127 -0
  127. package/templates/runtime/schema/define-toolcraft.control-sections.test.ts +10 -4
  128. package/templates/runtime/schema/define-toolcraft.file-drop-item-controls.test.ts +98 -0
  129. package/templates/runtime/schema/define-toolcraft.file-drop-normalization.test.ts +27 -0
  130. package/templates/runtime/schema/define-toolcraft.segmented-control-fit.test.ts +20 -2
  131. package/templates/runtime/schema/define-toolcraft.setup-background.test.ts +1 -1
  132. package/templates/runtime/schema/define-toolcraft.setup-canvas.test.ts +16 -3
  133. package/templates/runtime/schema/define-toolcraft.setup-render-scale-timeline.test.ts +71 -3
  134. package/templates/runtime/schema/define-toolcraft.source-collection.test.ts +79 -0
  135. package/templates/runtime/schema/define-toolcraft.ts +1 -1
  136. package/templates/runtime/schema/runtime-setup-section.ts +24 -5
  137. package/templates/runtime/schema/schema-resolvers.ts +0 -56
  138. package/templates/runtime/schema/types.ts +72 -17
  139. package/templates/runtime/state/canvas-background-state.ts +6 -0
  140. package/templates/runtime/testing/performance-render-plan-integration.test.ts +64 -0
  141. package/templates/runtime/testing/performance-renderer-pipeline-validation.ts +18 -1
  142. package/templates/starter/AGENTS.md +18 -15
  143. package/templates/starter/NOTICE.md +6 -0
  144. package/templates/starter/docs/toolcraft/README.md +2 -1
  145. package/templates/starter/docs/toolcraft/acceptance-testing.md +23 -35
  146. package/templates/starter/docs/toolcraft/agent-worklog.md +18 -3
  147. package/templates/starter/docs/toolcraft/assembly-workflow.md +13 -5
  148. package/templates/starter/docs/toolcraft/component-rules.md +8 -6
  149. package/templates/starter/docs/toolcraft/core/control-selection.md +9 -3
  150. package/templates/starter/docs/toolcraft/core/layout.md +7 -7
  151. package/templates/starter/docs/toolcraft/core/media-upload.md +4 -2
  152. package/templates/starter/docs/toolcraft/core/performance.md +14 -3
  153. package/templates/starter/docs/toolcraft/core/runtime-boundary.md +16 -3
  154. package/templates/starter/docs/toolcraft/core/setup-export.md +49 -19
  155. package/templates/starter/docs/toolcraft/core/timeline-animation.md +4 -4
  156. package/templates/starter/docs/toolcraft/custom-controls.md +6 -4
  157. package/templates/starter/docs/toolcraft/decision-contract.md +3 -1
  158. package/templates/starter/docs/toolcraft/performance.md +20 -6
  159. package/templates/starter/docs/toolcraft/renderer-technique.md +5 -1
  160. package/templates/starter/docs/toolcraft/schema-reference.md +23 -25
  161. package/templates/starter/docs/toolcraft/workflow.md +7 -2
  162. package/templates/starter/e2e/app-browser-control-applicability-requirements.spec.ts +163 -0
  163. package/templates/starter/e2e/app-browser-control-coverage.spec.ts +33 -0
  164. package/templates/starter/e2e/app-browser-infinity-canvas-evidence.spec.ts +50 -3
  165. package/templates/starter/e2e/app-browser-orientation-evidence.spec.ts +174 -21
  166. package/templates/starter/e2e/app-browser-render-scale-evidence.spec.ts +60 -6
  167. package/templates/starter/e2e/app-browser-render-scale-requirements.spec.ts +77 -1
  168. package/templates/starter/e2e/app-browser-runtime-provenance.spec.ts +8 -0
  169. package/templates/starter/e2e/app-browser-runtime-reporter.spec.ts +35 -0
  170. package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +5 -34
  171. package/templates/starter/e2e/app-browser-semantic-evidence.spec.ts +61 -16
  172. package/templates/starter/e2e/app-browser-shell.spec.ts +13 -5
  173. package/templates/starter/e2e/app-performance-path-adapters.ts +8 -1
  174. package/templates/starter/e2e/app-performance.spec.ts +16 -9
  175. package/templates/starter/e2e/{browser-conditional-output-evidence-helpers.ts → browser-background-output-evidence.ts} +0 -68
  176. package/templates/starter/e2e/browser-control-applicability-evidence.ts +114 -0
  177. package/templates/starter/e2e/browser-infinity-canvas-evidence.ts +29 -341
  178. package/templates/starter/e2e/browser-infinity-canvas-unavailable-image-evidence.ts +370 -0
  179. package/templates/starter/e2e/browser-media-export-evidence.spec.ts +77 -0
  180. package/templates/starter/e2e/browser-media-export-evidence.ts +208 -0
  181. package/templates/starter/e2e/browser-orientation-gizmo-evidence-helpers.ts +4 -0
  182. package/templates/starter/e2e/browser-orientation-gizmo-live-preconditions.ts +86 -0
  183. package/templates/starter/e2e/browser-render-scale-evidence.ts +37 -29
  184. package/templates/starter/e2e/browser-runtime-applicability-requirements.ts +84 -0
  185. package/templates/starter/e2e/browser-runtime-evidence-reporter.ts +13 -3
  186. package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +72 -35
  187. package/templates/starter/e2e/browser-semantic-evidence-test-helpers.ts +25 -0
  188. package/templates/starter/e2e/browser-standard-timeline-evidence.ts +106 -0
  189. package/templates/starter/e2e/decoded-pixel-observation.spec.ts +74 -0
  190. package/templates/starter/e2e/decoded-pixel-observation.ts +227 -0
  191. package/templates/starter/e2e/export-artifact-helpers.ts +206 -25
  192. package/templates/starter/e2e/image-artifact-inspection.spec.ts +41 -0
  193. package/templates/starter/e2e/image-artifact-inspection.ts +99 -0
  194. package/templates/starter/e2e/performance-canvas-helpers.ts +22 -21
  195. package/templates/starter/e2e/performance-canvas-quality-guard.spec.ts +312 -0
  196. package/templates/starter/e2e/performance-canvas-quality-guard.ts +196 -0
  197. package/templates/starter/e2e/performance-canvas-quality-observer.ts +351 -0
  198. package/templates/starter/e2e/performance-control-layout-helpers.ts +2 -2
  199. package/templates/starter/e2e/performance-path-adapter-contract.ts +4 -4
  200. package/templates/starter/e2e/performance-path-helpers.spec.ts +203 -70
  201. package/templates/starter/e2e/performance-path-helpers.ts +210 -91
  202. package/templates/starter/e2e/performance-pipeline-evidence-continuity.spec.ts +76 -0
  203. package/templates/starter/e2e/performance-pipeline-evidence-test-fixtures.ts +11 -2
  204. package/templates/starter/e2e/performance-pipeline-invariants.ts +47 -4
  205. package/templates/starter/e2e/performance-render-scale-runner.spec.ts +140 -38
  206. package/templates/starter/e2e/video-artifact-inspection.spec.ts +64 -0
  207. package/templates/starter/e2e/video-artifact-inspection.ts +281 -0
  208. package/templates/starter/gitignore +1 -0
  209. package/templates/starter/package.json +1 -0
  210. package/templates/starter/scripts/check-toolcraft-docs.mjs +17 -0
  211. package/templates/starter/scripts/toolcraft-contract-manifest.json +1 -0
  212. package/templates/starter/scripts/toolcraft-delivery-plan-authority.test.mjs +60 -0
  213. package/templates/starter/scripts/toolcraft-delivery-plan-errors.test.mjs +7 -2
  214. package/templates/starter/scripts/toolcraft-delivery-plan.mjs +7 -3
  215. package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +95 -103
  216. package/templates/starter/scripts/toolcraft-product-boundary-module-policy.mjs +101 -0
  217. package/templates/starter/scripts/toolcraft-product-boundary.mjs +12 -0
  218. package/templates/starter/scripts/toolcraft-product-boundary.test.mjs +0 -26
  219. package/templates/starter/scripts/toolcraft-product-control-bindings.mjs +182 -0
  220. package/templates/starter/scripts/toolcraft-product-control-boundary.mjs +146 -0
  221. package/templates/starter/scripts/toolcraft-product-control-boundary.test.mjs +186 -0
  222. package/templates/starter/scripts/toolcraft-product-evidence-boundary.test.mjs +85 -20
  223. package/templates/starter/scripts/toolcraft-product-evidence-import-policy.mjs +43 -0
  224. package/templates/starter/scripts/toolcraft-product-export-boundary.mjs +157 -0
  225. package/templates/starter/scripts/toolcraft-product-export-boundary.test.mjs +196 -0
  226. package/templates/starter/scripts/toolcraft-typescript-analysis.d.mts +73 -0
  227. package/templates/starter/scripts/toolcraft-typescript-source-evidence-structure.test.mjs +20 -0
  228. package/templates/starter/scripts/toolcraft-typescript-source-evidence.mjs +1 -0
  229. package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade-test-helpers.mjs +318 -0
  230. package/templates/starter/scripts/toolcraft-unavailable-resource-evidence-facade.test.mjs +157 -206
  231. package/templates/starter/scripts/toolcraft-verification-inventory.mjs +1 -0
  232. package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +51 -0
  233. package/templates/starter/scripts/toolcraft-vite-env-activation.test.mjs +128 -59
  234. package/templates/starter/src/app/acceptance/artifact-export-intent.ts +130 -0
  235. package/templates/starter/src/app/acceptance/conditions.ts +1 -1
  236. package/templates/starter/src/app/acceptance/control-acceptance-context.ts +2 -2
  237. package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +6 -20
  238. package/templates/starter/src/app/acceptance/control-acceptance-kind-rules.ts +24 -5
  239. package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +2 -13
  240. package/templates/starter/src/app/acceptance/control-applicability-cases.test.ts +321 -0
  241. package/templates/starter/src/app/acceptance/control-applicability-cases.ts +290 -0
  242. package/templates/starter/src/app/acceptance/control-applicability.ts +332 -0
  243. package/templates/starter/src/app/acceptance/control-layout-dependency-rules.ts +20 -9
  244. package/templates/starter/src/app/acceptance/control-layout-entity-rules.ts +4 -6
  245. package/templates/starter/src/app/acceptance/control-layout-model.ts +4 -4
  246. package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +3 -10
  247. package/templates/starter/src/app/acceptance/control-parts.ts +8 -0
  248. package/templates/starter/src/app/acceptance/control-section-entity-cohesion.test.ts +215 -0
  249. package/templates/starter/src/app/acceptance/control-section-entity-cohesion.ts +132 -0
  250. package/templates/starter/src/app/acceptance/control-section-inventory.test.ts +87 -0
  251. package/templates/starter/src/app/acceptance/control-section-inventory.ts +74 -44
  252. package/templates/starter/src/app/acceptance/custom-controls.ts +11 -3
  253. package/templates/starter/src/app/acceptance/export-artifact-coverage.ts +113 -0
  254. package/templates/starter/src/app/acceptance/inline-layout.ts +64 -9
  255. package/templates/starter/src/app/acceptance/media-upload.ts +5 -1
  256. package/templates/starter/src/app/acceptance/orientation-gizmo.ts +18 -11
  257. package/templates/starter/src/app/acceptance/output-background-rules.ts +2 -2
  258. package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +18 -10
  259. package/templates/starter/src/app/acceptance/output-export-model.ts +54 -11
  260. package/templates/starter/src/app/acceptance/output-export.ts +35 -12
  261. package/templates/starter/src/app/acceptance/output-video-export-rules.ts +99 -0
  262. package/templates/starter/src/app/acceptance/types.ts +30 -8
  263. package/templates/starter/src/app/acceptance/validate-coverage.ts +20 -2
  264. package/templates/starter/src/app/starter-acceptance.artifact-export-intent.test.ts +239 -0
  265. package/templates/starter/src/app/starter-acceptance.background-export.test.ts +33 -0
  266. package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +16 -1
  267. package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +65 -0
  268. package/templates/starter/src/app/starter-acceptance.contract-fixtures.test.ts +41 -0
  269. package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +112 -16
  270. package/templates/starter/src/app/starter-acceptance.control-applicability.test.ts +224 -0
  271. package/templates/starter/src/app/starter-acceptance.control-order.test.ts +58 -3
  272. package/templates/starter/src/app/starter-acceptance.control-state.test.ts +0 -111
  273. package/templates/starter/src/app/starter-acceptance.custom-control-collections.test.ts +3 -1
  274. package/templates/starter/src/app/starter-acceptance.custom-control-valid.test.ts +1 -1
  275. package/templates/starter/src/app/starter-acceptance.export-artifact.test.ts +131 -0
  276. package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +22 -0
  277. package/templates/starter/src/app/{starter-acceptance.image-video-export-settings.test.ts → starter-acceptance.image-export-settings.test.ts} +37 -9
  278. package/templates/starter/src/app/starter-acceptance.interaction-ownership.test.ts +12 -0
  279. package/templates/starter/src/app/starter-acceptance.keyframes.test.ts +14 -4
  280. package/templates/starter/src/app/starter-acceptance.media-upload.fixtures.ts +11 -1
  281. package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +28 -0
  282. package/templates/starter/src/app/starter-acceptance.output-export-intent.test.ts +384 -0
  283. package/templates/starter/src/app/starter-acceptance.output-export-rules.test.ts +46 -1
  284. package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +112 -105
  285. package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +12 -0
  286. package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +1 -1
  287. package/templates/starter/src/app/starter-acceptance.section-dependencies.test.ts +35 -24
  288. package/templates/starter/src/app/starter-acceptance.section-size.test.ts +72 -0
  289. package/templates/starter/src/app/starter-acceptance.ts +13 -2
  290. package/templates/starter/src/app/starter-acceptance.video-export-settings.test.ts +336 -0
  291. package/templates/starter/src/app/starter-acceptance.view-interaction.test.ts +8 -0
  292. package/templates/starter/src/app/starter-performance-test-utils.ts +103 -0
  293. package/templates/starter/src/app/starter-performance.gates.test.ts +231 -278
  294. package/templates/starter/src/app/starter-performance.lifecycle.test.ts +261 -0
  295. package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +4 -2
  296. package/templates/starter/src/routes/index.tsx +2 -0
  297. package/templates/ui/components/composites/tabs.tsx +2 -2
  298. package/templates/ui/components/controls/collection-actions/collection-item-groups.test.tsx +38 -0
  299. package/templates/ui/components/controls/collection-actions/collection-item-groups.tsx +36 -0
  300. package/templates/ui/components/controls/collection-actions/index.ts +2 -0
  301. package/templates/ui/components/controls/file-drop/file-drop-collection-control.tsx +137 -0
  302. package/templates/ui/components/controls/file-drop/file-drop-control.test.tsx +189 -0
  303. package/templates/ui/components/controls/file-drop/file-drop-control.tsx +81 -88
  304. package/templates/ui/components/controls/file-drop/file-drop-presentation.tsx +131 -9
  305. package/templates/ui/components/controls/file-drop/file-drop-types.ts +36 -22
  306. package/templates/ui/components/controls/file-drop/index.ts +1 -0
  307. package/templates/ui/components/controls/index.ts +3 -0
  308. package/templates/ui/components/controls/range-slider/range-slider-control.tsx +1 -1
  309. package/templates/ui/components/controls/range-slider/range-slider-value.test.ts +14 -0
  310. package/templates/ui/components/controls/range-slider/range-slider-value.ts +3 -2
  311. package/templates/runtime/export/export.ts +0 -166
  312. package/templates/starter/src/app/acceptance/condition-exclusivity.test.ts +0 -60
  313. package/templates/starter/src/app/acceptance/condition-exclusivity.ts +0 -221
@@ -239,6 +239,66 @@ test("creates a changed authorized iteration with exact affected proof", () => {
239
239
  assert.equal(getToolcraftDeliveryDiagnosticTier(plan), 3);
240
240
  });
241
241
 
242
+ test("creates an authorized iteration for a passless viewport path", () => {
243
+ const passlessPathId =
244
+ "performance-path:%5B%22interactive-continuous%22%2C%22viewport-drag%22%2C%5B%5D%2C%5B%5D%2C%5B%5D%5D";
245
+ const testName = `browser perf: toolcraft path ${passlessPathId}`;
246
+ const source = {
247
+ heading: "Delivery 2 - Slow viewport drag",
248
+ pathIds: [passlessPathId],
249
+ request: "The canvas is slow while panning.",
250
+ requestEvidence: "The canvas is slow while panning.",
251
+ };
252
+ const planningInputs = inputs({
253
+ requestAuthority: {
254
+ hash: createToolcraftPerformanceRequestAuthorityHash(source),
255
+ ...source,
256
+ },
257
+ });
258
+ planningInputs.catalog = {
259
+ ...catalog,
260
+ performance: [{ passIds: [], pathId: passlessPathId, testName }],
261
+ };
262
+ planningInputs.changeSet.impact.performanceCandidates = {
263
+ passIds: [],
264
+ pathIds: [passlessPathId],
265
+ testNames: [testName],
266
+ };
267
+
268
+ const plan = createToolcraftDeliveryPlan(planningInputs);
269
+
270
+ assert.equal(plan.kind, "performance-iteration");
271
+ assert.deepEqual(
272
+ plan.steps.find(({ kind }) => kind === "browser-performance"),
273
+ {
274
+ kind: "browser-performance",
275
+ passIds: [],
276
+ pathIds: [passlessPathId],
277
+ testNames: [testName],
278
+ },
279
+ );
280
+ });
281
+
282
+ test("keeps performance-adapter-only changes functional without inferred measurement", () => {
283
+ const planningInputs = inputs();
284
+ planningInputs.changeSet.impact = {
285
+ acceptanceIds: [],
286
+ browserTestNames: [],
287
+ buildRequired: false,
288
+ performanceCandidates: {
289
+ passIds: ["preview-composite"],
290
+ pathIds: [pathId],
291
+ testNames: [performanceTestName],
292
+ },
293
+ productTestFiles: [],
294
+ };
295
+
296
+ const plan = createToolcraftDeliveryPlan(planningInputs);
297
+
298
+ assert.equal(plan.kind, "functional");
299
+ assert.deepEqual(plan.steps, [{ kind: "code-health" }]);
300
+ });
301
+
242
302
  test("rejects malformed basis and functional performance proof", () => {
243
303
  const valid = createToolcraftDeliveryPlan(inputs());
244
304
  for (const basis of [
@@ -203,14 +203,19 @@ test("rejects malformed catalogs and inconsistent exact impact relations", () =>
203
203
  }
204
204
  });
205
205
 
206
- test("performance impact cannot omit functional acceptance proof", () => {
206
+ test("impact cannot omit both functional and performance proof", () => {
207
207
  const value = inputs();
208
208
  value.changeSet.impact.acceptanceIds = [];
209
209
  value.changeSet.impact.browserTestNames = [];
210
210
  value.changeSet.impact.productTestFiles = [];
211
+ value.changeSet.impact.performanceCandidates = {
212
+ passIds: [],
213
+ pathIds: [],
214
+ testNames: [],
215
+ };
211
216
  assert.throws(
212
217
  () => createToolcraftDeliveryPlan(value),
213
- /functional proof/iu,
218
+ /functional or performance proof/iu,
214
219
  );
215
220
  });
216
221
 
@@ -124,8 +124,9 @@ function impactError(impact, catalog, allTests) {
124
124
  impact.acceptanceIds.includes(row.acceptanceId));
125
125
  const performance = catalog.performance.filter((row) =>
126
126
  impact.performanceCandidates.pathIds.includes(row.pathId));
127
- if (!impact.browserTestNames.length && !impact.productTestFiles.length)
128
- return "Verification impact does not select functional proof.";
127
+ if (!impact.browserTestNames.length && !impact.productTestFiles.length &&
128
+ !impact.performanceCandidates.pathIds.length)
129
+ return "Verification impact does not select functional or performance proof.";
129
130
  if (acceptance.length !== impact.acceptanceIds.length ||
130
131
  !same(acceptance.map((row) => row.testName).sort(compare), impact.browserTestNames) ||
131
132
  performance.length !== impact.performanceCandidates.pathIds.length ||
@@ -227,7 +228,10 @@ function stepError(step) {
227
228
  if (step.kind === "dependencies" && !managers.has(step.packageManager))
228
229
  return "Dependency proof has an invalid package manager.";
229
230
  const badTarget = ["files", "testNames", "pathIds", "passIds"].find((key) =>
230
- Object.hasOwn(step, key) && !targets(step[key], { paths: key === "files" }));
231
+ Object.hasOwn(step, key) && !targets(step[key], {
232
+ empty: step.kind === "browser-performance" && key === "passIds",
233
+ paths: key === "files",
234
+ }));
231
235
  if (badTarget)
232
236
  return `Delivery proof ${badTarget} must be nonempty, sorted, and unique.`;
233
237
  }
@@ -1,11 +1,15 @@
1
- import path from "node:path";
2
-
3
1
  import ts from "typescript";
4
2
 
5
3
  import {
6
4
  builtInControlExportNames,
7
5
  runtimeSurfaceComponentNames,
8
6
  } from "./toolcraft-integrity-policy.mjs";
7
+ import {
8
+ createToolcraftProductExportInspector,
9
+ isForbiddenToolcraftRuntimeExport,
10
+ } from "./toolcraft-product-export-boundary.mjs";
11
+ import { createToolcraftProductControlInspector } from "./toolcraft-product-control-boundary.mjs";
12
+ import { getToolcraftSensitiveModuleKind } from "./toolcraft-product-boundary-module-policy.mjs";
9
13
  import { inspectToolcraftProductStyleNode } from "./toolcraft-product-style-boundary.mjs";
10
14
 
11
15
  const runtimeSurfaceNames = new Set(runtimeSurfaceComponentNames);
@@ -18,82 +22,9 @@ const runtimeModelPresentationInternalNames = new Set([
18
22
  "useToolcraftModelRenderHost",
19
23
  ]);
20
24
 
21
- function toPosixPath(value) {
22
- return value.split(path.sep).join("/");
23
- }
24
-
25
- function resolveSpecifierPath(sourceFilePath, moduleSpecifier, rootDir) {
26
- if (moduleSpecifier.startsWith("@/") || moduleSpecifier.startsWith("#/")) {
27
- return toPosixPath(path.resolve(rootDir, "src", moduleSpecifier.slice(2)));
28
- }
29
- if (moduleSpecifier.startsWith("/")) {
30
- return toPosixPath(path.resolve(rootDir, moduleSpecifier.slice(1)));
31
- }
32
- if (moduleSpecifier.startsWith(".")) {
33
- return toPosixPath(path.resolve(path.dirname(sourceFilePath), moduleSpecifier));
34
- }
35
- return null;
36
- }
37
-
38
- function getSensitiveModuleKind(sourceFilePath, moduleSpecifier, rootDir) {
39
- const normalizedSpecifier = moduleSpecifier.replaceAll("\\", "/");
40
- const resolvedSpecifier = resolveSpecifierPath(
41
- sourceFilePath,
42
- normalizedSpecifier,
43
- rootDir,
44
- );
45
-
46
- if (
47
- /^@repo\/toolcraft-runtime\/react\/model-rendering(?:\/|$)/u.test(
48
- normalizedSpecifier,
49
- ) ||
50
- /^[#@]\/toolcraft\/runtime\/react\/model-rendering(?:\/|$)/u.test(
51
- normalizedSpecifier,
52
- ) ||
53
- resolvedSpecifier?.includes("/src/toolcraft/runtime/react/model-rendering")
54
- ) {
55
- return "runtime-model-presentation";
56
- }
57
-
58
- if (
59
- /^three\/(?:addons|examples\/jsm)\/loaders(?:\/|$)/u.test(
60
- normalizedSpecifier,
61
- ) ||
62
- /^@gltf-transform(?:\/|$)/u.test(normalizedSpecifier) ||
63
- /^@repo\/toolcraft-runtime\/model-import(?:\/|$)/u.test(
64
- normalizedSpecifier,
65
- ) ||
66
- /^[#@]\/toolcraft\/runtime\/model-import(?:\/|$)/u.test(
67
- normalizedSpecifier,
68
- ) ||
69
- resolvedSpecifier?.includes("/src/toolcraft/runtime/model-import")
70
- ) {
71
- return "runtime-model-import";
72
- }
73
-
74
- if (
75
- /^@repo\/toolcraft-runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
76
- /^[#@]\/toolcraft\/runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
77
- resolvedSpecifier?.includes("/src/toolcraft/runtime/react")
78
- ) {
79
- return "runtime-react";
80
- }
81
-
82
- if (
83
- /^@repo\/ui(?:\/controls(?:\/|$)|$)/u.test(normalizedSpecifier) ||
84
- /^[#@]\/toolcraft\/ui(?:\/components\/controls(?:\/|$)|\/controls(?:\/|$)|$)/u.test(
85
- normalizedSpecifier,
86
- ) ||
87
- resolvedSpecifier?.includes("/src/toolcraft/ui/components/controls") ||
88
- /\/src\/toolcraft\/ui$/u.test(resolvedSpecifier ?? "")
89
- ) {
90
- return "ui-controls";
91
- }
92
-
93
- return null;
94
- }
95
-
96
25
  function isForbiddenNamedExport(moduleKind, importedName) {
26
+ if (moduleKind === "ui-control-implementation") return true;
27
+ if (isForbiddenToolcraftRuntimeExport(moduleKind)) return true;
97
28
  if (
98
29
  moduleKind === "runtime-model-import" ||
99
30
  moduleKind === "runtime-model-presentation"
@@ -106,6 +37,42 @@ function isForbiddenNamedExport(moduleKind, importedName) {
106
37
  importedName !== "createControlHistoryGroupId");
107
38
  }
108
39
 
40
+ function getImportViolationKind(moduleKind, importedName) {
41
+ switch (moduleKind) {
42
+ case "runtime-export-mechanics":
43
+ return "runtime-export-ownership";
44
+ case "runtime-model-presentation":
45
+ return "runtime-model-presentation-ownership";
46
+ case "runtime-react":
47
+ return runtimeModelPresentationInternalNames.has(importedName)
48
+ ? "runtime-model-presentation-ownership"
49
+ : "runtime-surface";
50
+ case "runtime-model-import":
51
+ return "runtime-model-import-ownership";
52
+ case "ui-control-implementation":
53
+ return "built-in-control-implementation";
54
+ default:
55
+ return "built-in-control";
56
+ }
57
+ }
58
+
59
+ function getViolationMessage(kind, subject, moduleSpecifier) {
60
+ switch (kind) {
61
+ case "runtime-export-ownership":
62
+ return `Product source must not own artifact encoding, recording, or download mechanics${subject} from ${moduleSpecifier}. Declare exportRenderer and let runtime export actions encode and download the artifact.`;
63
+ case "runtime-surface":
64
+ return `Product source must not import or re-export host-owned runtime surface${subject} from ${moduleSpecifier}. Use ToolcraftAppComposition, schema, canvasContent, controlRenderers, onPanelAction, and runtime commands.`;
65
+ case "runtime-model-presentation-ownership":
66
+ return `Product source must not import raw model render hosts or standard model canvas internals${subject} from ${moduleSpecifier}. Declare modelPresentation and use useToolcraftModelPresentationConsumer for visible custom model output.`;
67
+ case "runtime-model-import-ownership":
68
+ return `Product source must not import or re-export model loaders, topology/repair infrastructure, or runtime model-import internals${subject} from ${moduleSpecifier}. Declare a model fileDrop in schema and use the runtime-owned import, analysis, repair, persistence, preview, and export pipeline.`;
69
+ case "built-in-control-implementation":
70
+ return `Product source must not import or re-export a deep control implementation${subject} from ${moduleSpecifier}. Use the public schema control instead of copying or composing its private mechanics.`;
71
+ default:
72
+ return `Product source must not import or re-export built-in control${subject} from ${moduleSpecifier}. Declare it through schema or justify a true custom controlRenderer.`;
73
+ }
74
+ }
75
+
109
76
  function createViolation({
110
77
  getNodeLocation,
111
78
  importedName,
@@ -116,24 +83,17 @@ function createViolation({
116
83
  sourceFile,
117
84
  }) {
118
85
  const subject = importedName ? ` ${importedName}` : "";
119
- const message =
120
- kind === "runtime-surface"
121
- ? `Product source must not import or re-export host-owned runtime surface${subject} from ${moduleSpecifier}. Use ToolcraftAppComposition, schema, canvasContent, controlRenderers, onPanelAction, and runtime commands.`
122
- : kind === "runtime-model-presentation-ownership"
123
- ? `Product source must not import raw model render hosts or standard model canvas internals${subject} from ${moduleSpecifier}. Declare modelPresentation and use useToolcraftModelPresentationConsumer for visible custom model output.`
124
- : kind === "runtime-model-import-ownership"
125
- ? `Product source must not import or re-export model loaders, topology/repair infrastructure, or runtime model-import internals${subject} from ${moduleSpecifier}. Declare a model fileDrop in schema and use the runtime-owned import, analysis, repair, persistence, preview, and export pipeline.`
126
- : `Product source must not import or re-export built-in control${subject} from ${moduleSpecifier}. Declare it through schema or justify a true custom controlRenderer.`;
127
86
  return {
128
87
  ...getNodeLocation(sourceFile, node),
129
88
  kind,
130
- message,
89
+ message: getViolationMessage(kind, subject, moduleSpecifier),
131
90
  repoPath,
132
91
  };
133
92
  }
134
93
 
135
94
  export function inspectToolcraftProductSource({
136
95
  absolutePath,
96
+ checker,
137
97
  getNodeLocation,
138
98
  repoPath,
139
99
  resolveStaticString,
@@ -141,6 +101,18 @@ export function inspectToolcraftProductSource({
141
101
  sourceFile,
142
102
  }) {
143
103
  const violations = [];
104
+ const inspectExportMechanics = createToolcraftProductExportInspector({
105
+ getNodeLocation,
106
+ repoPath,
107
+ sourceFile,
108
+ });
109
+ const inspectControls = createToolcraftProductControlInspector({
110
+ checker,
111
+ getNodeLocation,
112
+ repoPath,
113
+ resolveStaticString,
114
+ sourceFile,
115
+ });
144
116
 
145
117
  function report(node, moduleSpecifier, moduleKind, importedName) {
146
118
  if (importedName && !isForbiddenNamedExport(moduleKind, importedName)) {
@@ -150,16 +122,7 @@ export function inspectToolcraftProductSource({
150
122
  createViolation({
151
123
  getNodeLocation,
152
124
  importedName,
153
- kind:
154
- moduleKind === "runtime-model-presentation"
155
- ? "runtime-model-presentation-ownership"
156
- : moduleKind === "runtime-react"
157
- ? runtimeModelPresentationInternalNames.has(importedName)
158
- ? "runtime-model-presentation-ownership"
159
- : "runtime-surface"
160
- : moduleKind === "runtime-model-import"
161
- ? "runtime-model-import-ownership"
162
- : "built-in-control",
125
+ kind: getImportViolationKind(moduleKind, importedName),
163
126
  moduleSpecifier,
164
127
  node,
165
128
  repoPath,
@@ -169,7 +132,25 @@ export function inspectToolcraftProductSource({
169
132
  }
170
133
 
171
134
  function getModuleKind(moduleSpecifier) {
172
- return getSensitiveModuleKind(absolutePath, moduleSpecifier, rootDir);
135
+ return getToolcraftSensitiveModuleKind({
136
+ moduleSpecifier,
137
+ rootDir,
138
+ sourceFilePath: absolutePath,
139
+ });
140
+ }
141
+
142
+ function inspectModuleSpecifier(node, moduleSpecifier) {
143
+ const moduleKind = getModuleKind(moduleSpecifier);
144
+ if (!moduleKind) return null;
145
+ if (moduleKind === "ui-control-implementation") {
146
+ report(node, moduleSpecifier, moduleKind);
147
+ return null;
148
+ }
149
+ if (isForbiddenToolcraftRuntimeExport(moduleKind)) {
150
+ report(node, moduleSpecifier, moduleKind);
151
+ return null;
152
+ }
153
+ return moduleKind;
173
154
  }
174
155
 
175
156
  function visit(node) {
@@ -180,6 +161,8 @@ export function inspectToolcraftProductSource({
180
161
  resolveStaticString,
181
162
  sourceFile,
182
163
  }),
164
+ ...inspectExportMechanics(node),
165
+ ...inspectControls.inspectNode(node),
183
166
  );
184
167
 
185
168
  if (
@@ -187,7 +170,7 @@ export function inspectToolcraftProductSource({
187
170
  ts.isStringLiteralLike(node.moduleSpecifier)
188
171
  ) {
189
172
  const moduleSpecifier = node.moduleSpecifier.text;
190
- const moduleKind = getModuleKind(moduleSpecifier);
173
+ const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
191
174
  const importClause = node.importClause;
192
175
 
193
176
  if (moduleKind && importClause && !importClause.isTypeOnly) {
@@ -216,7 +199,7 @@ export function inspectToolcraftProductSource({
216
199
  ts.isStringLiteralLike(node.moduleSpecifier)
217
200
  ) {
218
201
  const moduleSpecifier = node.moduleSpecifier.text;
219
- const moduleKind = getModuleKind(moduleSpecifier);
202
+ const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
220
203
 
221
204
  if (moduleKind && !node.isTypeOnly) {
222
205
  if (!node.exportClause || ts.isNamespaceExport(node.exportClause)) {
@@ -238,14 +221,23 @@ export function inspectToolcraftProductSource({
238
221
 
239
222
  if (
240
223
  ts.isImportEqualsDeclaration(node) &&
241
- !node.isTypeOnly &&
242
224
  ts.isExternalModuleReference(node.moduleReference) &&
243
225
  node.moduleReference.expression &&
244
226
  ts.isStringLiteralLike(node.moduleReference.expression)
245
227
  ) {
246
228
  const moduleSpecifier = node.moduleReference.expression.text;
247
- const moduleKind = getModuleKind(moduleSpecifier);
248
- if (moduleKind) report(node, moduleSpecifier, moduleKind);
229
+ const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
230
+ if (moduleKind && !node.isTypeOnly) {
231
+ report(node, moduleSpecifier, moduleKind);
232
+ }
233
+ }
234
+
235
+ if (
236
+ ts.isImportTypeNode(node) &&
237
+ ts.isLiteralTypeNode(node.argument) &&
238
+ ts.isStringLiteralLike(node.argument.literal)
239
+ ) {
240
+ inspectModuleSpecifier(node, node.argument.literal.text);
249
241
  }
250
242
 
251
243
  if (
@@ -266,7 +258,7 @@ export function inspectToolcraftProductSource({
266
258
  ts.forEachChild(node, visit);
267
259
  return;
268
260
  }
269
- const moduleKind = getModuleKind(moduleSpecifier);
261
+ const moduleKind = inspectModuleSpecifier(node, moduleSpecifier);
270
262
  if (moduleKind) report(node, moduleSpecifier, moduleKind);
271
263
  }
272
264
 
@@ -0,0 +1,101 @@
1
+ import path from "node:path";
2
+
3
+ import {
4
+ getToolcraftProductExportModuleKind,
5
+ } from "./toolcraft-product-export-boundary.mjs";
6
+ import {
7
+ isToolcraftPrivateControlImplementationModule,
8
+ } from "./toolcraft-product-control-boundary.mjs";
9
+
10
+ function toPosixPath(value) {
11
+ return value.split(path.sep).join("/");
12
+ }
13
+
14
+ function resolveSpecifierPath(sourceFilePath, moduleSpecifier, rootDir) {
15
+ if (moduleSpecifier.startsWith("@/") || moduleSpecifier.startsWith("#/")) {
16
+ return toPosixPath(path.resolve(rootDir, "src", moduleSpecifier.slice(2)));
17
+ }
18
+ if (moduleSpecifier.startsWith("/")) {
19
+ return toPosixPath(path.resolve(rootDir, moduleSpecifier.slice(1)));
20
+ }
21
+ if (moduleSpecifier.startsWith(".")) {
22
+ return toPosixPath(path.resolve(path.dirname(sourceFilePath), moduleSpecifier));
23
+ }
24
+ return null;
25
+ }
26
+
27
+ export function getToolcraftSensitiveModuleKind({
28
+ moduleSpecifier,
29
+ rootDir,
30
+ sourceFilePath,
31
+ }) {
32
+ const normalizedSpecifier = moduleSpecifier.replaceAll("\\", "/");
33
+ const resolvedSpecifier = resolveSpecifierPath(
34
+ sourceFilePath,
35
+ normalizedSpecifier,
36
+ rootDir,
37
+ );
38
+ const exportModuleKind = getToolcraftProductExportModuleKind(
39
+ normalizedSpecifier,
40
+ resolvedSpecifier,
41
+ );
42
+ if (exportModuleKind) return exportModuleKind;
43
+
44
+ if (
45
+ isToolcraftPrivateControlImplementationModule({
46
+ moduleSpecifier: normalizedSpecifier,
47
+ resolvedSpecifier,
48
+ })
49
+ ) {
50
+ return "ui-control-implementation";
51
+ }
52
+
53
+ if (
54
+ /^@repo\/toolcraft-runtime\/react\/model-rendering(?:\/|$)/u.test(
55
+ normalizedSpecifier,
56
+ ) ||
57
+ /^[#@]\/toolcraft\/runtime\/react\/model-rendering(?:\/|$)/u.test(
58
+ normalizedSpecifier,
59
+ ) ||
60
+ resolvedSpecifier?.includes("/src/toolcraft/runtime/react/model-rendering")
61
+ ) {
62
+ return "runtime-model-presentation";
63
+ }
64
+
65
+ if (
66
+ /^three\/(?:addons|examples\/jsm)\/loaders(?:\/|$)/u.test(
67
+ normalizedSpecifier,
68
+ ) ||
69
+ /^@gltf-transform(?:\/|$)/u.test(normalizedSpecifier) ||
70
+ /^@repo\/toolcraft-runtime\/model-import(?:\/|$)/u.test(
71
+ normalizedSpecifier,
72
+ ) ||
73
+ /^[#@]\/toolcraft\/runtime\/model-import(?:\/|$)/u.test(
74
+ normalizedSpecifier,
75
+ ) ||
76
+ resolvedSpecifier?.includes("/src/toolcraft/runtime/model-import")
77
+ ) {
78
+ return "runtime-model-import";
79
+ }
80
+
81
+ if (
82
+ /^@repo\/toolcraft-runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
83
+ /^[#@]\/toolcraft\/runtime\/react(?:\/|$)/u.test(normalizedSpecifier) ||
84
+ resolvedSpecifier?.includes("/src/toolcraft/runtime/react")
85
+ ) {
86
+ return "runtime-react";
87
+ }
88
+
89
+ if (
90
+ /^@repo\/ui(?:\/controls(?:\/|$)|$)/u.test(normalizedSpecifier) ||
91
+ /^[#@]\/toolcraft\/ui(?:\/components\/controls(?:\/|$)|\/controls(?:\/|$)|$)/u.test(
92
+ normalizedSpecifier,
93
+ ) ||
94
+ resolvedSpecifier?.includes("/src/toolcraft/ui/components/controls") ||
95
+ /\/src\/toolcraft\/ui$/u.test(resolvedSpecifier ?? "")
96
+ ) {
97
+ return "ui-controls";
98
+ }
99
+
100
+ return null;
101
+ }
@@ -4,6 +4,7 @@ import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
 
7
+ import { createToolcraftPrivateEvidenceImportViolation } from "./toolcraft-product-evidence-import-policy.mjs";
7
8
  import { isToolcraftTypeScriptCompilerAvailable } from "./toolcraft-typescript-source-evidence.mjs";
8
9
 
9
10
  function compareCodeUnits(left, right) {
@@ -94,6 +95,15 @@ export async function evaluateToolcraftProductBoundary({
94
95
  importerEvidence.push(evidence);
95
96
  importsByImporter.set(evidence.importerRepoPath, importerEvidence);
96
97
  }
98
+ const appendPrivateEvidenceImportViolations = (entry) => {
99
+ for (const moduleImport of importsByImporter.get(entry.repoPath) ?? []) {
100
+ const violation = createToolcraftPrivateEvidenceImportViolation({
101
+ importerRepoPath: entry.repoPath,
102
+ moduleImport,
103
+ });
104
+ if (violation) violations.push(violation);
105
+ }
106
+ };
97
107
 
98
108
  for (const entry of productEntries) {
99
109
  const sourceRecord = localDependencyGraph.sourceRecords.get(entry.repoPath);
@@ -113,6 +123,7 @@ export async function evaluateToolcraftProductBoundary({
113
123
  ...boundaryEvidence.reservedEvidenceViolations,
114
124
  ...boundaryEvidence.playwrightAuthorityViolations,
115
125
  );
126
+ appendPrivateEvidenceImportViolations(entry);
116
127
  for (const evidence of importsByImporter.get(entry.repoPath) ?? []) {
117
128
  if (evidence.resolution === "outside-inventory") {
118
129
  violations.push({
@@ -165,6 +176,7 @@ export async function evaluateToolcraftProductBoundary({
165
176
  ...boundaryEvidence.playwrightAuthorityViolations,
166
177
  ...boundaryEvidence.moduleLoadingViolations,
167
178
  );
179
+ appendPrivateEvidenceImportViolations(entry);
168
180
  }
169
181
 
170
182
  return {
@@ -75,32 +75,6 @@ test("checks Vite root-absolute imports against the same product boundary", asyn
75
75
  );
76
76
  });
77
77
 
78
- test("finds built-in controls through re-exports, aliases, namespaces, and dynamic imports", async (context) => {
79
- const rootDir = await createFixture(context, {
80
- "src/features/control-bridge.ts": `
81
- export { SliderControl as ProductSlider } from "@repo/ui/controls";
82
- export { Color as ProductColor } from "@/toolcraft/ui";
83
- `,
84
- "src/features/dynamic.ts": `
85
- export async function loadControls() {
86
- return import("@/toolcraft/ui/components/controls/slider");
87
- }
88
- `,
89
- "src/features/namespace.ts": `
90
- import * as Controls from "@repo/ui";
91
- export const Slider = Controls.Slider;
92
- `,
93
- });
94
-
95
- const result = await evaluateToolcraftProductBoundary({ rootDir });
96
-
97
- assert.equal(result.violations.length, 4);
98
- assert.equal(
99
- result.violations.every((violation) => violation.kind === "built-in-control"),
100
- true,
101
- );
102
- });
103
-
104
78
  test("keeps model import, topology, and repair infrastructure runtime-owned", async (context) => {
105
79
  const rootDir = await createFixture(context, {
106
80
  "src/features/direct-loaders.ts": `