@warpgogol/werkstatt-shared 0.14.0 → 0.15.0
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/README.md +31 -13
- package/README.uk.md +25 -15
- package/package.json +519 -762
- package/src/{share/agent → agent}/ard-catalog.ts +6 -1
- package/src/{share/agent → agent}/dns-aid.test.ts +2 -2
- package/src/{share/agent → agent}/manifest.ts +15 -1
- package/src/{share/agent → agent}/search.ts +6 -1
- package/src/{share → agent}/tests/api-catalog.test.ts +2 -2
- package/src/{share → agent}/tests/ard-catalog.test.ts +2 -2
- package/src/{share → agent}/tests/capability.test.ts +1 -1
- package/src/{share → agent}/tests/fleet-catalog.test.ts +1 -1
- package/src/{share → agent}/tests/knowledge.test.ts +2 -2
- package/src/{share → agent}/tests/manifest.test.ts +1 -1
- package/src/{share → agent}/tests/mcp-card.test.ts +2 -2
- package/src/agent/tests/omit-empty.test.ts +33 -0
- package/src/{share → agent}/tests/openapi.test.ts +2 -2
- package/src/{share → agent}/tests/proof.test.ts +1 -1
- package/src/{share → attribution}/material-credits.ts +4 -4
- package/src/{share → checks}/check-hints.ts +6 -1
- package/src/checks/index.ts +4 -1
- package/src/checks/lib/astro-site-url.ts +6 -1
- package/src/checks/lib/i18n.ts +14 -0
- package/src/checks/result-helpers.ts +22 -5
- package/src/checks/tests/remediation-auto-populate.test.ts +83 -0
- package/src/{share → client-scripts}/counter-utils.ts +6 -2
- package/src/{share/scripts → client-scripts}/external-link-qr.ts +11 -16
- package/src/{share/scripts → client-scripts}/external-links.ts +12 -1
- package/src/{share/scripts → client-scripts}/gsap-counter.ts +8 -3
- package/src/client-scripts/index.ts +35 -0
- package/src/{share/scripts → client-scripts}/inline-number-animation.ts +1 -1
- package/src/{share/scripts → client-scripts}/lenis.ts +6 -1
- package/src/{share/scripts → client-scripts}/lordicon.ts +6 -1
- package/src/{share/scripts → client-scripts}/orchestrator.ts +10 -1
- package/src/{share/scripts → client-scripts}/scheduler.ts +6 -1
- package/src/client-scripts/scroll-spy.ts +106 -0
- package/src/client-scripts/tests/external-link-qr.test.ts +8 -0
- package/src/client-scripts/tests/external-links.test.ts +25 -0
- package/src/client-scripts/tests/gsap-counter.test.ts +8 -0
- package/src/client-scripts/tests/gsap-mountain-journey.test.ts +8 -0
- package/src/client-scripts/tests/gsap-parallax.test.ts +8 -0
- package/src/client-scripts/tests/gsap-reveal.test.ts +8 -0
- package/src/client-scripts/tests/gsap-stagger.test.ts +8 -0
- package/src/client-scripts/tests/inline-number-animation.test.ts +8 -0
- package/src/client-scripts/tests/lenis.test.ts +8 -0
- package/src/client-scripts/tests/live-photos.test.ts +8 -0
- package/src/client-scripts/tests/lordicon.test.ts +8 -0
- package/src/client-scripts/tests/orchestrator.test.ts +47 -0
- package/src/client-scripts/tests/scheduler.test.ts +23 -0
- package/src/client-scripts/tests/scroll-spy.test.ts +204 -0
- package/src/{share/scripts → client-scripts/tests}/video-player.test.ts +51 -31
- package/src/component/contracts.ts +206 -0
- package/src/component/index.ts +11 -0
- package/src/{share → content}/content-reference.ts +3 -3
- package/src/{share/content → content}/entity-id.ts +6 -3
- package/src/content/index.ts +3 -0
- package/src/{share/content → content}/merge.ts +6 -1
- package/src/content/system-manifest.test.ts +107 -0
- package/src/content/system-manifest.ts +12 -94
- package/src/{share → content}/tests/resolve-field-path.test.ts +1 -1
- package/src/{share → content}/tests/substitute-deep.test.ts +1 -1
- package/src/content-discipline/index.ts +19 -0
- package/src/{share/content-discipline → content-discipline}/parsers.ts +2 -2
- package/src/{share/env.d.ts → env.d.ts} +6 -3
- package/src/fingerprint/canonical-json.ts +731 -0
- package/src/fingerprint/index.ts +12 -0
- package/src/fingerprint/primitives.ts +72 -0
- package/src/{share/i18n → i18n}/localization.ts +6 -2
- package/src/integration/adapters.ts +10 -71
- package/src/integration/dispatch.ts +1 -1
- package/src/integration/funnel.ts +6 -1
- package/src/integration/index.ts +101 -4
- package/src/integration/lagebild-destination-adapter.ts +108 -0
- package/src/integration/lagebild-ingress.ts +7 -12
- package/src/integration/orchestration.ts +11 -10
- package/src/integration/tests/deliver-event.test.ts +1 -1
- package/src/integration/tests/dispatch.test.ts +4 -4
- package/src/integration/tests/hub-runtime.test.ts +22 -14
- package/src/integration/vitest.config.ts +8 -0
- package/src/kernel/desired-state.ts +227 -0
- package/src/kernel/diagnostic.ts +289 -0
- package/src/kernel/fs-atomic.ts +131 -0
- package/src/kernel/index.ts +15 -0
- package/src/kernel/tests/fs-atomic.test.ts +150 -0
- package/src/kernel/tests/workspace-io.test.ts +187 -0
- package/src/kernel/types.ts +459 -0
- package/src/kernel/workspace-io.ts +248 -0
- package/src/{share → knowledge}/tests/claim.test.ts +1 -1
- package/src/{share → knowledge}/tests/derivation.test.ts +1 -1
- package/src/{share → knowledge}/tests/freshness.test.ts +1 -1
- package/src/{share → knowledge}/tests/ledger.test.ts +1 -1
- package/src/{share → knowledge}/tests/plan.test.ts +1 -1
- package/src/{share → knowledge}/tests/source.test.ts +1 -1
- package/src/legal/index.ts +15 -0
- package/src/{share/middleware → middleware}/access-protection.ts +8 -8
- package/src/{share → node}/dev-props-validator.ts +6 -1
- package/src/{share → node}/import-scan.ts +23 -3
- package/src/{share → node}/semantic/derived-prices-loader.ts +4 -2
- package/src/{share → node}/semantic/markdown-twin-provenance.ts +1 -1
- package/src/node/tests/derived-prices-loader.test.ts +59 -0
- package/src/node/tests/markdown-twin-provenance.test.ts +152 -0
- package/src/observability/env-resolver.ts +6 -1
- package/src/observability/index.ts +6 -1
- package/src/observability/otlp-converter.ts +6 -1
- package/src/observability/otlp-transport.ts +6 -1
- package/src/observability/pusher.ts +6 -1
- package/src/observability/redact.ts +6 -1
- package/src/observability/typed-refs.ts +6 -2
- package/src/observability/vitest.config.ts +1 -0
- package/src/{share → offers}/formula-eval.ts +3 -3
- package/src/{share → offers}/tests/formula-eval.test.ts +2 -2
- package/src/onboarding/index.ts +1 -0
- package/src/{share → onboarding}/tests/onboarding-yaml.test.ts +1 -1
- package/src/ontology/archetype-registry.ts +6 -1
- package/src/ontology/archetypes/index.json +33 -1
- package/src/ontology/archetypes/index.yaml +27 -1
- package/src/ontology/archetypes/sections/entity-grid.yaml +46 -0
- package/src/ontology/archetypes/sections/exit-diagram.yaml +43 -0
- package/src/ontology/biome-token-projection.ts +6 -1
- package/src/ontology/cosmic/index.ts +6 -1
- package/src/ontology/cosmic/moon-catalog.ts +6 -1
- package/src/ontology/cosmic/planet-catalog.ts +6 -1
- package/src/ontology/cosmic/star-catalog.ts +6 -1
- package/src/ontology/enums.ts +6 -1
- package/src/ontology/external-surfaces/index.ts +1 -1
- package/src/ontology/index.ts +6 -2
- package/src/ontology/manifest.ts +26 -4
- package/src/ontology/operations/artifact-store.ts +45 -0
- package/src/ontology/operations/dht.ts +98 -0
- package/src/ontology/operations/handoff.ts +92 -0
- package/src/ontology/operations/index.ts +187 -1
- package/src/ontology/operations/leitstand.ts +99 -0
- package/src/ontology/operations/materialization.ts +90 -0
- package/src/ontology/operations/mission.ts +111 -0
- package/src/ontology/operations/naming-policy.ts +132 -0
- package/src/ontology/operations/notausgang.ts +64 -0
- package/src/ontology/operations/release.ts +121 -0
- package/src/ontology/operations/sternsystem.ts +192 -0
- package/src/ontology/operations/werkstatt.ts +48 -0
- package/src/ontology/schemas/biome.ts +7 -2
- package/src/ontology/schemas/capability.ts +1 -1
- package/src/ontology/schemas/constellation.ts +6 -1
- package/src/ontology/schemas/index.ts +6 -2
- package/src/ontology/schemas/manifest-resolver.ts +6 -1
- package/src/ontology/schemas/page-entry.ts +9 -5
- package/src/ontology/schemas/system/growth.ts +6 -1
- package/src/ontology/schemas/system/manifest.ts +40 -1
- package/src/ontology/schemas/system/page-output.ts +7 -6
- package/src/ontology/schemas/system/tests/growth.test.ts +22 -0
- package/src/ontology/schemas/system/tests/integrations.test.ts +12 -0
- package/src/ontology/schemas/system/tests/manifest.test.ts +22 -0
- package/src/ontology/schemas/system/tests/page-output.test.ts +13 -0
- package/src/ontology/schemas/system/tests/release.test.ts +22 -0
- package/src/ontology/schemas/system/tests/text.test.ts +18 -0
- package/src/ontology/schemas/system/tests/verification.test.ts +12 -0
- package/src/ontology/schemas/system/text.ts +15 -0
- package/src/ontology/schemas/system.ts +6 -2
- package/src/ontology/schemas/tests/biome.test.ts +19 -0
- package/src/ontology/schemas/tests/capability.test.ts +22 -0
- package/src/ontology/schemas/tests/constellation.test.ts +22 -0
- package/src/ontology/schemas/tests/dns-records.test.ts +13 -0
- package/src/ontology/schemas/tests/manifest-resolver.test.ts +13 -0
- package/src/ontology/schemas/tests/page-entry.test.ts +22 -0
- package/src/ontology/schemas/tests/section-archetype.test.ts +12 -0
- package/src/ontology/schemas/tests/site-family.test.ts +18 -0
- package/src/ontology/schemas/tests/system.test.ts +20 -0
- package/src/ontology/shared-section-props/body-fragments.ts +2 -0
- package/src/ontology/tests/sternsystem-owner.test.ts +1 -1
- package/src/ontology/vitest.config.ts +1 -0
- package/src/{share → page}/page.ts +13 -9
- package/src/{share → page}/tests/dev-props-validator.test.ts +1 -1
- package/src/{share → page}/tests/hero-section-numbering-parity.test.ts +1 -1
- package/src/passport/index.ts +6 -1
- package/src/passport/key-rotate.ts +10 -2
- package/src/passport/schema.ts +6 -1
- package/src/passport/sign.ts +8 -3
- package/src/passport/vitest.config.ts +1 -0
- package/src/pbt/index.test.ts +95 -0
- package/src/pbt/index.ts +251 -0
- package/src/plugin/plugin-contract.ts +1 -1
- package/src/{share → policy}/entitlement.ts +24 -4
- package/src/{share → policy}/feature-policy.ts +8 -3
- package/src/{share → policy}/visibility.ts +7 -2
- package/src/redirects/redirects.ts +117 -0
- package/src/{share → redirects/tests}/redirects.test.ts +1 -1
- package/src/remediation/remediation-catalog.ts +316 -0
- package/src/{share/routes → routes}/template-filter.ts +1 -1
- package/src/{share → runtime}/runtime-context.ts +7 -2
- package/src/{share → runtime}/shared-context.ts +1 -1
- package/src/{share/schemas → schemas}/claims.ts +2 -2
- package/src/{share/schemas → schemas}/effects.ts +6 -1
- package/src/{share/schemas → schemas}/features.ts +1 -1
- package/src/{share/schemas → schemas}/index.ts +3 -3
- package/src/{share/schemas → schemas}/navigation.ts +6 -1
- package/src/{share/schemas → schemas}/page-base.ts +6 -2
- package/src/{share/schemas → schemas}/person.ts +1 -1
- package/src/{share/schemas → schemas}/standard-list-item.ts +1 -1
- package/src/schemas/tests/claim-records.test.ts +52 -0
- package/src/schemas/tests/claims.test.ts +23 -0
- package/src/schemas/tests/effects.test.ts +116 -0
- package/src/schemas/tests/features.test.ts +61 -0
- package/src/schemas/tests/horizontal-align.test.ts +16 -0
- package/src/schemas/tests/icon-color.test.ts +16 -0
- package/src/schemas/tests/live-photo.test.ts +40 -0
- package/src/schemas/tests/material-credit.test.ts +51 -0
- package/src/schemas/tests/media.test.ts +26 -0
- package/src/schemas/tests/navigation.test.ts +58 -0
- package/src/schemas/tests/page-base.test.ts +19 -0
- package/src/schemas/tests/participant.test.ts +26 -0
- package/src/schemas/tests/person.test.ts +12 -0
- package/src/schemas/tests/print.test.ts +30 -0
- package/src/schemas/tests/section-background.test.ts +31 -0
- package/src/schemas/tests/section-body.test.ts +16 -0
- package/src/schemas/tests/section-cards.test.ts +17 -0
- package/src/schemas/tests/section-cta.test.ts +41 -0
- package/src/schemas/tests/section-header.test.ts +31 -0
- package/src/schemas/tests/section-image.test.ts +24 -0
- package/src/schemas/tests/section-motion.test.ts +29 -0
- package/src/schemas/tests/section-shell.test.ts +42 -0
- package/src/schemas/tests/section-stats.test.ts +17 -0
- package/src/schemas/tests/site-background.test.ts +33 -0
- package/src/schemas/tests/standard-list-item.test.ts +16 -0
- package/src/{share → sections}/rfc0042-utils.ts +1 -1
- package/src/{share/semantic → semantic}/block-extractors/index.ts +20 -1
- package/src/{share/semantic → semantic}/business-projection.ts +95 -1
- package/src/semantic/canonical-uri.ts +54 -0
- package/src/{share/semantic → semantic}/extract.ts +100 -1
- package/src/semantic/fact-extraction.test.ts +47 -0
- package/src/semantic/fact-extraction.ts +46 -0
- package/src/semantic/freshness.ts +67 -0
- package/src/{share/semantic → semantic}/ids.ts +6 -1
- package/src/{share/semantic → semantic}/index.ts +9 -2
- package/src/{share/semantic → semantic}/jsonld/breadcrumb.ts +6 -2
- package/src/{share/semantic → semantic}/jsonld/context.ts +6 -2
- package/src/{share/semantic → semantic}/jsonld/faq.ts +6 -2
- package/src/{share/semantic → semantic}/jsonld/initiative.ts +6 -1
- package/src/{share/semantic → semantic}/jsonld/organization.ts +6 -1
- package/src/{share/semantic → semantic}/jsonld/person.ts +6 -2
- package/src/{share/semantic → semantic}/jsonld/service.ts +6 -2
- package/src/semantic/jsonld/shared.ts +36 -0
- package/src/semantic/jsonld/tests/article.test.ts +89 -0
- package/src/semantic/jsonld/tests/breadcrumb.test.ts +62 -0
- package/src/semantic/jsonld/tests/collection-list.test.ts +39 -0
- package/src/semantic/jsonld/tests/faq.test.ts +60 -0
- package/src/semantic/jsonld/tests/initiative.test.ts +56 -0
- package/src/semantic/jsonld/tests/organization.test.ts +123 -0
- package/src/semantic/jsonld/tests/person.test.ts +89 -0
- package/src/semantic/jsonld/tests/service.test.ts +65 -0
- package/src/semantic/jsonld/tests/shared.test.ts +41 -0
- package/src/semantic/jsonld/tests/video.test.ts +84 -0
- package/src/semantic/jsonld/tests/webpage.test.ts +93 -0
- package/src/semantic/jsonld/tests/website.test.ts +27 -0
- package/src/semantic/jsonld/types.ts +24 -0
- package/src/{share/semantic → semantic}/jsonld/webpage.ts +6 -1
- package/src/semantic/jsonld/website.ts +32 -0
- package/src/{share/semantic → semantic}/jsonld.ts +6 -1
- package/src/{share/semantic → semantic}/llms.ts +41 -3
- package/src/{share/semantic → semantic}/models.ts +27 -38
- package/src/{share/semantic → semantic}/organization-profile.ts +3 -0
- package/src/{share/semantic → semantic}/page-builders/markdown-page.ts +6 -3
- package/src/{share/semantic → semantic}/page-utils.ts +6 -3
- package/src/semantic/tests/ai.test.ts +55 -0
- package/src/semantic/tests/block-extraction.test.ts +34 -0
- package/src/{share/tests/breadcrumbs.test.ts → semantic/tests/breadcrumbs-0229.test.ts} +1 -1
- package/src/semantic/tests/breadcrumbs.test.ts +127 -0
- package/src/{share → semantic}/tests/build-page-price-markers.test.ts +2 -2
- package/src/semantic/tests/build-page.test.ts +122 -0
- package/src/semantic/tests/business-projection.test.ts +367 -0
- package/src/semantic/tests/canonical-uri.test.ts +56 -0
- package/src/semantic/tests/extract.test.ts +209 -0
- package/src/semantic/tests/feed.test.ts +113 -0
- package/src/semantic/tests/freshness.pbt.test.ts +108 -0
- package/src/semantic/tests/helpers.ts +32 -0
- package/src/semantic/tests/ids.test.ts +118 -0
- package/src/{share/tests/image-sitemap.test.ts → semantic/tests/image-sitemap-0150.test.ts} +1 -1
- package/src/semantic/tests/image-sitemap.test.ts +109 -0
- package/src/{share → semantic}/tests/jsonld-service.test.ts +2 -2
- package/src/{share → semantic}/tests/jsonld-video.test.ts +3 -3
- package/src/{share → semantic}/tests/jsonld-webpage.test.ts +3 -3
- package/src/semantic/tests/jsonld.test.ts +61 -0
- package/src/{share → semantic}/tests/llms-0789.test.ts +2 -2
- package/src/semantic/tests/llms-policy.test.ts +60 -0
- package/src/semantic/tests/llms.test.ts +164 -0
- package/src/semantic/tests/markdown-hygiene.test.ts +72 -0
- package/src/semantic/tests/markdown-page.test.ts +97 -0
- package/src/{share → semantic}/tests/organization-jsonld.test.ts +3 -3
- package/src/semantic/tests/organization-profile.test.ts +107 -0
- package/src/{share/tests/output-projection.test.ts → semantic/tests/output-projection-0143.test.ts} +1 -1
- package/src/semantic/tests/output-projection.test.ts +77 -0
- package/src/semantic/tests/page-markdown.test.ts +98 -0
- package/src/semantic/tests/page-utils.test.ts +88 -0
- package/src/{share/tests/price-marker-resolver.test.ts → semantic/tests/price-marker-resolver-0767.test.ts} +2 -2
- package/src/semantic/tests/price-marker-resolver.test.ts +90 -0
- package/src/semantic/tests/project-claims.pbt.test.ts +60 -0
- package/src/semantic/tests/robots.test.ts +70 -0
- package/src/{share/semantic → semantic}/tests/split-sentences.test.ts +1 -1
- package/src/{share → semantic}/tests/twin-path.test.ts +1 -1
- package/src/semantic/tests/update-stamp.test.ts +102 -0
- package/src/signing/index.ts +13 -0
- package/src/signing/key.ts +139 -0
- package/src/signing/sign.ts +66 -0
- package/src/signing/types.ts +29 -0
- package/src/{share/slug → slug}/slug-url.ts +4 -1
- package/src/stack/run-tool.ts +108 -0
- package/src/stack/stack-checks.ts +124 -0
- package/src/stack/tests/run-tool.test.ts +138 -0
- package/src/stack/tests/stack-checks.test.ts +141 -0
- package/src/stack/tests/walk-files.test.ts +131 -0
- package/src/stack/walk-files.ts +114 -0
- package/src/surface/blueprint.ts +342 -66
- package/src/surface/decision-composer.ts +6 -1
- package/src/surface/geo.ts +6 -1
- package/src/surface/index.ts +11 -7
- package/src/surface/types.ts +2 -2
- package/src/surface/vitest.config.ts +1 -0
- package/src/tests/signing-core.test.ts +129 -0
- package/src/{share → text}/css-value-normalize.ts +6 -1
- package/src/text/string-utils.ts +24 -0
- package/src/{share → text}/tests/text-normalize.test.ts +5 -0
- package/src/{share → text}/text-normalize.ts +4 -3
- package/src/{share → text}/wrap-inline-numbers.ts +1 -1
- package/src/types/axiom-study.d.ts +36 -0
- package/src/types/hls-js-light.d.ts +21 -0
- package/src/types/qrcode-browser.d.ts +23 -0
- package/src/typography/fix.pbt.test.ts +208 -0
- package/src/typography/fix.ts +148 -0
- package/src/typography/index.ts +54 -0
- package/src/typography/locale-defaults.ts +97 -0
- package/src/typography/rules-tier1.test.ts +459 -0
- package/src/typography/rules-tier1.ts +925 -0
- package/src/typography/rules-tier2-locale.pbt.test.ts +190 -0
- package/src/typography/rules-tier2-locale.test.ts +286 -0
- package/src/typography/rules-tier2-locale.ts +399 -0
- package/src/typography/rules-tier2-structure.test.ts +330 -0
- package/src/typography/rules-tier2-structure.ts +378 -0
- package/src/typography/rules-tier3-advisory.test.ts +290 -0
- package/src/typography/rules-tier3-advisory.ts +239 -0
- package/src/typography/text-surface.test.ts +244 -0
- package/src/typography/text-surface.ts +448 -0
- package/src/index.ts +0 -14
- package/src/integration/port-barrel.ts +0 -105
- package/src/share/content/index.ts +0 -16
- package/src/share/content-discipline/index.ts +0 -14
- package/src/share/index.ts +0 -86
- package/src/share/legal/index.ts +0 -1
- package/src/share/redirects.ts +0 -54
- package/src/share/scripts/index.ts +0 -26
- package/src/share/semantic/jsonld/shared.ts +0 -31
- package/src/share/semantic/jsonld/types.ts +0 -18
- package/src/share/semantic/jsonld/website.ts +0 -27
- package/src/share/string-utils.ts +0 -19
- package/src/share/types/axiom-study.d.ts +0 -22
- package/src/share/types/hls-js-light.d.ts +0 -16
- package/src/share/types/qrcode-browser.d.ts +0 -18
- package/src/share/utility-registry.yaml +0 -36
- package/src/share/vitest.config.ts +0 -8
- package/src/surface/blueprint-schema.ts +0 -314
- package/src/surface/blueprint-types.ts +0 -256
- /package/src/{share/agent → agent}/api-catalog.ts +0 -0
- /package/src/{share/agent → agent}/capability.ts +0 -0
- /package/src/{share/agent → agent}/dns-aid.ts +0 -0
- /package/src/{share/agent → agent}/fleet-catalog.ts +0 -0
- /package/src/{share/agent → agent}/index.ts +0 -0
- /package/src/{share/agent → agent}/knowledge.ts +0 -0
- /package/src/{share/agent → agent}/mcp-card.ts +0 -0
- /package/src/{share/agent → agent}/omit-empty.ts +0 -0
- /package/src/{share/agent → agent}/openapi.ts +0 -0
- /package/src/{share/agent → agent}/proof.ts +0 -0
- /package/src/{share/agent → agent}/search.test.ts +0 -0
- /package/src/{share → attribution}/attribution-display.ts +0 -0
- /package/src/{share/scripts → client-scripts}/gsap-mountain-journey.ts +0 -0
- /package/src/{share/scripts → client-scripts}/gsap-parallax.ts +0 -0
- /package/src/{share/scripts → client-scripts}/gsap-reveal.ts +0 -0
- /package/src/{share/scripts → client-scripts}/gsap-stagger.ts +0 -0
- /package/src/{share/scripts → client-scripts}/live-photos.ts +0 -0
- /package/src/{share/scripts → client-scripts}/video-player.ts +0 -0
- /package/src/{share/content → content}/resolve-field-path.ts +0 -0
- /package/src/{share/content → content}/substitute-deep.ts +0 -0
- /package/src/{share → content}/tests/content-ref-index.test.ts +0 -0
- /package/src/{share/content-discipline → content-discipline}/types.ts +0 -0
- /package/src/{share → image-provider}/image-provider.ts +0 -0
- /package/src/{share/knowledge → knowledge}/claim.ts +0 -0
- /package/src/{share/knowledge → knowledge}/derivation.ts +0 -0
- /package/src/{share/knowledge → knowledge}/freshness.ts +0 -0
- /package/src/{share/knowledge → knowledge}/index.ts +0 -0
- /package/src/{share/knowledge → knowledge}/ledger.ts +0 -0
- /package/src/{share/knowledge → knowledge}/plan.ts +0 -0
- /package/src/{share/knowledge → knowledge}/source.ts +0 -0
- /package/src/{share/legal → legal}/translation-policy.ts +0 -0
- /package/src/{share/middleware → middleware}/language-redirect.ts +0 -0
- /package/src/{share/middleware → middleware}/tests/access-protection.test.ts +0 -0
- /package/src/{share → node}/fs/index.ts +0 -0
- /package/src/{share/tests/markdown-twin-provenance.test.ts → node/tests/markdown-twin-provenance-0613.test.ts} +0 -0
- /package/src/{share → offers}/offer-capacity.ts +0 -0
- /package/src/{share/onboarding-yaml/index.ts → onboarding/yaml.ts} +0 -0
- /package/src/{share → ontology}/tests/ontology-role-by-cosmic-name.test.ts +0 -0
- /package/src/{share/routes → routes}/tests/template-filter.test.ts +0 -0
- /package/src/{share/schemas → schemas}/claim-records.ts +0 -0
- /package/src/{share/schemas → schemas}/horizontal-align.ts +0 -0
- /package/src/{share/schemas → schemas}/icon-color.ts +0 -0
- /package/src/{share/schemas → schemas}/live-photo.ts +0 -0
- /package/src/{share/schemas → schemas}/material-credit.ts +0 -0
- /package/src/{share/schemas → schemas}/media.ts +0 -0
- /package/src/{share/schemas → schemas}/participant.ts +0 -0
- /package/src/{share/schemas → schemas}/print.ts +0 -0
- /package/src/{share/schemas → schemas}/section-background.ts +0 -0
- /package/src/{share/schemas → schemas}/section-body.ts +0 -0
- /package/src/{share/schemas → schemas}/section-cards.ts +0 -0
- /package/src/{share/schemas → schemas}/section-cta.ts +0 -0
- /package/src/{share/schemas → schemas}/section-header.ts +0 -0
- /package/src/{share/schemas → schemas}/section-image.ts +0 -0
- /package/src/{share/schemas → schemas}/section-motion.ts +0 -0
- /package/src/{share/schemas → schemas}/section-shell.ts +0 -0
- /package/src/{share/schemas → schemas}/section-stats.ts +0 -0
- /package/src/{share/schemas → schemas}/site-background.ts +0 -0
- /package/src/{share/semantic → semantic}/ai.ts +0 -0
- /package/src/{share/semantic → semantic}/block-extraction.ts +0 -0
- /package/src/{share/semantic → semantic}/breadcrumbs.ts +0 -0
- /package/src/{share/semantic → semantic}/build-page.ts +0 -0
- /package/src/{share/semantic → semantic}/feed.ts +0 -0
- /package/src/{share/semantic → semantic}/image-sitemap.ts +0 -0
- /package/src/{share/semantic → semantic}/jsonld/article.ts +0 -0
- /package/src/{share/semantic → semantic}/jsonld/collection-list.ts +0 -0
- /package/src/{share/semantic → semantic}/jsonld/video.ts +0 -0
- /package/src/{share/semantic → semantic}/llms-policy.ts +0 -0
- /package/src/{share/semantic → semantic}/markdown-hygiene.ts +0 -0
- /package/src/{share/semantic → semantic}/output-projection.ts +0 -0
- /package/src/{share/semantic → semantic}/page-markdown.ts +0 -0
- /package/src/{share/semantic → semantic}/price-marker-resolver.ts +0 -0
- /package/src/{share/semantic → semantic}/robots.ts +0 -0
- /package/src/{share/semantic → semantic}/update-stamp.ts +0 -0
- /package/src/{share/slug → slug}/heading-slugger.ts +0 -0
- /package/src/{share/slug → slug}/index.ts +0 -0
- /package/src/{share/slug → slug}/slug-id.ts +0 -0
- /package/src/{share/slug → slug}/strategies.ts +0 -0
- /package/src/{share/slug → slug}/tests/slug.test.ts +0 -0
- /package/src/{share → text}/tests/text-normalize.pbt.test.ts +0 -0
- /package/src/{share → text}/text-position.ts +0 -0
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
/*
|
|
2
2
|
<MODULE_CONTRACT>
|
|
3
|
-
<purpose>
|
|
3
|
+
<purpose>key-rotate — facilitates the generation and rotation of Ed25519 keypairs for secure application authentication.</purpose>
|
|
4
4
|
<non-goals>
|
|
5
5
|
<item>Do not handle raw key parsing or validation beyond schema checks.</item>
|
|
6
6
|
<item>Do not manage application configuration or orchestration.</item>
|
|
7
7
|
</non-goals>
|
|
8
8
|
</MODULE_CONTRACT>
|
|
9
9
|
<CHANGE_SUMMARY>
|
|
10
|
-
<item>
|
|
10
|
+
<item>RFC-1097: step 6 — compass.migrate codemod run
|
|
11
|
+
|
|
12
|
+
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
|
|
13
|
+
<item>RFC-1097: sweep — tail packages clean
|
|
14
|
+
|
|
15
|
+
Sweep batch 3: rewrote ~95 purposes across werkstatt-knowledge, werkstatt-shared, godot-game, phaser-game, lifecycle-core, projektarchiv-*, portal-*, billing-*, typescript (CONTRACT-02/PURPOSE-02). Real KEY_DECISIONS on 5 godot utils, non-goals on 5 CONTRACT-03 files, headers on 4 headerless files, CS-07 history literal fix on 2 files. Policy: vitest.config.ts + test-fixtures testPatterns, worker-configuration.d.ts excludedPath. All non-site/engine packages now 0 diagnostics.</item>
|
|
16
|
+
<item>RFC-1097: sweep — werkstatt-engine clean
|
|
17
|
+
|
|
18
|
+
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
|
|
11
19
|
</CHANGE_SUMMARY>
|
|
12
20
|
*/
|
|
13
21
|
|
package/src/passport/schema.ts
CHANGED
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
</MODULE_CONTRACT>
|
|
12
12
|
|
|
13
13
|
<CHANGE_SUMMARY>
|
|
14
|
-
<item>
|
|
14
|
+
<item>RFC-1097: step 6 — compass.migrate codemod run
|
|
15
|
+
|
|
16
|
+
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
|
|
17
|
+
<item>RFC-1097: sweep — werkstatt-engine clean
|
|
18
|
+
|
|
19
|
+
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
|
|
15
20
|
</CHANGE_SUMMARY>
|
|
16
21
|
*******************************************************************************/
|
|
17
22
|
|
package/src/passport/sign.ts
CHANGED
|
@@ -7,8 +7,13 @@
|
|
|
7
7
|
</non-goals>
|
|
8
8
|
</MODULE_CONTRACT>
|
|
9
9
|
<CHANGE_SUMMARY>
|
|
10
|
-
<item>
|
|
11
|
-
<item>RFC-
|
|
10
|
+
<item>RFC-0921: delegate Ed25519 sign/verify/keygen to shared signing core (@warpgogol/werkstatt-shared/signing). Remove @noble/ed25519 import.</item>
|
|
11
|
+
<item>RFC-1097: step 6 — compass.migrate codemod run
|
|
12
|
+
|
|
13
|
+
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
|
|
14
|
+
<item>RFC-1097: sweep — werkstatt-engine clean
|
|
15
|
+
|
|
16
|
+
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
|
|
12
17
|
</CHANGE_SUMMARY> */
|
|
13
18
|
|
|
14
19
|
/**
|
|
@@ -32,7 +37,7 @@ import {
|
|
|
32
37
|
verifyBytes as signingVerifyBytes,
|
|
33
38
|
fromHex,
|
|
34
39
|
toHex,
|
|
35
|
-
} from "@warpgogol/werkstatt-
|
|
40
|
+
} from "@warpgogol/werkstatt-shared/signing";
|
|
36
41
|
import type { VCProof, VerifiableCredential } from "./schema.ts";
|
|
37
42
|
|
|
38
43
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
fcAssert,
|
|
4
|
+
letterString,
|
|
5
|
+
composeWord,
|
|
6
|
+
safeText,
|
|
7
|
+
DEFAULT_NUM_RUNS,
|
|
8
|
+
DEFAULT_MAX_SKIPS_PER_RUN,
|
|
9
|
+
} from "./index.ts";
|
|
10
|
+
import fc from "fast-check";
|
|
11
|
+
|
|
12
|
+
describe("PBT helpers", () => {
|
|
13
|
+
describe("constants", () => {
|
|
14
|
+
it("DEFAULT_NUM_RUNS is 50", () => {
|
|
15
|
+
expect(DEFAULT_NUM_RUNS).toBe(50);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("DEFAULT_MAX_SKIPS_PER_RUN is 100", () => {
|
|
19
|
+
expect(DEFAULT_MAX_SKIPS_PER_RUN).toBe(100);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("letterString", () => {
|
|
24
|
+
it("generates only letters (\\p{L}+)", () => {
|
|
25
|
+
fcAssert(
|
|
26
|
+
fc.property(letterString(1, 10), (word) => {
|
|
27
|
+
return /^\p{L}+$/u.test(word);
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("respects minLength", () => {
|
|
33
|
+
fcAssert(
|
|
34
|
+
fc.property(letterString(3, 5), (word) => {
|
|
35
|
+
return word.length >= 3 && word.length <= 5;
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("never generates empty string when minLength=1", () => {
|
|
41
|
+
fcAssert(
|
|
42
|
+
fc.property(letterString(1, 5), (word) => {
|
|
43
|
+
return word.length > 0;
|
|
44
|
+
}),
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("composeWord", () => {
|
|
50
|
+
it("generates letter + separator + letter", () => {
|
|
51
|
+
const sep = "\u2019";
|
|
52
|
+
fcAssert(
|
|
53
|
+
fc.property(composeWord(sep), (word) => {
|
|
54
|
+
return /\p{L}+\u2019\p{L}+/u.test(word);
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("contains exactly one separator", () => {
|
|
60
|
+
const sep = "-";
|
|
61
|
+
fcAssert(
|
|
62
|
+
fc.property(composeWord(sep), (word) => {
|
|
63
|
+
const count = (word.match(/-/g) ?? []).length;
|
|
64
|
+
return count === 1;
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe("safeText", () => {
|
|
71
|
+
it("respects maxLength", () => {
|
|
72
|
+
fcAssert(
|
|
73
|
+
fc.property(safeText(50), (text) => {
|
|
74
|
+
return text.length <= 50;
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe("fcAssert", () => {
|
|
81
|
+
it("accepts custom numRuns", () => {
|
|
82
|
+
fcAssert(
|
|
83
|
+
fc.property(letterString(1, 3), (word) => word.length > 0),
|
|
84
|
+
{ numRuns: 10 },
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("accepts custom maxSkipsPerRun", () => {
|
|
89
|
+
fcAssert(
|
|
90
|
+
fc.property(letterString(1, 3), (word) => word.length > 0),
|
|
91
|
+
{ maxSkipsPerRun: 50 },
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
package/src/pbt/index.ts
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
Canonical PBT (property-based testing) helpers for the Werkstatt.
|
|
5
|
+
Provides safe defaults for `fc.assert` (numRuns, maxSkips) and efficient
|
|
6
|
+
arbitraries that avoid the `fc.string().filter()` anti-pattern that causes
|
|
7
|
+
test hangs when the filter regex rejects most generated candidates.
|
|
8
|
+
</purpose>
|
|
9
|
+
<non-goals>
|
|
10
|
+
<item>Does not wrap every fast-check arbitrary — only the ones that need safety defaults.</item>
|
|
11
|
+
<item>Does not replace `fc.assert` entirely — callers can still use it directly with explicit options.</item>
|
|
12
|
+
</non-goals>
|
|
13
|
+
</MODULE_CONTRACT>
|
|
14
|
+
<CHANGE_SUMMARY>
|
|
15
|
+
<item>RFC-1070: Create PBT helpers (fcAssert, letterString, composeWord) to prevent filter-induced hangs.</item>
|
|
16
|
+
</CHANGE_SUMMARY>
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import fc from "fast-check";
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Default PBT configuration
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
/** Default number of property runs. fast-check default is 100; we use 50 for speed. */
|
|
26
|
+
export const DEFAULT_NUM_RUNS = 50;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Default max pre-condition skips per run.
|
|
30
|
+
* fast-check default is 100. We keep it at 100 — this covers `fc.pre()` failures,
|
|
31
|
+
* NOT `.filter()` rejections (which have no limit and are the real hang cause).
|
|
32
|
+
* The hang prevention comes from using `letterString`/`composeWord` instead of
|
|
33
|
+
* `fc.string().filter()`, plus the vitest `testTimeout: 30_000` safety net.
|
|
34
|
+
*/
|
|
35
|
+
export const DEFAULT_MAX_SKIPS_PER_RUN = 100;
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// fcAssert — safe wrapper around fc.assert with defaults
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
export interface FcAssertOptions {
|
|
42
|
+
numRuns?: number;
|
|
43
|
+
maxSkipsPerRun?: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Wraps `fc.assert` with safe defaults: `numRuns: 50`, `maxSkipsPerRun: 100`.
|
|
48
|
+
* Callers can override either value.
|
|
49
|
+
*
|
|
50
|
+
* Note: `maxSkipsPerRun` only covers `fc.pre()` pre-condition failures.
|
|
51
|
+
* It does NOT cover `.filter()` rejections on arbitraries — those have no
|
|
52
|
+
* limit and are the primary cause of test hangs. Use `letterString` or
|
|
53
|
+
* `composeWord` instead of `fc.string().filter()` to avoid this entirely.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* fcAssert(fc.property(letterString, (word) => { ... }));
|
|
57
|
+
* fcAssert(fc.property(letterString, (word) => { ... }), { numRuns: 100 });
|
|
58
|
+
*/
|
|
59
|
+
export function fcAssert<T>(property: fc.IProperty<T>, options?: FcAssertOptions): void {
|
|
60
|
+
fc.assert(property, {
|
|
61
|
+
numRuns: options?.numRuns ?? DEFAULT_NUM_RUNS,
|
|
62
|
+
maxSkipsPerRun: options?.maxSkipsPerRun ?? DEFAULT_MAX_SKIPS_PER_RUN,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Efficient letter-only arbitrary — replaces fc.string().filter(/^\p{L}+$/u)
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Latin + Cyrillic letter characters for efficient generation.
|
|
72
|
+
* Uses `fc.constantFrom` (no filtering) instead of `fc.string().filter()`.
|
|
73
|
+
*/
|
|
74
|
+
const LETTER_CHARS = [
|
|
75
|
+
// Latin lowercase
|
|
76
|
+
"a",
|
|
77
|
+
"b",
|
|
78
|
+
"c",
|
|
79
|
+
"d",
|
|
80
|
+
"e",
|
|
81
|
+
"f",
|
|
82
|
+
"g",
|
|
83
|
+
"h",
|
|
84
|
+
"i",
|
|
85
|
+
"j",
|
|
86
|
+
"k",
|
|
87
|
+
"l",
|
|
88
|
+
"m",
|
|
89
|
+
"n",
|
|
90
|
+
"o",
|
|
91
|
+
"p",
|
|
92
|
+
"q",
|
|
93
|
+
"r",
|
|
94
|
+
"s",
|
|
95
|
+
"t",
|
|
96
|
+
"u",
|
|
97
|
+
"v",
|
|
98
|
+
"w",
|
|
99
|
+
"x",
|
|
100
|
+
"y",
|
|
101
|
+
"z",
|
|
102
|
+
// Latin uppercase
|
|
103
|
+
"A",
|
|
104
|
+
"B",
|
|
105
|
+
"C",
|
|
106
|
+
"D",
|
|
107
|
+
"E",
|
|
108
|
+
"F",
|
|
109
|
+
"G",
|
|
110
|
+
"H",
|
|
111
|
+
"I",
|
|
112
|
+
"J",
|
|
113
|
+
"K",
|
|
114
|
+
"L",
|
|
115
|
+
"M",
|
|
116
|
+
"N",
|
|
117
|
+
"O",
|
|
118
|
+
"P",
|
|
119
|
+
"Q",
|
|
120
|
+
"R",
|
|
121
|
+
"S",
|
|
122
|
+
"T",
|
|
123
|
+
"U",
|
|
124
|
+
"V",
|
|
125
|
+
"W",
|
|
126
|
+
"X",
|
|
127
|
+
"Y",
|
|
128
|
+
"Z",
|
|
129
|
+
// Cyrillic lowercase (Ukrainian + Russian)
|
|
130
|
+
"а",
|
|
131
|
+
"б",
|
|
132
|
+
"в",
|
|
133
|
+
"г",
|
|
134
|
+
"д",
|
|
135
|
+
"е",
|
|
136
|
+
"ж",
|
|
137
|
+
"з",
|
|
138
|
+
"и",
|
|
139
|
+
"і",
|
|
140
|
+
"к",
|
|
141
|
+
"л",
|
|
142
|
+
"м",
|
|
143
|
+
"н",
|
|
144
|
+
"о",
|
|
145
|
+
"п",
|
|
146
|
+
"р",
|
|
147
|
+
"с",
|
|
148
|
+
"т",
|
|
149
|
+
"у",
|
|
150
|
+
"ф",
|
|
151
|
+
"х",
|
|
152
|
+
"ц",
|
|
153
|
+
"ч",
|
|
154
|
+
"ш",
|
|
155
|
+
"щ",
|
|
156
|
+
"ь",
|
|
157
|
+
"ю",
|
|
158
|
+
"я",
|
|
159
|
+
"ї",
|
|
160
|
+
"є",
|
|
161
|
+
"ґ",
|
|
162
|
+
// Cyrillic uppercase
|
|
163
|
+
"А",
|
|
164
|
+
"Б",
|
|
165
|
+
"В",
|
|
166
|
+
"Г",
|
|
167
|
+
"Д",
|
|
168
|
+
"Е",
|
|
169
|
+
"Ж",
|
|
170
|
+
"З",
|
|
171
|
+
"И",
|
|
172
|
+
"І",
|
|
173
|
+
"К",
|
|
174
|
+
"Л",
|
|
175
|
+
"М",
|
|
176
|
+
"Н",
|
|
177
|
+
"О",
|
|
178
|
+
"П",
|
|
179
|
+
"Р",
|
|
180
|
+
"С",
|
|
181
|
+
"Т",
|
|
182
|
+
"У",
|
|
183
|
+
"Ф",
|
|
184
|
+
"Х",
|
|
185
|
+
"Ц",
|
|
186
|
+
"Ч",
|
|
187
|
+
"Ш",
|
|
188
|
+
"Щ",
|
|
189
|
+
"Ь",
|
|
190
|
+
"Ю",
|
|
191
|
+
"Я",
|
|
192
|
+
"Ї",
|
|
193
|
+
"Є",
|
|
194
|
+
"Ґ",
|
|
195
|
+
];
|
|
196
|
+
|
|
197
|
+
const letterArb = fc.constantFrom(...LETTER_CHARS);
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Generates strings consisting only of letters (Latin + Cyrillic).
|
|
201
|
+
* Efficient: uses `fc.constantFrom` + `fc.array` — no filtering.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* const word = letterString(1, 5); // 1-5 letter word
|
|
205
|
+
* fcAssert(fc.property(word, (w) => /^\p{L}+$/u.test(w)));
|
|
206
|
+
*/
|
|
207
|
+
export function letterString(minLength = 1, maxLength = 10): fc.Arbitrary<string> {
|
|
208
|
+
return fc.array(letterArb, { minLength, maxLength }).map((arr) => arr.join(""));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// composeWord — builds words with guaranteed structure (no filter needed)
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
|
|
215
|
+
export interface ComposeWordOptions {
|
|
216
|
+
minLength?: number;
|
|
217
|
+
maxLength?: number;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Generates words with a guaranteed `letter + separator + letter` structure.
|
|
222
|
+
* Eliminates the need for `fc.string().filter()` when testing pattern-based rules.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* const curlyAposWord = composeWord("\u2019"); // e.g. "ім'я"
|
|
226
|
+
* const modAposWord = composeWord("\u02BC"); // e.g. "імʼя"
|
|
227
|
+
*/
|
|
228
|
+
export function composeWord(separator: string, options?: ComposeWordOptions): fc.Arbitrary<string> {
|
|
229
|
+
const min = options?.minLength ?? 1;
|
|
230
|
+
const max = options?.maxLength ?? 5;
|
|
231
|
+
return fc
|
|
232
|
+
.tuple(letterString(min, max), letterString(min, max))
|
|
233
|
+
.map(([a, b]) => `${a}${separator}${b}`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// safeText — bounded-length string for negative tests (no filter needed)
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Generates random strings with a max length for negative property tests.
|
|
242
|
+
* Use when the property should NOT fire on arbitrary text — the test verifies
|
|
243
|
+
* that no findings are produced. The `maxLength` bound prevents excessive
|
|
244
|
+
* string generation time.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* fcAssert(fc.property(safeText(80), (text) => runRule("TYPO-XX", text).length === 0));
|
|
248
|
+
*/
|
|
249
|
+
export function safeText(maxLength = 80): fc.Arbitrary<string> {
|
|
250
|
+
return fc.string({ maxLength });
|
|
251
|
+
}
|
|
@@ -14,7 +14,7 @@ are shared infrastructure, not engine internals.</purpose>
|
|
|
14
14
|
<item>RFC-0942: moved from werkstatt-engine/src/plugin-contract.ts to werkstatt-shared/src/plugin/plugin-contract.ts.</item>
|
|
15
15
|
</CHANGE_SUMMARY>
|
|
16
16
|
*/
|
|
17
|
-
import type { KernelModule, KernelPipelineStep } from "@warpgogol/werkstatt-
|
|
17
|
+
import type { KernelModule, KernelPipelineStep } from "@warpgogol/werkstatt-shared/kernel";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Placeholder type for deploy adapter factories.
|
|
@@ -10,10 +10,16 @@ agnostic contract consumed by the build-time resolver, the feature gates, and ru
|
|
|
10
10
|
</non-goals>
|
|
11
11
|
</MODULE_CONTRACT>
|
|
12
12
|
<CHANGE_SUMMARY>
|
|
13
|
-
<item>RFC-0169: initial implementation.</item>
|
|
14
13
|
<item>RFC-0706: add nachweis feature for Nachweisregister commercial module.</item>
|
|
15
14
|
<item>RFC-0741: add multi-currency feature for multi-currency build pipeline.</item>
|
|
16
15
|
<item>RFC-0932: add external-link-qr feature for QR code modal entitlement module.</item>
|
|
16
|
+
<item>RFC-1097: step 6 — compass.migrate codemod run
|
|
17
|
+
|
|
18
|
+
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
|
|
19
|
+
<item>RFC-1097: sweep — werkstatt-engine clean
|
|
20
|
+
|
|
21
|
+
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
|
|
22
|
+
<history>RFC-0169</history>
|
|
17
23
|
</CHANGE_SUMMARY>
|
|
18
24
|
*/
|
|
19
25
|
|
|
@@ -42,6 +48,12 @@ export const ENTITLED_FEATURES = [
|
|
|
42
48
|
"external-link-qr",
|
|
43
49
|
] as const;
|
|
44
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Features that are always enabled for all sites, regardless of Stripe or override state.
|
|
53
|
+
* These are platform-level capabilities that every site gets for free.
|
|
54
|
+
*/
|
|
55
|
+
export const FREE_ENTITLED_FEATURES: EntitledFeature[] = ["external-link-qr"];
|
|
56
|
+
|
|
45
57
|
export type EntitledFeature = (typeof ENTITLED_FEATURES)[number];
|
|
46
58
|
|
|
47
59
|
/** Stripe Feature `lookup_key` → EntitledFeature. The single mapping point. */
|
|
@@ -149,10 +161,13 @@ export function resolveEntitlements(input: {
|
|
|
149
161
|
? { pseo: { indexBudget: input.pseoIndexBudget, regionalUnlocked } }
|
|
150
162
|
: {};
|
|
151
163
|
|
|
164
|
+
const mergeFree = (features: string[]): EntitledFeature[] =>
|
|
165
|
+
dedupe([...features, ...FREE_ENTITLED_FEATURES]);
|
|
166
|
+
|
|
152
167
|
if (input.override && input.override.length > 0) {
|
|
153
168
|
return {
|
|
154
169
|
customerId: input.customerId,
|
|
155
|
-
features:
|
|
170
|
+
features: mergeFree(input.override),
|
|
156
171
|
source: "override",
|
|
157
172
|
...pseo,
|
|
158
173
|
};
|
|
@@ -160,12 +175,17 @@ export function resolveEntitlements(input: {
|
|
|
160
175
|
if (input.stripeFeatures) {
|
|
161
176
|
return {
|
|
162
177
|
customerId: input.customerId,
|
|
163
|
-
features:
|
|
178
|
+
features: mergeFree(input.stripeFeatures),
|
|
164
179
|
source: "stripe",
|
|
165
180
|
...pseo,
|
|
166
181
|
};
|
|
167
182
|
}
|
|
168
|
-
return {
|
|
183
|
+
return {
|
|
184
|
+
customerId: input.customerId,
|
|
185
|
+
features: dedupe([...FREE_ENTITLED_FEATURES]),
|
|
186
|
+
source: "none",
|
|
187
|
+
...pseo,
|
|
188
|
+
};
|
|
169
189
|
}
|
|
170
190
|
|
|
171
191
|
/** Reader used by build gates (which modules compile) and runtime endpoints. */
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
</MODULE_CONTRACT>
|
|
10
10
|
<CHANGE_SUMMARY>
|
|
11
11
|
<item>RFC-0183: Initial runtime resolver for Feature Policy without Feature Graph dependency.</item>
|
|
12
|
-
<item>
|
|
12
|
+
<item>RFC-1097: step 6 — compass.migrate codemod run
|
|
13
|
+
|
|
14
|
+
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
|
|
15
|
+
<item>RFC-1097: sweep — werkstatt-engine clean
|
|
16
|
+
|
|
17
|
+
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
|
|
13
18
|
</CHANGE_SUMMARY>
|
|
14
19
|
*/
|
|
15
20
|
|
|
@@ -19,7 +24,7 @@ import type {
|
|
|
19
24
|
FeaturePolicyTargetRef,
|
|
20
25
|
FeaturePolicyVisibility,
|
|
21
26
|
ResolvedFeaturePolicy,
|
|
22
|
-
} from "
|
|
27
|
+
} from "../schemas/features.ts";
|
|
23
28
|
|
|
24
29
|
// Re-export types for consumers
|
|
25
30
|
export type {
|
|
@@ -29,7 +34,7 @@ export type {
|
|
|
29
34
|
FeaturePolicyTargetRef,
|
|
30
35
|
FeaturePolicyVisibility,
|
|
31
36
|
ResolvedFeaturePolicy,
|
|
32
|
-
} from "
|
|
37
|
+
} from "../schemas/features.ts";
|
|
33
38
|
|
|
34
39
|
export interface FeaturePolicyResolverOptions {
|
|
35
40
|
/**
|
|
@@ -15,12 +15,17 @@ requires a superseding RFC.
|
|
|
15
15
|
</non-goals>
|
|
16
16
|
</MODULE_CONTRACT>
|
|
17
17
|
<CHANGE_SUMMARY>
|
|
18
|
-
<item>
|
|
18
|
+
<item>RFC-1097: step 6 — compass.migrate codemod run
|
|
19
|
+
|
|
20
|
+
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
|
|
21
|
+
<item>RFC-1097: sweep — werkstatt-engine clean
|
|
22
|
+
|
|
23
|
+
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
|
|
19
24
|
</CHANGE_SUMMARY>
|
|
20
25
|
*/
|
|
21
26
|
|
|
22
27
|
import { z } from "zod";
|
|
23
|
-
import type { RuntimeContext } from "
|
|
28
|
+
import type { RuntimeContext } from "../runtime/runtime-context.ts";
|
|
24
29
|
|
|
25
30
|
// ---------------------------------------------------------------------------
|
|
26
31
|
// VisibilityExpr — closed discriminated union (DNA-19, RFC-0026)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>App-agnostic _redirects file parsing for reuse across site-kernel-checks and site-kernel-handoff (RFC-0588).</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not handle advanced Cloudflare Pages syntax (query parameters, placeholders) — only whitespace-delimited `from to status` lines.</item>
|
|
6
|
+
<item>Do not perform glob-to-regex conversion — that is the consumer's responsibility.</item>
|
|
7
|
+
</non-goals>
|
|
8
|
+
</MODULE_CONTRACT>
|
|
9
|
+
<CHANGE_SUMMARY>
|
|
10
|
+
<item>RFC-0588: extracted parseRedirectRules and RedirectRule from site-kernel-checks/managed-public.ts into @warpgogol/werkstatt-shared/redirects subpath.</item>
|
|
11
|
+
<item>RFC-0595: add extractRedirectTarget helper for parsing url= from meta-refresh tags.</item>
|
|
12
|
+
<item>RFC-1097: step 6 — compass.migrate codemod run
|
|
13
|
+
|
|
14
|
+
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
|
|
15
|
+
<item>RFC-1097: sweep — werkstatt-engine clean
|
|
16
|
+
|
|
17
|
+
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
|
|
18
|
+
</CHANGE_SUMMARY>
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export type RedirectRule = {
|
|
22
|
+
from: string;
|
|
23
|
+
to: string | undefined;
|
|
24
|
+
status: number;
|
|
25
|
+
line: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* File extensions excluded from trailing-slash normalization in the Cloudflare Worker
|
|
30
|
+
* `isPageRoute` function. If a request URL ends with one of these extensions, the Worker
|
|
31
|
+
* must NOT 308-redirect it to a trailing-slash URL (which would cause a 404).
|
|
32
|
+
*
|
|
33
|
+
* This is the single source of truth — injected into worker.ts.template and
|
|
34
|
+
* markdown-negotiation.ts.template via the `{{EXCLUDED_EXTENSIONS}}` placeholder.
|
|
35
|
+
* The `trailing.slash.config.validate` SLASH-04 rule scans `public/` for file extensions
|
|
36
|
+
* not in this list and fails the build.
|
|
37
|
+
*
|
|
38
|
+
* When adding a new media/asset type to `public/`, add its extension here.
|
|
39
|
+
*/
|
|
40
|
+
export const PAGE_ROUTE_EXCLUDED_EXTENSIONS: readonly string[] = [
|
|
41
|
+
"ico",
|
|
42
|
+
"png",
|
|
43
|
+
"jpg",
|
|
44
|
+
"jpeg",
|
|
45
|
+
"webp",
|
|
46
|
+
"avif",
|
|
47
|
+
"gif",
|
|
48
|
+
"bmp",
|
|
49
|
+
"svg",
|
|
50
|
+
"css",
|
|
51
|
+
"js",
|
|
52
|
+
"mjs",
|
|
53
|
+
"json",
|
|
54
|
+
"txt",
|
|
55
|
+
"xml",
|
|
56
|
+
"woff",
|
|
57
|
+
"woff2",
|
|
58
|
+
"ttf",
|
|
59
|
+
"otf",
|
|
60
|
+
"webmanifest",
|
|
61
|
+
"md",
|
|
62
|
+
"pdf",
|
|
63
|
+
"webm",
|
|
64
|
+
"mp4",
|
|
65
|
+
"wasm",
|
|
66
|
+
"map",
|
|
67
|
+
"m3u8",
|
|
68
|
+
"ts",
|
|
69
|
+
"html",
|
|
70
|
+
"ndjson",
|
|
71
|
+
"vtt",
|
|
72
|
+
"yaml",
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Build a regex string (without delimiters) that matches any of the excluded extensions.
|
|
77
|
+
* Used by the codegen to inject the alternation into the `isPageRoute` regex.
|
|
78
|
+
*/
|
|
79
|
+
export function buildPageRouteExclusionAlternation(
|
|
80
|
+
extensions: readonly string[] = PAGE_ROUTE_EXCLUDED_EXTENSIONS,
|
|
81
|
+
): string {
|
|
82
|
+
return extensions.join("|");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function parseRedirectRules(body: string): RedirectRule[] {
|
|
86
|
+
return body
|
|
87
|
+
.split(/\r?\n/)
|
|
88
|
+
.map((line) => line.trim())
|
|
89
|
+
.filter((line) => line && !line.startsWith("#"))
|
|
90
|
+
.map((line) => {
|
|
91
|
+
const [from, to, statusRaw] = line.split(/\s+/);
|
|
92
|
+
return {
|
|
93
|
+
from: from ?? "",
|
|
94
|
+
to,
|
|
95
|
+
status: Number(statusRaw ?? 301),
|
|
96
|
+
line,
|
|
97
|
+
};
|
|
98
|
+
})
|
|
99
|
+
.filter((rule) => rule.from.length > 0);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Extract the redirect target URL from a `<meta http-equiv="refresh" content="0;url=...">` tag.
|
|
104
|
+
* Returns the immediate target only (first hop). Returns null if the tag is
|
|
105
|
+
* absent or the url= value cannot be parsed.
|
|
106
|
+
*/
|
|
107
|
+
export function extractRedirectTarget(html: string): string | null {
|
|
108
|
+
const m = html.match(
|
|
109
|
+
/<meta[^>]+http-equiv=["']refresh["'][^>]*content=["']\s*\d+\s*;\s*url=([^"']+)['"][^>]*>/i,
|
|
110
|
+
);
|
|
111
|
+
if (m?.[1]) return m[1].trim();
|
|
112
|
+
const m2 = html.match(
|
|
113
|
+
/<meta[^>]+content=["']\s*\d+\s*;\s*url=([^"']+)['"][^>]*http-equiv=["']refresh["'][^>]*>/i,
|
|
114
|
+
);
|
|
115
|
+
if (m2?.[1]) return m2[1].trim();
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { test, expect } from "vitest";
|
|
11
|
-
import { extractRedirectTarget, parseRedirectRules } from "
|
|
11
|
+
import { extractRedirectTarget, parseRedirectRules } from "../redirects.ts";
|
|
12
12
|
|
|
13
13
|
test("extractRedirectTarget: extracts url from standard meta-refresh tag", () => {
|
|
14
14
|
const html = `<html><head><meta http-equiv="refresh" content="0;url=/de/agb"></head><body></body></html>`;
|