@thanh01.pmt/curriculum-kit 1.4.35 → 1.4.37
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.
- package/dist/ai/index.cjs +57 -1
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +2 -2
- package/dist/ai/index.d.ts +2 -2
- package/dist/ai/index.mjs +57 -1
- package/dist/ai/index.mjs.map +1 -1
- package/dist/{gateSettings-DabOqP6_.d.cts → gateSettings-oo5tCUS_.d.cts} +18 -0
- package/dist/{gateSettings-DabOqP6_.d.ts → gateSettings-oo5tCUS_.d.ts} +18 -0
- package/dist/index.cjs +793 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +251 -74
- package/dist/index.d.ts +251 -74
- package/dist/index.mjs +775 -52
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +57 -1
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +57 -1
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/schemas/index.cjs +63 -1
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +436 -33
- package/dist/schemas/index.d.ts +436 -33
- package/dist/schemas/index.mjs +58 -2
- package/dist/schemas/index.mjs.map +1 -1
- package/dist/standards/index.d.cts +2 -2
- package/dist/standards/index.d.ts +2 -2
- package/dist/workflow/index.cjs +84 -2
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.d.cts +3 -3
- package/dist/workflow/index.d.ts +3 -3
- package/dist/workflow/index.mjs +84 -2
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/{standardsCoverageGate-DR5YTtlt.d.cts → standardsCoverageGate-49pJq5t8.d.cts} +6 -6
- package/dist/{standardsCoverageGate-DR5YTtlt.d.ts → standardsCoverageGate-49pJq5t8.d.ts} +6 -6
package/dist/index.mjs
CHANGED
|
@@ -3562,6 +3562,50 @@ var ScaffoldDecisionEntrySchema = z.object({
|
|
|
3562
3562
|
minutes_saved: z.number().int().nonnegative().default(0),
|
|
3563
3563
|
reason: z.string().min(3)
|
|
3564
3564
|
});
|
|
3565
|
+
var ZpdVerdictSchema = z.enum(["OK", "TOO_MANY_NEW", "NO_ZPD_BRIDGE"]);
|
|
3566
|
+
var SessionZpdStatusSchema = z.object({
|
|
3567
|
+
verdict: ZpdVerdictSchema,
|
|
3568
|
+
new_concept_count: z.number().int().nonnegative().default(0),
|
|
3569
|
+
known_concept_count: z.number().int().nonnegative().default(0),
|
|
3570
|
+
issues: z.array(z.string()).default([])
|
|
3571
|
+
});
|
|
3572
|
+
var ConceptSpiralEncounterSchema = z.object({
|
|
3573
|
+
concept_code: z.string(),
|
|
3574
|
+
session_id: LessonCodeSchema,
|
|
3575
|
+
encounter_index: z.number().int().positive(),
|
|
3576
|
+
bloom_cap: BloomLevelSchema,
|
|
3577
|
+
depth: DepthLevelSchema
|
|
3578
|
+
});
|
|
3579
|
+
var WalkingSkeletonSchema = z.object({
|
|
3580
|
+
epitome_unit_id: z.string().default("U01"),
|
|
3581
|
+
epitome_deliverables: z.array(z.string()).default([]),
|
|
3582
|
+
elaborations: z.array(z.object({
|
|
3583
|
+
unit_id: z.string(),
|
|
3584
|
+
focus_area: z.string(),
|
|
3585
|
+
elaborates_on: z.array(z.string()).default([])
|
|
3586
|
+
})).default([])
|
|
3587
|
+
});
|
|
3588
|
+
var MasteryGateSchema = z.object({
|
|
3589
|
+
phase_or_unit_id: z.string(),
|
|
3590
|
+
gate_name: z.string(),
|
|
3591
|
+
exit_criteria: z.array(z.string()).min(1),
|
|
3592
|
+
next_unit_id: z.string(),
|
|
3593
|
+
remediation: z.object({
|
|
3594
|
+
trigger: z.literal("FAIL_GATE_CRITERIA"),
|
|
3595
|
+
focus_minutes: z.number().int().default(15),
|
|
3596
|
+
action: z.string()
|
|
3597
|
+
})
|
|
3598
|
+
});
|
|
3599
|
+
var ConceptPrerequisiteEdgeSchema = z.object({
|
|
3600
|
+
concept_code: z.string(),
|
|
3601
|
+
requires: z.string(),
|
|
3602
|
+
source: z.enum(["MASTER_TREE", "INFERRED", "CONCEPT_LEVEL_PREREQ"]).default("CONCEPT_LEVEL_PREREQ"),
|
|
3603
|
+
confidence: z.number().min(0).max(1).default(0.8),
|
|
3604
|
+
rationale: z.string().default(""),
|
|
3605
|
+
structure_supported: z.boolean().default(true),
|
|
3606
|
+
needs_review: z.boolean().default(false),
|
|
3607
|
+
hub: z.boolean().default(false)
|
|
3608
|
+
});
|
|
3565
3609
|
var SessionPlanSchema = z.object({
|
|
3566
3610
|
id: LessonCodeSchema,
|
|
3567
3611
|
unit_id: z.string().regex(/^U\d{2}$/),
|
|
@@ -3582,7 +3626,14 @@ var SessionPlanSchema = z.object({
|
|
|
3582
3626
|
scaffold_decisions: z.array(ScaffoldDecisionEntrySchema).default([]),
|
|
3583
3627
|
// What the student can demonstrate after this session — feeds exit tickets.
|
|
3584
3628
|
exit_evidence: z.array(z.string()).min(1),
|
|
3585
|
-
differentiation: z.object({ bronze: z.string(), silver: z.string(), gold: z.string() })
|
|
3629
|
+
differentiation: z.object({ bronze: z.string(), silver: z.string(), gold: z.string() }),
|
|
3630
|
+
// P50: ZPD cognitive load status for this session
|
|
3631
|
+
zpd_status: SessionZpdStatusSchema.default({
|
|
3632
|
+
verdict: "OK",
|
|
3633
|
+
new_concept_count: 0,
|
|
3634
|
+
known_concept_count: 0,
|
|
3635
|
+
issues: []
|
|
3636
|
+
})
|
|
3586
3637
|
});
|
|
3587
3638
|
var TranslationPolicySchema = z.object({
|
|
3588
3639
|
policy: z.enum(["after_artifact", "end_of_unit", "at_publish", "native"]).default("native"),
|
|
@@ -3637,6 +3688,11 @@ var CurriculumPlanSchema = z.object({
|
|
|
3637
3688
|
// [2]
|
|
3638
3689
|
sessions: z.array(SessionPlanSchema).min(1),
|
|
3639
3690
|
// [3][4][5][6]
|
|
3691
|
+
// P50: Macro-pedagogical course structures
|
|
3692
|
+
walking_skeleton: WalkingSkeletonSchema.optional(),
|
|
3693
|
+
mastery_gates: z.array(MasteryGateSchema).default([]),
|
|
3694
|
+
concept_spiral_progression: z.array(ConceptSpiralEncounterSchema).default([]),
|
|
3695
|
+
concept_prerequisites: z.array(ConceptPrerequisiteEdgeSchema).default([]),
|
|
3640
3696
|
glossary_scope: z.array(z.object({
|
|
3641
3697
|
session_id: LessonCodeSchema,
|
|
3642
3698
|
terms: z.array(z.string())
|
|
@@ -11267,7 +11323,8 @@ function parseAllSessions(plan, frameworkMarkdown) {
|
|
|
11267
11323
|
prose_objective: s.prose_objective || s.objective || "",
|
|
11268
11324
|
new_keywords: Array.isArray(s.new_keywords) ? s.new_keywords : Array.isArray(s.keywords) ? s.keywords : [],
|
|
11269
11325
|
prerequisite_keywords: Array.isArray(s.prerequisite_keywords) ? s.prerequisite_keywords : [],
|
|
11270
|
-
depth_assignments: Array.isArray(s.depth_assignments) ? s.depth_assignments : []
|
|
11326
|
+
depth_assignments: Array.isArray(s.depth_assignments) ? s.depth_assignments : [],
|
|
11327
|
+
zpd_status: s.zpd_status
|
|
11271
11328
|
}));
|
|
11272
11329
|
}
|
|
11273
11330
|
}
|
|
@@ -11415,12 +11472,16 @@ async function extractCurriculumHorizon(opts) {
|
|
|
11415
11472
|
title: s.title,
|
|
11416
11473
|
keywords: s.new_keywords || []
|
|
11417
11474
|
}));
|
|
11475
|
+
const rawSpirals = Array.isArray(plan?.concept_spiral_progression) ? plan.concept_spiral_progression : [];
|
|
11476
|
+
const sessionSpirals = rawSpirals.filter((e) => e.session_id === targetLessonId);
|
|
11418
11477
|
return {
|
|
11419
11478
|
targetLessonId,
|
|
11420
11479
|
targetLessonIndex: targetIndex + 1,
|
|
11421
11480
|
totalLessons: sessions.length,
|
|
11422
11481
|
targetTitle: currentSession.title,
|
|
11423
11482
|
targetKeywords: currentSession.new_keywords || [],
|
|
11483
|
+
zpdStatus: currentSession.zpd_status,
|
|
11484
|
+
spiralProgression: sessionSpirals,
|
|
11424
11485
|
compactMasterySet: {
|
|
11425
11486
|
masteredKeywords,
|
|
11426
11487
|
masteredConcepts
|
|
@@ -11436,6 +11497,8 @@ function renderHorizonPromptBlock(horizon) {
|
|
|
11436
11497
|
totalLessons,
|
|
11437
11498
|
targetTitle,
|
|
11438
11499
|
targetKeywords,
|
|
11500
|
+
zpdStatus,
|
|
11501
|
+
spiralProgression,
|
|
11439
11502
|
compactMasterySet,
|
|
11440
11503
|
detailedBridge,
|
|
11441
11504
|
boundaryPeek
|
|
@@ -11443,6 +11506,19 @@ function renderHorizonPromptBlock(horizon) {
|
|
|
11443
11506
|
const lines = [
|
|
11444
11507
|
`# \u{1F9ED} CURRICULUM HORIZON & SCAFFOLDING MATRIX (Lesson ${targetLessonIndex}/${totalLessons}: "${targetTitle}" [${targetLessonId}])`
|
|
11445
11508
|
];
|
|
11509
|
+
if (zpdStatus && zpdStatus.verdict !== "OK") {
|
|
11510
|
+
lines.push(
|
|
11511
|
+
`
|
|
11512
|
+
> \u26A0\uFE0F **ZPD COGNITIVE LOAD ALERT (${zpdStatus.verdict}):** ${zpdStatus.issues?.join("; ") || "Scaffolding bridge mandated"}. Introduce minimal new syntax and anchor into known concepts.`
|
|
11513
|
+
);
|
|
11514
|
+
}
|
|
11515
|
+
if (spiralProgression && spiralProgression.length > 0) {
|
|
11516
|
+
const spiralNotes = spiralProgression.map(
|
|
11517
|
+
(sp) => `\`${sp.concept_code}\` (Encounter #${sp.encounter_index}): Bloom Cap [${sp.bloom_cap}], Depth [${sp.depth.toUpperCase()}]`
|
|
11518
|
+
);
|
|
11519
|
+
lines.push(`
|
|
11520
|
+
- **\u{1F300} Bruner Spiral Curricula Guidance:** ${spiralNotes.join(" | ")}`);
|
|
11521
|
+
}
|
|
11446
11522
|
if (compactMasterySet.masteredKeywords.length > 0 || compactMasterySet.masteredConcepts.length > 0) {
|
|
11447
11523
|
const rawKeywords = compactMasterySet.masteredKeywords;
|
|
11448
11524
|
const displayedKeywords = rawKeywords.length > 20 ? rawKeywords.slice(-20) : rawKeywords;
|
|
@@ -11613,9 +11689,9 @@ function buildSectionAwareExcerpt(markdown, opts = {}) {
|
|
|
11613
11689
|
if (s.canonicalKey && !byCanonical.has(s.canonicalKey)) {
|
|
11614
11690
|
byCanonical.set(s.canonicalKey, s);
|
|
11615
11691
|
}
|
|
11616
|
-
const
|
|
11617
|
-
if (!byCleanTitle.has(
|
|
11618
|
-
byCleanTitle.set(
|
|
11692
|
+
const norm2 = normalizeHeading(s.cleanTitle);
|
|
11693
|
+
if (!byCleanTitle.has(norm2)) {
|
|
11694
|
+
byCleanTitle.set(norm2, s);
|
|
11619
11695
|
}
|
|
11620
11696
|
if (!s.canonicalKey) {
|
|
11621
11697
|
unmatched.push(s);
|
|
@@ -11753,8 +11829,8 @@ function parseMarkdownSections(markdown, slcMap, artifactType) {
|
|
|
11753
11829
|
const flush = () => {
|
|
11754
11830
|
if (!currentHeading) return;
|
|
11755
11831
|
const cleanTitle = currentHeading.replace(/^#{1,4}\s+/, "").trim();
|
|
11756
|
-
const
|
|
11757
|
-
const canonicalKey = reverseMap.get(
|
|
11832
|
+
const norm2 = normalizeHeading(cleanTitle);
|
|
11833
|
+
const canonicalKey = reverseMap.get(norm2) || findCanonicalFuzzy(norm2);
|
|
11758
11834
|
sections.push({
|
|
11759
11835
|
rawHeading: currentHeading,
|
|
11760
11836
|
cleanTitle,
|
|
@@ -11780,49 +11856,55 @@ function parseMarkdownSections(markdown, slcMap, artifactType) {
|
|
|
11780
11856
|
function normalizeHeading(str) {
|
|
11781
11857
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
11782
11858
|
}
|
|
11783
|
-
function findCanonicalFuzzy(
|
|
11784
|
-
if (
|
|
11859
|
+
function findCanonicalFuzzy(norm2) {
|
|
11860
|
+
if (norm2.includes("toolchain") || norm2.includes("moi truong phat trien") || norm2.includes("cong cu") || norm2.includes("version") || norm2.includes("phan mem") || norm2.includes("development environment") || norm2.includes("technical overview") || norm2.includes("kien truc")) {
|
|
11785
11861
|
return "Technical Overview & Architecture Blueprint";
|
|
11786
11862
|
}
|
|
11787
|
-
if (
|
|
11863
|
+
if (norm2.includes("pinout") || norm2.includes("phan cung") || norm2.includes("hardware") || norm2.includes("wiring") || norm2.includes("ket noi")) {
|
|
11788
11864
|
return "Hardware Pinout & Wiring Configuration Matrix";
|
|
11789
11865
|
}
|
|
11790
|
-
if (
|
|
11866
|
+
if (norm2.includes("pedagog") || norm2.includes("phuong phap") || norm2.includes("day hoc") || norm2.includes("su pham")) {
|
|
11791
11867
|
return "Core Pedagogical Concept Anchor & Real-World Domain Bridge";
|
|
11792
11868
|
}
|
|
11793
|
-
if (
|
|
11869
|
+
if (norm2.includes("standard") || norm2.includes("tieu chuan") || norm2.includes("csta") || norm2.includes("cs2023") || norm2.includes("chuan academic")) {
|
|
11794
11870
|
return "Standards Alignment";
|
|
11795
11871
|
}
|
|
11796
|
-
if (
|
|
11872
|
+
if (norm2.includes("roadmap") || norm2.includes("lo trinh") || norm2.includes("milestone") || norm2.includes("giai doan")) {
|
|
11797
11873
|
return void 0;
|
|
11798
11874
|
}
|
|
11799
|
-
if (
|
|
11875
|
+
if (norm2.includes("symbol") || norm2.includes("identifier ledger") || norm2.includes("dinh danh")) {
|
|
11800
11876
|
return "Symbol & Identifier Ledger";
|
|
11801
11877
|
}
|
|
11802
|
-
if (
|
|
11878
|
+
if (norm2.includes("artifact contract") || norm2.includes("hop dong hoc lieu")) {
|
|
11803
11879
|
return "Artifact Contract";
|
|
11804
11880
|
}
|
|
11805
|
-
if (
|
|
11881
|
+
if (norm2.includes("lesson design plan") || norm2.includes("ke hoach thiet ke")) {
|
|
11806
11882
|
return "A. Lesson Design Plan";
|
|
11807
11883
|
}
|
|
11808
|
-
if (
|
|
11884
|
+
if (norm2.includes("lesson flow") || norm2.includes("tien trinh giang day")) {
|
|
11809
11885
|
return "B. Lesson Flow";
|
|
11810
11886
|
}
|
|
11811
|
-
if (
|
|
11887
|
+
if (norm2.includes("learning objective") || norm2.includes("muc tieu bai hoc")) {
|
|
11812
11888
|
return "Learning Objectives & Evidence";
|
|
11813
11889
|
}
|
|
11814
|
-
if (
|
|
11890
|
+
if (norm2.includes("activity sequence") || norm2.includes("chuoi hoat dong")) {
|
|
11815
11891
|
return "Activity Sequence";
|
|
11816
11892
|
}
|
|
11817
|
-
if (
|
|
11893
|
+
if (norm2.includes("key term") || norm2.includes("thuat ngu")) {
|
|
11818
11894
|
return "Key Terms";
|
|
11819
11895
|
}
|
|
11820
|
-
if (
|
|
11896
|
+
if (norm2.includes("concept narrative") || norm2.includes("dien giai khai niem")) {
|
|
11821
11897
|
return "Concept Narratives";
|
|
11822
11898
|
}
|
|
11823
|
-
if (
|
|
11899
|
+
if (norm2.includes("worked example") || norm2.includes("vi du")) {
|
|
11824
11900
|
return "Worked Micro-Examples";
|
|
11825
11901
|
}
|
|
11902
|
+
if (norm2.includes("common mistake") || norm2.includes("loi thuong gap") || norm2.includes("sai lam") || norm2.includes("pitfall")) {
|
|
11903
|
+
return "Common Mistakes";
|
|
11904
|
+
}
|
|
11905
|
+
if (norm2.includes("self check") || norm2.includes("self-check") || norm2.includes("tu kiem tra")) {
|
|
11906
|
+
return "Self-Check Questions";
|
|
11907
|
+
}
|
|
11826
11908
|
return void 0;
|
|
11827
11909
|
}
|
|
11828
11910
|
function truncateByBudget(source, budget) {
|
|
@@ -12757,7 +12839,7 @@ function decideScaffolds(session, nodeById, warnings) {
|
|
|
12757
12839
|
return decisions;
|
|
12758
12840
|
}
|
|
12759
12841
|
var DEPTH_NEXT = { ulo: "cio", cio: "sio", sio: "sio" };
|
|
12760
|
-
function assignDepths(nodeIds, nodeById) {
|
|
12842
|
+
function assignDepths(nodeIds, nodeById, conceptEncounterMap) {
|
|
12761
12843
|
const assignments = [];
|
|
12762
12844
|
let lastDepth = null;
|
|
12763
12845
|
for (const id of nodeIds) {
|
|
@@ -12765,8 +12847,14 @@ function assignDepths(nodeIds, nodeById) {
|
|
|
12765
12847
|
let depth;
|
|
12766
12848
|
let source;
|
|
12767
12849
|
if (node.kind === "concept") {
|
|
12850
|
+
const primaryCode = node.concept_codes[0];
|
|
12851
|
+
const encounters = primaryCode && conceptEncounterMap ? conceptEncounterMap.get(primaryCode) ?? 1 : 1;
|
|
12768
12852
|
const advanced = node.phase_id !== "" && /__ADV\d{2}$/.test(node.id);
|
|
12769
|
-
|
|
12853
|
+
if (encounters >= 2 || advanced) {
|
|
12854
|
+
depth = "sio";
|
|
12855
|
+
} else {
|
|
12856
|
+
depth = "cio";
|
|
12857
|
+
}
|
|
12770
12858
|
source = "planner";
|
|
12771
12859
|
} else {
|
|
12772
12860
|
depth = node.depth_hint ?? "cio";
|
|
@@ -12781,6 +12869,201 @@ function assignDepths(nodeIds, nodeById) {
|
|
|
12781
12869
|
}
|
|
12782
12870
|
return assignments;
|
|
12783
12871
|
}
|
|
12872
|
+
function computeConceptSpiralProgression(sessions, nodeById) {
|
|
12873
|
+
const encounters = [];
|
|
12874
|
+
const conceptCounts = /* @__PURE__ */ new Map();
|
|
12875
|
+
for (const s of sessions) {
|
|
12876
|
+
const sessionConcepts = [...new Set(s.node_ids.flatMap((id) => nodeById.get(id)?.concept_codes || []))];
|
|
12877
|
+
for (const cCode of sessionConcepts) {
|
|
12878
|
+
const count = (conceptCounts.get(cCode) || 0) + 1;
|
|
12879
|
+
conceptCounts.set(cCode, count);
|
|
12880
|
+
let bloomCap;
|
|
12881
|
+
let depth;
|
|
12882
|
+
if (count === 1) {
|
|
12883
|
+
bloomCap = "Understand";
|
|
12884
|
+
depth = "cio";
|
|
12885
|
+
} else if (count === 2) {
|
|
12886
|
+
bloomCap = "Apply";
|
|
12887
|
+
depth = "sio";
|
|
12888
|
+
} else {
|
|
12889
|
+
bloomCap = "Analyze";
|
|
12890
|
+
depth = "sio";
|
|
12891
|
+
}
|
|
12892
|
+
encounters.push({
|
|
12893
|
+
concept_code: cCode,
|
|
12894
|
+
session_id: s.id,
|
|
12895
|
+
encounter_index: count,
|
|
12896
|
+
bloom_cap: bloomCap,
|
|
12897
|
+
depth
|
|
12898
|
+
});
|
|
12899
|
+
}
|
|
12900
|
+
}
|
|
12901
|
+
return encounters;
|
|
12902
|
+
}
|
|
12903
|
+
function checkSessionZpd(sessionIndex, nodeIds, nodeById, allSeenConcepts, allSeenKeywords, entryKw, warnings) {
|
|
12904
|
+
const concepts = [...new Set(nodeIds.flatMap((id) => nodeById.get(id)?.concept_codes || []))];
|
|
12905
|
+
const newConcepts = concepts.filter((c) => !allSeenConcepts.has(c));
|
|
12906
|
+
const knownConcepts = concepts.filter((c) => allSeenConcepts.has(c));
|
|
12907
|
+
const allKeywords = [...new Set(nodeIds.flatMap((id) => nodeById.get(id)?.keywords || []))];
|
|
12908
|
+
const newKeywords = allKeywords.filter((k) => !allSeenKeywords.has(k.toLowerCase()) && !entryKw.has(k.toLowerCase()));
|
|
12909
|
+
const knownKeywords = allKeywords.filter((k) => allSeenKeywords.has(k.toLowerCase()) || entryKw.has(k.toLowerCase()));
|
|
12910
|
+
const issues = [];
|
|
12911
|
+
let verdict = "OK";
|
|
12912
|
+
if (concepts.length > 0 && newConcepts.length > 2) {
|
|
12913
|
+
verdict = "TOO_MANY_NEW";
|
|
12914
|
+
issues.push(`${newConcepts.length} new concepts exceed ZPD limit (max 2)`);
|
|
12915
|
+
} else if (concepts.length === 0 && newKeywords.length > 4) {
|
|
12916
|
+
verdict = "TOO_MANY_NEW";
|
|
12917
|
+
issues.push(`${newKeywords.length} new keywords exceed ZPD limit (max 4)`);
|
|
12918
|
+
}
|
|
12919
|
+
if (sessionIndex > 0) {
|
|
12920
|
+
if (concepts.length > 1 && knownConcepts.length === 0) {
|
|
12921
|
+
verdict = "NO_ZPD_BRIDGE";
|
|
12922
|
+
issues.push("No known concepts from previous sessions to bridge new learning");
|
|
12923
|
+
} else if (concepts.length === 0 && allKeywords.length > 2 && knownKeywords.length === 0) {
|
|
12924
|
+
verdict = "NO_ZPD_BRIDGE";
|
|
12925
|
+
issues.push("No known keywords from previous sessions to bridge new learning");
|
|
12926
|
+
}
|
|
12927
|
+
}
|
|
12928
|
+
let bridgeRepair;
|
|
12929
|
+
if (verdict === "NO_ZPD_BRIDGE" && (allSeenConcepts.size > 0 || allSeenKeywords.size > 0)) {
|
|
12930
|
+
const bridgeAnchor = [...allSeenConcepts].pop() || [...allSeenKeywords].pop() || "prior knowledge";
|
|
12931
|
+
bridgeRepair = {
|
|
12932
|
+
node_id: nodeIds[0],
|
|
12933
|
+
decision: "recap_in_lesson",
|
|
12934
|
+
reason: `ZPD self-healing: recap anchor (${bridgeAnchor}) to bridge into new material`
|
|
12935
|
+
};
|
|
12936
|
+
warnings.push(`ZPD bridge self-healing: session ${sessionIndex + 1} injected recap anchor (${bridgeAnchor})`);
|
|
12937
|
+
}
|
|
12938
|
+
for (const c of concepts) allSeenConcepts.add(c);
|
|
12939
|
+
for (const k of allKeywords) allSeenKeywords.add(k.toLowerCase());
|
|
12940
|
+
return {
|
|
12941
|
+
status: {
|
|
12942
|
+
verdict,
|
|
12943
|
+
new_concept_count: concepts.length > 0 ? newConcepts.length : newKeywords.length,
|
|
12944
|
+
known_concept_count: concepts.length > 0 ? knownConcepts.length : knownKeywords.length,
|
|
12945
|
+
issues
|
|
12946
|
+
},
|
|
12947
|
+
bridgeRepair
|
|
12948
|
+
};
|
|
12949
|
+
}
|
|
12950
|
+
function buildWalkingSkeleton(units, sessions) {
|
|
12951
|
+
const epitomeUnit = units[0];
|
|
12952
|
+
const epitomeId = epitomeUnit?.id || "U01";
|
|
12953
|
+
const epitomeDeliverables = sessions.filter((s) => s.unit_id === epitomeId).flatMap((s) => s.exit_evidence || []).slice(0, 8);
|
|
12954
|
+
const elaborations = units.slice(1).map((u) => ({
|
|
12955
|
+
unit_id: u.id,
|
|
12956
|
+
focus_area: u.name,
|
|
12957
|
+
elaborates_on: epitomeDeliverables.slice(0, 3)
|
|
12958
|
+
}));
|
|
12959
|
+
return {
|
|
12960
|
+
epitome_unit_id: epitomeId,
|
|
12961
|
+
epitome_deliverables: epitomeDeliverables,
|
|
12962
|
+
elaborations
|
|
12963
|
+
};
|
|
12964
|
+
}
|
|
12965
|
+
function buildMasteryGates(units, sessions) {
|
|
12966
|
+
const gates = [];
|
|
12967
|
+
for (let i = 0; i < units.length - 1; i++) {
|
|
12968
|
+
const cur = units[i];
|
|
12969
|
+
const next = units[i + 1];
|
|
12970
|
+
const unitEvidence = sessions.filter((s) => s.unit_id === cur.id).flatMap((s) => s.exit_evidence || []).slice(0, 6);
|
|
12971
|
+
gates.push({
|
|
12972
|
+
phase_or_unit_id: cur.id,
|
|
12973
|
+
gate_name: `${cur.name} Mastery Gate`,
|
|
12974
|
+
exit_criteria: unitEvidence.length > 0 ? unitEvidence : [`Master all deliverables for ${cur.name}`],
|
|
12975
|
+
next_unit_id: next.id,
|
|
12976
|
+
remediation: {
|
|
12977
|
+
trigger: "FAIL_GATE_CRITERIA",
|
|
12978
|
+
focus_minutes: 15,
|
|
12979
|
+
action: `Review and complete failing practical criteria for ${cur.name} before starting ${next.name}`
|
|
12980
|
+
}
|
|
12981
|
+
});
|
|
12982
|
+
}
|
|
12983
|
+
return gates;
|
|
12984
|
+
}
|
|
12985
|
+
function dropCyclicConceptEdges(edges) {
|
|
12986
|
+
const pairSet = new Set(edges.map((e) => `${e.concept_code}|${e.requires}`));
|
|
12987
|
+
const nonSymmetric = edges.filter((e) => !pairSet.has(`${e.requires}|${e.concept_code}`));
|
|
12988
|
+
const deps = /* @__PURE__ */ new Map();
|
|
12989
|
+
const createsCycle = (a, b) => {
|
|
12990
|
+
const stack = [b];
|
|
12991
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12992
|
+
while (stack.length > 0) {
|
|
12993
|
+
const n = stack.pop();
|
|
12994
|
+
if (n === a) return true;
|
|
12995
|
+
if (seen.has(n)) continue;
|
|
12996
|
+
seen.add(n);
|
|
12997
|
+
const targets = deps.get(n);
|
|
12998
|
+
if (targets) {
|
|
12999
|
+
for (const t of targets) stack.push(t);
|
|
13000
|
+
}
|
|
13001
|
+
}
|
|
13002
|
+
return false;
|
|
13003
|
+
};
|
|
13004
|
+
const out = [];
|
|
13005
|
+
for (const e of nonSymmetric) {
|
|
13006
|
+
if (createsCycle(e.concept_code, e.requires)) continue;
|
|
13007
|
+
if (!deps.has(e.concept_code)) deps.set(e.concept_code, /* @__PURE__ */ new Set());
|
|
13008
|
+
deps.get(e.concept_code).add(e.requires);
|
|
13009
|
+
out.push(e);
|
|
13010
|
+
}
|
|
13011
|
+
return out;
|
|
13012
|
+
}
|
|
13013
|
+
function buildConceptPrerequisites(sessions, nodeById, edges) {
|
|
13014
|
+
const firstSeen = /* @__PURE__ */ new Map();
|
|
13015
|
+
for (let i = 0; i < sessions.length; i++) {
|
|
13016
|
+
const s = sessions[i];
|
|
13017
|
+
for (const nid of s.node_ids) {
|
|
13018
|
+
const codes = nodeById.get(nid)?.concept_codes || [];
|
|
13019
|
+
for (const c of codes) {
|
|
13020
|
+
if (!firstSeen.has(c)) firstSeen.set(c, i);
|
|
13021
|
+
}
|
|
13022
|
+
}
|
|
13023
|
+
}
|
|
13024
|
+
const rawEdges = [];
|
|
13025
|
+
const seenPair = /* @__PURE__ */ new Set();
|
|
13026
|
+
for (const e of edges) {
|
|
13027
|
+
const fromNode = nodeById.get(e.from);
|
|
13028
|
+
const toNode = nodeById.get(e.to);
|
|
13029
|
+
if (!fromNode || !toNode) continue;
|
|
13030
|
+
const fromCodes = fromNode.concept_codes || [];
|
|
13031
|
+
const toCodes = toNode.concept_codes || [];
|
|
13032
|
+
for (const tc of toCodes) {
|
|
13033
|
+
for (const fc of fromCodes) {
|
|
13034
|
+
if (tc === fc) continue;
|
|
13035
|
+
const key = `${tc}|${fc}`;
|
|
13036
|
+
if (seenPair.has(key)) continue;
|
|
13037
|
+
seenPair.add(key);
|
|
13038
|
+
const firstSeenTc = firstSeen.get(tc) ?? 999;
|
|
13039
|
+
const firstSeenFc = firstSeen.get(fc) ?? 999;
|
|
13040
|
+
const supported = firstSeenFc <= firstSeenTc;
|
|
13041
|
+
rawEdges.push({
|
|
13042
|
+
concept_code: tc,
|
|
13043
|
+
requires: fc,
|
|
13044
|
+
source: "CONCEPT_LEVEL_PREREQ",
|
|
13045
|
+
confidence: supported ? 0.8 : 0.6,
|
|
13046
|
+
rationale: e.reason || `Derived from planning node dependency: ${fromNode.name} -> ${toNode.name}`,
|
|
13047
|
+
structure_supported: supported,
|
|
13048
|
+
needs_review: !supported,
|
|
13049
|
+
hub: false
|
|
13050
|
+
});
|
|
13051
|
+
}
|
|
13052
|
+
}
|
|
13053
|
+
}
|
|
13054
|
+
const fanOut = /* @__PURE__ */ new Map();
|
|
13055
|
+
for (const re of rawEdges) {
|
|
13056
|
+
fanOut.set(re.concept_code, (fanOut.get(re.concept_code) || 0) + 1);
|
|
13057
|
+
}
|
|
13058
|
+
for (const re of rawEdges) {
|
|
13059
|
+
if ((fanOut.get(re.concept_code) || 0) >= 6) {
|
|
13060
|
+
re.hub = true;
|
|
13061
|
+
re.confidence = Math.min(re.confidence, 0.5);
|
|
13062
|
+
re.needs_review = true;
|
|
13063
|
+
}
|
|
13064
|
+
}
|
|
13065
|
+
return dropCyclicConceptEdges(rawEdges);
|
|
13066
|
+
}
|
|
12784
13067
|
async function buildCurriculumPlan(rawGraph, options) {
|
|
12785
13068
|
const { constraints } = options;
|
|
12786
13069
|
const warnings = [];
|
|
@@ -12876,6 +13159,9 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12876
13159
|
const seenNodes = /* @__PURE__ */ new Set();
|
|
12877
13160
|
const multiPartNodes = new Set(packed.flatMap((s) => s.entries.filter((e) => e.totalParts > 1).map((e) => e.id)));
|
|
12878
13161
|
const sessions = [];
|
|
13162
|
+
const allSeenConcepts = /* @__PURE__ */ new Set();
|
|
13163
|
+
const allSeenKeywords = /* @__PURE__ */ new Set();
|
|
13164
|
+
const conceptEncounterMap = /* @__PURE__ */ new Map();
|
|
12879
13165
|
for (let i = 0; i < packed.length; i++) {
|
|
12880
13166
|
const s = packed[i];
|
|
12881
13167
|
for (const id of s.nodeIds) {
|
|
@@ -12920,6 +13206,16 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12920
13206
|
knowledge: s.knowledgeMinutes || 0,
|
|
12921
13207
|
practice: s.practiceMinutes + (s.practiceMinutes === 0 && s.knowledgeMinutes > 0 ? Math.min(spareMinutes, 10) : 0)
|
|
12922
13208
|
};
|
|
13209
|
+
const sessionConcepts = [...new Set(s.nodeIds.flatMap((id) => nodeById.get(id)?.concept_codes || []))];
|
|
13210
|
+
for (const cCode of sessionConcepts) {
|
|
13211
|
+
const curCount = (conceptEncounterMap.get(cCode) || 0) + 1;
|
|
13212
|
+
conceptEncounterMap.set(cCode, curCount);
|
|
13213
|
+
}
|
|
13214
|
+
const zpdResult = checkSessionZpd(i, s.nodeIds, nodeById, allSeenConcepts, allSeenKeywords, entryKw, warnings);
|
|
13215
|
+
const prereqDecisions = decidePrerequisites(ctx, nodeById, graph.edges, sessionIndexByNode, sessionOrderByIndex, constraints);
|
|
13216
|
+
if (zpdResult.bridgeRepair) {
|
|
13217
|
+
prereqDecisions.unshift(zpdResult.bridgeRepair);
|
|
13218
|
+
}
|
|
12923
13219
|
sessions.push({
|
|
12924
13220
|
id: lessonCode,
|
|
12925
13221
|
unit_id: unit.id,
|
|
@@ -12940,8 +13236,8 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12940
13236
|
// Spiral pedagogy = apply at greater depth, not re-lecture.
|
|
12941
13237
|
practice_minutes: sessionMinutes.practice,
|
|
12942
13238
|
overhead_minutes: spec.overheadMinutes,
|
|
12943
|
-
depth_assignments: assignDepths(s.nodeIds, nodeById),
|
|
12944
|
-
prerequisite_decisions:
|
|
13239
|
+
depth_assignments: assignDepths(s.nodeIds, nodeById, conceptEncounterMap),
|
|
13240
|
+
prerequisite_decisions: prereqDecisions,
|
|
12945
13241
|
scaffold_decisions: decideScaffolds(ctx, nodeById, warnings),
|
|
12946
13242
|
// Deliverable phrasing follows the node role: concept → evidence is the
|
|
12947
13243
|
// explanation, product_step/skill → the artifact or activity itself.
|
|
@@ -12956,16 +13252,58 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12956
13252
|
bronze: "Complete the core deliverable for " + nodeNames[0] + " with provided scaffolding.",
|
|
12957
13253
|
silver: "Complete all session deliverables independently.",
|
|
12958
13254
|
gold: "Extend the deliverable: combine " + nodeNames.join(", ") + " in a self-chosen variant."
|
|
12959
|
-
}
|
|
13255
|
+
},
|
|
13256
|
+
// P50: ZPD cognitive load status for this session
|
|
13257
|
+
zpd_status: zpdResult.status
|
|
12960
13258
|
});
|
|
12961
13259
|
}
|
|
12962
13260
|
const unassigned = graph.nodes.map((n) => n.id).filter((id) => !seenNodes.has(id));
|
|
12963
13261
|
if (unassigned.length > 0) throw new Error("Coverage violation: unassigned nodes " + unassigned.join(", "));
|
|
13262
|
+
if (options.llmFn && sessions.length > 0) {
|
|
13263
|
+
try {
|
|
13264
|
+
const sessionSummaries = sessions.map((s) => `${s.id}|${s.title}|objective: ${s.prose_objective.slice(0, 120)}|keywords: ${s.new_keywords.join("/")}`).join("\n");
|
|
13265
|
+
const dSys = 'You differentiate learning tasks. Output ONLY a JSON object mapping session-id to {"bronze":string,"silver":string,"gold":string}. Each tier ONE sentence: bronze = foundational task with provided scaffolding; silver = independent application; gold = creative extension combining session concepts. Same language as the objectives.';
|
|
13266
|
+
const dUsr = `Age band: ${constraints.age_band[0]}-${constraints.age_band[1]}. Entry level: ${constraints.entry_level}.
|
|
13267
|
+
Sessions:
|
|
13268
|
+
${sessionSummaries}`;
|
|
13269
|
+
const raw = (await options.llmFn(dSys, dUsr)).trim();
|
|
13270
|
+
const match = raw.match(/\{[\s\S]*\}/);
|
|
13271
|
+
if (match) {
|
|
13272
|
+
const parsed = JSON.parse(match[0]);
|
|
13273
|
+
let upgraded = 0;
|
|
13274
|
+
for (const s of sessions) {
|
|
13275
|
+
const d = parsed[s.id];
|
|
13276
|
+
if (d && typeof d.bronze === "string" && d.bronze.length >= 10 && typeof d.silver === "string" && d.silver.length >= 10 && typeof d.gold === "string" && d.gold.length >= 10) {
|
|
13277
|
+
s.differentiation = { bronze: d.bronze, silver: d.silver, gold: d.gold };
|
|
13278
|
+
upgraded++;
|
|
13279
|
+
}
|
|
13280
|
+
}
|
|
13281
|
+
if (upgraded < sessions.length) warnings.push(`differentiation_llm_partial:${upgraded}/${sessions.length}`);
|
|
13282
|
+
} else {
|
|
13283
|
+
warnings.push("differentiation_llm_unparseable");
|
|
13284
|
+
}
|
|
13285
|
+
} catch (e) {
|
|
13286
|
+
warnings.push("differentiation_llm_failed:" + (e instanceof Error ? e.message.slice(0, 80) : String(e).slice(0, 80)));
|
|
13287
|
+
}
|
|
13288
|
+
}
|
|
12964
13289
|
const glossaryScope = sessions.map((s) => ({
|
|
12965
13290
|
session_id: s.id,
|
|
12966
13291
|
terms: [...new Set(s.node_ids.flatMap((id) => nodeById.get(id).keywords))]
|
|
12967
13292
|
}));
|
|
12968
|
-
const
|
|
13293
|
+
const conceptSpiralProgression = computeConceptSpiralProgression(sessions, nodeById);
|
|
13294
|
+
const walkingSkeleton = buildWalkingSkeleton(units, sessions);
|
|
13295
|
+
const masteryGates = buildMasteryGates(units, sessions);
|
|
13296
|
+
const conceptPrerequisites = buildConceptPrerequisites(sessions, nodeById, graph.edges);
|
|
13297
|
+
const planPayload = {
|
|
13298
|
+
units,
|
|
13299
|
+
sessions,
|
|
13300
|
+
course: { objectives: courseObjectives },
|
|
13301
|
+
constraints,
|
|
13302
|
+
walking_skeleton: walkingSkeleton,
|
|
13303
|
+
mastery_gates: masteryGates,
|
|
13304
|
+
concept_spiral_progression: conceptSpiralProgression,
|
|
13305
|
+
concept_prerequisites: conceptPrerequisites
|
|
13306
|
+
};
|
|
12969
13307
|
const planHash = createHash("sha256").update(JSON.stringify(planPayload)).digest("hex").slice(0, 16);
|
|
12970
13308
|
const plan = CurriculumPlanSchema.parse({
|
|
12971
13309
|
schema_version: 1,
|
|
@@ -12977,6 +13315,10 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12977
13315
|
course: { objectives: courseObjectives, capstone_ref: constraints.capstone },
|
|
12978
13316
|
units,
|
|
12979
13317
|
sessions,
|
|
13318
|
+
walking_skeleton: walkingSkeleton,
|
|
13319
|
+
mastery_gates: masteryGates,
|
|
13320
|
+
concept_spiral_progression: conceptSpiralProgression,
|
|
13321
|
+
concept_prerequisites: conceptPrerequisites,
|
|
12980
13322
|
glossary_scope: glossaryScope,
|
|
12981
13323
|
translation: options.translation ?? { policy: "at_publish", target_language: null },
|
|
12982
13324
|
coverage_report: { assigned_node_ids: [...seenNodes], unassigned_node_ids: [], warnings },
|
|
@@ -13008,6 +13350,13 @@ function buildSessionSliceContext(plan, lessonCode) {
|
|
|
13008
13350
|
lines.push("- Prerequisite keywords: " + (s.prerequisite_keywords.join(", ") || "(none)"));
|
|
13009
13351
|
lines.push("- Time split: knowledge " + s.knowledge_minutes + "m / practice " + s.practice_minutes + "m / overhead " + s.overhead_minutes + "m");
|
|
13010
13352
|
lines.push("- Depth assignments: " + s.depth_assignments.map((d) => d.node_id + "=" + d.depth.toUpperCase() + "(" + d.source + ")").join("; "));
|
|
13353
|
+
if (s.zpd_status && s.zpd_status.verdict !== "OK") {
|
|
13354
|
+
lines.push("- ZPD alert: " + s.zpd_status.verdict + " (" + s.zpd_status.issues.join("; ") + ")");
|
|
13355
|
+
}
|
|
13356
|
+
const sessionSpirals = (plan.concept_spiral_progression || []).filter((e) => e.session_id === lessonCode);
|
|
13357
|
+
if (sessionSpirals.length > 0) {
|
|
13358
|
+
lines.push("- Spiral encounters: " + sessionSpirals.map((e) => `${e.concept_code}#${e.encounter_index}=${e.bloom_cap}(${e.depth.toUpperCase()})`).join("; "));
|
|
13359
|
+
}
|
|
13011
13360
|
if (s.prerequisite_decisions.length > 0) {
|
|
13012
13361
|
lines.push("- Prerequisite decisions [" + s.prerequisite_decisions.length + "]:");
|
|
13013
13362
|
for (const d of s.prerequisite_decisions) lines.push(" * " + d.node_id + ": " + d.decision + " \u2014 " + d.reason);
|
|
@@ -13329,14 +13678,14 @@ function lintFrameworkPack(pack) {
|
|
|
13329
13678
|
const primaryLang = pack.manifest.languages[0];
|
|
13330
13679
|
const text = s.texts[primaryLang];
|
|
13331
13680
|
if (!text) continue;
|
|
13332
|
-
const
|
|
13333
|
-
if (!
|
|
13334
|
-
const prev = seen.get(
|
|
13681
|
+
const norm2 = text.toLowerCase().replace(/[^\p{L}\p{N}\s]/gu, " ").split(/\s+/).filter((w) => w.length > 2).sort().join(" ");
|
|
13682
|
+
if (!norm2) continue;
|
|
13683
|
+
const prev = seen.get(norm2);
|
|
13335
13684
|
if (prev !== void 0) {
|
|
13336
13685
|
issues.push({ severity: "WARNING", code: "DUP_TEXT_EXACT", message: `Text is token-identical to statement "${prev}"`, ref: s.id });
|
|
13337
13686
|
} else {
|
|
13338
13687
|
for (const [otherNorm, otherId] of seen.entries()) {
|
|
13339
|
-
const a = new Set(
|
|
13688
|
+
const a = new Set(norm2.split(" "));
|
|
13340
13689
|
const b = new Set(otherNorm.split(" "));
|
|
13341
13690
|
let inter = 0;
|
|
13342
13691
|
for (const w of a) if (b.has(w)) inter++;
|
|
@@ -13346,7 +13695,7 @@ function lintFrameworkPack(pack) {
|
|
|
13346
13695
|
break;
|
|
13347
13696
|
}
|
|
13348
13697
|
}
|
|
13349
|
-
seen.set(
|
|
13698
|
+
seen.set(norm2, s.id);
|
|
13350
13699
|
}
|
|
13351
13700
|
}
|
|
13352
13701
|
for (const m of pack.mappings ?? []) {
|
|
@@ -26087,6 +26436,263 @@ function extractStandardRefs(text) {
|
|
|
26087
26436
|
return Array.from(new Set(matches));
|
|
26088
26437
|
}
|
|
26089
26438
|
|
|
26439
|
+
// src/services/contextSlots.ts
|
|
26440
|
+
var LESSON_SLOT_BUDGETS = {
|
|
26441
|
+
ACT: { budget: 8e3 },
|
|
26442
|
+
GUIDE: { budget: 6e3 },
|
|
26443
|
+
QUIZ: { budget: 3500, priorities: ["A. Lesson Design Plan"] },
|
|
26444
|
+
SLIDE: { budget: 4500, priorities: ["B. Lesson Flow", "A. Lesson Design Plan"] },
|
|
26445
|
+
WKS: { budget: 4500, priorities: ["A. Lesson Design Plan", "B. Lesson Flow"] },
|
|
26446
|
+
EXIT_TICKET: { budget: 3e3, priorities: ["A. Lesson Design Plan", "B. Lesson Flow"] }
|
|
26447
|
+
};
|
|
26448
|
+
var KX_ONLY_TYPES = /* @__PURE__ */ new Set(["CODE", "HANDOUT", "EXT"]);
|
|
26449
|
+
var KX_SLOT_PRIORITIES = {
|
|
26450
|
+
QUIZ: ["Common Mistakes", "Self-Check Questions", "Key Terms", "Concept Narratives"],
|
|
26451
|
+
EXIT_TICKET: ["Self-Check Questions", "Key Terms"],
|
|
26452
|
+
WKS: ["Self-Check Questions", "Worked Micro-Examples", "Key Terms"],
|
|
26453
|
+
CODE: ["Worked Micro-Examples", "Key Terms", "Common Mistakes"],
|
|
26454
|
+
GUIDE: ["Common Mistakes", "Key Terms", "Concept Narratives"],
|
|
26455
|
+
HANDOUT: ["Key Terms", "Concept Narratives", "Common Mistakes"],
|
|
26456
|
+
SLIDE: ["Key Terms", "Worked Micro-Examples"],
|
|
26457
|
+
ACT: ["Worked Micro-Examples", "Common Mistakes"],
|
|
26458
|
+
EXT: ["Worked Micro-Examples", "Common Mistakes"]
|
|
26459
|
+
};
|
|
26460
|
+
var norm = (s) => s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "");
|
|
26461
|
+
function extractActivityContractRows(lessonContent, artifactType, maxChars = 1500) {
|
|
26462
|
+
if (!lessonContent) return "";
|
|
26463
|
+
const wanted = norm(artifactType).replace(/_/g, "");
|
|
26464
|
+
const lines = lessonContent.split("\n");
|
|
26465
|
+
let inSeq = false;
|
|
26466
|
+
const headerRows = [];
|
|
26467
|
+
const matchedRows = [];
|
|
26468
|
+
const allRows = [];
|
|
26469
|
+
for (let i = 0; i < lines.length; i++) {
|
|
26470
|
+
const line = lines[i];
|
|
26471
|
+
const h = line.match(/^#{2,4}\s+(.*)$/);
|
|
26472
|
+
if (h) {
|
|
26473
|
+
const t2 = h[1];
|
|
26474
|
+
if (/activity\s*sequence/i.test(t2)) inSeq = true;
|
|
26475
|
+
else if (inSeq) break;
|
|
26476
|
+
continue;
|
|
26477
|
+
}
|
|
26478
|
+
if (!inSeq) continue;
|
|
26479
|
+
const t = line.trim();
|
|
26480
|
+
if (!t.startsWith("|")) continue;
|
|
26481
|
+
if (/^\|\s*[-: |]+\|\s*$/.test(t)) continue;
|
|
26482
|
+
const cells = t.split("|").slice(1, -1).map((c) => c.trim());
|
|
26483
|
+
if (cells.length >= 4) {
|
|
26484
|
+
if (headerRows.length === 0) {
|
|
26485
|
+
headerRows.push(t);
|
|
26486
|
+
continue;
|
|
26487
|
+
}
|
|
26488
|
+
allRows.push(t);
|
|
26489
|
+
const contract = cells[cells.length - 1] ?? "";
|
|
26490
|
+
const candidates = contract.split(/[,;/]/).map((c) => norm(c));
|
|
26491
|
+
if (candidates.some((c) => c === wanted || c.length > 3 && (c.includes(wanted) || wanted.includes(c)))) {
|
|
26492
|
+
matchedRows.push(t);
|
|
26493
|
+
}
|
|
26494
|
+
}
|
|
26495
|
+
}
|
|
26496
|
+
const rows = matchedRows.length > 0 ? matchedRows : allRows.slice(0, 3);
|
|
26497
|
+
if (rows.length === 0) return "";
|
|
26498
|
+
let out = headerRows[0] ?? "";
|
|
26499
|
+
for (const r of rows) {
|
|
26500
|
+
if (out.length + r.length + 1 > maxChars) break;
|
|
26501
|
+
out += "\n" + r;
|
|
26502
|
+
}
|
|
26503
|
+
return out;
|
|
26504
|
+
}
|
|
26505
|
+
function extractTieredScaffoldingBlock(lessonContent, maxChars = 900) {
|
|
26506
|
+
if (!lessonContent) return "";
|
|
26507
|
+
const lines = lessonContent.split("\n");
|
|
26508
|
+
let capture = null;
|
|
26509
|
+
for (const line of lines) {
|
|
26510
|
+
const h = line.match(/^#{2,4}\s+(.*)$/);
|
|
26511
|
+
if (h) {
|
|
26512
|
+
const isTierHeading = /elaborate|tiered|scaffold/i.test(h[1] ?? "");
|
|
26513
|
+
if (capture && !isTierHeading) break;
|
|
26514
|
+
if (isTierHeading) capture = [];
|
|
26515
|
+
continue;
|
|
26516
|
+
}
|
|
26517
|
+
if (capture) {
|
|
26518
|
+
capture.push(line);
|
|
26519
|
+
if (capture.join("").length >= maxChars) break;
|
|
26520
|
+
}
|
|
26521
|
+
}
|
|
26522
|
+
const body = (capture ?? []).join("\n").trim();
|
|
26523
|
+
return body ? body.slice(0, maxChars) : "";
|
|
26524
|
+
}
|
|
26525
|
+
function extractAssessmentMap(lessonContent, maxChars = 1200) {
|
|
26526
|
+
if (!lessonContent) return "";
|
|
26527
|
+
const lines = lessonContent.split("\n");
|
|
26528
|
+
let capture = null;
|
|
26529
|
+
for (const line of lines) {
|
|
26530
|
+
const h = line.match(/^#{2,4}\s+(.*)$/);
|
|
26531
|
+
if (h) {
|
|
26532
|
+
const isTarget = /assessment\s*map/i.test(h[1] ?? "");
|
|
26533
|
+
if (capture && !isTarget) break;
|
|
26534
|
+
if (isTarget) capture = [];
|
|
26535
|
+
continue;
|
|
26536
|
+
}
|
|
26537
|
+
if (capture) {
|
|
26538
|
+
capture.push(line);
|
|
26539
|
+
if (capture.join("").length >= maxChars) break;
|
|
26540
|
+
}
|
|
26541
|
+
}
|
|
26542
|
+
const body = (capture ?? []).join("\n").trim();
|
|
26543
|
+
return body ? body.slice(0, maxChars) : "";
|
|
26544
|
+
}
|
|
26545
|
+
function blockMeta(slot, source, text, verified, issues = []) {
|
|
26546
|
+
return { slot, source, chars: text.length, verified, issues };
|
|
26547
|
+
}
|
|
26548
|
+
function buildSatelliteContext(input) {
|
|
26549
|
+
const {
|
|
26550
|
+
artifactType,
|
|
26551
|
+
commonContext,
|
|
26552
|
+
lessonContent,
|
|
26553
|
+
lessonExcerpt,
|
|
26554
|
+
expositionContent,
|
|
26555
|
+
slcMarkdown,
|
|
26556
|
+
symbolLedgerBlock,
|
|
26557
|
+
pedagogyLabel,
|
|
26558
|
+
mode = "legacy"
|
|
26559
|
+
} = input;
|
|
26560
|
+
const type = (artifactType || "").toUpperCase().trim();
|
|
26561
|
+
if (mode === "legacy" || type === "LESSON") {
|
|
26562
|
+
const context2 = `${commonContext}
|
|
26563
|
+
|
|
26564
|
+
[CANONICAL LESSON PLAN (${pedagogyLabel ?? "LESSON"})]:
|
|
26565
|
+
${lessonExcerpt.excerpt}${symbolLedgerBlock}`;
|
|
26566
|
+
return {
|
|
26567
|
+
context: context2,
|
|
26568
|
+
blocks: [
|
|
26569
|
+
blockMeta("commonContext", "COMPOSITE", commonContext, true),
|
|
26570
|
+
blockMeta("lessonExcerpt", "LESSON", lessonExcerpt.excerpt, lessonExcerpt.verified, lessonExcerpt.issues)
|
|
26571
|
+
],
|
|
26572
|
+
verified: lessonExcerpt.verified,
|
|
26573
|
+
sectionAware: lessonExcerpt.sectionAware,
|
|
26574
|
+
issues: lessonExcerpt.issues,
|
|
26575
|
+
tokenEstimate: Math.round(context2.length / 4),
|
|
26576
|
+
canonicalExcerpt: lessonExcerpt.excerpt
|
|
26577
|
+
};
|
|
26578
|
+
}
|
|
26579
|
+
const blocks = [];
|
|
26580
|
+
const issues = [];
|
|
26581
|
+
const parts = [commonContext];
|
|
26582
|
+
blocks.push(blockMeta("commonContext", "COMPOSITE", commonContext, true));
|
|
26583
|
+
let excerptSlot;
|
|
26584
|
+
let miniSlot;
|
|
26585
|
+
const compositeHasKx = /###\s+KNOWLEDGE_EXPOSITION/.test(commonContext);
|
|
26586
|
+
if (expositionContent.trim() && !compositeHasKx) {
|
|
26587
|
+
const kxExcerpt = buildSectionAwareExcerpt(expositionContent, {
|
|
26588
|
+
priorities: KX_SLOT_PRIORITIES[type] ?? ["Key Terms", "Concept Narratives", "Worked Micro-Examples"],
|
|
26589
|
+
budget: 4500,
|
|
26590
|
+
sectionLanguageContract: slcMarkdown,
|
|
26591
|
+
artifactType: "KNOWLEDGE_EXPOSITION"
|
|
26592
|
+
});
|
|
26593
|
+
parts.push(`
|
|
26594
|
+
|
|
26595
|
+
[KNOWLEDGE_EXPOSITION (canonical knowledge \u2014 teach from this, do not contradict; scoped for ${type})]:
|
|
26596
|
+
${kxExcerpt.excerpt}`);
|
|
26597
|
+
blocks.push(blockMeta("kxExcerpt:" + type, "KNOWLEDGE_EXPOSITION", kxExcerpt.excerpt, kxExcerpt.verified, kxExcerpt.issues));
|
|
26598
|
+
if (!kxExcerpt.verified) issues.push(...kxExcerpt.issues.map((i) => `kx:${i}`));
|
|
26599
|
+
}
|
|
26600
|
+
if (!KX_ONLY_TYPES.has(type)) {
|
|
26601
|
+
const spec = LESSON_SLOT_BUDGETS[type] ?? { budget: 12e3 };
|
|
26602
|
+
const excerpt = buildSectionAwareExcerpt(lessonContent, {
|
|
26603
|
+
priorities: spec.priorities ?? ["Artifact Contract", "A. Lesson Design Plan", "B. Lesson Flow", "Learning Objectives & Evidence", "Activity Sequence"],
|
|
26604
|
+
budget: spec.budget,
|
|
26605
|
+
sectionLanguageContract: slcMarkdown,
|
|
26606
|
+
artifactType: "LESSON"
|
|
26607
|
+
});
|
|
26608
|
+
const excerptBlock = `
|
|
26609
|
+
|
|
26610
|
+
[CANONICAL LESSON PLAN (scoped for ${type})]:
|
|
26611
|
+
${excerpt.excerpt}`;
|
|
26612
|
+
parts.push(excerptBlock);
|
|
26613
|
+
excerptSlot = excerptBlock;
|
|
26614
|
+
blocks.push(blockMeta("lessonExcerpt:" + type, "LESSON", excerpt.excerpt, excerpt.verified, excerpt.issues));
|
|
26615
|
+
if (!excerpt.verified) issues.push(...excerpt.issues.map((i) => `lesson:${i}`));
|
|
26616
|
+
if (type === "QUIZ" || type === "WKS") {
|
|
26617
|
+
const am = extractAssessmentMap(lessonContent, 1200);
|
|
26618
|
+
if (am) {
|
|
26619
|
+
parts.push(`
|
|
26620
|
+
|
|
26621
|
+
[ASSESSMENT MAP (criteria anchor \u2014 assess exactly these)]:
|
|
26622
|
+
${am}`);
|
|
26623
|
+
blocks.push(blockMeta("assessmentMap:" + type, "LESSON", am, true));
|
|
26624
|
+
} else {
|
|
26625
|
+
issues.push(`assessment-map:unresolved:${type}`);
|
|
26626
|
+
}
|
|
26627
|
+
}
|
|
26628
|
+
if (symbolLedgerBlock) {
|
|
26629
|
+
parts.push(symbolLedgerBlock);
|
|
26630
|
+
blocks.push(blockMeta("symbolLedger", "LESSON", symbolLedgerBlock, true));
|
|
26631
|
+
}
|
|
26632
|
+
} else {
|
|
26633
|
+
const contractRows = extractActivityContractRows(lessonContent, type === "CODE" ? "CODE_LAB" : type, 1500);
|
|
26634
|
+
const tierBlock = type === "CODE" || type === "EXT" ? extractTieredScaffoldingBlock(lessonContent, 900) : "";
|
|
26635
|
+
const mini = [
|
|
26636
|
+
contractRows ? `### Activity Sequence rows assigned to ${type} (canonical \u2014 do not invent a different task):
|
|
26637
|
+
${contractRows}` : "",
|
|
26638
|
+
tierBlock ? `### Tiered task ladder (from LESSON Elaborate phase):
|
|
26639
|
+
${tierBlock}` : ""
|
|
26640
|
+
].filter(Boolean).join("\n\n");
|
|
26641
|
+
if (mini) {
|
|
26642
|
+
const miniBlock = `
|
|
26643
|
+
|
|
26644
|
+
[LESSON ACTIVITY CONTRACT (mini-slot)]:
|
|
26645
|
+
${mini}`;
|
|
26646
|
+
parts.push(miniBlock);
|
|
26647
|
+
miniSlot = miniBlock;
|
|
26648
|
+
blocks.push(blockMeta("activityContract:" + type, "LESSON", mini, true));
|
|
26649
|
+
} else {
|
|
26650
|
+
issues.push(`activity-contract:unresolved:${type}`);
|
|
26651
|
+
blocks.push(blockMeta("activityContract:" + type, "LESSON", "", false, ["no-matching-rows"]));
|
|
26652
|
+
}
|
|
26653
|
+
if (type === "CODE" && symbolLedgerBlock) {
|
|
26654
|
+
parts.push(symbolLedgerBlock);
|
|
26655
|
+
blocks.push(blockMeta("symbolLedger", "LESSON", symbolLedgerBlock, true));
|
|
26656
|
+
}
|
|
26657
|
+
}
|
|
26658
|
+
const context = parts.join("");
|
|
26659
|
+
return {
|
|
26660
|
+
context,
|
|
26661
|
+
blocks,
|
|
26662
|
+
verified: blocks.filter((b) => b.slot !== "commonContext").every((b) => b.verified),
|
|
26663
|
+
sectionAware: blocks.some((b) => b.slot.startsWith("lessonExcerpt") || b.slot.startsWith("kxExcerpt")),
|
|
26664
|
+
issues,
|
|
26665
|
+
tokenEstimate: Math.round(context.length / 4),
|
|
26666
|
+
// Judge ground truth = exactly what THIS type consumed (scoped or mini slot).
|
|
26667
|
+
canonicalExcerpt: (miniSlot ?? excerptSlot ?? lessonExcerpt.excerpt).trim()
|
|
26668
|
+
};
|
|
26669
|
+
}
|
|
26670
|
+
var ACTIVITY_ALIGNMENT_LOG_ONLY_UNTIL = /* @__PURE__ */ new Date("2026-09-23T00:00:00Z");
|
|
26671
|
+
function isActivityAlignmentLogOnly(now = /* @__PURE__ */ new Date()) {
|
|
26672
|
+
const env = (process.env.DRIFT_ALIGNMENT_LOG_ONLY ?? "").toLowerCase().trim();
|
|
26673
|
+
if (env === "false" || env === "0") return false;
|
|
26674
|
+
if (env === "true" || env === "1") return true;
|
|
26675
|
+
return now < ACTIVITY_ALIGNMENT_LOG_ONLY_UNTIL;
|
|
26676
|
+
}
|
|
26677
|
+
function evaluateActivityAlignment(canonicalExcerpt, generatedContent, now = /* @__PURE__ */ new Date()) {
|
|
26678
|
+
const mode = isActivityAlignmentLogOnly(now) ? "log_only" : "enforcing";
|
|
26679
|
+
if (!canonicalExcerpt || !canonicalExcerpt.trim()) {
|
|
26680
|
+
return { checked: false, passed: null, matchedTokens: [], missingTokens: [], mode };
|
|
26681
|
+
}
|
|
26682
|
+
const content = (generatedContent || "").toLowerCase();
|
|
26683
|
+
const stripped = canonicalExcerpt.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
26684
|
+
const latin = Array.from(new Set(stripped.match(/[a-z][a-z0-9_]{3,}/g) ?? []));
|
|
26685
|
+
const cjk = Array.from(new Set(canonicalExcerpt.match(/[\u4e00-\u9fff]{2,}/g) ?? []));
|
|
26686
|
+
const tokens = [...latin, ...cjk];
|
|
26687
|
+
if (tokens.length === 0) {
|
|
26688
|
+
return { checked: false, passed: null, matchedTokens: [], missingTokens: [], mode };
|
|
26689
|
+
}
|
|
26690
|
+
const matchedTokens = tokens.filter((t) => content.includes(t));
|
|
26691
|
+
const missingTokens = tokens.filter((t) => !content.includes(t));
|
|
26692
|
+
const passed = matchedTokens.length > 0;
|
|
26693
|
+
return { checked: true, passed, matchedTokens: matchedTokens.slice(0, 10), missingTokens: missingTokens.slice(0, 10), mode };
|
|
26694
|
+
}
|
|
26695
|
+
|
|
26090
26696
|
// src/services/lessonProductionService.ts
|
|
26091
26697
|
var __filename2 = typeof import.meta?.url === "string" && typeof fileURLToPath === "function" ? fileURLToPath(import.meta.url) : "";
|
|
26092
26698
|
var _resolvedDir = __filename2 ? path3.dirname(__filename2) : typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
@@ -26659,9 +27265,9 @@ ${renderHorizonPromptBlock(horizon)}`;
|
|
|
26659
27265
|
console.warn(`[produceSingleLesson] Notice: Curriculum Horizon extraction:`, hErr?.message || hErr);
|
|
26660
27266
|
}
|
|
26661
27267
|
let productSpecBlock = "";
|
|
26662
|
-
const buildGroundTruthBlock = () => {
|
|
27268
|
+
const buildGroundTruthBlock = (includeKx = true) => {
|
|
26663
27269
|
const parts = [];
|
|
26664
|
-
if (expositionContext) {
|
|
27270
|
+
if (includeKx && expositionContext) {
|
|
26665
27271
|
parts.push(`### KNOWLEDGE_EXPOSITION (CANONICAL KNOWLEDGE \u2014 teach from this, do not contradict)
|
|
26666
27272
|
${expositionContext}`);
|
|
26667
27273
|
}
|
|
@@ -26695,10 +27301,10 @@ ${sessionSliceContext}` : "";
|
|
|
26695
27301
|
const guardrailBlock = `
|
|
26696
27302
|
|
|
26697
27303
|
${platformGuardrail}`;
|
|
26698
|
-
const assembleCommonContext = (sg) => `${baseContextPrefix}
|
|
27304
|
+
const assembleCommonContext = (sg, includeKx = true) => `${baseContextPrefix}
|
|
26699
27305
|
|
|
26700
27306
|
[CONTENT STYLE GUIDE EXCERPT]:
|
|
26701
|
-
${sg}${standardsBlock}${glossaryBlock}${buildGroundTruthBlock()}${sessionSliceBlock}${horizonBlock}${guardrailBlock}`;
|
|
27307
|
+
${sg}${standardsBlock}${glossaryBlock}${buildGroundTruthBlock(includeKx)}${sessionSliceBlock}${horizonBlock}${guardrailBlock}`;
|
|
26702
27308
|
let commonContext = assembleCommonContext(effectiveStyleGuide);
|
|
26703
27309
|
const MAX_COMPOSITE_PROMPT_CHARS = 3e4;
|
|
26704
27310
|
const runnerOptions = options.customInference ? { customInference: options.customInference } : {};
|
|
@@ -27107,10 +27713,34 @@ ${currentContent}` }],
|
|
|
27107
27713
|
- Entry Source File: \`${symbolLedger.entryFileName || symbolLedger.primarySymbol}\`
|
|
27108
27714
|
- Key Identifiers to inherit verbatim: ${symbolLedger.keySymbols.map((s) => `\`${s}\``).join(", ")}
|
|
27109
27715
|
- INVARIANT: You MUST use these exact identifier names in all code examples, exercises, and test assertions. Do NOT invent new struct/class names!` : "";
|
|
27110
|
-
const
|
|
27111
|
-
|
|
27112
|
-
|
|
27113
|
-
|
|
27716
|
+
const routingMode = options.contextRoutingMode ?? "legacy";
|
|
27717
|
+
const kxFreeCommonContext = routingMode === "hybrid" ? assembleCommonContext(effectiveStyleGuide, false) : "";
|
|
27718
|
+
const satelliteContexts = {};
|
|
27719
|
+
const satelliteContextMeta = {};
|
|
27720
|
+
const satelliteContextFor = (artifactType) => {
|
|
27721
|
+
const key = artifactType.toUpperCase();
|
|
27722
|
+
if (!satelliteContexts[key]) {
|
|
27723
|
+
const built = buildSatelliteContext({
|
|
27724
|
+
artifactType: key,
|
|
27725
|
+
commonContext: routingMode === "hybrid" ? kxFreeCommonContext : commonContext,
|
|
27726
|
+
lessonContent,
|
|
27727
|
+
lessonExcerpt: lessonExcerptResult,
|
|
27728
|
+
expositionContent: expositionContext,
|
|
27729
|
+
slcMarkdown,
|
|
27730
|
+
symbolLedgerBlock,
|
|
27731
|
+
pedagogyLabel,
|
|
27732
|
+
mode: routingMode
|
|
27733
|
+
});
|
|
27734
|
+
satelliteContexts[key] = built.context;
|
|
27735
|
+
satelliteContextMeta[key] = built;
|
|
27736
|
+
onProgress?.(
|
|
27737
|
+
"@content",
|
|
27738
|
+
`[CONTEXT] ${key} satellite context: ${built.context.length} chars (${built.blocks.map((b) => `${b.slot}:${b.chars}`).join(", ")})`,
|
|
27739
|
+
{ type: "progress", promptChars: built.context.length, artifactType: key }
|
|
27740
|
+
);
|
|
27741
|
+
}
|
|
27742
|
+
return satelliteContexts[key];
|
|
27743
|
+
};
|
|
27114
27744
|
const judgeSat = (sat, content) => {
|
|
27115
27745
|
if (gateModeFor(gates, sat) !== "LLM_JUDGE") return Promise.resolve();
|
|
27116
27746
|
const det = validateArtifactDeterministic({ content, refPack });
|
|
@@ -27130,6 +27760,30 @@ ${lessonExcerpt}${symbolLedgerBlock}`;
|
|
|
27130
27760
|
}
|
|
27131
27761
|
});
|
|
27132
27762
|
}
|
|
27763
|
+
const slotMeta = satelliteContextMeta[sat.toUpperCase()];
|
|
27764
|
+
if (slotMeta) {
|
|
27765
|
+
const alignment = evaluateActivityAlignment(slotMeta.canonicalExcerpt, content);
|
|
27766
|
+
if (alignment.checked && alignment.passed === false) {
|
|
27767
|
+
const note = `activity-alignment drift vs ${sat} contract slot (matched: ${alignment.matchedTokens.join(", ") || "none"}); canonical tokens absent from output`;
|
|
27768
|
+
if (alignment.mode === "enforcing") {
|
|
27769
|
+
const critique = validatorRepairPrompt([{ code: "scope-drift", detail: note, evidence: alignment.missingTokens }]);
|
|
27770
|
+
onProgress?.("@reviewer", `\u26D4 ${sat} activity-alignment drift FAIL: ${note}`);
|
|
27771
|
+
return storage.updateArtifactState(projectId, lessonCode, sat, {
|
|
27772
|
+
state: "rejected",
|
|
27773
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27774
|
+
contentHash: computeContentHash(content),
|
|
27775
|
+
review: {
|
|
27776
|
+
decision: "NEEDS_REVISION",
|
|
27777
|
+
reviewedBy: "@heuristic-linter",
|
|
27778
|
+
reviewedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27779
|
+
score: 0,
|
|
27780
|
+
critique
|
|
27781
|
+
}
|
|
27782
|
+
});
|
|
27783
|
+
}
|
|
27784
|
+
onProgress?.("@reviewer", `\u{1F9ED} [log-only] ${sat} activity-alignment drift: ${note}`);
|
|
27785
|
+
}
|
|
27786
|
+
}
|
|
27133
27787
|
return judgeSatelliteArtifact({
|
|
27134
27788
|
storage,
|
|
27135
27789
|
projectId,
|
|
@@ -27142,7 +27796,7 @@ ${lessonExcerpt}${symbolLedgerBlock}`;
|
|
|
27142
27796
|
onProgress,
|
|
27143
27797
|
targetLang,
|
|
27144
27798
|
canonicalLessonContent: lessonContent,
|
|
27145
|
-
canonicalLessonExcerpt: lessonExcerpt
|
|
27799
|
+
canonicalLessonExcerpt: slotMeta?.canonicalExcerpt ?? lessonExcerpt
|
|
27146
27800
|
});
|
|
27147
27801
|
};
|
|
27148
27802
|
const actRelPath = `_content/${unitCode}/ACT_${lessonCode}.md`;
|
|
@@ -27191,7 +27845,7 @@ ${languageDirective}
|
|
|
27191
27845
|
${buildHeadingDirective("ACT", slcMarkdown, targetLang)}`;
|
|
27192
27846
|
const rawAct = await runCurriculumAIInference(
|
|
27193
27847
|
[{ role: "user", content: actPrompt }],
|
|
27194
|
-
|
|
27848
|
+
satelliteContextFor("ACT"),
|
|
27195
27849
|
runnerOptions,
|
|
27196
27850
|
(chunk, type) => {
|
|
27197
27851
|
options.onProgress?.("@activity", chunk, { type: type || "content", artifactType: "ACT" });
|
|
@@ -27261,7 +27915,7 @@ ${languageDirective}
|
|
|
27261
27915
|
${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
27262
27916
|
const rawQuiz = await runCurriculumAIInference(
|
|
27263
27917
|
[{ role: "user", content: quizPrompt }],
|
|
27264
|
-
|
|
27918
|
+
satelliteContextFor("QUIZ"),
|
|
27265
27919
|
runnerOptions,
|
|
27266
27920
|
(chunk, type) => {
|
|
27267
27921
|
options.onProgress?.("@assessor", chunk, { type: type || "content", artifactType: "QUIZ" });
|
|
@@ -27314,7 +27968,7 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
27314
27968
|
headingDirective: buildHeadingDirective("SLIDE", slcMarkdown, targetLang),
|
|
27315
27969
|
groundContext: slideGroundContext,
|
|
27316
27970
|
productSpecBlock: productSpecBlock || void 0,
|
|
27317
|
-
satelliteContext,
|
|
27971
|
+
satelliteContext: satelliteContextFor("SLIDE"),
|
|
27318
27972
|
runnerOptions,
|
|
27319
27973
|
onProgress: (agent, msg, meta) => {
|
|
27320
27974
|
options.onProgress?.(agent, msg, meta || { type: "content", artifactType: "SLIDE" });
|
|
@@ -27398,7 +28052,7 @@ footer: "Curriculum OS \u2022 ${lessonCode} (${pedagogyLabel})"
|
|
|
27398
28052
|
});
|
|
27399
28053
|
const rawSlide = await runCurriculumAIInference(
|
|
27400
28054
|
[{ role: "user", content: slidePrompt }],
|
|
27401
|
-
|
|
28055
|
+
satelliteContextFor("SLIDE"),
|
|
27402
28056
|
runnerOptions,
|
|
27403
28057
|
(chunk, type) => {
|
|
27404
28058
|
options.onProgress?.("@illustrator", chunk, { type: type || "content", artifactType: "SLIDE" });
|
|
@@ -27459,7 +28113,7 @@ ${languageDirective}
|
|
|
27459
28113
|
${buildHeadingDirective("GUIDE", slcMarkdown, targetLang)}`;
|
|
27460
28114
|
const rawGuide = await runCurriculumAIInference(
|
|
27461
28115
|
[{ role: "user", content: guidePrompt }],
|
|
27462
|
-
|
|
28116
|
+
satelliteContextFor("GUIDE"),
|
|
27463
28117
|
runnerOptions,
|
|
27464
28118
|
(chunk, type) => {
|
|
27465
28119
|
options.onProgress?.("@content", chunk, { type: type || "chunk", artifactType: "GUIDE" });
|
|
@@ -27511,7 +28165,7 @@ ${languageDirective}
|
|
|
27511
28165
|
${buildHeadingDirective("HANDOUT", slcMarkdown, targetLang)}`;
|
|
27512
28166
|
const rawHandout = await runCurriculumAIInference(
|
|
27513
28167
|
[{ role: "user", content: handoutPrompt }],
|
|
27514
|
-
|
|
28168
|
+
satelliteContextFor("HANDOUT"),
|
|
27515
28169
|
runnerOptions,
|
|
27516
28170
|
(chunk, type) => {
|
|
27517
28171
|
options.onProgress?.("@content", chunk, { type: type || "chunk", artifactType: "HANDOUT" });
|
|
@@ -27567,7 +28221,7 @@ ${languageDirective}
|
|
|
27567
28221
|
${buildHeadingDirective("WKS", slcMarkdown, targetLang)}`;
|
|
27568
28222
|
const rawWks = await runCurriculumAIInference(
|
|
27569
28223
|
[{ role: "user", content: wksPrompt }],
|
|
27570
|
-
|
|
28224
|
+
satelliteContextFor("WKS"),
|
|
27571
28225
|
runnerOptions,
|
|
27572
28226
|
(chunk, type) => {
|
|
27573
28227
|
options.onProgress?.("@content", chunk, { type: type || "chunk", artifactType: "WKS" });
|
|
@@ -27627,7 +28281,7 @@ ${languageDirective}
|
|
|
27627
28281
|
${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
|
|
27628
28282
|
const rawCode = await runCurriculumAIInference(
|
|
27629
28283
|
[{ role: "user", content: codePrompt }],
|
|
27630
|
-
|
|
28284
|
+
satelliteContextFor("CODE"),
|
|
27631
28285
|
runnerOptions,
|
|
27632
28286
|
(chunk, type) => {
|
|
27633
28287
|
options.onProgress?.("@activity", chunk, { type: type || "chunk", artifactType: "CODE" });
|
|
@@ -27714,7 +28368,7 @@ ${languageDirective}
|
|
|
27714
28368
|
${buildHeadingDirective("EXT", slcMarkdown, targetLang)}`;
|
|
27715
28369
|
const rawExt = await runCurriculumAIInference(
|
|
27716
28370
|
[{ role: "user", content: extPrompt }],
|
|
27717
|
-
|
|
28371
|
+
satelliteContextFor("EXT"),
|
|
27718
28372
|
runnerOptions,
|
|
27719
28373
|
(chunk, type) => {
|
|
27720
28374
|
options.onProgress?.("@activity", chunk, { type: type || "chunk", artifactType: "EXT" });
|
|
@@ -30814,6 +31468,75 @@ var DeterministicStructuralLinter = class {
|
|
|
30814
31468
|
strengths
|
|
30815
31469
|
};
|
|
30816
31470
|
}
|
|
31471
|
+
/**
|
|
31472
|
+
* P50: Validates macro-pedagogical invariants across a CurriculumPlan.
|
|
31473
|
+
* Checks:
|
|
31474
|
+
* 1. ZPD violations without self-healing recap (NO_ZPD_BRIDGE)
|
|
31475
|
+
* 2. Walking Skeleton existence (Unit 1 delivers working software)
|
|
31476
|
+
* 3. Inter-unit Mastery Gate presence
|
|
31477
|
+
*/
|
|
31478
|
+
static lintPlan(plan) {
|
|
31479
|
+
const findings = [];
|
|
31480
|
+
const strengths = [];
|
|
31481
|
+
let score = 100;
|
|
31482
|
+
for (const s of plan.sessions) {
|
|
31483
|
+
if (s.zpd_status?.verdict === "TOO_MANY_NEW") {
|
|
31484
|
+
score -= 10;
|
|
31485
|
+
findings.push({
|
|
31486
|
+
id: `PLAN_TOO_MANY_NEW_${s.id}`,
|
|
31487
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
31488
|
+
severity: "MINOR",
|
|
31489
|
+
title: `Cognitive Overload in Session ${s.id}`,
|
|
31490
|
+
description: s.zpd_status.issues.join("; ") || `Session introduces too many new concepts/keywords, exceeding ZPD capacity.`,
|
|
31491
|
+
remediationAdvice: `Distribute new concepts across multiple sessions or introduce via scaffolding.`,
|
|
31492
|
+
affectedElement: s.id
|
|
31493
|
+
});
|
|
31494
|
+
} else if (s.zpd_status?.verdict === "NO_ZPD_BRIDGE") {
|
|
31495
|
+
const hasRecap = s.prerequisite_decisions.some((d) => d.decision === "recap_in_lesson");
|
|
31496
|
+
if (!hasRecap) {
|
|
31497
|
+
score -= 15;
|
|
31498
|
+
findings.push({
|
|
31499
|
+
id: `PLAN_NO_ZPD_BRIDGE_${s.id}`,
|
|
31500
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
31501
|
+
severity: "MAJOR",
|
|
31502
|
+
title: `Unhealed ZPD Bridge in Session ${s.id}`,
|
|
31503
|
+
description: `Session introduces new concepts with 0 known concept bridges, and lacks recap scaffolding.`,
|
|
31504
|
+
remediationAdvice: `Add a recap_in_lesson prerequisite decision to anchor new learning in prior concepts.`,
|
|
31505
|
+
affectedElement: s.id
|
|
31506
|
+
});
|
|
31507
|
+
}
|
|
31508
|
+
}
|
|
31509
|
+
}
|
|
31510
|
+
if (!plan.walking_skeleton || plan.walking_skeleton.epitome_deliverables.length === 0) {
|
|
31511
|
+
score -= 10;
|
|
31512
|
+
findings.push({
|
|
31513
|
+
id: "PLAN_MISSING_WALKING_SKELETON",
|
|
31514
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
31515
|
+
severity: "MINOR",
|
|
31516
|
+
title: "Missing Walking Skeleton Definition",
|
|
31517
|
+
description: "Plan does not declare an Epitome (walking skeleton) in Unit 1.",
|
|
31518
|
+
remediationAdvice: "Ensure Unit 1 defines minimal end-to-end deliverables."
|
|
31519
|
+
});
|
|
31520
|
+
} else {
|
|
31521
|
+
strengths.push(`Unit ${plan.walking_skeleton.epitome_unit_id} establishes an end-to-end Walking Skeleton (Epitome).`);
|
|
31522
|
+
}
|
|
31523
|
+
if (plan.units.length > 1 && (!plan.mastery_gates || plan.mastery_gates.length === 0)) {
|
|
31524
|
+
score -= 10;
|
|
31525
|
+
findings.push({
|
|
31526
|
+
id: "PLAN_MISSING_MASTERY_GATES",
|
|
31527
|
+
dimension: "5E_INSTRUCTIONAL_FIDELITY",
|
|
31528
|
+
severity: "MINOR",
|
|
31529
|
+
title: "Missing Inter-Unit Mastery Gates",
|
|
31530
|
+
description: "Multi-unit course lacks formal transition gates between units.",
|
|
31531
|
+
remediationAdvice: "Define exit criteria and remediation sprints for each inter-unit boundary."
|
|
31532
|
+
});
|
|
31533
|
+
} else if (plan.mastery_gates && plan.mastery_gates.length > 0) {
|
|
31534
|
+
strengths.push(`${plan.mastery_gates.length} inter-unit Mastery Gates defined with remediation protocols.`);
|
|
31535
|
+
}
|
|
31536
|
+
score = Math.max(0, Math.min(100, score));
|
|
31537
|
+
const passed = score >= 80 && !findings.some((f) => f.severity === "CRITICAL");
|
|
31538
|
+
return { passed, score, findings, strengths };
|
|
31539
|
+
}
|
|
30817
31540
|
};
|
|
30818
31541
|
|
|
30819
31542
|
// src/evaluators/academicAuditor.ts
|
|
@@ -32448,6 +33171,6 @@ function renderMediaPlaceholder(entry) {
|
|
|
32448
33171
|
return `> \u{1F5BC}\uFE0F [\u1EA2nh \u0111ang ch\u1EDD: ${entry.name} \u2014 s\u1EBD \u0111\u01B0\u1EE3c t\u1EA1o sau khi duy\u1EC7t media]`;
|
|
32449
33172
|
}
|
|
32450
33173
|
|
|
32451
|
-
export { ACT_TEMPLATE, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, AcademicAuditor, ActiveLearningWorkflowSchema, ActivityLabSchema, ActivitySeqRowSchema, ActivityStepSchema, ArtifactContractRowSchema, AssessmentMapRowSchema, AssessmentObjectiveSchema, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BUNDLED_STANDARDS_PACK_IDS, BellRingerDaySchema, BellRingerSchema, BloomHintSchema, BloomLevelSchema, BloomTaxonomyEvaluator, BronzeTierSchema, CERConclusionSchema, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, CardTierEnum, ChoiceBoardRubricRowSchema, ChoiceBoardSchema, ChoiceRuleSchema, ChoiceSquareSchema, ClassificationSchema, CodeHardwareFeasibilityEvaluator, CodeLabSchema, CodeSnippetSchema, CompetencyRubricRowSchema, ComputationalThinkingSchema, ConstructiveAlignmentEvaluator, CoreConceptSchema, CourseObjectiveSchema, CoverageReportSchema, CrossArtifactDriftEvaluator, CurriculumArtifactSchema, CurriculumError, CurriculumPlanSchema, CurriculumQualityReportSchema, DEFAULT_ARTIFACT_STREAM_IDLE_MS, DEFAULT_ARTIFACT_STREAM_TOTAL_MS, DEFAULT_ENABLED_PROVIDERS, DEFAULT_GATE_SETTINGS, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdgeSchema, DepthAssignmentSchema, DepthLevelSchema, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuestionSchema, DiagnosticQuizSchema, EDPPhaseEnum, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, EntryLevelSchema, ExitTicketBugHuntSchema, ExitTicketMetacognitionSchema, ExitTicketQuickItemSchema, ExitTicketRecallPromptSchema, ExitTicketSchema, ExperimentalDesignSchema, ExpositionApprovalError, ExtensionChallengeSchema, ExtensionSchema, FileSystemCurriculumAdapter, FiveEFlowPhaseSchema, FiveEInstructionalEvaluator, FiveEPhaseEnum, FrameworkMappingSchema, FrameworkPackManifestSchema, FrameworkPackSchema, FrameworkStatementSchema, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, GeneratedSlideArraySchema, GeneratedSlideSchema, GlossaryQuickRefRowSchema, GlossarySchema, GlossaryTermSchema, GoldTierSchema, GradeBandSchema, GraphicOrganizerItemSchema, GraphicOrganizerSchema, HANDOUT_TEMPLATE, HandoutSchema, HandoutSectionSchema, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, InstructionSectionSchema, InstructionStepSchema, JudgeCriterionSchema, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, LLMJudgeEngine, LabTierTaskSchema, LearningObjectiveInputSchema, LearningObjectiveRowSchema, LessonFlowPhaseSchema, LessonPlan5ESchema, LessonPlanEDPSchema, LessonPlanSchema, LessonSectionSchema, LocalWorkspaceManager, MappingKindSchema, MarpSlideSchema, MediaError, MediaLedger, MentorCheatsheetSchema, MilestoneInputSchema, MisconceptionEvaluator, MisconceptionSchema, ModelPolicyResolver, NVIDIA_MODELS, NodeKindSchema, OrganizerTypeEnum, PROJECT_INSTRUCTION_TEMPLATE, PhaseInputSchema, PlanConstraintsSchema, PlannerInputSchema, PlanningGraphSchema, PlanningNodeSchema, PrerequisiteDecisionEntrySchema, PrerequisiteDecisionSchema, ProductGoalSchema, ProgressiveHintsSchema, ProjectGraphSchema, ProjectInstructionSchema, ProjectProfileSchema, QUIZ_TEMPLATE, QualityAuditVerdictSchema, QuizOptionSchema, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, RecordProvenanceSchema, ResourceMapRowSchema, ReviewGameExportRowSchema, ReviewGameQuestionSchema, ReviewGameSchema, RoadmapInputSchema, RotationStationSchema, RubricCriteriaSchema, RubricSchema, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_CANONICAL_METHODOLOGY, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STANDARD_REF_REGEX, STANDARD_SOT_FILES, STATION_ROTATION_TEMPLATE, ScaffoldDecisionEntrySchema, ScaffoldDecisionSchema, ScienceLabSchema, ScoringRubricRowSchema, SelfLabSchema, SelfPacedBundleSchema, SelfPacedChallengeSchema, SessionPlanSchema, SilverTierSchema, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeckSchema, StandardizedTermRowSchema, StandardsRegistryAdapter, StationRecordRowSchema, StationRotationSchema, StationTypeEnum, SupabaseCurriculumAdapter, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TaskCardSchema, TaskCardsSchema, TeacherGuideSchema, TeachingScriptPhaseSchema, TierLevelEnum, TierObjectiveSchema, TieredPracticeSchema, TranslationPolicySchema, TroubleshootingEntrySchema, TroubleshootingRowSchema, UnitPlanSchema, UserJourneySchema, WORKSHEET_TEMPLATE, WorksheetItemSchema, WorksheetItemTypeEnum, WorksheetPartSchema, WorksheetSchema, activityTools, analystTools, analyzeProjectCreationIntent, assertAcyclic, assessorTools, atomicWriteFileSync, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildExtensionPrompt, buildHandoutPrompt, buildHeadingDirective, buildHtmlDeckSlidePrompt, buildImagePrompt, buildJudgePrompt, buildLanguageDirective, buildLessonExcerpt, buildLessonMasterPrompt, buildMarpMarkdownSlidePrompt, buildProjectInstructionPrompt, buildSectionAwareExcerpt, buildSelfLabPrompt, buildSessionSliceContext, buildSlidesPrompt, buildStandardStackMarkdown, buildStandardsContext, buildStandardsContextBlock, buildTeacherGuidePrompt, buildWorksheetPrompt, closeTruncatedJson, computeContentHash, computePackingSpec, conductPreliminaryResearch, contentTools, convertRoadmapToFoundationSot, createAiInferenceError, createContextMissingError, createCurriculumStorage, createIdleAbortController, createStreamAbortController, createStreamAbortSignal, createStreamChunkExtractor, curateMediaLedger, designerTools, detectProjectPedagogy, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateStandardsCoverage, executeCurriculumCommand, executeSlideProductionWorkflow, exportAllProjectQuizzes, expositionCacheKey, extractCurriculumHorizon, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStandardRefs, extractStreamChunk, extractSymbolLedger, extractThoughtAndContent, findStandardStatement, formatQuizzesToCsv, fulfillMediaLedger, gateModeFor, generateActivityFlow, generateCodeLabFlow, generateDiagnosticQuizFlow, generateEducationalImage, generateExtensionFlow, generateHandoutFlow, generateLessonMasterFlow, generateMilestoneCurriculumBundle, generatePhase1SotArtifacts, generatePhase2SotArtifacts, generateProjectInstruction, generateProjectInstructionFlow, generateRoadmapCurriculum, generateSelfLabFlow, generateSelfPacedBundle, generateSingleArtifact, generateSlidesFlow, generateTeacherGuideFlow, generateWorksheetFlow, getAIModel, getArtifactMetadata, getDesignatedFallbackChain, getDesignatedFallbackConfig, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, illustratorTools, importRoadmapToProject, ingestProjectGraphIntoProject, initializeProjectInStorage, injectMediaIntoMarkdown, isExpositionFresh, isModelAllowed, isProviderEnabled, isTranslationDue, lintAndSanitizeArtifact, lintCurriculumFramework, lintFrameworkPack, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, packagerTools, parseAllSessions, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToSupabase, rankGenCandidates, renderFrameworkFromPlan, renderHorizonPromptBlock, renderMediaPlaceholder, researcherTools, resolveApiKey, resolveGateSettings, resolveStandardsPacks, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, reviewerTools, runCurriculumAIInference, safeParseJson, searchEducationalImages, searchEducationalVideos, selectStatementsForLesson, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, slugifyProjectName, streamCurriculumAIInference, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLLMWithFallback, streamLayerPrefillWithFallback, streamLessonMasterFlow, streamSelfLabFlow, stripLlmJsonWrappers, targetLanguageDisplayName, techSmeTools, topoSort, uploadAssetToBucket, validateArtifactDependencies, validateCurriculumPlan, validateFrameworkPack, validateHorizonCompliance, validateHybridDeckSlides, validateMarkdownTables, validateMermaidSyntax, withAutoRepair };
|
|
33174
|
+
export { ACT_TEMPLATE, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, AcademicAuditor, ActiveLearningWorkflowSchema, ActivityLabSchema, ActivitySeqRowSchema, ActivityStepSchema, ArtifactContractRowSchema, AssessmentMapRowSchema, AssessmentObjectiveSchema, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BUNDLED_STANDARDS_PACK_IDS, BellRingerDaySchema, BellRingerSchema, BloomHintSchema, BloomLevelSchema, BloomTaxonomyEvaluator, BronzeTierSchema, CERConclusionSchema, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, CardTierEnum, ChoiceBoardRubricRowSchema, ChoiceBoardSchema, ChoiceRuleSchema, ChoiceSquareSchema, ClassificationSchema, CodeHardwareFeasibilityEvaluator, CodeLabSchema, CodeSnippetSchema, CompetencyRubricRowSchema, ComputationalThinkingSchema, ConceptPrerequisiteEdgeSchema, ConceptSpiralEncounterSchema, ConstructiveAlignmentEvaluator, CoreConceptSchema, CourseObjectiveSchema, CoverageReportSchema, CrossArtifactDriftEvaluator, CurriculumArtifactSchema, CurriculumError, CurriculumPlanSchema, CurriculumQualityReportSchema, DEFAULT_ARTIFACT_STREAM_IDLE_MS, DEFAULT_ARTIFACT_STREAM_TOTAL_MS, DEFAULT_ENABLED_PROVIDERS, DEFAULT_GATE_SETTINGS, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdgeSchema, DepthAssignmentSchema, DepthLevelSchema, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuestionSchema, DiagnosticQuizSchema, EDPPhaseEnum, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, EntryLevelSchema, ExitTicketBugHuntSchema, ExitTicketMetacognitionSchema, ExitTicketQuickItemSchema, ExitTicketRecallPromptSchema, ExitTicketSchema, ExperimentalDesignSchema, ExpositionApprovalError, ExtensionChallengeSchema, ExtensionSchema, FileSystemCurriculumAdapter, FiveEFlowPhaseSchema, FiveEInstructionalEvaluator, FiveEPhaseEnum, FrameworkMappingSchema, FrameworkPackManifestSchema, FrameworkPackSchema, FrameworkStatementSchema, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, GeneratedSlideArraySchema, GeneratedSlideSchema, GlossaryQuickRefRowSchema, GlossarySchema, GlossaryTermSchema, GoldTierSchema, GradeBandSchema, GraphicOrganizerItemSchema, GraphicOrganizerSchema, HANDOUT_TEMPLATE, HandoutSchema, HandoutSectionSchema, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, InstructionSectionSchema, InstructionStepSchema, JudgeCriterionSchema, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, LLMJudgeEngine, LabTierTaskSchema, LearningObjectiveInputSchema, LearningObjectiveRowSchema, LessonFlowPhaseSchema, LessonPlan5ESchema, LessonPlanEDPSchema, LessonPlanSchema, LessonSectionSchema, LocalWorkspaceManager, MappingKindSchema, MarpSlideSchema, MasteryGateSchema, MediaError, MediaLedger, MentorCheatsheetSchema, MilestoneInputSchema, MisconceptionEvaluator, MisconceptionSchema, ModelPolicyResolver, NVIDIA_MODELS, NodeKindSchema, OrganizerTypeEnum, PROJECT_INSTRUCTION_TEMPLATE, PhaseInputSchema, PlanConstraintsSchema, PlannerInputSchema, PlanningGraphSchema, PlanningNodeSchema, PrerequisiteDecisionEntrySchema, PrerequisiteDecisionSchema, ProductGoalSchema, ProgressiveHintsSchema, ProjectGraphSchema, ProjectInstructionSchema, ProjectProfileSchema, QUIZ_TEMPLATE, QualityAuditVerdictSchema, QuizOptionSchema, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, RecordProvenanceSchema, ResourceMapRowSchema, ReviewGameExportRowSchema, ReviewGameQuestionSchema, ReviewGameSchema, RoadmapInputSchema, RotationStationSchema, RubricCriteriaSchema, RubricSchema, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_CANONICAL_METHODOLOGY, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STANDARD_REF_REGEX, STANDARD_SOT_FILES, STATION_ROTATION_TEMPLATE, ScaffoldDecisionEntrySchema, ScaffoldDecisionSchema, ScienceLabSchema, ScoringRubricRowSchema, SelfLabSchema, SelfPacedBundleSchema, SelfPacedChallengeSchema, SessionPlanSchema, SessionZpdStatusSchema, SilverTierSchema, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeckSchema, StandardizedTermRowSchema, StandardsRegistryAdapter, StationRecordRowSchema, StationRotationSchema, StationTypeEnum, SupabaseCurriculumAdapter, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TaskCardSchema, TaskCardsSchema, TeacherGuideSchema, TeachingScriptPhaseSchema, TierLevelEnum, TierObjectiveSchema, TieredPracticeSchema, TranslationPolicySchema, TroubleshootingEntrySchema, TroubleshootingRowSchema, UnitPlanSchema, UserJourneySchema, WORKSHEET_TEMPLATE, WalkingSkeletonSchema, WorksheetItemSchema, WorksheetItemTypeEnum, WorksheetPartSchema, WorksheetSchema, ZpdVerdictSchema, activityTools, analystTools, analyzeProjectCreationIntent, assertAcyclic, assessorTools, assignDepths, atomicWriteFileSync, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildConceptPrerequisites, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildExtensionPrompt, buildHandoutPrompt, buildHeadingDirective, buildHtmlDeckSlidePrompt, buildImagePrompt, buildJudgePrompt, buildLanguageDirective, buildLessonExcerpt, buildLessonMasterPrompt, buildMarpMarkdownSlidePrompt, buildMasteryGates, buildProjectInstructionPrompt, buildSatelliteContext, buildSectionAwareExcerpt, buildSelfLabPrompt, buildSessionSliceContext, buildSlidesPrompt, buildStandardStackMarkdown, buildStandardsContext, buildStandardsContextBlock, buildTeacherGuidePrompt, buildWalkingSkeleton, buildWorksheetPrompt, checkSessionZpd, closeTruncatedJson, computeConceptSpiralProgression, computeContentHash, computePackingSpec, conductPreliminaryResearch, contentTools, convertRoadmapToFoundationSot, createAiInferenceError, createContextMissingError, createCurriculumStorage, createIdleAbortController, createStreamAbortController, createStreamAbortSignal, createStreamChunkExtractor, curateMediaLedger, designerTools, detectProjectPedagogy, dropCyclicConceptEdges, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateActivityAlignment, evaluateStandardsCoverage, executeCurriculumCommand, executeSlideProductionWorkflow, exportAllProjectQuizzes, expositionCacheKey, extractActivityContractRows, extractAssessmentMap, extractCurriculumHorizon, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStandardRefs, extractStreamChunk, extractSymbolLedger, extractThoughtAndContent, extractTieredScaffoldingBlock, findStandardStatement, formatQuizzesToCsv, fulfillMediaLedger, gateModeFor, generateActivityFlow, generateCodeLabFlow, generateDiagnosticQuizFlow, generateEducationalImage, generateExtensionFlow, generateHandoutFlow, generateLessonMasterFlow, generateMilestoneCurriculumBundle, generatePhase1SotArtifacts, generatePhase2SotArtifacts, generateProjectInstruction, generateProjectInstructionFlow, generateRoadmapCurriculum, generateSelfLabFlow, generateSelfPacedBundle, generateSingleArtifact, generateSlidesFlow, generateTeacherGuideFlow, generateWorksheetFlow, getAIModel, getArtifactMetadata, getDesignatedFallbackChain, getDesignatedFallbackConfig, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, illustratorTools, importRoadmapToProject, ingestProjectGraphIntoProject, initializeProjectInStorage, injectMediaIntoMarkdown, isActivityAlignmentLogOnly, isExpositionFresh, isModelAllowed, isProviderEnabled, isTranslationDue, lintAndSanitizeArtifact, lintCurriculumFramework, lintFrameworkPack, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, packagerTools, parseAllSessions, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToSupabase, rankGenCandidates, renderFrameworkFromPlan, renderHorizonPromptBlock, renderMediaPlaceholder, researcherTools, resolveApiKey, resolveGateSettings, resolveStandardsPacks, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, reviewerTools, runCurriculumAIInference, safeParseJson, searchEducationalImages, searchEducationalVideos, selectStatementsForLesson, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, slugifyProjectName, streamCurriculumAIInference, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLLMWithFallback, streamLayerPrefillWithFallback, streamLessonMasterFlow, streamSelfLabFlow, stripLlmJsonWrappers, targetLanguageDisplayName, techSmeTools, topoSort, uploadAssetToBucket, validateArtifactDependencies, validateCurriculumPlan, validateFrameworkPack, validateHorizonCompliance, validateHybridDeckSlides, validateMarkdownTables, validateMermaidSyntax, withAutoRepair };
|
|
32452
33175
|
//# sourceMappingURL=index.mjs.map
|
|
32453
33176
|
//# sourceMappingURL=index.mjs.map
|