@contractspec/example.kb-update-pipeline 3.7.17 → 3.7.19

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 (45) hide show
  1. package/.turbo/turbo-build.log +45 -45
  2. package/CHANGELOG.md +17 -0
  3. package/dist/browser/docs/index.js +3 -27
  4. package/dist/browser/docs/kb-update-pipeline.docblock.js +3 -27
  5. package/dist/browser/entities/index.js +1 -56
  6. package/dist/browser/entities/models.js +1 -56
  7. package/dist/browser/events.js +1 -128
  8. package/dist/browser/example.js +1 -35
  9. package/dist/browser/handlers/index.js +1 -109
  10. package/dist/browser/handlers/memory.handlers.js +1 -109
  11. package/dist/browser/index.js +3 -636
  12. package/dist/browser/kb-update-pipeline.feature.js +1 -68
  13. package/dist/browser/operations/index.js +1 -199
  14. package/dist/browser/operations/pipeline.js +1 -199
  15. package/dist/browser/presentations.js +1 -123
  16. package/dist/browser/tests/operations.test-spec.js +1 -85
  17. package/dist/docs/index.js +3 -27
  18. package/dist/docs/kb-update-pipeline.docblock.js +3 -27
  19. package/dist/entities/index.js +1 -56
  20. package/dist/entities/models.js +1 -56
  21. package/dist/events.js +1 -128
  22. package/dist/example.js +1 -35
  23. package/dist/handlers/index.js +1 -109
  24. package/dist/handlers/memory.handlers.js +1 -109
  25. package/dist/index.js +3 -636
  26. package/dist/kb-update-pipeline.feature.js +1 -68
  27. package/dist/node/docs/index.js +3 -27
  28. package/dist/node/docs/kb-update-pipeline.docblock.js +3 -27
  29. package/dist/node/entities/index.js +1 -56
  30. package/dist/node/entities/models.js +1 -56
  31. package/dist/node/events.js +1 -128
  32. package/dist/node/example.js +1 -35
  33. package/dist/node/handlers/index.js +1 -109
  34. package/dist/node/handlers/memory.handlers.js +1 -109
  35. package/dist/node/index.js +3 -636
  36. package/dist/node/kb-update-pipeline.feature.js +1 -68
  37. package/dist/node/operations/index.js +1 -199
  38. package/dist/node/operations/pipeline.js +1 -199
  39. package/dist/node/presentations.js +1 -123
  40. package/dist/node/tests/operations.test-spec.js +1 -85
  41. package/dist/operations/index.js +1 -199
  42. package/dist/operations/pipeline.js +1 -199
  43. package/dist/presentations.js +1 -123
  44. package/dist/tests/operations.test-spec.js +1 -85
  45. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -1,33 +1,12 @@
1
1
  // @bun
2
- // src/docs/kb-update-pipeline.docblock.ts
3
- import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
4
- var docBlocks = [
5
- {
6
- id: "docs.examples.kb-update-pipeline.goal",
7
- title: "KB Update Pipeline \u2014 Goal",
8
- summary: "Automation proposes KB patches; humans verify; publishing is blocked until approvals are complete.",
9
- kind: "goal",
10
- visibility: "public",
11
- route: "/docs/examples/kb-update-pipeline/goal",
12
- tags: ["knowledge", "pipeline", "hitl", "audit"],
13
- body: `## Why it matters
2
+ import{registerDocBlocks as I}from"@contractspec/lib.contracts-spec/docs";var v=[{id:"docs.examples.kb-update-pipeline.goal",title:"KB Update Pipeline \u2014 Goal",summary:"Automation proposes KB patches; humans verify; publishing is blocked until approvals are complete.",kind:"goal",visibility:"public",route:"/docs/examples/kb-update-pipeline/goal",tags:["knowledge","pipeline","hitl","audit"],body:`## Why it matters
14
3
  - Keeps humans as the verifiers (HITL) while automation does the busywork.
15
4
  - Produces an auditable chain: source change -> diff -> proposal -> review -> publish.
16
5
 
17
6
  ## Guardrails
18
7
  - High-risk changes require expert approval.
19
8
  - Publishing fails if any included rule versions are not approved.
20
- - Review requests emit notifications/events.`
21
- },
22
- {
23
- id: "docs.examples.kb-update-pipeline.reference",
24
- title: "KB Update Pipeline \u2014 Reference",
25
- summary: "Entities, contracts, and events for the KB update pipeline example.",
26
- kind: "reference",
27
- visibility: "public",
28
- route: "/docs/examples/kb-update-pipeline",
29
- tags: ["knowledge", "reference"],
30
- body: `## Contracts
9
+ - Review requests emit notifications/events.`},{id:"docs.examples.kb-update-pipeline.reference",title:"KB Update Pipeline \u2014 Reference",summary:"Entities, contracts, and events for the KB update pipeline example.",kind:"reference",visibility:"public",route:"/docs/examples/kb-update-pipeline",tags:["knowledge","reference"],body:`## Contracts
31
10
  - kbPipeline.runWatch
32
11
  - kbPipeline.createReviewTask
33
12
  - kbPipeline.submitDecision
@@ -38,616 +17,4 @@ var docBlocks = [
38
17
  - kb.change.summarized
39
18
  - kb.patch.proposed
40
19
  - kb.review.requested
41
- - kb.review.decided`
42
- }
43
- ];
44
- registerDocBlocks(docBlocks);
45
- // src/entities/models.ts
46
- import {
47
- defineEnum,
48
- defineSchemaModel,
49
- ScalarTypeEnum
50
- } from "@contractspec/lib.schema";
51
- var ChangeRiskLevelEnum = defineEnum("ChangeRiskLevel", [
52
- "low",
53
- "medium",
54
- "high"
55
- ]);
56
- var ReviewAssignedRoleEnum = defineEnum("ReviewAssignedRole", [
57
- "curator",
58
- "expert"
59
- ]);
60
- var ReviewDecisionEnum = defineEnum("ReviewDecision", [
61
- "approve",
62
- "reject"
63
- ]);
64
- var ChangeCandidateModel = defineSchemaModel({
65
- name: "ChangeCandidate",
66
- description: "Candidate change detected in a source document.",
67
- fields: {
68
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
69
- sourceDocumentId: {
70
- type: ScalarTypeEnum.String_unsecure(),
71
- isOptional: false
72
- },
73
- detectedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
74
- diffSummary: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
75
- riskLevel: { type: ChangeRiskLevelEnum, isOptional: false }
76
- }
77
- });
78
- var ReviewTaskModel = defineSchemaModel({
79
- name: "ReviewTask",
80
- description: "Human verification task for a change candidate.",
81
- fields: {
82
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
83
- changeCandidateId: {
84
- type: ScalarTypeEnum.String_unsecure(),
85
- isOptional: false
86
- },
87
- status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
88
- assignedRole: { type: ReviewAssignedRoleEnum, isOptional: false },
89
- decision: { type: ReviewDecisionEnum, isOptional: true },
90
- decidedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
91
- decidedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
92
- }
93
- });
94
- // src/events.ts
95
- import { defineEvent, StabilityEnum } from "@contractspec/lib.contracts-spec";
96
- import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
97
- var KbChangeDetectedPayload = defineSchemaModel2({
98
- name: "KbChangeDetectedPayload",
99
- description: "Emitted when a source change is detected.",
100
- fields: {
101
- changeCandidateId: {
102
- type: ScalarTypeEnum2.String_unsecure(),
103
- isOptional: false
104
- },
105
- sourceDocumentId: {
106
- type: ScalarTypeEnum2.String_unsecure(),
107
- isOptional: false
108
- },
109
- riskLevel: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
110
- }
111
- });
112
- var KbChangeDetectedEvent = defineEvent({
113
- meta: {
114
- key: "kb.change.detected",
115
- version: "1.0.0",
116
- description: "KB source change detected.",
117
- stability: StabilityEnum.Experimental,
118
- owners: [],
119
- tags: []
120
- },
121
- payload: KbChangeDetectedPayload
122
- });
123
- var KbChangeSummarizedPayload = defineSchemaModel2({
124
- name: "KbChangeSummarizedPayload",
125
- description: "Emitted when a change summary is produced.",
126
- fields: {
127
- changeCandidateId: {
128
- type: ScalarTypeEnum2.String_unsecure(),
129
- isOptional: false
130
- },
131
- summary: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
132
- riskLevel: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
133
- }
134
- });
135
- var KbChangeSummarizedEvent = defineEvent({
136
- meta: {
137
- key: "kb.change.summarized",
138
- version: "1.0.0",
139
- description: "KB change summarized.",
140
- stability: StabilityEnum.Experimental,
141
- owners: [],
142
- tags: []
143
- },
144
- payload: KbChangeSummarizedPayload
145
- });
146
- var KbPatchProposedPayload = defineSchemaModel2({
147
- name: "KbPatchProposedPayload",
148
- description: "Emitted when draft rule patches are proposed.",
149
- fields: {
150
- changeCandidateId: {
151
- type: ScalarTypeEnum2.String_unsecure(),
152
- isOptional: false
153
- },
154
- proposedRuleVersionIds: {
155
- type: ScalarTypeEnum2.String_unsecure(),
156
- isArray: true,
157
- isOptional: false
158
- }
159
- }
160
- });
161
- var KbPatchProposedEvent = defineEvent({
162
- meta: {
163
- key: "kb.patch.proposed",
164
- version: "1.0.0",
165
- description: "KB rule patch proposed (draft versions created).",
166
- stability: StabilityEnum.Experimental,
167
- owners: [],
168
- tags: []
169
- },
170
- payload: KbPatchProposedPayload
171
- });
172
- var KbReviewRequestedPayload = defineSchemaModel2({
173
- name: "KbReviewRequestedPayload",
174
- description: "Emitted when a review is requested.",
175
- fields: {
176
- reviewTaskId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
177
- changeCandidateId: {
178
- type: ScalarTypeEnum2.String_unsecure(),
179
- isOptional: false
180
- },
181
- assignedRole: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
182
- }
183
- });
184
- var KbReviewRequestedEvent = defineEvent({
185
- meta: {
186
- key: "kb.review.requested",
187
- version: "1.0.0",
188
- description: "KB review requested.",
189
- stability: StabilityEnum.Experimental,
190
- owners: [],
191
- tags: []
192
- },
193
- payload: KbReviewRequestedPayload
194
- });
195
- var KbReviewDecidedPayload = defineSchemaModel2({
196
- name: "KbReviewDecidedPayload",
197
- description: "Emitted when a review task is decided.",
198
- fields: {
199
- reviewTaskId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
200
- decision: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
201
- decidedBy: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
202
- }
203
- });
204
- var KbReviewDecidedEvent = defineEvent({
205
- meta: {
206
- key: "kb.review.decided",
207
- version: "1.0.0",
208
- description: "KB review decided.",
209
- stability: StabilityEnum.Experimental,
210
- owners: [],
211
- tags: []
212
- },
213
- payload: KbReviewDecidedPayload
214
- });
215
-
216
- // src/example.ts
217
- import { defineExample } from "@contractspec/lib.contracts-spec";
218
- var example = defineExample({
219
- meta: {
220
- key: "kb-update-pipeline",
221
- version: "1.0.0",
222
- title: "KB Update Pipeline",
223
- description: "Automation proposes KB updates; humans verify; everything audited and notified.",
224
- kind: "knowledge",
225
- visibility: "public",
226
- stability: "experimental",
227
- owners: ["@platform.core"],
228
- tags: ["knowledge", "pipeline", "hitl", "audit"]
229
- },
230
- docs: {
231
- rootDocId: "docs.examples.kb-update-pipeline"
232
- },
233
- entrypoints: {
234
- packageName: "@contractspec/example.kb-update-pipeline",
235
- feature: "./feature",
236
- contracts: "./contracts",
237
- handlers: "./handlers",
238
- docs: "./docs"
239
- },
240
- surfaces: {
241
- templates: true,
242
- sandbox: { enabled: true, modes: ["markdown", "specs", "builder"] },
243
- studio: { enabled: true, installable: true },
244
- mcp: { enabled: true }
245
- }
246
- });
247
- var example_default = example;
248
-
249
- // src/handlers/memory.handlers.ts
250
- function createPipelineMemoryStore() {
251
- return {
252
- candidates: new Map,
253
- reviewTasks: new Map,
254
- proposedRuleVersionIdsByCandidate: new Map,
255
- approvedRuleVersionIds: new Set,
256
- notifications: []
257
- };
258
- }
259
- function stableId(prefix, value) {
260
- return `${prefix}_${value.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
261
- }
262
- function createPipelineMemoryHandlers(store) {
263
- async function runWatch(input) {
264
- const candidates = [...store.candidates.values()].filter((c) => c.sourceDocumentId.startsWith(`${input.jurisdiction}_`) || true);
265
- return { candidates };
266
- }
267
- async function createReviewTask(input) {
268
- const candidate = store.candidates.get(input.changeCandidateId);
269
- if (!candidate)
270
- throw new Error("CHANGE_CANDIDATE_NOT_FOUND");
271
- const assignedRole = candidate.riskLevel === "high" ? "expert" : "curator";
272
- const id = stableId("review", input.changeCandidateId);
273
- const task = {
274
- id,
275
- changeCandidateId: input.changeCandidateId,
276
- status: "open",
277
- assignedRole,
278
- decision: undefined,
279
- decidedAt: undefined,
280
- decidedBy: undefined
281
- };
282
- store.reviewTasks.set(id, task);
283
- store.notifications.push({
284
- kind: "kb.review.requested",
285
- reviewTaskId: id,
286
- changeCandidateId: input.changeCandidateId,
287
- assignedRole,
288
- createdAt: new Date
289
- });
290
- return task;
291
- }
292
- async function proposeRulePatch(input) {
293
- if (!store.candidates.has(input.changeCandidateId)) {
294
- throw new Error("CHANGE_CANDIDATE_NOT_FOUND");
295
- }
296
- store.proposedRuleVersionIdsByCandidate.set(input.changeCandidateId, [
297
- ...input.proposedRuleVersionIds
298
- ]);
299
- return { proposedRuleVersionIds: [...input.proposedRuleVersionIds] };
300
- }
301
- async function markRuleVersionApproved(input) {
302
- store.approvedRuleVersionIds.add(input.ruleVersionId);
303
- return { ruleVersionId: input.ruleVersionId };
304
- }
305
- async function submitDecision(input) {
306
- const task = store.reviewTasks.get(input.reviewTaskId);
307
- if (!task)
308
- throw new Error("REVIEW_TASK_NOT_FOUND");
309
- const candidate = store.candidates.get(task.changeCandidateId);
310
- if (!candidate)
311
- throw new Error("CHANGE_CANDIDATE_NOT_FOUND");
312
- if (candidate.riskLevel === "high" && input.decision === "approve") {
313
- if (input.decidedByRole !== "expert")
314
- throw new Error("FORBIDDEN_ROLE");
315
- }
316
- const decided = {
317
- ...task,
318
- status: "decided",
319
- decision: input.decision,
320
- decidedAt: new Date,
321
- decidedBy: input.decidedBy
322
- };
323
- store.reviewTasks.set(decided.id, decided);
324
- return decided;
325
- }
326
- async function publishIfReady(_input) {
327
- const openTasks = [...store.reviewTasks.values()].filter((t) => t.status !== "decided");
328
- if (openTasks.length) {
329
- throw new Error("NOT_READY");
330
- }
331
- const rejected = [...store.reviewTasks.values()].some((t) => t.decision === "reject");
332
- if (rejected)
333
- return { published: false, reason: "REJECTED" };
334
- for (const task of store.reviewTasks.values()) {
335
- if (task.decision !== "approve")
336
- continue;
337
- const proposed = store.proposedRuleVersionIdsByCandidate.get(task.changeCandidateId) ?? [];
338
- const unapproved = proposed.filter((id) => !store.approvedRuleVersionIds.has(id));
339
- if (unapproved.length) {
340
- throw new Error("NOT_READY");
341
- }
342
- }
343
- return { published: true };
344
- }
345
- return {
346
- runWatch,
347
- createReviewTask,
348
- proposeRulePatch,
349
- markRuleVersionApproved,
350
- submitDecision,
351
- publishIfReady
352
- };
353
- }
354
- // src/kb-update-pipeline.feature.ts
355
- import { defineFeature } from "@contractspec/lib.contracts-spec";
356
- var KbUpdatePipelineFeature = defineFeature({
357
- meta: {
358
- key: "kb-update-pipeline",
359
- version: "1.0.0",
360
- title: "KB Update Pipeline (HITL)",
361
- description: "Automation proposes KB patches; humans verify; publishing is blocked until approvals are complete.",
362
- domain: "knowledge",
363
- owners: ["@examples"],
364
- tags: ["knowledge", "pipeline", "hitl", "audit", "notifications"],
365
- stability: "experimental"
366
- },
367
- operations: [
368
- { key: "kbPipeline.runWatch", version: "1.0.0" },
369
- { key: "kbPipeline.createReviewTask", version: "1.0.0" },
370
- { key: "kbPipeline.submitDecision", version: "1.0.0" },
371
- { key: "kbPipeline.publishIfReady", version: "1.0.0" }
372
- ],
373
- events: [
374
- { key: "kb.change.detected", version: "1.0.0" },
375
- { key: "kb.change.summarized", version: "1.0.0" },
376
- { key: "kb.patch.proposed", version: "1.0.0" },
377
- { key: "kb.review.requested", version: "1.0.0" },
378
- { key: "kb.review.decided", version: "1.0.0" }
379
- ],
380
- presentations: [
381
- { key: "kb.dashboard", version: "1.0.0" },
382
- { key: "kb.review.list", version: "1.0.0" },
383
- { key: "kb.review.form", version: "1.0.0" }
384
- ],
385
- opToPresentation: [
386
- {
387
- op: { key: "kbPipeline.runWatch", version: "1.0.0" },
388
- pres: { key: "kb.dashboard", version: "1.0.0" }
389
- },
390
- {
391
- op: { key: "kbPipeline.createReviewTask", version: "1.0.0" },
392
- pres: { key: "kb.review.list", version: "1.0.0" }
393
- },
394
- {
395
- op: { key: "kbPipeline.submitDecision", version: "1.0.0" },
396
- pres: { key: "kb.review.form", version: "1.0.0" }
397
- }
398
- ],
399
- presentationsTargets: [
400
- { key: "kb.dashboard", version: "1.0.0", targets: ["react", "markdown"] },
401
- { key: "kb.review.list", version: "1.0.0", targets: ["react", "markdown"] },
402
- { key: "kb.review.form", version: "1.0.0", targets: ["react"] }
403
- ],
404
- capabilities: {
405
- requires: [
406
- { key: "identity", version: "1.0.0" },
407
- { key: "notifications", version: "1.0.0" },
408
- { key: "audit-trail", version: "1.0.0" }
409
- ]
410
- },
411
- knowledge: [{ key: "kb.knowledge.rules", version: "1.0.0" }],
412
- telemetry: [{ key: "kb-pipeline.telemetry", version: "1.0.0" }],
413
- jobs: [{ key: "kb-pipeline.job.watch", version: "1.0.0" }],
414
- docs: [
415
- "docs.examples.kb-update-pipeline.goal",
416
- "docs.examples.kb-update-pipeline.reference"
417
- ]
418
- });
419
-
420
- // src/operations/pipeline.ts
421
- import { defineCommand } from "@contractspec/lib.contracts-spec";
422
- import { defineSchemaModel as defineSchemaModel3, ScalarTypeEnum as ScalarTypeEnum3 } from "@contractspec/lib.schema";
423
- var RunWatchInput = defineSchemaModel3({
424
- name: "KbPipelineRunWatchInput",
425
- description: "Trigger a watch cycle for KB sources (demo).",
426
- fields: {
427
- jurisdiction: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
428
- }
429
- });
430
- var RunWatchOutput = defineSchemaModel3({
431
- name: "KbPipelineRunWatchOutput",
432
- description: "Output containing detected changes.",
433
- fields: {
434
- candidates: {
435
- type: ChangeCandidateModel,
436
- isArray: true,
437
- isOptional: false
438
- }
439
- }
440
- });
441
- var CreateReviewTaskInput = defineSchemaModel3({
442
- name: "KbPipelineCreateReviewTaskInput",
443
- description: "Create a review task for a change candidate.",
444
- fields: {
445
- changeCandidateId: {
446
- type: ScalarTypeEnum3.String_unsecure(),
447
- isOptional: false
448
- }
449
- }
450
- });
451
- var SubmitDecisionInput = defineSchemaModel3({
452
- name: "KbPipelineSubmitDecisionInput",
453
- description: "Submit a decision for a review task.",
454
- fields: {
455
- reviewTaskId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
456
- decision: { type: ReviewDecisionEnum, isOptional: false },
457
- decidedBy: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
458
- decidedByRole: {
459
- type: ScalarTypeEnum3.String_unsecure(),
460
- isOptional: false
461
- }
462
- }
463
- });
464
- var PublishIfReadyInput = defineSchemaModel3({
465
- name: "KbPipelinePublishIfReadyInput",
466
- description: "Publish snapshot if approvals are satisfied for a jurisdiction.",
467
- fields: {
468
- jurisdiction: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
469
- }
470
- });
471
- var PublishIfReadyOutput = defineSchemaModel3({
472
- name: "KbPipelinePublishIfReadyOutput",
473
- description: "Output for publish-if-ready operation.",
474
- fields: {
475
- published: { type: ScalarTypeEnum3.Boolean(), isOptional: false },
476
- reason: { type: ScalarTypeEnum3.String_unsecure(), isOptional: true }
477
- }
478
- });
479
- var KbPipelineRunWatchContract = defineCommand({
480
- meta: {
481
- key: "kbPipeline.runWatch",
482
- version: "1.0.0",
483
- stability: "experimental",
484
- owners: ["@examples"],
485
- tags: ["knowledge", "pipeline", "jobs"],
486
- description: "Detect source changes and create change candidates.",
487
- goal: "Automate discovery of updates needing review.",
488
- context: "Scheduled job or manual trigger in demos."
489
- },
490
- io: { input: RunWatchInput, output: RunWatchOutput },
491
- policy: { auth: "user" }
492
- });
493
- var KbPipelineCreateReviewTaskContract = defineCommand({
494
- meta: {
495
- key: "kbPipeline.createReviewTask",
496
- version: "1.0.0",
497
- stability: "experimental",
498
- owners: ["@examples"],
499
- tags: ["knowledge", "pipeline", "hitl"],
500
- description: "Create a review task for a detected change.",
501
- goal: "Route work to human verifiers.",
502
- context: "Called after change detection or manual selection."
503
- },
504
- io: { input: CreateReviewTaskInput, output: ReviewTaskModel },
505
- policy: { auth: "user" }
506
- });
507
- var KbPipelineSubmitDecisionContract = defineCommand({
508
- meta: {
509
- key: "kbPipeline.submitDecision",
510
- version: "1.0.0",
511
- stability: "experimental",
512
- owners: ["@examples"],
513
- tags: ["knowledge", "pipeline", "hitl", "rbac"],
514
- description: "Submit approve/reject decision for a review task.",
515
- goal: "Ensure humans verify before publishing.",
516
- context: "Curator/expert reviews and decides."
517
- },
518
- io: {
519
- input: SubmitDecisionInput,
520
- output: ReviewTaskModel,
521
- errors: {
522
- FORBIDDEN_ROLE: {
523
- description: "Role not allowed to approve the given risk level",
524
- http: 403,
525
- gqlCode: "FORBIDDEN_ROLE",
526
- when: "curator attempts to approve a high-risk change"
527
- },
528
- REVIEW_TASK_NOT_FOUND: {
529
- description: "Review task not found",
530
- http: 404,
531
- gqlCode: "REVIEW_TASK_NOT_FOUND",
532
- when: "reviewTaskId is invalid"
533
- }
534
- }
535
- },
536
- policy: { auth: "user" }
537
- });
538
- var KbPipelinePublishIfReadyContract = defineCommand({
539
- meta: {
540
- key: "kbPipeline.publishIfReady",
541
- version: "1.0.0",
542
- stability: "experimental",
543
- owners: ["@examples"],
544
- tags: ["knowledge", "pipeline", "publishing"],
545
- description: "Publish snapshot if ready (all approvals satisfied).",
546
- goal: "Prevent publishing until all required approvals exist.",
547
- context: "Called by job or UI to attempt publish."
548
- },
549
- io: {
550
- input: PublishIfReadyInput,
551
- output: PublishIfReadyOutput,
552
- errors: {
553
- NOT_READY: {
554
- description: "Publishing is blocked because approvals are incomplete",
555
- http: 409,
556
- gqlCode: "NOT_READY",
557
- when: "there are open review tasks or unapproved rule versions"
558
- }
559
- }
560
- },
561
- policy: { auth: "user" }
562
- });
563
- // src/presentations.ts
564
- import {
565
- definePresentation,
566
- StabilityEnum as StabilityEnum2
567
- } from "@contractspec/lib.contracts-spec";
568
- var KbDashboardPresentation = definePresentation({
569
- meta: {
570
- key: "kb.dashboard",
571
- version: "1.0.0",
572
- title: "KB Update Dashboard",
573
- description: "Overview of KB change candidates and review tasks.",
574
- domain: "knowledge",
575
- owners: ["@examples"],
576
- tags: ["dashboard", "knowledge"],
577
- stability: StabilityEnum2.Experimental,
578
- goal: "Visualize status",
579
- context: "Dashboard"
580
- },
581
- source: {
582
- type: "component",
583
- framework: "react",
584
- componentKey: "KbDashboard",
585
- props: ChangeCandidateModel
586
- },
587
- targets: ["react", "markdown"]
588
- });
589
- var KbReviewListPresentation = definePresentation({
590
- meta: {
591
- key: "kb.review.list",
592
- version: "1.0.0",
593
- title: "Review Tasks",
594
- description: "List of pending review tasks for the current user.",
595
- domain: "knowledge",
596
- owners: ["@examples"],
597
- tags: ["list", "review"],
598
- stability: StabilityEnum2.Experimental,
599
- goal: "List tasks",
600
- context: "Inbox"
601
- },
602
- source: {
603
- type: "component",
604
- framework: "react",
605
- componentKey: "ReviewTaskList",
606
- props: ReviewTaskModel
607
- },
608
- targets: ["react", "markdown"]
609
- });
610
- var KbReviewFormPresentation = definePresentation({
611
- meta: {
612
- key: "kb.review.form",
613
- version: "1.0.0",
614
- title: "Review Change",
615
- description: "Form to approve or reject a KB change candidate.",
616
- domain: "knowledge",
617
- owners: ["@examples"],
618
- tags: ["form", "review"],
619
- stability: StabilityEnum2.Experimental,
620
- goal: "Review",
621
- context: "Detail"
622
- },
623
- source: {
624
- type: "component",
625
- framework: "react",
626
- componentKey: "ReviewDecisionForm",
627
- props: ReviewTaskModel
628
- },
629
- targets: ["react"]
630
- });
631
- export {
632
- example_default as example,
633
- createPipelineMemoryStore,
634
- createPipelineMemoryHandlers,
635
- ReviewTaskModel,
636
- ReviewDecisionEnum,
637
- ReviewAssignedRoleEnum,
638
- KbUpdatePipelineFeature,
639
- KbReviewRequestedEvent,
640
- KbReviewListPresentation,
641
- KbReviewFormPresentation,
642
- KbReviewDecidedEvent,
643
- KbPipelineSubmitDecisionContract,
644
- KbPipelineRunWatchContract,
645
- KbPipelinePublishIfReadyContract,
646
- KbPipelineCreateReviewTaskContract,
647
- KbPatchProposedEvent,
648
- KbDashboardPresentation,
649
- KbChangeSummarizedEvent,
650
- KbChangeDetectedEvent,
651
- ChangeRiskLevelEnum,
652
- ChangeCandidateModel
653
- };
20
+ - kb.review.decided`}];I(v);import{defineEnum as Z,defineSchemaModel as D,ScalarTypeEnum as A}from"@contractspec/lib.schema";var R=Z("ChangeRiskLevel",["low","medium","high"]),k=Z("ReviewAssignedRole",["curator","expert"]),$=Z("ReviewDecision",["approve","reject"]),N=D({name:"ChangeCandidate",description:"Candidate change detected in a source document.",fields:{id:{type:A.String_unsecure(),isOptional:!1},sourceDocumentId:{type:A.String_unsecure(),isOptional:!1},detectedAt:{type:A.DateTime(),isOptional:!1},diffSummary:{type:A.String_unsecure(),isOptional:!1},riskLevel:{type:R,isOptional:!1}}}),H=D({name:"ReviewTask",description:"Human verification task for a change candidate.",fields:{id:{type:A.String_unsecure(),isOptional:!1},changeCandidateId:{type:A.String_unsecure(),isOptional:!1},status:{type:A.String_unsecure(),isOptional:!1},assignedRole:{type:k,isOptional:!1},decision:{type:$,isOptional:!0},decidedAt:{type:A.DateTime(),isOptional:!0},decidedBy:{type:A.String_unsecure(),isOptional:!0}}});import{defineEvent as f,StabilityEnum as G}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as J,ScalarTypeEnum as _}from"@contractspec/lib.schema";var P=J({name:"KbChangeDetectedPayload",description:"Emitted when a source change is detected.",fields:{changeCandidateId:{type:_.String_unsecure(),isOptional:!1},sourceDocumentId:{type:_.String_unsecure(),isOptional:!1},riskLevel:{type:_.String_unsecure(),isOptional:!1}}}),_x=f({meta:{key:"kb.change.detected",version:"1.0.0",description:"KB source change detected.",stability:G.Experimental,owners:[],tags:[]},payload:P}),h=J({name:"KbChangeSummarizedPayload",description:"Emitted when a change summary is produced.",fields:{changeCandidateId:{type:_.String_unsecure(),isOptional:!1},summary:{type:_.String_unsecure(),isOptional:!1},riskLevel:{type:_.String_unsecure(),isOptional:!1}}}),Ax=f({meta:{key:"kb.change.summarized",version:"1.0.0",description:"KB change summarized.",stability:G.Experimental,owners:[],tags:[]},payload:h}),M=J({name:"KbPatchProposedPayload",description:"Emitted when draft rule patches are proposed.",fields:{changeCandidateId:{type:_.String_unsecure(),isOptional:!1},proposedRuleVersionIds:{type:_.String_unsecure(),isArray:!0,isOptional:!1}}}),Lx=f({meta:{key:"kb.patch.proposed",version:"1.0.0",description:"KB rule patch proposed (draft versions created).",stability:G.Experimental,owners:[],tags:[]},payload:M}),y=J({name:"KbReviewRequestedPayload",description:"Emitted when a review is requested.",fields:{reviewTaskId:{type:_.String_unsecure(),isOptional:!1},changeCandidateId:{type:_.String_unsecure(),isOptional:!1},assignedRole:{type:_.String_unsecure(),isOptional:!1}}}),jx=f({meta:{key:"kb.review.requested",version:"1.0.0",description:"KB review requested.",stability:G.Experimental,owners:[],tags:[]},payload:y}),T=J({name:"KbReviewDecidedPayload",description:"Emitted when a review task is decided.",fields:{reviewTaskId:{type:_.String_unsecure(),isOptional:!1},decision:{type:_.String_unsecure(),isOptional:!1},decidedBy:{type:_.String_unsecure(),isOptional:!1}}}),Bx=f({meta:{key:"kb.review.decided",version:"1.0.0",description:"KB review decided.",stability:G.Experimental,owners:[],tags:[]},payload:T});import{defineExample as o}from"@contractspec/lib.contracts-spec";var m=o({meta:{key:"kb-update-pipeline",version:"1.0.0",title:"KB Update Pipeline",description:"Automation proposes KB updates; humans verify; everything audited and notified.",kind:"knowledge",visibility:"public",stability:"experimental",owners:["@platform.core"],tags:["knowledge","pipeline","hitl","audit"]},docs:{rootDocId:"docs.examples.kb-update-pipeline"},entrypoints:{packageName:"@contractspec/example.kb-update-pipeline",feature:"./feature",contracts:"./contracts",handlers:"./handlers",docs:"./docs"},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["markdown","specs","builder"]},studio:{enabled:!0,installable:!0},mcp:{enabled:!0}}}),r=m;function Gx(){return{candidates:new Map,reviewTasks:new Map,proposedRuleVersionIdsByCandidate:new Map,approvedRuleVersionIds:new Set,notifications:[]}}function b(g,X){return`${g}_${X.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function Jx(g){async function X(x){return{candidates:[...g.candidates.values()].filter((j)=>j.sourceDocumentId.startsWith(`${x.jurisdiction}_`)||!0)}}async function F(x){let L=g.candidates.get(x.changeCandidateId);if(!L)throw Error("CHANGE_CANDIDATE_NOT_FOUND");let j=L.riskLevel==="high"?"expert":"curator",O=b("review",x.changeCandidateId),Y={id:O,changeCandidateId:x.changeCandidateId,status:"open",assignedRole:j,decision:void 0,decidedAt:void 0,decidedBy:void 0};return g.reviewTasks.set(O,Y),g.notifications.push({kind:"kb.review.requested",reviewTaskId:O,changeCandidateId:x.changeCandidateId,assignedRole:j,createdAt:new Date}),Y}async function V(x){if(!g.candidates.has(x.changeCandidateId))throw Error("CHANGE_CANDIDATE_NOT_FOUND");return g.proposedRuleVersionIdsByCandidate.set(x.changeCandidateId,[...x.proposedRuleVersionIds]),{proposedRuleVersionIds:[...x.proposedRuleVersionIds]}}async function w(x){return g.approvedRuleVersionIds.add(x.ruleVersionId),{ruleVersionId:x.ruleVersionId}}async function C(x){let L=g.reviewTasks.get(x.reviewTaskId);if(!L)throw Error("REVIEW_TASK_NOT_FOUND");let j=g.candidates.get(L.changeCandidateId);if(!j)throw Error("CHANGE_CANDIDATE_NOT_FOUND");if(j.riskLevel==="high"&&x.decision==="approve"){if(x.decidedByRole!=="expert")throw Error("FORBIDDEN_ROLE")}let O={...L,status:"decided",decision:x.decision,decidedAt:new Date,decidedBy:x.decidedBy};return g.reviewTasks.set(O.id,O),O}async function K(x){if([...g.reviewTasks.values()].filter((O)=>O.status!=="decided").length)throw Error("NOT_READY");if([...g.reviewTasks.values()].some((O)=>O.decision==="reject"))return{published:!1,reason:"REJECTED"};for(let O of g.reviewTasks.values()){if(O.decision!=="approve")continue;if((g.proposedRuleVersionIdsByCandidate.get(O.changeCandidateId)??[]).filter((W)=>!g.approvedRuleVersionIds.has(W)).length)throw Error("NOT_READY")}return{published:!0}}return{runWatch:X,createReviewTask:F,proposeRulePatch:V,markRuleVersionApproved:w,submitDecision:C,publishIfReady:K}}import{defineFeature as E}from"@contractspec/lib.contracts-spec";var Zx=E({meta:{key:"kb-update-pipeline",version:"1.0.0",title:"KB Update Pipeline (HITL)",description:"Automation proposes KB patches; humans verify; publishing is blocked until approvals are complete.",domain:"knowledge",owners:["@examples"],tags:["knowledge","pipeline","hitl","audit","notifications"],stability:"experimental"},operations:[{key:"kbPipeline.runWatch",version:"1.0.0"},{key:"kbPipeline.createReviewTask",version:"1.0.0"},{key:"kbPipeline.submitDecision",version:"1.0.0"},{key:"kbPipeline.publishIfReady",version:"1.0.0"}],events:[{key:"kb.change.detected",version:"1.0.0"},{key:"kb.change.summarized",version:"1.0.0"},{key:"kb.patch.proposed",version:"1.0.0"},{key:"kb.review.requested",version:"1.0.0"},{key:"kb.review.decided",version:"1.0.0"}],presentations:[{key:"kb.dashboard",version:"1.0.0"},{key:"kb.review.list",version:"1.0.0"},{key:"kb.review.form",version:"1.0.0"}],opToPresentation:[{op:{key:"kbPipeline.runWatch",version:"1.0.0"},pres:{key:"kb.dashboard",version:"1.0.0"}},{op:{key:"kbPipeline.createReviewTask",version:"1.0.0"},pres:{key:"kb.review.list",version:"1.0.0"}},{op:{key:"kbPipeline.submitDecision",version:"1.0.0"},pres:{key:"kb.review.form",version:"1.0.0"}}],presentationsTargets:[{key:"kb.dashboard",version:"1.0.0",targets:["react","markdown"]},{key:"kb.review.list",version:"1.0.0",targets:["react","markdown"]},{key:"kb.review.form",version:"1.0.0",targets:["react"]}],capabilities:{requires:[{key:"identity",version:"1.0.0"},{key:"notifications",version:"1.0.0"},{key:"audit-trail",version:"1.0.0"}]},knowledge:[{key:"kb.knowledge.rules",version:"1.0.0"}],telemetry:[{key:"kb-pipeline.telemetry",version:"1.0.0"}],jobs:[{key:"kb-pipeline.job.watch",version:"1.0.0"}],docs:["docs.examples.kb-update-pipeline.goal","docs.examples.kb-update-pipeline.reference"]});import{defineCommand as Q}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as U,ScalarTypeEnum as B}from"@contractspec/lib.schema";var S=U({name:"KbPipelineRunWatchInput",description:"Trigger a watch cycle for KB sources (demo).",fields:{jurisdiction:{type:B.String_unsecure(),isOptional:!1}}}),p=U({name:"KbPipelineRunWatchOutput",description:"Output containing detected changes.",fields:{candidates:{type:N,isArray:!0,isOptional:!1}}}),s=U({name:"KbPipelineCreateReviewTaskInput",description:"Create a review task for a change candidate.",fields:{changeCandidateId:{type:B.String_unsecure(),isOptional:!1}}}),l=U({name:"KbPipelineSubmitDecisionInput",description:"Submit a decision for a review task.",fields:{reviewTaskId:{type:B.String_unsecure(),isOptional:!1},decision:{type:$,isOptional:!1},decidedBy:{type:B.String_unsecure(),isOptional:!1},decidedByRole:{type:B.String_unsecure(),isOptional:!1}}}),i=U({name:"KbPipelinePublishIfReadyInput",description:"Publish snapshot if approvals are satisfied for a jurisdiction.",fields:{jurisdiction:{type:B.String_unsecure(),isOptional:!1}}}),d=U({name:"KbPipelinePublishIfReadyOutput",description:"Output for publish-if-ready operation.",fields:{published:{type:B.Boolean(),isOptional:!1},reason:{type:B.String_unsecure(),isOptional:!0}}}),Fx=Q({meta:{key:"kbPipeline.runWatch",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["knowledge","pipeline","jobs"],description:"Detect source changes and create change candidates.",goal:"Automate discovery of updates needing review.",context:"Scheduled job or manual trigger in demos."},io:{input:S,output:p},policy:{auth:"user"}}),Vx=Q({meta:{key:"kbPipeline.createReviewTask",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["knowledge","pipeline","hitl"],description:"Create a review task for a detected change.",goal:"Route work to human verifiers.",context:"Called after change detection or manual selection."},io:{input:s,output:H},policy:{auth:"user"}}),wx=Q({meta:{key:"kbPipeline.submitDecision",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["knowledge","pipeline","hitl","rbac"],description:"Submit approve/reject decision for a review task.",goal:"Ensure humans verify before publishing.",context:"Curator/expert reviews and decides."},io:{input:l,output:H,errors:{FORBIDDEN_ROLE:{description:"Role not allowed to approve the given risk level",http:403,gqlCode:"FORBIDDEN_ROLE",when:"curator attempts to approve a high-risk change"},REVIEW_TASK_NOT_FOUND:{description:"Review task not found",http:404,gqlCode:"REVIEW_TASK_NOT_FOUND",when:"reviewTaskId is invalid"}}},policy:{auth:"user"}}),Cx=Q({meta:{key:"kbPipeline.publishIfReady",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["knowledge","pipeline","publishing"],description:"Publish snapshot if ready (all approvals satisfied).",goal:"Prevent publishing until all required approvals exist.",context:"Called by job or UI to attempt publish."},io:{input:i,output:d,errors:{NOT_READY:{description:"Publishing is blocked because approvals are incomplete",http:409,gqlCode:"NOT_READY",when:"there are open review tasks or unapproved rule versions"}}},policy:{auth:"user"}});import{definePresentation as q,StabilityEnum as z}from"@contractspec/lib.contracts-spec";var kx=q({meta:{key:"kb.dashboard",version:"1.0.0",title:"KB Update Dashboard",description:"Overview of KB change candidates and review tasks.",domain:"knowledge",owners:["@examples"],tags:["dashboard","knowledge"],stability:z.Experimental,goal:"Visualize status",context:"Dashboard"},source:{type:"component",framework:"react",componentKey:"KbDashboard",props:N},targets:["react","markdown"]}),Px=q({meta:{key:"kb.review.list",version:"1.0.0",title:"Review Tasks",description:"List of pending review tasks for the current user.",domain:"knowledge",owners:["@examples"],tags:["list","review"],stability:z.Experimental,goal:"List tasks",context:"Inbox"},source:{type:"component",framework:"react",componentKey:"ReviewTaskList",props:H},targets:["react","markdown"]}),hx=q({meta:{key:"kb.review.form",version:"1.0.0",title:"Review Change",description:"Form to approve or reject a KB change candidate.",domain:"knowledge",owners:["@examples"],tags:["form","review"],stability:z.Experimental,goal:"Review",context:"Detail"},source:{type:"component",framework:"react",componentKey:"ReviewDecisionForm",props:H},targets:["react"]});export{r as example,Gx as createPipelineMemoryStore,Jx as createPipelineMemoryHandlers,H as ReviewTaskModel,$ as ReviewDecisionEnum,k as ReviewAssignedRoleEnum,Zx as KbUpdatePipelineFeature,jx as KbReviewRequestedEvent,Px as KbReviewListPresentation,hx as KbReviewFormPresentation,Bx as KbReviewDecidedEvent,wx as KbPipelineSubmitDecisionContract,Fx as KbPipelineRunWatchContract,Cx as KbPipelinePublishIfReadyContract,Vx as KbPipelineCreateReviewTaskContract,Lx as KbPatchProposedEvent,kx as KbDashboardPresentation,Ax as KbChangeSummarizedEvent,_x as KbChangeDetectedEvent,R as ChangeRiskLevelEnum,N as ChangeCandidateModel};