@warpgogol/werkstatt-shared 0.14.1 → 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 (438) hide show
  1. package/README.md +23 -15
  2. package/README.uk.md +1 -1
  3. package/package.json +517 -766
  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/{share → agent}/tests/openapi.test.ts +2 -2
  16. package/src/{share → agent}/tests/proof.test.ts +1 -1
  17. package/src/{share → attribution}/material-credits.ts +4 -4
  18. package/src/{share → checks}/check-hints.ts +6 -1
  19. package/src/checks/index.ts +4 -1
  20. package/src/checks/lib/astro-site-url.ts +6 -1
  21. package/src/checks/lib/i18n.ts +14 -0
  22. package/src/checks/result-helpers.ts +2 -2
  23. package/src/checks/tests/remediation-auto-populate.test.ts +1 -1
  24. package/src/{share → client-scripts}/counter-utils.ts +6 -2
  25. package/src/{share/scripts → client-scripts}/external-link-qr.ts +11 -16
  26. package/src/{share/scripts → client-scripts}/external-links.ts +12 -1
  27. package/src/{share/scripts → client-scripts}/gsap-counter.ts +8 -3
  28. package/src/client-scripts/index.ts +35 -0
  29. package/src/{share/scripts → client-scripts}/inline-number-animation.ts +1 -1
  30. package/src/{share/scripts → client-scripts}/lenis.ts +6 -1
  31. package/src/{share/scripts → client-scripts}/lordicon.ts +6 -1
  32. package/src/{share/scripts → client-scripts}/orchestrator.ts +10 -1
  33. package/src/{share/scripts → client-scripts}/scheduler.ts +6 -1
  34. package/src/client-scripts/scroll-spy.ts +106 -0
  35. package/src/client-scripts/tests/orchestrator.test.ts +47 -0
  36. package/src/client-scripts/tests/scroll-spy.test.ts +204 -0
  37. package/src/{share/scripts → client-scripts/tests}/video-player.test.ts +51 -31
  38. package/src/component/contracts.ts +206 -0
  39. package/src/component/index.ts +11 -0
  40. package/src/{share → content}/content-reference.ts +3 -3
  41. package/src/{share/content → content}/entity-id.ts +6 -3
  42. package/src/content/index.ts +3 -0
  43. package/src/{share/content → content}/merge.ts +6 -1
  44. package/src/content/system-manifest.test.ts +107 -0
  45. package/src/content/system-manifest.ts +12 -94
  46. package/src/{share → content}/tests/resolve-field-path.test.ts +1 -1
  47. package/src/{share → content}/tests/substitute-deep.test.ts +1 -1
  48. package/src/content-discipline/index.ts +19 -0
  49. package/src/{share/content-discipline → content-discipline}/parsers.ts +2 -2
  50. package/src/{share/env.d.ts → env.d.ts} +6 -3
  51. package/src/fingerprint/canonical-json.ts +731 -0
  52. package/src/fingerprint/index.ts +12 -0
  53. package/src/fingerprint/primitives.ts +72 -0
  54. package/src/{share/i18n → i18n}/localization.ts +6 -2
  55. package/src/integration/adapters.ts +10 -71
  56. package/src/integration/dispatch.ts +1 -1
  57. package/src/integration/funnel.ts +6 -1
  58. package/src/integration/index.ts +101 -4
  59. package/src/integration/lagebild-destination-adapter.ts +108 -0
  60. package/src/integration/lagebild-ingress.ts +7 -12
  61. package/src/integration/orchestration.ts +11 -10
  62. package/src/integration/tests/deliver-event.test.ts +1 -1
  63. package/src/integration/tests/dispatch.test.ts +4 -4
  64. package/src/integration/tests/hub-runtime.test.ts +22 -14
  65. package/src/integration/vitest.config.ts +1 -0
  66. package/src/kernel/desired-state.ts +227 -0
  67. package/src/kernel/diagnostic.ts +289 -0
  68. package/src/kernel/fs-atomic.ts +131 -0
  69. package/src/kernel/index.ts +15 -0
  70. package/src/kernel/tests/fs-atomic.test.ts +150 -0
  71. package/src/kernel/tests/workspace-io.test.ts +187 -0
  72. package/src/kernel/types.ts +459 -0
  73. package/src/kernel/workspace-io.ts +248 -0
  74. package/src/{share → knowledge}/tests/claim.test.ts +1 -1
  75. package/src/{share → knowledge}/tests/derivation.test.ts +1 -1
  76. package/src/{share → knowledge}/tests/freshness.test.ts +1 -1
  77. package/src/{share → knowledge}/tests/ledger.test.ts +1 -1
  78. package/src/{share → knowledge}/tests/plan.test.ts +1 -1
  79. package/src/{share → knowledge}/tests/source.test.ts +1 -1
  80. package/src/legal/index.ts +15 -0
  81. package/src/{share/middleware → middleware}/access-protection.ts +8 -8
  82. package/src/{share → node}/dev-props-validator.ts +6 -1
  83. package/src/{share → node}/import-scan.ts +23 -3
  84. package/src/{share → node}/semantic/derived-prices-loader.ts +4 -2
  85. package/src/{share → node}/semantic/markdown-twin-provenance.ts +1 -1
  86. package/src/{share/semantic → node}/tests/derived-prices-loader.test.ts +14 -1
  87. package/src/{share/semantic → node}/tests/markdown-twin-provenance.test.ts +1 -1
  88. package/src/observability/env-resolver.ts +6 -1
  89. package/src/observability/index.ts +6 -1
  90. package/src/observability/otlp-converter.ts +6 -1
  91. package/src/observability/otlp-transport.ts +6 -1
  92. package/src/observability/pusher.ts +6 -1
  93. package/src/observability/redact.ts +6 -1
  94. package/src/observability/typed-refs.ts +6 -2
  95. package/src/observability/vitest.config.ts +1 -0
  96. package/src/{share → offers}/formula-eval.ts +3 -3
  97. package/src/{share → offers}/tests/formula-eval.test.ts +2 -2
  98. package/src/onboarding/index.ts +1 -0
  99. package/src/{share → onboarding}/tests/onboarding-yaml.test.ts +1 -1
  100. package/src/ontology/archetype-registry.ts +6 -1
  101. package/src/ontology/archetypes/index.json +33 -1
  102. package/src/ontology/archetypes/index.yaml +27 -1
  103. package/src/ontology/archetypes/sections/entity-grid.yaml +46 -0
  104. package/src/ontology/archetypes/sections/exit-diagram.yaml +43 -0
  105. package/src/ontology/biome-token-projection.ts +6 -1
  106. package/src/ontology/cosmic/index.ts +6 -1
  107. package/src/ontology/cosmic/moon-catalog.ts +6 -1
  108. package/src/ontology/cosmic/planet-catalog.ts +6 -1
  109. package/src/ontology/cosmic/star-catalog.ts +6 -1
  110. package/src/ontology/enums.ts +6 -1
  111. package/src/ontology/external-surfaces/index.ts +1 -1
  112. package/src/ontology/index.ts +6 -2
  113. package/src/ontology/manifest.ts +7 -4
  114. package/src/ontology/operations/artifact-store.ts +45 -0
  115. package/src/ontology/operations/dht.ts +98 -0
  116. package/src/ontology/operations/handoff.ts +92 -0
  117. package/src/ontology/operations/index.ts +187 -1
  118. package/src/ontology/operations/leitstand.ts +99 -0
  119. package/src/ontology/operations/materialization.ts +90 -0
  120. package/src/ontology/operations/mission.ts +111 -0
  121. package/src/ontology/operations/naming-policy.ts +132 -0
  122. package/src/ontology/operations/notausgang.ts +64 -0
  123. package/src/ontology/operations/release.ts +121 -0
  124. package/src/ontology/operations/sternsystem.ts +192 -0
  125. package/src/ontology/operations/werkstatt.ts +48 -0
  126. package/src/ontology/schemas/biome.ts +7 -2
  127. package/src/ontology/schemas/capability.ts +1 -1
  128. package/src/ontology/schemas/constellation.ts +6 -1
  129. package/src/ontology/schemas/index.ts +6 -2
  130. package/src/ontology/schemas/manifest-resolver.ts +6 -1
  131. package/src/ontology/schemas/page-entry.ts +9 -5
  132. package/src/ontology/schemas/system/growth.ts +6 -1
  133. package/src/ontology/schemas/system/manifest.ts +40 -1
  134. package/src/ontology/schemas/system/page-output.ts +7 -6
  135. package/src/ontology/schemas/system/text.ts +15 -0
  136. package/src/ontology/schemas/system.ts +6 -2
  137. package/src/ontology/shared-section-props/body-fragments.ts +2 -0
  138. package/src/ontology/tests/sternsystem-owner.test.ts +1 -1
  139. package/src/ontology/vitest.config.ts +1 -0
  140. package/src/{share → page}/page.ts +13 -9
  141. package/src/{share → page}/tests/dev-props-validator.test.ts +1 -1
  142. package/src/{share → page}/tests/hero-section-numbering-parity.test.ts +1 -1
  143. package/src/passport/index.ts +6 -1
  144. package/src/passport/key-rotate.ts +10 -2
  145. package/src/passport/schema.ts +6 -1
  146. package/src/passport/sign.ts +8 -3
  147. package/src/passport/vitest.config.ts +1 -0
  148. package/src/pbt/index.test.ts +95 -0
  149. package/src/pbt/index.ts +251 -0
  150. package/src/plugin/plugin-contract.ts +1 -1
  151. package/src/{share → policy}/entitlement.ts +24 -4
  152. package/src/{share → policy}/feature-policy.ts +8 -3
  153. package/src/{share → policy}/visibility.ts +7 -2
  154. package/src/redirects/redirects.ts +117 -0
  155. package/src/{share → redirects/tests}/redirects.test.ts +1 -1
  156. package/src/remediation/remediation-catalog.ts +316 -0
  157. package/src/{share/routes → routes}/template-filter.ts +1 -1
  158. package/src/{share → runtime}/runtime-context.ts +7 -2
  159. package/src/{share → runtime}/shared-context.ts +1 -1
  160. package/src/{share/schemas → schemas}/claims.ts +2 -2
  161. package/src/{share/schemas → schemas}/effects.ts +6 -1
  162. package/src/{share/schemas → schemas}/features.ts +1 -1
  163. package/src/{share/schemas → schemas}/index.ts +3 -3
  164. package/src/{share/schemas → schemas}/navigation.ts +6 -1
  165. package/src/{share/schemas → schemas}/page-base.ts +6 -2
  166. package/src/{share/schemas → schemas}/person.ts +1 -1
  167. package/src/{share/schemas → schemas}/standard-list-item.ts +1 -1
  168. package/src/{share → sections}/rfc0042-utils.ts +1 -1
  169. package/src/{share/semantic → semantic}/block-extractors/index.ts +20 -1
  170. package/src/{share/semantic → semantic}/business-projection.ts +95 -1
  171. package/src/semantic/canonical-uri.ts +54 -0
  172. package/src/{share/semantic → semantic}/extract.ts +100 -1
  173. package/src/semantic/fact-extraction.test.ts +47 -0
  174. package/src/semantic/fact-extraction.ts +46 -0
  175. package/src/semantic/freshness.ts +67 -0
  176. package/src/{share/semantic → semantic}/ids.ts +6 -1
  177. package/src/{share/semantic → semantic}/index.ts +9 -2
  178. package/src/{share/semantic → semantic}/jsonld/breadcrumb.ts +6 -2
  179. package/src/{share/semantic → semantic}/jsonld/context.ts +6 -2
  180. package/src/{share/semantic → semantic}/jsonld/faq.ts +6 -2
  181. package/src/{share/semantic → semantic}/jsonld/initiative.ts +6 -1
  182. package/src/{share/semantic → semantic}/jsonld/organization.ts +6 -1
  183. package/src/{share/semantic → semantic}/jsonld/person.ts +6 -2
  184. package/src/{share/semantic → semantic}/jsonld/service.ts +6 -2
  185. package/src/semantic/jsonld/shared.ts +36 -0
  186. package/src/semantic/jsonld/types.ts +24 -0
  187. package/src/{share/semantic → semantic}/jsonld/webpage.ts +6 -1
  188. package/src/semantic/jsonld/website.ts +32 -0
  189. package/src/{share/semantic → semantic}/jsonld.ts +6 -1
  190. package/src/{share/semantic → semantic}/llms.ts +41 -3
  191. package/src/{share/semantic → semantic}/models.ts +26 -38
  192. package/src/{share/semantic → semantic}/organization-profile.ts +3 -0
  193. package/src/{share/semantic → semantic}/page-builders/markdown-page.ts +6 -3
  194. package/src/{share/semantic → semantic}/page-utils.ts +6 -3
  195. package/src/{share/tests/breadcrumbs.test.ts → semantic/tests/breadcrumbs-0229.test.ts} +1 -1
  196. package/src/{share → semantic}/tests/build-page-price-markers.test.ts +2 -2
  197. package/src/{share/semantic → semantic}/tests/business-projection.test.ts +179 -0
  198. package/src/semantic/tests/canonical-uri.test.ts +56 -0
  199. package/src/{share/semantic → semantic}/tests/extract.test.ts +83 -0
  200. package/src/semantic/tests/freshness.pbt.test.ts +108 -0
  201. package/src/{share/tests/image-sitemap.test.ts → semantic/tests/image-sitemap-0150.test.ts} +1 -1
  202. package/src/{share → semantic}/tests/jsonld-service.test.ts +2 -2
  203. package/src/{share → semantic}/tests/jsonld-video.test.ts +3 -3
  204. package/src/{share → semantic}/tests/jsonld-webpage.test.ts +3 -3
  205. package/src/{share → semantic}/tests/llms-0789.test.ts +2 -2
  206. package/src/{share/semantic → semantic}/tests/llms.test.ts +46 -0
  207. package/src/{share → semantic}/tests/organization-jsonld.test.ts +3 -3
  208. package/src/{share/tests/output-projection.test.ts → semantic/tests/output-projection-0143.test.ts} +1 -1
  209. package/src/{share/tests/price-marker-resolver.test.ts → semantic/tests/price-marker-resolver-0767.test.ts} +2 -2
  210. package/src/{share/semantic → semantic}/tests/price-marker-resolver.test.ts +4 -2
  211. package/src/semantic/tests/project-claims.pbt.test.ts +60 -0
  212. package/src/{share/semantic → semantic}/tests/split-sentences.test.ts +1 -1
  213. package/src/{share → semantic}/tests/twin-path.test.ts +1 -1
  214. package/src/signing/index.ts +13 -0
  215. package/src/signing/key.ts +139 -0
  216. package/src/signing/sign.ts +66 -0
  217. package/src/signing/types.ts +29 -0
  218. package/src/{share/slug → slug}/slug-url.ts +4 -1
  219. package/src/stack/run-tool.ts +108 -0
  220. package/src/stack/stack-checks.ts +124 -0
  221. package/src/stack/tests/run-tool.test.ts +138 -0
  222. package/src/stack/tests/stack-checks.test.ts +141 -0
  223. package/src/stack/tests/walk-files.test.ts +131 -0
  224. package/src/stack/walk-files.ts +114 -0
  225. package/src/surface/blueprint.ts +342 -66
  226. package/src/surface/decision-composer.ts +6 -1
  227. package/src/surface/geo.ts +6 -1
  228. package/src/surface/index.ts +11 -7
  229. package/src/surface/types.ts +2 -2
  230. package/src/surface/vitest.config.ts +1 -0
  231. package/src/tests/signing-core.test.ts +129 -0
  232. package/src/{share → text}/css-value-normalize.ts +6 -1
  233. package/src/text/string-utils.ts +24 -0
  234. package/src/{share → text}/tests/text-normalize.test.ts +5 -0
  235. package/src/{share → text}/text-normalize.ts +4 -3
  236. package/src/{share → text}/wrap-inline-numbers.ts +1 -1
  237. package/src/types/axiom-study.d.ts +36 -0
  238. package/src/types/hls-js-light.d.ts +21 -0
  239. package/src/types/qrcode-browser.d.ts +23 -0
  240. package/src/typography/fix.pbt.test.ts +208 -0
  241. package/src/typography/fix.ts +148 -0
  242. package/src/typography/index.ts +54 -0
  243. package/src/typography/locale-defaults.ts +97 -0
  244. package/src/typography/rules-tier1.test.ts +459 -0
  245. package/src/typography/rules-tier1.ts +925 -0
  246. package/src/typography/rules-tier2-locale.pbt.test.ts +190 -0
  247. package/src/typography/rules-tier2-locale.test.ts +286 -0
  248. package/src/typography/rules-tier2-locale.ts +399 -0
  249. package/src/typography/rules-tier2-structure.test.ts +330 -0
  250. package/src/typography/rules-tier2-structure.ts +378 -0
  251. package/src/typography/rules-tier3-advisory.test.ts +290 -0
  252. package/src/typography/rules-tier3-advisory.ts +239 -0
  253. package/src/typography/text-surface.test.ts +244 -0
  254. package/src/typography/text-surface.ts +448 -0
  255. package/src/index.ts +0 -14
  256. package/src/integration/port-barrel.ts +0 -105
  257. package/src/share/agent/tests/api-catalog.test.ts +0 -8
  258. package/src/share/agent/tests/ard-catalog.test.ts +0 -8
  259. package/src/share/agent/tests/capability.test.ts +0 -14
  260. package/src/share/agent/tests/fleet-catalog.test.ts +0 -15
  261. package/src/share/agent/tests/knowledge.test.ts +0 -20
  262. package/src/share/agent/tests/manifest.test.ts +0 -9
  263. package/src/share/agent/tests/mcp-card.test.ts +0 -8
  264. package/src/share/agent/tests/openapi.test.ts +0 -8
  265. package/src/share/agent/tests/proof.test.ts +0 -15
  266. package/src/share/content/index.ts +0 -16
  267. package/src/share/content-discipline/index.ts +0 -14
  268. package/src/share/index.ts +0 -86
  269. package/src/share/knowledge/tests/claim.test.ts +0 -11
  270. package/src/share/knowledge/tests/derivation.test.ts +0 -30
  271. package/src/share/knowledge/tests/freshness.test.ts +0 -18
  272. package/src/share/knowledge/tests/ledger.test.ts +0 -35
  273. package/src/share/knowledge/tests/plan.test.ts +0 -19
  274. package/src/share/knowledge/tests/source.test.ts +0 -19
  275. package/src/share/legal/index.ts +0 -1
  276. package/src/share/redirects.ts +0 -54
  277. package/src/share/remediation/remediation-catalog.ts +0 -196
  278. package/src/share/scripts/index.ts +0 -26
  279. package/src/share/scripts/tests/orchestrator.test.ts +0 -8
  280. package/src/share/semantic/jsonld/shared.ts +0 -31
  281. package/src/share/semantic/jsonld/types.ts +0 -19
  282. package/src/share/semantic/jsonld/website.ts +0 -27
  283. package/src/share/string-utils.ts +0 -19
  284. package/src/share/types/axiom-study.d.ts +0 -22
  285. package/src/share/types/hls-js-light.d.ts +0 -16
  286. package/src/share/types/qrcode-browser.d.ts +0 -18
  287. package/src/share/utility-registry.yaml +0 -50
  288. package/src/share/vitest.config.ts +0 -8
  289. package/src/surface/blueprint-schema.ts +0 -314
  290. package/src/surface/blueprint-types.ts +0 -256
  291. /package/src/{share/agent → agent}/api-catalog.ts +0 -0
  292. /package/src/{share/agent → agent}/capability.ts +0 -0
  293. /package/src/{share/agent → agent}/dns-aid.ts +0 -0
  294. /package/src/{share/agent → agent}/fleet-catalog.ts +0 -0
  295. /package/src/{share/agent → agent}/index.ts +0 -0
  296. /package/src/{share/agent → agent}/knowledge.ts +0 -0
  297. /package/src/{share/agent → agent}/mcp-card.ts +0 -0
  298. /package/src/{share/agent → agent}/omit-empty.ts +0 -0
  299. /package/src/{share/agent → agent}/openapi.ts +0 -0
  300. /package/src/{share/agent → agent}/proof.ts +0 -0
  301. /package/src/{share/agent → agent}/search.test.ts +0 -0
  302. /package/src/{share/agent → agent}/tests/omit-empty.test.ts +0 -0
  303. /package/src/{share → attribution}/attribution-display.ts +0 -0
  304. /package/src/{share/scripts → client-scripts}/gsap-mountain-journey.ts +0 -0
  305. /package/src/{share/scripts → client-scripts}/gsap-parallax.ts +0 -0
  306. /package/src/{share/scripts → client-scripts}/gsap-reveal.ts +0 -0
  307. /package/src/{share/scripts → client-scripts}/gsap-stagger.ts +0 -0
  308. /package/src/{share/scripts → client-scripts}/live-photos.ts +0 -0
  309. /package/src/{share/scripts → client-scripts}/tests/external-link-qr.test.ts +0 -0
  310. /package/src/{share/scripts → client-scripts}/tests/external-links.test.ts +0 -0
  311. /package/src/{share/scripts → client-scripts}/tests/gsap-counter.test.ts +0 -0
  312. /package/src/{share/scripts → client-scripts}/tests/gsap-mountain-journey.test.ts +0 -0
  313. /package/src/{share/scripts → client-scripts}/tests/gsap-parallax.test.ts +0 -0
  314. /package/src/{share/scripts → client-scripts}/tests/gsap-reveal.test.ts +0 -0
  315. /package/src/{share/scripts → client-scripts}/tests/gsap-stagger.test.ts +0 -0
  316. /package/src/{share/scripts → client-scripts}/tests/inline-number-animation.test.ts +0 -0
  317. /package/src/{share/scripts → client-scripts}/tests/lenis.test.ts +0 -0
  318. /package/src/{share/scripts → client-scripts}/tests/live-photos.test.ts +0 -0
  319. /package/src/{share/scripts → client-scripts}/tests/lordicon.test.ts +0 -0
  320. /package/src/{share/scripts → client-scripts}/tests/scheduler.test.ts +0 -0
  321. /package/src/{share/scripts → client-scripts}/video-player.ts +0 -0
  322. /package/src/{share/content → content}/resolve-field-path.ts +0 -0
  323. /package/src/{share/content → content}/substitute-deep.ts +0 -0
  324. /package/src/{share → content}/tests/content-ref-index.test.ts +0 -0
  325. /package/src/{share/content-discipline → content-discipline}/types.ts +0 -0
  326. /package/src/{share → image-provider}/image-provider.ts +0 -0
  327. /package/src/{share/knowledge → knowledge}/claim.ts +0 -0
  328. /package/src/{share/knowledge → knowledge}/derivation.ts +0 -0
  329. /package/src/{share/knowledge → knowledge}/freshness.ts +0 -0
  330. /package/src/{share/knowledge → knowledge}/index.ts +0 -0
  331. /package/src/{share/knowledge → knowledge}/ledger.ts +0 -0
  332. /package/src/{share/knowledge → knowledge}/plan.ts +0 -0
  333. /package/src/{share/knowledge → knowledge}/source.ts +0 -0
  334. /package/src/{share/legal → legal}/translation-policy.ts +0 -0
  335. /package/src/{share/middleware → middleware}/language-redirect.ts +0 -0
  336. /package/src/{share/middleware → middleware}/tests/access-protection.test.ts +0 -0
  337. /package/src/{share → node}/fs/index.ts +0 -0
  338. /package/src/{share/tests/markdown-twin-provenance.test.ts → node/tests/markdown-twin-provenance-0613.test.ts} +0 -0
  339. /package/src/{share → offers}/offer-capacity.ts +0 -0
  340. /package/src/{share/onboarding-yaml/index.ts → onboarding/yaml.ts} +0 -0
  341. /package/src/{share → ontology}/tests/ontology-role-by-cosmic-name.test.ts +0 -0
  342. /package/src/{share/routes → routes}/tests/template-filter.test.ts +0 -0
  343. /package/src/{share/schemas → schemas}/claim-records.ts +0 -0
  344. /package/src/{share/schemas → schemas}/horizontal-align.ts +0 -0
  345. /package/src/{share/schemas → schemas}/icon-color.ts +0 -0
  346. /package/src/{share/schemas → schemas}/live-photo.ts +0 -0
  347. /package/src/{share/schemas → schemas}/material-credit.ts +0 -0
  348. /package/src/{share/schemas → schemas}/media.ts +0 -0
  349. /package/src/{share/schemas → schemas}/participant.ts +0 -0
  350. /package/src/{share/schemas → schemas}/print.ts +0 -0
  351. /package/src/{share/schemas → schemas}/section-background.ts +0 -0
  352. /package/src/{share/schemas → schemas}/section-body.ts +0 -0
  353. /package/src/{share/schemas → schemas}/section-cards.ts +0 -0
  354. /package/src/{share/schemas → schemas}/section-cta.ts +0 -0
  355. /package/src/{share/schemas → schemas}/section-header.ts +0 -0
  356. /package/src/{share/schemas → schemas}/section-image.ts +0 -0
  357. /package/src/{share/schemas → schemas}/section-motion.ts +0 -0
  358. /package/src/{share/schemas → schemas}/section-shell.ts +0 -0
  359. /package/src/{share/schemas → schemas}/section-stats.ts +0 -0
  360. /package/src/{share/schemas → schemas}/site-background.ts +0 -0
  361. /package/src/{share/schemas → schemas}/tests/claim-records.test.ts +0 -0
  362. /package/src/{share/schemas → schemas}/tests/claims.test.ts +0 -0
  363. /package/src/{share/schemas → schemas}/tests/effects.test.ts +0 -0
  364. /package/src/{share/schemas → schemas}/tests/features.test.ts +0 -0
  365. /package/src/{share/schemas → schemas}/tests/horizontal-align.test.ts +0 -0
  366. /package/src/{share/schemas → schemas}/tests/icon-color.test.ts +0 -0
  367. /package/src/{share/schemas → schemas}/tests/live-photo.test.ts +0 -0
  368. /package/src/{share/schemas → schemas}/tests/material-credit.test.ts +0 -0
  369. /package/src/{share/schemas → schemas}/tests/media.test.ts +0 -0
  370. /package/src/{share/schemas → schemas}/tests/navigation.test.ts +0 -0
  371. /package/src/{share/schemas → schemas}/tests/page-base.test.ts +0 -0
  372. /package/src/{share/schemas → schemas}/tests/participant.test.ts +0 -0
  373. /package/src/{share/schemas → schemas}/tests/person.test.ts +0 -0
  374. /package/src/{share/schemas → schemas}/tests/print.test.ts +0 -0
  375. /package/src/{share/schemas → schemas}/tests/section-background.test.ts +0 -0
  376. /package/src/{share/schemas → schemas}/tests/section-body.test.ts +0 -0
  377. /package/src/{share/schemas → schemas}/tests/section-cards.test.ts +0 -0
  378. /package/src/{share/schemas → schemas}/tests/section-cta.test.ts +0 -0
  379. /package/src/{share/schemas → schemas}/tests/section-header.test.ts +0 -0
  380. /package/src/{share/schemas → schemas}/tests/section-image.test.ts +0 -0
  381. /package/src/{share/schemas → schemas}/tests/section-motion.test.ts +0 -0
  382. /package/src/{share/schemas → schemas}/tests/section-shell.test.ts +0 -0
  383. /package/src/{share/schemas → schemas}/tests/section-stats.test.ts +0 -0
  384. /package/src/{share/schemas → schemas}/tests/site-background.test.ts +0 -0
  385. /package/src/{share/schemas → schemas}/tests/standard-list-item.test.ts +0 -0
  386. /package/src/{share/semantic → semantic}/ai.ts +0 -0
  387. /package/src/{share/semantic → semantic}/block-extraction.ts +0 -0
  388. /package/src/{share/semantic → semantic}/breadcrumbs.ts +0 -0
  389. /package/src/{share/semantic → semantic}/build-page.ts +0 -0
  390. /package/src/{share/semantic → semantic}/feed.ts +0 -0
  391. /package/src/{share/semantic → semantic}/image-sitemap.ts +0 -0
  392. /package/src/{share/semantic → semantic}/jsonld/article.ts +0 -0
  393. /package/src/{share/semantic → semantic}/jsonld/collection-list.ts +0 -0
  394. /package/src/{share/semantic → semantic}/jsonld/tests/article.test.ts +0 -0
  395. /package/src/{share/semantic → semantic}/jsonld/tests/breadcrumb.test.ts +0 -0
  396. /package/src/{share/semantic → semantic}/jsonld/tests/collection-list.test.ts +0 -0
  397. /package/src/{share/semantic → semantic}/jsonld/tests/faq.test.ts +0 -0
  398. /package/src/{share/semantic → semantic}/jsonld/tests/initiative.test.ts +0 -0
  399. /package/src/{share/semantic → semantic}/jsonld/tests/organization.test.ts +0 -0
  400. /package/src/{share/semantic → semantic}/jsonld/tests/person.test.ts +0 -0
  401. /package/src/{share/semantic → semantic}/jsonld/tests/service.test.ts +0 -0
  402. /package/src/{share/semantic → semantic}/jsonld/tests/shared.test.ts +0 -0
  403. /package/src/{share/semantic → semantic}/jsonld/tests/video.test.ts +0 -0
  404. /package/src/{share/semantic → semantic}/jsonld/tests/webpage.test.ts +0 -0
  405. /package/src/{share/semantic → semantic}/jsonld/tests/website.test.ts +0 -0
  406. /package/src/{share/semantic → semantic}/jsonld/video.ts +0 -0
  407. /package/src/{share/semantic → semantic}/llms-policy.ts +0 -0
  408. /package/src/{share/semantic → semantic}/markdown-hygiene.ts +0 -0
  409. /package/src/{share/semantic → semantic}/output-projection.ts +0 -0
  410. /package/src/{share/semantic → semantic}/page-markdown.ts +0 -0
  411. /package/src/{share/semantic → semantic}/price-marker-resolver.ts +0 -0
  412. /package/src/{share/semantic → semantic}/robots.ts +0 -0
  413. /package/src/{share/semantic → semantic}/tests/ai.test.ts +0 -0
  414. /package/src/{share/semantic → semantic}/tests/block-extraction.test.ts +0 -0
  415. /package/src/{share/semantic → semantic}/tests/breadcrumbs.test.ts +0 -0
  416. /package/src/{share/semantic → semantic}/tests/build-page.test.ts +0 -0
  417. /package/src/{share/semantic → semantic}/tests/feed.test.ts +0 -0
  418. /package/src/{share/semantic → semantic}/tests/helpers.ts +0 -0
  419. /package/src/{share/semantic → semantic}/tests/ids.test.ts +0 -0
  420. /package/src/{share/semantic → semantic}/tests/image-sitemap.test.ts +0 -0
  421. /package/src/{share/semantic → semantic}/tests/jsonld.test.ts +0 -0
  422. /package/src/{share/semantic → semantic}/tests/llms-policy.test.ts +0 -0
  423. /package/src/{share/semantic → semantic}/tests/markdown-hygiene.test.ts +0 -0
  424. /package/src/{share/semantic → semantic}/tests/markdown-page.test.ts +0 -0
  425. /package/src/{share/semantic → semantic}/tests/organization-profile.test.ts +0 -0
  426. /package/src/{share/semantic → semantic}/tests/output-projection.test.ts +0 -0
  427. /package/src/{share/semantic → semantic}/tests/page-markdown.test.ts +0 -0
  428. /package/src/{share/semantic → semantic}/tests/page-utils.test.ts +0 -0
  429. /package/src/{share/semantic → semantic}/tests/robots.test.ts +0 -0
  430. /package/src/{share/semantic → semantic}/tests/update-stamp.test.ts +0 -0
  431. /package/src/{share/semantic → semantic}/update-stamp.ts +0 -0
  432. /package/src/{share/slug → slug}/heading-slugger.ts +0 -0
  433. /package/src/{share/slug → slug}/index.ts +0 -0
  434. /package/src/{share/slug → slug}/slug-id.ts +0 -0
  435. /package/src/{share/slug → slug}/strategies.ts +0 -0
  436. /package/src/{share/slug → slug}/tests/slug.test.ts +0 -0
  437. /package/src/{share → text}/tests/text-normalize.pbt.test.ts +0 -0
  438. /package/src/{share → text}/text-position.ts +0 -0
@@ -12,7 +12,12 @@
12
12
  </MODULE_CONTRACT>
13
13
  <CHANGE_SUMMARY>
14
14
  <item>RFC-0195: initial GEO projection.</item>
15
- <item>Architecture review 2026-07-10: extract blockTwinRegistry so each block type has a registered twin renderer instead of pattern-matching on prop shapes in renderTwin.</item>
15
+ <item>RFC-1097: step 6 — compass.migrate codemod run
16
+
17
+ 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>
18
+ <item>RFC-1097: sweep — werkstatt-engine clean
19
+
20
+ 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
21
  </CHANGE_SUMMARY>
17
22
  */
18
23
 
@@ -6,14 +6,18 @@
6
6
  </non-goals>
7
7
  </MODULE_CONTRACT>
8
8
  <CHANGE_SUMMARY>
9
- <item>RFC-0192: initial barrel.</item>
10
- <item>RFC-0271: export SurfaceModuleContext schema, type, and ownership helpers.</item>
11
- <item>RFC-0276: export Bordbuch event/status schemas and types.</item>
12
- <item>RFC-0280/RFC-0281: export DemandSignal and WerkRecord schemas.</item>
13
- <item>RFC-0278/RFC-0279/RFC-0285: export governance schemas and types.</item>
14
- <item>RFC-0282/RFC-0283: export visibility and breaker schemas.</item>
15
9
  <item>RFC-0284: export fleet Leitstand schemas and types.</item>
16
10
  <item>RFC-0264 cleanup: root barrel delegates governance exports to the governance subpath.</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 — tail packages clean
15
+
16
+ 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>
17
+ <item>RFC-1106: step 5 — merge blueprint triplet
18
+
19
+ surface/blueprint.ts now holds the blueprintSchema (sole declaration), all ~30 contract type names derived via z.infer, parseBlueprint, and the pure helpers. Deleted satellites blueprint-types.ts + blueprint-schema.ts, their package.json export entries, and the zero-consumer site shims (domain/surface/blueprint{,-types,-schema}.ts + 2 load-verification tests). All barrel consumers unchanged.</item>
20
+ <history>RFC-0192, RFC-0271, RFC-0276, RFC-0278, RFC-0280, RFC-0282</history>
17
21
  </CHANGE_SUMMARY>
18
22
  */
19
23
 
@@ -87,7 +91,7 @@ export {
87
91
  type LocalizedString,
88
92
  } from "./blueprint.ts";
89
93
 
90
- export { blueprintSchema, parseBlueprint, type ParseBlueprintResult } from "./blueprint-schema.ts";
94
+ export { blueprintSchema, parseBlueprint, type ParseBlueprintResult } from "./blueprint.ts";
91
95
 
92
96
  // Governance and operational schema bags (RFC-0271..0285) — explicit re-exports.
93
97
  export type {
@@ -46,7 +46,7 @@ export interface SurfaceRecordImage {
46
46
  }
47
47
 
48
48
  /**
49
- * RFC-0192: a block in a baked page. Structurally compatible with `@warpgogol/werkstatt-shared/share` `BlockEntry`, but
49
+ * RFC-0192: a block in a baked page. Structurally compatible with `@warpgogol/werkstatt-shared/page` `BlockEntry`, but
50
50
  * declared here so `@warpgogol/werkstatt-shared/surface` stays the lower-level package with no dependency on share
51
51
  * (avoids a workspace cycle — share consumes surface's route types).
52
52
  */
@@ -60,7 +60,7 @@ export interface SurfaceBlock {
60
60
  layer?: "shell" | "section";
61
61
  }
62
62
 
63
- /** RFC-0192: a baked block-declarative page. Structurally compatible with `@warpgogol/werkstatt-shared/share` `PageEntry`. */
63
+ /** RFC-0192: a baked block-declarative page. Structurally compatible with `@warpgogol/werkstatt-shared/page` `PageEntry`. */
64
64
  export interface PageEntry {
65
65
  kind: "page";
66
66
  cosmicStar: string;
@@ -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,129 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>RFC-0921: Unit tests for the shared signing core — sign/verify round-trip, key generation, canonicalization.</purpose>
4
+ </MODULE_CONTRACT>
5
+ <CHANGE_SUMMARY>
6
+ <item>RFC-0921: initial signing core unit tests.</item>
7
+ </CHANGE_SUMMARY>
8
+ */
9
+
10
+ import { describe, it, expect } from "vitest";
11
+ import {
12
+ generateKeyPair,
13
+ toHex,
14
+ fromHex,
15
+ toPem,
16
+ fromPem,
17
+ canonicalBytes,
18
+ signBytes,
19
+ verifyBytes,
20
+ sign,
21
+ verify,
22
+ } from "../signing/index.ts";
23
+
24
+ describe("signing core — key generation", () => {
25
+ it("generates a valid Ed25519 keypair (32-byte private + 32-byte public)", async () => {
26
+ const keyPair = await generateKeyPair();
27
+ expect(keyPair.privateKey).toBeInstanceOf(Uint8Array);
28
+ expect(keyPair.publicKey).toBeInstanceOf(Uint8Array);
29
+ expect(keyPair.privateKey.length).toBe(32);
30
+ expect(keyPair.publicKey.length).toBe(32);
31
+ });
32
+
33
+ it("generates unique keypairs on each call", async () => {
34
+ const a = await generateKeyPair();
35
+ const b = await generateKeyPair();
36
+ expect(toHex(a.privateKey)).not.toBe(toHex(b.privateKey));
37
+ expect(toHex(a.publicKey)).not.toBe(toHex(b.publicKey));
38
+ });
39
+ });
40
+
41
+ describe("signing core — encoding helpers", () => {
42
+ it("toHex / fromHex round-trip", () => {
43
+ const bytes = new Uint8Array([0, 1, 2, 255, 128, 64]);
44
+ const hex = toHex(bytes);
45
+ expect(hex).toBe("000102ff8040");
46
+ expect(fromHex(hex)).toEqual(bytes);
47
+ });
48
+
49
+ it("toPem / fromPem round-trip for private key", () => {
50
+ const bytes = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
51
+ const pem = toPem(bytes, "private");
52
+ expect(pem).toContain("-----BEGIN" + " PRIVATE KEY-----");
53
+ expect(pem).toContain("-----END" + " PRIVATE KEY-----");
54
+ expect(fromPem(pem)).toEqual(bytes);
55
+ });
56
+
57
+ it("toPem / fromPem round-trip for public key", () => {
58
+ const bytes = new Uint8Array([10, 20, 30, 40, 50, 60, 70, 80]);
59
+ const pem = toPem(bytes, "public");
60
+ expect(pem).toContain("-----BEGIN" + " PUBLIC KEY-----");
61
+ expect(pem).toContain("-----END" + " PUBLIC KEY-----");
62
+ expect(fromPem(pem)).toEqual(bytes);
63
+ });
64
+ });
65
+
66
+ describe("signing core — sign/verify", () => {
67
+ it("sign and verify round-trip with payload", async () => {
68
+ const keyPair = await generateKeyPair();
69
+ const payload = { buildId: "test-123", signedAt: "2026-08-22T00:00:00Z", outputsDigest: "abc" };
70
+ const signature = await sign(keyPair.privateKey, payload);
71
+ expect(signature).toBeInstanceOf(Uint8Array);
72
+ expect(signature.length).toBe(64);
73
+
74
+ const valid = await verify(keyPair.publicKey, payload, signature);
75
+ expect(valid).toBe(true);
76
+ });
77
+
78
+ it("verification fails with tampered payload", async () => {
79
+ const keyPair = await generateKeyPair();
80
+ const payload = { buildId: "test-123", signedAt: "2026-08-22" };
81
+ const signature = await sign(keyPair.privateKey, payload);
82
+
83
+ const tampered = { buildId: "tampered", signedAt: "2026-08-22" };
84
+ const valid = await verify(keyPair.publicKey, tampered, signature);
85
+ expect(valid).toBe(false);
86
+ });
87
+
88
+ it("verification fails with wrong public key", async () => {
89
+ const keyPairA = await generateKeyPair();
90
+ const keyPairB = await generateKeyPair();
91
+ const payload = { test: "data" };
92
+ const signature = await sign(keyPairA.privateKey, payload);
93
+
94
+ const valid = await verify(keyPairB.publicKey, payload, signature);
95
+ expect(valid).toBe(false);
96
+ });
97
+
98
+ it("signBytes / verifyBytes round-trip with raw message", async () => {
99
+ const keyPair = await generateKeyPair();
100
+ const message = new TextEncoder().encode("hello world");
101
+ const signature = await signBytes(keyPair.privateKey, message);
102
+ expect(signature.length).toBe(64);
103
+
104
+ const valid = await verifyBytes(keyPair.publicKey, message, signature);
105
+ expect(valid).toBe(true);
106
+ });
107
+
108
+ it("verifyBytes returns false on invalid signature (not throw)", async () => {
109
+ const keyPair = await generateKeyPair();
110
+ const message = new TextEncoder().encode("test");
111
+ const badSignature = new Uint8Array(64);
112
+ const valid = await verifyBytes(keyPair.publicKey, message, badSignature);
113
+ expect(valid).toBe(false);
114
+ });
115
+ });
116
+
117
+ describe("signing core — canonicalBytes", () => {
118
+ it("produces deterministic bytes regardless of key order", () => {
119
+ const a = canonicalBytes({ b: 2, a: 1, c: 3 });
120
+ const b = canonicalBytes({ a: 1, c: 3, b: 2 });
121
+ expect(a).toEqual(b);
122
+ });
123
+
124
+ it("produces different bytes for different payloads", () => {
125
+ const a = canonicalBytes({ a: 1 });
126
+ const b = canonicalBytes({ a: 2 });
127
+ expect(a).not.toEqual(b);
128
+ });
129
+ });
@@ -13,7 +13,12 @@ disagree on equality.
13
13
  </non-goals>
14
14
  </MODULE_CONTRACT>
15
15
  <CHANGE_SUMMARY>
16
- <item>Initial: unified normalizeCssValue from site-kernel-codegen and site-kernel-checks.</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>
17
22
  </CHANGE_SUMMARY>
18
23
  */
19
24
 
@@ -0,0 +1,24 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Maintains packages/share/src/string-utils.ts as an authored share authored module so agents can evolve it without rediscovering local boundaries.</purpose>
4
+ <non-goals>
5
+ <item>Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file.</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
+ /** Lowercase, dash-only kebab-case. Strips leading/trailing hyphens. */
19
+ export function toKebabCase(value: string): string {
20
+ return value
21
+ .toLowerCase()
22
+ .replace(/[^a-z0-9]+/g, "-")
23
+ .replace(/^-+|-+$/g, "");
24
+ }
@@ -36,6 +36,11 @@ test("quotes: curly + guillemets become straight", () => {
36
36
  expect(normalizeText(input, ALL_ON)).toBe(`"hi" "yo" it's 'a' "de"`);
37
37
  });
38
38
 
39
+ test("quotes: U+02BC modifier letter apostrophe becomes straight (RFC-1070)", () => {
40
+ const input = "it\u02BCs";
41
+ expect(normalizeText(input, ALL_ON)).toBe("it's");
42
+ });
43
+
39
44
  test("ellipsis: single char becomes three dots", () => {
40
45
  expect(normalizeText("wait…", ALL_ON)).toBe("wait...");
41
46
  });
@@ -18,6 +18,7 @@ never touched; this only transforms output strings.
18
18
  <CHANGE_SUMMARY>
19
19
  <item>RFC-0235: initial egress text normalizer.</item>
20
20
  <item>RFC-0569: add createDevNormalizeMiddleware for dev/prod egress parity.</item>
21
+ <item>RFC-1070: add U+02BC modifier letter apostrophe to quotes signal.</item>
21
22
  </CHANGE_SUMMARY>
22
23
  */
23
24
 
@@ -72,7 +73,7 @@ export const SIGNAL_REGISTRY: readonly SignalSpec[] = [
72
73
  {
73
74
  id: "quotes",
74
75
  title: "Typographic / smart quotes",
75
- unicode: "U+00AB U+00BB U+2018-U+201F",
76
+ unicode: "U+00AB U+00BB U+2018-U+201F U+02BC",
76
77
  replacement: "straight double / single quote",
77
78
  default: true,
78
79
  },
@@ -148,8 +149,8 @@ export function resolveNormalizeConfig(manifest: unknown): NormalizeConfig {
148
149
  const RE_DASHES = /[‐‑‒–—―−]/g;
149
150
  // U+00AB U+00BB U+201C U+201D U+201E U+201F
150
151
  const RE_QUOTES_DOUBLE = /[«»“”„‟]/g;
151
- // U+2018 U+2019 U+201A U+201B
152
- const RE_QUOTES_SINGLE = /[‘’‚‛]/g;
152
+ // U+2018 U+2019 U+201A U+201B U+02BC (modifier letter apostrophe, RFC-1070)
153
+ const RE_QUOTES_SINGLE = /[‘’‚‛ʼ]/g;
153
154
  const RE_ELLIPSIS = /…/g;
154
155
  // U+00A0 nbsp, U+1680 ogham, U+2000-U+200A, U+202F narrow nbsp, U+205F medium math,
155
156
  // U+3000 ideographic space.
@@ -8,7 +8,7 @@
8
8
  </non-goals>
9
9
  </MODULE_CONTRACT>
10
10
  <CHANGE_SUMMARY>
11
- <item>RFC-0041: Created as SSR inline number pre-wrap utility in @warpgogol/werkstatt-shared/share.</item>
11
+ <item>RFC-0041: Created as SSR inline number pre-wrap utility in @warpgogol/werkstatt-shared/text.</item>
12
12
  </CHANGE_SUMMARY>
13
13
  */
14
14
 
@@ -0,0 +1,36 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>axiom-study.d.ts — ambient module declaration for the external @syrokomskyi/axiom-study package types.</purpose>
4
+ <non-goals>
5
+ <item>Do not implement runtime code — this file only declares types for an external package.</item>
6
+ </non-goals>
7
+ </MODULE_CONTRACT>
8
+ <CHANGE_SUMMARY>
9
+ <item>RFC-1097: sweep — tail packages clean
10
+
11
+ 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>
12
+ </CHANGE_SUMMARY>
13
+ */
14
+
15
+ declare module "@syrokomskyi/axiom-study" {
16
+ export interface Finding {
17
+ findingId: string;
18
+ semanticFingerprint: { algorithm: "sha256"; digest: string; size: number; mediaType: string };
19
+ methodologyId: string;
20
+ ruleId: string;
21
+ affectedSubjectId: string;
22
+ title: string;
23
+ severity: "info" | "low" | "medium" | "high" | "critical";
24
+ evidence: Array<{
25
+ evidenceRef: {
26
+ artifactId: string;
27
+ rootDigest: { algorithm: "sha256"; digest: string; size: number; mediaType: string };
28
+ schema: string;
29
+ };
30
+ selector: string;
31
+ evidenceClass: string;
32
+ }>;
33
+ uncertainty: unknown[];
34
+ extension: Record<string, unknown>;
35
+ }
36
+ }
@@ -0,0 +1,21 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Type shim for the official `hls.js/light` export used by the lazy feature-video runtime.</purpose>
4
+ <non-goals>
5
+ <item>Do not change runtime resolution; this file only fills the missing package declaration.</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
+ declare module "hls.js/light" {
19
+ export { default } from "hls.js";
20
+ export * from "hls.js";
21
+ }
@@ -0,0 +1,23 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Type shim for the qrcode browser entry point (qrcode/lib/browser.js).
4
+ The qrcode package only ships types for its main entry, but the browser entry
5
+ exports the same toCanvas function. This shim re-exports all types from qrcode
6
+ so the client-side QR code script gets full type safety.</purpose>
7
+ <non-goals>
8
+ <item>Do not change runtime resolution; this file only fills the missing package declaration.</item>
9
+ </non-goals>
10
+ </MODULE_CONTRACT>
11
+ <CHANGE_SUMMARY>
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
+ declare module "qrcode/lib/browser.js" {
22
+ export * from "qrcode";
23
+ }
@@ -0,0 +1,208 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import fc from "fast-check";
3
+ import { applyFixes, FIXABLE_RULE_IDS, isFixable } from "./fix.ts";
4
+ import {
5
+ TIER1_RULES,
6
+ createTypographyContext,
7
+ type TypographyFinding,
8
+ type TypographyRule,
9
+ } from "./rules-tier1.ts";
10
+ import { TIER2_LOCALE_RULES } from "./rules-tier2-locale.ts";
11
+ import type { TextSegment } from "./text-surface.ts";
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Helpers
15
+ // ---------------------------------------------------------------------------
16
+
17
+ function makeSegment(text: string, locale = "de"): TextSegment {
18
+ return {
19
+ file: "test.md",
20
+ line: 1,
21
+ path: "$body",
22
+ source: "body",
23
+ text,
24
+ raw: text,
25
+ isTableRow: false,
26
+ locale,
27
+ };
28
+ }
29
+
30
+ const ALL_FIXABLE_RULES: readonly TypographyRule[] = [...TIER1_RULES, ...TIER2_LOCALE_RULES].filter(
31
+ (rule) => isFixable(rule.id),
32
+ );
33
+
34
+ function runFixableRules(text: string, locale: string): TypographyFinding[] {
35
+ const segment = makeSegment(text, locale);
36
+ const ctx = createTypographyContext(locale, new Set());
37
+ const findings: TypographyFinding[] = [];
38
+ for (const rule of ALL_FIXABLE_RULES) {
39
+ if (rule.id === "TYPO-ABBR-02" && locale !== "de") continue;
40
+ if ((rule.id === "TYPO-APOS-01" || rule.id === "TYPO-APOS-02") && locale !== "uk") continue;
41
+ findings.push(...rule.check(segment, ctx));
42
+ }
43
+ return findings;
44
+ }
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Property tests (DNA-101: idempotency)
48
+ // ---------------------------------------------------------------------------
49
+
50
+ describe("Fix engine — property-based tests (RFC-1072, DNA-101)", () => {
51
+ it("FIXABLE_RULE_IDS contains exactly 7 rule IDs", () => {
52
+ expect(FIXABLE_RULE_IDS).toHaveLength(7);
53
+ expect(FIXABLE_RULE_IDS).toContain("TYPO-PUNCT-01");
54
+ expect(FIXABLE_RULE_IDS).toContain("TYPO-SPACE-01");
55
+ expect(FIXABLE_RULE_IDS).toContain("TYPO-SPACE-02");
56
+ expect(FIXABLE_RULE_IDS).toContain("TYPO-APOS-01");
57
+ expect(FIXABLE_RULE_IDS).toContain("TYPO-APOS-02");
58
+ expect(FIXABLE_RULE_IDS).toContain("TYPO-ABBR-01");
59
+ expect(FIXABLE_RULE_IDS).toContain("TYPO-ABBR-02");
60
+ });
61
+
62
+ it("isFixable returns true only for whitelisted rules", () => {
63
+ for (const id of FIXABLE_RULE_IDS) {
64
+ expect(isFixable(id)).toBe(true);
65
+ }
66
+ expect(isFixable("TYPO-PUNCT-02")).toBe(false);
67
+ expect(isFixable("TYPO-CASE-01")).toBe(false);
68
+ expect(isFixable("TYPO-UNICODE-01")).toBe(false);
69
+ });
70
+
71
+ it("applyFixes is idempotent: fixing an already-fixed text produces no new fixes", () => {
72
+ fc.assert(
73
+ fc.property(
74
+ fc.oneof(
75
+ fc.constant("Hello world"), // SPACE-01
76
+ fc.constant("Hello "), // SPACE-02
77
+ fc.constant("Hello,, world"), // PUNCT-01
78
+ fc.constant("Hello:: world"), // PUNCT-01
79
+ fc.constant("z.B. Hallo"), // ABBR-02 (de)
80
+ fc.constant("z. B. Hallo"), // already fixed ABBR-02
81
+ ),
82
+ (text) => {
83
+ const findings1 = runFixableRules(text, "de");
84
+ const { fixedSegments } = applyFixes(findings1, createTypographyContext("de", new Set()));
85
+ const fixedText = fixedSegments.get("test.md:1:$body") ?? text;
86
+
87
+ // Running fixable rules on the fixed text should produce zero fixable findings
88
+ const findings2 = runFixableRules(fixedText, "de");
89
+ const fixableFindings2 = findings2.filter((f) => f.fix !== null);
90
+ expect(fixableFindings2).toHaveLength(0);
91
+ },
92
+ ),
93
+ { numRuns: 100 },
94
+ );
95
+ });
96
+
97
+ it("applyFixes with no fixable findings returns empty map", () => {
98
+ const findings: TypographyFinding[] = [];
99
+ const ctx = createTypographyContext("de", new Set());
100
+ const result = applyFixes(findings, ctx);
101
+ expect(result.fixedSegments.size).toBe(0);
102
+ expect(result.fixCount).toBe(0);
103
+ });
104
+
105
+ it("applyFixes skips findings with fix: null", () => {
106
+ const segment = makeSegment("Hello world", "de");
107
+ const findings: TypographyFinding[] = [
108
+ {
109
+ ruleId: "TYPO-PUNCT-02",
110
+ segment,
111
+ match: "..",
112
+ column: 5,
113
+ message: "test",
114
+ fixHint: "test",
115
+ fix: null,
116
+ },
117
+ ];
118
+ const ctx = createTypographyContext("de", new Set());
119
+ const result = applyFixes(findings, ctx);
120
+ expect(result.fixedSegments.size).toBe(0);
121
+ expect(result.fixCount).toBe(0);
122
+ });
123
+
124
+ it("replace action replaces the match at the given column", () => {
125
+ const segment = makeSegment("Hello,, world", "de");
126
+ const findings: TypographyFinding[] = [
127
+ {
128
+ ruleId: "TYPO-PUNCT-01",
129
+ segment,
130
+ match: ",,",
131
+ column: 5,
132
+ message: "test",
133
+ fixHint: "test",
134
+ fix: { type: "replace", old: ",,", new: "," },
135
+ },
136
+ ];
137
+ const ctx = createTypographyContext("de", new Set());
138
+ const result = applyFixes(findings, ctx);
139
+ const fixed = result.fixedSegments.get("test.md:1:$body");
140
+ expect(fixed).toBe("Hello, world");
141
+ });
142
+
143
+ it("insert action inserts text at the specified position", () => {
144
+ const segment = makeSegment("zB Hallo", "de");
145
+ const findings: TypographyFinding[] = [
146
+ {
147
+ ruleId: "TYPO-ABBR-01",
148
+ segment,
149
+ match: "zB",
150
+ column: 0,
151
+ message: "test",
152
+ fixHint: "test",
153
+ fix: { type: "insert", at: 2, text: "." },
154
+ },
155
+ ];
156
+ const ctx = createTypographyContext("de", new Set());
157
+ const result = applyFixes(findings, ctx);
158
+ const fixed = result.fixedSegments.get("test.md:1:$body");
159
+ expect(fixed).toBe("zB. Hallo");
160
+ });
161
+
162
+ it("delete action removes characters at the specified position", () => {
163
+ const segment = makeSegment("Hello ", "de");
164
+ const findings: TypographyFinding[] = [
165
+ {
166
+ ruleId: "TYPO-SPACE-02",
167
+ segment,
168
+ match: " ",
169
+ column: 5,
170
+ message: "test",
171
+ fixHint: "test",
172
+ fix: { type: "delete", at: 5, length: 3 },
173
+ },
174
+ ];
175
+ const ctx = createTypographyContext("de", new Set());
176
+ const result = applyFixes(findings, ctx);
177
+ const fixed = result.fixedSegments.get("test.md:1:$body");
178
+ expect(fixed).toBe("Hello");
179
+ });
180
+
181
+ it("multiple fixes in the same segment are applied correctly (right-to-left)", () => {
182
+ const segment = makeSegment("Hello,, world", "de");
183
+ const findings: TypographyFinding[] = [
184
+ {
185
+ ruleId: "TYPO-PUNCT-01",
186
+ segment,
187
+ match: ",,",
188
+ column: 5,
189
+ message: "test",
190
+ fixHint: "test",
191
+ fix: { type: "replace", old: ",,", new: "," },
192
+ },
193
+ {
194
+ ruleId: "TYPO-SPACE-01",
195
+ segment,
196
+ match: " w",
197
+ column: 7,
198
+ message: "test",
199
+ fixHint: "test",
200
+ fix: { type: "replace", old: " w", new: " w" },
201
+ },
202
+ ];
203
+ const ctx = createTypographyContext("de", new Set());
204
+ const result = applyFixes(findings, ctx);
205
+ const fixed = result.fixedSegments.get("test.md:1:$body");
206
+ expect(fixed).toBe("Hello, world");
207
+ });
208
+ });