@pixel-point/toolcraft 0.0.18 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/generate-demand-only-lifecycle.test.mjs +9 -1
- package/src/generate-performance-iteration-execution.test.mjs +3 -3
- package/src/generate-test-delivery-architecture-assertions.mjs +11 -73
- package/src/generate-test-demand-only-lifecycle.mjs +34 -36
- package/src/generate-test-dependency-sandbox.mjs +4 -1
- package/src/generate-test-doc-assertions.mjs +55 -53
- package/src/generate-test-doc-assertions.test.mjs +1 -1
- package/src/generate-test-doc-policy-assertions.mjs +1 -1
- package/src/generate-test-export-doc-assertions.mjs +53 -0
- package/src/generate-test-file-assertions.mjs +51 -8
- package/src/generate-test-integrity-assertions.mjs +5 -2
- package/src/generate-test-integrity-manifest-assertions.mjs +16 -5
- package/src/generate-test-integrity-ownership-assertions.mjs +36 -4
- package/src/generate-test-package-assertions.mjs +4 -0
- package/src/generate-test-product-fixture.mjs +1 -1
- package/src/generate-test-product-fixture.test.mjs +35 -38
- package/src/generate-test-product-iteration.mjs +0 -1
- package/src/generate-test-product-iteration.test.mjs +0 -1
- package/src/generate-test-runtime-boundary-assertions.mjs +20 -0
- package/src/generate-test-standalone-assertions.mjs +0 -16
- package/src/generate-test-standalone-delivery-stages.mjs +2 -86
- package/src/generate.test.mjs +4 -0
- package/src/generated-integrity-manifest.test.mjs +5 -2
- package/src/generated-source-policy.test.mjs +0 -4
- package/src/package-json.mjs +5 -0
- package/src/package-json.test.mjs +21 -0
- package/src/package-manager.mjs +2 -0
- package/src/package-manager.test.mjs +8 -0
- package/src/packaged-template-fallback-helpers.mjs +254 -0
- package/src/packaged-template-fallback.test.mjs +121 -46
- package/src/packaged-template-runtime-assertions.mjs +150 -0
- package/templates/runtime/contracts/component-contracts.choices.test.ts +18 -3
- package/templates/runtime/contracts/component-contracts.choices.ts +8 -3
- package/templates/runtime/contracts/component-contracts.inputs.ts +2 -1
- package/templates/runtime/contracts/component-contracts.runtime-acceptance.test.ts +18 -4
- package/templates/runtime/contracts/component-contracts.runtime-shell.test.ts +1 -1
- package/templates/runtime/contracts/component-contracts.runtime.ts +7 -4
- package/templates/runtime/contracts/component-contracts.visual.test.ts +20 -0
- package/templates/runtime/contracts/component-contracts.visual.ts +4 -0
- package/templates/runtime/contracts/decision-contracts.test.ts +18 -12
- package/templates/runtime/contracts/decision-contracts.ts +4 -4
- package/templates/runtime/contracts/performance-verification-policy.test.ts +12 -12
- package/templates/runtime/contracts/performance-verification-policy.ts +8 -8
- package/templates/runtime/export/artifact-download.ts +1 -0
- package/templates/runtime/export/artifact-frame-renderer.ts +2 -15
- package/templates/runtime/export/artifact-frame-state.ts +16 -0
- package/templates/runtime/export/artifact-scene-frame.test.ts +3 -3
- package/templates/runtime/export/artifact-scene-frame.ts +3 -3
- package/templates/runtime/export/export-error.ts +5 -0
- package/templates/runtime/export/export-renderer-coverage.ts +54 -0
- package/templates/runtime/export/image-artifact-export.ts +2 -2
- package/templates/runtime/export/index.ts +13 -0
- package/templates/runtime/export/product-export-renderer.test.ts +38 -4
- package/templates/runtime/export/product-export-renderer.ts +0 -41
- package/templates/runtime/export/product-svg-export-renderer.ts +21 -0
- package/templates/runtime/export/svg-artifact-export.test.ts +98 -0
- package/templates/runtime/export/svg-artifact-export.ts +120 -0
- package/templates/runtime/export/svg-document.test.ts +221 -0
- package/templates/runtime/export/svg-document.ts +400 -0
- package/templates/runtime/export/svg-policy.ts +47 -0
- package/templates/runtime/index.ts +1 -0
- package/templates/runtime/react/app-shell/runtime-public-api.test.tsx +10 -0
- package/templates/runtime/react/app-shell/settings-transfer.test.ts +21 -0
- package/templates/runtime/react/app-shell/toolcraft-app.scene-export.test.tsx +46 -1
- package/templates/runtime/react/app-shell/toolcraft-app.tsx +7 -2
- package/templates/runtime/react/canvas/canvas-shell-interactions.test.tsx +30 -0
- package/templates/runtime/react/canvas/canvas-shell-pinch-interactions.test.tsx +155 -0
- package/templates/runtime/react/canvas/canvas-shell-rendering.test.tsx +1 -1
- package/templates/runtime/react/canvas/canvas-shell.tsx +16 -5
- package/templates/runtime/react/canvas/canvas-viewport-geometry.ts +133 -0
- package/templates/runtime/react/canvas/use-canvas-viewport-interactions.ts +285 -36
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-applicability-layout.test.tsx +134 -0
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.color-layout.test.tsx +16 -1
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.render-isolation.test.tsx +2 -0
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.scene-export-actions.test.tsx +39 -0
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.setup-controls.test.tsx +3 -3
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-collection.test.tsx +1 -4
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.source-color-bank.test.tsx +2 -2
- package/templates/runtime/react/controls-panel/__tests__/controls-panel.vector-interaction.test.tsx +6 -6
- package/templates/runtime/react/controls-panel/actions/controls-panel-actions.ts +2 -2
- package/templates/runtime/react/controls-panel/actions/export-action-runner.ts +40 -11
- package/templates/runtime/react/controls-panel/layout/controls-panel-layout.tsx +31 -2
- package/templates/runtime/react/controls-panel/layout/controls-panel-section.tsx +4 -1
- package/templates/runtime/react/controls-panel/renderers/controls-panel-action-renderer.tsx +2 -1
- package/templates/runtime/react/controls-panel/renderers/controls-panel-basic-renderers.tsx +2 -52
- package/templates/runtime/react/controls-panel/values/controls-panel-color-values.ts +1 -9
- package/templates/runtime/react/controls-panel/values/controls-panel-spatial-values.ts +7 -2
- package/templates/runtime/react/orientation-gizmo/orientation-gizmo-math.ts +9 -69
- package/templates/runtime/schema/artifact-export-actions.test.ts +47 -0
- package/templates/runtime/schema/artifact-export-actions.ts +49 -0
- package/templates/runtime/schema/types.ts +1 -0
- package/templates/runtime/state/canvas-background-state.ts +1 -16
- package/templates/runtime/state/canvas-state.ts +32 -20
- package/templates/runtime/state/control-value-codecs.test.ts +98 -0
- package/templates/runtime/state/control-value-codecs.ts +700 -0
- package/templates/runtime/state/control-value-normalization.test.ts +1 -1
- package/templates/runtime/state/control-value-normalization.ts +127 -135
- package/templates/runtime/state/controls-reducer.ts +26 -3
- package/templates/runtime/state/create-template-state.test.ts +30 -0
- package/templates/runtime/state/create-template-state.ts +52 -31
- package/templates/runtime/state/orientation-pose.ts +80 -0
- package/templates/runtime/state/persistence-control-values.test.ts +59 -0
- package/templates/runtime/state/reducer-controls.test.ts +45 -0
- package/templates/runtime/state/reducer-media-reset.test.ts +1 -1
- package/templates/runtime/state/reducer-timeline.test.ts +70 -0
- package/templates/runtime/state/timeline-reducer.ts +40 -2
- package/templates/runtime/testing/performance-schema-queries.ts +2 -2
- package/templates/starter/AGENTS.md +21 -22
- package/templates/starter/docs/toolcraft/README.md +6 -6
- package/templates/starter/docs/toolcraft/acceptance-testing.md +20 -20
- package/templates/starter/docs/toolcraft/agent-worklog.md +88 -1
- package/templates/starter/docs/toolcraft/assembly-workflow.md +7 -6
- package/templates/starter/docs/toolcraft/component-rules.md +2 -2
- package/templates/starter/docs/toolcraft/core/layout.md +6 -1
- package/templates/starter/docs/toolcraft/core/media-upload.md +1 -1
- package/templates/starter/docs/toolcraft/core/performance.md +8 -10
- package/templates/starter/docs/toolcraft/core/reference-study.md +80 -19
- package/templates/starter/docs/toolcraft/core/runtime-boundary.md +2 -1
- package/templates/starter/docs/toolcraft/core/setup-export.md +43 -13
- package/templates/starter/docs/toolcraft/decision-contract.md +2 -2
- package/templates/starter/docs/toolcraft/performance.md +8 -10
- package/templates/starter/docs/toolcraft/renderer-technique.md +2 -2
- package/templates/starter/docs/toolcraft/schema-reference.md +8 -8
- package/templates/starter/docs/toolcraft/workflow.md +14 -14
- package/templates/starter/e2e/app-browser-infinity-canvas-evidence.spec.ts +38 -0
- package/templates/starter/e2e/app-browser-motion-reference-requirements.spec.ts +411 -0
- package/templates/starter/e2e/app-browser-proof-session.spec.ts +85 -0
- package/templates/starter/e2e/app-browser-runtime-requirements.spec.ts +62 -0
- package/templates/starter/e2e/app-browser-selection-scope-evidence.spec.ts +137 -0
- package/templates/starter/e2e/browser-infinity-canvas-svg-evidence.ts +42 -0
- package/templates/starter/e2e/browser-layer-evidence-helpers.ts +15 -36
- package/templates/starter/e2e/browser-product-raster-snapshot.ts +213 -0
- package/templates/starter/e2e/browser-proof-session.ts +43 -15
- package/templates/starter/e2e/browser-proof-surface-action.ts +79 -0
- package/templates/starter/e2e/browser-proof-types.ts +15 -0
- package/templates/starter/e2e/browser-runtime-evidence-requirements.ts +22 -6
- package/templates/starter/e2e/browser-selection-scope-evidence.ts +269 -0
- package/templates/starter/e2e/browser-semantic-evidence-test-helpers.ts +97 -0
- package/templates/starter/e2e/browser-svg-export-evidence.spec.ts +79 -0
- package/templates/starter/e2e/browser-svg-export-evidence.ts +152 -0
- package/templates/starter/e2e/export-artifact-helpers.ts +70 -0
- package/templates/starter/e2e/product-observable-helpers.ts +8 -129
- package/templates/starter/e2e/svg-artifact-inspection.spec.ts +136 -0
- package/templates/starter/e2e/svg-artifact-inspection.ts +331 -0
- package/templates/starter/e2e/svg-download-test-fixtures.ts +34 -0
- package/templates/starter/e2e/toolcraft-delivery-catalog-reporter.ts +198 -15
- package/templates/starter/e2e/toolcraft-feature-verification-reporter.spec.ts +149 -0
- package/templates/starter/e2e/toolcraft-feature-verification-reporter.ts +223 -0
- package/templates/starter/package.json +2 -0
- package/templates/starter/scripts/check-toolcraft-docs.mjs +1 -0
- package/templates/starter/scripts/create-toolcraft-motion-reference-study.mjs +233 -0
- package/templates/starter/scripts/create-toolcraft-motion-reference-study.test.mjs +459 -0
- package/templates/starter/scripts/playwright-test-title-selection.d.mts +45 -0
- package/templates/starter/scripts/run-browser-performance-test-helpers.mjs +0 -27
- package/templates/starter/scripts/run-browser-performance.mjs +0 -6
- package/templates/starter/scripts/run-browser-performance.test.mjs +5 -13
- package/templates/starter/scripts/run-delivery-verification-test-helpers.mjs +0 -34
- package/templates/starter/scripts/run-delivery-verification.test.mjs +135 -31
- package/templates/starter/scripts/run-feature-verification.mjs +212 -0
- package/templates/starter/scripts/run-feature-verification.test.mjs +226 -0
- package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.mjs +21 -8
- package/templates/starter/scripts/toolcraft-checkpoint-delivery-state.test.mjs +32 -92
- package/templates/starter/scripts/toolcraft-checkpoint-transaction.mjs +28 -6
- package/templates/starter/scripts/toolcraft-checkpoint-transaction.test.mjs +8 -63
- package/templates/starter/scripts/toolcraft-delivery-anchor.mjs +28 -8
- package/templates/starter/scripts/toolcraft-delivery-anchor.test.mjs +50 -61
- package/templates/starter/scripts/toolcraft-delivery-architecture-inventory.mjs +0 -4
- package/templates/starter/scripts/toolcraft-delivery-architecture-policy.mjs +0 -1
- package/templates/starter/scripts/toolcraft-delivery-evidence.test.mjs +2 -3
- package/templates/starter/scripts/toolcraft-delivery-executor.mjs +5 -1
- package/templates/starter/scripts/toolcraft-delivery-executor.test.mjs +5 -12
- package/templates/starter/scripts/toolcraft-delivery-functional-context.d.mts +1 -48
- package/templates/starter/scripts/toolcraft-delivery-functional-context.mjs +2 -30
- package/templates/starter/scripts/toolcraft-delivery-functional-context.test.mjs +4 -166
- package/templates/starter/scripts/toolcraft-delivery-functional-initial.test.mjs +4 -20
- package/templates/starter/scripts/toolcraft-delivery-lifecycle.mjs +43 -192
- package/templates/starter/scripts/toolcraft-delivery-performance-iteration-lifecycle.test.mjs +79 -440
- package/templates/starter/scripts/toolcraft-delivery-plan-authority.test.mjs +102 -297
- package/templates/starter/scripts/toolcraft-delivery-plan-construction.mjs +46 -97
- package/templates/starter/scripts/toolcraft-delivery-plan-test-helpers.mjs +125 -0
- package/templates/starter/scripts/toolcraft-delivery-plan-validation.test.mjs +58 -0
- package/templates/starter/scripts/toolcraft-delivery-plan.d.mts +19 -31
- package/templates/starter/scripts/toolcraft-delivery-plan.mjs +254 -252
- package/templates/starter/scripts/toolcraft-delivery-plan.test.mjs +29 -457
- package/templates/starter/scripts/toolcraft-delivery-receipt-performance.test.mjs +1 -1
- package/templates/starter/scripts/toolcraft-delivery-receipt-strictness.test.mjs +3 -72
- package/templates/starter/scripts/toolcraft-delivery-receipt-test-helpers.mjs +7 -36
- package/templates/starter/scripts/toolcraft-delivery-receipt.d.mts +3 -5
- package/templates/starter/scripts/toolcraft-delivery-receipt.mjs +15 -31
- package/templates/starter/scripts/toolcraft-delivery-receipt.test.mjs +28 -20
- package/templates/starter/scripts/toolcraft-delivery-receipt.types.test.mts +22 -30
- package/templates/starter/scripts/toolcraft-feature-verification-plan.d.mts +20 -0
- package/templates/starter/scripts/toolcraft-feature-verification-plan.mjs +146 -0
- package/templates/starter/scripts/toolcraft-feature-verification-plan.test.mjs +96 -0
- package/templates/starter/scripts/toolcraft-functional-proof-model.d.mts +3 -18
- package/templates/starter/scripts/toolcraft-functional-proof-model.mjs +39 -127
- package/templates/starter/scripts/toolcraft-functional-proof-model.test.mjs +25 -362
- package/templates/starter/scripts/toolcraft-functional-proof-model.types.test.mts +6 -83
- package/templates/starter/scripts/toolcraft-functional-proof-primitives.d.mts +11 -0
- package/templates/starter/scripts/toolcraft-functional-proof-primitives.mjs +61 -0
- package/templates/starter/scripts/toolcraft-functional-proof-primitives.test.mjs +43 -0
- package/templates/starter/scripts/toolcraft-integrity-policy.mjs +13 -0
- package/templates/starter/scripts/toolcraft-integrity-test-utils.mjs +1 -1
- package/templates/starter/scripts/toolcraft-layer-evidence-facade.test.mjs +58 -22
- package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.mjs +111 -0
- package/templates/starter/scripts/toolcraft-motion-reference-analysis-protocol.test.mjs +116 -0
- package/templates/starter/scripts/toolcraft-motion-reference-artifacts.d.mts +37 -0
- package/templates/starter/scripts/toolcraft-motion-reference-artifacts.mjs +308 -0
- package/templates/starter/scripts/toolcraft-motion-reference-artifacts.test.mjs +420 -0
- package/templates/starter/scripts/toolcraft-motion-reference-artifacts.types.test.mts +50 -0
- package/templates/starter/scripts/toolcraft-motion-reference-command-options.mjs +195 -0
- package/templates/starter/scripts/toolcraft-motion-reference-command-options.test.mjs +224 -0
- package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.mjs +122 -0
- package/templates/starter/scripts/toolcraft-motion-reference-contact-sheet.test.mjs +153 -0
- package/templates/starter/scripts/toolcraft-motion-reference-evidence-assembly.mjs +270 -0
- package/templates/starter/scripts/toolcraft-motion-reference-evidence.test.mjs +432 -0
- package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.mjs +275 -0
- package/templates/starter/scripts/toolcraft-motion-reference-ffmpeg-output.test.mjs +294 -0
- package/templates/starter/scripts/toolcraft-motion-reference-group-inventory.mjs +148 -0
- package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.mjs +101 -0
- package/templates/starter/scripts/toolcraft-motion-reference-image-filter-graph.test.mjs +124 -0
- package/templates/starter/scripts/toolcraft-motion-reference-image-source.mjs +259 -0
- package/templates/starter/scripts/toolcraft-motion-reference-image-source.test.mjs +338 -0
- package/templates/starter/scripts/toolcraft-motion-reference-image-timing.mjs +96 -0
- package/templates/starter/scripts/toolcraft-motion-reference-image-timing.test.mjs +81 -0
- package/templates/starter/scripts/toolcraft-motion-reference-lock-recovery.test.mjs +144 -0
- package/templates/starter/scripts/toolcraft-motion-reference-media-source.mjs +165 -0
- package/templates/starter/scripts/toolcraft-motion-reference-media-source.test.mjs +299 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-discovery.test.mjs +142 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-isolation.test.mjs +234 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-schema.mjs +122 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.mjs +89 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-journal-store.test.mjs +74 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.mjs +264 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-journal.test.mjs +377 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.mjs +254 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-lease.test.mjs +130 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.mjs +128 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication-staging.test.mjs +209 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication.fixtures.mjs +88 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication.mjs +249 -0
- package/templates/starter/scripts/toolcraft-motion-reference-publication.test.mjs +433 -0
- package/templates/starter/scripts/toolcraft-motion-reference-review-output.mjs +38 -0
- package/templates/starter/scripts/toolcraft-motion-reference-review-output.test.mjs +29 -0
- package/templates/starter/scripts/toolcraft-motion-reference-root-safety.test.mjs +84 -0
- package/templates/starter/scripts/toolcraft-motion-reference-roots.mjs +83 -0
- package/templates/starter/scripts/toolcraft-motion-reference-sampling.mjs +283 -0
- package/templates/starter/scripts/toolcraft-motion-reference-sampling.test.mjs +480 -0
- package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.mjs +39 -0
- package/templates/starter/scripts/toolcraft-motion-reference-stage-registry.test.mjs +59 -0
- package/templates/starter/scripts/toolcraft-motion-reference-stage.mjs +71 -0
- package/templates/starter/scripts/toolcraft-motion-reference-stage.test.mjs +61 -0
- package/templates/starter/scripts/toolcraft-motion-review-numeric.mjs +74 -0
- package/templates/starter/scripts/toolcraft-motion-review-numeric.test.mjs +65 -0
- package/templates/starter/scripts/toolcraft-motion-review-partitioning.mjs +268 -0
- package/templates/starter/scripts/toolcraft-motion-review-partitioning.test.mjs +329 -0
- package/templates/starter/scripts/toolcraft-motion-review-protected-units.mjs +120 -0
- package/templates/starter/scripts/toolcraft-motion-review-protected-units.test.mjs +111 -0
- package/templates/starter/scripts/toolcraft-performance-escalation-policy.test.mjs +77 -345
- package/templates/starter/scripts/toolcraft-performance-receipt-validation.test.mjs +19 -21
- package/templates/starter/scripts/toolcraft-product-boundary-ast.mjs +1 -1
- package/templates/starter/scripts/toolcraft-product-export-boundary.mjs +10 -1
- package/templates/starter/scripts/toolcraft-product-export-boundary.test.mjs +5 -1
- package/templates/starter/scripts/toolcraft-product-observable-facade.test.mjs +46 -1
- package/templates/starter/scripts/toolcraft-receipt-boundary.test.mjs +0 -1
- package/templates/starter/scripts/toolcraft-source-inventory.d.mts +5 -0
- package/templates/starter/scripts/toolcraft-source-inventory.mjs +25 -14
- package/templates/starter/scripts/toolcraft-source-inventory.test.mjs +48 -0
- package/templates/starter/scripts/toolcraft-source-ownership.mjs +0 -1
- package/templates/starter/scripts/toolcraft-source-ownership.test.mjs +30 -5
- package/templates/starter/scripts/toolcraft-verification-receipt-test-helpers.mjs +5 -26
- package/templates/starter/scripts/toolcraft-verification-receipt.d.mts +0 -7
- package/templates/starter/scripts/toolcraft-verification-receipt.mjs +3 -47
- package/templates/starter/scripts/toolcraft-verification-receipt.test.mjs +6 -87
- package/templates/starter/scripts/toolcraft-vitest-runtime-contract.d.mts +19 -0
- package/templates/starter/scripts/toolcraft-vitest-runtime-contract.mjs +107 -0
- package/templates/starter/scripts/toolcraft-vitest-runtime-contract.test.mjs +114 -0
- package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.mjs +13 -2
- package/templates/starter/scripts/toolcraft-vitest-runtime-evidence-reporter.test.mjs +110 -0
- package/templates/starter/src/app/acceptance/artifact-export-intent.ts +51 -20
- package/templates/starter/src/app/acceptance/canvas-coverage.ts +1 -0
- package/templates/starter/src/app/acceptance/color-bank-labels.ts +11 -15
- package/templates/starter/src/app/acceptance/color-row-grouping.ts +33 -0
- package/templates/starter/src/app/acceptance/control-acceptance-coverage.ts +0 -11
- package/templates/starter/src/app/acceptance/control-acceptance-policy.ts +2 -3
- package/templates/starter/src/app/acceptance/control-component-rules.ts +0 -10
- package/templates/starter/src/app/acceptance/control-labels.ts +30 -1
- package/templates/starter/src/app/acceptance/control-layout-section-rules.ts +18 -0
- package/templates/starter/src/app/acceptance/export-artifact-coverage.ts +25 -17
- package/templates/starter/src/app/acceptance/feature-verification-selection.test.ts +295 -0
- package/templates/starter/src/app/acceptance/feature-verification-selection.ts +161 -0
- package/templates/starter/src/app/acceptance/infinity-canvas.ts +10 -0
- package/templates/starter/src/app/acceptance/interaction-ownership-intent.ts +19 -1
- package/templates/starter/src/app/acceptance/interaction-ownership.ts +18 -2
- package/templates/starter/src/app/acceptance/motion-reference-evidence-validation.mjs +65 -0
- package/templates/starter/src/app/acceptance/motion-reference-evidence-windows.mjs +301 -0
- package/templates/starter/src/app/acceptance/motion-reference-evidence.d.mts +11 -0
- package/templates/starter/src/app/acceptance/motion-reference-evidence.mjs +145 -0
- package/templates/starter/src/app/acceptance/motion-reference-study-behaviors.ts +162 -0
- package/templates/starter/src/app/acceptance/motion-reference-study-coverage.ts +206 -0
- package/templates/starter/src/app/acceptance/motion-reference-study-identity.ts +129 -0
- package/templates/starter/src/app/acceptance/motion-reference-study-partitions.ts +186 -0
- package/templates/starter/src/app/acceptance/motion-reference-study.ts +90 -0
- package/templates/starter/src/app/acceptance/output-export-actions.test.ts +9 -1
- package/templates/starter/src/app/acceptance/output-export-actions.ts +14 -22
- package/templates/starter/src/app/acceptance/output-export-layout-rules.ts +5 -1
- package/templates/starter/src/app/acceptance/output-export-model.ts +4 -0
- package/templates/starter/src/app/acceptance/output-export.ts +4 -1
- package/templates/starter/src/app/acceptance/reference-study-types.ts +167 -17
- package/templates/starter/src/app/acceptance/runtime-coverage.ts +6 -1
- package/templates/starter/src/app/acceptance/selection-scope.test.ts +200 -0
- package/templates/starter/src/app/acceptance/selection-scope.ts +151 -0
- package/templates/starter/src/app/acceptance/transfer-mode-types.ts +114 -0
- package/templates/starter/src/app/acceptance/types.ts +43 -118
- package/templates/starter/src/app/acceptance/validate-coverage.ts +14 -3
- package/templates/starter/src/app/starter-acceptance-data.ts +1 -0
- package/templates/starter/src/app/starter-acceptance.animation-intent.test.ts +3 -0
- package/templates/starter/src/app/starter-acceptance.artifact-export-intent.test.ts +81 -8
- package/templates/starter/src/app/starter-acceptance.background-export.test.ts +2 -0
- package/templates/starter/src/app/starter-acceptance.canvas-sizing.test.ts +2 -0
- package/templates/starter/src/app/starter-acceptance.color-row-grouping.test.ts +118 -0
- package/templates/starter/src/app/starter-acceptance.compound-part-coverage.test.ts +1 -1
- package/templates/starter/src/app/starter-acceptance.contract-fixtures.ts +1 -0
- package/templates/starter/src/app/starter-acceptance.control-applicability.test.ts +1 -0
- package/templates/starter/src/app/starter-acceptance.control-label-context.test.ts +1 -0
- package/templates/starter/src/app/starter-acceptance.control-labels.test.ts +78 -3
- package/templates/starter/src/app/starter-acceptance.control-naming-rules.test.ts +77 -1
- package/templates/starter/src/app/starter-acceptance.custom-control-fit-check.test.ts +1 -1
- package/templates/starter/src/app/starter-acceptance.export-artifact.test.ts +74 -3
- package/templates/starter/src/app/starter-acceptance.export-test-utils.ts +5 -1
- package/templates/starter/src/app/starter-acceptance.image-export-settings.test.ts +2 -0
- package/templates/starter/src/app/starter-acceptance.interaction-ownership.test.ts +19 -3
- package/templates/starter/src/app/starter-acceptance.layers.test.ts +2 -1
- package/templates/starter/src/app/starter-acceptance.media-upload.test.ts +28 -0
- package/templates/starter/src/app/starter-acceptance.motion-reference-evidence.test.ts +17 -0
- package/templates/starter/src/app/starter-acceptance.motion-reference-identity.test.ts +163 -0
- package/templates/starter/src/app/starter-acceptance.motion-reference-mapping.test.ts +133 -0
- package/templates/starter/src/app/starter-acceptance.motion-reference-ownership.test.ts +121 -0
- package/templates/starter/src/app/starter-acceptance.motion-reference-partitions.test.ts +210 -0
- package/templates/starter/src/app/starter-acceptance.motion-reference-test-utils.ts +313 -0
- package/templates/starter/src/app/starter-acceptance.output-export-intent.test.ts +78 -4
- package/templates/starter/src/app/starter-acceptance.product-output-export.test.ts +6 -1
- package/templates/starter/src/app/starter-acceptance.product-readiness.test.ts +18 -1
- package/templates/starter/src/app/starter-acceptance.product-worklog.test.ts +123 -2
- package/templates/starter/src/app/starter-acceptance.reference-custom-timeline.test.ts +2 -0
- package/templates/starter/src/app/starter-acceptance.reference-foundation.test.ts +8 -0
- package/templates/starter/src/app/starter-acceptance.reference-timeline.test.ts +7 -0
- package/templates/starter/src/app/starter-acceptance.section-cohesion.test.ts +2 -0
- package/templates/starter/src/app/starter-acceptance.timeline-playback.test.ts +5 -0
- package/templates/starter/src/app/starter-acceptance.ts +34 -8
- package/templates/starter/src/app/starter-acceptance.video-export-settings.test.ts +2 -0
- package/templates/starter/src/app/starter-acceptance.video-reference-study.test.ts +34 -236
- package/templates/starter/src/app/starter-acceptance.view-interaction.test.ts +4 -0
- package/templates/starter/src/app/starter-acceptance.worklog-test-utils.ts +122 -6
- package/templates/starter/src/app/starter-acceptance.worklog.test.ts +152 -16
- package/templates/starter/src/app/starter-performance.gates.test.ts +20 -18
- package/templates/starter/src/app/starter-performance.lifecycle.test.ts +22 -6
- package/templates/starter/src/app/test-evidence/browser-runtime-contract.ts +3 -0
- package/templates/starter/tsconfig.json +1 -0
- package/templates/starter/scripts/toolcraft-browser-impact-selection.mjs +0 -26
- package/templates/starter/scripts/toolcraft-delivery-framework-refresh.test.mjs +0 -141
- package/templates/starter/scripts/toolcraft-delivery-functional-changed.test.mjs +0 -468
- package/templates/starter/scripts/toolcraft-delivery-functional-model-lifecycle.test.mjs +0 -254
- package/templates/starter/scripts/toolcraft-delivery-functional-semantic-regression.test.mjs +0 -135
- package/templates/starter/scripts/toolcraft-delivery-performance-iteration-durability.test.mjs +0 -329
- package/templates/starter/scripts/toolcraft-delivery-plan-errors.test.mjs +0 -430
- package/templates/starter/scripts/toolcraft-delivery-plan-functional-model.test.mjs +0 -358
- package/templates/starter/scripts/toolcraft-functional-proof-regression-fixtures.mjs +0 -298
- package/templates/starter/scripts/toolcraft-verification-impact-inventory.d.mts +0 -62
- package/templates/starter/scripts/toolcraft-verification-impact-inventory.mjs +0 -344
- package/templates/starter/scripts/toolcraft-verification-impact-inventory.test.mjs +0 -204
- package/templates/starter/scripts/toolcraft-verification-impact-performance-candidates.test.mjs +0 -210
- package/templates/starter/scripts/toolcraft-verification-impact-resolution.mjs +0 -344
- package/templates/starter/scripts/toolcraft-verification-impact-resolution.test.mjs +0 -270
- package/templates/starter/scripts/toolcraft-verification-impact-semantic-resolution.test.mjs +0 -449
- package/templates/starter/scripts/toolcraft-verification-impact-support-resolution.test.mjs +0 -195
- package/templates/starter/scripts/toolcraft-verification-impact.d.mts +0 -132
- package/templates/starter/scripts/toolcraft-verification-impact.mjs +0 -169
- package/templates/starter/scripts/toolcraft-verification-impact.test.mjs +0 -300
- package/templates/starter/scripts/toolcraft-verification-input-roles.mjs +0 -197
- package/templates/starter/scripts/toolcraft-verification-input-roles.test.mjs +0 -225
- package/templates/starter/src/app/acceptance/video-reference-study.ts +0 -217
- package/templates/starter/src/app/starter-verification-impact.json +0 -15
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
ToolcraftFunctionalProofModel,
|
|
12
12
|
} from "./toolcraft-functional-proof-model.mjs";
|
|
13
13
|
|
|
14
|
-
export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION:
|
|
14
|
+
export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION: 8;
|
|
15
15
|
|
|
16
16
|
export type ToolcraftResolvedTestEvidence = Readonly<{
|
|
17
17
|
fullTitle: string;
|
|
@@ -19,7 +19,6 @@ export type ToolcraftResolvedTestEvidence = Readonly<{
|
|
|
19
19
|
}>;
|
|
20
20
|
|
|
21
21
|
export type ToolcraftDeliveryStepEvidence =
|
|
22
|
-
| Readonly<{ kind: "dependencies"; packageManager: "npm" | "pnpm" | "yarn" | "bun" }>
|
|
23
22
|
| Readonly<{ kind: "docs" }>
|
|
24
23
|
| Readonly<{ kind: "code-health" }>
|
|
25
24
|
| Readonly<{ kind: "product-tests"; files: readonly string[] }>
|
|
@@ -49,12 +48,12 @@ export type ToolcraftDeliveryReceipt = Readonly<{
|
|
|
49
48
|
files: readonly ToolcraftVerificationInventoryEntry[];
|
|
50
49
|
functionalProofModel: ToolcraftFunctionalProofModel;
|
|
51
50
|
functionalProofModelHash: string;
|
|
52
|
-
kind: "delivery-verification";
|
|
51
|
+
kind: "delivery-verification" | "targeted-performance-verification";
|
|
53
52
|
manifestHash: string;
|
|
54
53
|
mode?: never;
|
|
55
54
|
plan: ToolcraftDeliveryPlan;
|
|
56
55
|
planHash: string;
|
|
57
|
-
planVersion:
|
|
56
|
+
planVersion: 6;
|
|
58
57
|
runner: "protected-delivery";
|
|
59
58
|
sourceHash: string;
|
|
60
59
|
status: "passed";
|
|
@@ -78,6 +77,5 @@ export function readToolcraftDeliveryReceipt(rootDir: string): Promise<{
|
|
|
78
77
|
}>;
|
|
79
78
|
|
|
80
79
|
export function validateToolcraftDeliveryReceipt(options: {
|
|
81
|
-
collectInventory?: (rootDir: string) => Promise<ToolcraftVerificationInventory>;
|
|
82
80
|
rootDir: string;
|
|
83
81
|
}): Promise<string[]>;
|
|
@@ -12,12 +12,10 @@ import {
|
|
|
12
12
|
} from "./toolcraft-functional-proof-model.mjs";
|
|
13
13
|
import { readToolcraftCheckpointBundle } from "./toolcraft-checkpoint-bundle.mjs";
|
|
14
14
|
import {
|
|
15
|
-
collectToolcraftVerificationInputs,
|
|
16
|
-
getToolcraftChangedVerificationFiles,
|
|
17
15
|
getToolcraftVerificationInventoryError,
|
|
18
16
|
} from "./toolcraft-verification-inventory.mjs";
|
|
19
17
|
|
|
20
|
-
export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION =
|
|
18
|
+
export const TOOLCRAFT_DELIVERY_RECEIPT_VERSION = 8;
|
|
21
19
|
|
|
22
20
|
const receiptKeys = Object.freeze([
|
|
23
21
|
"completedAt",
|
|
@@ -57,15 +55,6 @@ function hasExactKeys(value, expected) {
|
|
|
57
55
|
);
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
function arraysEqual(left, right) {
|
|
61
|
-
return (
|
|
62
|
-
Array.isArray(left) &&
|
|
63
|
-
Array.isArray(right) &&
|
|
64
|
-
left.length === right.length &&
|
|
65
|
-
left.every((item, index) => item === right[index])
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
58
|
function deepFreeze(value) {
|
|
70
59
|
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
71
60
|
Object.values(value).forEach(deepFreeze);
|
|
@@ -77,7 +66,10 @@ function deepFreeze(value) {
|
|
|
77
66
|
function getCurrentReceiptCommonError(receipt) {
|
|
78
67
|
if (
|
|
79
68
|
!hasExactKeys(receipt, receiptKeys) ||
|
|
80
|
-
|
|
69
|
+
![
|
|
70
|
+
"delivery-verification",
|
|
71
|
+
"targeted-performance-verification",
|
|
72
|
+
].includes(receipt.kind) ||
|
|
81
73
|
receipt.runner !== "protected-delivery" ||
|
|
82
74
|
receipt.status !== "passed" ||
|
|
83
75
|
receipt.version !== TOOLCRAFT_DELIVERY_RECEIPT_VERSION ||
|
|
@@ -104,6 +96,12 @@ export function getToolcraftDeliveryReceiptShapeError(receipt) {
|
|
|
104
96
|
const functionalProofModel = deepFreeze(receipt.functionalProofModel);
|
|
105
97
|
const planError = getToolcraftDeliveryPlanError(plan);
|
|
106
98
|
if (planError) return planError;
|
|
99
|
+
const expectedKind = plan.kind === "functional"
|
|
100
|
+
? "delivery-verification"
|
|
101
|
+
: "targeted-performance-verification";
|
|
102
|
+
if (receipt.kind !== expectedKind) {
|
|
103
|
+
return "Toolcraft protected receipt kind does not match its plan.";
|
|
104
|
+
}
|
|
107
105
|
const modelError =
|
|
108
106
|
getToolcraftFunctionalProofModelError(functionalProofModel);
|
|
109
107
|
if (modelError) {
|
|
@@ -125,18 +123,6 @@ export function getToolcraftDeliveryReceiptShapeError(receipt) {
|
|
|
125
123
|
if (createToolcraftDeliveryPlanHash(plan) !== receipt.planHash) {
|
|
126
124
|
return "Toolcraft delivery receipt plan hash does not match its plan.";
|
|
127
125
|
}
|
|
128
|
-
if (
|
|
129
|
-
plan.basis.kind === "changed" &&
|
|
130
|
-
!arraysEqual(
|
|
131
|
-
plan.basis.changedFiles,
|
|
132
|
-
getToolcraftChangedVerificationFiles(
|
|
133
|
-
plan.basis.comparisonInventory.entries,
|
|
134
|
-
receipt.files,
|
|
135
|
-
),
|
|
136
|
-
)
|
|
137
|
-
) {
|
|
138
|
-
return "Toolcraft delivery receipt changed files do not exactly match its inventories.";
|
|
139
|
-
}
|
|
140
126
|
return getToolcraftExecutionEvidenceError({
|
|
141
127
|
evidence: receipt.evidence,
|
|
142
128
|
finalInventory: {
|
|
@@ -179,7 +165,9 @@ export function createToolcraftDeliveryReceipt({
|
|
|
179
165
|
files: result?.finalInventory?.entries,
|
|
180
166
|
functionalProofModel,
|
|
181
167
|
functionalProofModelHash,
|
|
182
|
-
kind: "
|
|
168
|
+
kind: plan.kind === "functional"
|
|
169
|
+
? "delivery-verification"
|
|
170
|
+
: "targeted-performance-verification",
|
|
183
171
|
manifestHash: plan.manifestHash,
|
|
184
172
|
plan,
|
|
185
173
|
planHash,
|
|
@@ -203,14 +191,10 @@ export async function readToolcraftDeliveryReceipt(rootDir) {
|
|
|
203
191
|
}
|
|
204
192
|
|
|
205
193
|
export async function validateToolcraftDeliveryReceipt({
|
|
206
|
-
collectInventory = collectToolcraftVerificationInputs,
|
|
207
194
|
rootDir,
|
|
208
195
|
}) {
|
|
209
196
|
const loaded = await readToolcraftDeliveryReceipt(rootDir);
|
|
210
197
|
if (loaded.missing) return ["Toolcraft delivery receipt is missing."];
|
|
211
198
|
if (loaded.error) return [loaded.error];
|
|
212
|
-
|
|
213
|
-
return loaded.receipt.sourceHash === inventory.sourceHash
|
|
214
|
-
? []
|
|
215
|
-
: ["Toolcraft delivery receipt is stale for the current source."];
|
|
199
|
+
return [];
|
|
216
200
|
}
|
|
@@ -24,7 +24,7 @@ function assertDeeplyFrozen(value) {
|
|
|
24
24
|
Object.values(value).forEach(assertDeeplyFrozen);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
test("constructs the exact deeply frozen version
|
|
27
|
+
test("constructs the exact deeply frozen version 8 receipt", () => {
|
|
28
28
|
const { functionalProofModel, plan, result } = createPlanReceiptFixture();
|
|
29
29
|
const receipt = createToolcraftDeliveryReceipt({
|
|
30
30
|
functionalProofModel,
|
|
@@ -32,9 +32,9 @@ test("constructs the exact deeply frozen version 7 receipt", () => {
|
|
|
32
32
|
result,
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
assert.equal(TOOLCRAFT_DELIVERY_RECEIPT_VERSION,
|
|
36
|
-
assert.equal(receipt.planVersion,
|
|
37
|
-
assert.equal(receipt.version,
|
|
35
|
+
assert.equal(TOOLCRAFT_DELIVERY_RECEIPT_VERSION, 8);
|
|
36
|
+
assert.equal(receipt.planVersion, 6);
|
|
37
|
+
assert.equal(receipt.version, 8);
|
|
38
38
|
assert.deepEqual(Object.keys(receipt).sort(), [
|
|
39
39
|
"completedAt",
|
|
40
40
|
"evidence",
|
|
@@ -74,22 +74,40 @@ test("constructs initial functional proof with exact browser evidence", () => {
|
|
|
74
74
|
);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
test("
|
|
77
|
+
test("receipt creation rejects an initial plan with an empty runtime selection", () => {
|
|
78
|
+
const fixture = createPlanReceiptFixture("functional-initial");
|
|
79
|
+
const plan = structuredClone(fixture.plan);
|
|
80
|
+
plan.steps.find(({ kind }) => kind === "product-tests").acceptanceIds = [];
|
|
81
|
+
const freeze = (value) => {
|
|
82
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
83
|
+
Object.values(value).forEach(freeze);
|
|
84
|
+
Object.freeze(value);
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
assert.throws(
|
|
90
|
+
() => createToolcraftDeliveryReceipt({ ...fixture, plan: freeze(plan) }),
|
|
91
|
+
/complete product-test selection/iu,
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("rejects obsolete receipt 7 and plan 5 identities", () => {
|
|
78
96
|
const receipt = createToolcraftDeliveryReceipt(
|
|
79
|
-
createPlanReceiptFixture("functional-
|
|
97
|
+
createPlanReceiptFixture("functional-initial"),
|
|
80
98
|
);
|
|
81
99
|
|
|
82
100
|
assert.match(
|
|
83
|
-
getToolcraftDeliveryReceiptShapeError({ ...receipt, version:
|
|
101
|
+
getToolcraftDeliveryReceiptShapeError({ ...receipt, version: 7 }),
|
|
84
102
|
/malformed|unsupported/iu,
|
|
85
103
|
);
|
|
86
104
|
assert.match(
|
|
87
|
-
getToolcraftDeliveryReceiptShapeError({ ...receipt, planVersion:
|
|
105
|
+
getToolcraftDeliveryReceiptShapeError({ ...receipt, planVersion: 5 }),
|
|
88
106
|
/malformed|unsupported/iu,
|
|
89
107
|
);
|
|
90
108
|
});
|
|
91
109
|
|
|
92
|
-
test("validates
|
|
110
|
+
test("validates historical initial proof without requiring later source freshness", async (t) => {
|
|
93
111
|
const rootDir = await createReceiptFixture();
|
|
94
112
|
t.after(() => fs.rm(rootDir, { force: true, recursive: true }));
|
|
95
113
|
const { functionalProofModel, plan, result } = createPlanReceiptFixture();
|
|
@@ -106,17 +124,7 @@ test("validates only the current receipt source and ignores full-performance sta
|
|
|
106
124
|
bundle.performanceBaseline = { malformed: true };
|
|
107
125
|
await fs.writeFile(bundlePath, `${JSON.stringify(bundle)}\n`);
|
|
108
126
|
|
|
109
|
-
assert.deepEqual(await validateToolcraftDeliveryReceipt({
|
|
110
|
-
collectInventory: async () => result.finalInventory,
|
|
111
|
-
rootDir,
|
|
112
|
-
}), []);
|
|
113
|
-
assert.deepEqual(await validateToolcraftDeliveryReceipt({
|
|
114
|
-
collectInventory: async () => ({
|
|
115
|
-
...result.finalInventory,
|
|
116
|
-
sourceHash: "0".repeat(64),
|
|
117
|
-
}),
|
|
118
|
-
rootDir,
|
|
119
|
-
}), ["Toolcraft delivery receipt is stale for the current source."]);
|
|
127
|
+
assert.deepEqual(await validateToolcraftDeliveryReceipt({ rootDir }), []);
|
|
120
128
|
});
|
|
121
129
|
|
|
122
130
|
test("rejects a different valid model and every model/hash tamper", () => {
|
|
@@ -18,23 +18,12 @@ import type {
|
|
|
18
18
|
} from "./toolcraft-functional-proof-model.mjs";
|
|
19
19
|
|
|
20
20
|
const files = [{ path: "src/app/app-schema.ts", sha256: "a".repeat(64) }];
|
|
21
|
-
const comparisonFiles = [
|
|
22
|
-
{ path: "src/app/app-schema.ts", sha256: "b".repeat(64) },
|
|
23
|
-
];
|
|
24
21
|
const lifecycle: ToolcraftDeliveryLifecycleState = {
|
|
25
22
|
consumedPerformanceRequestAuthorityHashes: ["e".repeat(64)],
|
|
26
23
|
performanceEscalationOffered: true,
|
|
27
24
|
};
|
|
28
25
|
const plan: ToolcraftDeliveryPlan = {
|
|
29
|
-
basis: {
|
|
30
|
-
changedFiles: ["src/app/app-schema.ts"],
|
|
31
|
-
comparisonFunctionalProofModelHash: "f".repeat(64),
|
|
32
|
-
comparisonInventory: {
|
|
33
|
-
entries: comparisonFiles,
|
|
34
|
-
sourceHash: "b".repeat(64),
|
|
35
|
-
},
|
|
36
|
-
kind: "changed",
|
|
37
|
-
},
|
|
26
|
+
basis: { kind: "initial" },
|
|
38
27
|
functionalProofModelHash: "f".repeat(64),
|
|
39
28
|
kind: "functional",
|
|
40
29
|
lifecycle,
|
|
@@ -53,12 +42,7 @@ const functionalProofModel: ToolcraftFunctionalProofModel = {
|
|
|
53
42
|
file: "app-controls.spec.ts",
|
|
54
43
|
testName: "browser: focused acceptance",
|
|
55
44
|
}],
|
|
56
|
-
|
|
57
|
-
acceptanceIds: ["canvas.focused"],
|
|
58
|
-
kind: "functional",
|
|
59
|
-
path: "src/app/app-schema.ts",
|
|
60
|
-
}],
|
|
61
|
-
version: 1,
|
|
45
|
+
version: 2,
|
|
62
46
|
};
|
|
63
47
|
const receipt: ToolcraftDeliveryReceipt = {
|
|
64
48
|
completedAt: "2026-07-24T00:00:00.000Z",
|
|
@@ -70,11 +54,11 @@ const receipt: ToolcraftDeliveryReceipt = {
|
|
|
70
54
|
manifestHash: plan.manifestHash,
|
|
71
55
|
plan,
|
|
72
56
|
planHash: "d".repeat(64),
|
|
73
|
-
planVersion:
|
|
57
|
+
planVersion: 6,
|
|
74
58
|
runner: "protected-delivery",
|
|
75
59
|
sourceHash: plan.sourceHash,
|
|
76
60
|
status: "passed",
|
|
77
|
-
version:
|
|
61
|
+
version: 8,
|
|
78
62
|
};
|
|
79
63
|
|
|
80
64
|
const withLegacyMode = { ...receipt, mode: "ordinary" as const };
|
|
@@ -88,10 +72,10 @@ const withBaseline = {
|
|
|
88
72
|
// @ts-expect-error Current delivery receipts cannot carry baseline linkage.
|
|
89
73
|
const invalidBaseline: ToolcraftDeliveryReceipt = withBaseline;
|
|
90
74
|
const withOldPlanVersion = { ...receipt, planVersion: 1 as const };
|
|
91
|
-
// @ts-expect-error Current delivery receipts require plan version
|
|
75
|
+
// @ts-expect-error Current delivery receipts require plan version 6.
|
|
92
76
|
const invalidPlanVersion: ToolcraftDeliveryReceipt = withOldPlanVersion;
|
|
93
|
-
const withOldReceiptVersion = { ...receipt, version:
|
|
94
|
-
// @ts-expect-error Current delivery receipts require receipt version
|
|
77
|
+
const withOldReceiptVersion = { ...receipt, version: 7 as const };
|
|
78
|
+
// @ts-expect-error Current delivery receipts require receipt version 8.
|
|
95
79
|
const invalidReceiptVersion: ToolcraftDeliveryReceipt = withOldReceiptVersion;
|
|
96
80
|
const { functionalProofModel: _model, ...withoutModel } = receipt;
|
|
97
81
|
// @ts-expect-error Current delivery receipts require the canonical proof model.
|
|
@@ -114,6 +98,11 @@ const invalidFunctional: FunctionalDeliveryPlan = {
|
|
|
114
98
|
};
|
|
115
99
|
const invalidIteration: PerformanceIterationPlan = {
|
|
116
100
|
...plan,
|
|
101
|
+
basis: {
|
|
102
|
+
initialFunctionalProofModelHash: "f".repeat(64),
|
|
103
|
+
initialSourceHash: "a".repeat(64),
|
|
104
|
+
kind: "performance-request",
|
|
105
|
+
},
|
|
117
106
|
kind: "performance-iteration",
|
|
118
107
|
performanceComparison: { kind: "none" },
|
|
119
108
|
requestAuthorityHash: "e".repeat(64),
|
|
@@ -129,14 +118,17 @@ const initialPerformanceCandidate = {
|
|
|
129
118
|
performanceComparison: { kind: "none" as const },
|
|
130
119
|
requestAuthorityHash: "e".repeat(64),
|
|
131
120
|
sourceHash: "a".repeat(64),
|
|
132
|
-
steps: [
|
|
133
|
-
kind: "
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
121
|
+
steps: [
|
|
122
|
+
{ kind: "build" as const },
|
|
123
|
+
{
|
|
124
|
+
kind: "browser-performance" as const,
|
|
125
|
+
passIds: ["preview"],
|
|
126
|
+
pathIds: ["path"],
|
|
127
|
+
testNames: ["browser perf: path"],
|
|
128
|
+
},
|
|
129
|
+
] as const,
|
|
138
130
|
};
|
|
139
|
-
// @ts-expect-error Performance iterations require a
|
|
131
|
+
// @ts-expect-error Performance iterations require a performance-request basis.
|
|
140
132
|
const invalidInitialIteration: PerformanceIterationPlan =
|
|
141
133
|
initialPerformanceCandidate;
|
|
142
134
|
// @ts-expect-error Lifecycle authority history is immutable.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION: 1;
|
|
2
|
+
|
|
3
|
+
export type ToolcraftFeatureVerificationPlan = Readonly<{
|
|
4
|
+
acceptanceIds: readonly string[];
|
|
5
|
+
testNames: readonly string[];
|
|
6
|
+
version: 1;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
9
|
+
export type ToolcraftFeatureVerificationPlanValidation = Readonly<{
|
|
10
|
+
errors: readonly string[];
|
|
11
|
+
plan?: ToolcraftFeatureVerificationPlan;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
export function validateToolcraftFeatureVerificationPlan(
|
|
15
|
+
value: unknown,
|
|
16
|
+
): ToolcraftFeatureVerificationPlanValidation;
|
|
17
|
+
|
|
18
|
+
export function parseToolcraftFeatureVerificationPlanOutput(
|
|
19
|
+
output: unknown,
|
|
20
|
+
): ToolcraftFeatureVerificationPlan;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
export const TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION = 1;
|
|
2
|
+
|
|
3
|
+
const compareCodeUnits = (left, right) =>
|
|
4
|
+
left < right ? -1 : left > right ? 1 : 0;
|
|
5
|
+
|
|
6
|
+
function isPlainObject(value) {
|
|
7
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const prototype = Object.getPrototypeOf(value);
|
|
11
|
+
return prototype === Object.prototype || prototype === null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getExactKeyErrors(value, expected, label) {
|
|
15
|
+
if (!isPlainObject(value)) return [`${label} must be a plain object.`];
|
|
16
|
+
const expectedSet = new Set(expected);
|
|
17
|
+
const ownKeys = Reflect.ownKeys(value);
|
|
18
|
+
const unknown = ownKeys
|
|
19
|
+
.filter((key) => typeof key !== "string" || !expectedSet.has(key))
|
|
20
|
+
.map(String)
|
|
21
|
+
.sort(compareCodeUnits);
|
|
22
|
+
const missing = expected.filter(
|
|
23
|
+
(key) => !Object.prototype.hasOwnProperty.call(value, key),
|
|
24
|
+
);
|
|
25
|
+
return [
|
|
26
|
+
...(unknown.length > 0
|
|
27
|
+
? [`${label} contains unknown fields: ${unknown.join(", ")}.`]
|
|
28
|
+
: []),
|
|
29
|
+
...(missing.length > 0
|
|
30
|
+
? [`${label} is missing required fields: ${missing.join(", ")}.`]
|
|
31
|
+
: []),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function validateCanonicalStringArray(value, label) {
|
|
36
|
+
if (!Array.isArray(value)) {
|
|
37
|
+
return [`Toolcraft feature verification plan.${label} must be an array.`];
|
|
38
|
+
}
|
|
39
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
40
|
+
return [
|
|
41
|
+
`Toolcraft feature verification plan.${label} contains symbol fields.`,
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
const errors = [];
|
|
45
|
+
if (value.length === 0) {
|
|
46
|
+
errors.push(
|
|
47
|
+
`Toolcraft feature verification plan.${label} must be non-empty.`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
if (
|
|
51
|
+
!value.every(
|
|
52
|
+
(entry) =>
|
|
53
|
+
typeof entry === "string" &&
|
|
54
|
+
entry.length > 0 &&
|
|
55
|
+
entry.trim() === entry,
|
|
56
|
+
)
|
|
57
|
+
) {
|
|
58
|
+
errors.push(
|
|
59
|
+
`Toolcraft feature verification plan.${label} must contain trimmed non-empty strings.`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
if (new Set(value).size !== value.length) {
|
|
63
|
+
errors.push(
|
|
64
|
+
`Toolcraft feature verification plan.${label} must contain unique values.`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
if (
|
|
68
|
+
value.every((entry) => typeof entry === "string") &&
|
|
69
|
+
value.some((entry, index) => entry !== [...value].sort(compareCodeUnits)[index])
|
|
70
|
+
) {
|
|
71
|
+
errors.push(
|
|
72
|
+
`Toolcraft feature verification plan.${label} must be sorted by code unit.`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return errors;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function validateToolcraftFeatureVerificationPlan(value) {
|
|
79
|
+
const errors = getExactKeyErrors(
|
|
80
|
+
value,
|
|
81
|
+
["acceptanceIds", "testNames", "version"],
|
|
82
|
+
"Toolcraft feature verification plan",
|
|
83
|
+
);
|
|
84
|
+
if (!isPlainObject(value)) return { errors };
|
|
85
|
+
|
|
86
|
+
if (value.version !== TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION) {
|
|
87
|
+
errors.push(
|
|
88
|
+
`Toolcraft feature verification plan.version must be ${TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION}.`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
errors.push(
|
|
92
|
+
...validateCanonicalStringArray(value.acceptanceIds, "acceptanceIds"),
|
|
93
|
+
...validateCanonicalStringArray(value.testNames, "testNames"),
|
|
94
|
+
);
|
|
95
|
+
if (
|
|
96
|
+
Array.isArray(value.acceptanceIds) &&
|
|
97
|
+
Array.isArray(value.testNames) &&
|
|
98
|
+
value.acceptanceIds.length !== value.testNames.length
|
|
99
|
+
) {
|
|
100
|
+
errors.push(
|
|
101
|
+
"Toolcraft feature verification plan must contain one test name per acceptance id.",
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (errors.length > 0) return { errors };
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
errors,
|
|
108
|
+
plan: Object.freeze({
|
|
109
|
+
acceptanceIds: Object.freeze([...value.acceptanceIds]),
|
|
110
|
+
testNames: Object.freeze([...value.testNames]),
|
|
111
|
+
version: TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION,
|
|
112
|
+
}),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function parseToolcraftFeatureVerificationPlanOutput(output) {
|
|
117
|
+
if (typeof output !== "string") {
|
|
118
|
+
throw new Error(
|
|
119
|
+
"Toolcraft feature verification reporter must emit exactly one JSON line.",
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
const lines = output.split(/\r?\n/u);
|
|
123
|
+
if (lines.at(-1) === "") lines.pop();
|
|
124
|
+
if (lines.length !== 1 || lines[0].length === 0) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
"Toolcraft feature verification reporter must emit exactly one JSON line.",
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let value;
|
|
131
|
+
try {
|
|
132
|
+
value = JSON.parse(lines[0]);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
"Toolcraft feature verification reporter must emit valid JSON.",
|
|
136
|
+
{ cause: error },
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
const validation = validateToolcraftFeatureVerificationPlan(value);
|
|
140
|
+
if (validation.errors.length > 0) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`Invalid Toolcraft feature verification plan:\n${validation.errors.join("\n")}`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
return validation.plan;
|
|
146
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION,
|
|
6
|
+
parseToolcraftFeatureVerificationPlanOutput,
|
|
7
|
+
validateToolcraftFeatureVerificationPlan,
|
|
8
|
+
} from "./toolcraft-feature-verification-plan.mjs";
|
|
9
|
+
|
|
10
|
+
const validPlan = () => ({
|
|
11
|
+
acceptanceIds: ["lighting.intensity", "material.layer"],
|
|
12
|
+
testNames: ["browser: lighting.intensity", "browser: material.layer"],
|
|
13
|
+
version: 1,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("normalizes a canonical deeply frozen feature verification plan", () => {
|
|
17
|
+
const validation = validateToolcraftFeatureVerificationPlan(validPlan());
|
|
18
|
+
|
|
19
|
+
assert.deepEqual(validation.errors, []);
|
|
20
|
+
assert.deepEqual(validation.plan, validPlan());
|
|
21
|
+
assert.equal(TOOLCRAFT_FEATURE_VERIFICATION_PLAN_VERSION, 1);
|
|
22
|
+
assert.equal(Object.isFrozen(validation.plan), true);
|
|
23
|
+
assert.equal(Object.isFrozen(validation.plan.acceptanceIds), true);
|
|
24
|
+
assert.equal(Object.isFrozen(validation.plan.testNames), true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("rejects malformed top-level plan shapes", () => {
|
|
28
|
+
for (const [value, pattern] of [
|
|
29
|
+
[null, /must be a plain object/iu],
|
|
30
|
+
[Object.create({ version: 1 }), /must be a plain object/iu],
|
|
31
|
+
[{ ...validPlan(), extra: true }, /unknown fields: extra/iu],
|
|
32
|
+
[{ acceptanceIds: [], testNames: [] }, /missing required fields: version/iu],
|
|
33
|
+
[{ ...validPlan(), version: 2 }, /version must be 1/iu],
|
|
34
|
+
]) {
|
|
35
|
+
assert.match(
|
|
36
|
+
validateToolcraftFeatureVerificationPlan(value).errors.join("\n"),
|
|
37
|
+
pattern,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("rejects empty, untrimmed, duplicate, and noncanonical arrays", () => {
|
|
43
|
+
const symbolArray = ["material.layer"];
|
|
44
|
+
symbolArray[Symbol("hidden")] = true;
|
|
45
|
+
for (const [value, pattern] of [
|
|
46
|
+
[{ ...validPlan(), acceptanceIds: [] }, /acceptanceIds must be non-empty/iu],
|
|
47
|
+
[{ ...validPlan(), testNames: [] }, /testNames must be non-empty/iu],
|
|
48
|
+
[
|
|
49
|
+
{ ...validPlan(), acceptanceIds: ["material.layer", "material.layer"] },
|
|
50
|
+
/acceptanceIds must contain unique/iu,
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
{ ...validPlan(), testNames: ["browser: layer", "browser: layer"] },
|
|
54
|
+
/testNames must contain unique/iu,
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
{ ...validPlan(), acceptanceIds: [" material.layer"] },
|
|
58
|
+
/acceptanceIds must contain trimmed/iu,
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
{ ...validPlan(), testNames: ["browser: layer "] },
|
|
62
|
+
/testNames must contain trimmed/iu,
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
{ ...validPlan(), acceptanceIds: ["material.layer", "lighting.intensity"] },
|
|
66
|
+
/acceptanceIds must be sorted/iu,
|
|
67
|
+
],
|
|
68
|
+
[{ ...validPlan(), acceptanceIds: symbolArray }, /symbol fields/iu],
|
|
69
|
+
]) {
|
|
70
|
+
assert.match(
|
|
71
|
+
validateToolcraftFeatureVerificationPlan(value).errors.join("\n"),
|
|
72
|
+
pattern,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("parses exactly one JSON plan line", () => {
|
|
78
|
+
assert.deepEqual(
|
|
79
|
+
parseToolcraftFeatureVerificationPlanOutput(`${JSON.stringify(validPlan())}\n`),
|
|
80
|
+
validPlan(),
|
|
81
|
+
);
|
|
82
|
+
for (const [output, pattern] of [
|
|
83
|
+
["", /exactly one JSON line/iu],
|
|
84
|
+
["not-json\n", /valid JSON/iu],
|
|
85
|
+
[
|
|
86
|
+
`${JSON.stringify(validPlan())}\n${JSON.stringify(validPlan())}\n`,
|
|
87
|
+
/exactly one JSON line/iu,
|
|
88
|
+
],
|
|
89
|
+
[JSON.stringify({ ...validPlan(), version: 2 }), /version must be 1/iu],
|
|
90
|
+
]) {
|
|
91
|
+
assert.throws(
|
|
92
|
+
() => parseToolcraftFeatureVerificationPlanOutput(output),
|
|
93
|
+
pattern,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ToolcraftDeliveryCatalog,
|
|
3
|
-
|
|
4
|
-
ToolcraftVerificationImpactOwner,
|
|
5
|
-
} from "./toolcraft-verification-impact-inventory.mjs";
|
|
3
|
+
} from "./playwright-test-title-selection.mjs";
|
|
6
4
|
|
|
7
5
|
export type ToolcraftFunctionalProofAcceptance = Readonly<{
|
|
8
6
|
acceptanceId: string;
|
|
@@ -12,16 +10,12 @@ export type ToolcraftFunctionalProofAcceptance = Readonly<{
|
|
|
12
10
|
testName: string;
|
|
13
11
|
}>;
|
|
14
12
|
|
|
15
|
-
export type ToolcraftFunctionalProofOwner =
|
|
16
|
-
ToolcraftVerificationImpactOwner;
|
|
17
|
-
|
|
18
13
|
export type ToolcraftFunctionalProofModel = Readonly<{
|
|
19
14
|
acceptance: readonly ToolcraftFunctionalProofAcceptance[];
|
|
20
|
-
|
|
21
|
-
version: 1;
|
|
15
|
+
version: 2;
|
|
22
16
|
}>;
|
|
23
17
|
|
|
24
|
-
export const TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION:
|
|
18
|
+
export const TOOLCRAFT_FUNCTIONAL_PROOF_MODEL_VERSION: 2;
|
|
25
19
|
|
|
26
20
|
export {
|
|
27
21
|
createToolcraftAcceptanceContractHash,
|
|
@@ -29,7 +23,6 @@ export {
|
|
|
29
23
|
} from "./toolcraft-functional-proof-primitives.mjs";
|
|
30
24
|
export function createToolcraftFunctionalProofModel(input: {
|
|
31
25
|
catalog: ToolcraftDeliveryCatalog;
|
|
32
|
-
inventory: ToolcraftVerificationImpactInventory;
|
|
33
26
|
}): ToolcraftFunctionalProofModel;
|
|
34
27
|
export function createToolcraftFunctionalProofModelHash(
|
|
35
28
|
model: ToolcraftFunctionalProofModel,
|
|
@@ -37,11 +30,3 @@ export function createToolcraftFunctionalProofModelHash(
|
|
|
37
30
|
export function getToolcraftFunctionalProofModelError(
|
|
38
31
|
value: unknown,
|
|
39
32
|
): string | undefined;
|
|
40
|
-
export function diffToolcraftFunctionalProofModels(input: {
|
|
41
|
-
current: ToolcraftFunctionalProofModel;
|
|
42
|
-
previous: ToolcraftFunctionalProofModel;
|
|
43
|
-
}): Readonly<{
|
|
44
|
-
acceptanceIds: readonly string[];
|
|
45
|
-
changedOwnerPaths: readonly string[];
|
|
46
|
-
removedAcceptanceIds: readonly string[];
|
|
47
|
-
}>;
|