@thanh01.pmt/domain-kit 0.4.0 → 0.6.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 (68) hide show
  1. package/README.md +682 -168
  2. package/dist/assembly/index.d.cts +2 -2
  3. package/dist/assembly/index.d.ts +2 -2
  4. package/dist/{chunk-HILSUZOF.mjs → chunk-2OGNQUXC.mjs} +171 -31
  5. package/dist/chunk-2OGNQUXC.mjs.map +1 -0
  6. package/dist/{chunk-LZQLLAYP.mjs → chunk-5OMSYKQP.mjs} +43 -23
  7. package/dist/chunk-5OMSYKQP.mjs.map +1 -0
  8. package/dist/{chunk-BL5NBKPH.mjs → chunk-67GXK3ZE.mjs} +18 -8
  9. package/dist/chunk-67GXK3ZE.mjs.map +1 -0
  10. package/dist/{chunk-PKUEOSZ3.mjs → chunk-CGNXGVHV.mjs} +46 -4
  11. package/dist/chunk-CGNXGVHV.mjs.map +1 -0
  12. package/dist/{chunk-VCPIWJ7R.mjs → chunk-ERDTHXQA.mjs} +21 -3
  13. package/dist/chunk-ERDTHXQA.mjs.map +1 -0
  14. package/dist/chunk-OYSZQVPY.mjs +10 -0
  15. package/dist/chunk-OYSZQVPY.mjs.map +1 -0
  16. package/dist/{chunk-QJF4QCBJ.mjs → chunk-WKTH3JPA.mjs} +202 -36
  17. package/dist/chunk-WKTH3JPA.mjs.map +1 -0
  18. package/dist/{conceptEscalator-YfMKIKCZ.d.ts → conceptEscalator-BCsw0ys_.d.ts} +10 -1
  19. package/dist/{conceptEscalator-ltRLtPhf.d.cts → conceptEscalator-DPrs4PwC.d.cts} +10 -1
  20. package/dist/concepts/index.d.cts +1 -1
  21. package/dist/concepts/index.d.ts +1 -1
  22. package/dist/{curriculumFeedSchema-B66H3gEV.d.ts → curriculumFeedSchema-DYayelAA.d.cts} +212 -1
  23. package/dist/{curriculumFeedSchema-B66H3gEV.d.cts → curriculumFeedSchema-DYayelAA.d.ts} +212 -1
  24. package/dist/detector/index.cjs +21 -6
  25. package/dist/detector/index.cjs.map +1 -1
  26. package/dist/detector/index.mjs +2 -1
  27. package/dist/feed/index.cjs +243 -33
  28. package/dist/feed/index.cjs.map +1 -1
  29. package/dist/feed/index.d.cts +32 -2
  30. package/dist/feed/index.d.ts +32 -2
  31. package/dist/feed/index.mjs +2 -2
  32. package/dist/graph/index.cjs +163 -28
  33. package/dist/graph/index.cjs.map +1 -1
  34. package/dist/graph/index.d.cts +14 -5
  35. package/dist/graph/index.d.ts +14 -5
  36. package/dist/graph/index.mjs +2 -1
  37. package/dist/{hybridGraphPipeline-DXQDbBEj.d.ts → hybridGraphPipeline-9dRKJj7r.d.ts} +6 -2
  38. package/dist/{hybridGraphPipeline-dT-bio-3.d.cts → hybridGraphPipeline-CocfYe4d.d.cts} +6 -2
  39. package/dist/{hybridGraphSchema-nrUeSwpU.d.ts → hybridGraphSchema-C37qxdTM.d.cts} +16 -3
  40. package/dist/{hybridGraphSchema-nrUeSwpU.d.cts → hybridGraphSchema-C37qxdTM.d.ts} +16 -3
  41. package/dist/index.cjs +3742 -3362
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.d.cts +6 -6
  44. package/dist/index.d.ts +6 -6
  45. package/dist/index.mjs +7 -6
  46. package/dist/llmClient-CX5uUiQ1.d.cts +60 -0
  47. package/dist/llmClient-CX5uUiQ1.d.ts +60 -0
  48. package/dist/pipeline/index.cjs +1556 -1202
  49. package/dist/pipeline/index.cjs.map +1 -1
  50. package/dist/pipeline/index.d.cts +13 -5
  51. package/dist/pipeline/index.d.ts +13 -5
  52. package/dist/pipeline/index.mjs +6 -5
  53. package/dist/schemas/index.cjs +64 -2
  54. package/dist/schemas/index.cjs.map +1 -1
  55. package/dist/schemas/index.d.cts +2 -2
  56. package/dist/schemas/index.d.ts +2 -2
  57. package/dist/schemas/index.mjs +2 -2
  58. package/package.json +1 -1
  59. package/dist/chunk-BL5NBKPH.mjs.map +0 -1
  60. package/dist/chunk-HILSUZOF.mjs.map +0 -1
  61. package/dist/chunk-LZQLLAYP.mjs.map +0 -1
  62. package/dist/chunk-PKUEOSZ3.mjs.map +0 -1
  63. package/dist/chunk-QJF4QCBJ.mjs.map +0 -1
  64. package/dist/chunk-VCPIWJ7R.mjs.map +0 -1
  65. package/dist/curriculumFeedEmitter-6IK6PFDH.mjs +0 -4
  66. package/dist/curriculumFeedEmitter-6IK6PFDH.mjs.map +0 -1
  67. package/dist/llmClient-ysPhLjcH.d.cts +0 -16
  68. package/dist/llmClient-ysPhLjcH.d.ts +0 -16
@@ -1,4 +1,4 @@
1
- import { L as LlmClientConfig } from './llmClient-ysPhLjcH.cjs';
1
+ import { L as LlmClientConfig, a as LlmClient } from './llmClient-CX5uUiQ1.cjs';
2
2
  import { u as ProjectGraph } from './projectGraphSchema-DnD7orZV.cjs';
3
3
 
4
4
  /**
@@ -19,6 +19,12 @@ interface ConceptMapping {
19
19
  keyword: string;
20
20
  depth: 'ulo' | 'cio' | 'sio';
21
21
  depth_rationale: string;
22
+ /**
23
+ * Who decided `depth`. The regex fallback (comment → ulo, import → sio) has no
24
+ * pedagogical basis — without this marker a degraded run is indistinguishable
25
+ * from a considered one, because both write the same field.
26
+ */
27
+ depth_source: 'llm' | 'heuristic' | 'override';
22
28
  evidence_files: string[];
23
29
  }
24
30
  interface EscalateOptions {
@@ -31,6 +37,9 @@ interface EscalateOptions {
31
37
  depth?: string;
32
38
  }>;
33
39
  llmConfig?: LlmClientConfig;
40
+ /** Pre-built client from the calling pipeline — reused so every step of one run
41
+ * lands in ONE callLog and the feed can report real provenance. */
42
+ sharedClient?: LlmClient;
34
43
  }
35
44
  /**
36
45
  * Escalate keywords/api_usage to neutral concepts with ULO/CIO/SIO depth and join evidence files.
@@ -1,4 +1,4 @@
1
- import { L as LlmClientConfig } from '../llmClient-ysPhLjcH.cjs';
1
+ import { L as LlmClientConfig } from '../llmClient-CX5uUiQ1.cjs';
2
2
  import { K as Keyword } from '../keywordExtractor-BxlGRMHC.cjs';
3
3
  import '../cpp-CZUPqJt9.cjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { L as LlmClientConfig } from '../llmClient-ysPhLjcH.js';
1
+ import { L as LlmClientConfig } from '../llmClient-CX5uUiQ1.js';
2
2
  import { K as Keyword } from '../keywordExtractor-DU5XRN8-.js';
3
3
  import '../cpp-CZUPqJt9.js';
4
4
 
@@ -136,6 +136,27 @@ declare const FeedNodeSchema: z.ZodObject<{
136
136
  reason?: string | undefined;
137
137
  }>, "many">>;
138
138
  is_core: z.ZodDefault<z.ZodBoolean>;
139
+ /**
140
+ * Prerequisite concept ids this node needs that NO node in this feed provides —
141
+ * i.e. the learner must already know them before starting. Previously these were
142
+ * silently dropped (knowledge path) or crashed emission (both hybrid paths), so a
143
+ * course silently lost its entry requirements. Kept on the node so the mapping
144
+ * "concept X needs prior knowledge Y" survives; a course-level roll-up is derivable.
145
+ */
146
+ external_prerequisites: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
147
+ depth_context: z.ZodOptional<z.ZodObject<{
148
+ ulo: z.ZodDefault<z.ZodString>;
149
+ cio: z.ZodDefault<z.ZodString>;
150
+ sio: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
151
+ }, "strip", z.ZodTypeAny, {
152
+ ulo: string;
153
+ cio: string;
154
+ sio: string[];
155
+ }, {
156
+ ulo?: string | undefined;
157
+ cio?: string | undefined;
158
+ sio?: string[] | undefined;
159
+ }>>;
139
160
  phase_id: z.ZodDefault<z.ZodString>;
140
161
  introduce_aspect: z.ZodDefault<z.ZodNullable<z.ZodEnum<["new", "advanced", "preview"]>>>;
141
162
  }, "strip", z.ZodTypeAny, {
@@ -170,6 +191,7 @@ declare const FeedNodeSchema: z.ZodObject<{
170
191
  concept_ref: string | null;
171
192
  user_visible_deliverable: string;
172
193
  is_core: boolean;
194
+ external_prerequisites: string[];
173
195
  introduce_aspect: "new" | "advanced" | "preview" | null;
174
196
  depth_variants?: {
175
197
  ulo: number;
@@ -182,6 +204,11 @@ declare const FeedNodeSchema: z.ZodObject<{
182
204
  from_depth: "ulo" | "cio" | "sio";
183
205
  to_depth: "ulo" | "cio" | "sio";
184
206
  }[] | undefined;
207
+ depth_context?: {
208
+ ulo: string;
209
+ cio: string;
210
+ sio: string[];
211
+ } | undefined;
185
212
  }, {
186
213
  estimated_minutes: number;
187
214
  id: string;
@@ -225,6 +252,12 @@ declare const FeedNodeSchema: z.ZodObject<{
225
252
  reason?: string | undefined;
226
253
  }[] | undefined;
227
254
  is_core?: boolean | undefined;
255
+ external_prerequisites?: string[] | undefined;
256
+ depth_context?: {
257
+ ulo?: string | undefined;
258
+ cio?: string | undefined;
259
+ sio?: string[] | undefined;
260
+ } | undefined;
228
261
  introduce_aspect?: "new" | "advanced" | "preview" | null | undefined;
229
262
  }>;
230
263
  declare const FeedEdgeSchema: z.ZodObject<{
@@ -279,20 +312,127 @@ declare const FeedPhaseSchema: z.ZodObject<{
279
312
  node_ids: string[];
280
313
  }>;
281
314
  type FeedPhase = z.infer<typeof FeedPhaseSchema>;
315
+ /**
316
+ * Machine-readable diagnostic. `warnings` in `source` is the DERIVED text view of
317
+ * these (every diagnostic whose severity is not 'info'), so there is exactly one
318
+ * source of truth and the host can gate on `code`/`severity` instead of substring
319
+ * matching free text — the 2026-09-17 class of incident was a drift that was only
320
+ * ever a warning string.
321
+ */
322
+ declare const FeedDiagnosticSchema: z.ZodObject<{
323
+ code: z.ZodString;
324
+ severity: z.ZodEnum<["info", "warning", "error"]>;
325
+ message: z.ZodString;
326
+ node_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
327
+ }, "strip", z.ZodTypeAny, {
328
+ code: string;
329
+ message: string;
330
+ severity: "info" | "warning" | "error";
331
+ node_ids: string[];
332
+ }, {
333
+ code: string;
334
+ message: string;
335
+ severity: "info" | "warning" | "error";
336
+ node_ids?: string[] | undefined;
337
+ }>;
338
+ type FeedDiagnostic = z.infer<typeof FeedDiagnosticSchema>;
339
+ /** Which LLM providers actually served this graph, and whether any call fell over. */
340
+ declare const FeedProvenanceSchema: z.ZodObject<{
341
+ providers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
342
+ models: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
343
+ calls: z.ZodDefault<z.ZodNumber>;
344
+ failed_calls: z.ZodDefault<z.ZodNumber>;
345
+ degraded: z.ZodDefault<z.ZodBoolean>;
346
+ }, "strip", z.ZodTypeAny, {
347
+ models: string[];
348
+ providers: string[];
349
+ calls: number;
350
+ failed_calls: number;
351
+ degraded: boolean;
352
+ }, {
353
+ models?: string[] | undefined;
354
+ providers?: string[] | undefined;
355
+ calls?: number | undefined;
356
+ failed_calls?: number | undefined;
357
+ degraded?: boolean | undefined;
358
+ }>;
359
+ type FeedProvenance = z.infer<typeof FeedProvenanceSchema>;
282
360
  declare const CurriculumFeedSchema: z.ZodObject<{
283
361
  schema_version: z.ZodLiteral<2>;
284
362
  source: z.ZodObject<{
285
363
  graph_type: z.ZodEnum<["project_graph", "knowledge_graph", "hybrid_graph"]>;
364
+ /** DERIVED from diagnostics — do not write to it directly. */
286
365
  warnings: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
287
366
  hallucination_count: z.ZodDefault<z.ZodNumber>;
367
+ diagnostics: z.ZodDefault<z.ZodArray<z.ZodObject<{
368
+ code: z.ZodString;
369
+ severity: z.ZodEnum<["info", "warning", "error"]>;
370
+ message: z.ZodString;
371
+ node_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
372
+ }, "strip", z.ZodTypeAny, {
373
+ code: string;
374
+ message: string;
375
+ severity: "info" | "warning" | "error";
376
+ node_ids: string[];
377
+ }, {
378
+ code: string;
379
+ message: string;
380
+ severity: "info" | "warning" | "error";
381
+ node_ids?: string[] | undefined;
382
+ }>, "many">>;
383
+ provenance: z.ZodOptional<z.ZodObject<{
384
+ providers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
385
+ models: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
386
+ calls: z.ZodDefault<z.ZodNumber>;
387
+ failed_calls: z.ZodDefault<z.ZodNumber>;
388
+ degraded: z.ZodDefault<z.ZodBoolean>;
389
+ }, "strip", z.ZodTypeAny, {
390
+ models: string[];
391
+ providers: string[];
392
+ calls: number;
393
+ failed_calls: number;
394
+ degraded: boolean;
395
+ }, {
396
+ models?: string[] | undefined;
397
+ providers?: string[] | undefined;
398
+ calls?: number | undefined;
399
+ failed_calls?: number | undefined;
400
+ degraded?: boolean | undefined;
401
+ }>>;
288
402
  }, "strip", z.ZodTypeAny, {
289
403
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
290
404
  warnings: string[];
291
405
  hallucination_count: number;
406
+ diagnostics: {
407
+ code: string;
408
+ message: string;
409
+ severity: "info" | "warning" | "error";
410
+ node_ids: string[];
411
+ }[];
412
+ provenance?: {
413
+ models: string[];
414
+ providers: string[];
415
+ calls: number;
416
+ failed_calls: number;
417
+ degraded: boolean;
418
+ } | undefined;
292
419
  }, {
293
420
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
294
421
  warnings?: string[] | undefined;
295
422
  hallucination_count?: number | undefined;
423
+ diagnostics?: {
424
+ code: string;
425
+ message: string;
426
+ severity: "info" | "warning" | "error";
427
+ node_ids?: string[] | undefined;
428
+ }[] | undefined;
429
+ provenance?: {
430
+ models?: string[] | undefined;
431
+ providers?: string[] | undefined;
432
+ calls?: number | undefined;
433
+ failed_calls?: number | undefined;
434
+ degraded?: boolean | undefined;
435
+ } | undefined;
296
436
  }>;
297
437
  learning_nodes: z.ZodArray<z.ZodObject<{
298
438
  id: z.ZodString;
@@ -394,6 +534,27 @@ declare const CurriculumFeedSchema: z.ZodObject<{
394
534
  reason?: string | undefined;
395
535
  }>, "many">>;
396
536
  is_core: z.ZodDefault<z.ZodBoolean>;
537
+ /**
538
+ * Prerequisite concept ids this node needs that NO node in this feed provides —
539
+ * i.e. the learner must already know them before starting. Previously these were
540
+ * silently dropped (knowledge path) or crashed emission (both hybrid paths), so a
541
+ * course silently lost its entry requirements. Kept on the node so the mapping
542
+ * "concept X needs prior knowledge Y" survives; a course-level roll-up is derivable.
543
+ */
544
+ external_prerequisites: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
545
+ depth_context: z.ZodOptional<z.ZodObject<{
546
+ ulo: z.ZodDefault<z.ZodString>;
547
+ cio: z.ZodDefault<z.ZodString>;
548
+ sio: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
549
+ }, "strip", z.ZodTypeAny, {
550
+ ulo: string;
551
+ cio: string;
552
+ sio: string[];
553
+ }, {
554
+ ulo?: string | undefined;
555
+ cio?: string | undefined;
556
+ sio?: string[] | undefined;
557
+ }>>;
397
558
  phase_id: z.ZodDefault<z.ZodString>;
398
559
  introduce_aspect: z.ZodDefault<z.ZodNullable<z.ZodEnum<["new", "advanced", "preview"]>>>;
399
560
  }, "strip", z.ZodTypeAny, {
@@ -428,6 +589,7 @@ declare const CurriculumFeedSchema: z.ZodObject<{
428
589
  concept_ref: string | null;
429
590
  user_visible_deliverable: string;
430
591
  is_core: boolean;
592
+ external_prerequisites: string[];
431
593
  introduce_aspect: "new" | "advanced" | "preview" | null;
432
594
  depth_variants?: {
433
595
  ulo: number;
@@ -440,6 +602,11 @@ declare const CurriculumFeedSchema: z.ZodObject<{
440
602
  from_depth: "ulo" | "cio" | "sio";
441
603
  to_depth: "ulo" | "cio" | "sio";
442
604
  }[] | undefined;
605
+ depth_context?: {
606
+ ulo: string;
607
+ cio: string;
608
+ sio: string[];
609
+ } | undefined;
443
610
  }, {
444
611
  estimated_minutes: number;
445
612
  id: string;
@@ -483,6 +650,12 @@ declare const CurriculumFeedSchema: z.ZodObject<{
483
650
  reason?: string | undefined;
484
651
  }[] | undefined;
485
652
  is_core?: boolean | undefined;
653
+ external_prerequisites?: string[] | undefined;
654
+ depth_context?: {
655
+ ulo?: string | undefined;
656
+ cio?: string | undefined;
657
+ sio?: string[] | undefined;
658
+ } | undefined;
486
659
  introduce_aspect?: "new" | "advanced" | "preview" | null | undefined;
487
660
  }>, "many">;
488
661
  dependency_edges: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -541,6 +714,19 @@ declare const CurriculumFeedSchema: z.ZodObject<{
541
714
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
542
715
  warnings: string[];
543
716
  hallucination_count: number;
717
+ diagnostics: {
718
+ code: string;
719
+ message: string;
720
+ severity: "info" | "warning" | "error";
721
+ node_ids: string[];
722
+ }[];
723
+ provenance?: {
724
+ models: string[];
725
+ providers: string[];
726
+ calls: number;
727
+ failed_calls: number;
728
+ degraded: boolean;
729
+ } | undefined;
544
730
  };
545
731
  schema_version: 2;
546
732
  phases: {
@@ -582,6 +768,7 @@ declare const CurriculumFeedSchema: z.ZodObject<{
582
768
  concept_ref: string | null;
583
769
  user_visible_deliverable: string;
584
770
  is_core: boolean;
771
+ external_prerequisites: string[];
585
772
  introduce_aspect: "new" | "advanced" | "preview" | null;
586
773
  depth_variants?: {
587
774
  ulo: number;
@@ -594,6 +781,11 @@ declare const CurriculumFeedSchema: z.ZodObject<{
594
781
  from_depth: "ulo" | "cio" | "sio";
595
782
  to_depth: "ulo" | "cio" | "sio";
596
783
  }[] | undefined;
784
+ depth_context?: {
785
+ ulo: string;
786
+ cio: string;
787
+ sio: string[];
788
+ } | undefined;
597
789
  }[];
598
790
  dependency_edges: {
599
791
  from: string;
@@ -612,6 +804,19 @@ declare const CurriculumFeedSchema: z.ZodObject<{
612
804
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
613
805
  warnings?: string[] | undefined;
614
806
  hallucination_count?: number | undefined;
807
+ diagnostics?: {
808
+ code: string;
809
+ message: string;
810
+ severity: "info" | "warning" | "error";
811
+ node_ids?: string[] | undefined;
812
+ }[] | undefined;
813
+ provenance?: {
814
+ models?: string[] | undefined;
815
+ providers?: string[] | undefined;
816
+ calls?: number | undefined;
817
+ failed_calls?: number | undefined;
818
+ degraded?: boolean | undefined;
819
+ } | undefined;
615
820
  };
616
821
  schema_version: 2;
617
822
  learning_nodes: {
@@ -657,6 +862,12 @@ declare const CurriculumFeedSchema: z.ZodObject<{
657
862
  reason?: string | undefined;
658
863
  }[] | undefined;
659
864
  is_core?: boolean | undefined;
865
+ external_prerequisites?: string[] | undefined;
866
+ depth_context?: {
867
+ ulo?: string | undefined;
868
+ cio?: string | undefined;
869
+ sio?: string[] | undefined;
870
+ } | undefined;
660
871
  introduce_aspect?: "new" | "advanced" | "preview" | null | undefined;
661
872
  }[];
662
873
  phases?: {
@@ -686,4 +897,4 @@ type FeedGrouping = z.infer<typeof FeedGroupingSchema>;
686
897
  /** Strict pre-save resolution validation — fail-closed, no defaulted-empty graphs. */
687
898
  declare function validateCurriculumFeed(feed: unknown): CurriculumFeed;
688
899
 
689
- export { CurriculumFeedSchema as C, FeedKeywordsSchema as F, FeedScaffoldCandidateSchema as a, FeedNodeSchema as b, FeedEdgeSchema as c, FeedGroupingSchema as d, FeedPhaseSchema as e, type FeedPhase as f, type CurriculumFeed as g, type FeedNode as h, type FeedEdge as i, type FeedGrouping as j, validateCurriculumFeed as v };
900
+ export { CurriculumFeedSchema as C, FeedKeywordsSchema as F, FeedScaffoldCandidateSchema as a, FeedNodeSchema as b, FeedEdgeSchema as c, FeedGroupingSchema as d, FeedPhaseSchema as e, type FeedPhase as f, FeedDiagnosticSchema as g, type FeedDiagnostic as h, FeedProvenanceSchema as i, type FeedProvenance as j, type CurriculumFeed as k, type FeedNode as l, type FeedEdge as m, type FeedGrouping as n, validateCurriculumFeed as v };
@@ -136,6 +136,27 @@ declare const FeedNodeSchema: z.ZodObject<{
136
136
  reason?: string | undefined;
137
137
  }>, "many">>;
138
138
  is_core: z.ZodDefault<z.ZodBoolean>;
139
+ /**
140
+ * Prerequisite concept ids this node needs that NO node in this feed provides —
141
+ * i.e. the learner must already know them before starting. Previously these were
142
+ * silently dropped (knowledge path) or crashed emission (both hybrid paths), so a
143
+ * course silently lost its entry requirements. Kept on the node so the mapping
144
+ * "concept X needs prior knowledge Y" survives; a course-level roll-up is derivable.
145
+ */
146
+ external_prerequisites: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
147
+ depth_context: z.ZodOptional<z.ZodObject<{
148
+ ulo: z.ZodDefault<z.ZodString>;
149
+ cio: z.ZodDefault<z.ZodString>;
150
+ sio: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
151
+ }, "strip", z.ZodTypeAny, {
152
+ ulo: string;
153
+ cio: string;
154
+ sio: string[];
155
+ }, {
156
+ ulo?: string | undefined;
157
+ cio?: string | undefined;
158
+ sio?: string[] | undefined;
159
+ }>>;
139
160
  phase_id: z.ZodDefault<z.ZodString>;
140
161
  introduce_aspect: z.ZodDefault<z.ZodNullable<z.ZodEnum<["new", "advanced", "preview"]>>>;
141
162
  }, "strip", z.ZodTypeAny, {
@@ -170,6 +191,7 @@ declare const FeedNodeSchema: z.ZodObject<{
170
191
  concept_ref: string | null;
171
192
  user_visible_deliverable: string;
172
193
  is_core: boolean;
194
+ external_prerequisites: string[];
173
195
  introduce_aspect: "new" | "advanced" | "preview" | null;
174
196
  depth_variants?: {
175
197
  ulo: number;
@@ -182,6 +204,11 @@ declare const FeedNodeSchema: z.ZodObject<{
182
204
  from_depth: "ulo" | "cio" | "sio";
183
205
  to_depth: "ulo" | "cio" | "sio";
184
206
  }[] | undefined;
207
+ depth_context?: {
208
+ ulo: string;
209
+ cio: string;
210
+ sio: string[];
211
+ } | undefined;
185
212
  }, {
186
213
  estimated_minutes: number;
187
214
  id: string;
@@ -225,6 +252,12 @@ declare const FeedNodeSchema: z.ZodObject<{
225
252
  reason?: string | undefined;
226
253
  }[] | undefined;
227
254
  is_core?: boolean | undefined;
255
+ external_prerequisites?: string[] | undefined;
256
+ depth_context?: {
257
+ ulo?: string | undefined;
258
+ cio?: string | undefined;
259
+ sio?: string[] | undefined;
260
+ } | undefined;
228
261
  introduce_aspect?: "new" | "advanced" | "preview" | null | undefined;
229
262
  }>;
230
263
  declare const FeedEdgeSchema: z.ZodObject<{
@@ -279,20 +312,127 @@ declare const FeedPhaseSchema: z.ZodObject<{
279
312
  node_ids: string[];
280
313
  }>;
281
314
  type FeedPhase = z.infer<typeof FeedPhaseSchema>;
315
+ /**
316
+ * Machine-readable diagnostic. `warnings` in `source` is the DERIVED text view of
317
+ * these (every diagnostic whose severity is not 'info'), so there is exactly one
318
+ * source of truth and the host can gate on `code`/`severity` instead of substring
319
+ * matching free text — the 2026-09-17 class of incident was a drift that was only
320
+ * ever a warning string.
321
+ */
322
+ declare const FeedDiagnosticSchema: z.ZodObject<{
323
+ code: z.ZodString;
324
+ severity: z.ZodEnum<["info", "warning", "error"]>;
325
+ message: z.ZodString;
326
+ node_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
327
+ }, "strip", z.ZodTypeAny, {
328
+ code: string;
329
+ message: string;
330
+ severity: "info" | "warning" | "error";
331
+ node_ids: string[];
332
+ }, {
333
+ code: string;
334
+ message: string;
335
+ severity: "info" | "warning" | "error";
336
+ node_ids?: string[] | undefined;
337
+ }>;
338
+ type FeedDiagnostic = z.infer<typeof FeedDiagnosticSchema>;
339
+ /** Which LLM providers actually served this graph, and whether any call fell over. */
340
+ declare const FeedProvenanceSchema: z.ZodObject<{
341
+ providers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
342
+ models: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
343
+ calls: z.ZodDefault<z.ZodNumber>;
344
+ failed_calls: z.ZodDefault<z.ZodNumber>;
345
+ degraded: z.ZodDefault<z.ZodBoolean>;
346
+ }, "strip", z.ZodTypeAny, {
347
+ models: string[];
348
+ providers: string[];
349
+ calls: number;
350
+ failed_calls: number;
351
+ degraded: boolean;
352
+ }, {
353
+ models?: string[] | undefined;
354
+ providers?: string[] | undefined;
355
+ calls?: number | undefined;
356
+ failed_calls?: number | undefined;
357
+ degraded?: boolean | undefined;
358
+ }>;
359
+ type FeedProvenance = z.infer<typeof FeedProvenanceSchema>;
282
360
  declare const CurriculumFeedSchema: z.ZodObject<{
283
361
  schema_version: z.ZodLiteral<2>;
284
362
  source: z.ZodObject<{
285
363
  graph_type: z.ZodEnum<["project_graph", "knowledge_graph", "hybrid_graph"]>;
364
+ /** DERIVED from diagnostics — do not write to it directly. */
286
365
  warnings: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
287
366
  hallucination_count: z.ZodDefault<z.ZodNumber>;
367
+ diagnostics: z.ZodDefault<z.ZodArray<z.ZodObject<{
368
+ code: z.ZodString;
369
+ severity: z.ZodEnum<["info", "warning", "error"]>;
370
+ message: z.ZodString;
371
+ node_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
372
+ }, "strip", z.ZodTypeAny, {
373
+ code: string;
374
+ message: string;
375
+ severity: "info" | "warning" | "error";
376
+ node_ids: string[];
377
+ }, {
378
+ code: string;
379
+ message: string;
380
+ severity: "info" | "warning" | "error";
381
+ node_ids?: string[] | undefined;
382
+ }>, "many">>;
383
+ provenance: z.ZodOptional<z.ZodObject<{
384
+ providers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
385
+ models: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
386
+ calls: z.ZodDefault<z.ZodNumber>;
387
+ failed_calls: z.ZodDefault<z.ZodNumber>;
388
+ degraded: z.ZodDefault<z.ZodBoolean>;
389
+ }, "strip", z.ZodTypeAny, {
390
+ models: string[];
391
+ providers: string[];
392
+ calls: number;
393
+ failed_calls: number;
394
+ degraded: boolean;
395
+ }, {
396
+ models?: string[] | undefined;
397
+ providers?: string[] | undefined;
398
+ calls?: number | undefined;
399
+ failed_calls?: number | undefined;
400
+ degraded?: boolean | undefined;
401
+ }>>;
288
402
  }, "strip", z.ZodTypeAny, {
289
403
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
290
404
  warnings: string[];
291
405
  hallucination_count: number;
406
+ diagnostics: {
407
+ code: string;
408
+ message: string;
409
+ severity: "info" | "warning" | "error";
410
+ node_ids: string[];
411
+ }[];
412
+ provenance?: {
413
+ models: string[];
414
+ providers: string[];
415
+ calls: number;
416
+ failed_calls: number;
417
+ degraded: boolean;
418
+ } | undefined;
292
419
  }, {
293
420
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
294
421
  warnings?: string[] | undefined;
295
422
  hallucination_count?: number | undefined;
423
+ diagnostics?: {
424
+ code: string;
425
+ message: string;
426
+ severity: "info" | "warning" | "error";
427
+ node_ids?: string[] | undefined;
428
+ }[] | undefined;
429
+ provenance?: {
430
+ models?: string[] | undefined;
431
+ providers?: string[] | undefined;
432
+ calls?: number | undefined;
433
+ failed_calls?: number | undefined;
434
+ degraded?: boolean | undefined;
435
+ } | undefined;
296
436
  }>;
297
437
  learning_nodes: z.ZodArray<z.ZodObject<{
298
438
  id: z.ZodString;
@@ -394,6 +534,27 @@ declare const CurriculumFeedSchema: z.ZodObject<{
394
534
  reason?: string | undefined;
395
535
  }>, "many">>;
396
536
  is_core: z.ZodDefault<z.ZodBoolean>;
537
+ /**
538
+ * Prerequisite concept ids this node needs that NO node in this feed provides —
539
+ * i.e. the learner must already know them before starting. Previously these were
540
+ * silently dropped (knowledge path) or crashed emission (both hybrid paths), so a
541
+ * course silently lost its entry requirements. Kept on the node so the mapping
542
+ * "concept X needs prior knowledge Y" survives; a course-level roll-up is derivable.
543
+ */
544
+ external_prerequisites: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
545
+ depth_context: z.ZodOptional<z.ZodObject<{
546
+ ulo: z.ZodDefault<z.ZodString>;
547
+ cio: z.ZodDefault<z.ZodString>;
548
+ sio: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
549
+ }, "strip", z.ZodTypeAny, {
550
+ ulo: string;
551
+ cio: string;
552
+ sio: string[];
553
+ }, {
554
+ ulo?: string | undefined;
555
+ cio?: string | undefined;
556
+ sio?: string[] | undefined;
557
+ }>>;
397
558
  phase_id: z.ZodDefault<z.ZodString>;
398
559
  introduce_aspect: z.ZodDefault<z.ZodNullable<z.ZodEnum<["new", "advanced", "preview"]>>>;
399
560
  }, "strip", z.ZodTypeAny, {
@@ -428,6 +589,7 @@ declare const CurriculumFeedSchema: z.ZodObject<{
428
589
  concept_ref: string | null;
429
590
  user_visible_deliverable: string;
430
591
  is_core: boolean;
592
+ external_prerequisites: string[];
431
593
  introduce_aspect: "new" | "advanced" | "preview" | null;
432
594
  depth_variants?: {
433
595
  ulo: number;
@@ -440,6 +602,11 @@ declare const CurriculumFeedSchema: z.ZodObject<{
440
602
  from_depth: "ulo" | "cio" | "sio";
441
603
  to_depth: "ulo" | "cio" | "sio";
442
604
  }[] | undefined;
605
+ depth_context?: {
606
+ ulo: string;
607
+ cio: string;
608
+ sio: string[];
609
+ } | undefined;
443
610
  }, {
444
611
  estimated_minutes: number;
445
612
  id: string;
@@ -483,6 +650,12 @@ declare const CurriculumFeedSchema: z.ZodObject<{
483
650
  reason?: string | undefined;
484
651
  }[] | undefined;
485
652
  is_core?: boolean | undefined;
653
+ external_prerequisites?: string[] | undefined;
654
+ depth_context?: {
655
+ ulo?: string | undefined;
656
+ cio?: string | undefined;
657
+ sio?: string[] | undefined;
658
+ } | undefined;
486
659
  introduce_aspect?: "new" | "advanced" | "preview" | null | undefined;
487
660
  }>, "many">;
488
661
  dependency_edges: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -541,6 +714,19 @@ declare const CurriculumFeedSchema: z.ZodObject<{
541
714
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
542
715
  warnings: string[];
543
716
  hallucination_count: number;
717
+ diagnostics: {
718
+ code: string;
719
+ message: string;
720
+ severity: "info" | "warning" | "error";
721
+ node_ids: string[];
722
+ }[];
723
+ provenance?: {
724
+ models: string[];
725
+ providers: string[];
726
+ calls: number;
727
+ failed_calls: number;
728
+ degraded: boolean;
729
+ } | undefined;
544
730
  };
545
731
  schema_version: 2;
546
732
  phases: {
@@ -582,6 +768,7 @@ declare const CurriculumFeedSchema: z.ZodObject<{
582
768
  concept_ref: string | null;
583
769
  user_visible_deliverable: string;
584
770
  is_core: boolean;
771
+ external_prerequisites: string[];
585
772
  introduce_aspect: "new" | "advanced" | "preview" | null;
586
773
  depth_variants?: {
587
774
  ulo: number;
@@ -594,6 +781,11 @@ declare const CurriculumFeedSchema: z.ZodObject<{
594
781
  from_depth: "ulo" | "cio" | "sio";
595
782
  to_depth: "ulo" | "cio" | "sio";
596
783
  }[] | undefined;
784
+ depth_context?: {
785
+ ulo: string;
786
+ cio: string;
787
+ sio: string[];
788
+ } | undefined;
597
789
  }[];
598
790
  dependency_edges: {
599
791
  from: string;
@@ -612,6 +804,19 @@ declare const CurriculumFeedSchema: z.ZodObject<{
612
804
  graph_type: "knowledge_graph" | "hybrid_graph" | "project_graph";
613
805
  warnings?: string[] | undefined;
614
806
  hallucination_count?: number | undefined;
807
+ diagnostics?: {
808
+ code: string;
809
+ message: string;
810
+ severity: "info" | "warning" | "error";
811
+ node_ids?: string[] | undefined;
812
+ }[] | undefined;
813
+ provenance?: {
814
+ models?: string[] | undefined;
815
+ providers?: string[] | undefined;
816
+ calls?: number | undefined;
817
+ failed_calls?: number | undefined;
818
+ degraded?: boolean | undefined;
819
+ } | undefined;
615
820
  };
616
821
  schema_version: 2;
617
822
  learning_nodes: {
@@ -657,6 +862,12 @@ declare const CurriculumFeedSchema: z.ZodObject<{
657
862
  reason?: string | undefined;
658
863
  }[] | undefined;
659
864
  is_core?: boolean | undefined;
865
+ external_prerequisites?: string[] | undefined;
866
+ depth_context?: {
867
+ ulo?: string | undefined;
868
+ cio?: string | undefined;
869
+ sio?: string[] | undefined;
870
+ } | undefined;
660
871
  introduce_aspect?: "new" | "advanced" | "preview" | null | undefined;
661
872
  }[];
662
873
  phases?: {
@@ -686,4 +897,4 @@ type FeedGrouping = z.infer<typeof FeedGroupingSchema>;
686
897
  /** Strict pre-save resolution validation — fail-closed, no defaulted-empty graphs. */
687
898
  declare function validateCurriculumFeed(feed: unknown): CurriculumFeed;
688
899
 
689
- export { CurriculumFeedSchema as C, FeedKeywordsSchema as F, FeedScaffoldCandidateSchema as a, FeedNodeSchema as b, FeedEdgeSchema as c, FeedGroupingSchema as d, FeedPhaseSchema as e, type FeedPhase as f, type CurriculumFeed as g, type FeedNode as h, type FeedEdge as i, type FeedGrouping as j, validateCurriculumFeed as v };
900
+ export { CurriculumFeedSchema as C, FeedKeywordsSchema as F, FeedScaffoldCandidateSchema as a, FeedNodeSchema as b, FeedEdgeSchema as c, FeedGroupingSchema as d, FeedPhaseSchema as e, type FeedPhase as f, FeedDiagnosticSchema as g, type FeedDiagnostic as h, FeedProvenanceSchema as i, type FeedProvenance as j, type CurriculumFeed as k, type FeedNode as l, type FeedEdge as m, type FeedGrouping as n, validateCurriculumFeed as v };