@warpgogol/werkstatt-shared 0.2.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/package.json +352 -0
- package/src/checks/index.ts +24 -0
- package/src/checks/lib/astro-site-url.ts +30 -0
- package/src/checks/lib/i18n.ts +30 -0
- package/src/checks/result-helpers.ts +102 -0
- package/src/checks/suppressions-config.ts +195 -0
- package/src/index.ts +14 -0
- package/src/integration/README.md +38 -0
- package/src/integration/adapters.ts +143 -0
- package/src/integration/crm-buffer.ts +491 -0
- package/src/integration/dispatch.ts +106 -0
- package/src/integration/funnel.ts +379 -0
- package/src/integration/index.ts +56 -0
- package/src/integration/lifecycle.ts +155 -0
- package/src/integration/orchestration.ts +439 -0
- package/src/integration/port-barrel.ts +124 -0
- package/src/integration/port.ts +143 -0
- package/src/integration/qstash.ts +134 -0
- package/src/integration/sharding.ts +133 -0
- package/src/integration/tests/deliver-event.test.ts +52 -0
- package/src/integration/tests/dispatch.test.ts +88 -0
- package/src/integration/tests/funnel-bridge.test.ts +46 -0
- package/src/integration/tests/hub-runtime.test.ts +128 -0
- package/src/integration/tests/lifecycle.test.ts +69 -0
- package/src/integration/tests/qstash.test.ts +83 -0
- package/src/integration/tests/sharding.test.ts +64 -0
- package/src/integration/vitest.config.ts +8 -0
- package/src/integration-adapter-supabase-crm/adapter.ts +437 -0
- package/src/integration-adapter-supabase-crm/client.ts +605 -0
- package/src/integration-adapter-supabase-crm/index.ts +28 -0
- package/src/integration-adapter-supabase-crm/pipedrive-sync-target.ts +482 -0
- package/src/integration-adapter-supabase-crm/supabase-rest.ts +89 -0
- package/src/integration-adapter-supabase-crm/tenant-registry.ts +334 -0
- package/src/integration-adapter-supabase-crm/tests/change-balance.pbt.test.ts +83 -0
- package/src/integration-adapter-supabase-crm/tests/funnel-persistence.test.ts +409 -0
- package/src/integration-adapter-supabase-crm/tests/lifecycle-sync.test.ts +288 -0
- package/src/integration-adapter-supabase-crm/tests/stage-map.test.ts +80 -0
- package/src/integration-adapter-supabase-crm/vitest.config.ts +8 -0
- package/src/integration-adapter-supabase-crm/worker.ts +223 -0
- package/src/observability/conventions.ts +93 -0
- package/src/observability/env-resolver.ts +57 -0
- package/src/observability/index.ts +57 -0
- package/src/observability/metric-registry.ts +184 -0
- package/src/observability/otlp-converter.ts +125 -0
- package/src/observability/otlp-json.ts +135 -0
- package/src/observability/otlp-transport.ts +68 -0
- package/src/observability/pusher.ts +142 -0
- package/src/observability/redact.ts +27 -0
- package/src/observability/tests/conventions.test.ts +100 -0
- package/src/observability/tests/metric-registry.test.ts +117 -0
- package/src/observability/tests/otlp-converter.pbt.test.ts +77 -0
- package/src/observability/tests/otlp-converter.test.ts +157 -0
- package/src/observability/tests/otlp-json.test.ts +120 -0
- package/src/observability/tests/pusher.test.ts +75 -0
- package/src/observability/tests/redact.pbt.test.ts +71 -0
- package/src/observability/tests/redact.test.ts +37 -0
- package/src/observability/typed-refs.ts +137 -0
- package/src/observability/vitest.config.ts +8 -0
- package/src/ontology/analytics/matomo-binding.yaml +172 -0
- package/src/ontology/analytics/matomo-fleet.registry.yaml +26 -0
- package/src/ontology/analytics/messkanon.yaml +151 -0
- package/src/ontology/archetype-registry.ts +61 -0
- package/src/ontology/archetypes/components/brand-label.yaml +19 -0
- package/src/ontology/archetypes/components/copyright.yaml +19 -0
- package/src/ontology/archetypes/components/currency-aware-price-display.yaml +19 -0
- package/src/ontology/archetypes/components/currency-selector.yaml +19 -0
- package/src/ontology/archetypes/components/footer-promo.yaml +19 -0
- package/src/ontology/archetypes/components/lang-switcher.yaml +19 -0
- package/src/ontology/archetypes/components/layout.yaml +19 -0
- package/src/ontology/archetypes/components/live-photo.yaml +20 -0
- package/src/ontology/archetypes/components/material-credit.yaml +20 -0
- package/src/ontology/archetypes/components/media.yaml +21 -0
- package/src/ontology/archetypes/components/nachweis-card.yaml +34 -0
- package/src/ontology/archetypes/components/nachweis-detail.yaml +43 -0
- package/src/ontology/archetypes/components/nachweis-list.yaml +37 -0
- package/src/ontology/archetypes/components/nachweis-verify.yaml +31 -0
- package/src/ontology/archetypes/components/not-found.yaml +22 -0
- package/src/ontology/archetypes/components/offer-capacity.yaml +21 -0
- package/src/ontology/archetypes/components/passport-header.yaml +19 -0
- package/src/ontology/archetypes/components/passport-provenance.yaml +20 -0
- package/src/ontology/archetypes/components/passport-score-grid.yaml +20 -0
- package/src/ontology/archetypes/components/passport-star-map.yaml +20 -0
- package/src/ontology/archetypes/components/person-profile.yaml +20 -0
- package/src/ontology/archetypes/components/pulsar.yaml +20 -0
- package/src/ontology/archetypes/components/responsive-image.yaml +19 -0
- package/src/ontology/archetypes/components/scroll-to-top.yaml +22 -0
- package/src/ontology/archetypes/components/social-meta.yaml +20 -0
- package/src/ontology/archetypes/components/structured-data.yaml +19 -0
- package/src/ontology/archetypes/index.json +1003 -0
- package/src/ontology/archetypes/index.yaml +821 -0
- package/src/ontology/archetypes/sections/approach.yaml +23 -0
- package/src/ontology/archetypes/sections/article-list.yaml +30 -0
- package/src/ontology/archetypes/sections/audience-cards.yaml +30 -0
- package/src/ontology/archetypes/sections/breadcrumbs.yaml +21 -0
- package/src/ontology/archetypes/sections/chat-widget.yaml +37 -0
- package/src/ontology/archetypes/sections/comparison-cards.yaml +31 -0
- package/src/ontology/archetypes/sections/controlled-responsibility-block.yaml +34 -0
- package/src/ontology/archetypes/sections/credits.yaml +29 -0
- package/src/ontology/archetypes/sections/donation-card.yaml +53 -0
- package/src/ontology/archetypes/sections/donation-use.yaml +23 -0
- package/src/ontology/archetypes/sections/dynamic-status-block.yaml +35 -0
- package/src/ontology/archetypes/sections/faq-list.yaml +26 -0
- package/src/ontology/archetypes/sections/final-cta.yaml +53 -0
- package/src/ontology/archetypes/sections/hero-decision-card.yaml +65 -0
- package/src/ontology/archetypes/sections/hero.yaml +50 -0
- package/src/ontology/archetypes/sections/impact.yaml +23 -0
- package/src/ontology/archetypes/sections/markdown.yaml +43 -0
- package/src/ontology/archetypes/sections/mountain-journey.yaml +43 -0
- package/src/ontology/archetypes/sections/navigation.yaml +20 -0
- package/src/ontology/archetypes/sections/notausgang-block.yaml +41 -0
- package/src/ontology/archetypes/sections/open-source-registry.yaml +26 -0
- package/src/ontology/archetypes/sections/ownership-block.yaml +57 -0
- package/src/ontology/archetypes/sections/people.yaml +48 -0
- package/src/ontology/archetypes/sections/price-card.yaml +50 -0
- package/src/ontology/archetypes/sections/problem.yaml +23 -0
- package/src/ontology/archetypes/sections/send-message.yaml +63 -0
- package/src/ontology/archetypes/sections/service-metadata-block.yaml +40 -0
- package/src/ontology/archetypes/sections/social-proof.yaml +27 -0
- package/src/ontology/archetypes/sections/transparency.yaml +32 -0
- package/src/ontology/archetypes/sections/trust-strip.yaml +42 -0
- package/src/ontology/archetypes/sections/video-section.yaml +27 -0
- package/src/ontology/archetypes/sections/women.yaml +29 -0
- package/src/ontology/biome-token-projection.ts +229 -0
- package/src/ontology/biomes/check-concrete-blueprint.yaml +118 -0
- package/src/ontology/biomes/handwerk-material-warm.yaml +135 -0
- package/src/ontology/biomes/nonprofit-trust.yaml +123 -0
- package/src/ontology/blueprints/offer.yaml +39 -0
- package/src/ontology/blueprints/prompts/local-market-signal.md +13 -0
- package/src/ontology/blueprints/prompts/website-local-narrative.md +24 -0
- package/src/ontology/blueprints/ratgeber.yaml +62 -0
- package/src/ontology/blueprints/website-local.yaml +309 -0
- package/src/ontology/blueprints/website-service.yaml +84 -0
- package/src/ontology/capabilities/lead.submit.yaml +44 -0
- package/src/ontology/cosmic/index.ts +48 -0
- package/src/ontology/cosmic/moon-catalog.ts +173 -0
- package/src/ontology/cosmic/planet-catalog.ts +82 -0
- package/src/ontology/cosmic/star-catalog.ts +337 -0
- package/src/ontology/enums.ts +159 -0
- package/src/ontology/external-surfaces/index.ts +158 -0
- package/src/ontology/external-surfaces/jsonld-types.yaml +135 -0
- package/src/ontology/external-surfaces/sitemap-shape.yaml +6 -0
- package/src/ontology/external-surfaces/url-schema.yaml +95 -0
- package/src/ontology/growth/events/contact-email-click.yaml +21 -0
- package/src/ontology/growth/events/contact-form-submit.yaml +25 -0
- package/src/ontology/growth/events/contact-phone-click.yaml +21 -0
- package/src/ontology/growth/events/contact-route-click.yaml +21 -0
- package/src/ontology/growth/events/contact-submit.yaml +28 -0
- package/src/ontology/growth/events/contact-whatsapp-click.yaml +21 -0
- package/src/ontology/growth/events/cta-click.yaml +30 -0
- package/src/ontology/growth/events/donation-confirmed.yaml +32 -0
- package/src/ontology/growth/events/donation-form-start.yaml +21 -0
- package/src/ontology/growth/events/donation-form-submit.yaml +29 -0
- package/src/ontology/growth/events/donation-intent.yaml +29 -0
- package/src/ontology/growth/events/form-error.yaml +27 -0
- package/src/ontology/growth/events/form-start.yaml +21 -0
- package/src/ontology/growth/events/form-submit.yaml +21 -0
- package/src/ontology/growth/events/outbound-click.yaml +25 -0
- package/src/ontology/growth/events/page-view.yaml +24 -0
- package/src/ontology/growth/events/passport-view.yaml +28 -0
- package/src/ontology/growth/events/star-map-navigate.yaml +30 -0
- package/src/ontology/index.ts +165 -0
- package/src/ontology/manifest.ts +344 -0
- package/src/ontology/operations/index.ts +1 -0
- package/src/ontology/schemas/biome.ts +303 -0
- package/src/ontology/schemas/capability.ts +104 -0
- package/src/ontology/schemas/constellation.ts +114 -0
- package/src/ontology/schemas/dns-records.ts +53 -0
- package/src/ontology/schemas/index.ts +95 -0
- package/src/ontology/schemas/manifest-resolver.ts +123 -0
- package/src/ontology/schemas/page-entry.ts +213 -0
- package/src/ontology/schemas/section-archetype.ts +109 -0
- package/src/ontology/schemas/site-family.ts +98 -0
- package/src/ontology/schemas/system/growth.ts +80 -0
- package/src/ontology/schemas/system/integrations.ts +143 -0
- package/src/ontology/schemas/system/manifest.ts +492 -0
- package/src/ontology/schemas/system/page-output.ts +99 -0
- package/src/ontology/schemas/system/release.ts +58 -0
- package/src/ontology/schemas/system/text.ts +58 -0
- package/src/ontology/schemas/system.ts +53 -0
- package/src/ontology/shared-section-props/body-fragments.ts +182 -0
- package/src/ontology/shared-section-props/catalog.ts +195 -0
- package/src/ontology/shared-section-props/common.ts +178 -0
- package/src/ontology/shared-section-props/index.ts +34 -0
- package/src/ontology/shared-section-props/visual-header.ts +163 -0
- package/src/ontology/site-families/charity-donation-trust/cultural-rules.yaml +6 -0
- package/src/ontology/site-families/charity-donation-trust/family.yaml +44 -0
- package/src/ontology/site-families/charity-donation-trust/linguistic-rules.yaml +6 -0
- package/src/ontology/site-families/check-quality-operator/cultural-rules.yaml +6 -0
- package/src/ontology/site-families/check-quality-operator/family.yaml +40 -0
- package/src/ontology/site-families/check-quality-operator/linguistic-rules.yaml +6 -0
- package/src/ontology/site-families/handwerk-trust-engineering/cultural-rules.yaml +6 -0
- package/src/ontology/site-families/handwerk-trust-engineering/family.yaml +53 -0
- package/src/ontology/site-families/handwerk-trust-engineering/linguistic-rules.yaml +6 -0
- package/src/ontology/tests/catalogs.pbt.test.ts +89 -0
- package/src/ontology/tests/enums.test.ts +203 -0
- package/src/ontology/tests/sternsystem-owner.test.ts +63 -0
- package/src/ontology/vitest.config.ts +8 -0
- package/src/passport/dht-sign.test.ts +99 -0
- package/src/passport/dht-sign.ts +73 -0
- package/src/passport/identity-sign.test.ts +134 -0
- package/src/passport/identity-sign.ts +85 -0
- package/src/passport/index.ts +53 -0
- package/src/passport/key-rotate.ts +133 -0
- package/src/passport/schema.ts +198 -0
- package/src/passport/sign.ts +225 -0
- package/src/passport/tests/schema.pbt.test.ts +93 -0
- package/src/passport/tests/schema.test.ts +222 -0
- package/src/passport/vitest.config.ts +8 -0
- package/src/share/agent/api-catalog.ts +77 -0
- package/src/share/agent/capability.ts +68 -0
- package/src/share/agent/dns-aid.test.ts +74 -0
- package/src/share/agent/dns-aid.ts +53 -0
- package/src/share/agent/fleet-catalog.ts +149 -0
- package/src/share/agent/index.ts +29 -0
- package/src/share/agent/knowledge.ts +96 -0
- package/src/share/agent/manifest.ts +126 -0
- package/src/share/agent/mcp-card.ts +63 -0
- package/src/share/agent/omit-empty.ts +77 -0
- package/src/share/agent/openapi.ts +157 -0
- package/src/share/agent/proof.ts +61 -0
- package/src/share/attribution-display.ts +86 -0
- package/src/share/check-hints.ts +38 -0
- package/src/share/content/entity-id.ts +65 -0
- package/src/share/content/index.ts +16 -0
- package/src/share/content/merge.ts +86 -0
- package/src/share/content/resolve-field-path.ts +39 -0
- package/src/share/content/substitute-deep.ts +47 -0
- package/src/share/content-discipline/index.ts +14 -0
- package/src/share/content-discipline/parsers.ts +66 -0
- package/src/share/content-discipline/types.ts +118 -0
- package/src/share/content-reference.ts +333 -0
- package/src/share/counter-utils.ts +75 -0
- package/src/share/css-value-normalize.ts +48 -0
- package/src/share/dev-props-validator.ts +131 -0
- package/src/share/entitlement.ts +172 -0
- package/src/share/env.d.ts +73 -0
- package/src/share/feature-policy.ts +367 -0
- package/src/share/formula-eval.ts +364 -0
- package/src/share/fs/index.ts +96 -0
- package/src/share/i18n/localization.ts +57 -0
- package/src/share/image-provider.ts +314 -0
- package/src/share/index.ts +86 -0
- package/src/share/knowledge/claim.ts +129 -0
- package/src/share/knowledge/derivation.ts +55 -0
- package/src/share/knowledge/freshness.ts +127 -0
- package/src/share/knowledge/index.ts +23 -0
- package/src/share/knowledge/ledger.ts +222 -0
- package/src/share/knowledge/plan.ts +122 -0
- package/src/share/knowledge/source.ts +170 -0
- package/src/share/legal/translation-policy.ts +133 -0
- package/src/share/material-credits.ts +181 -0
- package/src/share/middleware/language-redirect.ts +49 -0
- package/src/share/offer-capacity.ts +149 -0
- package/src/share/onboarding-yaml/index.ts +162 -0
- package/src/share/page.ts +351 -0
- package/src/share/redirects.test.ts +62 -0
- package/src/share/redirects.ts +54 -0
- package/src/share/rfc0042-utils.ts +95 -0
- package/src/share/runtime-context.ts +70 -0
- package/src/share/schemas/claim-records.ts +69 -0
- package/src/share/schemas/claims.ts +150 -0
- package/src/share/schemas/effects.ts +212 -0
- package/src/share/schemas/features.ts +147 -0
- package/src/share/schemas/horizontal-align.ts +22 -0
- package/src/share/schemas/icon-color.ts +27 -0
- package/src/share/schemas/index.ts +43 -0
- package/src/share/schemas/live-photo.ts +53 -0
- package/src/share/schemas/material-credit.ts +292 -0
- package/src/share/schemas/media.ts +220 -0
- package/src/share/schemas/navigation.ts +74 -0
- package/src/share/schemas/page-base.ts +33 -0
- package/src/share/schemas/participant.ts +247 -0
- package/src/share/schemas/person.ts +24 -0
- package/src/share/schemas/print.ts +93 -0
- package/src/share/schemas/section-background.ts +106 -0
- package/src/share/schemas/section-body.ts +138 -0
- package/src/share/schemas/section-cards.ts +37 -0
- package/src/share/schemas/section-cta.ts +74 -0
- package/src/share/schemas/section-header.ts +77 -0
- package/src/share/schemas/section-image.ts +77 -0
- package/src/share/schemas/section-motion.ts +52 -0
- package/src/share/schemas/section-shell.ts +63 -0
- package/src/share/schemas/section-stats.ts +37 -0
- package/src/share/schemas/site-background.ts +78 -0
- package/src/share/schemas/standard-list-item.ts +38 -0
- package/src/share/scripts/external-links.ts +45 -0
- package/src/share/scripts/gsap-counter.ts +168 -0
- package/src/share/scripts/gsap-mountain-journey.ts +236 -0
- package/src/share/scripts/gsap-parallax.ts +50 -0
- package/src/share/scripts/gsap-reveal.ts +65 -0
- package/src/share/scripts/gsap-stagger.ts +54 -0
- package/src/share/scripts/index.ts +25 -0
- package/src/share/scripts/inline-number-animation.ts +120 -0
- package/src/share/scripts/lenis.ts +109 -0
- package/src/share/scripts/live-photos.ts +250 -0
- package/src/share/scripts/lordicon.ts +94 -0
- package/src/share/scripts/orchestrator.ts +138 -0
- package/src/share/scripts/scheduler.ts +53 -0
- package/src/share/scripts/video-player.ts +116 -0
- package/src/share/semantic/ai.ts +140 -0
- package/src/share/semantic/block-extraction.ts +52 -0
- package/src/share/semantic/block-extractors/index.ts +502 -0
- package/src/share/semantic/breadcrumbs.ts +120 -0
- package/src/share/semantic/build-page.ts +309 -0
- package/src/share/semantic/business-projection.ts +278 -0
- package/src/share/semantic/derived-prices-loader.ts +36 -0
- package/src/share/semantic/extract.ts +118 -0
- package/src/share/semantic/feed.ts +124 -0
- package/src/share/semantic/ids.ts +76 -0
- package/src/share/semantic/image-sitemap.ts +153 -0
- package/src/share/semantic/index.ts +36 -0
- package/src/share/semantic/jsonld/article.ts +47 -0
- package/src/share/semantic/jsonld/breadcrumb.ts +47 -0
- package/src/share/semantic/jsonld/collection-list.ts +30 -0
- package/src/share/semantic/jsonld/context.ts +46 -0
- package/src/share/semantic/jsonld/faq.ts +49 -0
- package/src/share/semantic/jsonld/initiative.ts +53 -0
- package/src/share/semantic/jsonld/organization.ts +101 -0
- package/src/share/semantic/jsonld/person.ts +71 -0
- package/src/share/semantic/jsonld/service.ts +80 -0
- package/src/share/semantic/jsonld/shared.ts +31 -0
- package/src/share/semantic/jsonld/types.ts +18 -0
- package/src/share/semantic/jsonld/webpage.ts +98 -0
- package/src/share/semantic/jsonld/website.ts +27 -0
- package/src/share/semantic/jsonld.ts +75 -0
- package/src/share/semantic/llms-policy.ts +74 -0
- package/src/share/semantic/llms.ts +394 -0
- package/src/share/semantic/markdown-hygiene.ts +68 -0
- package/src/share/semantic/markdown-twin-provenance.ts +242 -0
- package/src/share/semantic/models.ts +402 -0
- package/src/share/semantic/organization-profile.ts +160 -0
- package/src/share/semantic/output-projection.ts +131 -0
- package/src/share/semantic/page-builders/markdown-page.ts +84 -0
- package/src/share/semantic/page-markdown.ts +234 -0
- package/src/share/semantic/page-utils.ts +125 -0
- package/src/share/semantic/price-marker-resolver.ts +92 -0
- package/src/share/semantic/robots.ts +127 -0
- package/src/share/semantic/update-stamp.ts +136 -0
- package/src/share/shared-context.ts +177 -0
- package/src/share/string-utils.ts +19 -0
- package/src/share/tests/api-catalog.test.ts +97 -0
- package/src/share/tests/breadcrumbs.test.ts +126 -0
- package/src/share/tests/build-page-price-markers.test.ts +160 -0
- package/src/share/tests/capability.test.ts +107 -0
- package/src/share/tests/claim.test.ts +90 -0
- package/src/share/tests/content-ref-index.test.ts +328 -0
- package/src/share/tests/create-dev-props-validator.test.ts +38 -0
- package/src/share/tests/derivation.test.ts +39 -0
- package/src/share/tests/dev-props-validator.test.ts +88 -0
- package/src/share/tests/fleet-catalog.test.ts +134 -0
- package/src/share/tests/formula-eval.test.ts +619 -0
- package/src/share/tests/freshness.test.ts +60 -0
- package/src/share/tests/hero-section-numbering-parity.test.ts +51 -0
- package/src/share/tests/image-sitemap.test.ts +101 -0
- package/src/share/tests/jsonld-service.test.ts +282 -0
- package/src/share/tests/knowledge.test.ts +86 -0
- package/src/share/tests/ledger.test.ts +125 -0
- package/src/share/tests/llms-0789.test.ts +63 -0
- package/src/share/tests/manifest.test.ts +100 -0
- package/src/share/tests/markdown-twin-provenance.test.ts +108 -0
- package/src/share/tests/mcp-card.test.ts +57 -0
- package/src/share/tests/onboarding-yaml.test.ts +111 -0
- package/src/share/tests/ontology-role-by-cosmic-name.test.ts +28 -0
- package/src/share/tests/openapi.test.ts +116 -0
- package/src/share/tests/organization-jsonld.test.ts +74 -0
- package/src/share/tests/output-projection.test.ts +61 -0
- package/src/share/tests/plan.test.ts +97 -0
- package/src/share/tests/price-marker-resolver.test.ts +141 -0
- package/src/share/tests/proof.test.ts +72 -0
- package/src/share/tests/resolve-field-path.test.ts +52 -0
- package/src/share/tests/source.test.ts +81 -0
- package/src/share/tests/substitute-deep.test.ts +65 -0
- package/src/share/tests/text-normalize.pbt.test.ts +143 -0
- package/src/share/tests/text-normalize.test.ts +285 -0
- package/src/share/tests/twin-path.test.ts +43 -0
- package/src/share/text-normalize.ts +548 -0
- package/src/share/text-position.ts +19 -0
- package/src/share/types/hls-js-light.d.ts +16 -0
- package/src/share/visibility.ts +167 -0
- package/src/share/vitest.config.ts +8 -0
- package/src/share/wrap-inline-numbers.ts +139 -0
- package/src/surface/blueprint-schema.ts +314 -0
- package/src/surface/blueprint-types.ts +256 -0
- package/src/surface/blueprint.ts +300 -0
- package/src/surface/breaker.ts +57 -0
- package/src/surface/decision-composer.ts +156 -0
- package/src/surface/eligibility.ts +372 -0
- package/src/surface/evidence-records.ts +97 -0
- package/src/surface/fleet.ts +60 -0
- package/src/surface/geo.ts +170 -0
- package/src/surface/governance.ts +146 -0
- package/src/surface/index.ts +216 -0
- package/src/surface/io/index.ts +18 -0
- package/src/surface/io/surface-module-context-io.ts +60 -0
- package/src/surface/io/visibility-outcomes-io.ts +46 -0
- package/src/surface/module-context.ts +120 -0
- package/src/surface/substance.ts +161 -0
- package/src/surface/tests/eligibility.pbt.test.ts +137 -0
- package/src/surface/tests/eligibility.test.ts +302 -0
- package/src/surface/types.ts +289 -0
- package/src/surface/visibility.ts +57 -0
- package/src/surface/vitest.config.ts +8 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
RFC-0505: the ratgeber claim record schema. A structured claim record at
|
|
5
|
+
`surface/claims/{lang}/*.md` with claimId, articleId, claimText, claimType,
|
|
6
|
+
sourceRefs, calculationInputs, limitations, verifiedAt, expiresAt, and
|
|
7
|
+
reviewStatus. This is the ratgeber-specific claim registry that replaces
|
|
8
|
+
the RFC-0502 claim sidecars for ratgeber articles.
|
|
9
|
+
</purpose>
|
|
10
|
+
<non-goals>
|
|
11
|
+
<item>Do not validate claim records — the kernel validators (ratgeber.claim.validate) do that.</item>
|
|
12
|
+
<item>Do not resolve sourceRefs or calculationInputs — the validators resolve them against source descriptors and PBP data.</item>
|
|
13
|
+
<item>Do not confuse with recordClaimsSchema (RFC-0212) — that is the CKL claim sidecar for business records; this is the ratgeber claim record.</item>
|
|
14
|
+
</non-goals>
|
|
15
|
+
</MODULE_CONTRACT>
|
|
16
|
+
<CHANGE_SUMMARY>
|
|
17
|
+
<item>RFC-0505: initial claim record schema + type.</item>
|
|
18
|
+
</CHANGE_SUMMARY>
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
|
|
23
|
+
/** ISO 8601 calendar date, e.g. 2026-07-23. */
|
|
24
|
+
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
25
|
+
|
|
26
|
+
const isoDate = z.string().regex(ISO_DATE, "must be an ISO 8601 date (YYYY-MM-DD)");
|
|
27
|
+
|
|
28
|
+
/** A source reference within a claim record. */
|
|
29
|
+
export const claimSourceRefSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
sourceId: z.string().min(1),
|
|
32
|
+
url: z.string().url(),
|
|
33
|
+
title: z.string().min(1),
|
|
34
|
+
retrievedAt: isoDate,
|
|
35
|
+
})
|
|
36
|
+
.strict();
|
|
37
|
+
|
|
38
|
+
export type ClaimSourceRef = z.infer<typeof claimSourceRefSchema>;
|
|
39
|
+
|
|
40
|
+
/** A calculation input reference within a claim record (for `calculation` type). */
|
|
41
|
+
export const calculationInputSchema = z
|
|
42
|
+
.object({
|
|
43
|
+
ref: z.string().min(1),
|
|
44
|
+
value: z.string(),
|
|
45
|
+
})
|
|
46
|
+
.strict();
|
|
47
|
+
|
|
48
|
+
export type CalculationInput = z.infer<typeof calculationInputSchema>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A structured ratgeber claim record (RFC-0505). Lives at
|
|
52
|
+
* `surface/claims/{lang}/{claimId}.md` as frontmatter-only content.
|
|
53
|
+
*/
|
|
54
|
+
export const claimRecordSchema = z
|
|
55
|
+
.object({
|
|
56
|
+
claimId: z.string().min(1),
|
|
57
|
+
articleId: z.string().min(1),
|
|
58
|
+
claimText: z.string(),
|
|
59
|
+
claimType: z.enum(["factual", "calculation", "methodological", "regulatory"]),
|
|
60
|
+
sourceRefs: z.array(claimSourceRefSchema),
|
|
61
|
+
calculationInputs: z.array(calculationInputSchema).optional().default([]),
|
|
62
|
+
limitations: z.array(z.string()).optional().default([]),
|
|
63
|
+
verifiedAt: isoDate,
|
|
64
|
+
expiresAt: isoDate.optional(),
|
|
65
|
+
reviewStatus: z.enum(["verified", "unverified", "disputed"]),
|
|
66
|
+
})
|
|
67
|
+
.strict();
|
|
68
|
+
|
|
69
|
+
export type ClaimRecord = z.infer<typeof claimRecordSchema>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
RFC-0212: the claim annotation surface. A per-record provenance sidecar
|
|
5
|
+
`<record>.claims.yaml` is a map of field path → annotation, turning a bare field
|
|
6
|
+
into a CKL claim (RFC-0211) without touching the editable record body. Closed Zod
|
|
7
|
+
schema so `content.claim.validate` can shape-check every sidecar.
|
|
8
|
+
|
|
9
|
+
Moved from @warpgogol/business/schemas to @warpgogol/werkstatt-shared/share/schemas as part of RFC-0470
|
|
10
|
+
(legacy business layer deletion). This is Content Knowledge Lifecycle (CKL)
|
|
11
|
+
infrastructure, not business-layer code.
|
|
12
|
+
</purpose>
|
|
13
|
+
<non-goals>
|
|
14
|
+
<item>Do not resolve field paths, evaluate freshness, hash derivations, or read the filesystem — the kernel validators do that.</item>
|
|
15
|
+
<item>Do not wrap or validate the record value itself; a claim only annotates.</item>
|
|
16
|
+
</non-goals>
|
|
17
|
+
</MODULE_CONTRACT>
|
|
18
|
+
<CHANGE_SUMMARY>
|
|
19
|
+
<item>RFC-0212: initial claim annotation + record-claims schemas.</item>
|
|
20
|
+
<item>RFC-0470: moved from @warpgogol/business/schemas/claims.ts to @warpgogol/werkstatt-shared/share/schemas/claims.ts.</item>
|
|
21
|
+
</CHANGE_SUMMARY>
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { z } from "zod";
|
|
25
|
+
|
|
26
|
+
/** ISO 8601 calendar date, e.g. 2026-06-20. */
|
|
27
|
+
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
28
|
+
|
|
29
|
+
/** ISO 8601 duration with at least one component, e.g. P3M, P1Y, P2W, PT12H. */
|
|
30
|
+
const ISO8601_DURATION = /^P(?:\d+Y)?(?:\d+M)?(?:\d+W)?(?:\d+D)?(?:T(?:\d+H)?(?:\d+M)?(?:\d+S)?)?$/;
|
|
31
|
+
|
|
32
|
+
const isoDate = z.string().regex(ISO_DATE, "must be an ISO 8601 date (YYYY-MM-DD)");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* One field's claim annotation (RFC-0211 claim, minus the value which stays in the
|
|
36
|
+
* record body). `.strict()` so a typo'd key is caught as a schema violation
|
|
37
|
+
* (CKL-CLAIM-01) instead of silently ignored.
|
|
38
|
+
*/
|
|
39
|
+
export const claimAnnotationSchema = z
|
|
40
|
+
.object({
|
|
41
|
+
claimClass: z
|
|
42
|
+
.enum(["general", "legal", "price", "comparative-commercial"])
|
|
43
|
+
.optional()
|
|
44
|
+
.default("general"),
|
|
45
|
+
provenance: z.enum(["external", "derived", "asserted", "generated"]),
|
|
46
|
+
/** ISO date the value was last verified / asserted. */
|
|
47
|
+
asOf: isoDate,
|
|
48
|
+
/** ISO date after which the claim is stale. */
|
|
49
|
+
validUntil: isoDate.optional(),
|
|
50
|
+
/** ISO 8601 recurring review cadence, e.g. "P3M". */
|
|
51
|
+
reviewEvery: z
|
|
52
|
+
.string()
|
|
53
|
+
.regex(ISO8601_DURATION, "must be an ISO 8601 duration (e.g. P3M)")
|
|
54
|
+
.refine((v) => v !== "P" && v !== "PT", "duration must have at least one component")
|
|
55
|
+
.optional(),
|
|
56
|
+
/** → source descriptor id (RFC-0214) when provenance = external. */
|
|
57
|
+
sourceRef: z.string().min(1).optional(),
|
|
58
|
+
/** Canonical source subject string (RFC-0215) when provenance = derived. */
|
|
59
|
+
derivedFrom: z.string().min(1).optional(),
|
|
60
|
+
/** Normalized hash of the source value at derivation time (RFC-0215). */
|
|
61
|
+
sourceHash: z.string().min(1).optional(),
|
|
62
|
+
comparedEntity: z
|
|
63
|
+
.object({
|
|
64
|
+
name: z.string().min(1),
|
|
65
|
+
kind: z.enum(["vendor", "marketplace", "platform", "competitor-category"]),
|
|
66
|
+
url: z.string().url().optional(),
|
|
67
|
+
})
|
|
68
|
+
.optional(),
|
|
69
|
+
claimKind: z
|
|
70
|
+
.enum(["third-party-price", "capability", "ownership", "export", "support", "risk", "other"])
|
|
71
|
+
.optional(),
|
|
72
|
+
statement: z.string().min(1).optional(),
|
|
73
|
+
value: z
|
|
74
|
+
.object({
|
|
75
|
+
amount: z.number().optional(),
|
|
76
|
+
min: z.number().optional(),
|
|
77
|
+
max: z.number().optional(),
|
|
78
|
+
currency: z.string().min(1).optional(),
|
|
79
|
+
unit: z.string().min(1).optional(),
|
|
80
|
+
})
|
|
81
|
+
.optional(),
|
|
82
|
+
publicDisclosure: z
|
|
83
|
+
.object({
|
|
84
|
+
label: z.string().min(1),
|
|
85
|
+
showStandDate: z.literal(true),
|
|
86
|
+
showSourceLabel: z.boolean(),
|
|
87
|
+
})
|
|
88
|
+
.optional(),
|
|
89
|
+
criticality: z.enum(["advisory", "important", "blocking"]).optional(),
|
|
90
|
+
/** Responsible agent/human handle — routing (RFC-0216). */
|
|
91
|
+
owner: z.string().min(1).optional(),
|
|
92
|
+
confidence: z.enum(["high", "medium", "low"]).optional(),
|
|
93
|
+
})
|
|
94
|
+
.strict()
|
|
95
|
+
.superRefine((claim, ctx) => {
|
|
96
|
+
if (claim.claimClass !== "comparative-commercial") return;
|
|
97
|
+
const required: Array<keyof typeof claim> = [
|
|
98
|
+
"comparedEntity",
|
|
99
|
+
"claimKind",
|
|
100
|
+
"statement",
|
|
101
|
+
"sourceRef",
|
|
102
|
+
"reviewEvery",
|
|
103
|
+
"publicDisclosure",
|
|
104
|
+
"criticality",
|
|
105
|
+
];
|
|
106
|
+
for (const key of required) {
|
|
107
|
+
if (claim[key] === undefined) {
|
|
108
|
+
ctx.addIssue({
|
|
109
|
+
code: "custom",
|
|
110
|
+
path: [key],
|
|
111
|
+
message: "required for comparative-commercial claims",
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (claim.provenance !== "external") {
|
|
116
|
+
ctx.addIssue({
|
|
117
|
+
code: "custom",
|
|
118
|
+
path: ["provenance"],
|
|
119
|
+
message: "comparative-commercial claims must use external provenance",
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (claim.criticality !== "blocking") {
|
|
123
|
+
ctx.addIssue({
|
|
124
|
+
code: "custom",
|
|
125
|
+
path: ["criticality"],
|
|
126
|
+
message: "comparative-commercial claims must be blocking",
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (claim.claimKind === "third-party-price") {
|
|
130
|
+
if (!claim.value?.currency)
|
|
131
|
+
ctx.addIssue({
|
|
132
|
+
code: "custom",
|
|
133
|
+
path: ["value", "currency"],
|
|
134
|
+
message: "third-party-price claims require value.currency",
|
|
135
|
+
});
|
|
136
|
+
if (!claim.value?.unit)
|
|
137
|
+
ctx.addIssue({
|
|
138
|
+
code: "custom",
|
|
139
|
+
path: ["value", "unit"],
|
|
140
|
+
message: "third-party-price claims require value.unit",
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export type ClaimAnnotation = z.infer<typeof claimAnnotationSchema>;
|
|
146
|
+
|
|
147
|
+
/** The full `<record>.claims.yaml` sidecar: fieldPath → annotation. */
|
|
148
|
+
export const recordClaimsSchema = z.record(z.string().min(1), claimAnnotationSchema);
|
|
149
|
+
|
|
150
|
+
export type RecordClaims = z.infer<typeof recordClaimsSchema>;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
Canonical composable UI effects contract for shared sections and components.
|
|
5
|
+
Owns effect targets, discriminated effect kinds, assignment arrays, and
|
|
6
|
+
schema validation for the RFC-0134 glass-first effects model.
|
|
7
|
+
</purpose>
|
|
8
|
+
<non-goals>
|
|
9
|
+
<item>Do not render effects — rendering belongs to @warpgogol/werkstatt-site/ui.</item>
|
|
10
|
+
<item>Do not implement future effect kinds beyond glass in the initial wave.</item>
|
|
11
|
+
</non-goals>
|
|
12
|
+
</MODULE_CONTRACT>
|
|
13
|
+
<CHANGE_SUMMARY>
|
|
14
|
+
<item>Introduces RFC-0134 composable effects contracts with glass as the first supported effect kind.</item>
|
|
15
|
+
</CHANGE_SUMMARY>
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
|
|
20
|
+
const NAMED_EFFECT_TARGETS = [
|
|
21
|
+
"section",
|
|
22
|
+
"body",
|
|
23
|
+
"panel",
|
|
24
|
+
"item",
|
|
25
|
+
"card",
|
|
26
|
+
"row",
|
|
27
|
+
"column",
|
|
28
|
+
"media",
|
|
29
|
+
"cta",
|
|
30
|
+
"heading", // RFC-0151 — typographic effects on the section heading
|
|
31
|
+
"subheading", // typographic effects on the section subheading/tagline
|
|
32
|
+
] as const;
|
|
33
|
+
|
|
34
|
+
export const namedEffectTargetSchema = z.enum(NAMED_EFFECT_TARGETS);
|
|
35
|
+
const slotEffectTargetSchema = z.string().regex(/^slot:[a-z0-9-]+$/);
|
|
36
|
+
export const effectTargetSchema = z.union([namedEffectTargetSchema, slotEffectTargetSchema]);
|
|
37
|
+
export type EffectTarget = z.infer<typeof effectTargetSchema>;
|
|
38
|
+
|
|
39
|
+
export const glassEffectSchema = z
|
|
40
|
+
.object({
|
|
41
|
+
kind: z.literal("glass"),
|
|
42
|
+
enabled: z.boolean(),
|
|
43
|
+
blur: z.number().min(0).max(64).optional(),
|
|
44
|
+
saturate: z.number().min(0).max(400).optional(),
|
|
45
|
+
tint: z.string().min(1).optional(),
|
|
46
|
+
tintOpacity: z.number().min(0).max(1).optional(),
|
|
47
|
+
border: z.enum(["hairline", "none"]).optional(),
|
|
48
|
+
})
|
|
49
|
+
.strict();
|
|
50
|
+
export type GlassEffect = z.infer<typeof glassEffectSchema>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* RFC-0151 — shared color alias for typographic effects. Either a biome token
|
|
54
|
+
* alias resolved by the renderer, or a raw passthrough value (e.g. "#0af").
|
|
55
|
+
*/
|
|
56
|
+
export const effectColorSchema = z.union([
|
|
57
|
+
z.enum(["text", "primary", "accent", "shadow", "surface", "inverse"]),
|
|
58
|
+
z.string().min(1),
|
|
59
|
+
]);
|
|
60
|
+
export type EffectColor = z.infer<typeof effectColorSchema>;
|
|
61
|
+
|
|
62
|
+
export const shadowEffectSchema = z
|
|
63
|
+
.object({
|
|
64
|
+
kind: z.literal("shadow"),
|
|
65
|
+
enabled: z.boolean(),
|
|
66
|
+
offsetX: z.number().min(-64).max(64).optional(),
|
|
67
|
+
offsetY: z.number().min(-64).max(64).optional(),
|
|
68
|
+
blur: z.number().min(0).max(64).optional(),
|
|
69
|
+
color: effectColorSchema.optional(),
|
|
70
|
+
opacity: z.number().min(0).max(1).optional(),
|
|
71
|
+
})
|
|
72
|
+
.strict();
|
|
73
|
+
export type ShadowEffect = z.infer<typeof shadowEffectSchema>;
|
|
74
|
+
|
|
75
|
+
export const glowEffectSchema = z
|
|
76
|
+
.object({
|
|
77
|
+
kind: z.literal("glow"),
|
|
78
|
+
enabled: z.boolean(),
|
|
79
|
+
blur: z.number().min(0).max(96).optional(),
|
|
80
|
+
color: effectColorSchema.optional(),
|
|
81
|
+
opacity: z.number().min(0).max(1).optional(),
|
|
82
|
+
})
|
|
83
|
+
.strict();
|
|
84
|
+
export type GlowEffect = z.infer<typeof glowEffectSchema>;
|
|
85
|
+
|
|
86
|
+
export const bulgeEffectSchema = z
|
|
87
|
+
.object({
|
|
88
|
+
kind: z.literal("bulge"),
|
|
89
|
+
enabled: z.boolean(),
|
|
90
|
+
depth: z.number().min(0).max(16).optional(),
|
|
91
|
+
highlight: z.number().min(0).max(1).optional(),
|
|
92
|
+
shade: z.number().min(0).max(1).optional(),
|
|
93
|
+
shadowColor: effectColorSchema.optional(),
|
|
94
|
+
highlightColor: effectColorSchema.optional(),
|
|
95
|
+
})
|
|
96
|
+
.strict();
|
|
97
|
+
export type BulgeEffect = z.infer<typeof bulgeEffectSchema>;
|
|
98
|
+
|
|
99
|
+
export const tiltEffectSchema = z
|
|
100
|
+
.object({
|
|
101
|
+
kind: z.literal("tilt"),
|
|
102
|
+
enabled: z.boolean(),
|
|
103
|
+
rotate: z.number().min(-15).max(15).optional(),
|
|
104
|
+
skewX: z.number().min(-15).max(15).optional(),
|
|
105
|
+
})
|
|
106
|
+
.strict();
|
|
107
|
+
export type TiltEffect = z.infer<typeof tiltEffectSchema>;
|
|
108
|
+
|
|
109
|
+
export const effectSchema = z.discriminatedUnion("kind", [
|
|
110
|
+
glassEffectSchema,
|
|
111
|
+
shadowEffectSchema,
|
|
112
|
+
glowEffectSchema,
|
|
113
|
+
bulgeEffectSchema,
|
|
114
|
+
tiltEffectSchema,
|
|
115
|
+
]);
|
|
116
|
+
export type Effect = z.infer<typeof effectSchema>;
|
|
117
|
+
|
|
118
|
+
export type EffectKind = Effect["kind"];
|
|
119
|
+
export type EffectRenderStrategy = "surface" | "text";
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* RFC-0151 — per-kind metadata. Single source of truth shared by the stack
|
|
123
|
+
* validator (maxPerStack) and the @warpgogol/werkstatt-site/ui renderer (strategy).
|
|
124
|
+
*/
|
|
125
|
+
export const EFFECT_KIND_META = {
|
|
126
|
+
glass: { strategy: "surface", maxPerStack: 1 },
|
|
127
|
+
shadow: { strategy: "text", maxPerStack: 1 },
|
|
128
|
+
glow: { strategy: "text", maxPerStack: 1 },
|
|
129
|
+
bulge: { strategy: "text", maxPerStack: 1 },
|
|
130
|
+
tilt: { strategy: "text", maxPerStack: 1 },
|
|
131
|
+
} as const satisfies Record<EffectKind, { strategy: EffectRenderStrategy; maxPerStack: number }>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* RFC-0151 — which effect kinds each target accepts. Targets absent from this
|
|
135
|
+
* map default to glass-only (the RFC-0134 surface behavior). The `heading`
|
|
136
|
+
* target accepts only the typographic (text-strategy) kinds.
|
|
137
|
+
*/
|
|
138
|
+
export const TARGET_ALLOWED_KINDS: Record<string, readonly EffectKind[]> = {
|
|
139
|
+
heading: ["shadow", "glow", "bulge", "tilt"],
|
|
140
|
+
subheading: ["shadow", "glow", "bulge", "tilt"],
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const DEFAULT_ALLOWED_KINDS: readonly EffectKind[] = ["glass"];
|
|
144
|
+
|
|
145
|
+
/** RFC-0151 — kinds accepted by a target, falling back to the glass-only default. */
|
|
146
|
+
export function allowedKindsForTarget(target: EffectTarget): readonly EffectKind[] {
|
|
147
|
+
return TARGET_ALLOWED_KINDS[target] ?? DEFAULT_ALLOWED_KINDS;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const effectStackSchema = z
|
|
151
|
+
.array(effectSchema)
|
|
152
|
+
.min(1)
|
|
153
|
+
.superRefine((stack, ctx) => {
|
|
154
|
+
const counts = new Map<EffectKind, number>();
|
|
155
|
+
for (const effect of stack) {
|
|
156
|
+
counts.set(effect.kind, (counts.get(effect.kind) ?? 0) + 1);
|
|
157
|
+
}
|
|
158
|
+
for (const [kind, count] of counts) {
|
|
159
|
+
const max = EFFECT_KIND_META[kind].maxPerStack;
|
|
160
|
+
if (count > max) {
|
|
161
|
+
ctx.addIssue({
|
|
162
|
+
code: z.ZodIssueCode.custom,
|
|
163
|
+
message: `Only ${max} ${kind} effect(s) allowed per effect stack.`,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
export const effectAssignmentSchema = z
|
|
170
|
+
.object({
|
|
171
|
+
target: effectTargetSchema,
|
|
172
|
+
stack: effectStackSchema,
|
|
173
|
+
})
|
|
174
|
+
.strict()
|
|
175
|
+
.superRefine((assignment, ctx) => {
|
|
176
|
+
// RFC-0151 — target × kind admissibility. A heading accepts only the
|
|
177
|
+
// typographic kinds; surface targets accept only glass. This is the
|
|
178
|
+
// contract guard the RFC describes, enforced wherever content is validated.
|
|
179
|
+
const allowed = allowedKindsForTarget(assignment.target);
|
|
180
|
+
for (const effect of assignment.stack) {
|
|
181
|
+
if (!allowed.includes(effect.kind)) {
|
|
182
|
+
ctx.addIssue({
|
|
183
|
+
code: z.ZodIssueCode.custom,
|
|
184
|
+
path: ["stack"],
|
|
185
|
+
message: `Target '${assignment.target}' supports kinds [${allowed.join(", ")}], not '${effect.kind}'.`,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
export type EffectAssignment = z.infer<typeof effectAssignmentSchema>;
|
|
191
|
+
|
|
192
|
+
export const effectsSchema = z.array(effectAssignmentSchema).min(1);
|
|
193
|
+
export type Effects = z.infer<typeof effectsSchema>;
|
|
194
|
+
|
|
195
|
+
export function resolveEffectsForTarget(
|
|
196
|
+
assignments: readonly EffectAssignment[] | undefined,
|
|
197
|
+
target: EffectTarget,
|
|
198
|
+
): Effect[] {
|
|
199
|
+
return assignments?.find((assignment) => assignment.target === target)?.stack ?? [];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function hasEnabledGlassEffect(effects: readonly Effect[] | undefined): effects is Effect[] {
|
|
203
|
+
return Boolean(effects?.some((effect) => effect.kind === "glass" && effect.enabled));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function resolveGlassEffect(
|
|
207
|
+
effects: readonly Effect[] | undefined,
|
|
208
|
+
): GlassEffect | undefined {
|
|
209
|
+
return effects?.find(
|
|
210
|
+
(effect): effect is GlassEffect => effect.kind === "glass" && effect.enabled,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
Shared Zod schemas for the content-declared feature graph (RFC-0018).
|
|
5
|
+
App-agnostic — every app that adopts RFC-0018 imports from here instead of
|
|
6
|
+
copy-pasting. Canonical home per RFC-0033.
|
|
7
|
+
</purpose>
|
|
8
|
+
<non-goals>
|
|
9
|
+
<item>Do not import from astro:content or apps/*.</item>
|
|
10
|
+
<item>Do not handle runtime resolution or navigation logic.</item>
|
|
11
|
+
<item>Do not manage state or side effects.</item>
|
|
12
|
+
</non-goals>
|
|
13
|
+
</MODULE_CONTRACT>
|
|
14
|
+
<CHANGE_SUMMARY>
|
|
15
|
+
<item>RFC-0033: Moved from app content schemas/features to @warpgogol/werkstatt-shared/share. Import switched from "astro/zod" to "zod" for framework neutrality.</item>
|
|
16
|
+
<item>RFC-0183: Added Feature Policy schema for policy embedded in existing RFC-0047 content domains.</item>
|
|
17
|
+
</CHANGE_SUMMARY>
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// [RFC-0018] Feature graph schemas — canonical implementation in packages/share.
|
|
21
|
+
// Import z from "zod" — not "astro/zod" — so this package stays framework-neutral.
|
|
22
|
+
import { z } from "zod";
|
|
23
|
+
|
|
24
|
+
const featureVisibilitySchema = z.enum(["enabled", "disabled"]);
|
|
25
|
+
|
|
26
|
+
export const featurePolicyVisibilitySchema = z.enum(["enabled", "disabled", "hidden", "draft"]);
|
|
27
|
+
|
|
28
|
+
export const featurePolicyBehaviorValueSchema = z.union([
|
|
29
|
+
z.string(),
|
|
30
|
+
z.number(),
|
|
31
|
+
z.boolean(),
|
|
32
|
+
z.null(),
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
export const featurePolicySchema = z.object({
|
|
36
|
+
visibility: featurePolicyVisibilitySchema.optional(),
|
|
37
|
+
behavior: z.record(z.string(), featurePolicyBehaviorValueSchema).optional(),
|
|
38
|
+
reason: z.string().optional(),
|
|
39
|
+
expiresAt: z.string().optional(),
|
|
40
|
+
audience: z.string().optional(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const featurePolicyTargetKindSchema = z.enum(["page", "section", "component", "item"]);
|
|
44
|
+
|
|
45
|
+
export const featurePolicyTargetRefSchema = z.object({
|
|
46
|
+
kind: featurePolicyTargetKindSchema,
|
|
47
|
+
pageId: z.string().optional(),
|
|
48
|
+
blockId: z.string().optional(),
|
|
49
|
+
componentId: z.string().optional(),
|
|
50
|
+
itemId: z.string().optional(),
|
|
51
|
+
lang: z.string().optional(),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const resolvedFeaturePolicySchema = z.object({
|
|
55
|
+
target: featurePolicyTargetRefSchema,
|
|
56
|
+
visibility: featurePolicyVisibilitySchema,
|
|
57
|
+
behavior: z.record(z.string(), featurePolicyBehaviorValueSchema),
|
|
58
|
+
sourcePath: z.string(),
|
|
59
|
+
inheritedFrom: featurePolicyTargetRefSchema.optional(),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const behaviorOverrideSchema = z.record(z.string(), z.any());
|
|
63
|
+
|
|
64
|
+
export const featureItemSchema = z.object({
|
|
65
|
+
id: z.string(),
|
|
66
|
+
visibility: featureVisibilitySchema,
|
|
67
|
+
behavior: behaviorOverrideSchema.optional(),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const featureComponentSchema = z.object({
|
|
71
|
+
id: z.string(),
|
|
72
|
+
componentPath: z.string(),
|
|
73
|
+
anchor: z.string(),
|
|
74
|
+
visibility: featureVisibilitySchema,
|
|
75
|
+
items: z.array(featureItemSchema).optional(),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Broad feature-graph category for a section node (RFC-0018).
|
|
80
|
+
*
|
|
81
|
+
* This is a FEATURE-GRAPH concept — it determines how the visibility engine
|
|
82
|
+
* classifies and processes a section. It is NOT the per-section SemanticRole
|
|
83
|
+
* from @warpgogol/werkstatt-shared/ontology (DNA-17, RFC-0023), which identifies each section
|
|
84
|
+
* individually (hero, dna, final-cta, …) and lives in manifest.yaml.
|
|
85
|
+
*
|
|
86
|
+
* SectionKind values:
|
|
87
|
+
* navigation — anchored nav / in-page links
|
|
88
|
+
* hero — primary above-the-fold section
|
|
89
|
+
* content — main informational section
|
|
90
|
+
* supporting — supplementary / secondary section
|
|
91
|
+
* cta — conversion / call-to-action section
|
|
92
|
+
* custom — does not fit the above categories
|
|
93
|
+
*/
|
|
94
|
+
export const sectionKindSchema = z.enum([
|
|
95
|
+
"navigation",
|
|
96
|
+
"hero",
|
|
97
|
+
"content",
|
|
98
|
+
"supporting",
|
|
99
|
+
"cta",
|
|
100
|
+
"custom",
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
export const featureSectionSchema = z.object({
|
|
104
|
+
id: z.string(),
|
|
105
|
+
role: sectionKindSchema,
|
|
106
|
+
anchor: z.string(),
|
|
107
|
+
visibility: featureVisibilitySchema,
|
|
108
|
+
components: z.array(featureComponentSchema),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
export const featurePageSchema = z.object({
|
|
112
|
+
id: z.string(),
|
|
113
|
+
routeSlug: z.string(),
|
|
114
|
+
visibility: featureVisibilitySchema,
|
|
115
|
+
sections: z.array(featureSectionSchema),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export const sharedComponentFeatureSchema = z.object({
|
|
119
|
+
id: z.string(),
|
|
120
|
+
componentPath: z.string(),
|
|
121
|
+
anchor: z.string(),
|
|
122
|
+
visibility: featureVisibilitySchema,
|
|
123
|
+
items: z.array(featureItemSchema).optional(),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export const siteFeaturesSchema = z
|
|
127
|
+
.object({
|
|
128
|
+
kind: z.enum(["page", "sharedComponent"]),
|
|
129
|
+
})
|
|
130
|
+
.loose();
|
|
131
|
+
|
|
132
|
+
export type FeatureVisibility = z.infer<typeof featureVisibilitySchema>;
|
|
133
|
+
export type FeaturePolicyVisibility = z.infer<typeof featurePolicyVisibilitySchema>;
|
|
134
|
+
export type FeaturePolicyBehaviorValue = z.infer<typeof featurePolicyBehaviorValueSchema>;
|
|
135
|
+
export type FeaturePolicy = z.infer<typeof featurePolicySchema>;
|
|
136
|
+
export type FeaturePolicyTargetKind = z.infer<typeof featurePolicyTargetKindSchema>;
|
|
137
|
+
export type FeaturePolicyTargetRef = z.infer<typeof featurePolicyTargetRefSchema>;
|
|
138
|
+
export type ResolvedFeaturePolicy = z.infer<typeof resolvedFeaturePolicySchema>;
|
|
139
|
+
export type BehaviorOverride = z.infer<typeof behaviorOverrideSchema>;
|
|
140
|
+
/** @see sectionKindSchema for the distinction between SectionKind and SemanticRole */
|
|
141
|
+
export type SectionKind = z.infer<typeof sectionKindSchema>;
|
|
142
|
+
export type FeatureItem = z.infer<typeof featureItemSchema>;
|
|
143
|
+
export type FeatureComponent = z.infer<typeof featureComponentSchema>;
|
|
144
|
+
export type FeatureSection = z.infer<typeof featureSectionSchema>;
|
|
145
|
+
export type FeaturePage = z.infer<typeof featurePageSchema>;
|
|
146
|
+
export type SharedComponentFeature = z.infer<typeof sharedComponentFeatureSchema>;
|
|
147
|
+
export type SiteFeature = z.infer<typeof siteFeaturesSchema>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
[RFC-0101][RFC-0102][RFC-0103][RFC-0104] Canonical horizontal alignment enum
|
|
5
|
+
shared by SectionHeader, SectionBody, SectionCtaGroup and any future section
|
|
6
|
+
primitive that needs left | center | right.
|
|
7
|
+
</purpose>
|
|
8
|
+
<non-goals>
|
|
9
|
+
<item>Do not add vertical alignment or alignment for shell-level layouts.</item>
|
|
10
|
+
<item>Do not couple alignment to section content shape.</item>
|
|
11
|
+
</non-goals>
|
|
12
|
+
</MODULE_CONTRACT>
|
|
13
|
+
<CHANGE_SUMMARY>
|
|
14
|
+
<item>RFC-0133: backfilled MODULE_MAP and CHANGE_SUMMARY markers for compass.validate compliance.</item>
|
|
15
|
+
</CHANGE_SUMMARY>
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
|
|
20
|
+
export const horizontalAlignSchema = z.enum(["left", "center", "right"]);
|
|
21
|
+
|
|
22
|
+
export type HorizontalAlign = z.infer<typeof horizontalAlignSchema>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
[RFC-0103] Canonical IconColor enum consumed by body components (<SectionList>,
|
|
5
|
+
<SectionSplitList>, <SectionCardGrid>, ...) for per-row icon tinting.
|
|
6
|
+
</purpose>
|
|
7
|
+
<non-goals>
|
|
8
|
+
<item>Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file.</item>
|
|
9
|
+
</non-goals>
|
|
10
|
+
</MODULE_CONTRACT>
|
|
11
|
+
<CHANGE_SUMMARY>
|
|
12
|
+
<item>RFC-0133: backfilled MODULE_MAP and CHANGE_SUMMARY markers for compass.validate compliance.</item>
|
|
13
|
+
</CHANGE_SUMMARY>
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
|
|
18
|
+
export const iconColorSchema = z.enum([
|
|
19
|
+
"primary",
|
|
20
|
+
"accent",
|
|
21
|
+
"success",
|
|
22
|
+
"warning",
|
|
23
|
+
"error",
|
|
24
|
+
"muted",
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
export type IconColor = z.infer<typeof iconColorSchema>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
RFC-0264: barrel for the entire @warpgogol/werkstatt-shared/share schemas domain — base page schema,
|
|
5
|
+
navigation, feature policy, and the RFC-0101..0106/0202/0210/0220/0231/0257
|
|
6
|
+
canonical section-visual / section-content / media / material-credit / print
|
|
7
|
+
contracts. Consumers should prefer `@warpgogol/werkstatt-shared/share/schemas` over the deprecated
|
|
8
|
+
root barrel.
|
|
9
|
+
</purpose>
|
|
10
|
+
<non-goals>
|
|
11
|
+
<item>Do not contain schema definitions — pure re-export barrel.</item>
|
|
12
|
+
</non-goals>
|
|
13
|
+
</MODULE_CONTRACT>
|
|
14
|
+
<CHANGE_SUMMARY>
|
|
15
|
+
<item>RFC-0264: initial creation — aggregates the schemas/ domain for the @warpgogol/werkstatt-shared/share/schemas subpath.</item>
|
|
16
|
+
</CHANGE_SUMMARY>
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export * from "./page-base.ts";
|
|
20
|
+
export * from "./navigation.ts";
|
|
21
|
+
export * from "./features.ts";
|
|
22
|
+
export * from "./horizontal-align.ts";
|
|
23
|
+
export * from "./section-background.ts";
|
|
24
|
+
export * from "./effects.ts";
|
|
25
|
+
export * from "./section-shell.ts";
|
|
26
|
+
export * from "./section-header.ts";
|
|
27
|
+
export * from "./icon-color.ts";
|
|
28
|
+
export * from "./standard-list-item.ts";
|
|
29
|
+
export * from "./section-cards.ts";
|
|
30
|
+
export * from "./section-stats.ts";
|
|
31
|
+
export * from "./section-body.ts";
|
|
32
|
+
export * from "./section-cta.ts";
|
|
33
|
+
export * from "./section-image.ts";
|
|
34
|
+
export * from "./live-photo.ts";
|
|
35
|
+
export * from "./media.ts";
|
|
36
|
+
export * from "./material-credit.ts";
|
|
37
|
+
export * from "./site-background.ts";
|
|
38
|
+
export * from "./section-motion.ts";
|
|
39
|
+
export * from "./print.ts";
|
|
40
|
+
export * from "./claims.ts";
|
|
41
|
+
export * from "./claim-records.ts";
|
|
42
|
+
export * from "./person.ts";
|
|
43
|
+
export * from "./participant.ts";
|