domain-knowledge-kit 0.1.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 (142) hide show
  1. package/LICENSE +94 -0
  2. package/README.md +266 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +40 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/features/adr/commands/adr-related.d.ts +14 -0
  8. package/dist/features/adr/commands/adr-related.d.ts.map +1 -0
  9. package/dist/features/adr/commands/adr-related.js +146 -0
  10. package/dist/features/adr/commands/adr-related.js.map +1 -0
  11. package/dist/features/adr/commands/adr-show.d.ts +10 -0
  12. package/dist/features/adr/commands/adr-show.d.ts.map +1 -0
  13. package/dist/features/adr/commands/adr-show.js +30 -0
  14. package/dist/features/adr/commands/adr-show.js.map +1 -0
  15. package/dist/features/pipeline/commands/render.d.ts +10 -0
  16. package/dist/features/pipeline/commands/render.d.ts.map +1 -0
  17. package/dist/features/pipeline/commands/render.js +71 -0
  18. package/dist/features/pipeline/commands/render.js.map +1 -0
  19. package/dist/features/pipeline/commands/validate.d.ts +10 -0
  20. package/dist/features/pipeline/commands/validate.d.ts.map +1 -0
  21. package/dist/features/pipeline/commands/validate.js +48 -0
  22. package/dist/features/pipeline/commands/validate.js.map +1 -0
  23. package/dist/features/pipeline/indexer.d.ts +36 -0
  24. package/dist/features/pipeline/indexer.d.ts.map +1 -0
  25. package/dist/features/pipeline/indexer.js +279 -0
  26. package/dist/features/pipeline/indexer.js.map +1 -0
  27. package/dist/features/pipeline/renderer.d.ts +42 -0
  28. package/dist/features/pipeline/renderer.d.ts.map +1 -0
  29. package/dist/features/pipeline/renderer.js +239 -0
  30. package/dist/features/pipeline/renderer.js.map +1 -0
  31. package/dist/features/pipeline/tests/indexer.test.d.ts +2 -0
  32. package/dist/features/pipeline/tests/indexer.test.d.ts.map +1 -0
  33. package/dist/features/pipeline/tests/indexer.test.js +224 -0
  34. package/dist/features/pipeline/tests/indexer.test.js.map +1 -0
  35. package/dist/features/pipeline/tests/renderer.test.d.ts +2 -0
  36. package/dist/features/pipeline/tests/renderer.test.d.ts.map +1 -0
  37. package/dist/features/pipeline/tests/renderer.test.js +252 -0
  38. package/dist/features/pipeline/tests/renderer.test.js.map +1 -0
  39. package/dist/features/pipeline/tests/validate-schemas.test.d.ts +2 -0
  40. package/dist/features/pipeline/tests/validate-schemas.test.d.ts.map +1 -0
  41. package/dist/features/pipeline/tests/validate-schemas.test.js +183 -0
  42. package/dist/features/pipeline/tests/validate-schemas.test.js.map +1 -0
  43. package/dist/features/pipeline/tests/validator.test.d.ts +2 -0
  44. package/dist/features/pipeline/tests/validator.test.d.ts.map +1 -0
  45. package/dist/features/pipeline/tests/validator.test.js +371 -0
  46. package/dist/features/pipeline/tests/validator.test.js.map +1 -0
  47. package/dist/features/pipeline/validator.d.ts +44 -0
  48. package/dist/features/pipeline/validator.d.ts.map +1 -0
  49. package/dist/features/pipeline/validator.js +289 -0
  50. package/dist/features/pipeline/validator.js.map +1 -0
  51. package/dist/features/query/commands/list.d.ts +10 -0
  52. package/dist/features/query/commands/list.d.ts.map +1 -0
  53. package/dist/features/query/commands/list.js +123 -0
  54. package/dist/features/query/commands/list.js.map +1 -0
  55. package/dist/features/query/commands/related.d.ts +10 -0
  56. package/dist/features/query/commands/related.d.ts.map +1 -0
  57. package/dist/features/query/commands/related.js +61 -0
  58. package/dist/features/query/commands/related.js.map +1 -0
  59. package/dist/features/query/commands/search.d.ts +10 -0
  60. package/dist/features/query/commands/search.d.ts.map +1 -0
  61. package/dist/features/query/commands/search.js +55 -0
  62. package/dist/features/query/commands/search.js.map +1 -0
  63. package/dist/features/query/commands/show.d.ts +10 -0
  64. package/dist/features/query/commands/show.d.ts.map +1 -0
  65. package/dist/features/query/commands/show.js +96 -0
  66. package/dist/features/query/commands/show.js.map +1 -0
  67. package/dist/features/query/searcher.d.ts +58 -0
  68. package/dist/features/query/searcher.d.ts.map +1 -0
  69. package/dist/features/query/searcher.js +185 -0
  70. package/dist/features/query/searcher.js.map +1 -0
  71. package/dist/features/query/tests/searcher.test.d.ts +2 -0
  72. package/dist/features/query/tests/searcher.test.d.ts.map +1 -0
  73. package/dist/features/query/tests/searcher.test.js +320 -0
  74. package/dist/features/query/tests/searcher.test.js.map +1 -0
  75. package/dist/shared/adr-parser.d.ts +14 -0
  76. package/dist/shared/adr-parser.d.ts.map +1 -0
  77. package/dist/shared/adr-parser.js +72 -0
  78. package/dist/shared/adr-parser.js.map +1 -0
  79. package/dist/shared/errors.d.ts +43 -0
  80. package/dist/shared/errors.d.ts.map +1 -0
  81. package/dist/shared/errors.js +60 -0
  82. package/dist/shared/errors.js.map +1 -0
  83. package/dist/shared/graph.d.ts +71 -0
  84. package/dist/shared/graph.d.ts.map +1 -0
  85. package/dist/shared/graph.js +250 -0
  86. package/dist/shared/graph.js.map +1 -0
  87. package/dist/shared/index.d.ts +16 -0
  88. package/dist/shared/index.d.ts.map +1 -0
  89. package/dist/shared/index.js +24 -0
  90. package/dist/shared/index.js.map +1 -0
  91. package/dist/shared/item-visitor.d.ts +62 -0
  92. package/dist/shared/item-visitor.d.ts.map +1 -0
  93. package/dist/shared/item-visitor.js +95 -0
  94. package/dist/shared/item-visitor.js.map +1 -0
  95. package/dist/shared/loader.d.ts +19 -0
  96. package/dist/shared/loader.d.ts.map +1 -0
  97. package/dist/shared/loader.js +166 -0
  98. package/dist/shared/loader.js.map +1 -0
  99. package/dist/shared/paths.d.ts +32 -0
  100. package/dist/shared/paths.d.ts.map +1 -0
  101. package/dist/shared/paths.js +62 -0
  102. package/dist/shared/paths.js.map +1 -0
  103. package/dist/shared/tests/graph.test.d.ts +2 -0
  104. package/dist/shared/tests/graph.test.d.ts.map +1 -0
  105. package/dist/shared/tests/graph.test.js +291 -0
  106. package/dist/shared/tests/graph.test.js.map +1 -0
  107. package/dist/shared/tests/loader.test.d.ts +2 -0
  108. package/dist/shared/tests/loader.test.d.ts.map +1 -0
  109. package/dist/shared/tests/loader.test.js +239 -0
  110. package/dist/shared/tests/loader.test.js.map +1 -0
  111. package/dist/shared/tests/verify-collision-fix.test.d.ts +2 -0
  112. package/dist/shared/tests/verify-collision-fix.test.d.ts.map +1 -0
  113. package/dist/shared/tests/verify-collision-fix.test.js +114 -0
  114. package/dist/shared/tests/verify-collision-fix.test.js.map +1 -0
  115. package/dist/shared/types/domain.d.ts +244 -0
  116. package/dist/shared/types/domain.d.ts.map +1 -0
  117. package/dist/shared/types/domain.js +6 -0
  118. package/dist/shared/types/domain.js.map +1 -0
  119. package/dist/shared/types/index.d.ts +34 -0
  120. package/dist/shared/types/index.d.ts.map +1 -0
  121. package/dist/shared/types/index.js +9 -0
  122. package/dist/shared/types/index.js.map +1 -0
  123. package/dist/shared/yaml.d.ts +13 -0
  124. package/dist/shared/yaml.d.ts.map +1 -0
  125. package/dist/shared/yaml.js +29 -0
  126. package/dist/shared/yaml.js.map +1 -0
  127. package/package.json +48 -0
  128. package/tools/domain-pack/schema/.gitkeep +0 -0
  129. package/tools/domain-pack/schema/actors.schema.json +42 -0
  130. package/tools/domain-pack/schema/adr-frontmatter.schema.json +51 -0
  131. package/tools/domain-pack/schema/aggregate.schema.json +58 -0
  132. package/tools/domain-pack/schema/command.schema.json +76 -0
  133. package/tools/domain-pack/schema/context.schema.json +51 -0
  134. package/tools/domain-pack/schema/event.schema.json +66 -0
  135. package/tools/domain-pack/schema/glossary.schema.json +33 -0
  136. package/tools/domain-pack/schema/index.schema.json +76 -0
  137. package/tools/domain-pack/schema/policy.schema.json +53 -0
  138. package/tools/domain-pack/schema/read-model.schema.json +39 -0
  139. package/tools/domain-pack/templates/.gitkeep +0 -0
  140. package/tools/domain-pack/templates/context.md.hbs +89 -0
  141. package/tools/domain-pack/templates/index.md.hbs +60 -0
  142. package/tools/domain-pack/templates/item.md.hbs +85 -0
@@ -0,0 +1,371 @@
1
+ /**
2
+ * Tests for the domain model validator.
3
+ *
4
+ * Builds various DomainModel fixtures (valid and intentionally broken)
5
+ * and asserts that validateDomainModel reports the expected errors and warnings.
6
+ */
7
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { tmpdir } from "node:os";
10
+ import { loadDomainModel } from "../../../shared/loader.js";
11
+ import { validateDomainModel, } from "../validator.js";
12
+ // ── Helpers ───────────────────────────────────────────────────────────
13
+ const SCHEMA_DIR = join(import.meta.dirname, "../../../../tools/domain-pack/schema");
14
+ let passed = 0;
15
+ let failed = 0;
16
+ function assert(label, condition, detail) {
17
+ if (condition) {
18
+ console.log(` OK: ${label}`);
19
+ passed++;
20
+ }
21
+ else {
22
+ console.error(`FAIL: ${label}${detail ? ` — ${detail}` : ""}`);
23
+ failed++;
24
+ }
25
+ }
26
+ function hasError(result, substring) {
27
+ return result.errors.some((e) => e.message.includes(substring));
28
+ }
29
+ function hasWarning(result, substring) {
30
+ return result.warnings.some((w) => w.message.includes(substring));
31
+ }
32
+ /** Create a minimal temp domain tree and return its root path. */
33
+ function makeTempRoot(suffix) {
34
+ const root = join(tmpdir(), `dkk-validator-${suffix}-${Date.now()}`);
35
+ mkdirSync(join(root, "domain", "contexts"), { recursive: true });
36
+ mkdirSync(join(root, "docs", "adr"), { recursive: true });
37
+ return root;
38
+ }
39
+ /** Write a YAML string to a file. */
40
+ function writeYaml(path, content) {
41
+ writeFileSync(path, content, "utf-8");
42
+ }
43
+ /** Write an ADR Markdown file. */
44
+ function writeAdr(dir, filename, frontmatter) {
45
+ writeFileSync(join(dir, filename), `---\n${frontmatter}\n---\n\n# Title\n\nContent.\n`, "utf-8");
46
+ }
47
+ /**
48
+ * Write a per-item context directory under domain/contexts/<name>/.
49
+ * - contextYaml: YAML for context.yml (contains name, description, optional glossary)
50
+ * - items: map of sub-dir name → array of [filename, yamlContent] pairs
51
+ */
52
+ function writeContextDir(root, contextYaml, items = {}) {
53
+ const nameMatch = contextYaml.match(/^name:\s*(\S+)/m);
54
+ const name = nameMatch[1];
55
+ const ctxDir = join(root, "domain", "contexts", name);
56
+ mkdirSync(ctxDir, { recursive: true });
57
+ writeYaml(join(ctxDir, "context.yml"), contextYaml);
58
+ for (const [subDir, files] of Object.entries(items)) {
59
+ mkdirSync(join(ctxDir, subDir), { recursive: true });
60
+ for (const [filename, content] of files) {
61
+ writeYaml(join(ctxDir, subDir, filename), content);
62
+ }
63
+ }
64
+ }
65
+ // ── Test: Valid model ─────────────────────────────────────────────────
66
+ function testValidModel() {
67
+ console.log("\n=== Valid model ===");
68
+ const root = makeTempRoot("valid");
69
+ writeYaml(join(root, "domain", "index.yml"), [
70
+ "contexts:",
71
+ " - name: ordering",
72
+ "flows:",
73
+ " - name: PlaceFlow",
74
+ " steps:",
75
+ " - ref: ordering.PlaceOrder",
76
+ " type: command",
77
+ " - ref: ordering.OrderPlaced",
78
+ " type: event",
79
+ ].join("\n"));
80
+ writeYaml(join(root, "domain", "actors.yml"), [
81
+ "actors:",
82
+ " - name: Customer",
83
+ " type: human",
84
+ ' description: "A paying customer"',
85
+ ].join("\n"));
86
+ writeContextDir(root, [
87
+ "name: ordering",
88
+ 'description: "Handles orders"',
89
+ "glossary:",
90
+ " - term: OrderLifecycle",
91
+ ' definition: "The lifecycle of a purchase request"',
92
+ ].join("\n"), {
93
+ events: [["OrderPlaced.yml", [
94
+ "name: OrderPlaced",
95
+ 'description: "Raised when order placed"',
96
+ "fields:",
97
+ " - name: orderId",
98
+ " type: UUID",
99
+ "raised_by: Order",
100
+ ].join("\n")]],
101
+ commands: [["PlaceOrder.yml", [
102
+ "name: PlaceOrder",
103
+ 'description: "Submit a new order"',
104
+ "actor: Customer",
105
+ "handled_by: Order",
106
+ "fields:",
107
+ " - name: items",
108
+ " type: array",
109
+ ].join("\n")]],
110
+ aggregates: [["Order.yml", [
111
+ "name: Order",
112
+ 'description: "Order aggregate root"',
113
+ "handles:",
114
+ " commands:",
115
+ " - PlaceOrder",
116
+ "emits:",
117
+ " events:",
118
+ " - OrderPlaced",
119
+ ].join("\n")]],
120
+ });
121
+ writeAdr(join(root, "docs", "adr"), "0001-use-yaml.md", [
122
+ "id: adr-0001",
123
+ "title: Use YAML for domain models",
124
+ "status: accepted",
125
+ "date: 2026-01-15",
126
+ "domain_refs:",
127
+ " - ordering.OrderPlaced",
128
+ ].join("\n"));
129
+ const model = loadDomainModel({ root });
130
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
131
+ assert("valid model has no errors", result.valid, `errors: ${result.errors.map((e) => e.message).join("; ")}`);
132
+ assert("valid model has no warnings", result.warnings.length === 0);
133
+ rmSync(root, { recursive: true, force: true });
134
+ }
135
+ // ── Test: Broken ADR refs ─────────────────────────────────────────────
136
+ function testBrokenAdrRefs() {
137
+ console.log("\n=== Broken ADR refs ===");
138
+ const root = makeTempRoot("brokenadr");
139
+ writeYaml(join(root, "domain", "index.yml"), "contexts:\n - name: ordering\n");
140
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
141
+ writeContextDir(root, [
142
+ "name: ordering",
143
+ 'description: "Orders"',
144
+ ].join("\n"), {
145
+ events: [["OrderPlaced.yml", [
146
+ "name: OrderPlaced",
147
+ 'description: "Placed"',
148
+ "adr_refs:",
149
+ " - adr-9999",
150
+ ].join("\n")]],
151
+ });
152
+ const model = loadDomainModel({ root });
153
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
154
+ assert("detects unresolved adr_ref", hasError(result, "adr-9999"));
155
+ assert("result is invalid", !result.valid);
156
+ rmSync(root, { recursive: true, force: true });
157
+ }
158
+ // ── Test: Broken domain_refs on ADR ───────────────────────────────────
159
+ function testBrokenDomainRefs() {
160
+ console.log("\n=== Broken ADR domain_refs ===");
161
+ const root = makeTempRoot("brokendomainref");
162
+ writeYaml(join(root, "domain", "index.yml"), "contexts: []\n");
163
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
164
+ writeAdr(join(root, "docs", "adr"), "0001-test.md", [
165
+ "id: adr-0001",
166
+ "title: Test",
167
+ "status: accepted",
168
+ "date: 2026-02-20",
169
+ "domain_refs:",
170
+ " - nonexistent.Thing",
171
+ ].join("\n"));
172
+ const model = loadDomainModel({ root });
173
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
174
+ assert("detects unresolved ADR domain_ref", hasError(result, "nonexistent.Thing"));
175
+ assert("result is invalid", !result.valid);
176
+ rmSync(root, { recursive: true, force: true });
177
+ }
178
+ // ── Test: Broken intra-context references ─────────────────────────────
179
+ function testBrokenIntraContextRefs() {
180
+ console.log("\n=== Broken intra-context refs ===");
181
+ const root = makeTempRoot("brokenintra");
182
+ writeYaml(join(root, "domain", "index.yml"), "contexts:\n - name: sales\n");
183
+ writeYaml(join(root, "domain", "actors.yml"), "actors:\n - name: Admin\n type: human\n description: Admin user\n");
184
+ writeContextDir(root, "name: sales\ndescription: \"Sales context\"", {
185
+ events: [["SaleCompleted.yml", [
186
+ "name: SaleCompleted",
187
+ 'description: "A sale was completed"',
188
+ "raised_by: NonExistentAggregate",
189
+ ].join("\n")]],
190
+ commands: [["CompleteSale.yml", [
191
+ "name: CompleteSale",
192
+ 'description: "Complete a sale"',
193
+ "handled_by: GhostAggregate",
194
+ "actor: GhostActor",
195
+ ].join("\n")]],
196
+ aggregates: [["Sale.yml", [
197
+ "name: Sale",
198
+ 'description: "Sale aggregate"',
199
+ "handles:",
200
+ " commands:",
201
+ " - NonExistentCommand",
202
+ "emits:",
203
+ " events:",
204
+ " - NonExistentEvent",
205
+ ].join("\n")]],
206
+ policies: [["NotifyOnSale.yml", [
207
+ "name: NotifyOnSale",
208
+ 'description: "Notify on sale"',
209
+ "when:",
210
+ " events:",
211
+ " - GhostEvent",
212
+ "then:",
213
+ " commands:",
214
+ " - GhostCommand",
215
+ ].join("\n")]],
216
+ "read-models": [["SaleDashboard.yml", [
217
+ "name: SaleDashboard",
218
+ 'description: "Dashboard"',
219
+ "subscribes_to:",
220
+ " - GhostEvent",
221
+ "used_by:",
222
+ " - GhostActor",
223
+ ].join("\n")]],
224
+ });
225
+ const model = loadDomainModel({ root });
226
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
227
+ assert("detects event raised_by unknown aggregate", hasError(result, "raised_by") && hasError(result, "NonExistentAggregate"));
228
+ assert("detects command handled_by unknown aggregate", hasError(result, "handled_by") && hasError(result, "GhostAggregate"));
229
+ assert("detects command actor unknown", hasError(result, "actor") && hasError(result, "GhostActor"));
230
+ assert("detects aggregate handles unknown command", hasError(result, "NonExistentCommand"));
231
+ assert("detects aggregate emits unknown event", hasError(result, "NonExistentEvent"));
232
+ assert("detects policy triggers unknown event", hasError(result, 'when.events "GhostEvent"'));
233
+ assert("detects policy emits unknown command", hasError(result, 'then.commands "GhostCommand"'));
234
+ assert("detects read_model subscribes_to unknown event", hasError(result, 'subscribes_to "GhostEvent"'));
235
+ assert("detects read_model used_by unknown actor", hasError(result, 'used_by "GhostActor"'));
236
+ rmSync(root, { recursive: true, force: true });
237
+ }
238
+ // ── Test: Duplicate names ─────────────────────────────────────────────
239
+ function testDuplicateNames() {
240
+ console.log("\n=== Duplicate names ===");
241
+ const root = makeTempRoot("dupes");
242
+ writeYaml(join(root, "domain", "index.yml"), "contexts:\n - name: ctx\n");
243
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
244
+ writeContextDir(root, "name: ctx\ndescription: \"Test context\"", {
245
+ events: [["Clash.yml", "name: Clash\ndescription: \"Event\""]],
246
+ commands: [["Clash.yml", "name: Clash\ndescription: \"Command\""]],
247
+ });
248
+ const model = loadDomainModel({ root });
249
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
250
+ assert("detects duplicate name", hasError(result, 'Duplicate name "Clash"'));
251
+ rmSync(root, { recursive: true, force: true });
252
+ }
253
+ // ── Test: Glossary-aggregate name collision ───────────────────────────
254
+ function testGlossaryAggregateCollision() {
255
+ console.log("\n=== Glossary-aggregate collision ===");
256
+ const root = makeTempRoot("glosscoll");
257
+ writeYaml(join(root, "domain", "index.yml"), "contexts:\n - name: ctx\n");
258
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
259
+ writeContextDir(root, [
260
+ "name: ctx",
261
+ 'description: "Test context"',
262
+ "glossary:",
263
+ " - term: Order",
264
+ ' definition: "A purchase"',
265
+ ].join("\n"), {
266
+ aggregates: [["Order.yml", "name: Order\ndescription: \"Root\""]],
267
+ });
268
+ const model = loadDomainModel({ root });
269
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
270
+ assert("detects glossary-aggregate collision", hasError(result, 'Duplicate name "Order"'));
271
+ rmSync(root, { recursive: true, force: true });
272
+ }
273
+ // ── Test: Missing context file ────────────────────────────────────────
274
+ function testMissingContextFile() {
275
+ console.log("\n=== Missing context file ===");
276
+ const root = makeTempRoot("missingctx");
277
+ writeYaml(join(root, "domain", "index.yml"), "contexts:\n - name: phantom\n");
278
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
279
+ const model = loadDomainModel({ root });
280
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
281
+ assert("detects missing context file", hasError(result, "phantom"));
282
+ rmSync(root, { recursive: true, force: true });
283
+ }
284
+ // ── Test: Broken flow step refs ───────────────────────────────────────
285
+ function testBrokenFlowSteps() {
286
+ console.log("\n=== Broken flow step refs ===");
287
+ const root = makeTempRoot("brokenflow");
288
+ writeYaml(join(root, "domain", "index.yml"), [
289
+ "contexts: []",
290
+ "flows:",
291
+ " - name: BadFlow",
292
+ " steps:",
293
+ " - ref: ghost.DoThing",
294
+ " type: command",
295
+ ].join("\n"));
296
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
297
+ const model = loadDomainModel({ root });
298
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
299
+ assert("detects unresolved flow step ref", hasError(result, "ghost.DoThing"));
300
+ rmSync(root, { recursive: true, force: true });
301
+ }
302
+ // ── Test: ADR superseded_by unresolved ────────────────────────────────
303
+ function testBrokenSupersededBy() {
304
+ console.log("\n=== ADR superseded_by unresolved ===");
305
+ const root = makeTempRoot("superseded");
306
+ writeYaml(join(root, "domain", "index.yml"), "contexts: []\n");
307
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
308
+ writeAdr(join(root, "docs", "adr"), "0001-old.md", [
309
+ "id: adr-0001",
310
+ "title: Old decision",
311
+ "status: superseded",
312
+ "date: 2026-02-20",
313
+ "superseded_by: adr-9999",
314
+ ].join("\n"));
315
+ const model = loadDomainModel({ root });
316
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
317
+ assert("detects unresolved superseded_by", hasError(result, "adr-9999"));
318
+ rmSync(root, { recursive: true, force: true });
319
+ }
320
+ // ── Test: warnMissingFields ───────────────────────────────────────────
321
+ function testWarnMissingFields() {
322
+ console.log("\n=== warnMissingFields ===");
323
+ const root = makeTempRoot("warnfields");
324
+ writeYaml(join(root, "domain", "index.yml"), "contexts:\n - name: ctx\n");
325
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
326
+ writeContextDir(root, 'name: ctx\ndescription: "Test"', {
327
+ events: [["NoFieldsEvent.yml", 'name: NoFieldsEvent\ndescription: "Event with no fields"']],
328
+ commands: [["NoFieldsCommand.yml", 'name: NoFieldsCommand\ndescription: "Command with no fields"']],
329
+ });
330
+ const model = loadDomainModel({ root });
331
+ // Without the option — no warnings
332
+ const r1 = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
333
+ assert("no warnings when warnMissingFields is off", r1.warnings.length === 0);
334
+ // With the option — warnings
335
+ const r2 = validateDomainModel(model, { schemaDir: SCHEMA_DIR, warnMissingFields: true });
336
+ assert("warns about event without fields", hasWarning(r2, "NoFieldsEvent"));
337
+ assert("warns about command without fields", hasWarning(r2, "NoFieldsCommand"));
338
+ assert("warnings are non-blocking", r2.valid);
339
+ rmSync(root, { recursive: true, force: true });
340
+ }
341
+ // ── Test: Empty model (should be valid) ───────────────────────────────
342
+ function testEmptyModel() {
343
+ console.log("\n=== Empty model ===");
344
+ const root = makeTempRoot("empty");
345
+ writeYaml(join(root, "domain", "index.yml"), "contexts: []\n");
346
+ writeYaml(join(root, "domain", "actors.yml"), "actors: []\n");
347
+ const model = loadDomainModel({ root });
348
+ const result = validateDomainModel(model, { schemaDir: SCHEMA_DIR });
349
+ assert("empty model is valid", result.valid);
350
+ assert("no errors", result.errors.length === 0);
351
+ assert("no warnings", result.warnings.length === 0);
352
+ rmSync(root, { recursive: true, force: true });
353
+ }
354
+ // ── Run all ───────────────────────────────────────────────────────────
355
+ testValidModel();
356
+ testBrokenAdrRefs();
357
+ testBrokenDomainRefs();
358
+ testBrokenIntraContextRefs();
359
+ testDuplicateNames();
360
+ testGlossaryAggregateCollision();
361
+ testMissingContextFile();
362
+ testBrokenFlowSteps();
363
+ testBrokenSupersededBy();
364
+ testWarnMissingFields();
365
+ testEmptyModel();
366
+ // ── Summary ───────────────────────────────────────────────────────────
367
+ console.log(`\n${"=".repeat(40)}`);
368
+ console.log(`Results: ${passed} passed, ${failed} failed`);
369
+ if (failed > 0)
370
+ process.exit(1);
371
+ //# sourceMappingURL=validator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.test.js","sourceRoot":"","sources":["../../../../src/features/pipeline/tests/validator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { DomainModel } from "../../shared/types/domain.js";
2
+ /** Severity of a validation finding. */
3
+ export type Severity = "error" | "warning";
4
+ /** A single validation finding. */
5
+ export interface ValidationIssue {
6
+ /** error = blocking (fail), warning = informational. */
7
+ severity: Severity;
8
+ /** Human-readable problem description. */
9
+ message: string;
10
+ /** Location hint (e.g. "context:ordering", "adr:adr-0001"). */
11
+ path?: string;
12
+ }
13
+ /** Complete validation result. */
14
+ export interface ValidationResult {
15
+ /** True when there are zero errors (warnings are OK). */
16
+ valid: boolean;
17
+ /** All findings grouped for convenience. */
18
+ errors: ValidationIssue[];
19
+ warnings: ValidationIssue[];
20
+ }
21
+ /** Options that control validator behaviour. */
22
+ export interface ValidatorOptions {
23
+ /**
24
+ * Absolute path to the schema directory.
25
+ * Defaults to `<repoRoot>/tools/domain-pack/schema`.
26
+ */
27
+ schemaDir?: string;
28
+ /**
29
+ * When true, emit warnings for events and commands that have no
30
+ * `fields` array defined. Default: `false`.
31
+ */
32
+ warnMissingFields?: boolean;
33
+ }
34
+ /**
35
+ * Validate a loaded {@link DomainModel}.
36
+ *
37
+ * Runs JSON Schema validation followed by cross-reference checks.
38
+ * Returns a {@link ValidationResult} containing errors and warnings.
39
+ *
40
+ * @param model - The domain model to validate (from `loadDomainModel()`).
41
+ * @param options - Optional validator configuration.
42
+ */
43
+ export declare function validateDomainModel(model: DomainModel, options?: ValidatorOptions): ValidationResult;
44
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/features/pipeline/validator.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,WAAW,EAMZ,MAAM,8BAA8B,CAAC;AAYtC,wCAAwC;AACxC,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3C,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,QAAQ,EAAE,QAAQ,CAAC;IACnB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,4CAA4C;IAC5C,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AA4VD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,gBAAqB,GAC7B,gBAAgB,CAgBlB"}