@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,198 @@
|
|
|
1
|
+
/*******************************************************************************
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Defines JSON schemas for passport-related data structures, ensuring data integrity and validation.</purpose>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
<non-goals>
|
|
7
|
+
<item>Do not handle data persistence or retrieval logic.</item>
|
|
8
|
+
<item>Do not perform runtime data transformations outside of validation.</item>
|
|
9
|
+
<item>Do not manage application state or side effects.</item>
|
|
10
|
+
</non-goals>
|
|
11
|
+
</MODULE_CONTRACT>
|
|
12
|
+
|
|
13
|
+
<CHANGE_SUMMARY>
|
|
14
|
+
<item>Tidied by compass.changesummary.tidy; see git history for prior entries.</item>
|
|
15
|
+
</CHANGE_SUMMARY>
|
|
16
|
+
*******************************************************************************/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @warpgogol/werkstatt-shared/passport — Passport JSON schema (schemaVersion 1.0)
|
|
20
|
+
*
|
|
21
|
+
* DNA-31 / RFC-0028
|
|
22
|
+
*
|
|
23
|
+
* This is the authoritative schema for dist/.well-known/cosmic-passport.json.
|
|
24
|
+
* Additive changes bump schemaVersion minor; breaking changes require a
|
|
25
|
+
* superseding RFC.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { z } from "zod";
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Sub-schemas
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
const PlanetPinSchema = z.object({
|
|
35
|
+
cosmicPlanet: z.string().min(1),
|
|
36
|
+
pin: z.string().min(1),
|
|
37
|
+
semanticId: z.string().optional(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const StarCompositionSchema = z.object({
|
|
41
|
+
route: z.string().min(1),
|
|
42
|
+
cosmicStar: z.string().min(1),
|
|
43
|
+
planets: z.array(PlanetPinSchema).default([]),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const CompositionSchema = z.object({
|
|
47
|
+
/**
|
|
48
|
+
* SHA-256 hash of the canonical system.yaml content at build time.
|
|
49
|
+
* Format: "sha256:<hex>"
|
|
50
|
+
*/
|
|
51
|
+
systemHash: z.string().regex(/^sha256:[0-9a-f]{64}$/),
|
|
52
|
+
constellation: z.string().min(1),
|
|
53
|
+
biome: z.string().min(1),
|
|
54
|
+
stars: z.array(StarCompositionSchema).default([]),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const VCProofSchema = z.object({
|
|
58
|
+
type: z.literal("Ed25519Signature2020"),
|
|
59
|
+
created: z.string(),
|
|
60
|
+
verificationMethod: z.string(),
|
|
61
|
+
proofPurpose: z.literal("assertionMethod"),
|
|
62
|
+
/** Multibase-encoded Ed25519 signature */
|
|
63
|
+
proofValue: z.string(),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const VerifiableCredentialSchema = z.object({
|
|
67
|
+
"@context": z.array(z.string()),
|
|
68
|
+
type: z.array(z.string()),
|
|
69
|
+
issuer: z.string(),
|
|
70
|
+
issuanceDate: z.string(),
|
|
71
|
+
credentialSubject: z.object({
|
|
72
|
+
id: z.string(),
|
|
73
|
+
systemHash: z.string(),
|
|
74
|
+
commitSha: z.string(),
|
|
75
|
+
}),
|
|
76
|
+
proof: VCProofSchema,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const ProvenanceSchema = z.object({
|
|
80
|
+
commitSha: z.string().min(1),
|
|
81
|
+
commitAt: z.string(),
|
|
82
|
+
builtAt: z.string(),
|
|
83
|
+
buildDurationMs: z.number().int().nonnegative(),
|
|
84
|
+
builder: z.string().min(1),
|
|
85
|
+
keyVersion: z.string().min(1),
|
|
86
|
+
verifiableCredential: VerifiableCredentialSchema,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const NebulaPillarSchema = z.object({
|
|
90
|
+
score: z.number().min(0).max(100),
|
|
91
|
+
weight: z.number().min(0).max(1),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const ScoresSchema = z.object({
|
|
95
|
+
nebula: z.number().int().min(0).max(100),
|
|
96
|
+
pillars: z.object({
|
|
97
|
+
performance: NebulaPillarSchema,
|
|
98
|
+
accessibility: NebulaPillarSchema,
|
|
99
|
+
contentHealth: NebulaPillarSchema,
|
|
100
|
+
architecturalCompliance: NebulaPillarSchema,
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const LinksSchema = z.object({
|
|
105
|
+
starMapSvg: z.string(),
|
|
106
|
+
publicKey: z.string(),
|
|
107
|
+
dnaReport: z.string(),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Root schema
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
export const PassportSchema = z.object({
|
|
115
|
+
schemaVersion: z.literal("1.0"),
|
|
116
|
+
appId: z.string().min(1),
|
|
117
|
+
issuedAt: z.string(),
|
|
118
|
+
composition: CompositionSchema,
|
|
119
|
+
provenance: ProvenanceSchema,
|
|
120
|
+
scores: ScoresSchema,
|
|
121
|
+
links: LinksSchema,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// Public key file schema (/.well-known/cosmic-passport-key.json)
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
export const PassportPublicKeyEntrySchema = z.object({
|
|
129
|
+
version: z.string().min(1),
|
|
130
|
+
active: z.boolean(),
|
|
131
|
+
type: z.literal("Ed25519VerificationKey2020"),
|
|
132
|
+
/** Multibase-encoded (base58btc, prefix "z") Ed25519 public key */
|
|
133
|
+
publicKeyMultibase: z.string().regex(/^z[1-9A-HJ-NP-Za-km-z]+$/),
|
|
134
|
+
createdAt: z.string(),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
export const PassportPublicKeyFileSchema = z.object({
|
|
138
|
+
schemaVersion: z.literal("1.0"),
|
|
139
|
+
appId: z.string().min(1),
|
|
140
|
+
keys: z.array(PassportPublicKeyEntrySchema).min(1),
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// Identity credentials (RFC-0558)
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
export const SiteOwnershipCredentialSubjectSchema = z.object({
|
|
148
|
+
id: z.string().min(1),
|
|
149
|
+
siteId: z.string().min(1),
|
|
150
|
+
role: z.literal("owner"),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
export const ActorDelegationCredentialSubjectSchema = z.object({
|
|
154
|
+
id: z.string().min(1),
|
|
155
|
+
siteId: z.string().min(1),
|
|
156
|
+
delegatedBy: z.string().min(1),
|
|
157
|
+
expiresAt: z.string().datetime(),
|
|
158
|
+
scopes: z.array(z.string().min(1)),
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
export const WerkstattCredentialSchema = z.object({
|
|
162
|
+
credentialId: z.string().min(1),
|
|
163
|
+
type: z.enum(["SiteOwnershipCredential", "ActorDelegationCredential"]),
|
|
164
|
+
subject: z.union([SiteOwnershipCredentialSubjectSchema, ActorDelegationCredentialSubjectSchema]),
|
|
165
|
+
proof: VCProofSchema,
|
|
166
|
+
issuedAt: z.string().datetime(),
|
|
167
|
+
issuer: z.string().min(1),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
export const WerkstattIdentityConfigSchema = z.object({
|
|
171
|
+
schemaVersion: z.literal("1.0"),
|
|
172
|
+
operatorName: z.string().min(1),
|
|
173
|
+
operatorKeyPair: z.object({
|
|
174
|
+
publicKeyMultibase: z.string().regex(/^z[1-9A-HJ-NP-Za-km-z]+$/),
|
|
175
|
+
keyVersion: z.string().min(1),
|
|
176
|
+
algId: z.literal("Ed25519Signature2020"),
|
|
177
|
+
}),
|
|
178
|
+
authMode: z.enum(["permissive", "enforced"]),
|
|
179
|
+
domain: z.string().min(1),
|
|
180
|
+
issuedCredentials: z.array(WerkstattCredentialSchema),
|
|
181
|
+
revokedCredentialIds: z.array(z.string().min(1)),
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// TypeScript types
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
export type PassportJson = z.infer<typeof PassportSchema>;
|
|
189
|
+
export type PassportPublicKeyFile = z.infer<typeof PassportPublicKeyFileSchema>;
|
|
190
|
+
export type PassportPublicKeyEntry = z.infer<typeof PassportPublicKeyEntrySchema>;
|
|
191
|
+
export type VCProof = z.infer<typeof VCProofSchema>;
|
|
192
|
+
export type VerifiableCredential = z.infer<typeof VerifiableCredentialSchema>;
|
|
193
|
+
export type SiteOwnershipCredentialSubject = z.infer<typeof SiteOwnershipCredentialSubjectSchema>;
|
|
194
|
+
export type ActorDelegationCredentialSubject = z.infer<
|
|
195
|
+
typeof ActorDelegationCredentialSubjectSchema
|
|
196
|
+
>;
|
|
197
|
+
export type WerkstattCredential = z.infer<typeof WerkstattCredentialSchema>;
|
|
198
|
+
export type WerkstattIdentityConfig = z.infer<typeof WerkstattIdentityConfigSchema>;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/* <MODULE_CONTRACT>
|
|
2
|
+
<purpose>Facilitates Ed25519 key generation, signing, and verification for verifiable credentials.</purpose>
|
|
3
|
+
<non-goals>
|
|
4
|
+
<item>Do not handle raw key storage or management.</item>
|
|
5
|
+
<item>Do not perform network operations or external API calls.</item>
|
|
6
|
+
<item>Do not parse or validate credential content beyond signing/verification.</item>
|
|
7
|
+
</non-goals>
|
|
8
|
+
</MODULE_CONTRACT>
|
|
9
|
+
<CHANGE_SUMMARY>
|
|
10
|
+
<item>Tidied by compass.changesummary.tidy; see git history for prior entries.</item>
|
|
11
|
+
</CHANGE_SUMMARY> */
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @warpgogol/werkstatt-shared/passport — Ed25519 VC signing helpers
|
|
15
|
+
*
|
|
16
|
+
* DNA-34 / RFC-0028
|
|
17
|
+
*
|
|
18
|
+
* Uses the Web Crypto API (available in Node.js 16+ and all modern browsers).
|
|
19
|
+
* No private keys are ever written to disk by this module.
|
|
20
|
+
*
|
|
21
|
+
* SECURITY CONTRACT:
|
|
22
|
+
* - Private keys arrive exclusively as environment variable `PASSPORT_SIGNING_KEY`
|
|
23
|
+
* (hex-encoded, 32 bytes) or as a runtime parameter in key-rotate.ts.
|
|
24
|
+
* - This module never logs, writes, or returns private key material.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import * as ed from "@noble/ed25519";
|
|
28
|
+
import bs58 from "bs58";
|
|
29
|
+
import type { VCProof, VerifiableCredential } from "./schema.ts";
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Multibase base58btc encoding (prefix "z")
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
/** Encode bytes as multibase base58btc (prefix "z"). */
|
|
36
|
+
export function toMultibase(bytes: Uint8Array): string {
|
|
37
|
+
return "z" + bs58.encode(bytes);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Decode multibase base58btc string (prefix "z") to bytes. */
|
|
41
|
+
export function fromMultibase(multibase: string): Uint8Array {
|
|
42
|
+
if (!multibase.startsWith("z")) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Unsupported multibase prefix "${multibase[0]}". Only "z" (base58btc) is supported.`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return bs58.decode(multibase.slice(1));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// The canonical credential subject digest
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
/** The data signed in the VC proof — composition hash + commit SHA. */
|
|
55
|
+
export interface CredentialSubjectDigest {
|
|
56
|
+
systemHash: string;
|
|
57
|
+
commitSha: string;
|
|
58
|
+
issuedAt: string;
|
|
59
|
+
appId: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Produce the canonical UTF-8 bytes that are signed/verified.
|
|
64
|
+
* DETERMINISM: identical inputs → identical bytes.
|
|
65
|
+
*/
|
|
66
|
+
export function credentialBytes(subject: CredentialSubjectDigest): Uint8Array {
|
|
67
|
+
// Stable JSON: sorted keys, no whitespace
|
|
68
|
+
const canonical = JSON.stringify({
|
|
69
|
+
appId: subject.appId,
|
|
70
|
+
commitSha: subject.commitSha,
|
|
71
|
+
issuedAt: subject.issuedAt,
|
|
72
|
+
systemHash: subject.systemHash,
|
|
73
|
+
});
|
|
74
|
+
return new TextEncoder().encode(canonical);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Key generation
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Generate a new Ed25519 keypair.
|
|
83
|
+
* @returns { privateKeyHex, publicKeyBytes, publicKeyMultibase }
|
|
84
|
+
*
|
|
85
|
+
* The private key is returned as a hex string for one-time copy into a
|
|
86
|
+
* GitHub Actions secret. It is NEVER written to disk by this function.
|
|
87
|
+
*/
|
|
88
|
+
export async function generateKeypair(): Promise<{
|
|
89
|
+
privateKeyHex: string;
|
|
90
|
+
publicKeyBytes: Uint8Array;
|
|
91
|
+
publicKeyMultibase: string;
|
|
92
|
+
}> {
|
|
93
|
+
const privateKeyBytes = ed.utils.randomSecretKey();
|
|
94
|
+
const publicKeyBytes = await ed.getPublicKeyAsync(privateKeyBytes);
|
|
95
|
+
return {
|
|
96
|
+
privateKeyHex: Buffer.from(privateKeyBytes).toString("hex"),
|
|
97
|
+
publicKeyBytes,
|
|
98
|
+
publicKeyMultibase: toMultibase(publicKeyBytes),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Signing
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Sign the credential subject and produce a W3C VC proof.
|
|
108
|
+
*
|
|
109
|
+
* @param subject — canonical credential subject fields
|
|
110
|
+
* @param privateKeyHex — 32-byte Ed25519 private key as hex (from env secret)
|
|
111
|
+
* @param verificationMethod — DID key reference (e.g. "did:web:example.org#key-v1")
|
|
112
|
+
*/
|
|
113
|
+
// @ai-invariant: signCredential uses @noble/ed25519. Private keys arrive
|
|
114
|
+
// exclusively as hex env vars — never logged, written to disk, or returned.
|
|
115
|
+
// The signed output is a W3C VC with Ed25519Signature2020 proof.
|
|
116
|
+
|
|
117
|
+
export async function signCredential(
|
|
118
|
+
subject: CredentialSubjectDigest,
|
|
119
|
+
privateKeyHex: string,
|
|
120
|
+
verificationMethod: string,
|
|
121
|
+
): Promise<VCProof> {
|
|
122
|
+
const privateKeyBytes = new Uint8Array(Buffer.from(privateKeyHex, "hex"));
|
|
123
|
+
const message = credentialBytes(subject);
|
|
124
|
+
const signatureBytes = await ed.signAsync(message, privateKeyBytes);
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
type: "Ed25519Signature2020",
|
|
128
|
+
created: subject.issuedAt,
|
|
129
|
+
verificationMethod,
|
|
130
|
+
proofPurpose: "assertionMethod",
|
|
131
|
+
proofValue: toMultibase(signatureBytes),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
// Verification
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Verify a VC proof against the published public key.
|
|
141
|
+
*
|
|
142
|
+
* @param subject — credential subject fields from passport.json
|
|
143
|
+
* @param proof — proof object from passport.json
|
|
144
|
+
* @param publicKeyMultibase — multibase public key from cosmic-passport-key.json
|
|
145
|
+
* @returns true if signature is valid
|
|
146
|
+
*/
|
|
147
|
+
export async function verifyCredential(
|
|
148
|
+
subject: CredentialSubjectDigest,
|
|
149
|
+
proof: VCProof,
|
|
150
|
+
publicKeyMultibase: string,
|
|
151
|
+
): Promise<boolean> {
|
|
152
|
+
try {
|
|
153
|
+
const publicKeyBytes = fromMultibase(publicKeyMultibase);
|
|
154
|
+
const signatureBytes = fromMultibase(proof.proofValue);
|
|
155
|
+
const message = credentialBytes(subject);
|
|
156
|
+
return await ed.verifyAsync(signatureBytes, message, publicKeyBytes);
|
|
157
|
+
} catch {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Raw detached signing (RFC-0135 amend provenance trail)
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Sign arbitrary bytes with an Ed25519 private key, returning a multibase
|
|
168
|
+
* base58btc detached signature. Reused by the amend provenance trail
|
|
169
|
+
* (RFC-0135) so provenance records carry the same signing facility as the
|
|
170
|
+
* Cosmic Passport (RFC-0028).
|
|
171
|
+
*
|
|
172
|
+
* @param privateKeyHex — 32-byte Ed25519 private key as hex (from env secret)
|
|
173
|
+
* @param message — canonical bytes to sign
|
|
174
|
+
*/
|
|
175
|
+
export async function signBytes(privateKeyHex: string, message: Uint8Array): Promise<string> {
|
|
176
|
+
const privateKeyBytes = new Uint8Array(Buffer.from(privateKeyHex, "hex"));
|
|
177
|
+
const signatureBytes = await ed.signAsync(message, privateKeyBytes);
|
|
178
|
+
return toMultibase(signatureBytes);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Verify a multibase detached signature produced by {@link signBytes} against
|
|
183
|
+
* a multibase public key. Returns false on any decode/verify failure.
|
|
184
|
+
*/
|
|
185
|
+
export async function verifyBytes(
|
|
186
|
+
publicKeyMultibase: string,
|
|
187
|
+
message: Uint8Array,
|
|
188
|
+
signatureMultibase: string,
|
|
189
|
+
): Promise<boolean> {
|
|
190
|
+
try {
|
|
191
|
+
const publicKeyBytes = fromMultibase(publicKeyMultibase);
|
|
192
|
+
const signatureBytes = fromMultibase(signatureMultibase);
|
|
193
|
+
return await ed.verifyAsync(signatureBytes, message, publicKeyBytes);
|
|
194
|
+
} catch {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
// Assemble full VC
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
|
|
203
|
+
export function assembleVerifiableCredential(
|
|
204
|
+
appId: string,
|
|
205
|
+
domain: string,
|
|
206
|
+
subject: CredentialSubjectDigest,
|
|
207
|
+
proof: VCProof,
|
|
208
|
+
keyVersion: string,
|
|
209
|
+
): VerifiableCredential {
|
|
210
|
+
return {
|
|
211
|
+
"@context": ["https://www.w3.org/2018/credentials/v1"],
|
|
212
|
+
type: ["VerifiableCredential", "CosmicPassportCredential"],
|
|
213
|
+
issuer: `did:web:${domain}`,
|
|
214
|
+
issuanceDate: subject.issuedAt,
|
|
215
|
+
credentialSubject: {
|
|
216
|
+
id: `urn:warpgogol:app:${appId}`,
|
|
217
|
+
systemHash: subject.systemHash,
|
|
218
|
+
commitSha: subject.commitSha,
|
|
219
|
+
},
|
|
220
|
+
proof: {
|
|
221
|
+
...proof,
|
|
222
|
+
verificationMethod: `did:web:${domain}#key-${keyVersion}`,
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { test, expect } from "vitest";
|
|
2
|
+
import fc from "fast-check";
|
|
3
|
+
import { PassportSchema } from "../schema.ts";
|
|
4
|
+
|
|
5
|
+
const validHash = "sha256:" + "a".repeat(64);
|
|
6
|
+
|
|
7
|
+
const arbValidPassport = fc.record({
|
|
8
|
+
schemaVersion: fc.constant("1.0"),
|
|
9
|
+
appId: fc.string({ minLength: 1, maxLength: 20 }),
|
|
10
|
+
issuedAt: fc.string({ minLength: 1, maxLength: 30 }),
|
|
11
|
+
composition: fc.record({
|
|
12
|
+
systemHash: fc.constant(validHash),
|
|
13
|
+
constellation: fc.string({ minLength: 1, maxLength: 20 }),
|
|
14
|
+
biome: fc.string({ minLength: 1, maxLength: 20 }),
|
|
15
|
+
stars: fc.constant([]),
|
|
16
|
+
}),
|
|
17
|
+
provenance: fc.record({
|
|
18
|
+
commitSha: fc.string({ minLength: 1, maxLength: 40 }),
|
|
19
|
+
commitAt: fc.string({ minLength: 1, maxLength: 30 }),
|
|
20
|
+
builtAt: fc.string({ minLength: 1, maxLength: 30 }),
|
|
21
|
+
buildDurationMs: fc.integer({ min: 0, max: 999999 }),
|
|
22
|
+
builder: fc.string({ minLength: 1, maxLength: 20 }),
|
|
23
|
+
keyVersion: fc.string({ minLength: 1, maxLength: 10 }),
|
|
24
|
+
verifiableCredential: fc.record({
|
|
25
|
+
"@context": fc.constant(["https://www.w3.org/2018/credentials/v1"]),
|
|
26
|
+
type: fc.constant(["VerifiableCredential"]),
|
|
27
|
+
issuer: fc.string({ minLength: 1, maxLength: 50 }),
|
|
28
|
+
issuanceDate: fc.string({ minLength: 1, maxLength: 30 }),
|
|
29
|
+
credentialSubject: fc.record({
|
|
30
|
+
id: fc.string({ minLength: 1, maxLength: 50 }),
|
|
31
|
+
systemHash: fc.constant(validHash),
|
|
32
|
+
commitSha: fc.string({ minLength: 1, maxLength: 40 }),
|
|
33
|
+
}),
|
|
34
|
+
proof: fc.record({
|
|
35
|
+
type: fc.constant("Ed25519Signature2020"),
|
|
36
|
+
created: fc.string({ minLength: 1, maxLength: 30 }),
|
|
37
|
+
verificationMethod: fc.string({ minLength: 1, maxLength: 50 }),
|
|
38
|
+
proofPurpose: fc.constant("assertionMethod"),
|
|
39
|
+
proofValue: fc.string({ minLength: 1, maxLength: 100 }),
|
|
40
|
+
}),
|
|
41
|
+
}),
|
|
42
|
+
}),
|
|
43
|
+
scores: fc.record({
|
|
44
|
+
nebula: fc.integer({ min: 0, max: 100 }),
|
|
45
|
+
pillars: fc.record({
|
|
46
|
+
performance: fc.record({
|
|
47
|
+
score: fc.float({ min: 0, max: 100, noNaN: true }),
|
|
48
|
+
weight: fc.float({ min: 0, max: 1, noNaN: true }),
|
|
49
|
+
}),
|
|
50
|
+
accessibility: fc.record({
|
|
51
|
+
score: fc.float({ min: 0, max: 100, noNaN: true }),
|
|
52
|
+
weight: fc.float({ min: 0, max: 1, noNaN: true }),
|
|
53
|
+
}),
|
|
54
|
+
contentHealth: fc.record({
|
|
55
|
+
score: fc.float({ min: 0, max: 100, noNaN: true }),
|
|
56
|
+
weight: fc.float({ min: 0, max: 1, noNaN: true }),
|
|
57
|
+
}),
|
|
58
|
+
architecturalCompliance: fc.record({
|
|
59
|
+
score: fc.float({ min: 0, max: 100, noNaN: true }),
|
|
60
|
+
weight: fc.float({ min: 0, max: 1, noNaN: true }),
|
|
61
|
+
}),
|
|
62
|
+
}),
|
|
63
|
+
}),
|
|
64
|
+
links: fc.record({
|
|
65
|
+
starMapSvg: fc.string({ minLength: 1, maxLength: 50 }),
|
|
66
|
+
publicKey: fc.string({ minLength: 1, maxLength: 50 }),
|
|
67
|
+
dnaReport: fc.string({ minLength: 1, maxLength: 50 }),
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("PBT: valid passport always passes schema validation", () => {
|
|
72
|
+
fc.assert(
|
|
73
|
+
fc.property(arbValidPassport, (passport) => {
|
|
74
|
+
expect(PassportSchema.safeParse(passport).success).toBe(true);
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("PBT: nebula score outside [0,100] always fails", () => {
|
|
80
|
+
fc.assert(
|
|
81
|
+
fc.property(
|
|
82
|
+
arbValidPassport,
|
|
83
|
+
fc.integer({ min: -500, max: 500 }).filter((n) => n < 0 || n > 100),
|
|
84
|
+
(passport, badNebula) => {
|
|
85
|
+
const result = PassportSchema.safeParse({
|
|
86
|
+
...passport,
|
|
87
|
+
scores: { ...passport.scores, nebula: badNebula },
|
|
88
|
+
});
|
|
89
|
+
expect(result.success).toBe(false);
|
|
90
|
+
},
|
|
91
|
+
),
|
|
92
|
+
);
|
|
93
|
+
});
|