@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
@@ -0,0 +1,84 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildVideoObjectNodes } from "../video.ts";
3
+ import { createJsonLdContext } from "../context.ts";
4
+ import { makePage } from "../../tests/helpers.ts";
5
+
6
+ describe("buildVideoObjectNodes", () => {
7
+ it("returns empty array when no blocks have video data", () => {
8
+ const page = makePage({ blocks: [{ id: "b1", heading: "Test" }] });
9
+ const ctx = createJsonLdContext(page);
10
+ expect(buildVideoObjectNodes(ctx)).toEqual([]);
11
+ });
12
+
13
+ it("builds VideoObject nodes for blocks with video data", () => {
14
+ const page = makePage({
15
+ blocks: [
16
+ {
17
+ id: "vid-1",
18
+ heading: "Video Section",
19
+ video: {
20
+ seo: { name: "Intro Video", description: "An intro", uploadDate: "2024-01-15" },
21
+ manifest: {
22
+ posterUrl: "https://example.com/poster.jpg",
23
+ contentUrl: "https://example.com/video.mp4",
24
+ durationSec: 90,
25
+ },
26
+ },
27
+ },
28
+ ],
29
+ });
30
+ const ctx = createJsonLdContext(page);
31
+ const nodes = buildVideoObjectNodes(ctx);
32
+ expect(nodes).toHaveLength(1);
33
+ expect(nodes[0]["@type"]).toBe("VideoObject");
34
+ expect(nodes[0].name).toBe("Intro Video");
35
+ expect(nodes[0].description).toBe("An intro");
36
+ expect(nodes[0].uploadDate).toBe("2024-01-15");
37
+ expect(nodes[0].thumbnailUrl).toBe("https://example.com/poster.jpg");
38
+ expect(nodes[0].contentUrl).toBe("https://example.com/video.mp4");
39
+ expect(nodes[0].duration).toBe("PT1M30S");
40
+ });
41
+
42
+ it("formats duration correctly for hours, minutes, seconds", () => {
43
+ const page = makePage({
44
+ blocks: [
45
+ {
46
+ id: "vid-2",
47
+ heading: "Long Video",
48
+ video: {
49
+ seo: { name: "Long", description: "Long", uploadDate: "2024-01-15" },
50
+ manifest: {
51
+ posterUrl: "https://example.com/p.jpg",
52
+ contentUrl: "https://example.com/v.mp4",
53
+ durationSec: 3661,
54
+ },
55
+ },
56
+ },
57
+ ],
58
+ });
59
+ const ctx = createJsonLdContext(page);
60
+ const nodes = buildVideoObjectNodes(ctx);
61
+ expect(nodes[0].duration).toBe("PT1H1M1S");
62
+ });
63
+
64
+ it("omits duration when durationSec is not provided", () => {
65
+ const page = makePage({
66
+ blocks: [
67
+ {
68
+ id: "vid-3",
69
+ heading: "No Duration",
70
+ video: {
71
+ seo: { name: "NoDur", description: "No dur", uploadDate: "2024-01-15" },
72
+ manifest: {
73
+ posterUrl: "https://example.com/p.jpg",
74
+ contentUrl: "https://example.com/v.mp4",
75
+ },
76
+ },
77
+ },
78
+ ],
79
+ });
80
+ const ctx = createJsonLdContext(page);
81
+ const nodes = buildVideoObjectNodes(ctx);
82
+ expect(nodes[0].duration).toBeUndefined();
83
+ });
84
+ });
@@ -0,0 +1,93 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildWebPageNode } from "../webpage.ts";
3
+ import { createJsonLdContext } from "../context.ts";
4
+ import { makePage } from "../../tests/helpers.ts";
5
+
6
+ describe("buildWebPageNode", () => {
7
+ it("builds WebPage node for content type", () => {
8
+ const page = makePage({ type: "content" });
9
+ const ctx = createJsonLdContext(page);
10
+ const node = buildWebPageNode(ctx);
11
+ expect(node["@type"]).toEqual(["WebPage"]);
12
+ expect(node["@id"]).toBe(ctx.webpageId);
13
+ expect(node.url).toBe(page.url);
14
+ expect(node.name).toBe("Test Page");
15
+ expect(node.description).toBe("A test page description");
16
+ expect(node.inLanguage).toBe("de");
17
+ });
18
+
19
+ it("uses heading for name when available", () => {
20
+ const page = makePage({ heading: "Custom Heading" });
21
+ const ctx = createJsonLdContext(page);
22
+ const node = buildWebPageNode(ctx);
23
+ expect(node.headline).toBe("Custom Heading");
24
+ });
25
+
26
+ it("uses title for headline", () => {
27
+ const page = makePage({ title: "Page Title" });
28
+ const ctx = createJsonLdContext(page);
29
+ const node = buildWebPageNode(ctx);
30
+ expect(node.name).toBe("Page Title");
31
+ });
32
+
33
+ it("emits CollectionPage for collection type", () => {
34
+ const page = makePage({ type: "collection" });
35
+ const ctx = createJsonLdContext(page);
36
+ const node = buildWebPageNode(ctx);
37
+ expect(node["@type"]).toEqual(["WebPage", "CollectionPage"]);
38
+ });
39
+
40
+ it("emits AboutPage for about type", () => {
41
+ const page = makePage({ type: "about" });
42
+ const ctx = createJsonLdContext(page);
43
+ const node = buildWebPageNode(ctx);
44
+ expect(node["@type"]).toEqual(["WebPage", "AboutPage"]);
45
+ });
46
+
47
+ it("emits ProfilePage for person type", () => {
48
+ const page = makePage({ type: "person" });
49
+ const ctx = createJsonLdContext(page);
50
+ const node = buildWebPageNode(ctx);
51
+ expect(node["@type"]).toEqual(["WebPage", "ProfilePage"]);
52
+ });
53
+
54
+ it("links to organization via publisher", () => {
55
+ const page = makePage();
56
+ const ctx = createJsonLdContext(page);
57
+ const node = buildWebPageNode(ctx);
58
+ expect(node.publisher).toEqual({ "@id": ctx.ids.organization });
59
+ });
60
+
61
+ it("links to breadcrumb when breadcrumbs > 1", () => {
62
+ const page = makePage({
63
+ breadcrumbs: [
64
+ { name: "Home", url: "https://example.com/de/" },
65
+ { name: "Page", url: "https://example.com/de/page/" },
66
+ ],
67
+ });
68
+ const ctx = createJsonLdContext(page);
69
+ const node = buildWebPageNode(ctx);
70
+ expect(node.breadcrumb).toEqual({ "@id": ctx.breadcrumbId });
71
+ });
72
+
73
+ it("omits breadcrumb when only one crumb", () => {
74
+ const page = makePage({
75
+ breadcrumbs: [{ name: "Home", url: "https://example.com/de/" }],
76
+ });
77
+ const ctx = createJsonLdContext(page);
78
+ const node = buildWebPageNode(ctx);
79
+ expect(node.breadcrumb).toBeUndefined();
80
+ });
81
+
82
+ it("emits primaryImage when present", () => {
83
+ const page = makePage({
84
+ primaryImage: { url: "https://example.com/img.jpg" },
85
+ });
86
+ const ctx = createJsonLdContext(page);
87
+ const node = buildWebPageNode(ctx);
88
+ expect(node.primaryImageOfPage).toEqual({
89
+ "@type": "ImageObject",
90
+ url: "https://example.com/img.jpg",
91
+ });
92
+ });
93
+ });
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildWebSiteNode } from "../website.ts";
3
+ import { createJsonLdContext } from "../context.ts";
4
+ import { makePage } from "../../tests/helpers.ts";
5
+
6
+ describe("buildWebSiteNode", () => {
7
+ it("builds WebSite node with organization URL and language", () => {
8
+ const page = makePage({ lang: "de" });
9
+ const ctx = createJsonLdContext(page);
10
+ const node = buildWebSiteNode(ctx);
11
+ expect(node["@type"]).toBe("WebSite");
12
+ expect(node["@id"]).toBe(ctx.ids.website);
13
+ expect(node.url).toBe(page.organization.url);
14
+ expect(node.inLanguage).toBe("de");
15
+ expect(node.publisher).toEqual({ "@id": ctx.ids.organization });
16
+ });
17
+
18
+ it("uses organization name for WebSite name", () => {
19
+ const page = makePage({
20
+ organization: makePage().organization,
21
+ });
22
+ page.organization.name = "Test Org";
23
+ const ctx = createJsonLdContext(page);
24
+ const node = buildWebSiteNode(ctx);
25
+ expect(node.name).toBe("Test Org");
26
+ });
27
+ });
@@ -0,0 +1,24 @@
1
+ // test-adjacency: exempt — pure type definitions
2
+ /*
3
+ <MODULE_CONTRACT>
4
+ <purpose>Maintains packages/share/src/semantic/jsonld/types.ts as an authored share authored module so agents can evolve it without rediscovering local boundaries.</purpose>
5
+ <non-goals>
6
+ <item>Do not implement JSON-LD processing logic.</item>
7
+ </non-goals>
8
+ </MODULE_CONTRACT>
9
+ <CHANGE_SUMMARY>
10
+ <item>RFC-1097: step 6 — compass.migrate codemod run
11
+
12
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
13
+ <item>RFC-1097: sweep — werkstatt-engine clean
14
+
15
+ Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
16
+ </CHANGE_SUMMARY>
17
+ */
18
+
19
+ export type JsonLdNode = Record<string, unknown>;
20
+
21
+ export type JsonLdDocument = {
22
+ "@context": "https://schema.org";
23
+ "@graph": JsonLdNode[];
24
+ };
@@ -6,8 +6,13 @@
6
6
  </non-goals>
7
7
  </MODULE_CONTRACT>
8
8
  <CHANGE_SUMMARY>
9
- <item>Added type expansion for donate/faq/news page variants.</item>
10
9
  <item>RFC-0372: speakable reads from unified page.blocks instead of answerBlocks.</item>
10
+ <item>RFC-1097: step 6 — compass.migrate codemod run
11
+
12
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
13
+ <item>RFC-1097: sweep — werkstatt-engine clean
14
+
15
+ Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
11
16
  </CHANGE_SUMMARY>
12
17
  */
13
18
 
@@ -0,0 +1,32 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Maintains packages/share/src/semantic/jsonld/website.ts as an authored share authored module so agents can evolve it without rediscovering local boundaries.</purpose>
4
+ <non-goals>
5
+ <item>Do not parse raw content.</item>
6
+ </non-goals>
7
+ </MODULE_CONTRACT>
8
+ <CHANGE_SUMMARY>
9
+ <item>RFC-1097: step 6 — compass.migrate codemod run
10
+
11
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
12
+ <item>RFC-1097: sweep — werkstatt-engine clean
13
+
14
+ Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
15
+ </CHANGE_SUMMARY>
16
+ */
17
+
18
+ import type { JsonLdContext } from "./context.ts";
19
+ import type { JsonLdNode } from "./types.ts";
20
+
21
+ export function buildWebSiteNode(context: JsonLdContext): JsonLdNode {
22
+ const { page, ids } = context;
23
+
24
+ return {
25
+ "@type": "WebSite",
26
+ "@id": ids.website,
27
+ url: page.organization.url,
28
+ name: page.organization.name,
29
+ inLanguage: page.lang,
30
+ publisher: { "@id": ids.organization },
31
+ };
32
+ }
@@ -7,8 +7,13 @@
7
7
  </non-goals>
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
- <item>Added initiative list graph node, breadcrumb fallback, and shared dedupe utility.</item>
11
10
  <item>RFC-0912: added VideoObject node composition for opted-in content video blocks.</item>
11
+ <item>RFC-1097: step 6 — compass.migrate codemod run
12
+
13
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
14
+ <item>RFC-1097: sweep — werkstatt-engine clean
15
+
16
+ Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
12
17
  </CHANGE_SUMMARY>
13
18
  */
14
19
 
@@ -7,9 +7,16 @@
7
7
  </non-goals>
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
- <item>Added full llms.txt generation and optional title-aware page labels.</item>
11
- <item>RFC-0184: canonical Markdown links, blockquoted summary, absolute URLs, llms-full.txt reference, and empty-section filtering.</item>
12
10
  <item>RFC-0372: formatBlocks reads from unified page.blocks instead of answerBlocks + contentBlocks.</item>
11
+ <item>RFC-1075: emit canonicalUri for organization and offer in llms-full.txt.</item>
12
+ <item>RFC-1076: add formatClaims section in buildLlmsFull for claim provenance.</item>
13
+ <item>RFC-1097: step 6 — compass.migrate codemod run
14
+
15
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
16
+ <item>RFC-1097: sweep — werkstatt-engine clean
17
+
18
+ Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
19
+ <history>RFC-0184</history>
13
20
  </CHANGE_SUMMARY>
14
21
  */
15
22
 
@@ -119,6 +126,9 @@ function formatInitiatives(page: SemanticPageModel): string {
119
126
 
120
127
  function formatOrganizationFacts(site: SemanticSiteModel): string[] {
121
128
  return [
129
+ ...(site.organization.canonicalUri
130
+ ? [`- Canonical URI: ${site.organization.canonicalUri}`]
131
+ : []),
122
132
  `- Name: ${site.organization.legalName ?? site.organization.name}`,
123
133
  ...(site.organization.foundingYear ? [`- Founded: ${site.organization.foundingYear}`] : []),
124
134
  ...(site.organization.registration
@@ -182,7 +192,8 @@ function formatOffer(site: SemanticSiteModel): string[] {
182
192
  const offer = site.organization.offer;
183
193
  if (
184
194
  !offer ||
185
- (!offer.prices?.length &&
195
+ (!offer.canonicalUri &&
196
+ !offer.prices?.length &&
186
197
  !offer.guarantees?.length &&
187
198
  !offer.growthModules?.length &&
188
199
  !offer.changePrice &&
@@ -192,6 +203,9 @@ function formatOffer(site: SemanticSiteModel): string[] {
192
203
  return [];
193
204
  }
194
205
  const lines: string[] = ["## Offer"];
206
+ if (offer.canonicalUri) {
207
+ lines.push(`- Canonical URI: ${offer.canonicalUri}`);
208
+ }
195
209
  if (offer.prices?.length) {
196
210
  lines.push(...offer.prices.map((price) => `- ${price.label}: ${price.amount}`));
197
211
  }
@@ -281,6 +295,29 @@ function formatTeam(site: SemanticSiteModel): string[] {
281
295
  return lines;
282
296
  }
283
297
 
298
+ /** RFC-1076: render projected claims with their evidence references. */
299
+ function formatClaims(site: SemanticSiteModel): string[] {
300
+ if (!site.claims?.length) return [];
301
+ const lines: string[] = ["## Claims"];
302
+ for (const claim of site.claims) {
303
+ lines.push(`### ${claim.statement}`);
304
+ lines.push(`- Class: ${claim.claimClass}`);
305
+ if (claim.verificationLevel) lines.push(`- Verification: ${claim.verificationLevel}`);
306
+ if (claim.confidence) lines.push(`- Confidence: ${claim.confidence}`);
307
+ if (claim.evidence.length > 0) {
308
+ lines.push("- Evidence:");
309
+ for (const ref of claim.evidence) {
310
+ const sha = ref.sha256 ? ` — sha256: ${ref.sha256}` : "";
311
+ lines.push(` - ${ref.kind}: ${ref.label}${sha}`);
312
+ }
313
+ } else {
314
+ lines.push("- Evidence: none");
315
+ }
316
+ }
317
+ lines.push("");
318
+ return lines;
319
+ }
320
+
284
321
  function toAbsoluteUrl(site: SemanticSiteModel, pathname: string): string {
285
322
  const rawBase = site.organization.url ?? site.baseUrl;
286
323
  const base = (() => {
@@ -380,6 +417,7 @@ export function buildLlmsFull(site: SemanticSiteModel): string {
380
417
  ...formatServices(site),
381
418
  ...formatLocation(site),
382
419
  ...formatTeam(site),
420
+ ...formatClaims(site),
383
421
  ].filter((s) => s.length > 0);
384
422
 
385
423
  return [
@@ -1,3 +1,4 @@
1
+ // test-adjacency: exempt — pure type definitions
1
2
  /*
2
3
  <MODULE_CONTRACT>
3
4
  <purpose>Defines types for semantic data structures used throughout the Warpgogol ecosystem.</purpose>
@@ -6,49 +7,31 @@
6
7
  </non-goals>
7
8
  </MODULE_CONTRACT>
8
9
  <CHANGE_SUMMARY>
9
- <item>RFC-0133: backfilled MODULE_MAP and CHANGE_SUMMARY markers for compass.validate compliance.</item>
10
- <item>RFC-0165/0167: SemanticImage.contentImage flag + PageOutputProjection.image (author-declared per-page content illustration, single source for image:image + top-precedence og:image).</item>
11
- <item>RFC-0328: Added "legal" to the SemanticPageType closed enum.</item>
12
- <item>RFC-0490: Added "collection" to the SemanticPageType closed enum.</item>
13
- <item>RFC-0508: Added "participant" to the SemanticPageType closed enum.</item>
14
10
  <item>RFC-0372: Unified SemanticBlock type replaces SemanticAnswerBlock + SemanticContentBlock; SemanticPageModel.blocks replaces answerBlocks/contentBlocks/bodyText.</item>
15
11
  <item>RFC-0912: Added VideoSeoData type and optional SemanticBlock.video field for opted-in content video structured data.</item>
12
+ <item>RFC-1097: step 6 — compass.migrate codemod run
13
+
14
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
15
+ <item>RFC-1097: sweep — tail packages clean
16
+
17
+ Sweep batch 3: rewrote ~95 purposes across werkstatt-knowledge, werkstatt-shared, godot-game, phaser-game, lifecycle-core, projektarchiv-*, portal-*, billing-*, typescript (CONTRACT-02/PURPOSE-02). Real KEY_DECISIONS on 5 godot utils, non-goals on 5 CONTRACT-03 files, headers on 4 headerless files, CS-07 history literal fix on 2 files. Policy: vitest.config.ts + test-fixtures testPatterns, worker-configuration.d.ts excludedPath. All non-site/engine packages now 0 diagnostics.</item>
18
+ <item>RFC-1106: step 4 — single-source SemanticPageType
19
+
20
+ semanticPageTypeSchema (ontology/schemas/system/page-output.ts) is now the sole declaration of the closed DNA-19 vocabulary. semantic/models.ts derives the type via z.infer and SEMANTIC_PAGE_TYPES via schema.options — the hand-synced union/array and stale circular-dependency comments are deleted.</item>
21
+ <history>RFC-0133, RFC-0165, RFC-0328, RFC-0490, RFC-0508</history>
16
22
  </CHANGE_SUMMARY>
17
23
  */
18
24
 
19
- // NOTE: This closed union is mirrored by `semanticPageTypeSchema` in
20
- // `@warpgogol/werkstatt-shared/ontology/src/schemas/system.ts`. `share` owns the compile-time
21
- // contract used by lightweight consumers; `ontology` owns the runtime Zod
22
- // validator for `system.md`. They are kept in sync manually because deriving
23
- // one from the other would create a circular dependency between the two
24
- // packages.
25
- export type SemanticPageType =
26
- | "home"
27
- | "about"
28
- | "projects"
29
- | "donationContact"
30
- | "openSource"
31
- | "content"
32
- | "article"
33
- | "person"
34
- | "participant"
35
- | "legal"
36
- | "collection";
37
-
38
- /** Runtime counterpart to the `SemanticPageType` closed union. Keep in sync manually. */
39
- export const SEMANTIC_PAGE_TYPES: readonly SemanticPageType[] = [
40
- "home",
41
- "about",
42
- "projects",
43
- "donationContact",
44
- "openSource",
45
- "content",
46
- "article",
47
- "person",
48
- "participant",
49
- "legal",
50
- "collection",
51
- ];
25
+ import { z } from "zod";
26
+ import { semanticPageTypeSchema } from "../ontology/schemas/system/page-output.ts";
27
+
28
+ // RFC-1106: semanticPageTypeSchema (ontology/schemas/system/page-output.ts) is
29
+ // the sole declaration of this closed DNA-19 vocabulary. The type and the
30
+ // runtime array derive from it — no hand-synced mirror.
31
+ export type SemanticPageType = z.infer<typeof semanticPageTypeSchema>;
32
+
33
+ /** Runtime list of the closed vocabulary — derived from the schema's options. */
34
+ export const SEMANTIC_PAGE_TYPES: readonly SemanticPageType[] = semanticPageTypeSchema.options;
52
35
 
53
36
  export type SemanticBreadcrumb = {
54
37
  name: string;
@@ -235,6 +218,8 @@ export type SemanticOfferCapacity = {
235
218
  };
236
219
 
237
220
  export type SemanticOffer = {
221
+ /** RFC-1075: persistent canonical URI for Linked Data @id. */
222
+ canonicalUri?: string;
238
223
  prices?: SemanticPrice[];
239
224
  guarantees?: SemanticGuarantee[];
240
225
  growthModules?: SemanticGrowthModule[];
@@ -268,6 +253,8 @@ export type SemanticFaqEntry = {
268
253
  };
269
254
 
270
255
  export type SemanticOrganization = {
256
+ /** RFC-1075: persistent canonical URI for Linked Data @id. */
257
+ canonicalUri?: string;
271
258
  name: string;
272
259
  legalName?: string;
273
260
  description: string;
@@ -416,4 +403,6 @@ export type SemanticSiteModel = {
416
403
  pages: SemanticPageModel[];
417
404
  /** RFC-0789: agent block from system.md, populated by the semantic loader. */
418
405
  agent?: { enabled?: boolean };
406
+ /** RFC-1076: projected claims with evidence provenance, loaded by the semantic loader. */
407
+ claims?: import("./business-projection.ts").SemanticClaimProvenance[];
419
408
  };
@@ -9,10 +9,12 @@
9
9
  <CHANGE_SUMMARY>
10
10
  <item>RFC-0148: extracted the shared org-profile assembler from the disk + Astro builders.</item>
11
11
  <item>RFC-0910: Organization.url uses canonicalRootUrl (unprefixed root) instead of language-prefixed path.</item>
12
+ <item>RFC-1075: populate canonicalUri on SemanticOrganization using deriveCanonicalUri.</item>
12
13
  </CHANGE_SUMMARY>
13
14
  */
14
15
 
15
16
  import { canonicalRootUrl, getBaseUrl, toAbsoluteUrl } from "./ids.ts";
17
+ import { deriveCanonicalUri } from "./canonical-uri.ts";
16
18
  import type {
17
19
  SemanticInitiative,
18
20
  SemanticLocation,
@@ -106,6 +108,7 @@ export function buildOrganizationProfile(input: OrganizationProfileInput): Seman
106
108
  legalName: input.legalName,
107
109
  description: input.description,
108
110
  url: canonicalRootUrl(baseUrl),
111
+ ...({ canonicalUri: deriveCanonicalUri(baseUrl, "business") } as { canonicalUri?: string }),
109
112
  foundingYear: input.foundingYear,
110
113
  email: input.email,
111
114
  registration: input.registration,
@@ -7,10 +7,13 @@
7
7
  </non-goals>
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
- <item>Consolidated 7 copy-paste page builders (impressum, datenschutz, agb, widerruf, open-source, projekte, wir-ueber-uns) into one generic function.</item>
11
- <item>Introduced app-agnostic markdown-page semantic builder and breadcrumb normalization.</item>
12
- <item>Unified blocksToMarkdown signature — eliminated duplication.</item>
13
10
  <item>RFC-0372: MarkdownPageInput now accepts blocks: SemanticBlock[] directly; removed bodyText/contentBlocks/answerBlocks from input and output.</item>
11
+ <item>RFC-1097: step 6 — compass.migrate codemod run
12
+
13
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
14
+ <item>RFC-1097: sweep — werkstatt-engine clean
15
+
16
+ Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
14
17
  </CHANGE_SUMMARY>
15
18
  */
16
19
 
@@ -7,11 +7,14 @@
7
7
  </non-goals>
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
- <item>Extracted from app semantic pages _shared — framework-agnostic utilities moved to packages/share.</item>
11
- <item>Unified single blocksToMarkdown signature (was duplicated with different signatures in app).</item>
12
- <item>Added slugify export and markdown answer-block extraction utilities.</item>
13
10
  <item>RFC-0372: toSemanticAnswerBlocks now returns SemanticBlock[] with blockType: "prose".</item>
14
11
  <item>RFC-0915: replaced slugify import from extract.ts with slugId from canonical slug module.</item>
12
+ <item>RFC-1097: step 6 — compass.migrate codemod run
13
+
14
+ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
15
+ <item>RFC-1097: sweep — werkstatt-engine clean
16
+
17
+ Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
15
18
  </CHANGE_SUMMARY>
16
19
  */
17
20
 
@@ -0,0 +1,55 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildAiTxt } from "../ai.ts";
3
+
4
+ describe("buildAiTxt", () => {
5
+ it("generates header from siteUrl", () => {
6
+ const result = buildAiTxt({ policy: "allow" }, "https://example.com");
7
+ expect(result).toContain("# ai.txt for example.com");
8
+ expect(result).toContain("policy: allow");
9
+ });
10
+
11
+ it("includes version and updated", () => {
12
+ const result = buildAiTxt({ policy: "allow", version: "1.0", updated: "2024-01-01" }, "https://example.com");
13
+ expect(result).toContain("version: 1.0");
14
+ expect(result).toContain("updated: 2024-01-01");
15
+ });
16
+
17
+ it("includes optional fields when provided", () => {
18
+ const result = buildAiTxt({
19
+ policy: "limited",
20
+ training: "disallow",
21
+ usage: ["search", "summarization"],
22
+ commercial: "no",
23
+ attribution: "required",
24
+ license: "CC-BY-4.0",
25
+ }, "https://example.com");
26
+ expect(result).toContain("training: disallow");
27
+ expect(result).toContain("usage: search, summarization");
28
+ expect(result).toContain("commercial: no");
29
+ expect(result).toContain("attribution: required");
30
+ expect(result).toContain("license: CC-BY-4.0");
31
+ });
32
+
33
+ it("emits provider sections", () => {
34
+ const result = buildAiTxt({
35
+ policy: "allow",
36
+ providers: [
37
+ { name: "OpenAI", policy: "disallow", training: "disallow" },
38
+ { name: "Anthropic", policy: "allow", url: "https://anthropic.com" },
39
+ ],
40
+ }, "https://example.com");
41
+ expect(result).toContain("[OpenAI]");
42
+ expect(result).toContain("[Anthropic]");
43
+ expect(result).toContain("url: https://anthropic.com");
44
+ });
45
+
46
+ it("includes url and contact in header comments", () => {
47
+ const result = buildAiTxt({
48
+ policy: "allow",
49
+ url: "https://example.com/policy",
50
+ contact: "info@example.com",
51
+ }, "https://example.com");
52
+ expect(result).toContain("# See: https://example.com/policy");
53
+ expect(result).toContain("# Contact: info@example.com");
54
+ });
55
+ });
@@ -0,0 +1,34 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { BlockExtractorRegistry, BLOCK_EXTRACTORS } from "../block-extraction.ts";
3
+ import "../block-extractors/index.ts";
4
+
5
+ describe("BlockExtractorRegistry", () => {
6
+ it("registers and retrieves extractors", () => {
7
+ const registry = new BlockExtractorRegistry();
8
+ registry.register({
9
+ blockType: "test-block",
10
+ extract: () => ({ heading: "Test" }),
11
+ });
12
+ expect(registry.has("test-block")).toBe(true);
13
+ expect(registry.get("test-block")?.blockType).toBe("test-block");
14
+ });
15
+
16
+ it("returns undefined for unregistered type", () => {
17
+ const registry = new BlockExtractorRegistry();
18
+ expect(registry.get("nonexistent")).toBeUndefined();
19
+ });
20
+
21
+ it("lists registered types", () => {
22
+ const registry = new BlockExtractorRegistry();
23
+ registry.register({ blockType: "a", extract: () => ({}) });
24
+ registry.register({ blockType: "b", extract: () => ({}) });
25
+ expect(registry.listTypes().sort()).toEqual(["a", "b"]);
26
+ });
27
+ });
28
+
29
+ describe("BLOCK_EXTRACTORS", () => {
30
+ it("is a registry instance with pre-registered extractors", () => {
31
+ expect(BLOCK_EXTRACTORS).toBeInstanceOf(BlockExtractorRegistry);
32
+ expect(BLOCK_EXTRACTORS.listTypes().length).toBeGreaterThan(0);
33
+ });
34
+ });
@@ -14,7 +14,7 @@ import {
14
14
  surfaceAncestorPageIds,
15
15
  type BreadcrumbAncestorResolver,
16
16
  type BreadcrumbCrumb,
17
- } from "../semantic/breadcrumbs.ts";
17
+ } from "../breadcrumbs.ts";
18
18
 
19
19
  const HOME = "https://example.com/";
20
20
  const SELF = "https://example.com/website/schreiner/muenchen/";