@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.
Files changed (403) hide show
  1. package/package.json +352 -0
  2. package/src/checks/index.ts +24 -0
  3. package/src/checks/lib/astro-site-url.ts +30 -0
  4. package/src/checks/lib/i18n.ts +30 -0
  5. package/src/checks/result-helpers.ts +102 -0
  6. package/src/checks/suppressions-config.ts +195 -0
  7. package/src/index.ts +14 -0
  8. package/src/integration/README.md +38 -0
  9. package/src/integration/adapters.ts +143 -0
  10. package/src/integration/crm-buffer.ts +491 -0
  11. package/src/integration/dispatch.ts +106 -0
  12. package/src/integration/funnel.ts +379 -0
  13. package/src/integration/index.ts +56 -0
  14. package/src/integration/lifecycle.ts +155 -0
  15. package/src/integration/orchestration.ts +439 -0
  16. package/src/integration/port-barrel.ts +124 -0
  17. package/src/integration/port.ts +143 -0
  18. package/src/integration/qstash.ts +134 -0
  19. package/src/integration/sharding.ts +133 -0
  20. package/src/integration/tests/deliver-event.test.ts +52 -0
  21. package/src/integration/tests/dispatch.test.ts +88 -0
  22. package/src/integration/tests/funnel-bridge.test.ts +46 -0
  23. package/src/integration/tests/hub-runtime.test.ts +128 -0
  24. package/src/integration/tests/lifecycle.test.ts +69 -0
  25. package/src/integration/tests/qstash.test.ts +83 -0
  26. package/src/integration/tests/sharding.test.ts +64 -0
  27. package/src/integration/vitest.config.ts +8 -0
  28. package/src/integration-adapter-supabase-crm/adapter.ts +437 -0
  29. package/src/integration-adapter-supabase-crm/client.ts +605 -0
  30. package/src/integration-adapter-supabase-crm/index.ts +28 -0
  31. package/src/integration-adapter-supabase-crm/pipedrive-sync-target.ts +482 -0
  32. package/src/integration-adapter-supabase-crm/supabase-rest.ts +89 -0
  33. package/src/integration-adapter-supabase-crm/tenant-registry.ts +334 -0
  34. package/src/integration-adapter-supabase-crm/tests/change-balance.pbt.test.ts +83 -0
  35. package/src/integration-adapter-supabase-crm/tests/funnel-persistence.test.ts +409 -0
  36. package/src/integration-adapter-supabase-crm/tests/lifecycle-sync.test.ts +288 -0
  37. package/src/integration-adapter-supabase-crm/tests/stage-map.test.ts +80 -0
  38. package/src/integration-adapter-supabase-crm/vitest.config.ts +8 -0
  39. package/src/integration-adapter-supabase-crm/worker.ts +223 -0
  40. package/src/observability/conventions.ts +93 -0
  41. package/src/observability/env-resolver.ts +57 -0
  42. package/src/observability/index.ts +57 -0
  43. package/src/observability/metric-registry.ts +184 -0
  44. package/src/observability/otlp-converter.ts +125 -0
  45. package/src/observability/otlp-json.ts +135 -0
  46. package/src/observability/otlp-transport.ts +68 -0
  47. package/src/observability/pusher.ts +142 -0
  48. package/src/observability/redact.ts +27 -0
  49. package/src/observability/tests/conventions.test.ts +100 -0
  50. package/src/observability/tests/metric-registry.test.ts +117 -0
  51. package/src/observability/tests/otlp-converter.pbt.test.ts +77 -0
  52. package/src/observability/tests/otlp-converter.test.ts +157 -0
  53. package/src/observability/tests/otlp-json.test.ts +120 -0
  54. package/src/observability/tests/pusher.test.ts +75 -0
  55. package/src/observability/tests/redact.pbt.test.ts +71 -0
  56. package/src/observability/tests/redact.test.ts +37 -0
  57. package/src/observability/typed-refs.ts +137 -0
  58. package/src/observability/vitest.config.ts +8 -0
  59. package/src/ontology/analytics/matomo-binding.yaml +172 -0
  60. package/src/ontology/analytics/matomo-fleet.registry.yaml +26 -0
  61. package/src/ontology/analytics/messkanon.yaml +151 -0
  62. package/src/ontology/archetype-registry.ts +61 -0
  63. package/src/ontology/archetypes/components/brand-label.yaml +19 -0
  64. package/src/ontology/archetypes/components/copyright.yaml +19 -0
  65. package/src/ontology/archetypes/components/currency-aware-price-display.yaml +19 -0
  66. package/src/ontology/archetypes/components/currency-selector.yaml +19 -0
  67. package/src/ontology/archetypes/components/footer-promo.yaml +19 -0
  68. package/src/ontology/archetypes/components/lang-switcher.yaml +19 -0
  69. package/src/ontology/archetypes/components/layout.yaml +19 -0
  70. package/src/ontology/archetypes/components/live-photo.yaml +20 -0
  71. package/src/ontology/archetypes/components/material-credit.yaml +20 -0
  72. package/src/ontology/archetypes/components/media.yaml +21 -0
  73. package/src/ontology/archetypes/components/nachweis-card.yaml +34 -0
  74. package/src/ontology/archetypes/components/nachweis-detail.yaml +43 -0
  75. package/src/ontology/archetypes/components/nachweis-list.yaml +37 -0
  76. package/src/ontology/archetypes/components/nachweis-verify.yaml +31 -0
  77. package/src/ontology/archetypes/components/not-found.yaml +22 -0
  78. package/src/ontology/archetypes/components/offer-capacity.yaml +21 -0
  79. package/src/ontology/archetypes/components/passport-header.yaml +19 -0
  80. package/src/ontology/archetypes/components/passport-provenance.yaml +20 -0
  81. package/src/ontology/archetypes/components/passport-score-grid.yaml +20 -0
  82. package/src/ontology/archetypes/components/passport-star-map.yaml +20 -0
  83. package/src/ontology/archetypes/components/person-profile.yaml +20 -0
  84. package/src/ontology/archetypes/components/pulsar.yaml +20 -0
  85. package/src/ontology/archetypes/components/responsive-image.yaml +19 -0
  86. package/src/ontology/archetypes/components/scroll-to-top.yaml +22 -0
  87. package/src/ontology/archetypes/components/social-meta.yaml +20 -0
  88. package/src/ontology/archetypes/components/structured-data.yaml +19 -0
  89. package/src/ontology/archetypes/index.json +1003 -0
  90. package/src/ontology/archetypes/index.yaml +821 -0
  91. package/src/ontology/archetypes/sections/approach.yaml +23 -0
  92. package/src/ontology/archetypes/sections/article-list.yaml +30 -0
  93. package/src/ontology/archetypes/sections/audience-cards.yaml +30 -0
  94. package/src/ontology/archetypes/sections/breadcrumbs.yaml +21 -0
  95. package/src/ontology/archetypes/sections/chat-widget.yaml +37 -0
  96. package/src/ontology/archetypes/sections/comparison-cards.yaml +31 -0
  97. package/src/ontology/archetypes/sections/controlled-responsibility-block.yaml +34 -0
  98. package/src/ontology/archetypes/sections/credits.yaml +29 -0
  99. package/src/ontology/archetypes/sections/donation-card.yaml +53 -0
  100. package/src/ontology/archetypes/sections/donation-use.yaml +23 -0
  101. package/src/ontology/archetypes/sections/dynamic-status-block.yaml +35 -0
  102. package/src/ontology/archetypes/sections/faq-list.yaml +26 -0
  103. package/src/ontology/archetypes/sections/final-cta.yaml +53 -0
  104. package/src/ontology/archetypes/sections/hero-decision-card.yaml +65 -0
  105. package/src/ontology/archetypes/sections/hero.yaml +50 -0
  106. package/src/ontology/archetypes/sections/impact.yaml +23 -0
  107. package/src/ontology/archetypes/sections/markdown.yaml +43 -0
  108. package/src/ontology/archetypes/sections/mountain-journey.yaml +43 -0
  109. package/src/ontology/archetypes/sections/navigation.yaml +20 -0
  110. package/src/ontology/archetypes/sections/notausgang-block.yaml +41 -0
  111. package/src/ontology/archetypes/sections/open-source-registry.yaml +26 -0
  112. package/src/ontology/archetypes/sections/ownership-block.yaml +57 -0
  113. package/src/ontology/archetypes/sections/people.yaml +48 -0
  114. package/src/ontology/archetypes/sections/price-card.yaml +50 -0
  115. package/src/ontology/archetypes/sections/problem.yaml +23 -0
  116. package/src/ontology/archetypes/sections/send-message.yaml +63 -0
  117. package/src/ontology/archetypes/sections/service-metadata-block.yaml +40 -0
  118. package/src/ontology/archetypes/sections/social-proof.yaml +27 -0
  119. package/src/ontology/archetypes/sections/transparency.yaml +32 -0
  120. package/src/ontology/archetypes/sections/trust-strip.yaml +42 -0
  121. package/src/ontology/archetypes/sections/video-section.yaml +27 -0
  122. package/src/ontology/archetypes/sections/women.yaml +29 -0
  123. package/src/ontology/biome-token-projection.ts +229 -0
  124. package/src/ontology/biomes/check-concrete-blueprint.yaml +118 -0
  125. package/src/ontology/biomes/handwerk-material-warm.yaml +135 -0
  126. package/src/ontology/biomes/nonprofit-trust.yaml +123 -0
  127. package/src/ontology/blueprints/offer.yaml +39 -0
  128. package/src/ontology/blueprints/prompts/local-market-signal.md +13 -0
  129. package/src/ontology/blueprints/prompts/website-local-narrative.md +24 -0
  130. package/src/ontology/blueprints/ratgeber.yaml +62 -0
  131. package/src/ontology/blueprints/website-local.yaml +309 -0
  132. package/src/ontology/blueprints/website-service.yaml +84 -0
  133. package/src/ontology/capabilities/lead.submit.yaml +44 -0
  134. package/src/ontology/cosmic/index.ts +48 -0
  135. package/src/ontology/cosmic/moon-catalog.ts +173 -0
  136. package/src/ontology/cosmic/planet-catalog.ts +82 -0
  137. package/src/ontology/cosmic/star-catalog.ts +337 -0
  138. package/src/ontology/enums.ts +159 -0
  139. package/src/ontology/external-surfaces/index.ts +158 -0
  140. package/src/ontology/external-surfaces/jsonld-types.yaml +135 -0
  141. package/src/ontology/external-surfaces/sitemap-shape.yaml +6 -0
  142. package/src/ontology/external-surfaces/url-schema.yaml +95 -0
  143. package/src/ontology/growth/events/contact-email-click.yaml +21 -0
  144. package/src/ontology/growth/events/contact-form-submit.yaml +25 -0
  145. package/src/ontology/growth/events/contact-phone-click.yaml +21 -0
  146. package/src/ontology/growth/events/contact-route-click.yaml +21 -0
  147. package/src/ontology/growth/events/contact-submit.yaml +28 -0
  148. package/src/ontology/growth/events/contact-whatsapp-click.yaml +21 -0
  149. package/src/ontology/growth/events/cta-click.yaml +30 -0
  150. package/src/ontology/growth/events/donation-confirmed.yaml +32 -0
  151. package/src/ontology/growth/events/donation-form-start.yaml +21 -0
  152. package/src/ontology/growth/events/donation-form-submit.yaml +29 -0
  153. package/src/ontology/growth/events/donation-intent.yaml +29 -0
  154. package/src/ontology/growth/events/form-error.yaml +27 -0
  155. package/src/ontology/growth/events/form-start.yaml +21 -0
  156. package/src/ontology/growth/events/form-submit.yaml +21 -0
  157. package/src/ontology/growth/events/outbound-click.yaml +25 -0
  158. package/src/ontology/growth/events/page-view.yaml +24 -0
  159. package/src/ontology/growth/events/passport-view.yaml +28 -0
  160. package/src/ontology/growth/events/star-map-navigate.yaml +30 -0
  161. package/src/ontology/index.ts +165 -0
  162. package/src/ontology/manifest.ts +344 -0
  163. package/src/ontology/operations/index.ts +1 -0
  164. package/src/ontology/schemas/biome.ts +303 -0
  165. package/src/ontology/schemas/capability.ts +104 -0
  166. package/src/ontology/schemas/constellation.ts +114 -0
  167. package/src/ontology/schemas/dns-records.ts +53 -0
  168. package/src/ontology/schemas/index.ts +95 -0
  169. package/src/ontology/schemas/manifest-resolver.ts +123 -0
  170. package/src/ontology/schemas/page-entry.ts +213 -0
  171. package/src/ontology/schemas/section-archetype.ts +109 -0
  172. package/src/ontology/schemas/site-family.ts +98 -0
  173. package/src/ontology/schemas/system/growth.ts +80 -0
  174. package/src/ontology/schemas/system/integrations.ts +143 -0
  175. package/src/ontology/schemas/system/manifest.ts +492 -0
  176. package/src/ontology/schemas/system/page-output.ts +99 -0
  177. package/src/ontology/schemas/system/release.ts +58 -0
  178. package/src/ontology/schemas/system/text.ts +58 -0
  179. package/src/ontology/schemas/system.ts +53 -0
  180. package/src/ontology/shared-section-props/body-fragments.ts +182 -0
  181. package/src/ontology/shared-section-props/catalog.ts +195 -0
  182. package/src/ontology/shared-section-props/common.ts +178 -0
  183. package/src/ontology/shared-section-props/index.ts +34 -0
  184. package/src/ontology/shared-section-props/visual-header.ts +163 -0
  185. package/src/ontology/site-families/charity-donation-trust/cultural-rules.yaml +6 -0
  186. package/src/ontology/site-families/charity-donation-trust/family.yaml +44 -0
  187. package/src/ontology/site-families/charity-donation-trust/linguistic-rules.yaml +6 -0
  188. package/src/ontology/site-families/check-quality-operator/cultural-rules.yaml +6 -0
  189. package/src/ontology/site-families/check-quality-operator/family.yaml +40 -0
  190. package/src/ontology/site-families/check-quality-operator/linguistic-rules.yaml +6 -0
  191. package/src/ontology/site-families/handwerk-trust-engineering/cultural-rules.yaml +6 -0
  192. package/src/ontology/site-families/handwerk-trust-engineering/family.yaml +53 -0
  193. package/src/ontology/site-families/handwerk-trust-engineering/linguistic-rules.yaml +6 -0
  194. package/src/ontology/tests/catalogs.pbt.test.ts +89 -0
  195. package/src/ontology/tests/enums.test.ts +203 -0
  196. package/src/ontology/tests/sternsystem-owner.test.ts +63 -0
  197. package/src/ontology/vitest.config.ts +8 -0
  198. package/src/passport/dht-sign.test.ts +99 -0
  199. package/src/passport/dht-sign.ts +73 -0
  200. package/src/passport/identity-sign.test.ts +134 -0
  201. package/src/passport/identity-sign.ts +85 -0
  202. package/src/passport/index.ts +53 -0
  203. package/src/passport/key-rotate.ts +133 -0
  204. package/src/passport/schema.ts +198 -0
  205. package/src/passport/sign.ts +225 -0
  206. package/src/passport/tests/schema.pbt.test.ts +93 -0
  207. package/src/passport/tests/schema.test.ts +222 -0
  208. package/src/passport/vitest.config.ts +8 -0
  209. package/src/share/agent/api-catalog.ts +77 -0
  210. package/src/share/agent/capability.ts +68 -0
  211. package/src/share/agent/dns-aid.test.ts +74 -0
  212. package/src/share/agent/dns-aid.ts +53 -0
  213. package/src/share/agent/fleet-catalog.ts +149 -0
  214. package/src/share/agent/index.ts +29 -0
  215. package/src/share/agent/knowledge.ts +96 -0
  216. package/src/share/agent/manifest.ts +126 -0
  217. package/src/share/agent/mcp-card.ts +63 -0
  218. package/src/share/agent/omit-empty.ts +77 -0
  219. package/src/share/agent/openapi.ts +157 -0
  220. package/src/share/agent/proof.ts +61 -0
  221. package/src/share/attribution-display.ts +86 -0
  222. package/src/share/check-hints.ts +38 -0
  223. package/src/share/content/entity-id.ts +65 -0
  224. package/src/share/content/index.ts +16 -0
  225. package/src/share/content/merge.ts +86 -0
  226. package/src/share/content/resolve-field-path.ts +39 -0
  227. package/src/share/content/substitute-deep.ts +47 -0
  228. package/src/share/content-discipline/index.ts +14 -0
  229. package/src/share/content-discipline/parsers.ts +66 -0
  230. package/src/share/content-discipline/types.ts +118 -0
  231. package/src/share/content-reference.ts +333 -0
  232. package/src/share/counter-utils.ts +75 -0
  233. package/src/share/css-value-normalize.ts +48 -0
  234. package/src/share/dev-props-validator.ts +131 -0
  235. package/src/share/entitlement.ts +172 -0
  236. package/src/share/env.d.ts +73 -0
  237. package/src/share/feature-policy.ts +367 -0
  238. package/src/share/formula-eval.ts +364 -0
  239. package/src/share/fs/index.ts +96 -0
  240. package/src/share/i18n/localization.ts +57 -0
  241. package/src/share/image-provider.ts +314 -0
  242. package/src/share/index.ts +86 -0
  243. package/src/share/knowledge/claim.ts +129 -0
  244. package/src/share/knowledge/derivation.ts +55 -0
  245. package/src/share/knowledge/freshness.ts +127 -0
  246. package/src/share/knowledge/index.ts +23 -0
  247. package/src/share/knowledge/ledger.ts +222 -0
  248. package/src/share/knowledge/plan.ts +122 -0
  249. package/src/share/knowledge/source.ts +170 -0
  250. package/src/share/legal/translation-policy.ts +133 -0
  251. package/src/share/material-credits.ts +181 -0
  252. package/src/share/middleware/language-redirect.ts +49 -0
  253. package/src/share/offer-capacity.ts +149 -0
  254. package/src/share/onboarding-yaml/index.ts +162 -0
  255. package/src/share/page.ts +351 -0
  256. package/src/share/redirects.test.ts +62 -0
  257. package/src/share/redirects.ts +54 -0
  258. package/src/share/rfc0042-utils.ts +95 -0
  259. package/src/share/runtime-context.ts +70 -0
  260. package/src/share/schemas/claim-records.ts +69 -0
  261. package/src/share/schemas/claims.ts +150 -0
  262. package/src/share/schemas/effects.ts +212 -0
  263. package/src/share/schemas/features.ts +147 -0
  264. package/src/share/schemas/horizontal-align.ts +22 -0
  265. package/src/share/schemas/icon-color.ts +27 -0
  266. package/src/share/schemas/index.ts +43 -0
  267. package/src/share/schemas/live-photo.ts +53 -0
  268. package/src/share/schemas/material-credit.ts +292 -0
  269. package/src/share/schemas/media.ts +220 -0
  270. package/src/share/schemas/navigation.ts +74 -0
  271. package/src/share/schemas/page-base.ts +33 -0
  272. package/src/share/schemas/participant.ts +247 -0
  273. package/src/share/schemas/person.ts +24 -0
  274. package/src/share/schemas/print.ts +93 -0
  275. package/src/share/schemas/section-background.ts +106 -0
  276. package/src/share/schemas/section-body.ts +138 -0
  277. package/src/share/schemas/section-cards.ts +37 -0
  278. package/src/share/schemas/section-cta.ts +74 -0
  279. package/src/share/schemas/section-header.ts +77 -0
  280. package/src/share/schemas/section-image.ts +77 -0
  281. package/src/share/schemas/section-motion.ts +52 -0
  282. package/src/share/schemas/section-shell.ts +63 -0
  283. package/src/share/schemas/section-stats.ts +37 -0
  284. package/src/share/schemas/site-background.ts +78 -0
  285. package/src/share/schemas/standard-list-item.ts +38 -0
  286. package/src/share/scripts/external-links.ts +45 -0
  287. package/src/share/scripts/gsap-counter.ts +168 -0
  288. package/src/share/scripts/gsap-mountain-journey.ts +236 -0
  289. package/src/share/scripts/gsap-parallax.ts +50 -0
  290. package/src/share/scripts/gsap-reveal.ts +65 -0
  291. package/src/share/scripts/gsap-stagger.ts +54 -0
  292. package/src/share/scripts/index.ts +25 -0
  293. package/src/share/scripts/inline-number-animation.ts +120 -0
  294. package/src/share/scripts/lenis.ts +109 -0
  295. package/src/share/scripts/live-photos.ts +250 -0
  296. package/src/share/scripts/lordicon.ts +94 -0
  297. package/src/share/scripts/orchestrator.ts +138 -0
  298. package/src/share/scripts/scheduler.ts +53 -0
  299. package/src/share/scripts/video-player.ts +116 -0
  300. package/src/share/semantic/ai.ts +140 -0
  301. package/src/share/semantic/block-extraction.ts +52 -0
  302. package/src/share/semantic/block-extractors/index.ts +502 -0
  303. package/src/share/semantic/breadcrumbs.ts +120 -0
  304. package/src/share/semantic/build-page.ts +309 -0
  305. package/src/share/semantic/business-projection.ts +278 -0
  306. package/src/share/semantic/derived-prices-loader.ts +36 -0
  307. package/src/share/semantic/extract.ts +118 -0
  308. package/src/share/semantic/feed.ts +124 -0
  309. package/src/share/semantic/ids.ts +76 -0
  310. package/src/share/semantic/image-sitemap.ts +153 -0
  311. package/src/share/semantic/index.ts +36 -0
  312. package/src/share/semantic/jsonld/article.ts +47 -0
  313. package/src/share/semantic/jsonld/breadcrumb.ts +47 -0
  314. package/src/share/semantic/jsonld/collection-list.ts +30 -0
  315. package/src/share/semantic/jsonld/context.ts +46 -0
  316. package/src/share/semantic/jsonld/faq.ts +49 -0
  317. package/src/share/semantic/jsonld/initiative.ts +53 -0
  318. package/src/share/semantic/jsonld/organization.ts +101 -0
  319. package/src/share/semantic/jsonld/person.ts +71 -0
  320. package/src/share/semantic/jsonld/service.ts +80 -0
  321. package/src/share/semantic/jsonld/shared.ts +31 -0
  322. package/src/share/semantic/jsonld/types.ts +18 -0
  323. package/src/share/semantic/jsonld/webpage.ts +98 -0
  324. package/src/share/semantic/jsonld/website.ts +27 -0
  325. package/src/share/semantic/jsonld.ts +75 -0
  326. package/src/share/semantic/llms-policy.ts +74 -0
  327. package/src/share/semantic/llms.ts +394 -0
  328. package/src/share/semantic/markdown-hygiene.ts +68 -0
  329. package/src/share/semantic/markdown-twin-provenance.ts +242 -0
  330. package/src/share/semantic/models.ts +402 -0
  331. package/src/share/semantic/organization-profile.ts +160 -0
  332. package/src/share/semantic/output-projection.ts +131 -0
  333. package/src/share/semantic/page-builders/markdown-page.ts +84 -0
  334. package/src/share/semantic/page-markdown.ts +234 -0
  335. package/src/share/semantic/page-utils.ts +125 -0
  336. package/src/share/semantic/price-marker-resolver.ts +92 -0
  337. package/src/share/semantic/robots.ts +127 -0
  338. package/src/share/semantic/update-stamp.ts +136 -0
  339. package/src/share/shared-context.ts +177 -0
  340. package/src/share/string-utils.ts +19 -0
  341. package/src/share/tests/api-catalog.test.ts +97 -0
  342. package/src/share/tests/breadcrumbs.test.ts +126 -0
  343. package/src/share/tests/build-page-price-markers.test.ts +160 -0
  344. package/src/share/tests/capability.test.ts +107 -0
  345. package/src/share/tests/claim.test.ts +90 -0
  346. package/src/share/tests/content-ref-index.test.ts +328 -0
  347. package/src/share/tests/create-dev-props-validator.test.ts +38 -0
  348. package/src/share/tests/derivation.test.ts +39 -0
  349. package/src/share/tests/dev-props-validator.test.ts +88 -0
  350. package/src/share/tests/fleet-catalog.test.ts +134 -0
  351. package/src/share/tests/formula-eval.test.ts +619 -0
  352. package/src/share/tests/freshness.test.ts +60 -0
  353. package/src/share/tests/hero-section-numbering-parity.test.ts +51 -0
  354. package/src/share/tests/image-sitemap.test.ts +101 -0
  355. package/src/share/tests/jsonld-service.test.ts +282 -0
  356. package/src/share/tests/knowledge.test.ts +86 -0
  357. package/src/share/tests/ledger.test.ts +125 -0
  358. package/src/share/tests/llms-0789.test.ts +63 -0
  359. package/src/share/tests/manifest.test.ts +100 -0
  360. package/src/share/tests/markdown-twin-provenance.test.ts +108 -0
  361. package/src/share/tests/mcp-card.test.ts +57 -0
  362. package/src/share/tests/onboarding-yaml.test.ts +111 -0
  363. package/src/share/tests/ontology-role-by-cosmic-name.test.ts +28 -0
  364. package/src/share/tests/openapi.test.ts +116 -0
  365. package/src/share/tests/organization-jsonld.test.ts +74 -0
  366. package/src/share/tests/output-projection.test.ts +61 -0
  367. package/src/share/tests/plan.test.ts +97 -0
  368. package/src/share/tests/price-marker-resolver.test.ts +141 -0
  369. package/src/share/tests/proof.test.ts +72 -0
  370. package/src/share/tests/resolve-field-path.test.ts +52 -0
  371. package/src/share/tests/source.test.ts +81 -0
  372. package/src/share/tests/substitute-deep.test.ts +65 -0
  373. package/src/share/tests/text-normalize.pbt.test.ts +143 -0
  374. package/src/share/tests/text-normalize.test.ts +285 -0
  375. package/src/share/tests/twin-path.test.ts +43 -0
  376. package/src/share/text-normalize.ts +548 -0
  377. package/src/share/text-position.ts +19 -0
  378. package/src/share/types/hls-js-light.d.ts +16 -0
  379. package/src/share/visibility.ts +167 -0
  380. package/src/share/vitest.config.ts +8 -0
  381. package/src/share/wrap-inline-numbers.ts +139 -0
  382. package/src/surface/blueprint-schema.ts +314 -0
  383. package/src/surface/blueprint-types.ts +256 -0
  384. package/src/surface/blueprint.ts +300 -0
  385. package/src/surface/breaker.ts +57 -0
  386. package/src/surface/decision-composer.ts +156 -0
  387. package/src/surface/eligibility.ts +372 -0
  388. package/src/surface/evidence-records.ts +97 -0
  389. package/src/surface/fleet.ts +60 -0
  390. package/src/surface/geo.ts +170 -0
  391. package/src/surface/governance.ts +146 -0
  392. package/src/surface/index.ts +216 -0
  393. package/src/surface/io/index.ts +18 -0
  394. package/src/surface/io/surface-module-context-io.ts +60 -0
  395. package/src/surface/io/visibility-outcomes-io.ts +46 -0
  396. package/src/surface/module-context.ts +120 -0
  397. package/src/surface/substance.ts +161 -0
  398. package/src/surface/tests/eligibility.pbt.test.ts +137 -0
  399. package/src/surface/tests/eligibility.test.ts +302 -0
  400. package/src/surface/types.ts +289 -0
  401. package/src/surface/visibility.ts +57 -0
  402. package/src/surface/vitest.config.ts +8 -0
  403. 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
+ });