@warpgogol/werkstatt-shared 0.13.0 → 0.14.1

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 (178) hide show
  1. package/README.md +26 -16
  2. package/README.uk.md +24 -14
  3. package/package.json +27 -69
  4. package/src/checks/result-helpers.ts +21 -4
  5. package/src/checks/tests/remediation-auto-populate.test.ts +83 -0
  6. package/src/integration/funnel.ts +78 -1
  7. package/src/integration/index.ts +19 -2
  8. package/src/integration/lagebild-ingress.ts +169 -0
  9. package/src/integration/orchestration.ts +7 -13
  10. package/src/integration/port-barrel.ts +9 -28
  11. package/src/integration/tests/funnel-bridge.test.ts +7 -7
  12. package/src/integration/tests/lagebild-ingress.test.ts +118 -0
  13. package/src/integration/vitest.config.ts +7 -0
  14. package/src/observability/typed-refs.ts +1 -1
  15. package/src/ontology/analytics/matomo-fleet.registry.yaml +1 -1
  16. package/src/ontology/archetypes/index.json +12 -9
  17. package/src/ontology/archetypes/index.yaml +26 -10
  18. package/src/ontology/blueprints/website-local.yaml +11 -11
  19. package/src/ontology/blueprints/website-service.yaml +20 -20
  20. package/src/ontology/capabilities/lead.submit.yaml +2 -2
  21. package/src/ontology/enums.ts +2 -2
  22. package/src/ontology/external-surfaces/jsonld-types.yaml +14 -14
  23. package/src/ontology/external-surfaces/url-schema.yaml +1 -1
  24. package/src/ontology/index.ts +2 -0
  25. package/src/ontology/manifest.ts +19 -0
  26. package/src/ontology/schemas/index.ts +7 -2
  27. package/src/ontology/schemas/system/integrations.ts +1 -1
  28. package/src/ontology/schemas/system/manifest.ts +38 -1
  29. package/src/ontology/schemas/system/tests/growth.test.ts +22 -0
  30. package/src/ontology/schemas/system/tests/integrations.test.ts +12 -0
  31. package/src/ontology/schemas/system/tests/manifest.test.ts +22 -0
  32. package/src/ontology/schemas/system/tests/page-output.test.ts +13 -0
  33. package/src/ontology/schemas/system/tests/release.test.ts +22 -0
  34. package/src/ontology/schemas/system/tests/text.test.ts +18 -0
  35. package/src/ontology/schemas/system/tests/verification.test.ts +12 -0
  36. package/src/ontology/schemas/system.ts +7 -2
  37. package/src/ontology/schemas/tests/biome.test.ts +19 -0
  38. package/src/ontology/schemas/tests/capability.test.ts +22 -0
  39. package/src/ontology/schemas/tests/constellation.test.ts +22 -0
  40. package/src/ontology/schemas/tests/dns-records.test.ts +13 -0
  41. package/src/ontology/schemas/tests/manifest-resolver.test.ts +13 -0
  42. package/src/ontology/schemas/tests/page-entry.test.ts +22 -0
  43. package/src/ontology/schemas/tests/section-archetype.test.ts +12 -0
  44. package/src/ontology/schemas/tests/site-family.test.ts +18 -0
  45. package/src/ontology/schemas/tests/system.test.ts +20 -0
  46. package/src/ontology/shared-section-props/common.ts +11 -0
  47. package/src/ontology/shared-section-props/visual-header.ts +1 -1
  48. package/src/share/agent/api-catalog.ts +5 -0
  49. package/src/share/agent/ard-catalog.ts +14 -0
  50. package/src/share/agent/index.ts +2 -0
  51. package/src/share/agent/manifest.ts +25 -2
  52. package/src/share/agent/mcp-card.ts +4 -0
  53. package/src/share/agent/openapi.ts +78 -0
  54. package/src/share/agent/search.test.ts +188 -0
  55. package/src/share/agent/search.ts +164 -0
  56. package/src/share/agent/tests/api-catalog.test.ts +8 -0
  57. package/src/share/agent/tests/ard-catalog.test.ts +8 -0
  58. package/src/share/agent/tests/capability.test.ts +14 -0
  59. package/src/share/agent/tests/fleet-catalog.test.ts +15 -0
  60. package/src/share/agent/tests/knowledge.test.ts +20 -0
  61. package/src/share/agent/tests/manifest.test.ts +9 -0
  62. package/src/share/agent/tests/mcp-card.test.ts +8 -0
  63. package/src/share/agent/tests/omit-empty.test.ts +33 -0
  64. package/src/share/agent/tests/openapi.test.ts +8 -0
  65. package/src/share/agent/tests/proof.test.ts +15 -0
  66. package/src/share/env.d.ts +0 -4
  67. package/src/share/knowledge/tests/claim.test.ts +11 -0
  68. package/src/share/knowledge/tests/derivation.test.ts +30 -0
  69. package/src/share/knowledge/tests/freshness.test.ts +18 -0
  70. package/src/share/knowledge/tests/ledger.test.ts +35 -0
  71. package/src/share/knowledge/tests/plan.test.ts +19 -0
  72. package/src/share/knowledge/tests/source.test.ts +19 -0
  73. package/src/share/remediation/remediation-catalog.ts +196 -0
  74. package/src/share/schemas/effects.ts +16 -0
  75. package/src/share/schemas/media.ts +4 -0
  76. package/src/share/schemas/section-shell.ts +2 -1
  77. package/src/share/schemas/tests/claim-records.test.ts +52 -0
  78. package/src/share/schemas/tests/claims.test.ts +23 -0
  79. package/src/share/schemas/tests/effects.test.ts +116 -0
  80. package/src/share/schemas/tests/features.test.ts +61 -0
  81. package/src/share/schemas/tests/horizontal-align.test.ts +16 -0
  82. package/src/share/schemas/tests/icon-color.test.ts +16 -0
  83. package/src/share/schemas/tests/live-photo.test.ts +40 -0
  84. package/src/share/schemas/tests/material-credit.test.ts +51 -0
  85. package/src/share/schemas/tests/media.test.ts +26 -0
  86. package/src/share/schemas/tests/navigation.test.ts +58 -0
  87. package/src/share/schemas/tests/page-base.test.ts +19 -0
  88. package/src/share/schemas/tests/participant.test.ts +26 -0
  89. package/src/share/schemas/tests/person.test.ts +12 -0
  90. package/src/share/schemas/tests/print.test.ts +30 -0
  91. package/src/share/schemas/tests/section-background.test.ts +31 -0
  92. package/src/share/schemas/tests/section-body.test.ts +16 -0
  93. package/src/share/schemas/tests/section-cards.test.ts +17 -0
  94. package/src/share/schemas/tests/section-cta.test.ts +41 -0
  95. package/src/share/schemas/tests/section-header.test.ts +31 -0
  96. package/src/share/schemas/tests/section-image.test.ts +24 -0
  97. package/src/share/schemas/tests/section-motion.test.ts +29 -0
  98. package/src/share/schemas/tests/section-shell.test.ts +42 -0
  99. package/src/share/schemas/tests/section-stats.test.ts +17 -0
  100. package/src/share/schemas/tests/site-background.test.ts +33 -0
  101. package/src/share/schemas/tests/standard-list-item.test.ts +16 -0
  102. package/src/share/scripts/external-link-qr.ts +9 -1
  103. package/src/share/scripts/gsap-counter.ts +2 -0
  104. package/src/share/scripts/inline-number-animation.ts +2 -0
  105. package/src/share/scripts/live-photos.ts +2 -0
  106. package/src/share/scripts/tests/external-link-qr.test.ts +8 -0
  107. package/src/share/scripts/tests/external-links.test.ts +25 -0
  108. package/src/share/scripts/tests/gsap-counter.test.ts +8 -0
  109. package/src/share/scripts/tests/gsap-mountain-journey.test.ts +8 -0
  110. package/src/share/scripts/tests/gsap-parallax.test.ts +8 -0
  111. package/src/share/scripts/tests/gsap-reveal.test.ts +8 -0
  112. package/src/share/scripts/tests/gsap-stagger.test.ts +8 -0
  113. package/src/share/scripts/tests/inline-number-animation.test.ts +8 -0
  114. package/src/share/scripts/tests/lenis.test.ts +8 -0
  115. package/src/share/scripts/tests/live-photos.test.ts +8 -0
  116. package/src/share/scripts/tests/lordicon.test.ts +8 -0
  117. package/src/share/scripts/tests/orchestrator.test.ts +8 -0
  118. package/src/share/scripts/tests/scheduler.test.ts +23 -0
  119. package/src/share/scripts/video-player.test.ts +210 -0
  120. package/src/share/scripts/video-player.ts +73 -13
  121. package/src/share/semantic/extract.ts +25 -1
  122. package/src/share/semantic/jsonld/tests/article.test.ts +89 -0
  123. package/src/share/semantic/jsonld/tests/breadcrumb.test.ts +62 -0
  124. package/src/share/semantic/jsonld/tests/collection-list.test.ts +39 -0
  125. package/src/share/semantic/jsonld/tests/faq.test.ts +60 -0
  126. package/src/share/semantic/jsonld/tests/initiative.test.ts +56 -0
  127. package/src/share/semantic/jsonld/tests/organization.test.ts +123 -0
  128. package/src/share/semantic/jsonld/tests/person.test.ts +89 -0
  129. package/src/share/semantic/jsonld/tests/service.test.ts +65 -0
  130. package/src/share/semantic/jsonld/tests/shared.test.ts +41 -0
  131. package/src/share/semantic/jsonld/tests/video.test.ts +84 -0
  132. package/src/share/semantic/jsonld/tests/webpage.test.ts +93 -0
  133. package/src/share/semantic/jsonld/tests/website.test.ts +27 -0
  134. package/src/share/semantic/jsonld/types.ts +1 -0
  135. package/src/share/semantic/models.ts +1 -0
  136. package/src/share/semantic/tests/ai.test.ts +55 -0
  137. package/src/share/semantic/tests/block-extraction.test.ts +34 -0
  138. package/src/share/semantic/tests/breadcrumbs.test.ts +127 -0
  139. package/src/share/semantic/tests/build-page.test.ts +122 -0
  140. package/src/share/semantic/tests/business-projection.test.ts +188 -0
  141. package/src/share/semantic/tests/derived-prices-loader.test.ts +46 -0
  142. package/src/share/semantic/tests/extract.test.ts +126 -0
  143. package/src/share/semantic/tests/feed.test.ts +113 -0
  144. package/src/share/semantic/tests/helpers.ts +32 -0
  145. package/src/share/semantic/tests/ids.test.ts +118 -0
  146. package/src/share/semantic/tests/image-sitemap.test.ts +109 -0
  147. package/src/share/semantic/tests/jsonld.test.ts +61 -0
  148. package/src/share/semantic/tests/llms-policy.test.ts +60 -0
  149. package/src/share/semantic/tests/llms.test.ts +118 -0
  150. package/src/share/semantic/tests/markdown-hygiene.test.ts +72 -0
  151. package/src/share/semantic/tests/markdown-page.test.ts +97 -0
  152. package/src/share/semantic/tests/markdown-twin-provenance.test.ts +152 -0
  153. package/src/share/semantic/tests/organization-profile.test.ts +107 -0
  154. package/src/share/semantic/tests/output-projection.test.ts +77 -0
  155. package/src/share/semantic/tests/page-markdown.test.ts +98 -0
  156. package/src/share/semantic/tests/page-utils.test.ts +88 -0
  157. package/src/share/semantic/tests/price-marker-resolver.test.ts +88 -0
  158. package/src/share/semantic/tests/robots.test.ts +70 -0
  159. package/src/share/semantic/tests/split-sentences.test.ts +57 -0
  160. package/src/share/semantic/tests/update-stamp.test.ts +102 -0
  161. package/src/share/tests/manifest.test.ts +51 -0
  162. package/src/share/tests/openapi.test.ts +30 -0
  163. package/src/share/types/qrcode-browser.d.ts +18 -0
  164. package/src/share/utility-registry.yaml +16 -2
  165. package/src/integration/crm-buffer.ts +0 -491
  166. package/src/integration-adapter-supabase-crm/adapter.ts +0 -437
  167. package/src/integration-adapter-supabase-crm/client.ts +0 -605
  168. package/src/integration-adapter-supabase-crm/index.ts +0 -28
  169. package/src/integration-adapter-supabase-crm/pipedrive-sync-target.ts +0 -482
  170. package/src/integration-adapter-supabase-crm/supabase-rest.ts +0 -89
  171. package/src/integration-adapter-supabase-crm/tenant-registry.ts +0 -334
  172. package/src/integration-adapter-supabase-crm/tests/change-balance.pbt.test.ts +0 -83
  173. package/src/integration-adapter-supabase-crm/tests/funnel-persistence.test.ts +0 -409
  174. package/src/integration-adapter-supabase-crm/tests/lifecycle-sync.test.ts +0 -288
  175. package/src/integration-adapter-supabase-crm/tests/stage-map.test.ts +0 -80
  176. package/src/integration-adapter-supabase-crm/vitest.config.ts +0 -8
  177. package/src/integration-adapter-supabase-crm/worker.ts +0 -223
  178. package/src/ontology/archetypes/components/currency-selector.yaml +0 -19
@@ -0,0 +1,102 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ isValidStampDate,
4
+ resolveAuthoredStamp,
5
+ resolveCklStamp,
6
+ resolvePageUpdateStamp,
7
+ } from "../update-stamp.ts";
8
+
9
+ describe("isValidStampDate", () => {
10
+ it("accepts YYYY-MM-DD", () => {
11
+ expect(isValidStampDate("2024-01-15")).toBe(true);
12
+ });
13
+
14
+ it("rejects non-string", () => {
15
+ expect(isValidStampDate(20240115)).toBe(false);
16
+ });
17
+
18
+ it("rejects wrong format", () => {
19
+ expect(isValidStampDate("2024/01/15")).toBe(false);
20
+ expect(isValidStampDate("January 15, 2024")).toBe(false);
21
+ });
22
+ });
23
+
24
+ describe("resolveAuthoredStamp", () => {
25
+ it("uses output.sitemap.lastmod first", () => {
26
+ const result = resolveAuthoredStamp({
27
+ output: { sitemap: { lastmod: "2024-06-01" } },
28
+ });
29
+ expect(result?.date).toBe("2024-06-01");
30
+ expect(result?.source).toBe("authored-system-output");
31
+ });
32
+
33
+ it("uses article.updatedAt when no sitemap lastmod", () => {
34
+ const result = resolveAuthoredStamp({
35
+ article: { updatedAt: "2024-05-01" },
36
+ });
37
+ expect(result?.date).toBe("2024-05-01");
38
+ expect(result?.source).toBe("authored-page-frontmatter");
39
+ });
40
+
41
+ it("uses article.publishedAt when no updatedAt", () => {
42
+ const result = resolveAuthoredStamp({
43
+ article: { publishedAt: "2024-01-01" },
44
+ });
45
+ expect(result?.date).toBe("2024-01-01");
46
+ });
47
+
48
+ it("returns undefined when no valid dates", () => {
49
+ expect(resolveAuthoredStamp({})).toBeUndefined();
50
+ });
51
+
52
+ it("ignores invalid date formats", () => {
53
+ expect(resolveAuthoredStamp({ article: { updatedAt: "not-a-date" } })).toBeUndefined();
54
+ });
55
+ });
56
+
57
+ describe("resolveCklStamp", () => {
58
+ it("returns latest valid date", () => {
59
+ const result = resolveCklStamp(["2024-01-01", "2024-06-15", "2024-03-01"], ["ledger"]);
60
+ expect(result?.date).toBe("2024-06-15");
61
+ expect(result?.source).toBe("ckl-claim-ledger");
62
+ });
63
+
64
+ it("returns undefined when no valid dates", () => {
65
+ expect(resolveCklStamp(["invalid"], ["ledger"])).toBeUndefined();
66
+ });
67
+ });
68
+
69
+ describe("resolvePageUpdateStamp", () => {
70
+ it("prefers authored stamp over CKL", () => {
71
+ const result = resolvePageUpdateStamp({
72
+ pageId: "p1",
73
+ lang: "de",
74
+ pageEntry: { output: { sitemap: { lastmod: "2024-06-01" } } },
75
+ cklLedgerDates: ["2024-01-01"],
76
+ });
77
+ expect(result.stamp?.date).toBe("2024-06-01");
78
+ expect(result.stamp?.source).toBe("authored-system-output");
79
+ });
80
+
81
+ it("falls back to CKL when no authored stamp", () => {
82
+ const result = resolvePageUpdateStamp({
83
+ pageId: "p1",
84
+ lang: "de",
85
+ pageEntry: {},
86
+ cklLedgerDates: ["2024-03-01"],
87
+ cklInputs: ["ledger"],
88
+ });
89
+ expect(result.stamp?.date).toBe("2024-03-01");
90
+ expect(result.stamp?.source).toBe("ckl-claim-ledger");
91
+ });
92
+
93
+ it("returns missingReason when no sources available", () => {
94
+ const result = resolvePageUpdateStamp({
95
+ pageId: "p1",
96
+ lang: "de",
97
+ pageEntry: {},
98
+ });
99
+ expect(result.stamp).toBeUndefined();
100
+ expect(result.missingReason).toBe("no-content-source");
101
+ });
102
+ });
@@ -8,6 +8,7 @@
8
8
  </MODULE_MAP>
9
9
  <CHANGE_SUMMARY>
10
10
  <item>RFC-0286: initial builder tests.</item>
11
+ <item>RFC-0954: add search interface tests.</item>
11
12
  </CHANGE_SUMMARY>
12
13
  */
13
14
 
@@ -16,6 +17,7 @@ import {
16
17
  AGENT_SURFACE_VERSION,
17
18
  buildAgentSurfaceManifest,
18
19
  computeAgentManifestContentHash,
20
+ computeSignedContentHash,
19
21
  canonicalJson,
20
22
  } from "../agent/manifest.ts";
21
23
 
@@ -38,6 +40,7 @@ test("buildAgentSurfaceManifest: safe default — empty knowledge/actions, null
38
40
  expect(m.interfaces.openapi).toBe(null);
39
41
  expect(m.interfaces.mcp).toBe(null);
40
42
  expect(m.interfaces.twins).toBe(null);
43
+ expect(m.interfaces.search).toBe(null);
41
44
  expect(m.proof).toBe(null);
42
45
  expect(m.surfaceVersion).toBe(AGENT_SURFACE_VERSION);
43
46
  });
@@ -81,6 +84,32 @@ test("buildAgentSurfaceManifest: sorts knowledge refs by domain and actions by i
81
84
  expect(m.actions.map((a) => a.id)).toEqual(["appointment.request", "lead.submit"]);
82
85
  });
83
86
 
87
+ test("buildAgentSurfaceManifest: populates search interface when search input is provided", () => {
88
+ const m = buildAgentSurfaceManifest({
89
+ ...baseInput,
90
+ search: { url: "/api/agent/search", model: "@cf/baai/bge-m3", dimensions: 1024 },
91
+ });
92
+ expect(m.interfaces.search).toEqual({
93
+ url: "/api/agent/search",
94
+ model: "@cf/baai/bge-m3",
95
+ dimensions: 1024,
96
+ });
97
+ });
98
+
99
+ test("buildAgentSurfaceManifest: search interface is null by default", () => {
100
+ const m = buildAgentSurfaceManifest(baseInput);
101
+ expect(m.interfaces.search).toBe(null);
102
+ });
103
+
104
+ test("buildAgentSurfaceManifest: search interface presence changes contentHash", () => {
105
+ const without = buildAgentSurfaceManifest(baseInput);
106
+ const withSearch = buildAgentSurfaceManifest({
107
+ ...baseInput,
108
+ search: { url: "/api/agent/search", model: "@cf/baai/bge-m3", dimensions: 1024 },
109
+ });
110
+ expect(without.contentHash).not.toBe(withSearch.contentHash);
111
+ });
112
+
84
113
  test("computeAgentManifestContentHash: excludes contentHash and proof fields from the hash input", () => {
85
114
  const doc: Record<string, unknown> = { a: 1, b: 2, contentHash: "whatever", proof: { x: 1 } };
86
115
  const withoutHashFields = { a: 1, b: 2 };
@@ -98,3 +127,25 @@ test("canonicalJson: sorts object keys deeply, preserves array order", () => {
98
127
  expect(canonicalJson({ b: 1, a: { d: 2, c: 3 } })).toBe('{"a":{"c":3,"d":2},"b":1}');
99
128
  expect(canonicalJson([3, 1, 2])).toBe("[3,1,2]");
100
129
  });
130
+
131
+ test("computeSignedContentHash: always excludes contentHash and proof", () => {
132
+ const base = { a: 1, b: 2 };
133
+ const withHash = { ...base, contentHash: "abc", proof: { type: "test" } };
134
+ const withDifferentHash = { ...base, contentHash: "xyz", proof: { type: "other" } };
135
+ expect(computeSignedContentHash(withHash)).toBe(computeSignedContentHash(base));
136
+ expect(computeSignedContentHash(withDifferentHash)).toBe(computeSignedContentHash(base));
137
+ });
138
+
139
+ test("computeSignedContentHash: supports additional excludeFields", () => {
140
+ const base = { a: 1, b: 2 };
141
+ const withTimestamp = { ...base, generatedAt: "2026-01-01T00:00:00Z" };
142
+ const withDifferentTimestamp = { ...base, generatedAt: "2026-12-31T23:59:59Z" };
143
+ expect(computeSignedContentHash(withTimestamp, ["generatedAt"])).toBe(
144
+ computeSignedContentHash(withDifferentTimestamp, ["generatedAt"]),
145
+ );
146
+ });
147
+
148
+ test("computeSignedContentHash: matches computeAgentManifestContentHash for same inputs", () => {
149
+ const doc = { a: 1, b: 2, contentHash: "x", proof: null };
150
+ expect(computeSignedContentHash(doc)).toBe(computeAgentManifestContentHash(doc));
151
+ });
@@ -8,6 +8,7 @@
8
8
  </MODULE_MAP>
9
9
  <CHANGE_SUMMARY>
10
10
  <item>RFC-0289: initial OpenAPI formatter tests.</item>
11
+ <item>RFC-0954: add search path projection tests.</item>
11
12
  </CHANGE_SUMMARY>
12
13
  */
13
14
 
@@ -114,3 +115,32 @@ test("formatAgentOpenApi: mcp interface present → x-gogol-mcp is set", () => {
114
115
  const doc = formatAgentOpenApi(manifest, []);
115
116
  expect(doc["x-gogol-mcp"]).toEqual({ url: "/api/agent/mcp", protocolVersion: "2025-06-18" });
116
117
  });
118
+
119
+ test("formatAgentOpenApi: search interface present → /api/agent/search GET path with dynamic lang enum", () => {
120
+ const manifest = buildAgentSurfaceManifest({
121
+ site: "s",
122
+ baseUrl: "https://s.example",
123
+ languages: { default: "de", supported: ["de", "uk"] },
124
+ search: { url: "/api/agent/search", model: "@cf/baai/bge-m3", dimensions: 1024 },
125
+ });
126
+ const doc = formatAgentOpenApi(manifest, []);
127
+ const op = doc.paths["/api/agent/search"]?.get;
128
+ expect(op).toBeTruthy();
129
+ expect(op!.operationId).toBe("search.query");
130
+ expect(op!.tags).toEqual(["search"]);
131
+ expect(doc.components.schemas["search-response"]).toBeTruthy();
132
+ const langParam = op!.parameters!.find((p: { name: string }) => p.name === "lang");
133
+ expect(langParam).toBeTruthy();
134
+ expect(langParam!.schema.enum).toEqual(["de", "uk"]);
135
+ });
136
+
137
+ test("formatAgentOpenApi: search interface absent → no search path", () => {
138
+ const manifest = buildAgentSurfaceManifest({
139
+ site: "s",
140
+ baseUrl: "https://s.example",
141
+ languages: { default: "de", supported: ["de"] },
142
+ });
143
+ const doc = formatAgentOpenApi(manifest, []);
144
+ expect(doc.paths["/api/agent/search"]).toBe(undefined);
145
+ expect(doc.components.schemas["search-response"]).toBe(undefined);
146
+ });
@@ -0,0 +1,18 @@
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>Add type declaration for qrcode/lib/browser.js deep import used by external-link-qr.ts.</item>
13
+ </CHANGE_SUMMARY>
14
+ */
15
+
16
+ declare module "qrcode/lib/browser.js" {
17
+ export * from "qrcode";
18
+ }
@@ -3,8 +3,8 @@ utilities:
3
3
  canonicalPath: packages/werkstatt-shared/src/share/slug/
4
4
  forbiddenImports:
5
5
  - "@sindresorhus/slugify"
6
- - "cyrillic-to-translit-js"
7
- - "github-slugger"
6
+ - cyrillic-to-translit-js
7
+ - github-slugger
8
8
  functionNames:
9
9
  - slugify
10
10
  - toSlug
@@ -34,3 +34,17 @@ utilities:
34
34
  allowlist:
35
35
  - path: packages/werkstatt-shared/src/share/routes/
36
36
  reason: Canonical placeholder route filter — owns all template detection logic (RFC-0917)
37
+ - id: remediation-catalog
38
+ canonicalPath: packages/werkstatt-shared/src/share/remediation/
39
+ forbiddenImports: []
40
+ functionNames:
41
+ - lookupRemediation
42
+ - REMEDIATION_CATALOG
43
+ patterns: []
44
+ allowlist:
45
+ - path: packages/werkstatt-shared/src/share/remediation/
46
+ reason: Canonical remediation catalog — owns all ruleId-to-remediation-pattern mappings (RFC-1027)
47
+ - path: packages/werkstatt-shared/src/checks/result-helpers.ts
48
+ reason: Consumes lookupRemediation to auto-populate Diagnostic.remediation (RFC-1027)
49
+ - path: packages/werkstatt-engine/src/remediation/
50
+ reason: Engine remediation module reads REMEDIATION_CATALOG for catalog.generate and hint.validate (RFC-1027)