@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,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Warpgogol check hints schema and parser: defines the hint configuration shape for check-warpgogol runs.</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file.</item>
|
|
6
|
+
</non-goals>
|
|
7
|
+
</MODULE_CONTRACT>
|
|
8
|
+
<CHANGE_SUMMARY>
|
|
9
|
+
<item>Initial implementation for check-warpgogol hints support.</item>
|
|
10
|
+
</CHANGE_SUMMARY>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
|
|
15
|
+
export const warpgogolCheckHintsSchema = z.object({
|
|
16
|
+
schemaVersion: z.literal(1),
|
|
17
|
+
siteId: z.string().min(1),
|
|
18
|
+
baseUrl: z.string().url().optional(),
|
|
19
|
+
languages: z.object({
|
|
20
|
+
default: z.string().min(1),
|
|
21
|
+
supported: z.array(z.string().min(1)).min(1),
|
|
22
|
+
}),
|
|
23
|
+
preferredStartPaths: z.array(z.string().startsWith("/")),
|
|
24
|
+
sectionAnchors: z.array(
|
|
25
|
+
z.object({
|
|
26
|
+
path: z.string().startsWith("/"),
|
|
27
|
+
sectionId: z.string().min(1),
|
|
28
|
+
label: z.string().optional(),
|
|
29
|
+
}),
|
|
30
|
+
),
|
|
31
|
+
audienceProfiles: z.array(z.string().min(1)),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export type WarpgogolCheckHints = z.infer<typeof warpgogolCheckHintsSchema>;
|
|
35
|
+
|
|
36
|
+
export function parseWarpgogolCheckHints(value: unknown): WarpgogolCheckHints {
|
|
37
|
+
return warpgogolCheckHintsSchema.parse(value);
|
|
38
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
App-agnostic utility functions for normalizing Astro content entry IDs and extracting
|
|
5
|
+
language codes from them. Shared across all apps in apps/*; no app-specific imports allowed.
|
|
6
|
+
</purpose>
|
|
7
|
+
<non-goals>
|
|
8
|
+
<item>Do not import from apps/* or astro:content.</item>
|
|
9
|
+
<item>Do not perform schema validation or runtime data fetching.</item>
|
|
10
|
+
</non-goals>
|
|
11
|
+
</MODULE_CONTRACT>
|
|
12
|
+
<CHANGE_SUMMARY>
|
|
13
|
+
<item>Merged createDispatcherResolver from dispatch.ts (micro-module consolidation).</item>
|
|
14
|
+
<item>Tightened createDispatcherResolver typing: replaced any with generic T parameter.</item>
|
|
15
|
+
<item>Fixed JSDoc: removed references to non-existent callers (components-dispatcher, layouts-dispatcher, pages-dispatcher).</item>
|
|
16
|
+
</CHANGE_SUMMARY>
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Shared entity-ID normalization for all schema dispatchers.
|
|
20
|
+
// Source: app content schemas/entity-id (migrated to packages/share).
|
|
21
|
+
|
|
22
|
+
export function toDataEntryId(entry: string): string {
|
|
23
|
+
return entry.replace(/\\/g, "/").replace(/\.md$/i, "");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getEntryLanguage(id: string): string | null {
|
|
27
|
+
const [firstSegment] = toDataEntryId(id).split("/");
|
|
28
|
+
|
|
29
|
+
if (!firstSegment || !/^[a-z]{2}$/i.test(firstSegment)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return firstSegment;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function stripEntryLanguage(id: string): string {
|
|
37
|
+
const normalizedId = toDataEntryId(id);
|
|
38
|
+
const entryLanguage = getEntryLanguage(normalizedId);
|
|
39
|
+
|
|
40
|
+
if (!entryLanguage) {
|
|
41
|
+
return normalizedId;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return normalizedId.slice(entryLanguage.length + 1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function pageIdToContentFileSlug(pageId: string): string {
|
|
48
|
+
return pageId
|
|
49
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1-$2")
|
|
50
|
+
.replace(/([A-Z])([A-Z][a-z])/g, "$1-$2")
|
|
51
|
+
.toLowerCase();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Creates a schema lookup function keyed by normalized entry ID.
|
|
56
|
+
*/
|
|
57
|
+
export function createDispatcherResolver<T = unknown>(schemaMap: Record<string, T>) {
|
|
58
|
+
return (entryId: string): T | undefined => {
|
|
59
|
+
const schemaId = stripEntryLanguage(toDataEntryId(entryId));
|
|
60
|
+
if (!(schemaId in schemaMap)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return schemaMap[schemaId];
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Maintains packages/share/src/content/index.ts as an authored share content module so agents can evolve it without rediscovering local boundaries.</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file.</item>
|
|
6
|
+
</non-goals>
|
|
7
|
+
</MODULE_CONTRACT>
|
|
8
|
+
<CHANGE_SUMMARY>
|
|
9
|
+
<item>RFC-0133: backfilled MODULE_MAP and CHANGE_SUMMARY markers for compass.validate compliance.</item>
|
|
10
|
+
<item>Removed dispatch.ts re-export (merged into entity-id.ts).</item>
|
|
11
|
+
</CHANGE_SUMMARY>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export * from "./entity-id.ts";
|
|
15
|
+
export * from "./merge.ts";
|
|
16
|
+
export * from "./resolve-field-path.ts";
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Maintains packages/share/src/content/merge.ts as an authored share content module so agents can evolve it without rediscovering local boundaries.</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file.</item>
|
|
6
|
+
</non-goals>
|
|
7
|
+
</MODULE_CONTRACT>
|
|
8
|
+
<CHANGE_SUMMARY>
|
|
9
|
+
<item>RFC-0133: backfilled MODULE_MAP and CHANGE_SUMMARY markers for compass.validate compliance.</item>
|
|
10
|
+
<item>Deepening: unified deepMergeEntryData and mergeComponentContent into one configurable deepMerge; old names kept as thin wrappers.</item>
|
|
11
|
+
</CHANGE_SUMMARY>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
15
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface DeepMergeOptions {
|
|
19
|
+
/** When true, keep the default array if the override array is empty. Default: false. */
|
|
20
|
+
keepDefaultOnEmptyArray?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Unified deep merge: override wins at each key, recursing into objects.
|
|
25
|
+
* Arrays are replaced wholesale (no per-element merge). When
|
|
26
|
+
* `keepDefaultOnEmptyArray` is true, an empty override array falls back to the
|
|
27
|
+
* default array instead of replacing it.
|
|
28
|
+
*/
|
|
29
|
+
export function deepMerge(
|
|
30
|
+
defaultValue: Record<string, unknown>,
|
|
31
|
+
overrideValue: Record<string, unknown>,
|
|
32
|
+
options?: DeepMergeOptions,
|
|
33
|
+
): Record<string, unknown> {
|
|
34
|
+
const keepDefaultOnEmptyArray = options?.keepDefaultOnEmptyArray ?? false;
|
|
35
|
+
const result: Record<string, unknown> = {};
|
|
36
|
+
const keys = new Set([...Object.keys(defaultValue), ...Object.keys(overrideValue)]);
|
|
37
|
+
for (const key of keys) {
|
|
38
|
+
const dv = defaultValue[key];
|
|
39
|
+
const ov = overrideValue[key];
|
|
40
|
+
if (ov === undefined) {
|
|
41
|
+
result[key] = dv;
|
|
42
|
+
} else if (Array.isArray(dv) && Array.isArray(ov)) {
|
|
43
|
+
if (ov.length > 0) {
|
|
44
|
+
result[key] = ov;
|
|
45
|
+
} else if (keepDefaultOnEmptyArray) {
|
|
46
|
+
result[key] = dv;
|
|
47
|
+
} else {
|
|
48
|
+
result[key] = ov;
|
|
49
|
+
}
|
|
50
|
+
} else if (isRecord(dv) && isRecord(ov)) {
|
|
51
|
+
result[key] = deepMerge(dv, ov, options);
|
|
52
|
+
} else {
|
|
53
|
+
result[key] = ov;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Deep merge for content entry data: override wins, non-empty arrays replace
|
|
61
|
+
* wholesale, empty override arrays keep the default. Thin wrapper over deepMerge.
|
|
62
|
+
*/
|
|
63
|
+
export function deepMergeEntryData(
|
|
64
|
+
defaultValue: Record<string, unknown>,
|
|
65
|
+
overrideValue: Record<string, unknown>,
|
|
66
|
+
): Record<string, unknown> {
|
|
67
|
+
return deepMerge(defaultValue, overrideValue, { keepDefaultOnEmptyArray: true });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Deep merge for component content: override wins, arrays always replace.
|
|
72
|
+
* Handles undefined override and non-record inputs. Thin wrapper over deepMerge.
|
|
73
|
+
*/
|
|
74
|
+
export function mergeComponentContent<TContent>(
|
|
75
|
+
defaultContent: TContent,
|
|
76
|
+
overrideContent?: Partial<TContent>,
|
|
77
|
+
): TContent {
|
|
78
|
+
if (overrideContent == null) return defaultContent;
|
|
79
|
+
if (!isRecord(defaultContent) || !isRecord(overrideContent)) {
|
|
80
|
+
return overrideContent as TContent;
|
|
81
|
+
}
|
|
82
|
+
return deepMerge(
|
|
83
|
+
defaultContent as Record<string, unknown>,
|
|
84
|
+
overrideContent as Record<string, unknown>,
|
|
85
|
+
) as TContent;
|
|
86
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Resolve a dotted field path through a data object, reporting the first missing segment — the shared primitive behind content-reference substitution (RFC-0045 / RFC-0138).</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not perform substitution or formatting — only path resolution.</item>
|
|
6
|
+
<item>Do not throw on a missing field; report it in the result.</item>
|
|
7
|
+
</non-goals>
|
|
8
|
+
</MODULE_CONTRACT>
|
|
9
|
+
<CHANGE_SUMMARY>
|
|
10
|
+
<item>RFC-0155: add Compass scaffolding markers for compass.validate compliance.</item>
|
|
11
|
+
</CHANGE_SUMMARY>
|
|
12
|
+
*/
|
|
13
|
+
export interface FieldResolution {
|
|
14
|
+
value: unknown;
|
|
15
|
+
missingField: string | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Walks a field path through a data object. Returns the value and the first
|
|
20
|
+
* missing field name, or null if the entire path resolves.
|
|
21
|
+
*/
|
|
22
|
+
export function resolveFieldPath(data: unknown, fieldPath: string[]): FieldResolution {
|
|
23
|
+
let value: unknown = data;
|
|
24
|
+
for (let i = 0; i < fieldPath.length; i++) {
|
|
25
|
+
const field = fieldPath[i];
|
|
26
|
+
if (value === null || value === undefined) {
|
|
27
|
+
return { value: undefined, missingField: field };
|
|
28
|
+
}
|
|
29
|
+
if (typeof value !== "object") {
|
|
30
|
+
return { value: undefined, missingField: field };
|
|
31
|
+
}
|
|
32
|
+
if (!(field in value)) {
|
|
33
|
+
const nextField = i + 1 < fieldPath.length ? fieldPath[i + 1] : null;
|
|
34
|
+
return { value: undefined, missingField: nextField };
|
|
35
|
+
}
|
|
36
|
+
value = (value as Record<string, unknown>)[field];
|
|
37
|
+
}
|
|
38
|
+
return { value, missingField: null };
|
|
39
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Framework-agnostic deep walk that applies a string-substitution function to every
|
|
4
|
+
string leaf of an arbitrary data structure, leaving non-string values unchanged (RFC-0138).</purpose>
|
|
5
|
+
<non-goals>
|
|
6
|
+
<item>Do not parse or resolve {collection.file.field} references — that is the caller's
|
|
7
|
+
substitute function (RFC-0045 / RFC-0050 resolvers).</item>
|
|
8
|
+
<item>Do not mutate the input — return a new structure.</item>
|
|
9
|
+
</non-goals>
|
|
10
|
+
</MODULE_CONTRACT>
|
|
11
|
+
<CHANGE_SUMMARY>
|
|
12
|
+
<item>RFC-0138: extracted the recursive prop-walk so block-prop reference substitution is
|
|
13
|
+
shared by the astro resolver and the page handler, and unit-testable without astro.</item>
|
|
14
|
+
</CHANGE_SUMMARY>
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Recursively substitutes string leaves of a data structure using `substituteString`.
|
|
19
|
+
*
|
|
20
|
+
* - strings → `await substituteString(value)`
|
|
21
|
+
* - arrays / plain objects → recurse
|
|
22
|
+
* - everything else (number, boolean, null, undefined) → identity
|
|
23
|
+
*
|
|
24
|
+
* The input is not mutated; a new structure is returned.
|
|
25
|
+
*/
|
|
26
|
+
export async function substituteRefsDeep(
|
|
27
|
+
data: unknown,
|
|
28
|
+
substituteString: (value: string) => Promise<string>,
|
|
29
|
+
): Promise<unknown> {
|
|
30
|
+
if (typeof data === "string") {
|
|
31
|
+
return substituteString(data);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (Array.isArray(data)) {
|
|
35
|
+
return Promise.all(data.map((item) => substituteRefsDeep(item, substituteString)));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (data !== null && typeof data === "object") {
|
|
39
|
+
const result: Record<string, unknown> = {};
|
|
40
|
+
for (const [key, value] of Object.entries(data as Record<string, unknown>)) {
|
|
41
|
+
result[key] = await substituteRefsDeep(value, substituteString);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return data;
|
|
47
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Maintains packages/share/src/content-discipline/index.ts as an authored share authored module so agents can evolve it without rediscovering local boundaries.</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not define validation logic here.</item>
|
|
6
|
+
</non-goals>
|
|
7
|
+
</MODULE_CONTRACT>
|
|
8
|
+
<CHANGE_SUMMARY>
|
|
9
|
+
<item>Added barrel exports for content-discipline submodules.</item>
|
|
10
|
+
</CHANGE_SUMMARY>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export * from "./types.ts";
|
|
14
|
+
export * from "./parsers.ts";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Parses RFC-0073 content-discipline artifacts and exposes reusable normalization helpers for validators.</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not read files from disk.</item>
|
|
6
|
+
<item>Do not resolve Astro content references here.</item>
|
|
7
|
+
</non-goals>
|
|
8
|
+
</MODULE_CONTRACT>
|
|
9
|
+
<CHANGE_SUMMARY>
|
|
10
|
+
<item>RFC-0073: Add shared parsers and normalization helpers for content-discipline validators.</item>
|
|
11
|
+
<item>RFC-0082: Delegate YAML reading to @warpgogol/werkstatt-shared/share/onboarding-yaml so single-doc and two-doc RFC-0076-headed files both parse correctly.</item>
|
|
12
|
+
</CHANGE_SUMMARY>
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { parseOnboardingArtifactPayload } from "../onboarding-yaml/index.ts";
|
|
16
|
+
import {
|
|
17
|
+
contentAtomsFileSchema,
|
|
18
|
+
coverageLedgerEntrySchema,
|
|
19
|
+
voiceProfileSchema,
|
|
20
|
+
type ContentAtomsFile,
|
|
21
|
+
type CoverageLedgerEntry,
|
|
22
|
+
type VoiceProfile,
|
|
23
|
+
} from "./types.ts";
|
|
24
|
+
|
|
25
|
+
const COVERAGE_LEDGER_LINE = /^-\s+(atom-\d{4,})\s+·\s+reason:\s+([a-z-]+)\s+·\s+note:\s+(.+)$/;
|
|
26
|
+
|
|
27
|
+
export function parseContentAtomsFile(source: string): ContentAtomsFile {
|
|
28
|
+
return parseOnboardingArtifactPayload(source, contentAtomsFileSchema);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function parseVoiceProfileFile(source: string): VoiceProfile {
|
|
32
|
+
return parseOnboardingArtifactPayload(source, voiceProfileSchema);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function parseCoverageLedgerMarkdown(source: string): CoverageLedgerEntry[] {
|
|
36
|
+
const entries: CoverageLedgerEntry[] = [];
|
|
37
|
+
for (const rawLine of source.split(/\r?\n/)) {
|
|
38
|
+
const line = rawLine.trim();
|
|
39
|
+
const match = line.match(COVERAGE_LEDGER_LINE);
|
|
40
|
+
if (!match) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const [, atomId, reason, note] = match;
|
|
44
|
+
entries.push(
|
|
45
|
+
coverageLedgerEntrySchema.parse({
|
|
46
|
+
atomId,
|
|
47
|
+
reason,
|
|
48
|
+
note: note.trim(),
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return entries;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function normalizeComparableText(value: string): string {
|
|
56
|
+
return value
|
|
57
|
+
.normalize("NFKC")
|
|
58
|
+
.replace(/\{\{quote\}\}[\s\S]*?\{\{\/quote\}\}/g, " ")
|
|
59
|
+
.replace(/\s+/g, " ")
|
|
60
|
+
.trim()
|
|
61
|
+
.toLocaleLowerCase();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function stripAllowedQuoteBlocks(value: string): string {
|
|
65
|
+
return value.replace(/\{\{quote\}\}[\s\S]*?\{\{\/quote\}\}/g, " ");
|
|
66
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Defines RFC-0073 shared content-discipline contracts for atom coverage, voice profile, and unplaced-atom reasoning.</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not read files from disk.</item>
|
|
6
|
+
<item>Do not perform app-specific validation logic.</item>
|
|
7
|
+
</non-goals>
|
|
8
|
+
</MODULE_CONTRACT>
|
|
9
|
+
<CHANGE_SUMMARY>
|
|
10
|
+
<item>RFC-0073: Introduce shared content-discipline contracts.</item>
|
|
11
|
+
</CHANGE_SUMMARY>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
|
|
16
|
+
export const contentAtomIntentValues = [
|
|
17
|
+
"heading",
|
|
18
|
+
"subheading",
|
|
19
|
+
"body",
|
|
20
|
+
"lead",
|
|
21
|
+
"cta-primary",
|
|
22
|
+
"cta-secondary",
|
|
23
|
+
"trust",
|
|
24
|
+
"proof",
|
|
25
|
+
"stat-value",
|
|
26
|
+
"stat-label",
|
|
27
|
+
"faq-question",
|
|
28
|
+
"faq-answer",
|
|
29
|
+
"meta-title",
|
|
30
|
+
"meta-description",
|
|
31
|
+
"og-title",
|
|
32
|
+
"og-description",
|
|
33
|
+
"legal-prose",
|
|
34
|
+
"process-step",
|
|
35
|
+
"comparison-row",
|
|
36
|
+
"microcopy",
|
|
37
|
+
"error-message",
|
|
38
|
+
"confirmation",
|
|
39
|
+
"placeholder",
|
|
40
|
+
"consent",
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
43
|
+
export const unplacedReasonValues = [
|
|
44
|
+
"legal-deferred",
|
|
45
|
+
"redundant",
|
|
46
|
+
"out-of-scope-for-mvp",
|
|
47
|
+
"client-deprecated",
|
|
48
|
+
"quality-concern",
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
export const contentAtomIntentSchema = z.enum(contentAtomIntentValues);
|
|
52
|
+
export const unplacedReasonSchema = z.enum(unplacedReasonValues);
|
|
53
|
+
|
|
54
|
+
export const contentAtomSchema = z
|
|
55
|
+
.object({
|
|
56
|
+
id: z.string().regex(/^atom-\d{4,}$/),
|
|
57
|
+
sourceId: z.string().min(1),
|
|
58
|
+
sourceLines: z.tuple([z.number().int().positive(), z.number().int().positive()]),
|
|
59
|
+
intent: contentAtomIntentSchema,
|
|
60
|
+
pageHint: z.string().min(1),
|
|
61
|
+
sectionHint: z.string().min(1),
|
|
62
|
+
faqQuestion: z.string().min(1).optional(),
|
|
63
|
+
paraphraseOf: z
|
|
64
|
+
.string()
|
|
65
|
+
.regex(/^atom-\d{4,}$/)
|
|
66
|
+
.optional(),
|
|
67
|
+
text: z.string().min(1),
|
|
68
|
+
})
|
|
69
|
+
.strict();
|
|
70
|
+
|
|
71
|
+
export const contentAtomsFileSchema = z
|
|
72
|
+
.object({
|
|
73
|
+
// RFC-0082: payload is read via parseOnboardingArtifactPayload, which strips
|
|
74
|
+
// RFC-0076 metadata keys before validation, so .strict() is safe again.
|
|
75
|
+
client: z.string().min(1),
|
|
76
|
+
language: z.string().regex(/^[a-z]{2}$/),
|
|
77
|
+
materialsHash: z.string().min(1),
|
|
78
|
+
generatedAt: z.string().min(1),
|
|
79
|
+
atoms: z.array(contentAtomSchema),
|
|
80
|
+
})
|
|
81
|
+
.strict();
|
|
82
|
+
|
|
83
|
+
export const preferredPhrasingSchema = z
|
|
84
|
+
.object({
|
|
85
|
+
avoid: z.string().min(1),
|
|
86
|
+
prefer: z.string().min(1),
|
|
87
|
+
})
|
|
88
|
+
.strict();
|
|
89
|
+
|
|
90
|
+
export const voiceProfileSchema = z
|
|
91
|
+
.object({
|
|
92
|
+
// RFC-0082: payload is read via parseOnboardingArtifactPayload, which strips
|
|
93
|
+
// RFC-0076 metadata keys before validation, so .strict() is safe again.
|
|
94
|
+
client: z.string().min(1),
|
|
95
|
+
language: z.string().regex(/^[a-z]{2}$/),
|
|
96
|
+
register: z.enum(["Sie", "Du", "you", "informal"]),
|
|
97
|
+
forbiddenPhrases: z.array(z.string().min(1)).default([]),
|
|
98
|
+
preferredPhrasings: z.array(preferredPhrasingSchema).default([]),
|
|
99
|
+
mandatoryPhrases: z.array(z.string().min(1)).default([]),
|
|
100
|
+
allowedQuotes: z.array(z.string().min(1)).default([]),
|
|
101
|
+
})
|
|
102
|
+
.strict();
|
|
103
|
+
|
|
104
|
+
export const coverageLedgerEntrySchema = z
|
|
105
|
+
.object({
|
|
106
|
+
atomId: z.string().regex(/^atom-\d{4,}$/),
|
|
107
|
+
reason: unplacedReasonSchema,
|
|
108
|
+
note: z.string().min(1),
|
|
109
|
+
})
|
|
110
|
+
.strict();
|
|
111
|
+
|
|
112
|
+
export type ContentAtomIntent = z.infer<typeof contentAtomIntentSchema>;
|
|
113
|
+
export type ContentAtom = z.infer<typeof contentAtomSchema>;
|
|
114
|
+
export type ContentAtomsFile = z.infer<typeof contentAtomsFileSchema>;
|
|
115
|
+
export type UnplacedReason = z.infer<typeof unplacedReasonSchema>;
|
|
116
|
+
export type PreferredPhrasing = z.infer<typeof preferredPhrasingSchema>;
|
|
117
|
+
export type VoiceProfile = z.infer<typeof voiceProfileSchema>;
|
|
118
|
+
export type CoverageLedgerEntry = z.infer<typeof coverageLedgerEntrySchema>;
|