@warpgogol/werkstatt-shared 0.14.0 → 0.15.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 (437) hide show
  1. package/README.md +31 -13
  2. package/README.uk.md +25 -15
  3. package/package.json +519 -762
  4. package/src/{share/agent → agent}/ard-catalog.ts +6 -1
  5. package/src/{share/agent → agent}/dns-aid.test.ts +2 -2
  6. package/src/{share/agent → agent}/manifest.ts +15 -1
  7. package/src/{share/agent → agent}/search.ts +6 -1
  8. package/src/{share → agent}/tests/api-catalog.test.ts +2 -2
  9. package/src/{share → agent}/tests/ard-catalog.test.ts +2 -2
  10. package/src/{share → agent}/tests/capability.test.ts +1 -1
  11. package/src/{share → agent}/tests/fleet-catalog.test.ts +1 -1
  12. package/src/{share → agent}/tests/knowledge.test.ts +2 -2
  13. package/src/{share → agent}/tests/manifest.test.ts +1 -1
  14. package/src/{share → agent}/tests/mcp-card.test.ts +2 -2
  15. package/src/agent/tests/omit-empty.test.ts +33 -0
  16. package/src/{share → agent}/tests/openapi.test.ts +2 -2
  17. package/src/{share → agent}/tests/proof.test.ts +1 -1
  18. package/src/{share → attribution}/material-credits.ts +4 -4
  19. package/src/{share → checks}/check-hints.ts +6 -1
  20. package/src/checks/index.ts +4 -1
  21. package/src/checks/lib/astro-site-url.ts +6 -1
  22. package/src/checks/lib/i18n.ts +14 -0
  23. package/src/checks/result-helpers.ts +22 -5
  24. package/src/checks/tests/remediation-auto-populate.test.ts +83 -0
  25. package/src/{share → client-scripts}/counter-utils.ts +6 -2
  26. package/src/{share/scripts → client-scripts}/external-link-qr.ts +11 -16
  27. package/src/{share/scripts → client-scripts}/external-links.ts +12 -1
  28. package/src/{share/scripts → client-scripts}/gsap-counter.ts +8 -3
  29. package/src/client-scripts/index.ts +35 -0
  30. package/src/{share/scripts → client-scripts}/inline-number-animation.ts +1 -1
  31. package/src/{share/scripts → client-scripts}/lenis.ts +6 -1
  32. package/src/{share/scripts → client-scripts}/lordicon.ts +6 -1
  33. package/src/{share/scripts → client-scripts}/orchestrator.ts +10 -1
  34. package/src/{share/scripts → client-scripts}/scheduler.ts +6 -1
  35. package/src/client-scripts/scroll-spy.ts +106 -0
  36. package/src/client-scripts/tests/external-link-qr.test.ts +8 -0
  37. package/src/client-scripts/tests/external-links.test.ts +25 -0
  38. package/src/client-scripts/tests/gsap-counter.test.ts +8 -0
  39. package/src/client-scripts/tests/gsap-mountain-journey.test.ts +8 -0
  40. package/src/client-scripts/tests/gsap-parallax.test.ts +8 -0
  41. package/src/client-scripts/tests/gsap-reveal.test.ts +8 -0
  42. package/src/client-scripts/tests/gsap-stagger.test.ts +8 -0
  43. package/src/client-scripts/tests/inline-number-animation.test.ts +8 -0
  44. package/src/client-scripts/tests/lenis.test.ts +8 -0
  45. package/src/client-scripts/tests/live-photos.test.ts +8 -0
  46. package/src/client-scripts/tests/lordicon.test.ts +8 -0
  47. package/src/client-scripts/tests/orchestrator.test.ts +47 -0
  48. package/src/client-scripts/tests/scheduler.test.ts +23 -0
  49. package/src/client-scripts/tests/scroll-spy.test.ts +204 -0
  50. package/src/{share/scripts → client-scripts/tests}/video-player.test.ts +51 -31
  51. package/src/component/contracts.ts +206 -0
  52. package/src/component/index.ts +11 -0
  53. package/src/{share → content}/content-reference.ts +3 -3
  54. package/src/{share/content → content}/entity-id.ts +6 -3
  55. package/src/content/index.ts +3 -0
  56. package/src/{share/content → content}/merge.ts +6 -1
  57. package/src/content/system-manifest.test.ts +107 -0
  58. package/src/content/system-manifest.ts +12 -94
  59. package/src/{share → content}/tests/resolve-field-path.test.ts +1 -1
  60. package/src/{share → content}/tests/substitute-deep.test.ts +1 -1
  61. package/src/content-discipline/index.ts +19 -0
  62. package/src/{share/content-discipline → content-discipline}/parsers.ts +2 -2
  63. package/src/{share/env.d.ts → env.d.ts} +6 -3
  64. package/src/fingerprint/canonical-json.ts +731 -0
  65. package/src/fingerprint/index.ts +12 -0
  66. package/src/fingerprint/primitives.ts +72 -0
  67. package/src/{share/i18n → i18n}/localization.ts +6 -2
  68. package/src/integration/adapters.ts +10 -71
  69. package/src/integration/dispatch.ts +1 -1
  70. package/src/integration/funnel.ts +6 -1
  71. package/src/integration/index.ts +101 -4
  72. package/src/integration/lagebild-destination-adapter.ts +108 -0
  73. package/src/integration/lagebild-ingress.ts +7 -12
  74. package/src/integration/orchestration.ts +11 -10
  75. package/src/integration/tests/deliver-event.test.ts +1 -1
  76. package/src/integration/tests/dispatch.test.ts +4 -4
  77. package/src/integration/tests/hub-runtime.test.ts +22 -14
  78. package/src/integration/vitest.config.ts +8 -0
  79. package/src/kernel/desired-state.ts +227 -0
  80. package/src/kernel/diagnostic.ts +289 -0
  81. package/src/kernel/fs-atomic.ts +131 -0
  82. package/src/kernel/index.ts +15 -0
  83. package/src/kernel/tests/fs-atomic.test.ts +150 -0
  84. package/src/kernel/tests/workspace-io.test.ts +187 -0
  85. package/src/kernel/types.ts +459 -0
  86. package/src/kernel/workspace-io.ts +248 -0
  87. package/src/{share → knowledge}/tests/claim.test.ts +1 -1
  88. package/src/{share → knowledge}/tests/derivation.test.ts +1 -1
  89. package/src/{share → knowledge}/tests/freshness.test.ts +1 -1
  90. package/src/{share → knowledge}/tests/ledger.test.ts +1 -1
  91. package/src/{share → knowledge}/tests/plan.test.ts +1 -1
  92. package/src/{share → knowledge}/tests/source.test.ts +1 -1
  93. package/src/legal/index.ts +15 -0
  94. package/src/{share/middleware → middleware}/access-protection.ts +8 -8
  95. package/src/{share → node}/dev-props-validator.ts +6 -1
  96. package/src/{share → node}/import-scan.ts +23 -3
  97. package/src/{share → node}/semantic/derived-prices-loader.ts +4 -2
  98. package/src/{share → node}/semantic/markdown-twin-provenance.ts +1 -1
  99. package/src/node/tests/derived-prices-loader.test.ts +59 -0
  100. package/src/node/tests/markdown-twin-provenance.test.ts +152 -0
  101. package/src/observability/env-resolver.ts +6 -1
  102. package/src/observability/index.ts +6 -1
  103. package/src/observability/otlp-converter.ts +6 -1
  104. package/src/observability/otlp-transport.ts +6 -1
  105. package/src/observability/pusher.ts +6 -1
  106. package/src/observability/redact.ts +6 -1
  107. package/src/observability/typed-refs.ts +6 -2
  108. package/src/observability/vitest.config.ts +1 -0
  109. package/src/{share → offers}/formula-eval.ts +3 -3
  110. package/src/{share → offers}/tests/formula-eval.test.ts +2 -2
  111. package/src/onboarding/index.ts +1 -0
  112. package/src/{share → onboarding}/tests/onboarding-yaml.test.ts +1 -1
  113. package/src/ontology/archetype-registry.ts +6 -1
  114. package/src/ontology/archetypes/index.json +33 -1
  115. package/src/ontology/archetypes/index.yaml +27 -1
  116. package/src/ontology/archetypes/sections/entity-grid.yaml +46 -0
  117. package/src/ontology/archetypes/sections/exit-diagram.yaml +43 -0
  118. package/src/ontology/biome-token-projection.ts +6 -1
  119. package/src/ontology/cosmic/index.ts +6 -1
  120. package/src/ontology/cosmic/moon-catalog.ts +6 -1
  121. package/src/ontology/cosmic/planet-catalog.ts +6 -1
  122. package/src/ontology/cosmic/star-catalog.ts +6 -1
  123. package/src/ontology/enums.ts +6 -1
  124. package/src/ontology/external-surfaces/index.ts +1 -1
  125. package/src/ontology/index.ts +6 -2
  126. package/src/ontology/manifest.ts +26 -4
  127. package/src/ontology/operations/artifact-store.ts +45 -0
  128. package/src/ontology/operations/dht.ts +98 -0
  129. package/src/ontology/operations/handoff.ts +92 -0
  130. package/src/ontology/operations/index.ts +187 -1
  131. package/src/ontology/operations/leitstand.ts +99 -0
  132. package/src/ontology/operations/materialization.ts +90 -0
  133. package/src/ontology/operations/mission.ts +111 -0
  134. package/src/ontology/operations/naming-policy.ts +132 -0
  135. package/src/ontology/operations/notausgang.ts +64 -0
  136. package/src/ontology/operations/release.ts +121 -0
  137. package/src/ontology/operations/sternsystem.ts +192 -0
  138. package/src/ontology/operations/werkstatt.ts +48 -0
  139. package/src/ontology/schemas/biome.ts +7 -2
  140. package/src/ontology/schemas/capability.ts +1 -1
  141. package/src/ontology/schemas/constellation.ts +6 -1
  142. package/src/ontology/schemas/index.ts +6 -2
  143. package/src/ontology/schemas/manifest-resolver.ts +6 -1
  144. package/src/ontology/schemas/page-entry.ts +9 -5
  145. package/src/ontology/schemas/system/growth.ts +6 -1
  146. package/src/ontology/schemas/system/manifest.ts +40 -1
  147. package/src/ontology/schemas/system/page-output.ts +7 -6
  148. package/src/ontology/schemas/system/tests/growth.test.ts +22 -0
  149. package/src/ontology/schemas/system/tests/integrations.test.ts +12 -0
  150. package/src/ontology/schemas/system/tests/manifest.test.ts +22 -0
  151. package/src/ontology/schemas/system/tests/page-output.test.ts +13 -0
  152. package/src/ontology/schemas/system/tests/release.test.ts +22 -0
  153. package/src/ontology/schemas/system/tests/text.test.ts +18 -0
  154. package/src/ontology/schemas/system/tests/verification.test.ts +12 -0
  155. package/src/ontology/schemas/system/text.ts +15 -0
  156. package/src/ontology/schemas/system.ts +6 -2
  157. package/src/ontology/schemas/tests/biome.test.ts +19 -0
  158. package/src/ontology/schemas/tests/capability.test.ts +22 -0
  159. package/src/ontology/schemas/tests/constellation.test.ts +22 -0
  160. package/src/ontology/schemas/tests/dns-records.test.ts +13 -0
  161. package/src/ontology/schemas/tests/manifest-resolver.test.ts +13 -0
  162. package/src/ontology/schemas/tests/page-entry.test.ts +22 -0
  163. package/src/ontology/schemas/tests/section-archetype.test.ts +12 -0
  164. package/src/ontology/schemas/tests/site-family.test.ts +18 -0
  165. package/src/ontology/schemas/tests/system.test.ts +20 -0
  166. package/src/ontology/shared-section-props/body-fragments.ts +2 -0
  167. package/src/ontology/tests/sternsystem-owner.test.ts +1 -1
  168. package/src/ontology/vitest.config.ts +1 -0
  169. package/src/{share → page}/page.ts +13 -9
  170. package/src/{share → page}/tests/dev-props-validator.test.ts +1 -1
  171. package/src/{share → page}/tests/hero-section-numbering-parity.test.ts +1 -1
  172. package/src/passport/index.ts +6 -1
  173. package/src/passport/key-rotate.ts +10 -2
  174. package/src/passport/schema.ts +6 -1
  175. package/src/passport/sign.ts +8 -3
  176. package/src/passport/vitest.config.ts +1 -0
  177. package/src/pbt/index.test.ts +95 -0
  178. package/src/pbt/index.ts +251 -0
  179. package/src/plugin/plugin-contract.ts +1 -1
  180. package/src/{share → policy}/entitlement.ts +24 -4
  181. package/src/{share → policy}/feature-policy.ts +8 -3
  182. package/src/{share → policy}/visibility.ts +7 -2
  183. package/src/redirects/redirects.ts +117 -0
  184. package/src/{share → redirects/tests}/redirects.test.ts +1 -1
  185. package/src/remediation/remediation-catalog.ts +316 -0
  186. package/src/{share/routes → routes}/template-filter.ts +1 -1
  187. package/src/{share → runtime}/runtime-context.ts +7 -2
  188. package/src/{share → runtime}/shared-context.ts +1 -1
  189. package/src/{share/schemas → schemas}/claims.ts +2 -2
  190. package/src/{share/schemas → schemas}/effects.ts +6 -1
  191. package/src/{share/schemas → schemas}/features.ts +1 -1
  192. package/src/{share/schemas → schemas}/index.ts +3 -3
  193. package/src/{share/schemas → schemas}/navigation.ts +6 -1
  194. package/src/{share/schemas → schemas}/page-base.ts +6 -2
  195. package/src/{share/schemas → schemas}/person.ts +1 -1
  196. package/src/{share/schemas → schemas}/standard-list-item.ts +1 -1
  197. package/src/schemas/tests/claim-records.test.ts +52 -0
  198. package/src/schemas/tests/claims.test.ts +23 -0
  199. package/src/schemas/tests/effects.test.ts +116 -0
  200. package/src/schemas/tests/features.test.ts +61 -0
  201. package/src/schemas/tests/horizontal-align.test.ts +16 -0
  202. package/src/schemas/tests/icon-color.test.ts +16 -0
  203. package/src/schemas/tests/live-photo.test.ts +40 -0
  204. package/src/schemas/tests/material-credit.test.ts +51 -0
  205. package/src/schemas/tests/media.test.ts +26 -0
  206. package/src/schemas/tests/navigation.test.ts +58 -0
  207. package/src/schemas/tests/page-base.test.ts +19 -0
  208. package/src/schemas/tests/participant.test.ts +26 -0
  209. package/src/schemas/tests/person.test.ts +12 -0
  210. package/src/schemas/tests/print.test.ts +30 -0
  211. package/src/schemas/tests/section-background.test.ts +31 -0
  212. package/src/schemas/tests/section-body.test.ts +16 -0
  213. package/src/schemas/tests/section-cards.test.ts +17 -0
  214. package/src/schemas/tests/section-cta.test.ts +41 -0
  215. package/src/schemas/tests/section-header.test.ts +31 -0
  216. package/src/schemas/tests/section-image.test.ts +24 -0
  217. package/src/schemas/tests/section-motion.test.ts +29 -0
  218. package/src/schemas/tests/section-shell.test.ts +42 -0
  219. package/src/schemas/tests/section-stats.test.ts +17 -0
  220. package/src/schemas/tests/site-background.test.ts +33 -0
  221. package/src/schemas/tests/standard-list-item.test.ts +16 -0
  222. package/src/{share → sections}/rfc0042-utils.ts +1 -1
  223. package/src/{share/semantic → semantic}/block-extractors/index.ts +20 -1
  224. package/src/{share/semantic → semantic}/business-projection.ts +95 -1
  225. package/src/semantic/canonical-uri.ts +54 -0
  226. package/src/{share/semantic → semantic}/extract.ts +100 -1
  227. package/src/semantic/fact-extraction.test.ts +47 -0
  228. package/src/semantic/fact-extraction.ts +46 -0
  229. package/src/semantic/freshness.ts +67 -0
  230. package/src/{share/semantic → semantic}/ids.ts +6 -1
  231. package/src/{share/semantic → semantic}/index.ts +9 -2
  232. package/src/{share/semantic → semantic}/jsonld/breadcrumb.ts +6 -2
  233. package/src/{share/semantic → semantic}/jsonld/context.ts +6 -2
  234. package/src/{share/semantic → semantic}/jsonld/faq.ts +6 -2
  235. package/src/{share/semantic → semantic}/jsonld/initiative.ts +6 -1
  236. package/src/{share/semantic → semantic}/jsonld/organization.ts +6 -1
  237. package/src/{share/semantic → semantic}/jsonld/person.ts +6 -2
  238. package/src/{share/semantic → semantic}/jsonld/service.ts +6 -2
  239. package/src/semantic/jsonld/shared.ts +36 -0
  240. package/src/semantic/jsonld/tests/article.test.ts +89 -0
  241. package/src/semantic/jsonld/tests/breadcrumb.test.ts +62 -0
  242. package/src/semantic/jsonld/tests/collection-list.test.ts +39 -0
  243. package/src/semantic/jsonld/tests/faq.test.ts +60 -0
  244. package/src/semantic/jsonld/tests/initiative.test.ts +56 -0
  245. package/src/semantic/jsonld/tests/organization.test.ts +123 -0
  246. package/src/semantic/jsonld/tests/person.test.ts +89 -0
  247. package/src/semantic/jsonld/tests/service.test.ts +65 -0
  248. package/src/semantic/jsonld/tests/shared.test.ts +41 -0
  249. package/src/semantic/jsonld/tests/video.test.ts +84 -0
  250. package/src/semantic/jsonld/tests/webpage.test.ts +93 -0
  251. package/src/semantic/jsonld/tests/website.test.ts +27 -0
  252. package/src/semantic/jsonld/types.ts +24 -0
  253. package/src/{share/semantic → semantic}/jsonld/webpage.ts +6 -1
  254. package/src/semantic/jsonld/website.ts +32 -0
  255. package/src/{share/semantic → semantic}/jsonld.ts +6 -1
  256. package/src/{share/semantic → semantic}/llms.ts +41 -3
  257. package/src/{share/semantic → semantic}/models.ts +27 -38
  258. package/src/{share/semantic → semantic}/organization-profile.ts +3 -0
  259. package/src/{share/semantic → semantic}/page-builders/markdown-page.ts +6 -3
  260. package/src/{share/semantic → semantic}/page-utils.ts +6 -3
  261. package/src/semantic/tests/ai.test.ts +55 -0
  262. package/src/semantic/tests/block-extraction.test.ts +34 -0
  263. package/src/{share/tests/breadcrumbs.test.ts → semantic/tests/breadcrumbs-0229.test.ts} +1 -1
  264. package/src/semantic/tests/breadcrumbs.test.ts +127 -0
  265. package/src/{share → semantic}/tests/build-page-price-markers.test.ts +2 -2
  266. package/src/semantic/tests/build-page.test.ts +122 -0
  267. package/src/semantic/tests/business-projection.test.ts +367 -0
  268. package/src/semantic/tests/canonical-uri.test.ts +56 -0
  269. package/src/semantic/tests/extract.test.ts +209 -0
  270. package/src/semantic/tests/feed.test.ts +113 -0
  271. package/src/semantic/tests/freshness.pbt.test.ts +108 -0
  272. package/src/semantic/tests/helpers.ts +32 -0
  273. package/src/semantic/tests/ids.test.ts +118 -0
  274. package/src/{share/tests/image-sitemap.test.ts → semantic/tests/image-sitemap-0150.test.ts} +1 -1
  275. package/src/semantic/tests/image-sitemap.test.ts +109 -0
  276. package/src/{share → semantic}/tests/jsonld-service.test.ts +2 -2
  277. package/src/{share → semantic}/tests/jsonld-video.test.ts +3 -3
  278. package/src/{share → semantic}/tests/jsonld-webpage.test.ts +3 -3
  279. package/src/semantic/tests/jsonld.test.ts +61 -0
  280. package/src/{share → semantic}/tests/llms-0789.test.ts +2 -2
  281. package/src/semantic/tests/llms-policy.test.ts +60 -0
  282. package/src/semantic/tests/llms.test.ts +164 -0
  283. package/src/semantic/tests/markdown-hygiene.test.ts +72 -0
  284. package/src/semantic/tests/markdown-page.test.ts +97 -0
  285. package/src/{share → semantic}/tests/organization-jsonld.test.ts +3 -3
  286. package/src/semantic/tests/organization-profile.test.ts +107 -0
  287. package/src/{share/tests/output-projection.test.ts → semantic/tests/output-projection-0143.test.ts} +1 -1
  288. package/src/semantic/tests/output-projection.test.ts +77 -0
  289. package/src/semantic/tests/page-markdown.test.ts +98 -0
  290. package/src/semantic/tests/page-utils.test.ts +88 -0
  291. package/src/{share/tests/price-marker-resolver.test.ts → semantic/tests/price-marker-resolver-0767.test.ts} +2 -2
  292. package/src/semantic/tests/price-marker-resolver.test.ts +90 -0
  293. package/src/semantic/tests/project-claims.pbt.test.ts +60 -0
  294. package/src/semantic/tests/robots.test.ts +70 -0
  295. package/src/{share/semantic → semantic}/tests/split-sentences.test.ts +1 -1
  296. package/src/{share → semantic}/tests/twin-path.test.ts +1 -1
  297. package/src/semantic/tests/update-stamp.test.ts +102 -0
  298. package/src/signing/index.ts +13 -0
  299. package/src/signing/key.ts +139 -0
  300. package/src/signing/sign.ts +66 -0
  301. package/src/signing/types.ts +29 -0
  302. package/src/{share/slug → slug}/slug-url.ts +4 -1
  303. package/src/stack/run-tool.ts +108 -0
  304. package/src/stack/stack-checks.ts +124 -0
  305. package/src/stack/tests/run-tool.test.ts +138 -0
  306. package/src/stack/tests/stack-checks.test.ts +141 -0
  307. package/src/stack/tests/walk-files.test.ts +131 -0
  308. package/src/stack/walk-files.ts +114 -0
  309. package/src/surface/blueprint.ts +342 -66
  310. package/src/surface/decision-composer.ts +6 -1
  311. package/src/surface/geo.ts +6 -1
  312. package/src/surface/index.ts +11 -7
  313. package/src/surface/types.ts +2 -2
  314. package/src/surface/vitest.config.ts +1 -0
  315. package/src/tests/signing-core.test.ts +129 -0
  316. package/src/{share → text}/css-value-normalize.ts +6 -1
  317. package/src/text/string-utils.ts +24 -0
  318. package/src/{share → text}/tests/text-normalize.test.ts +5 -0
  319. package/src/{share → text}/text-normalize.ts +4 -3
  320. package/src/{share → text}/wrap-inline-numbers.ts +1 -1
  321. package/src/types/axiom-study.d.ts +36 -0
  322. package/src/types/hls-js-light.d.ts +21 -0
  323. package/src/types/qrcode-browser.d.ts +23 -0
  324. package/src/typography/fix.pbt.test.ts +208 -0
  325. package/src/typography/fix.ts +148 -0
  326. package/src/typography/index.ts +54 -0
  327. package/src/typography/locale-defaults.ts +97 -0
  328. package/src/typography/rules-tier1.test.ts +459 -0
  329. package/src/typography/rules-tier1.ts +925 -0
  330. package/src/typography/rules-tier2-locale.pbt.test.ts +190 -0
  331. package/src/typography/rules-tier2-locale.test.ts +286 -0
  332. package/src/typography/rules-tier2-locale.ts +399 -0
  333. package/src/typography/rules-tier2-structure.test.ts +330 -0
  334. package/src/typography/rules-tier2-structure.ts +378 -0
  335. package/src/typography/rules-tier3-advisory.test.ts +290 -0
  336. package/src/typography/rules-tier3-advisory.ts +239 -0
  337. package/src/typography/text-surface.test.ts +244 -0
  338. package/src/typography/text-surface.ts +448 -0
  339. package/src/index.ts +0 -14
  340. package/src/integration/port-barrel.ts +0 -105
  341. package/src/share/content/index.ts +0 -16
  342. package/src/share/content-discipline/index.ts +0 -14
  343. package/src/share/index.ts +0 -86
  344. package/src/share/legal/index.ts +0 -1
  345. package/src/share/redirects.ts +0 -54
  346. package/src/share/scripts/index.ts +0 -26
  347. package/src/share/semantic/jsonld/shared.ts +0 -31
  348. package/src/share/semantic/jsonld/types.ts +0 -18
  349. package/src/share/semantic/jsonld/website.ts +0 -27
  350. package/src/share/string-utils.ts +0 -19
  351. package/src/share/types/axiom-study.d.ts +0 -22
  352. package/src/share/types/hls-js-light.d.ts +0 -16
  353. package/src/share/types/qrcode-browser.d.ts +0 -18
  354. package/src/share/utility-registry.yaml +0 -36
  355. package/src/share/vitest.config.ts +0 -8
  356. package/src/surface/blueprint-schema.ts +0 -314
  357. package/src/surface/blueprint-types.ts +0 -256
  358. /package/src/{share/agent → agent}/api-catalog.ts +0 -0
  359. /package/src/{share/agent → agent}/capability.ts +0 -0
  360. /package/src/{share/agent → agent}/dns-aid.ts +0 -0
  361. /package/src/{share/agent → agent}/fleet-catalog.ts +0 -0
  362. /package/src/{share/agent → agent}/index.ts +0 -0
  363. /package/src/{share/agent → agent}/knowledge.ts +0 -0
  364. /package/src/{share/agent → agent}/mcp-card.ts +0 -0
  365. /package/src/{share/agent → agent}/omit-empty.ts +0 -0
  366. /package/src/{share/agent → agent}/openapi.ts +0 -0
  367. /package/src/{share/agent → agent}/proof.ts +0 -0
  368. /package/src/{share/agent → agent}/search.test.ts +0 -0
  369. /package/src/{share → attribution}/attribution-display.ts +0 -0
  370. /package/src/{share/scripts → client-scripts}/gsap-mountain-journey.ts +0 -0
  371. /package/src/{share/scripts → client-scripts}/gsap-parallax.ts +0 -0
  372. /package/src/{share/scripts → client-scripts}/gsap-reveal.ts +0 -0
  373. /package/src/{share/scripts → client-scripts}/gsap-stagger.ts +0 -0
  374. /package/src/{share/scripts → client-scripts}/live-photos.ts +0 -0
  375. /package/src/{share/scripts → client-scripts}/video-player.ts +0 -0
  376. /package/src/{share/content → content}/resolve-field-path.ts +0 -0
  377. /package/src/{share/content → content}/substitute-deep.ts +0 -0
  378. /package/src/{share → content}/tests/content-ref-index.test.ts +0 -0
  379. /package/src/{share/content-discipline → content-discipline}/types.ts +0 -0
  380. /package/src/{share → image-provider}/image-provider.ts +0 -0
  381. /package/src/{share/knowledge → knowledge}/claim.ts +0 -0
  382. /package/src/{share/knowledge → knowledge}/derivation.ts +0 -0
  383. /package/src/{share/knowledge → knowledge}/freshness.ts +0 -0
  384. /package/src/{share/knowledge → knowledge}/index.ts +0 -0
  385. /package/src/{share/knowledge → knowledge}/ledger.ts +0 -0
  386. /package/src/{share/knowledge → knowledge}/plan.ts +0 -0
  387. /package/src/{share/knowledge → knowledge}/source.ts +0 -0
  388. /package/src/{share/legal → legal}/translation-policy.ts +0 -0
  389. /package/src/{share/middleware → middleware}/language-redirect.ts +0 -0
  390. /package/src/{share/middleware → middleware}/tests/access-protection.test.ts +0 -0
  391. /package/src/{share → node}/fs/index.ts +0 -0
  392. /package/src/{share/tests/markdown-twin-provenance.test.ts → node/tests/markdown-twin-provenance-0613.test.ts} +0 -0
  393. /package/src/{share → offers}/offer-capacity.ts +0 -0
  394. /package/src/{share/onboarding-yaml/index.ts → onboarding/yaml.ts} +0 -0
  395. /package/src/{share → ontology}/tests/ontology-role-by-cosmic-name.test.ts +0 -0
  396. /package/src/{share/routes → routes}/tests/template-filter.test.ts +0 -0
  397. /package/src/{share/schemas → schemas}/claim-records.ts +0 -0
  398. /package/src/{share/schemas → schemas}/horizontal-align.ts +0 -0
  399. /package/src/{share/schemas → schemas}/icon-color.ts +0 -0
  400. /package/src/{share/schemas → schemas}/live-photo.ts +0 -0
  401. /package/src/{share/schemas → schemas}/material-credit.ts +0 -0
  402. /package/src/{share/schemas → schemas}/media.ts +0 -0
  403. /package/src/{share/schemas → schemas}/participant.ts +0 -0
  404. /package/src/{share/schemas → schemas}/print.ts +0 -0
  405. /package/src/{share/schemas → schemas}/section-background.ts +0 -0
  406. /package/src/{share/schemas → schemas}/section-body.ts +0 -0
  407. /package/src/{share/schemas → schemas}/section-cards.ts +0 -0
  408. /package/src/{share/schemas → schemas}/section-cta.ts +0 -0
  409. /package/src/{share/schemas → schemas}/section-header.ts +0 -0
  410. /package/src/{share/schemas → schemas}/section-image.ts +0 -0
  411. /package/src/{share/schemas → schemas}/section-motion.ts +0 -0
  412. /package/src/{share/schemas → schemas}/section-shell.ts +0 -0
  413. /package/src/{share/schemas → schemas}/section-stats.ts +0 -0
  414. /package/src/{share/schemas → schemas}/site-background.ts +0 -0
  415. /package/src/{share/semantic → semantic}/ai.ts +0 -0
  416. /package/src/{share/semantic → semantic}/block-extraction.ts +0 -0
  417. /package/src/{share/semantic → semantic}/breadcrumbs.ts +0 -0
  418. /package/src/{share/semantic → semantic}/build-page.ts +0 -0
  419. /package/src/{share/semantic → semantic}/feed.ts +0 -0
  420. /package/src/{share/semantic → semantic}/image-sitemap.ts +0 -0
  421. /package/src/{share/semantic → semantic}/jsonld/article.ts +0 -0
  422. /package/src/{share/semantic → semantic}/jsonld/collection-list.ts +0 -0
  423. /package/src/{share/semantic → semantic}/jsonld/video.ts +0 -0
  424. /package/src/{share/semantic → semantic}/llms-policy.ts +0 -0
  425. /package/src/{share/semantic → semantic}/markdown-hygiene.ts +0 -0
  426. /package/src/{share/semantic → semantic}/output-projection.ts +0 -0
  427. /package/src/{share/semantic → semantic}/page-markdown.ts +0 -0
  428. /package/src/{share/semantic → semantic}/price-marker-resolver.ts +0 -0
  429. /package/src/{share/semantic → semantic}/robots.ts +0 -0
  430. /package/src/{share/semantic → semantic}/update-stamp.ts +0 -0
  431. /package/src/{share/slug → slug}/heading-slugger.ts +0 -0
  432. /package/src/{share/slug → slug}/index.ts +0 -0
  433. /package/src/{share/slug → slug}/slug-id.ts +0 -0
  434. /package/src/{share/slug → slug}/strategies.ts +0 -0
  435. /package/src/{share/slug → slug}/tests/slug.test.ts +0 -0
  436. /package/src/{share → text}/tests/text-normalize.pbt.test.ts +0 -0
  437. /package/src/{share → text}/text-position.ts +0 -0
@@ -1,10 +1,10 @@
1
1
  /*
2
2
  <MODULE_CONTRACT>
3
3
  <purpose>RFC-0176: verify the inbound/queue runtime — authenticateInbound, IntegrationEventSchema,
4
- routeEventToReady (self-enabling Pipedrive route), and consumeIntegrationBatch dedup via a KV-backed
4
+ routeEventToReady (self-enabling Lagebild route), and consumeIntegrationBatch dedup via a KV-backed
5
5
  seen-set. fetch + KV are stubbed so the full producer→consumer flow is exercised without Cloudflare.</purpose>
6
6
  <responsibilities>
7
- <item>Assert a valid event routes once to the pipedrive gogol-adapter destination.</item>
7
+ <item>Assert a valid event routes once to the lagebild gogol-adapter destination.</item>
8
8
  <item>Assert a queue redelivery is deduped (no double-write) via the KV seen-set.</item>
9
9
  <item>Assert inbound auth + event-shape validation are fail-closed.</item>
10
10
  </responsibilities>
@@ -14,6 +14,7 @@ seen-set. fetch + KV are stubbed so the full producer→consumer flow is exercis
14
14
  </MODULE_CONTRACT>
15
15
  <CHANGE_SUMMARY>
16
16
  <item>RFC-0176: initial queue/inbound runtime test.</item>
17
+ <item>Lagebild replaced Pipedrive as sole CRM destination — test updated accordingly.</item>
17
18
  </CHANGE_SUMMARY>
18
19
  */
19
20
 
@@ -30,8 +31,10 @@ import {
30
31
  } from "../index.ts";
31
32
 
32
33
  const SECRETS: IntegrationSecrets = {
33
- INTEGRATION_PIPEDRIVE_API_TOKEN: "tok",
34
- INTEGRATION_PIPEDRIVE_DOMAIN: "acme",
34
+ LAGEBILD_API_URL: "https://lagebild-api.example.workers.dev",
35
+ LAGEBILD_API_KEY: "lbk_test_key_0001",
36
+ LAGEBILD_TENANT_ID: "ten_warpgogol000001",
37
+ LAGEBILD_SOURCE_SYSTEM_ID: "site_warpgogol_com",
35
38
  };
36
39
 
37
40
  const EVENT: IntegrationEvent = {
@@ -63,13 +66,18 @@ const realFetch = globalThis.fetch;
63
66
 
64
67
  beforeEach(() => {
65
68
  fetchCalls = [];
66
- // Stub Pipedrive persons + leads endpoints — both return a usable id.
69
+ // Stub Lagebild ingress endpoint — returns accepted with a submission id.
67
70
  globalThis.fetch = (async (url: string | URL | Request) => {
68
71
  fetchCalls.push(String(url));
69
72
  return {
70
73
  ok: true,
71
74
  status: 200,
72
- json: async () => ({ data: { id: 1 } }),
75
+ json: async () => ({
76
+ submission_id: "sub_test123",
77
+ accepted: true,
78
+ is_replay: false,
79
+ correlation_id: null,
80
+ }),
73
81
  } as unknown as Response;
74
82
  }) as typeof fetch;
75
83
  });
@@ -78,17 +86,17 @@ afterEach(() => {
78
86
  globalThis.fetch = realFetch;
79
87
  });
80
88
 
81
- test("routeEventToReady routes a lead to the pipedrive gogol-adapter destination", async () => {
89
+ test("routeEventToReady routes a lead to the lagebild gogol-adapter destination", async () => {
82
90
  const result = await routeEventToReady(EVENT, SECRETS);
83
- expect(result.routed).toEqual(["crm:pipedrive"]);
91
+ expect(result.routed).toEqual(["crm:lagebild"]);
84
92
  expect(result.failed.length).toBe(0);
85
- // pipedrive adapter performs persons + leads calls.
86
- expect(fetchCalls.length).toBe(2);
93
+ // lagebild adapter performs a single POST to /v1/ingress.
94
+ expect(fetchCalls.length).toBe(1);
87
95
  });
88
96
 
89
97
  test("routeEventToReady skips when destination secrets are absent", async () => {
90
98
  const result = await routeEventToReady(EVENT, {});
91
- expect(result.skipped).toEqual(["crm:pipedrive"]);
99
+ expect(result.skipped).toEqual(["crm:lagebild"]);
92
100
  expect(result.routed.length).toBe(0);
93
101
  expect(fetchCalls.length).toBe(0);
94
102
  });
@@ -98,13 +106,13 @@ test("consumeIntegrationBatch dedups a queue redelivery via KV (no double-write)
98
106
  const dedup = kvDedup(kv);
99
107
 
100
108
  const first = await consumeIntegrationBatch([EVENT], SECRETS, dedup);
101
- expect(first[0].routed).toEqual(["crm:pipedrive"]);
109
+ expect(first[0].routed).toEqual(["crm:lagebild"]);
102
110
  const afterFirst = fetchCalls.length;
103
- expect(afterFirst).toBe(2);
111
+ expect(afterFirst).toBe(1);
104
112
 
105
113
  // Redeliver the SAME eventId — must be skipped by dedup, no new fetches.
106
114
  const second = await consumeIntegrationBatch([EVENT], SECRETS, dedup);
107
- expect(second[0].skipped).toEqual(["crm:pipedrive"]);
115
+ expect(second[0].skipped).toEqual(["crm:lagebild"]);
108
116
  expect(fetchCalls.length).toBe(afterFirst);
109
117
  expect(kv.size()).toBe(1);
110
118
  });
@@ -3,6 +3,14 @@ import { defineConfig } from "vitest/config";
3
3
  export default defineConfig({
4
4
  test: {
5
5
  environment: "node",
6
+ testTimeout: 30_000,
6
7
  include: ["src/**/*.test.ts"],
8
+ coverage: {
9
+ provider: "v8",
10
+ reporter: ["json", "json-summary", "text-summary", "html"],
11
+ reportsDirectory: "../../.coverage/integration",
12
+ include: ["src/integration/**/*.ts"],
13
+ exclude: ["src/integration/**/*.test.ts", "src/integration/**/*.d.ts"],
14
+ },
7
15
  },
8
16
  });
@@ -0,0 +1,227 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>
4
+ Desired-state composition types for RFC-1038. Defines the declarative target
5
+ (DesiredState), the runtime actual state (ActualState, replacing KernelRegistry),
6
+ component/command/pipeline declarations, and the module export shape that
7
+ replaces KernelModule.register().
8
+ </purpose>
9
+ <non-goals>
10
+ <item>Does not implement reconciliation logic — see reconciler.ts.</item>
11
+ <item>Does not implement overlay resolution — see overlay.ts.</item>
12
+ <item>Does not define Zod schemas — see component/schemas.ts.</item>
13
+ </non-goals>
14
+ </MODULE_CONTRACT>
15
+ <CHANGE_SUMMARY>
16
+ <item>RFC-1038: initial implementation — desired-state composition types replacing ComponentManifestV1, KernelModule, KernelRegistry.</item>
17
+ </CHANGE_SUMMARY>
18
+ */
19
+
20
+ import type { Sha256Digest } from "../fingerprint/primitives.ts";
21
+ import type { ComponentScope, ScopeContext, ComponentDeclaration } from "../component/contracts.ts";
22
+ import type {
23
+ KernelFlagSpec,
24
+ GeneratedArtifactSpec,
25
+ KernelPipelineStep,
26
+ KernelCommandMetadata,
27
+ KernelCommandInput,
28
+ KernelRuntimeContext,
29
+ KernelCommandResult,
30
+ ModuleFiberState,
31
+ } from "./types.ts";
32
+
33
+ /**
34
+ * Unified component type — replaces ComponentManifestV1.
35
+ * Re-exported from contracts.ts for convenience.
36
+ */
37
+ export type { ComponentDeclaration };
38
+
39
+ export interface DesiredState {
40
+ /** Stable component declarations keyed by componentId. Map for O(1) lookup. */
41
+ components: Map<string, ComponentDeclaration>;
42
+ /** Capability contracts that must be satisfied. */
43
+ requiredCapabilities: string[];
44
+ /** Available artifacts for resolution. */
45
+ availableArtifacts: ReadonlyMap<string, Sha256Digest>;
46
+ /** Admitted grants for resolution. */
47
+ admittedGrants: ReadonlyArray<{ scope: string; resource: string }>;
48
+ /** Profile ID for resolution. */
49
+ profileId: string;
50
+ }
51
+
52
+ export interface ReconciliationDelta {
53
+ /** Components to activate (present in desired, absent in actual). */
54
+ toActivate: ComponentDeclaration[];
55
+ /** Components to deactivate (absent in desired, present in actual). */
56
+ toDeactivate: string[];
57
+ /** Components to reconfigure (present in both, but config changed). */
58
+ toReconfigure: Array<{
59
+ id: string;
60
+ oldConfig: Record<string, unknown>;
61
+ newConfig: Record<string, unknown>;
62
+ }>;
63
+ /** Components unchanged (present in both, config identical). */
64
+ unchanged: string[];
65
+ /** Missing dependencies — required capabilities with no provider. */
66
+ missingDependencies: Array<{ capability: string; requiredBy: string }>;
67
+ }
68
+
69
+ export interface ReconciliationResult {
70
+ delta: ReconciliationDelta;
71
+ applied: boolean;
72
+ /** Components that failed to activate. */
73
+ failures: Array<{ id: string; reason: string }>;
74
+ /** Time taken to reconcile, in milliseconds. */
75
+ durationMs: number;
76
+ }
77
+
78
+ /**
79
+ * Command declaration — replaces KernelCommandDefinition for registration.
80
+ * Carries ALL metadata fields from KernelCommandDefinition plus the execute function.
81
+ * Type safety is preserved: execute receives typed KernelCommandInput and KernelRuntimeContext.
82
+ */
83
+ export interface CommandDeclaration extends KernelCommandMetadata {
84
+ /** Command name — e.g. "sternsystem.validate". */
85
+ name: string;
86
+ /** RFC-0260: declared flag schema. */
87
+ flags?: Record<string, KernelFlagSpec>;
88
+ /** RFC-0266: workspace-root-relative path globs this command reads. */
89
+ reads?: string[];
90
+ /** RFC-0266: workspace-root-relative path globs this command writes. */
91
+ writes?: string[];
92
+ /** RFC-0637: paths relative to module src/ for cache hashing. */
93
+ modulePaths?: string[];
94
+ /** RFC-0687: command names whose outputs this validator checks. */
95
+ validatesOutputs?: string[];
96
+ /** RFC-0960: repo-relative path to the implementing source file. */
97
+ modulePath?: string;
98
+ /** RFC-0960: declared generated artifacts. */
99
+ generates?: GeneratedArtifactSpec[];
100
+ /** RFC-0963: the single contract this validator enforces. */
101
+ contract?: string;
102
+ /** RFC-0963: the rule IDs this validator enforces. */
103
+ rules?: string[];
104
+ /** The execute function — typed, same signature as KernelCommandDefinition.execute. */
105
+ execute: (
106
+ input: KernelCommandInput,
107
+ context: KernelRuntimeContext,
108
+ ) => Promise<void | KernelCommandResult> | void | KernelCommandResult;
109
+ }
110
+
111
+ /**
112
+ * Pipeline declaration — replaces registerPipeline() calls.
113
+ * Carries the pipeline name and steps with all KernelPipelineStep fields.
114
+ */
115
+ export interface PipelineDeclaration {
116
+ /** Pipeline name — e.g. "packages.check". */
117
+ name: string;
118
+ /** Pipeline steps with command references, args, timeouts, and dependsOn (RFC-0686). */
119
+ steps: KernelPipelineStep[];
120
+ }
121
+
122
+ /**
123
+ * Module export — replaces KernelModule.
124
+ * Each *.module.ts file exports this object instead of calling register().
125
+ * The reconciler reads declarations, commands, and pipelines from this export.
126
+ */
127
+ export interface ModuleExport {
128
+ /** Module name — e.g. "sternsystem". */
129
+ name: string;
130
+ /** Module version. */
131
+ version: string;
132
+ /** Component declarations for desired-state composition. */
133
+ declarations: ComponentDeclaration[];
134
+ /**
135
+ * Command declarations — replaces registerCommand() calls.
136
+ * execute functions may lazy-load implementations via `await import()`
137
+ * inside the execute body, preserving the current lazy-loading pattern.
138
+ */
139
+ commands: CommandDeclaration[];
140
+ /** Pipeline declarations — replaces registerPipeline() calls. */
141
+ pipelines: PipelineDeclaration[];
142
+ /**
143
+ * Optional conditional declaration builder.
144
+ * Replaces conditional registration logic in register() bodies.
145
+ * Receives the runtime context (env vars, profile, etc.) and returns
146
+ * additional or modified declarations/commands/pipelines.
147
+ * This runs at startup before reconciliation, not at registration time.
148
+ */
149
+ conditionalBuilder?: (context: ModuleBuildContext) => {
150
+ declarations?: ComponentDeclaration[];
151
+ commands?: CommandDeclaration[];
152
+ pipelines?: PipelineDeclaration[];
153
+ };
154
+ }
155
+
156
+ /**
157
+ * Build context passed to conditionalBuilder.
158
+ * Provides environment and profile information for conditional declarations.
159
+ */
160
+ export interface ModuleBuildContext {
161
+ /** Environment variables (process.env snapshot). */
162
+ env: Record<string, string | undefined>;
163
+ /** Profile ID from kernel config. */
164
+ profileId: string;
165
+ /** Whether this is a long-running process (dev server, watch mode). */
166
+ longRunning: boolean;
167
+ }
168
+
169
+ /**
170
+ * Actual state — replaces KernelRegistry entirely.
171
+ * The desired state is the declarative target; the actual state is what's
172
+ * currently running. The reconciler updates actual state to match desired state.
173
+ * Command execution reads from actual state — no separate registry needed.
174
+ *
175
+ * Commands and pipelines are always available — they're the module's interface,
176
+ * not dynamically activated. They're populated once at startup from ModuleExport[]
177
+ * and never change. The reconciler only manages components (capabilities and effects).
178
+ * A command may check component state at execution time if it depends on a capability.
179
+ */
180
+ export interface ActualState {
181
+ /** Active components with their runtime fiber state, keyed by componentId. */
182
+ components: ReadonlyMap<string, { declaration: ComponentDeclaration; state: ModuleFiberState }>;
183
+ /**
184
+ * All declared commands from all ModuleExport[], keyed by command name.
185
+ * Populated once at startup, never changes.
186
+ */
187
+ commands: ReadonlyMap<string, CommandDeclaration>;
188
+ /**
189
+ * All declared pipelines from all ModuleExport[], keyed by pipeline name.
190
+ * Populated once at startup, never changes.
191
+ */
192
+ pipelines: ReadonlyMap<string, KernelPipelineStep[]>;
193
+ /**
194
+ * Map from command name to module name — used for command manifest generation.
195
+ * Populated once at startup alongside commands.
196
+ */
197
+ commandModules?: ReadonlyMap<string, string>;
198
+ }
199
+
200
+ /**
201
+ * Mutable version of ActualState — used by the reconciler for component mutations.
202
+ * Commands and pipelines are still readonly (populated once at startup).
203
+ */
204
+ export interface MutableActualState {
205
+ components: Map<string, { declaration: ComponentDeclaration; state: ModuleFiberState }>;
206
+ commands: ReadonlyMap<string, CommandDeclaration>;
207
+ pipelines: ReadonlyMap<string, KernelPipelineStep[]>;
208
+ }
209
+
210
+ /**
211
+ * Overlay — layered patch on the base desired state.
212
+ * Allows scope-specific modifications without rewriting the base.
213
+ */
214
+ export interface DesiredStateOverlay {
215
+ /** Overlay ID — stable and unique within the scope. */
216
+ id: string;
217
+ /** Scope this overlay applies to (RFC-1036). */
218
+ scope: ComponentScope;
219
+ /** Scope context (e.g., missionId for per-mission overlays). */
220
+ context: ScopeContext;
221
+ /** Components to add or replace in the base desired state. */
222
+ addOrReplace: Map<string, ComponentDeclaration>;
223
+ /** Component IDs to remove from the base desired state. */
224
+ remove: string[];
225
+ /** Priority — higher priority overlays override lower ones. */
226
+ priority: number;
227
+ }
@@ -0,0 +1,289 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>
4
+ Sole runtime and type owner of DiagnosticSeverity, DiagnosticEvidence, and
5
+ Diagnostic strict Zod schemas (RFC-0852). Types are inferred from schemas.
6
+ kernel/types.ts re-exports these types; the site plugin imports the schemas.
7
+ </purpose>
8
+ <non-goals>
9
+ <item>Do not define canonical JSON bytes or limits; RFC-0849 owns them.</item>
10
+ <item>Do not define EvidenceEnvelopeV1, certification identities, or dossier admission; RFC-0853 owns those.</item>
11
+ <item>Do not add command status vocabularies or suppression systems.</item>
12
+ </non-goals>
13
+ </MODULE_CONTRACT>
14
+ <CHANGE_SUMMARY>
15
+ <item>RFC-0852: Move canonical Diagnostic ownership from site plugin into the engine.</item>
16
+ <item>RFC-1027: Add structured remediation hints — remediationRefSchema and remediation field on Diagnostic.</item>
17
+ </CHANGE_SUMMARY>
18
+ */
19
+
20
+ import { z } from "zod";
21
+ import {
22
+ isCanonicalJsonObjectV1,
23
+ canonicalJsonBytesV1,
24
+ type CanonicalJsonObjectV1,
25
+ } from "../fingerprint/canonical-json.ts";
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Limits (RFC-0852 §Bounds)
29
+ // ---------------------------------------------------------------------------
30
+
31
+ export const DIAGNOSTIC_LIMITS = {
32
+ ruleIdChars: 128,
33
+ messageBytes: 4 * 1024,
34
+ fixHintBytes: 8 * 1024,
35
+ pathBytes: 1024,
36
+ urlBytes: 4 * 1024,
37
+ snippetBytes: 16 * 1024,
38
+ evidenceItems: 32,
39
+ dataBytes: 64 * 1024,
40
+ diagnosticBytes: 128 * 1024,
41
+ diagnosticsPerResult: 1000,
42
+ remediationActionBytes: 512,
43
+ remediationTargetFiles: 8,
44
+ } as const;
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Helpers
48
+ // ---------------------------------------------------------------------------
49
+
50
+ function utf8ByteLength(value: string): number {
51
+ return Buffer.byteLength(value, "utf8");
52
+ }
53
+
54
+ // ---------------------------------------------------------------------------
55
+ // Diagnostic rule ID — [A-Z0-9][A-Z0-9._-]* , max 128 ASCII chars
56
+ // ---------------------------------------------------------------------------
57
+
58
+ const diagnosticRuleIdPattern = /^[A-Z0-9][A-Z0-9._-]*$/;
59
+
60
+ export const diagnosticRuleIdSchema = z
61
+ .string()
62
+ .max(DIAGNOSTIC_LIMITS.ruleIdChars)
63
+ .regex(
64
+ diagnosticRuleIdPattern,
65
+ "CERT-DIAGNOSTIC-SCHEMA-01: ruleId must match [A-Z0-9][A-Z0-9._-]*",
66
+ );
67
+
68
+ // ---------------------------------------------------------------------------
69
+ // Safe workspace-relative POSIX path
70
+ // ---------------------------------------------------------------------------
71
+
72
+ const unsafePathPatterns = [
73
+ /[/\\]\.\.([/\\]|$)/, // .. component
74
+ /[/\\]\.([/\\]|$)/, // . component (but allow leading . for dotfiles? No — RFC says reject empty/.)
75
+ /^\//, // absolute path
76
+ /^[/\\]/, // leading separator
77
+ /\\/, // backslash
78
+ /\0/, // NUL
79
+ /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//, // URI scheme
80
+ /^~([/\\]|$)/, // home expansion
81
+ /^[a-zA-Z]:[\\/]/, // Windows drive letter
82
+ ];
83
+
84
+ function isSafeWorkspaceRelativePath(value: string): boolean {
85
+ if (value.length === 0) return false;
86
+ if (utf8ByteLength(value) > DIAGNOSTIC_LIMITS.pathBytes) return false;
87
+ for (const pattern of unsafePathPatterns) {
88
+ if (pattern.test(value)) return false;
89
+ }
90
+ // Reject empty components from split
91
+ const segments = value.split("/");
92
+ for (const seg of segments) {
93
+ if (seg.length === 0) return false; // empty component (e.g. "a//b")
94
+ if (seg === "." || seg === "..") return false;
95
+ }
96
+ return true;
97
+ }
98
+
99
+ export const safeWorkspaceRelativePathSchema = z.string().refine(isSafeWorkspaceRelativePath, {
100
+ message:
101
+ "CERT-DIAGNOSTIC-LOCATOR-01: path must be a workspace-relative POSIX path without absolute paths, backslashes, empty/./.. components, NUL, URI schemes, or home expansion",
102
+ });
103
+
104
+ // ---------------------------------------------------------------------------
105
+ // Safe diagnostic URL — absolute http/https, no userinfo, no credentials
106
+ // ---------------------------------------------------------------------------
107
+
108
+ function isSafeDiagnosticUrl(value: string): boolean {
109
+ if (utf8ByteLength(value) > DIAGNOSTIC_LIMITS.urlBytes) return false;
110
+ if (/\0/.test(value)) return false;
111
+ if (/[\x00-\x1f\x7f]/.test(value)) return false; // control characters
112
+
113
+ let parsed: URL;
114
+ try {
115
+ parsed = new URL(value);
116
+ } catch {
117
+ return false;
118
+ }
119
+
120
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return false;
121
+
122
+ // Reject userinfo (credentials in authority)
123
+ if (parsed.username || parsed.password) return false;
124
+
125
+ // Reject credential-bearing query parameters (best-effort high-confidence)
126
+ const query = parsed.searchParams;
127
+ const credentialKeys = [
128
+ "token",
129
+ "access_token",
130
+ "secret",
131
+ "api_key",
132
+ "apikey",
133
+ "key",
134
+ "password",
135
+ "passwd",
136
+ "pwd",
137
+ "authorization",
138
+ "auth",
139
+ "signature",
140
+ "sig",
141
+ ];
142
+ for (const key of credentialKeys) {
143
+ if (query.has(key)) return false;
144
+ }
145
+
146
+ return true;
147
+ }
148
+
149
+ export const safeDiagnosticUrlSchema = z.string().refine(isSafeDiagnosticUrl, {
150
+ message:
151
+ "CERT-DIAGNOSTIC-LOCATOR-01: URL must be an absolute http/https URL with no userinfo, control characters, or credential-bearing query parameters",
152
+ });
153
+
154
+ // ---------------------------------------------------------------------------
155
+ // Redacted diagnostic text — no known secrets/PII/absolute paths
156
+ // ---------------------------------------------------------------------------
157
+
158
+ const secretPatterns = [
159
+ /sk-[A-Za-z0-9_-]{20,}/, // OpenAI-style API key
160
+ /eyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]+/, // JWT
161
+ /-----BEGIN (?:RSA |EC |OPENSSH |)PRIVATE KEY-----/, // private key
162
+ /Bearer\s+[A-Za-z0-9_-]{20,}/, // bearer token
163
+ /Authorization:\s*Bearer\s+[A-Za-z0-9_-]{20,}/i, // auth header
164
+ /(?:mongodb|postgres|postgresql|mysql|redis):\/\/[^\s@"']+:[^\s@"']+@/, // connection string
165
+ /(?:aws_access_key_id|aws_secret_access_key)\s*=\s*[A-Za-z0-9/+=]{16,}/, // AWS creds
166
+ ];
167
+
168
+ const absolutePathPatterns = [
169
+ /^(?:\/|[A-Za-z]:[\\/]|~[\\/])/, // absolute or home path
170
+ ];
171
+
172
+ const piiPatterns = [
173
+ /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/, // email
174
+ /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/, // phone (US-like)
175
+ ];
176
+
177
+ function isRedactedDiagnosticText(value: string, maxBytes: number): boolean {
178
+ if (utf8ByteLength(value) > maxBytes) return false;
179
+ if (value.trim().length === 0) return false;
180
+
181
+ for (const pattern of secretPatterns) {
182
+ if (pattern.test(value)) return false;
183
+ }
184
+ for (const pattern of absolutePathPatterns) {
185
+ if (pattern.test(value)) return false;
186
+ }
187
+ for (const pattern of piiPatterns) {
188
+ if (pattern.test(value)) return false;
189
+ }
190
+ return true;
191
+ }
192
+
193
+ function redactedDiagnosticTextSchema(maxBytes: number) {
194
+ return z.string().refine((val) => isRedactedDiagnosticText(val, maxBytes), {
195
+ message: `CERT-DIAGNOSTIC-REDACTION-01: text must not contain known secrets, PII, or absolute paths and must be within ${maxBytes} UTF-8 bytes`,
196
+ });
197
+ }
198
+
199
+ // ---------------------------------------------------------------------------
200
+ // Canonical JSON object V1 schema for Diagnostic.data
201
+ // ---------------------------------------------------------------------------
202
+ // RFC-0852: data must be a runtime-branded CanonicalJsonObjectV1 at parse time.
203
+ // The TypeScript type is Record<string, unknown> for structural compatibility
204
+ // with existing producers; the Zod custom check enforces canonical validation
205
+ // before persistence. z.custom is used instead of z.record because Zod 4's
206
+ // z.record structural validation rejects branded frozen objects created by
207
+ // snapshotCanonicalJsonObjectV1.
208
+
209
+ const canonicalJsonObjectV1Schema = z
210
+ .custom<Record<string, unknown>>(
211
+ (val): val is CanonicalJsonObjectV1 => isCanonicalJsonObjectV1(val),
212
+ {
213
+ message: "CERT-DIAGNOSTIC-SCHEMA-01: data must be a runtime-branded CanonicalJsonObjectV1",
214
+ },
215
+ )
216
+ .refine(
217
+ (val) => {
218
+ if (!isCanonicalJsonObjectV1(val)) return false;
219
+ const bytes = canonicalJsonBytesV1(val);
220
+ return bytes.length <= DIAGNOSTIC_LIMITS.dataBytes;
221
+ },
222
+ {
223
+ message: `CERT-DIAGNOSTIC-LIMIT-01: canonical data bytes must not exceed ${DIAGNOSTIC_LIMITS.dataBytes} bytes`,
224
+ },
225
+ );
226
+
227
+ // ---------------------------------------------------------------------------
228
+ // Severity
229
+ // ---------------------------------------------------------------------------
230
+
231
+ export const diagnosticSeveritySchema = z.enum(["error", "warning", "info"]);
232
+ export type DiagnosticSeverity = z.infer<typeof diagnosticSeveritySchema>;
233
+
234
+ // ---------------------------------------------------------------------------
235
+ // Evidence
236
+ // ---------------------------------------------------------------------------
237
+
238
+ export const diagnosticEvidenceSchema = z
239
+ .object({
240
+ kind: z.enum(["rule", "rendered", "source", "config", "cache", "runtime"]),
241
+ ruleFile: safeWorkspaceRelativePathSchema.optional(),
242
+ ruleId: diagnosticRuleIdSchema.optional(),
243
+ file: safeWorkspaceRelativePathSchema.optional(),
244
+ url: safeDiagnosticUrlSchema.optional(),
245
+ snippet: redactedDiagnosticTextSchema(DIAGNOSTIC_LIMITS.snippetBytes).optional(),
246
+ })
247
+ .strict();
248
+
249
+ export type DiagnosticEvidence = z.infer<typeof diagnosticEvidenceSchema>;
250
+
251
+ // ---------------------------------------------------------------------------
252
+ // Remediation reference (RFC-1027)
253
+ // ---------------------------------------------------------------------------
254
+
255
+ export const remediationRefSchema = z
256
+ .object({
257
+ ruleId: diagnosticRuleIdSchema,
258
+ action: redactedDiagnosticTextSchema(DIAGNOSTIC_LIMITS.remediationActionBytes),
259
+ template: redactedDiagnosticTextSchema(DIAGNOSTIC_LIMITS.fixHintBytes).optional(),
260
+ docRef: safeWorkspaceRelativePathSchema.optional(),
261
+ targetFiles: z
262
+ .array(safeWorkspaceRelativePathSchema)
263
+ .max(DIAGNOSTIC_LIMITS.remediationTargetFiles)
264
+ .optional(),
265
+ })
266
+ .strict();
267
+
268
+ export type RemediationRef = z.infer<typeof remediationRefSchema>;
269
+
270
+ // ---------------------------------------------------------------------------
271
+ // Diagnostic
272
+ // ---------------------------------------------------------------------------
273
+
274
+ export const diagnosticSchema = z
275
+ .object({
276
+ ruleId: diagnosticRuleIdSchema,
277
+ severity: diagnosticSeveritySchema,
278
+ message: redactedDiagnosticTextSchema(DIAGNOSTIC_LIMITS.messageBytes),
279
+ file: safeWorkspaceRelativePathSchema.optional(),
280
+ line: z.number().int().positive().optional(),
281
+ column: z.number().int().positive().optional(),
282
+ fixHint: redactedDiagnosticTextSchema(DIAGNOSTIC_LIMITS.fixHintBytes).optional(),
283
+ remediation: remediationRefSchema.optional(),
284
+ evidence: z.array(diagnosticEvidenceSchema).max(DIAGNOSTIC_LIMITS.evidenceItems).optional(),
285
+ data: canonicalJsonObjectV1Schema.optional(),
286
+ })
287
+ .strict();
288
+
289
+ export type Diagnostic = z.infer<typeof diagnosticSchema>;