@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,242 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
RFC-0320: portable provenance frontmatter for generated Markdown twins.
|
|
5
|
+
Builds YAML frontmatter with canonical URL, language, lastModified, contentHash,
|
|
6
|
+
license, generator, and sourceKind. The contentHash is a deterministic sha256
|
|
7
|
+
over the normalized Markdown body (excluding frontmatter).
|
|
8
|
+
</purpose>
|
|
9
|
+
<non-goals>
|
|
10
|
+
<item>Do not hash the frontmatter — only the body is hashed.</item>
|
|
11
|
+
<item>Do not use build date or mtime for lastModified.</item>
|
|
12
|
+
</non-goals>
|
|
13
|
+
</MODULE_CONTRACT>
|
|
14
|
+
<CHANGE_SUMMARY>
|
|
15
|
+
<item>RFC-0320: initial implementation.</item>
|
|
16
|
+
<item>RFC-0377: extended provenance with MarkdownTwinSemanticMeta, derivation maps, and bumped schema to gogol.markdown-twin@2.</item>
|
|
17
|
+
<item>RFC-0602: allow null lastModified for person-slug twins without source-backed stamps.</item>
|
|
18
|
+
</CHANGE_SUMMARY>
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { createHash } from "node:crypto";
|
|
22
|
+
import type { SemanticPageType } from "./models.ts";
|
|
23
|
+
|
|
24
|
+
export interface MarkdownTwinSemanticMeta {
|
|
25
|
+
id: string;
|
|
26
|
+
route: string;
|
|
27
|
+
title: string;
|
|
28
|
+
type: SemanticPageType;
|
|
29
|
+
domain: string;
|
|
30
|
+
audience: string;
|
|
31
|
+
lang: string;
|
|
32
|
+
metaDescription: string;
|
|
33
|
+
priority: number;
|
|
34
|
+
tags: string[];
|
|
35
|
+
agentRoles?: string[];
|
|
36
|
+
visibility?: "public" | "internal" | "experimental";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface MarkdownTwinProvenance {
|
|
40
|
+
canonical: string;
|
|
41
|
+
language: string;
|
|
42
|
+
lastModified: string | null;
|
|
43
|
+
license: string;
|
|
44
|
+
generator: string;
|
|
45
|
+
sourceKind: string;
|
|
46
|
+
pageId?: string;
|
|
47
|
+
sourceInputs?: string[];
|
|
48
|
+
schema?: string;
|
|
49
|
+
semantic?: MarkdownTwinSemanticMeta;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const AUDIENCE_BY_PAGE_TYPE: Record<SemanticPageType, string> = {
|
|
53
|
+
home: "general",
|
|
54
|
+
about: "general",
|
|
55
|
+
projects: "developer",
|
|
56
|
+
donationContact: "general",
|
|
57
|
+
openSource: "developer",
|
|
58
|
+
content: "general",
|
|
59
|
+
article: "general",
|
|
60
|
+
person: "general",
|
|
61
|
+
participant: "general",
|
|
62
|
+
legal: "business_owner",
|
|
63
|
+
collection: "general",
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const PRIORITY_BY_PAGE_TYPE: Record<SemanticPageType, number> = {
|
|
67
|
+
home: 1.0,
|
|
68
|
+
about: 0.6,
|
|
69
|
+
projects: 0.5,
|
|
70
|
+
donationContact: 0.3,
|
|
71
|
+
openSource: 0.4,
|
|
72
|
+
content: 0.7,
|
|
73
|
+
article: 0.8,
|
|
74
|
+
person: 0.3,
|
|
75
|
+
participant: 0.3,
|
|
76
|
+
legal: 0.5,
|
|
77
|
+
collection: 0.8,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const DOMAIN_BY_PAGE_TYPE: Record<SemanticPageType, string> = {
|
|
81
|
+
home: "site",
|
|
82
|
+
about: "site",
|
|
83
|
+
projects: "projects",
|
|
84
|
+
donationContact: "contact",
|
|
85
|
+
openSource: "projects",
|
|
86
|
+
content: "content",
|
|
87
|
+
article: "content",
|
|
88
|
+
person: "team",
|
|
89
|
+
participant: "team",
|
|
90
|
+
legal: "legal",
|
|
91
|
+
collection: "content",
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const DEFAULT_SCHEMA = "gogol.markdown-twin@2";
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* RFC-0320: Normalize body for hashing.
|
|
98
|
+
* - Line endings to LF
|
|
99
|
+
* - Trim exactly one trailing newline
|
|
100
|
+
*/
|
|
101
|
+
function normalizeBody(body: string): string {
|
|
102
|
+
const lf = body.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
103
|
+
return `${lf.trimEnd()}\n`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* RFC-0320: Compute deterministic sha256 hash over normalized body bytes.
|
|
108
|
+
* Returns `sha256:<hex>`.
|
|
109
|
+
*/
|
|
110
|
+
export function computeContentHash(body: string): string {
|
|
111
|
+
const normalized = normalizeBody(body);
|
|
112
|
+
const hash = createHash("sha256").update(normalized, "utf-8").digest("hex");
|
|
113
|
+
return `sha256:${hash}`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* RFC-0320: Build YAML frontmatter for a Markdown twin.
|
|
118
|
+
*/
|
|
119
|
+
function buildYamlListField(name: string, items: string[]): string {
|
|
120
|
+
if (items.length === 0) {
|
|
121
|
+
return `${name}: []`;
|
|
122
|
+
}
|
|
123
|
+
const lines = items.map((item) => ` - "${item}"`).join("\n");
|
|
124
|
+
return `${name}:\n${lines}`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function buildMarkdownTwinFrontmatter(
|
|
128
|
+
provenance: MarkdownTwinProvenance,
|
|
129
|
+
contentHash: string,
|
|
130
|
+
): string {
|
|
131
|
+
const fields: string[] = [
|
|
132
|
+
`canonical: "${provenance.canonical}"`,
|
|
133
|
+
`language: "${provenance.language}"`,
|
|
134
|
+
`lastModified: ${provenance.lastModified === null ? "null" : `"${provenance.lastModified}"`}`,
|
|
135
|
+
`contentHash: "${contentHash}"`,
|
|
136
|
+
`license: "${provenance.license}"`,
|
|
137
|
+
`generator: "${provenance.generator}"`,
|
|
138
|
+
`sourceKind: "${provenance.sourceKind}"`,
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
if (provenance.pageId) {
|
|
142
|
+
fields.push(`pageId: "${provenance.pageId}"`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (provenance.sourceInputs && provenance.sourceInputs.length > 0) {
|
|
146
|
+
fields.push(buildYamlListField("sourceInputs", provenance.sourceInputs));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (provenance.semantic) {
|
|
150
|
+
const s = provenance.semantic;
|
|
151
|
+
fields.push(`id: "${s.id}"`);
|
|
152
|
+
fields.push(`route: "${s.route}"`);
|
|
153
|
+
fields.push(`title: "${s.title}"`);
|
|
154
|
+
fields.push(`type: "${s.type}"`);
|
|
155
|
+
fields.push(`domain: "${s.domain}"`);
|
|
156
|
+
fields.push(`audience: "${s.audience}"`);
|
|
157
|
+
fields.push(`lang: "${s.lang}"`);
|
|
158
|
+
fields.push(`metaDescription: "${s.metaDescription}"`);
|
|
159
|
+
fields.push(`priority: ${s.priority}`);
|
|
160
|
+
fields.push(buildYamlListField("tags", s.tags));
|
|
161
|
+
if (s.agentRoles && s.agentRoles.length > 0) {
|
|
162
|
+
fields.push(buildYamlListField("agentRoles", s.agentRoles));
|
|
163
|
+
}
|
|
164
|
+
if (s.visibility) {
|
|
165
|
+
fields.push(`visibility: "${s.visibility}"`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
fields.push(`schema: "${provenance.schema ?? DEFAULT_SCHEMA}"`);
|
|
170
|
+
|
|
171
|
+
return `---\n${fields.join("\n")}\n---\n\n`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* RFC-0320: Build a complete Markdown twin with frontmatter + body.
|
|
176
|
+
* The contentHash is computed over the normalized body.
|
|
177
|
+
*/
|
|
178
|
+
export function buildMarkdownTwin(body: string, provenance: MarkdownTwinProvenance): string {
|
|
179
|
+
const normalizedBody = normalizeBody(body);
|
|
180
|
+
const contentHash = computeContentHash(normalizedBody);
|
|
181
|
+
const frontmatter = buildMarkdownTwinFrontmatter(provenance, contentHash);
|
|
182
|
+
return `${frontmatter}${normalizedBody}`;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* RFC-0320: Parse frontmatter from a Markdown twin document.
|
|
187
|
+
* Returns { frontmatter, body } or null if no frontmatter found.
|
|
188
|
+
*/
|
|
189
|
+
export function parseMarkdownTwinFrontmatter(
|
|
190
|
+
content: string,
|
|
191
|
+
): { frontmatter: Record<string, unknown>; body: string } | null {
|
|
192
|
+
if (!content.startsWith("---\n")) return null;
|
|
193
|
+
const endIdx = content.indexOf("\n---\n", 4);
|
|
194
|
+
if (endIdx === -1) return null;
|
|
195
|
+
const yamlBlock = content.slice(4, endIdx);
|
|
196
|
+
// buildMarkdownTwinFrontmatter() closes with "---\n\n" (a blank separator line before the
|
|
197
|
+
// body). Skipping only "\n---\n" leaves that blank line's newline as a stray leading
|
|
198
|
+
// character in `body`, which then hashes differently than the body that was actually
|
|
199
|
+
// written — every twin's contentHash mismatched on validate. Consume the separator too.
|
|
200
|
+
const body = content.slice(endIdx + 5).replace(/^\n/, "");
|
|
201
|
+
|
|
202
|
+
const frontmatter: Record<string, unknown> = {};
|
|
203
|
+
let _currentKey = "";
|
|
204
|
+
let currentList: string[] | null = null;
|
|
205
|
+
|
|
206
|
+
for (const line of yamlBlock.split("\n")) {
|
|
207
|
+
if (line.startsWith(" - ")) {
|
|
208
|
+
if (currentList) {
|
|
209
|
+
currentList.push(line.slice(4).replace(/^["']|["']$/g, ""));
|
|
210
|
+
}
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const match = line.match(/^(\w+):\s*(.*)$/);
|
|
214
|
+
if (match) {
|
|
215
|
+
const [, key, value] = match;
|
|
216
|
+
if (value === "") {
|
|
217
|
+
_currentKey = key;
|
|
218
|
+
currentList = [];
|
|
219
|
+
frontmatter[key] = currentList;
|
|
220
|
+
} else {
|
|
221
|
+
_currentKey = "";
|
|
222
|
+
currentList = null;
|
|
223
|
+
const stripped = value.replace(/^["']|["']$/g, "");
|
|
224
|
+
frontmatter[key] = stripped === "null" ? null : stripped;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return { frontmatter, body };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* RFC-0320: Verify that the contentHash in frontmatter matches the body.
|
|
234
|
+
*/
|
|
235
|
+
export function verifyMarkdownTwinHash(content: string): boolean {
|
|
236
|
+
const parsed = parseMarkdownTwinFrontmatter(content);
|
|
237
|
+
if (!parsed) return false;
|
|
238
|
+
const declared = parsed.frontmatter.contentHash;
|
|
239
|
+
if (typeof declared !== "string") return false;
|
|
240
|
+
const actual = computeContentHash(parsed.body);
|
|
241
|
+
return declared === actual;
|
|
242
|
+
}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Defines types for semantic data structures used throughout the Warpgogol ecosystem.</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>RFC-0165/0167: SemanticImage.contentImage flag + PageOutputProjection.image (author-declared per-page content illustration, single source for image:image + top-precedence og:image).</item>
|
|
11
|
+
<item>RFC-0328: Added "legal" to the SemanticPageType closed enum.</item>
|
|
12
|
+
<item>RFC-0490: Added "collection" to the SemanticPageType closed enum.</item>
|
|
13
|
+
<item>RFC-0508: Added "participant" to the SemanticPageType closed enum.</item>
|
|
14
|
+
<item>RFC-0372: Unified SemanticBlock type replaces SemanticAnswerBlock + SemanticContentBlock; SemanticPageModel.blocks replaces answerBlocks/contentBlocks/bodyText.</item>
|
|
15
|
+
</CHANGE_SUMMARY>
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// NOTE: This closed union is mirrored by `semanticPageTypeSchema` in
|
|
19
|
+
// `@warpgogol/werkstatt-shared/ontology/src/schemas/system.ts`. `share` owns the compile-time
|
|
20
|
+
// contract used by lightweight consumers; `ontology` owns the runtime Zod
|
|
21
|
+
// validator for `system.md`. They are kept in sync manually because deriving
|
|
22
|
+
// one from the other would create a circular dependency between the two
|
|
23
|
+
// packages.
|
|
24
|
+
export type SemanticPageType =
|
|
25
|
+
| "home"
|
|
26
|
+
| "about"
|
|
27
|
+
| "projects"
|
|
28
|
+
| "donationContact"
|
|
29
|
+
| "openSource"
|
|
30
|
+
| "content"
|
|
31
|
+
| "article"
|
|
32
|
+
| "person"
|
|
33
|
+
| "participant"
|
|
34
|
+
| "legal"
|
|
35
|
+
| "collection";
|
|
36
|
+
|
|
37
|
+
/** Runtime counterpart to the `SemanticPageType` closed union. Keep in sync manually. */
|
|
38
|
+
export const SEMANTIC_PAGE_TYPES: readonly SemanticPageType[] = [
|
|
39
|
+
"home",
|
|
40
|
+
"about",
|
|
41
|
+
"projects",
|
|
42
|
+
"donationContact",
|
|
43
|
+
"openSource",
|
|
44
|
+
"content",
|
|
45
|
+
"article",
|
|
46
|
+
"person",
|
|
47
|
+
"participant",
|
|
48
|
+
"legal",
|
|
49
|
+
"collection",
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
export type SemanticBreadcrumb = {
|
|
53
|
+
name: string;
|
|
54
|
+
url: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* RFC-0372: Unified semantic block — replaces the former SemanticAnswerBlock and SemanticContentBlock.
|
|
59
|
+
* Every block in a SemanticPageModel is represented by this single type, regardless of
|
|
60
|
+
* whether it was derived from prose parsing or frontmatter block extraction.
|
|
61
|
+
*/
|
|
62
|
+
export type SemanticBlock = {
|
|
63
|
+
/** Stable id from frontmatter block.id (required) or slugified heading for prose-derived blocks. */
|
|
64
|
+
id: string;
|
|
65
|
+
/** Block type from frontmatter (e.g. "hero-decision-card", "markdown") or "prose" for prose-derived blocks. */
|
|
66
|
+
blockType?: string;
|
|
67
|
+
/** Section heading (H2 in markdown twin). Empty string for no-op blocks; rendering checks `if (block.heading)`. */
|
|
68
|
+
heading: string;
|
|
69
|
+
/** Lead / subheading text. Counts as substantive content for ART-DEPTH-03. */
|
|
70
|
+
summary?: string;
|
|
71
|
+
/** Free-form body text (prose paragraphs, descriptions). */
|
|
72
|
+
body?: string;
|
|
73
|
+
/** Bullet-list facts (from markdown answer blocks). */
|
|
74
|
+
facts?: string[];
|
|
75
|
+
/** Structured items (from block extractors: cards, comparison rows, etc.). */
|
|
76
|
+
items?: Array<{ title: string; description?: string }>;
|
|
77
|
+
/** Extractor metadata (absent for prose-derived blocks). */
|
|
78
|
+
extractedAt?: string;
|
|
79
|
+
extractorVersion?: string;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/* RFC-0142: per-page llms inclusion depth. */
|
|
83
|
+
export type SemanticLlmsDepth = "full" | "summary" | "index-only" | "exclude";
|
|
84
|
+
|
|
85
|
+
export type SemanticLlmsPolicy = {
|
|
86
|
+
depth: SemanticLlmsDepth;
|
|
87
|
+
sections?: { exclude?: string[] };
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/* RFC-0143: per-page sitemap projection (resolved). */
|
|
91
|
+
export type SitemapProjection = {
|
|
92
|
+
include: boolean;
|
|
93
|
+
category: string;
|
|
94
|
+
lastmod?: string;
|
|
95
|
+
includeLastmod: boolean;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/* RFC-0165: resolved per-page robots/indexability directive. */
|
|
99
|
+
export type RobotsProjection = {
|
|
100
|
+
index: boolean;
|
|
101
|
+
follow: boolean;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/* RFC-0143: resolved per-page `output` projection container. */
|
|
105
|
+
export type PageOutputProjection = {
|
|
106
|
+
sitemap: SitemapProjection;
|
|
107
|
+
llms: SemanticLlmsPolicy;
|
|
108
|
+
/* RFC-0165: indexability — drives the robots meta tag and sitemap inclusion. */
|
|
109
|
+
robots: RobotsProjection;
|
|
110
|
+
/**
|
|
111
|
+
* RFC-0165/0167: author-declared per-page content illustration (absolute
|
|
112
|
+
* https url). This is the single CLI-knowable source for the image sitemap
|
|
113
|
+
* (`image:image`) and the highest-precedence source for `og:image`. When
|
|
114
|
+
* present it carries `contentImage: true`. Absent when the page has no
|
|
115
|
+
* author-declared illustration.
|
|
116
|
+
*/
|
|
117
|
+
image?: SemanticImage;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/* RFC-0162: a resolved social/OG image (absolute https url + intrinsic size). */
|
|
121
|
+
export type SemanticImage = {
|
|
122
|
+
url: string;
|
|
123
|
+
width?: number;
|
|
124
|
+
height?: number;
|
|
125
|
+
alt?: string;
|
|
126
|
+
/**
|
|
127
|
+
* RFC-0165/0167: marks a genuine content illustration (author-declared or
|
|
128
|
+
* hero `leadImage`) as opposed to a synthetic fallback (RFC-0150 preview
|
|
129
|
+
* screenshot, business logo). Only `contentImage: true` images are eligible
|
|
130
|
+
* for the image sitemap (`image:image`); all images may serve `og:image`.
|
|
131
|
+
*/
|
|
132
|
+
contentImage?: boolean;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/* RFC-0162: Open Graph `og:type` discriminator. Defaults to "website"; "article" set by RFC-0167. */
|
|
136
|
+
export type OgType = "website" | "article" | "profile";
|
|
137
|
+
|
|
138
|
+
export type SemanticPostalAddress = {
|
|
139
|
+
streetAddress?: string;
|
|
140
|
+
postalCode?: string;
|
|
141
|
+
addressLocality?: string;
|
|
142
|
+
addressCountry?: string;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export type SemanticPerson = {
|
|
146
|
+
name: string;
|
|
147
|
+
role?: string;
|
|
148
|
+
description?: string;
|
|
149
|
+
isDeceased?: boolean;
|
|
150
|
+
/* RFC-0200: governance/presentational affiliations (founder | board | team | patron | author). */
|
|
151
|
+
affiliations?: string[];
|
|
152
|
+
/* RFC-0200: lifespan → schema.org Person.birthDate / deathDate (ISO or year). */
|
|
153
|
+
birthDate?: string;
|
|
154
|
+
deathDate?: string;
|
|
155
|
+
/* RFC-0200: representative portrait (absolute https url) → Person.image. */
|
|
156
|
+
image?: string;
|
|
157
|
+
/* RFC-0200: social/profile URLs → Person.sameAs (entity grounding). */
|
|
158
|
+
sameAs?: string[];
|
|
159
|
+
/* RFC-0200: absolute URL of this person's profile page, when one is live. */
|
|
160
|
+
profileUrl?: string;
|
|
161
|
+
/* RFC-0512: city-level address for Person JSON-LD (consent-gated at emission). */
|
|
162
|
+
address?: { addressLocality: string; addressRegion?: string; addressCountry: string };
|
|
163
|
+
/* RFC-0512: professional expertise areas → Person.knowsAbout. */
|
|
164
|
+
knowsAbout?: string[];
|
|
165
|
+
/* RFC-0512: organization affiliation → Person.affiliation. */
|
|
166
|
+
affiliation?: { name: string; url?: string };
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export type SemanticContactPoint = {
|
|
170
|
+
contactType: string;
|
|
171
|
+
email?: string;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export type SemanticDonationAccount = {
|
|
175
|
+
accountHolder?: string;
|
|
176
|
+
bankName?: string;
|
|
177
|
+
iban?: string;
|
|
178
|
+
bic?: string;
|
|
179
|
+
accountNumber?: string;
|
|
180
|
+
bankCode?: string;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export type SemanticInitiative = {
|
|
184
|
+
id: string;
|
|
185
|
+
name: string;
|
|
186
|
+
summary: string;
|
|
187
|
+
facts?: string[];
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export type SemanticService = {
|
|
191
|
+
id: string;
|
|
192
|
+
name: string;
|
|
193
|
+
description?: string;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/* RFC-0147/RFC-0148: business offer projection (prices + written guarantees + growth modules + terms). */
|
|
197
|
+
export type SemanticGuarantee = {
|
|
198
|
+
id: string;
|
|
199
|
+
label: string;
|
|
200
|
+
detail?: string;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export type SemanticPrice = {
|
|
204
|
+
id: string;
|
|
205
|
+
label: string;
|
|
206
|
+
amount: string;
|
|
207
|
+
currency?: string;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export type SemanticGrowthModule = {
|
|
211
|
+
id: string;
|
|
212
|
+
label: string;
|
|
213
|
+
description?: string;
|
|
214
|
+
price?: string;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export type SemanticOfferCapacity = {
|
|
218
|
+
enabled: boolean;
|
|
219
|
+
timezone: string;
|
|
220
|
+
startsAt: string;
|
|
221
|
+
cadence: "monthly" | "fixed-days";
|
|
222
|
+
cadenceDays?: number;
|
|
223
|
+
slotRange: { min: number; max: number };
|
|
224
|
+
maxSlotsPerWave: number;
|
|
225
|
+
availabilityStatus: "unknown";
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export type SemanticOffer = {
|
|
229
|
+
prices?: SemanticPrice[];
|
|
230
|
+
guarantees?: SemanticGuarantee[];
|
|
231
|
+
growthModules?: SemanticGrowthModule[];
|
|
232
|
+
capacity?: SemanticOfferCapacity;
|
|
233
|
+
changePrice?: string;
|
|
234
|
+
hourlyRate?: string;
|
|
235
|
+
billingDay?: string;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/* RFC-0148: business location projection (NAP + service area). */
|
|
239
|
+
export type SemanticLocation = {
|
|
240
|
+
locality?: string;
|
|
241
|
+
region?: string;
|
|
242
|
+
country?: string;
|
|
243
|
+
serviceArea?: string[];
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/* RFC-0287: business web/domain identity projection (business/{lang}/web.md). */
|
|
247
|
+
export type SemanticWeb = {
|
|
248
|
+
primaryUrl?: string;
|
|
249
|
+
statusUrl?: string;
|
|
250
|
+
domains?: { primary?: string; german?: string };
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export type SemanticFaqEntry = {
|
|
254
|
+
id: string;
|
|
255
|
+
question: string;
|
|
256
|
+
answer: string;
|
|
257
|
+
tags?: string[];
|
|
258
|
+
serviceSlug?: string;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export type SemanticOrganization = {
|
|
262
|
+
name: string;
|
|
263
|
+
legalName?: string;
|
|
264
|
+
description: string;
|
|
265
|
+
url: string;
|
|
266
|
+
foundingYear?: string;
|
|
267
|
+
email?: string;
|
|
268
|
+
registration?: string;
|
|
269
|
+
representative?: string;
|
|
270
|
+
address?: SemanticPostalAddress;
|
|
271
|
+
areaServed?: string[];
|
|
272
|
+
founders?: SemanticPerson[];
|
|
273
|
+
boardMembers?: SemanticPerson[];
|
|
274
|
+
contactPoints?: SemanticContactPoint[];
|
|
275
|
+
donationAccount?: SemanticDonationAccount;
|
|
276
|
+
/* RFC-0147/RFC-0148: projected business catalog (public-visibility schemas). */
|
|
277
|
+
offer?: SemanticOffer;
|
|
278
|
+
services?: SemanticService[];
|
|
279
|
+
location?: SemanticLocation;
|
|
280
|
+
sameAs?: string[];
|
|
281
|
+
/* RFC-0163: organization logo (absolute https url) → schema.org ImageObject. */
|
|
282
|
+
logo?: string;
|
|
283
|
+
/* RFC-0163: representative organization image (absolute https url). */
|
|
284
|
+
image?: string;
|
|
285
|
+
/* RFC-0148: public team members (distinct from governance founders/board). */
|
|
286
|
+
team?: SemanticPerson[];
|
|
287
|
+
/**
|
|
288
|
+
* RFC-0242: explicit schema.org @type override (e.g. `["Organization", "ProfessionalService"]`
|
|
289
|
+
* for a Bodenstation studio deployment). Defaults to `["Organization", "NGO"]` when absent.
|
|
290
|
+
*/
|
|
291
|
+
schemaType?: string[];
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
export type SemanticPageModel = {
|
|
295
|
+
type: SemanticPageType;
|
|
296
|
+
lang: string;
|
|
297
|
+
defaultLanguage?: string;
|
|
298
|
+
url: string;
|
|
299
|
+
title: string;
|
|
300
|
+
description: string;
|
|
301
|
+
/** RFC-0377: optional audience override (falls back to SemanticPageType derivation map). */
|
|
302
|
+
audience?: string;
|
|
303
|
+
heading?: string;
|
|
304
|
+
lead?: string;
|
|
305
|
+
breadcrumbs: SemanticBreadcrumb[];
|
|
306
|
+
/** RFC-0372: unified block array — replaces answerBlocks, contentBlocks, and bodyText. */
|
|
307
|
+
blocks: SemanticBlock[];
|
|
308
|
+
organization: SemanticOrganization;
|
|
309
|
+
people?: SemanticPerson[];
|
|
310
|
+
initiatives?: SemanticInitiative[];
|
|
311
|
+
faqEntries?: SemanticFaqEntry[];
|
|
312
|
+
/**
|
|
313
|
+
* RFC-0143/RFC-0142: resolved per-page output projection. Set by the
|
|
314
|
+
* semantic loaders via resolvePageOutput(); read by the llms formatters.
|
|
315
|
+
* Always resolved (never undefined) once a model leaves the loader.
|
|
316
|
+
*/
|
|
317
|
+
output?: PageOutputProjection;
|
|
318
|
+
/**
|
|
319
|
+
* RFC-0162: per-page social preview image (resolved from the RFC-0150
|
|
320
|
+
* preview pipeline, with a business-logo fallback). Consumed by <SocialMeta>
|
|
321
|
+
* for og:image / twitter:image and by RFC-0163 for primaryImageOfPage.
|
|
322
|
+
*/
|
|
323
|
+
primaryImage?: SemanticImage;
|
|
324
|
+
/**
|
|
325
|
+
* RFC-0209: unresolved hero `leadImage` token ({src, alt}) carried from the
|
|
326
|
+
* framework-free page handler to the asset-aware render layer. Set only when
|
|
327
|
+
* the page declares a hero `leadImage` and no explicit `output.image`. The
|
|
328
|
+
* layout resolves it through the Image Provider Port and promotes it to
|
|
329
|
+
* `primaryImage` (ahead of the RFC-0150 preview-screenshot fallback). The
|
|
330
|
+
* page handler cannot resolve the token to a URL (Astro content-hashing /
|
|
331
|
+
* Image Provider Port run in the render layer), so it ships the raw token.
|
|
332
|
+
*/
|
|
333
|
+
leadImageToken?: { src: string; alt: string };
|
|
334
|
+
/** RFC-0162: Open Graph type. Defaults to "website" when unset. */
|
|
335
|
+
ogType?: OgType;
|
|
336
|
+
/** RFC-0162: Open Graph locale in `xx_XX` form (from system.md i18n hreflang). */
|
|
337
|
+
ogLocale?: string;
|
|
338
|
+
/** RFC-0162: Open Graph alternate locales in `xx_XX` form (other supported languages). */
|
|
339
|
+
ogLocaleAlternates?: string[];
|
|
340
|
+
/* RFC-0167: article metadata — when present, the page emits an Article/BlogPosting node. */
|
|
341
|
+
datePublished?: string;
|
|
342
|
+
dateModified?: string;
|
|
343
|
+
author?: string;
|
|
344
|
+
keywords?: string[];
|
|
345
|
+
/**
|
|
346
|
+
* RFC-0506: author record reference for ratgeber depth-1 pages. When present,
|
|
347
|
+
* buildArticleNode emits a structured Person node with name and optional url
|
|
348
|
+
* instead of a plain string author.
|
|
349
|
+
*/
|
|
350
|
+
authorRecord?: {
|
|
351
|
+
name: string;
|
|
352
|
+
contactUrl?: string;
|
|
353
|
+
};
|
|
354
|
+
/** RFC-0506: latest reviewedAt date from article frontmatter, used for dateModified computation. */
|
|
355
|
+
reviewedAt?: string;
|
|
356
|
+
/** RFC-0506: changelog entries from article frontmatter (RFC-0504), used for dateModified computation. */
|
|
357
|
+
changelog?: Array<{ date: string; summary: string; authorId: string }>;
|
|
358
|
+
/**
|
|
359
|
+
* RFC-0227: stable @id values for all material credit nodes that appear on this page.
|
|
360
|
+
* When set, the WebPage node emits associatedMedia references so search engines can link
|
|
361
|
+
* disclosed credits to the page entity. Populated by page templates that load credit records.
|
|
362
|
+
*/
|
|
363
|
+
materialCreditAtIds?: string[];
|
|
364
|
+
/**
|
|
365
|
+
* RFC-0490: collection items for "collection"-typed pages (e.g. industry links on a pillar hub).
|
|
366
|
+
* Each item is a { url, name } pair emitted as a ListItem in the JSON-LD ItemList node.
|
|
367
|
+
*/
|
|
368
|
+
collectionItems?: Array<{ url: string; name: string }>;
|
|
369
|
+
/** RFC-0492: surface identity for depth-gated JSON-LD corrections. */
|
|
370
|
+
surfaceId?: string;
|
|
371
|
+
/** RFC-0492: surface depth for depth-gated JSON-LD corrections. */
|
|
372
|
+
depth?: number;
|
|
373
|
+
/**
|
|
374
|
+
* RFC-0492/RFC-0498: industry-specific Service node metadata for surface pages where Service is required.
|
|
375
|
+
* When present, `buildJsonLd` emits a single industry Service node instead of the
|
|
376
|
+
* organization-level Service nodes. Covers website-local depth-1, website-service depth-1,
|
|
377
|
+
* and website-local depth-5.
|
|
378
|
+
*/
|
|
379
|
+
industryService?: {
|
|
380
|
+
serviceType: string;
|
|
381
|
+
audience?: string;
|
|
382
|
+
description?: string;
|
|
383
|
+
areaServed?: string;
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* RFC-0512: extra JSON-LD nodes injected into the @graph for team profile pages.
|
|
387
|
+
* AI-agent profile pages inject a SoftwareApplication node; the team hub injects
|
|
388
|
+
* a CollectionPage node with hasPart. Human profile pages do not need this —
|
|
389
|
+
* the extended Person node is already emitted by buildPersonNode.
|
|
390
|
+
*/
|
|
391
|
+
extraGraphNodes?: import("./jsonld/types.ts").JsonLdNode[];
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
export type SemanticSiteModel = {
|
|
395
|
+
baseUrl: string;
|
|
396
|
+
lang: string;
|
|
397
|
+
defaultLanguage?: string;
|
|
398
|
+
organization: SemanticOrganization;
|
|
399
|
+
pages: SemanticPageModel[];
|
|
400
|
+
/** RFC-0789: agent block from system.md, populated by the semantic loader. */
|
|
401
|
+
agent?: { enabled?: boolean };
|
|
402
|
+
};
|