@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,13 +1,21 @@
1
1
  /*
2
2
  <MODULE_CONTRACT>
3
- <purpose>Facilitates the generation and rotation of Ed25519 keypairs for secure application authentication.</purpose>
3
+ <purpose>key-rotate — facilitates the generation and rotation of Ed25519 keypairs for secure application authentication.</purpose>
4
4
  <non-goals>
5
5
  <item>Do not handle raw key parsing or validation beyond schema checks.</item>
6
6
  <item>Do not manage application configuration or orchestration.</item>
7
7
  </non-goals>
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
- <item>Tidied by compass.changesummary.tidy; see git history for prior entries.</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 — tail packages clean
14
+
15
+ 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>
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>
11
19
  </CHANGE_SUMMARY>
12
20
  */
13
21
 
@@ -11,7 +11,12 @@
11
11
  </MODULE_CONTRACT>
12
12
 
13
13
  <CHANGE_SUMMARY>
14
- <item>Tidied by compass.changesummary.tidy; see git history for prior entries.</item>
14
+ <item>RFC-1097: step 6 — compass.migrate codemod run
15
+
16
+ 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>
17
+ <item>RFC-1097: sweep — werkstatt-engine clean
18
+
19
+ 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
20
  </CHANGE_SUMMARY>
16
21
  *******************************************************************************/
17
22
 
@@ -7,8 +7,13 @@
7
7
  </non-goals>
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
- <item>Tidied by compass.changesummary.tidy; see git history for prior entries.</item>
11
- <item>RFC-0921: delegate Ed25519 sign/verify/keygen to shared signing core (@warpgogol/werkstatt-engine/signing). Remove @noble/ed25519 import.</item>
10
+ <item>RFC-0921: delegate Ed25519 sign/verify/keygen to shared signing core (@warpgogol/werkstatt-shared/signing). Remove @noble/ed25519 import.</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
  /**
@@ -32,7 +37,7 @@ import {
32
37
  verifyBytes as signingVerifyBytes,
33
38
  fromHex,
34
39
  toHex,
35
- } from "@warpgogol/werkstatt-engine/signing";
40
+ } from "@warpgogol/werkstatt-shared/signing";
36
41
  import type { VCProof, VerifiableCredential } from "./schema.ts";
37
42
 
38
43
  // ---------------------------------------------------------------------------
@@ -3,6 +3,7 @@ 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"],
7
8
  },
8
9
  });
@@ -0,0 +1,95 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import {
3
+ fcAssert,
4
+ letterString,
5
+ composeWord,
6
+ safeText,
7
+ DEFAULT_NUM_RUNS,
8
+ DEFAULT_MAX_SKIPS_PER_RUN,
9
+ } from "./index.ts";
10
+ import fc from "fast-check";
11
+
12
+ describe("PBT helpers", () => {
13
+ describe("constants", () => {
14
+ it("DEFAULT_NUM_RUNS is 50", () => {
15
+ expect(DEFAULT_NUM_RUNS).toBe(50);
16
+ });
17
+
18
+ it("DEFAULT_MAX_SKIPS_PER_RUN is 100", () => {
19
+ expect(DEFAULT_MAX_SKIPS_PER_RUN).toBe(100);
20
+ });
21
+ });
22
+
23
+ describe("letterString", () => {
24
+ it("generates only letters (\\p{L}+)", () => {
25
+ fcAssert(
26
+ fc.property(letterString(1, 10), (word) => {
27
+ return /^\p{L}+$/u.test(word);
28
+ }),
29
+ );
30
+ });
31
+
32
+ it("respects minLength", () => {
33
+ fcAssert(
34
+ fc.property(letterString(3, 5), (word) => {
35
+ return word.length >= 3 && word.length <= 5;
36
+ }),
37
+ );
38
+ });
39
+
40
+ it("never generates empty string when minLength=1", () => {
41
+ fcAssert(
42
+ fc.property(letterString(1, 5), (word) => {
43
+ return word.length > 0;
44
+ }),
45
+ );
46
+ });
47
+ });
48
+
49
+ describe("composeWord", () => {
50
+ it("generates letter + separator + letter", () => {
51
+ const sep = "\u2019";
52
+ fcAssert(
53
+ fc.property(composeWord(sep), (word) => {
54
+ return /\p{L}+\u2019\p{L}+/u.test(word);
55
+ }),
56
+ );
57
+ });
58
+
59
+ it("contains exactly one separator", () => {
60
+ const sep = "-";
61
+ fcAssert(
62
+ fc.property(composeWord(sep), (word) => {
63
+ const count = (word.match(/-/g) ?? []).length;
64
+ return count === 1;
65
+ }),
66
+ );
67
+ });
68
+ });
69
+
70
+ describe("safeText", () => {
71
+ it("respects maxLength", () => {
72
+ fcAssert(
73
+ fc.property(safeText(50), (text) => {
74
+ return text.length <= 50;
75
+ }),
76
+ );
77
+ });
78
+ });
79
+
80
+ describe("fcAssert", () => {
81
+ it("accepts custom numRuns", () => {
82
+ fcAssert(
83
+ fc.property(letterString(1, 3), (word) => word.length > 0),
84
+ { numRuns: 10 },
85
+ );
86
+ });
87
+
88
+ it("accepts custom maxSkipsPerRun", () => {
89
+ fcAssert(
90
+ fc.property(letterString(1, 3), (word) => word.length > 0),
91
+ { maxSkipsPerRun: 50 },
92
+ );
93
+ });
94
+ });
95
+ });
@@ -0,0 +1,251 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>
4
+ Canonical PBT (property-based testing) helpers for the Werkstatt.
5
+ Provides safe defaults for `fc.assert` (numRuns, maxSkips) and efficient
6
+ arbitraries that avoid the `fc.string().filter()` anti-pattern that causes
7
+ test hangs when the filter regex rejects most generated candidates.
8
+ </purpose>
9
+ <non-goals>
10
+ <item>Does not wrap every fast-check arbitrary — only the ones that need safety defaults.</item>
11
+ <item>Does not replace `fc.assert` entirely — callers can still use it directly with explicit options.</item>
12
+ </non-goals>
13
+ </MODULE_CONTRACT>
14
+ <CHANGE_SUMMARY>
15
+ <item>RFC-1070: Create PBT helpers (fcAssert, letterString, composeWord) to prevent filter-induced hangs.</item>
16
+ </CHANGE_SUMMARY>
17
+ */
18
+
19
+ import fc from "fast-check";
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Default PBT configuration
23
+ // ---------------------------------------------------------------------------
24
+
25
+ /** Default number of property runs. fast-check default is 100; we use 50 for speed. */
26
+ export const DEFAULT_NUM_RUNS = 50;
27
+
28
+ /**
29
+ * Default max pre-condition skips per run.
30
+ * fast-check default is 100. We keep it at 100 — this covers `fc.pre()` failures,
31
+ * NOT `.filter()` rejections (which have no limit and are the real hang cause).
32
+ * The hang prevention comes from using `letterString`/`composeWord` instead of
33
+ * `fc.string().filter()`, plus the vitest `testTimeout: 30_000` safety net.
34
+ */
35
+ export const DEFAULT_MAX_SKIPS_PER_RUN = 100;
36
+
37
+ // ---------------------------------------------------------------------------
38
+ // fcAssert — safe wrapper around fc.assert with defaults
39
+ // ---------------------------------------------------------------------------
40
+
41
+ export interface FcAssertOptions {
42
+ numRuns?: number;
43
+ maxSkipsPerRun?: number;
44
+ }
45
+
46
+ /**
47
+ * Wraps `fc.assert` with safe defaults: `numRuns: 50`, `maxSkipsPerRun: 100`.
48
+ * Callers can override either value.
49
+ *
50
+ * Note: `maxSkipsPerRun` only covers `fc.pre()` pre-condition failures.
51
+ * It does NOT cover `.filter()` rejections on arbitraries — those have no
52
+ * limit and are the primary cause of test hangs. Use `letterString` or
53
+ * `composeWord` instead of `fc.string().filter()` to avoid this entirely.
54
+ *
55
+ * @example
56
+ * fcAssert(fc.property(letterString, (word) => { ... }));
57
+ * fcAssert(fc.property(letterString, (word) => { ... }), { numRuns: 100 });
58
+ */
59
+ export function fcAssert<T>(property: fc.IProperty<T>, options?: FcAssertOptions): void {
60
+ fc.assert(property, {
61
+ numRuns: options?.numRuns ?? DEFAULT_NUM_RUNS,
62
+ maxSkipsPerRun: options?.maxSkipsPerRun ?? DEFAULT_MAX_SKIPS_PER_RUN,
63
+ });
64
+ }
65
+
66
+ // ---------------------------------------------------------------------------
67
+ // Efficient letter-only arbitrary — replaces fc.string().filter(/^\p{L}+$/u)
68
+ // ---------------------------------------------------------------------------
69
+
70
+ /**
71
+ * Latin + Cyrillic letter characters for efficient generation.
72
+ * Uses `fc.constantFrom` (no filtering) instead of `fc.string().filter()`.
73
+ */
74
+ const LETTER_CHARS = [
75
+ // Latin lowercase
76
+ "a",
77
+ "b",
78
+ "c",
79
+ "d",
80
+ "e",
81
+ "f",
82
+ "g",
83
+ "h",
84
+ "i",
85
+ "j",
86
+ "k",
87
+ "l",
88
+ "m",
89
+ "n",
90
+ "o",
91
+ "p",
92
+ "q",
93
+ "r",
94
+ "s",
95
+ "t",
96
+ "u",
97
+ "v",
98
+ "w",
99
+ "x",
100
+ "y",
101
+ "z",
102
+ // Latin uppercase
103
+ "A",
104
+ "B",
105
+ "C",
106
+ "D",
107
+ "E",
108
+ "F",
109
+ "G",
110
+ "H",
111
+ "I",
112
+ "J",
113
+ "K",
114
+ "L",
115
+ "M",
116
+ "N",
117
+ "O",
118
+ "P",
119
+ "Q",
120
+ "R",
121
+ "S",
122
+ "T",
123
+ "U",
124
+ "V",
125
+ "W",
126
+ "X",
127
+ "Y",
128
+ "Z",
129
+ // Cyrillic lowercase (Ukrainian + Russian)
130
+ "а",
131
+ "б",
132
+ "в",
133
+ "г",
134
+ "д",
135
+ "е",
136
+ "ж",
137
+ "з",
138
+ "и",
139
+ "і",
140
+ "к",
141
+ "л",
142
+ "м",
143
+ "н",
144
+ "о",
145
+ "п",
146
+ "р",
147
+ "с",
148
+ "т",
149
+ "у",
150
+ "ф",
151
+ "х",
152
+ "ц",
153
+ "ч",
154
+ "ш",
155
+ "щ",
156
+ "ь",
157
+ "ю",
158
+ "я",
159
+ "ї",
160
+ "є",
161
+ "ґ",
162
+ // Cyrillic uppercase
163
+ "А",
164
+ "Б",
165
+ "В",
166
+ "Г",
167
+ "Д",
168
+ "Е",
169
+ "Ж",
170
+ "З",
171
+ "И",
172
+ "І",
173
+ "К",
174
+ "Л",
175
+ "М",
176
+ "Н",
177
+ "О",
178
+ "П",
179
+ "Р",
180
+ "С",
181
+ "Т",
182
+ "У",
183
+ "Ф",
184
+ "Х",
185
+ "Ц",
186
+ "Ч",
187
+ "Ш",
188
+ "Щ",
189
+ "Ь",
190
+ "Ю",
191
+ "Я",
192
+ "Ї",
193
+ "Є",
194
+ "Ґ",
195
+ ];
196
+
197
+ const letterArb = fc.constantFrom(...LETTER_CHARS);
198
+
199
+ /**
200
+ * Generates strings consisting only of letters (Latin + Cyrillic).
201
+ * Efficient: uses `fc.constantFrom` + `fc.array` — no filtering.
202
+ *
203
+ * @example
204
+ * const word = letterString(1, 5); // 1-5 letter word
205
+ * fcAssert(fc.property(word, (w) => /^\p{L}+$/u.test(w)));
206
+ */
207
+ export function letterString(minLength = 1, maxLength = 10): fc.Arbitrary<string> {
208
+ return fc.array(letterArb, { minLength, maxLength }).map((arr) => arr.join(""));
209
+ }
210
+
211
+ // ---------------------------------------------------------------------------
212
+ // composeWord — builds words with guaranteed structure (no filter needed)
213
+ // ---------------------------------------------------------------------------
214
+
215
+ export interface ComposeWordOptions {
216
+ minLength?: number;
217
+ maxLength?: number;
218
+ }
219
+
220
+ /**
221
+ * Generates words with a guaranteed `letter + separator + letter` structure.
222
+ * Eliminates the need for `fc.string().filter()` when testing pattern-based rules.
223
+ *
224
+ * @example
225
+ * const curlyAposWord = composeWord("\u2019"); // e.g. "ім'я"
226
+ * const modAposWord = composeWord("\u02BC"); // e.g. "імʼя"
227
+ */
228
+ export function composeWord(separator: string, options?: ComposeWordOptions): fc.Arbitrary<string> {
229
+ const min = options?.minLength ?? 1;
230
+ const max = options?.maxLength ?? 5;
231
+ return fc
232
+ .tuple(letterString(min, max), letterString(min, max))
233
+ .map(([a, b]) => `${a}${separator}${b}`);
234
+ }
235
+
236
+ // ---------------------------------------------------------------------------
237
+ // safeText — bounded-length string for negative tests (no filter needed)
238
+ // ---------------------------------------------------------------------------
239
+
240
+ /**
241
+ * Generates random strings with a max length for negative property tests.
242
+ * Use when the property should NOT fire on arbitrary text — the test verifies
243
+ * that no findings are produced. The `maxLength` bound prevents excessive
244
+ * string generation time.
245
+ *
246
+ * @example
247
+ * fcAssert(fc.property(safeText(80), (text) => runRule("TYPO-XX", text).length === 0));
248
+ */
249
+ export function safeText(maxLength = 80): fc.Arbitrary<string> {
250
+ return fc.string({ maxLength });
251
+ }
@@ -14,7 +14,7 @@ are shared infrastructure, not engine internals.</purpose>
14
14
  <item>RFC-0942: moved from werkstatt-engine/src/plugin-contract.ts to werkstatt-shared/src/plugin/plugin-contract.ts.</item>
15
15
  </CHANGE_SUMMARY>
16
16
  */
17
- import type { KernelModule, KernelPipelineStep } from "@warpgogol/werkstatt-engine/kernel/types";
17
+ import type { KernelModule, KernelPipelineStep } from "@warpgogol/werkstatt-shared/kernel";
18
18
 
19
19
  /**
20
20
  * Placeholder type for deploy adapter factories.
@@ -10,10 +10,16 @@ agnostic contract consumed by the build-time resolver, the feature gates, and ru
10
10
  </non-goals>
11
11
  </MODULE_CONTRACT>
12
12
  <CHANGE_SUMMARY>
13
- <item>RFC-0169: initial implementation.</item>
14
13
  <item>RFC-0706: add nachweis feature for Nachweisregister commercial module.</item>
15
14
  <item>RFC-0741: add multi-currency feature for multi-currency build pipeline.</item>
16
15
  <item>RFC-0932: add external-link-qr feature for QR code modal entitlement module.</item>
16
+ <item>RFC-1097: step 6 — compass.migrate codemod run
17
+
18
+ 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>
19
+ <item>RFC-1097: sweep — werkstatt-engine clean
20
+
21
+ 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>
22
+ <history>RFC-0169</history>
17
23
  </CHANGE_SUMMARY>
18
24
  */
19
25
 
@@ -42,6 +48,12 @@ export const ENTITLED_FEATURES = [
42
48
  "external-link-qr",
43
49
  ] as const;
44
50
 
51
+ /**
52
+ * Features that are always enabled for all sites, regardless of Stripe or override state.
53
+ * These are platform-level capabilities that every site gets for free.
54
+ */
55
+ export const FREE_ENTITLED_FEATURES: EntitledFeature[] = ["external-link-qr"];
56
+
45
57
  export type EntitledFeature = (typeof ENTITLED_FEATURES)[number];
46
58
 
47
59
  /** Stripe Feature `lookup_key` → EntitledFeature. The single mapping point. */
@@ -149,10 +161,13 @@ export function resolveEntitlements(input: {
149
161
  ? { pseo: { indexBudget: input.pseoIndexBudget, regionalUnlocked } }
150
162
  : {};
151
163
 
164
+ const mergeFree = (features: string[]): EntitledFeature[] =>
165
+ dedupe([...features, ...FREE_ENTITLED_FEATURES]);
166
+
152
167
  if (input.override && input.override.length > 0) {
153
168
  return {
154
169
  customerId: input.customerId,
155
- features: dedupe(input.override),
170
+ features: mergeFree(input.override),
156
171
  source: "override",
157
172
  ...pseo,
158
173
  };
@@ -160,12 +175,17 @@ export function resolveEntitlements(input: {
160
175
  if (input.stripeFeatures) {
161
176
  return {
162
177
  customerId: input.customerId,
163
- features: dedupe(input.stripeFeatures),
178
+ features: mergeFree(input.stripeFeatures),
164
179
  source: "stripe",
165
180
  ...pseo,
166
181
  };
167
182
  }
168
- return { customerId: input.customerId, features: [], source: "none", ...pseo };
183
+ return {
184
+ customerId: input.customerId,
185
+ features: dedupe([...FREE_ENTITLED_FEATURES]),
186
+ source: "none",
187
+ ...pseo,
188
+ };
169
189
  }
170
190
 
171
191
  /** Reader used by build gates (which modules compile) and runtime endpoints. */
@@ -9,7 +9,12 @@
9
9
  </MODULE_CONTRACT>
10
10
  <CHANGE_SUMMARY>
11
11
  <item>RFC-0183: Initial runtime resolver for Feature Policy without Feature Graph dependency.</item>
12
- <item>Removed false async from resolveFeaturePolicy; resolveFeaturePolicySync is now a thin alias.</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>
13
18
  </CHANGE_SUMMARY>
14
19
  */
15
20
 
@@ -19,7 +24,7 @@ import type {
19
24
  FeaturePolicyTargetRef,
20
25
  FeaturePolicyVisibility,
21
26
  ResolvedFeaturePolicy,
22
- } from "./schemas/features.ts";
27
+ } from "../schemas/features.ts";
23
28
 
24
29
  // Re-export types for consumers
25
30
  export type {
@@ -29,7 +34,7 @@ export type {
29
34
  FeaturePolicyTargetRef,
30
35
  FeaturePolicyVisibility,
31
36
  ResolvedFeaturePolicy,
32
- } from "./schemas/features.ts";
37
+ } from "../schemas/features.ts";
33
38
 
34
39
  export interface FeaturePolicyResolverOptions {
35
40
  /**
@@ -15,12 +15,17 @@ requires a superseding RFC.
15
15
  </non-goals>
16
16
  </MODULE_CONTRACT>
17
17
  <CHANGE_SUMMARY>
18
- <item>Wave 1 (RFC-0026): Initial creation — unified VisibilityExpr grammar with build-time evaluator.</item>
18
+ <item>RFC-1097: step 6 — compass.migrate codemod run
19
+
20
+ 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>
21
+ <item>RFC-1097: sweep — werkstatt-engine clean
22
+
23
+ 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
24
  </CHANGE_SUMMARY>
20
25
  */
21
26
 
22
27
  import { z } from "zod";
23
- import type { RuntimeContext } from "./runtime-context.ts";
28
+ import type { RuntimeContext } from "../runtime/runtime-context.ts";
24
29
 
25
30
  // ---------------------------------------------------------------------------
26
31
  // VisibilityExpr — closed discriminated union (DNA-19, RFC-0026)
@@ -0,0 +1,117 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>App-agnostic _redirects file parsing for reuse across site-kernel-checks and site-kernel-handoff (RFC-0588).</purpose>
4
+ <non-goals>
5
+ <item>Do not handle advanced Cloudflare Pages syntax (query parameters, placeholders) — only whitespace-delimited `from to status` lines.</item>
6
+ <item>Do not perform glob-to-regex conversion — that is the consumer's responsibility.</item>
7
+ </non-goals>
8
+ </MODULE_CONTRACT>
9
+ <CHANGE_SUMMARY>
10
+ <item>RFC-0588: extracted parseRedirectRules and RedirectRule from site-kernel-checks/managed-public.ts into @warpgogol/werkstatt-shared/redirects subpath.</item>
11
+ <item>RFC-0595: add extractRedirectTarget helper for parsing url= from meta-refresh tags.</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>
18
+ </CHANGE_SUMMARY>
19
+ */
20
+
21
+ export type RedirectRule = {
22
+ from: string;
23
+ to: string | undefined;
24
+ status: number;
25
+ line: string;
26
+ };
27
+
28
+ /**
29
+ * File extensions excluded from trailing-slash normalization in the Cloudflare Worker
30
+ * `isPageRoute` function. If a request URL ends with one of these extensions, the Worker
31
+ * must NOT 308-redirect it to a trailing-slash URL (which would cause a 404).
32
+ *
33
+ * This is the single source of truth — injected into worker.ts.template and
34
+ * markdown-negotiation.ts.template via the `{{EXCLUDED_EXTENSIONS}}` placeholder.
35
+ * The `trailing.slash.config.validate` SLASH-04 rule scans `public/` for file extensions
36
+ * not in this list and fails the build.
37
+ *
38
+ * When adding a new media/asset type to `public/`, add its extension here.
39
+ */
40
+ export const PAGE_ROUTE_EXCLUDED_EXTENSIONS: readonly string[] = [
41
+ "ico",
42
+ "png",
43
+ "jpg",
44
+ "jpeg",
45
+ "webp",
46
+ "avif",
47
+ "gif",
48
+ "bmp",
49
+ "svg",
50
+ "css",
51
+ "js",
52
+ "mjs",
53
+ "json",
54
+ "txt",
55
+ "xml",
56
+ "woff",
57
+ "woff2",
58
+ "ttf",
59
+ "otf",
60
+ "webmanifest",
61
+ "md",
62
+ "pdf",
63
+ "webm",
64
+ "mp4",
65
+ "wasm",
66
+ "map",
67
+ "m3u8",
68
+ "ts",
69
+ "html",
70
+ "ndjson",
71
+ "vtt",
72
+ "yaml",
73
+ ];
74
+
75
+ /**
76
+ * Build a regex string (without delimiters) that matches any of the excluded extensions.
77
+ * Used by the codegen to inject the alternation into the `isPageRoute` regex.
78
+ */
79
+ export function buildPageRouteExclusionAlternation(
80
+ extensions: readonly string[] = PAGE_ROUTE_EXCLUDED_EXTENSIONS,
81
+ ): string {
82
+ return extensions.join("|");
83
+ }
84
+
85
+ export function parseRedirectRules(body: string): RedirectRule[] {
86
+ return body
87
+ .split(/\r?\n/)
88
+ .map((line) => line.trim())
89
+ .filter((line) => line && !line.startsWith("#"))
90
+ .map((line) => {
91
+ const [from, to, statusRaw] = line.split(/\s+/);
92
+ return {
93
+ from: from ?? "",
94
+ to,
95
+ status: Number(statusRaw ?? 301),
96
+ line,
97
+ };
98
+ })
99
+ .filter((rule) => rule.from.length > 0);
100
+ }
101
+
102
+ /**
103
+ * Extract the redirect target URL from a `<meta http-equiv="refresh" content="0;url=...">` tag.
104
+ * Returns the immediate target only (first hop). Returns null if the tag is
105
+ * absent or the url= value cannot be parsed.
106
+ */
107
+ export function extractRedirectTarget(html: string): string | null {
108
+ const m = html.match(
109
+ /<meta[^>]+http-equiv=["']refresh["'][^>]*content=["']\s*\d+\s*;\s*url=([^"']+)['"][^>]*>/i,
110
+ );
111
+ if (m?.[1]) return m[1].trim();
112
+ const m2 = html.match(
113
+ /<meta[^>]+content=["']\s*\d+\s*;\s*url=([^"']+)['"][^>]*http-equiv=["']refresh["'][^>]*>/i,
114
+ );
115
+ if (m2?.[1]) return m2[1].trim();
116
+ return null;
117
+ }
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { test, expect } from "vitest";
11
- import { extractRedirectTarget, parseRedirectRules } from "./redirects.ts";
11
+ import { extractRedirectTarget, parseRedirectRules } from "../redirects.ts";
12
12
 
13
13
  test("extractRedirectTarget: extracts url from standard meta-refresh tag", () => {
14
14
  const html = `<html><head><meta http-equiv="refresh" content="0;url=/de/agb"></head><body></body></html>`;