@contractspec/example.versioned-knowledge-base 1.56.1 → 1.58.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 (76) hide show
  1. package/.turbo/turbo-build.log +53 -48
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +30 -0
  4. package/dist/browser/docs/index.js +44 -0
  5. package/dist/browser/docs/versioned-knowledge-base.docblock.js +44 -0
  6. package/dist/browser/entities/index.js +74 -0
  7. package/dist/browser/entities/models.js +74 -0
  8. package/dist/browser/events.js +101 -0
  9. package/dist/browser/example.js +35 -0
  10. package/dist/browser/handlers/index.js +115 -0
  11. package/dist/browser/handlers/memory.handlers.js +115 -0
  12. package/dist/browser/index.js +586 -0
  13. package/dist/browser/operations/index.js +257 -0
  14. package/dist/browser/operations/kb.js +257 -0
  15. package/dist/browser/versioned-knowledge-base.feature.js +36 -0
  16. package/dist/docs/index.d.ts +2 -1
  17. package/dist/docs/index.d.ts.map +1 -0
  18. package/dist/docs/index.js +45 -1
  19. package/dist/docs/versioned-knowledge-base.docblock.d.ts +2 -1
  20. package/dist/docs/versioned-knowledge-base.docblock.d.ts.map +1 -0
  21. package/dist/docs/versioned-knowledge-base.docblock.js +42 -28
  22. package/dist/entities/index.d.ts +2 -2
  23. package/dist/entities/index.d.ts.map +1 -0
  24. package/dist/entities/index.js +75 -3
  25. package/dist/entities/models.d.ts +127 -132
  26. package/dist/entities/models.d.ts.map +1 -1
  27. package/dist/entities/models.js +69 -145
  28. package/dist/events.d.ts +52 -58
  29. package/dist/events.d.ts.map +1 -1
  30. package/dist/events.js +92 -114
  31. package/dist/example.d.ts +2 -6
  32. package/dist/example.d.ts.map +1 -1
  33. package/dist/example.js +33 -46
  34. package/dist/handlers/index.d.ts +2 -2
  35. package/dist/handlers/index.d.ts.map +1 -0
  36. package/dist/handlers/index.js +116 -3
  37. package/dist/handlers/memory.handlers.d.ts +62 -64
  38. package/dist/handlers/memory.handlers.d.ts.map +1 -1
  39. package/dist/handlers/memory.handlers.js +110 -97
  40. package/dist/handlers/memory.handlers.test.d.ts +2 -0
  41. package/dist/handlers/memory.handlers.test.d.ts.map +1 -0
  42. package/dist/index.d.ts +13 -9
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +587 -11
  45. package/dist/node/docs/index.js +44 -0
  46. package/dist/node/docs/versioned-knowledge-base.docblock.js +44 -0
  47. package/dist/node/entities/index.js +74 -0
  48. package/dist/node/entities/models.js +74 -0
  49. package/dist/node/events.js +101 -0
  50. package/dist/node/example.js +35 -0
  51. package/dist/node/handlers/index.js +115 -0
  52. package/dist/node/handlers/memory.handlers.js +115 -0
  53. package/dist/node/index.js +586 -0
  54. package/dist/node/operations/index.js +257 -0
  55. package/dist/node/operations/kb.js +257 -0
  56. package/dist/node/versioned-knowledge-base.feature.js +36 -0
  57. package/dist/operations/index.d.ts +2 -2
  58. package/dist/operations/index.d.ts.map +1 -0
  59. package/dist/operations/index.js +257 -2
  60. package/dist/operations/kb.d.ts +252 -258
  61. package/dist/operations/kb.d.ts.map +1 -1
  62. package/dist/operations/kb.js +246 -244
  63. package/dist/versioned-knowledge-base.feature.d.ts +1 -6
  64. package/dist/versioned-knowledge-base.feature.d.ts.map +1 -1
  65. package/dist/versioned-knowledge-base.feature.js +35 -68
  66. package/package.json +141 -38
  67. package/tsdown.config.js +1 -2
  68. package/.turbo/turbo-build$colon$bundle.log +0 -47
  69. package/dist/docs/versioned-knowledge-base.docblock.js.map +0 -1
  70. package/dist/entities/models.js.map +0 -1
  71. package/dist/events.js.map +0 -1
  72. package/dist/example.js.map +0 -1
  73. package/dist/handlers/memory.handlers.js.map +0 -1
  74. package/dist/operations/kb.js.map +0 -1
  75. package/dist/versioned-knowledge-base.feature.js.map +0 -1
  76. package/tsconfig.tsbuildinfo +0 -1
package/dist/index.js CHANGED
@@ -1,11 +1,587 @@
1
- import { KbRuleVersionApprovedEvent, KbRuleVersionCreatedEvent, KbSnapshotPublishedEvent, KbSourceIngestedEvent } from "./events.js";
2
- import example_default from "./example.js";
3
- import { KBSnapshotModel, RuleModel, RuleVersionModel, SourceDocumentModel, SourceRefModel } from "./entities/models.js";
4
- import "./entities/index.js";
5
- import { KbApproveRuleVersionContract, KbIngestSourceContract, KbPublishSnapshotContract, KbSearchContract, KbUpsertRuleVersionContract } from "./operations/kb.js";
6
- import "./operations/index.js";
7
- import { createMemoryKbHandlers, createMemoryKbStore } from "./handlers/memory.handlers.js";
8
- import { VersionedKnowledgeBaseFeature } from "./versioned-knowledge-base.feature.js";
9
- import "./docs/index.js";
10
-
11
- export { KBSnapshotModel, KbApproveRuleVersionContract, KbIngestSourceContract, KbPublishSnapshotContract, KbRuleVersionApprovedEvent, KbRuleVersionCreatedEvent, KbSearchContract, KbSnapshotPublishedEvent, KbSourceIngestedEvent, KbUpsertRuleVersionContract, RuleModel, RuleVersionModel, SourceDocumentModel, SourceRefModel, VersionedKnowledgeBaseFeature, createMemoryKbHandlers, createMemoryKbStore, example_default as example };
1
+ // @bun
2
+ // src/docs/versioned-knowledge-base.docblock.ts
3
+ import { registerDocBlocks } from "@contractspec/lib.contracts/docs";
4
+ var docBlocks = [
5
+ {
6
+ id: "docs.examples.versioned-knowledge-base.goal",
7
+ title: "Versioned Knowledge Base \u2014 Goal",
8
+ summary: "Curated KB with immutable sources, versioned rules, and published snapshots referenced by answers.",
9
+ kind: "goal",
10
+ visibility: "public",
11
+ route: "/docs/examples/versioned-knowledge-base/goal",
12
+ tags: ["knowledge", "versioning", "snapshots", "traceability"],
13
+ body: `## Why it matters
14
+ - Separates raw sources from curated knowledge.
15
+ - Ensures assistant answers cite a published snapshot.
16
+ - Makes change review and safe regeneration possible.
17
+
18
+ ## Core invariants
19
+ - Sources are immutable and content-addressed (hash).
20
+ - Rule versions must cite at least one source.
21
+ - Snapshots include only approved rule versions.`
22
+ },
23
+ {
24
+ id: "docs.examples.versioned-knowledge-base.reference",
25
+ title: "Versioned Knowledge Base \u2014 Reference",
26
+ summary: "Entities, contracts, and events for the versioned KB example.",
27
+ kind: "reference",
28
+ visibility: "public",
29
+ route: "/docs/examples/versioned-knowledge-base",
30
+ tags: ["knowledge", "reference"],
31
+ body: `## Contracts
32
+ - kb.ingestSource
33
+ - kb.upsertRuleVersion
34
+ - kb.approveRuleVersion
35
+ - kb.publishSnapshot
36
+ - kb.search
37
+
38
+ ## Events
39
+ - kb.source.ingested
40
+ - kb.ruleVersion.created
41
+ - kb.ruleVersion.approved
42
+ - kb.snapshot.published`
43
+ }
44
+ ];
45
+ registerDocBlocks(docBlocks);
46
+ // src/entities/models.ts
47
+ import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
48
+ var SourceDocumentModel = defineSchemaModel({
49
+ name: "SourceDocument",
50
+ description: "Immutable raw source document metadata referencing a stored file.",
51
+ fields: {
52
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
53
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
54
+ authority: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
55
+ title: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
56
+ fetchedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
57
+ hash: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
58
+ fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
59
+ }
60
+ });
61
+ var SourceRefModel = defineSchemaModel({
62
+ name: "SourceRef",
63
+ description: "Reference to a source document used to justify a rule version.",
64
+ fields: {
65
+ sourceDocumentId: {
66
+ type: ScalarTypeEnum.String_unsecure(),
67
+ isOptional: false
68
+ },
69
+ excerpt: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
70
+ }
71
+ });
72
+ var RuleModel = defineSchemaModel({
73
+ name: "Rule",
74
+ description: "Curated rule (stable identity) with topic + jurisdiction scope.",
75
+ fields: {
76
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
77
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
78
+ topicKey: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
79
+ }
80
+ });
81
+ var RuleVersionModel = defineSchemaModel({
82
+ name: "RuleVersion",
83
+ description: "A versioned rule content with source references and approval status.",
84
+ fields: {
85
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
86
+ ruleId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
87
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
88
+ topicKey: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
89
+ version: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
90
+ content: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
91
+ sourceRefs: { type: SourceRefModel, isArray: true, isOptional: false },
92
+ status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
93
+ approvedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
94
+ approvedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
95
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
96
+ }
97
+ });
98
+ var KBSnapshotModel = defineSchemaModel({
99
+ name: "KBSnapshot",
100
+ description: "Published KB snapshot (as-of) referencing approved rule versions.",
101
+ fields: {
102
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
103
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
104
+ asOfDate: { type: ScalarTypeEnum.DateTime(), isOptional: false },
105
+ includedRuleVersionIds: {
106
+ type: ScalarTypeEnum.String_unsecure(),
107
+ isArray: true,
108
+ isOptional: false
109
+ },
110
+ publishedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
111
+ }
112
+ });
113
+ // src/events.ts
114
+ import { defineEvent, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.contracts";
115
+ import { ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
116
+ var KbSourceIngestedPayload = defineSchemaModel2({
117
+ name: "KbSourceIngestedPayload",
118
+ description: "Emitted when a source document is ingested.",
119
+ fields: {
120
+ sourceDocumentId: {
121
+ type: ScalarTypeEnum2.String_unsecure(),
122
+ isOptional: false
123
+ },
124
+ jurisdiction: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
125
+ hash: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
126
+ }
127
+ });
128
+ var KbSourceIngestedEvent = defineEvent({
129
+ meta: {
130
+ key: "kb.source.ingested",
131
+ version: "1.0.0",
132
+ description: "Source document ingested (immutable).",
133
+ stability: "experimental",
134
+ owners: ["@examples"],
135
+ tags: ["knowledge"]
136
+ },
137
+ payload: KbSourceIngestedPayload
138
+ });
139
+ var KbRuleVersionCreatedPayload = defineSchemaModel2({
140
+ name: "KbRuleVersionCreatedPayload",
141
+ description: "Emitted when a rule version draft is created.",
142
+ fields: {
143
+ ruleVersionId: {
144
+ type: ScalarTypeEnum2.String_unsecure(),
145
+ isOptional: false
146
+ },
147
+ ruleId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
148
+ jurisdiction: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
149
+ status: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
150
+ }
151
+ });
152
+ var KbRuleVersionCreatedEvent = defineEvent({
153
+ meta: {
154
+ key: "kb.ruleVersion.created",
155
+ version: "1.0.0",
156
+ description: "Rule version created (draft).",
157
+ stability: "experimental",
158
+ owners: ["@examples"],
159
+ tags: ["knowledge"]
160
+ },
161
+ payload: KbRuleVersionCreatedPayload
162
+ });
163
+ var KbRuleVersionApprovedPayload = defineSchemaModel2({
164
+ name: "KbRuleVersionApprovedPayload",
165
+ description: "Emitted when a rule version is approved.",
166
+ fields: {
167
+ ruleVersionId: {
168
+ type: ScalarTypeEnum2.String_unsecure(),
169
+ isOptional: false
170
+ },
171
+ approver: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
172
+ }
173
+ });
174
+ var KbRuleVersionApprovedEvent = defineEvent({
175
+ meta: {
176
+ key: "kb.ruleVersion.approved",
177
+ version: "1.0.0",
178
+ description: "Rule version approved (human verified).",
179
+ stability: "experimental",
180
+ owners: ["@examples"],
181
+ tags: ["knowledge"]
182
+ },
183
+ payload: KbRuleVersionApprovedPayload
184
+ });
185
+ var KbSnapshotPublishedPayload = defineSchemaModel2({
186
+ name: "KbSnapshotPublishedPayload",
187
+ description: "Emitted when a KB snapshot is published.",
188
+ fields: {
189
+ snapshotId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
190
+ jurisdiction: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
191
+ includedRuleVersionsCount: {
192
+ type: ScalarTypeEnum2.Int_unsecure(),
193
+ isOptional: false
194
+ }
195
+ }
196
+ });
197
+ var KbSnapshotPublishedEvent = defineEvent({
198
+ meta: {
199
+ key: "kb.snapshot.published",
200
+ version: "1.0.0",
201
+ description: "KB snapshot published.",
202
+ stability: "experimental",
203
+ owners: ["@examples"],
204
+ tags: ["knowledge"]
205
+ },
206
+ payload: KbSnapshotPublishedPayload
207
+ });
208
+
209
+ // src/example.ts
210
+ import { defineExample } from "@contractspec/lib.contracts";
211
+ var example = defineExample({
212
+ meta: {
213
+ key: "versioned-knowledge-base",
214
+ version: "1.0.0",
215
+ title: "Versioned Knowledge Base",
216
+ description: "Curated KB with immutable sources, reviewable rule versions, and published snapshots.",
217
+ kind: "knowledge",
218
+ visibility: "public",
219
+ stability: "experimental",
220
+ owners: ["@platform.core"],
221
+ tags: ["knowledge", "versioning", "snapshots"]
222
+ },
223
+ docs: {
224
+ rootDocId: "docs.examples.versioned-knowledge-base"
225
+ },
226
+ entrypoints: {
227
+ packageName: "@contractspec/example.versioned-knowledge-base",
228
+ feature: "./feature",
229
+ contracts: "./contracts",
230
+ handlers: "./handlers",
231
+ docs: "./docs"
232
+ },
233
+ surfaces: {
234
+ templates: true,
235
+ sandbox: { enabled: true, modes: ["markdown", "specs", "builder"] },
236
+ studio: { enabled: true, installable: true },
237
+ mcp: { enabled: true }
238
+ }
239
+ });
240
+ var example_default = example;
241
+
242
+ // src/handlers/memory.handlers.ts
243
+ function createMemoryKbStore() {
244
+ return {
245
+ sources: new Map,
246
+ rules: new Map,
247
+ ruleVersions: new Map,
248
+ snapshots: new Map,
249
+ nextRuleVersionNumberByRuleId: new Map
250
+ };
251
+ }
252
+ function stableId(prefix, value) {
253
+ return `${prefix}_${value.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
254
+ }
255
+ function createMemoryKbHandlers(store) {
256
+ async function createRule(rule) {
257
+ store.rules.set(rule.id, rule);
258
+ return rule;
259
+ }
260
+ async function ingestSource(input) {
261
+ const id = stableId("src", `${input.jurisdiction}_${input.hash}`);
262
+ const doc = { id, ...input };
263
+ store.sources.set(id, doc);
264
+ return doc;
265
+ }
266
+ async function upsertRuleVersion(input) {
267
+ if (!input.sourceRefs.length) {
268
+ throw new Error("SOURCE_REFS_REQUIRED");
269
+ }
270
+ const rule = store.rules.get(input.ruleId);
271
+ if (!rule) {
272
+ throw new Error("RULE_NOT_FOUND");
273
+ }
274
+ const next = (store.nextRuleVersionNumberByRuleId.get(input.ruleId) ?? 0) + 1;
275
+ const id = stableId("rv", `${input.ruleId}_${next}`);
276
+ const ruleVersion = {
277
+ id,
278
+ ruleId: input.ruleId,
279
+ jurisdiction: rule.jurisdiction,
280
+ topicKey: rule.topicKey,
281
+ version: next.toString(),
282
+ content: input.content,
283
+ sourceRefs: input.sourceRefs,
284
+ status: "draft",
285
+ createdAt: new Date,
286
+ approvedAt: undefined,
287
+ approvedBy: undefined
288
+ };
289
+ store.ruleVersions.set(id, ruleVersion);
290
+ return ruleVersion;
291
+ }
292
+ async function approveRuleVersion(input) {
293
+ const existing = store.ruleVersions.get(input.ruleVersionId);
294
+ if (!existing) {
295
+ throw new Error("RULE_VERSION_NOT_FOUND");
296
+ }
297
+ const approved = {
298
+ ...existing,
299
+ status: "approved",
300
+ approvedBy: input.approver,
301
+ approvedAt: new Date
302
+ };
303
+ store.ruleVersions.set(approved.id, approved);
304
+ return approved;
305
+ }
306
+ async function publishSnapshot(input) {
307
+ const approved = [...store.ruleVersions.values()].filter((rv) => rv.status === "approved" && rv.jurisdiction === input.jurisdiction);
308
+ if (approved.length === 0) {
309
+ throw new Error("NO_APPROVED_RULES");
310
+ }
311
+ const includedRuleVersionIds = approved.map((rv) => rv.id).sort();
312
+ const id = stableId("snap", `${input.jurisdiction}_${input.asOfDate.toISOString().slice(0, 10)}_${includedRuleVersionIds.length}`);
313
+ const snapshot = {
314
+ id,
315
+ jurisdiction: input.jurisdiction,
316
+ asOfDate: input.asOfDate,
317
+ includedRuleVersionIds,
318
+ publishedAt: new Date
319
+ };
320
+ store.snapshots.set(id, snapshot);
321
+ return snapshot;
322
+ }
323
+ async function search(input) {
324
+ const snapshot = store.snapshots.get(input.snapshotId);
325
+ if (!snapshot) {
326
+ throw new Error("SNAPSHOT_NOT_FOUND");
327
+ }
328
+ if (snapshot.jurisdiction !== input.jurisdiction) {
329
+ throw new Error("JURISDICTION_MISMATCH");
330
+ }
331
+ const q = input.query.toLowerCase();
332
+ const tokens = q.split(/\s+/).map((t) => t.trim()).filter(Boolean);
333
+ const items = snapshot.includedRuleVersionIds.map((id) => store.ruleVersions.get(id)).filter((rv) => Boolean(rv)).filter((rv) => {
334
+ if (tokens.length === 0)
335
+ return true;
336
+ const hay = rv.content.toLowerCase();
337
+ return tokens.every((token) => hay.includes(token));
338
+ }).map((rv) => ({
339
+ ruleVersionId: rv.id,
340
+ excerpt: rv.content.slice(0, 120)
341
+ }));
342
+ return { items };
343
+ }
344
+ return {
345
+ createRule,
346
+ ingestSource,
347
+ upsertRuleVersion,
348
+ approveRuleVersion,
349
+ publishSnapshot,
350
+ search
351
+ };
352
+ }
353
+ // src/operations/kb.ts
354
+ import { defineCommand, defineQuery } from "@contractspec/lib.contracts";
355
+ import { ScalarTypeEnum as ScalarTypeEnum3, defineSchemaModel as defineSchemaModel3 } from "@contractspec/lib.schema";
356
+ var IngestSourceInput = defineSchemaModel3({
357
+ name: "KbIngestSourceInput",
358
+ description: "Ingest immutable source metadata referencing a stored file.",
359
+ fields: {
360
+ jurisdiction: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
361
+ authority: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
362
+ title: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
363
+ fetchedAt: { type: ScalarTypeEnum3.DateTime(), isOptional: false },
364
+ hash: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
365
+ fileId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
366
+ }
367
+ });
368
+ var UpsertRuleVersionInput = defineSchemaModel3({
369
+ name: "KbUpsertRuleVersionInput",
370
+ description: "Create a new draft rule version (immutable history).",
371
+ fields: {
372
+ ruleId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
373
+ content: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
374
+ sourceRefs: { type: SourceRefModel, isArray: true, isOptional: false }
375
+ }
376
+ });
377
+ var ApproveRuleVersionInput = defineSchemaModel3({
378
+ name: "KbApproveRuleVersionInput",
379
+ description: "Approve a rule version (human verification).",
380
+ fields: {
381
+ ruleVersionId: {
382
+ type: ScalarTypeEnum3.String_unsecure(),
383
+ isOptional: false
384
+ },
385
+ approver: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
386
+ }
387
+ });
388
+ var PublishSnapshotInput = defineSchemaModel3({
389
+ name: "KbPublishSnapshotInput",
390
+ description: "Publish a snapshot for a jurisdiction as-of a date.",
391
+ fields: {
392
+ jurisdiction: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
393
+ asOfDate: { type: ScalarTypeEnum3.DateTime(), isOptional: false }
394
+ }
395
+ });
396
+ var SearchKbInput = defineSchemaModel3({
397
+ name: "KbSearchInput",
398
+ description: "Search within a published snapshot.",
399
+ fields: {
400
+ snapshotId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
401
+ jurisdiction: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
402
+ query: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
403
+ }
404
+ });
405
+ var SearchKbResultItem = defineSchemaModel3({
406
+ name: "KbSearchResultItem",
407
+ description: "Search result referencing a specific rule version.",
408
+ fields: {
409
+ ruleVersionId: {
410
+ type: ScalarTypeEnum3.String_unsecure(),
411
+ isOptional: false
412
+ },
413
+ excerpt: { type: ScalarTypeEnum3.String_unsecure(), isOptional: true }
414
+ }
415
+ });
416
+ var SearchKbOutput = defineSchemaModel3({
417
+ name: "KbSearchOutput",
418
+ description: "Search results constrained to snapshot + jurisdiction.",
419
+ fields: {
420
+ items: { type: SearchKbResultItem, isArray: true, isOptional: false }
421
+ }
422
+ });
423
+ var KbIngestSourceContract = defineCommand({
424
+ meta: {
425
+ key: "kb.ingestSource",
426
+ title: "Ingest Source",
427
+ version: "1.0.0",
428
+ stability: "experimental",
429
+ owners: ["@examples"],
430
+ tags: ["knowledge", "sources", "ingestion"],
431
+ description: "Ingest immutable source document metadata.",
432
+ goal: "Store traceable source documents for curated KB.",
433
+ context: "Called when an admin uploads/records authoritative sources."
434
+ },
435
+ io: {
436
+ input: IngestSourceInput,
437
+ output: SourceDocumentModel
438
+ },
439
+ policy: { auth: "user" }
440
+ });
441
+ var KbUpsertRuleVersionContract = defineCommand({
442
+ meta: {
443
+ key: "kb.upsertRuleVersion",
444
+ title: "Upsert Rule Version",
445
+ version: "1.0.0",
446
+ stability: "experimental",
447
+ owners: ["@examples"],
448
+ tags: ["knowledge", "rules", "versioning"],
449
+ description: "Create a new draft rule version with source references.",
450
+ goal: "Propose curated knowledge updates with traceability.",
451
+ context: "Automation or curators propose draft rule versions."
452
+ },
453
+ io: {
454
+ input: UpsertRuleVersionInput,
455
+ output: RuleVersionModel,
456
+ errors: {
457
+ SOURCE_REFS_REQUIRED: {
458
+ description: "Rule version must cite at least one sourceRef",
459
+ http: 400,
460
+ gqlCode: "SOURCE_REFS_REQUIRED",
461
+ when: "sourceRefs is empty"
462
+ },
463
+ RULE_NOT_FOUND: {
464
+ description: "Rule does not exist",
465
+ http: 404,
466
+ gqlCode: "RULE_NOT_FOUND",
467
+ when: "ruleId is unknown"
468
+ }
469
+ }
470
+ },
471
+ policy: { auth: "user" }
472
+ });
473
+ var KbApproveRuleVersionContract = defineCommand({
474
+ meta: {
475
+ key: "kb.approveRuleVersion",
476
+ title: "Approve Rule Version",
477
+ version: "1.0.0",
478
+ stability: "experimental",
479
+ owners: ["@examples"],
480
+ tags: ["knowledge", "rules", "approval"],
481
+ description: "Approve a draft rule version.",
482
+ goal: "Human verification step before publishing snapshots.",
483
+ context: "Curators/experts approve proposed KB changes."
484
+ },
485
+ io: {
486
+ input: ApproveRuleVersionInput,
487
+ output: RuleVersionModel
488
+ },
489
+ policy: { auth: "user" }
490
+ });
491
+ var KbPublishSnapshotContract = defineCommand({
492
+ meta: {
493
+ key: "kb.publishSnapshot",
494
+ title: "Publish Snapshot",
495
+ version: "1.0.0",
496
+ stability: "experimental",
497
+ owners: ["@examples"],
498
+ tags: ["knowledge", "snapshots", "publishing"],
499
+ description: "Publish a KB snapshot for a jurisdiction.",
500
+ goal: "Create a stable snapshot that assistant answers can cite.",
501
+ context: "Publishing happens after approvals; snapshot is referenced by answers."
502
+ },
503
+ io: {
504
+ input: PublishSnapshotInput,
505
+ output: KBSnapshotModel,
506
+ errors: {
507
+ NO_APPROVED_RULES: {
508
+ description: "No approved rule versions available to publish",
509
+ http: 409,
510
+ gqlCode: "NO_APPROVED_RULES",
511
+ when: "jurisdiction has zero approved rule versions"
512
+ }
513
+ }
514
+ },
515
+ policy: { auth: "user" }
516
+ });
517
+ var KbSearchContract = defineQuery({
518
+ meta: {
519
+ key: "kb.search",
520
+ title: "Search KB",
521
+ version: "1.0.0",
522
+ stability: "experimental",
523
+ owners: ["@examples"],
524
+ tags: ["knowledge", "search", "snapshots"],
525
+ description: "Search within a published KB snapshot.",
526
+ goal: "Provide scoped retrieval for assistant answers.",
527
+ context: "Assistant queries curated rules from a specific snapshot."
528
+ },
529
+ io: {
530
+ input: SearchKbInput,
531
+ output: SearchKbOutput
532
+ },
533
+ policy: { auth: "user" }
534
+ });
535
+ // src/versioned-knowledge-base.feature.ts
536
+ import { defineFeature } from "@contractspec/lib.contracts";
537
+ var VersionedKnowledgeBaseFeature = defineFeature({
538
+ meta: {
539
+ key: "versioned-knowledge-base",
540
+ version: "1.0.0",
541
+ title: "Versioned Knowledge Base",
542
+ description: "Curated KB with immutable sources, rule versions, and published snapshots.",
543
+ domain: "knowledge",
544
+ owners: ["@examples"],
545
+ tags: ["knowledge", "versioning", "snapshots"],
546
+ stability: "experimental"
547
+ },
548
+ operations: [
549
+ { key: "kb.ingestSource", version: "1.0.0" },
550
+ { key: "kb.upsertRuleVersion", version: "1.0.0" },
551
+ { key: "kb.approveRuleVersion", version: "1.0.0" },
552
+ { key: "kb.publishSnapshot", version: "1.0.0" },
553
+ { key: "kb.search", version: "1.0.0" }
554
+ ],
555
+ events: [
556
+ { key: "kb.source.ingested", version: "1.0.0" },
557
+ { key: "kb.ruleVersion.created", version: "1.0.0" },
558
+ { key: "kb.ruleVersion.approved", version: "1.0.0" },
559
+ { key: "kb.snapshot.published", version: "1.0.0" }
560
+ ],
561
+ presentations: [],
562
+ opToPresentation: [],
563
+ presentationsTargets: [],
564
+ capabilities: {
565
+ requires: [{ key: "knowledge", version: "1.0.0" }]
566
+ }
567
+ });
568
+ export {
569
+ example_default as example,
570
+ createMemoryKbStore,
571
+ createMemoryKbHandlers,
572
+ VersionedKnowledgeBaseFeature,
573
+ SourceRefModel,
574
+ SourceDocumentModel,
575
+ RuleVersionModel,
576
+ RuleModel,
577
+ KbUpsertRuleVersionContract,
578
+ KbSourceIngestedEvent,
579
+ KbSnapshotPublishedEvent,
580
+ KbSearchContract,
581
+ KbRuleVersionCreatedEvent,
582
+ KbRuleVersionApprovedEvent,
583
+ KbPublishSnapshotContract,
584
+ KbIngestSourceContract,
585
+ KbApproveRuleVersionContract,
586
+ KBSnapshotModel
587
+ };
@@ -0,0 +1,44 @@
1
+ // src/docs/versioned-knowledge-base.docblock.ts
2
+ import { registerDocBlocks } from "@contractspec/lib.contracts/docs";
3
+ var docBlocks = [
4
+ {
5
+ id: "docs.examples.versioned-knowledge-base.goal",
6
+ title: "Versioned Knowledge Base — Goal",
7
+ summary: "Curated KB with immutable sources, versioned rules, and published snapshots referenced by answers.",
8
+ kind: "goal",
9
+ visibility: "public",
10
+ route: "/docs/examples/versioned-knowledge-base/goal",
11
+ tags: ["knowledge", "versioning", "snapshots", "traceability"],
12
+ body: `## Why it matters
13
+ - Separates raw sources from curated knowledge.
14
+ - Ensures assistant answers cite a published snapshot.
15
+ - Makes change review and safe regeneration possible.
16
+
17
+ ## Core invariants
18
+ - Sources are immutable and content-addressed (hash).
19
+ - Rule versions must cite at least one source.
20
+ - Snapshots include only approved rule versions.`
21
+ },
22
+ {
23
+ id: "docs.examples.versioned-knowledge-base.reference",
24
+ title: "Versioned Knowledge Base — Reference",
25
+ summary: "Entities, contracts, and events for the versioned KB example.",
26
+ kind: "reference",
27
+ visibility: "public",
28
+ route: "/docs/examples/versioned-knowledge-base",
29
+ tags: ["knowledge", "reference"],
30
+ body: `## Contracts
31
+ - kb.ingestSource
32
+ - kb.upsertRuleVersion
33
+ - kb.approveRuleVersion
34
+ - kb.publishSnapshot
35
+ - kb.search
36
+
37
+ ## Events
38
+ - kb.source.ingested
39
+ - kb.ruleVersion.created
40
+ - kb.ruleVersion.approved
41
+ - kb.snapshot.published`
42
+ }
43
+ ];
44
+ registerDocBlocks(docBlocks);
@@ -0,0 +1,44 @@
1
+ // src/docs/versioned-knowledge-base.docblock.ts
2
+ import { registerDocBlocks } from "@contractspec/lib.contracts/docs";
3
+ var docBlocks = [
4
+ {
5
+ id: "docs.examples.versioned-knowledge-base.goal",
6
+ title: "Versioned Knowledge Base — Goal",
7
+ summary: "Curated KB with immutable sources, versioned rules, and published snapshots referenced by answers.",
8
+ kind: "goal",
9
+ visibility: "public",
10
+ route: "/docs/examples/versioned-knowledge-base/goal",
11
+ tags: ["knowledge", "versioning", "snapshots", "traceability"],
12
+ body: `## Why it matters
13
+ - Separates raw sources from curated knowledge.
14
+ - Ensures assistant answers cite a published snapshot.
15
+ - Makes change review and safe regeneration possible.
16
+
17
+ ## Core invariants
18
+ - Sources are immutable and content-addressed (hash).
19
+ - Rule versions must cite at least one source.
20
+ - Snapshots include only approved rule versions.`
21
+ },
22
+ {
23
+ id: "docs.examples.versioned-knowledge-base.reference",
24
+ title: "Versioned Knowledge Base — Reference",
25
+ summary: "Entities, contracts, and events for the versioned KB example.",
26
+ kind: "reference",
27
+ visibility: "public",
28
+ route: "/docs/examples/versioned-knowledge-base",
29
+ tags: ["knowledge", "reference"],
30
+ body: `## Contracts
31
+ - kb.ingestSource
32
+ - kb.upsertRuleVersion
33
+ - kb.approveRuleVersion
34
+ - kb.publishSnapshot
35
+ - kb.search
36
+
37
+ ## Events
38
+ - kb.source.ingested
39
+ - kb.ruleVersion.created
40
+ - kb.ruleVersion.approved
41
+ - kb.snapshot.published`
42
+ }
43
+ ];
44
+ registerDocBlocks(docBlocks);