@thanh01.pmt/curriculum-kit 1.4.38 → 1.4.40
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 +194 -2
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +39 -2
- package/dist/ai/index.d.ts +39 -2
- package/dist/ai/index.mjs +191 -3
- package/dist/ai/index.mjs.map +1 -1
- package/dist/index.cjs +326 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -3
- package/dist/index.d.ts +59 -3
- package/dist/index.mjs +310 -3
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +43 -2
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +43 -2
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/schemas/index.cjs +47 -2
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +473 -44
- package/dist/schemas/index.d.ts +473 -44
- package/dist/schemas/index.mjs +44 -3
- package/dist/schemas/index.mjs.map +1 -1
- package/dist/workflow/index.cjs +43 -2
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.mjs +43 -2
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2841,11 +2841,51 @@ var ExtensionSchema = zod.z.object({
|
|
|
2841
2841
|
});
|
|
2842
2842
|
var QualityAuditVerdictSchema = zod.z.enum(["PASS", "NEEDS_REVISION", "FAIL"]);
|
|
2843
2843
|
var JudgeCriterionSchema = zod.z.object({
|
|
2844
|
-
name: zod.z.string().describe("Criterion name, e.g. Bloom Alignment, Code Validity, Word Count Gate, Language Adherence"),
|
|
2844
|
+
name: zod.z.string().describe("Criterion name, e.g. Bloom Alignment, Code Validity, Word Count Gate, Language Adherence, Step Incrementality"),
|
|
2845
2845
|
passed: zod.z.boolean(),
|
|
2846
2846
|
score: zod.z.number().min(0).max(100).describe("Score out of 100"),
|
|
2847
2847
|
feedback: zod.z.string().describe("Constructive feedback or citation of issues")
|
|
2848
2848
|
});
|
|
2849
|
+
var ActionableRepairActionSchema = zod.z.enum([
|
|
2850
|
+
"SPLIT_STEP",
|
|
2851
|
+
"REVISE_PROVISIONING",
|
|
2852
|
+
"INSERT_RECAP",
|
|
2853
|
+
"ADJUST_TIME_BUDGET",
|
|
2854
|
+
"SUBSTITUTE_FALLBACK",
|
|
2855
|
+
"REVISE_EXIT_EVIDENCE"
|
|
2856
|
+
]);
|
|
2857
|
+
var ActionableRepairPromptSchema = zod.z.object({
|
|
2858
|
+
action: ActionableRepairActionSchema,
|
|
2859
|
+
targetId: zod.z.string().describe("ID of the session, feature, or step requiring repair, e.g. U01_M01_L02 or F1-S3"),
|
|
2860
|
+
severity: zod.z.enum(["CRITICAL", "WARNING", "INFO"]).default("WARNING"),
|
|
2861
|
+
rationale: zod.z.string().describe("Pedagogical or technical rationale for why this repair is mandated"),
|
|
2862
|
+
instruction: zod.z.string().describe("Exact, actionable text instruction for the planner/generator in the next turn")
|
|
2863
|
+
});
|
|
2864
|
+
var ProjectGraphAuditSchema = zod.z.object({
|
|
2865
|
+
schema_version: zod.z.number().default(1),
|
|
2866
|
+
projectId: zod.z.string(),
|
|
2867
|
+
overallVerdict: QualityAuditVerdictSchema,
|
|
2868
|
+
totalScore: zod.z.number().min(0).max(100),
|
|
2869
|
+
toolchainFeasibility: JudgeCriterionSchema.describe("Installation friction, admin rights, IDE/compiler matrix"),
|
|
2870
|
+
provisioningStrategy: JudgeCriterionSchema.describe("Clear model for heavy runtimes: Pre-installed lab, Cloud instance, or Dedicated setup"),
|
|
2871
|
+
hardwareRuntimeEnvelope: JudgeCriterionSchema.describe("Memory/Flash limits, pinout conflicts, hardware platform alignment"),
|
|
2872
|
+
timeToHelloWorld: JudgeCriterionSchema.describe("Student time to achieve first working feedback loop (target <= 15 mins)"),
|
|
2873
|
+
actionableRepairs: zod.z.array(ActionableRepairPromptSchema).default([])
|
|
2874
|
+
});
|
|
2875
|
+
var MacroPedagogyPlanAuditSchema = zod.z.object({
|
|
2876
|
+
schema_version: zod.z.number().default(1),
|
|
2877
|
+
planHash: zod.z.string(),
|
|
2878
|
+
overallVerdict: QualityAuditVerdictSchema,
|
|
2879
|
+
totalScore: zod.z.number().min(0).max(100),
|
|
2880
|
+
autoApproved: zod.z.boolean().default(false).describe("True if totalScore >= 85 and overallVerdict is PASS"),
|
|
2881
|
+
stepIncrementality: JudgeCriterionSchema.describe("Single leap principle: <= 1 new syntax or 1 new algorithm per step"),
|
|
2882
|
+
zpdSaturation: JudgeCriterionSchema.describe("Vygotsky ZPD: <= 2 new concepts per session (K-12) / 3 (Adults), with prior anchor"),
|
|
2883
|
+
frictionAdjustedBudget: JudgeCriterionSchema.describe("Student time multiplier (2.5x): total content <= 85% session minutes"),
|
|
2884
|
+
epitomeViability: JudgeCriterionSchema.describe("Reigeluth Walking Skeleton: Unit 1 produces an end-to-end runnable MVP"),
|
|
2885
|
+
exitEvidenceSpecificity: JudgeCriterionSchema.describe("Tangible, measurable student deliverable for every session"),
|
|
2886
|
+
actionableRepairs: zod.z.array(ActionableRepairPromptSchema).default([]),
|
|
2887
|
+
summary: zod.z.string().describe("High-level executive evaluation summary")
|
|
2888
|
+
});
|
|
2849
2889
|
var CurriculumQualityReportSchema = zod.z.object({
|
|
2850
2890
|
targetArtifactType: zod.z.string().describe("Type of artifact audited, e.g. LESSON, ACT, CODE, WKS, SLIDE"),
|
|
2851
2891
|
lessonId: zod.z.string(),
|
|
@@ -2853,7 +2893,8 @@ var CurriculumQualityReportSchema = zod.z.object({
|
|
|
2853
2893
|
totalScore: zod.z.number().min(0).max(100),
|
|
2854
2894
|
languageAdherencePassed: zod.z.boolean().describe("True if content strictly matches the requested target language"),
|
|
2855
2895
|
criteria: zod.z.array(JudgeCriterionSchema).min(3),
|
|
2856
|
-
actionableRepairPrompts: zod.z.array(zod.z.string()).default([]).describe("Concrete instruction prompts to fix detected issues in the next repair turn")
|
|
2896
|
+
actionableRepairPrompts: zod.z.array(zod.z.string()).default([]).describe("Concrete instruction prompts to fix detected issues in the next repair turn"),
|
|
2897
|
+
structuredRepairs: zod.z.array(ActionableRepairPromptSchema).optional()
|
|
2857
2898
|
});
|
|
2858
2899
|
var ProjectProfileSchema = zod.z.object({
|
|
2859
2900
|
id: zod.z.string().optional(),
|
|
@@ -6737,6 +6778,111 @@ Please return a single JSON object matching these exact keys:
|
|
|
6737
6778
|
- "actionableRepairPrompts": string[]
|
|
6738
6779
|
`.trim();
|
|
6739
6780
|
}
|
|
6781
|
+
function buildCurriculumPlanJudgePrompt(input) {
|
|
6782
|
+
const { planJson, briefingContext, expectedLanguage = "Vietnamese", linterFindings = [] } = input;
|
|
6783
|
+
return `
|
|
6784
|
+
# System Methodology: Principal Curriculum SME & Macro-Pedagogical Quality Judge (@sme_judge)
|
|
6785
|
+
|
|
6786
|
+
You are the **Lead Curriculum Architect & Classroom Practicum SME**. Your role is to rigorously evaluate a candidate \`CURRICULUM_PLAN\` (Schema v3) against empirical pedagogical science, cognitive load capacity, and real classroom delivery constraints.
|
|
6787
|
+
|
|
6788
|
+
## COURSE BRIEFING & TARGET CONSTRAINTS
|
|
6789
|
+
${briefingContext}
|
|
6790
|
+
|
|
6791
|
+
${linterFindings.length > 0 ? `## DETERMINISTIC PRE-LINT FINDINGS (0-TOKEN LINTER)
|
|
6792
|
+
The deterministic structural linter detected the following issues in advance:
|
|
6793
|
+
${linterFindings.map((f) => `- [${f.severity}] ${f.id}: ${f.title} \u2014 ${f.description}`).join("\n")}
|
|
6794
|
+
Consider these deterministic findings when scoring and issuing actionable repair prescriptions.` : ""}
|
|
6795
|
+
|
|
6796
|
+
## CANDIDATE CURRICULUM PLAN JSON
|
|
6797
|
+
\`\`\`json
|
|
6798
|
+
${planJson}
|
|
6799
|
+
\`\`\`
|
|
6800
|
+
|
|
6801
|
+
## EVALUATION RUBRICS & 5 CRITICAL DIMENSIONS (TOTAL 100 POINTS)
|
|
6802
|
+
|
|
6803
|
+
1. **Step Incrementality & Single Leap Principle (20 pts):**
|
|
6804
|
+
- 20 pts: Every session introduces at most ONE new syntax or algorithmic concept. No massive cognitive leaps (e.g. going from basic variables directly to asynchronous networking).
|
|
6805
|
+
- 10 pts: Minor leap detected in 1 session that can be mitigated with starter code.
|
|
6806
|
+
- 0 pts: Severe cognitive gap (e.g. multiple compound paradigms combined in one session).
|
|
6807
|
+
|
|
6808
|
+
2. **Vygotsky ZPD Saturation & Cognitive Capacity (20 pts):**
|
|
6809
|
+
- 20 pts: New concept count <= 2 per session (K-12) / 3 (Adults), with explicit prior concept anchor or recap slot.
|
|
6810
|
+
- 10 pts: Session introduces 3 concepts without adequate bridge.
|
|
6811
|
+
- 0 pts: Severe overload (>3 new concepts in a single session) or unanchored concepts.
|
|
6812
|
+
|
|
6813
|
+
3. **Classroom Friction-Adjusted Time Budget (20 pts):**
|
|
6814
|
+
- 20 pts: Incorporates 2.5x student friction multiplier. Total content minutes <= 85% of session duration (15% overhead reserved). No step > 76 minutes.
|
|
6815
|
+
- 10 pts: Content is slightly packed, leaving < 10% buffer time.
|
|
6816
|
+
- 0 pts: Overpacked content that will cause students to run out of time in a standard classroom.
|
|
6817
|
+
|
|
6818
|
+
4. **Reigeluth Walking Skeleton & Milestone Agency (20 pts):**
|
|
6819
|
+
- 20 pts: Unit 1 culminates in an end-to-end runnable MVP (Epitome). Subsequent units provide modular elaborations.
|
|
6820
|
+
- 10 pts: Walking skeleton present but delayed to Unit 2.
|
|
6821
|
+
- 0 pts: Pure theoretical silo teaching where no working product appears until the end of the course.
|
|
6822
|
+
|
|
6823
|
+
5. **Exit Evidence Specificity (20 pts):**
|
|
6824
|
+
- 20 pts: Every session produces an explicit, tangible, user-visible deliverable (e.g. running UI screen, passing test suite, physical LED sequence).
|
|
6825
|
+
- 10 pts: Some sessions have generic deliverables ("completed practice exercise").
|
|
6826
|
+
- 0 pts: Vague or absent deliverables ("student understands topic").
|
|
6827
|
+
|
|
6828
|
+
## DECISION RULES
|
|
6829
|
+
- **PASS & AUTO-APPROVE:** Total Score >= 85 AND overallVerdict is "PASS" AND no CRITICAL actionable repairs.
|
|
6830
|
+
- **NEEDS_REVISION:** Total Score between 70 and 84, or fixable flaws. Prescribe concrete structured \`actionableRepairs\` (\`SPLIT_STEP\`, \`INSERT_RECAP\`, \`ADJUST_TIME_BUDGET\`, \`REVISE_EXIT_EVIDENCE\`).
|
|
6831
|
+
- **FAIL:** Total Score < 70, structural collapse, or unbridgeable pedagogical gaps.
|
|
6832
|
+
|
|
6833
|
+
## OUTPUT FORMAT
|
|
6834
|
+
Return a valid JSON object matching the MacroPedagogyPlanAuditSchema.
|
|
6835
|
+
`.trim();
|
|
6836
|
+
}
|
|
6837
|
+
function buildProjectGraphJudgePrompt(input) {
|
|
6838
|
+
const { bundleJson, briefingContext, linterFindings = [] } = input;
|
|
6839
|
+
return `
|
|
6840
|
+
# System Methodology: Lead Systems Engineer & Lab Infrastructure Auditor (@infra_judge)
|
|
6841
|
+
|
|
6842
|
+
You are the **Lead Lab Systems Engineer**. Your role is to rigorously evaluate a candidate \`PROJECT_GRAPH\` and its associated \`technology_scope\` against real-world lab environment feasibility, toolchain friction, and hardware constraints.
|
|
6843
|
+
|
|
6844
|
+
## COURSE BRIEFING & INFRASTRUCTURE CONSTRAINTS
|
|
6845
|
+
${briefingContext}
|
|
6846
|
+
|
|
6847
|
+
${linterFindings.length > 0 ? `## DETERMINISTIC PRE-LINT FINDINGS
|
|
6848
|
+
${linterFindings.map((f) => `- [${f.severity}] ${f.id}: ${f.title} \u2014 ${f.description}`).join("\n")}` : ""}
|
|
6849
|
+
|
|
6850
|
+
## CANDIDATE PROJECT GRAPH BUNDLE JSON
|
|
6851
|
+
\`\`\`json
|
|
6852
|
+
${bundleJson}
|
|
6853
|
+
\`\`\`
|
|
6854
|
+
|
|
6855
|
+
## EVALUATION RUBRICS & 4 DIMENSIONS (TOTAL 100 POINTS)
|
|
6856
|
+
|
|
6857
|
+
1. **Toolchain & Installation Feasibility (25 pts):**
|
|
6858
|
+
- 25 pts: Toolchain installs cleanly without complex admin rights, OS friction, or fragile build scripts.
|
|
6859
|
+
- 10 pts: Toolchain requires moderate admin setup, suitable for guided lab but risky for BYOD.
|
|
6860
|
+
- 0 pts: High-friction setup that frequently breaks in student environments.
|
|
6861
|
+
|
|
6862
|
+
2. **Environment Provisioning Strategy (25 pts):**
|
|
6863
|
+
- 25 pts: Heavy technologies (PostgreSQL, Docker, ROS2, etc.) declare an explicit, realistic provisioning model (\`PRE_INSTALLED_LAB\`, \`CLOUD_MANAGED\`, or \`DEDICATED_SETUP\`). Core course topics are NEVER downgraded; instead, proper infrastructure is specified.
|
|
6864
|
+
- 10 pts: Heavy tech used with ambiguous provisioning plan.
|
|
6865
|
+
- 0 pts: Heavy tech dumped on students with no provisioning strategy, causing setup collapse.
|
|
6866
|
+
|
|
6867
|
+
3. **Hardware & Runtime Envelope (25 pts):**
|
|
6868
|
+
- 25 pts: Code, libraries, and algorithms fit comfortably within target device RAM, Flash, and pinout budget (<= 75% envelope).
|
|
6869
|
+
- 10 pts: Memory or resource limits are tight.
|
|
6870
|
+
- 0 pts: Guaranteed hardware crash or pinout conflict.
|
|
6871
|
+
|
|
6872
|
+
4. **Time to Hello World (25 pts):**
|
|
6873
|
+
- 25 pts: First working runnable milestone achieved in <= 15 minutes of student effort.
|
|
6874
|
+
- 10 pts: First milestone takes 20-30 minutes.
|
|
6875
|
+
- 0 pts: Student spends the entire first session on environment configuration without seeing running code.
|
|
6876
|
+
|
|
6877
|
+
## DECISION RULES
|
|
6878
|
+
- **PASS:** Score >= 85 AND overallVerdict is "PASS".
|
|
6879
|
+
- **NEEDS_REVISION:** Score between 70 and 84. Prescribe structured actionable repairs.
|
|
6880
|
+
- **FAIL:** Score < 70 or critical environment blocker.
|
|
6881
|
+
|
|
6882
|
+
## OUTPUT FORMAT
|
|
6883
|
+
Return a valid JSON object matching ProjectGraphAuditSchema.
|
|
6884
|
+
`.trim();
|
|
6885
|
+
}
|
|
6740
6886
|
|
|
6741
6887
|
// src/ai/prompts/projectInstructionPrompt.ts
|
|
6742
6888
|
function buildProjectInstructionPrompt(input) {
|
|
@@ -7178,6 +7324,23 @@ async function generateExtensionFlow(input) {
|
|
|
7178
7324
|
|
|
7179
7325
|
// src/ai/flows/auditCurriculumQualityFlow.ts
|
|
7180
7326
|
init_provider_factory();
|
|
7327
|
+
|
|
7328
|
+
// src/constants/pedagogy.ts
|
|
7329
|
+
var STUDENT_FRICTION_MULTIPLIER = 2.5;
|
|
7330
|
+
var MAX_NEW_CONCEPTS_PER_SESSION_K12 = 2;
|
|
7331
|
+
var MAX_NEW_CONCEPTS_PER_SESSION_ADULT = 3;
|
|
7332
|
+
var DEFAULT_OVERHEAD_RATIO = 0.15;
|
|
7333
|
+
var MAX_IN_SESSION_SETUP_MINUTES = 15;
|
|
7334
|
+
var ENVIRONMENT_PROVISIONING_MODELS = [
|
|
7335
|
+
"PRE_INSTALLED_LAB",
|
|
7336
|
+
"CLOUD_MANAGED",
|
|
7337
|
+
"DEDICATED_SETUP"
|
|
7338
|
+
];
|
|
7339
|
+
var JUDGE_AUTO_APPROVE_THRESHOLD = 85;
|
|
7340
|
+
var JUDGE_ESCALATE_THRESHOLD = 70;
|
|
7341
|
+
var MAX_AUTONOMOUS_REPAIR_TURNS = 3;
|
|
7342
|
+
|
|
7343
|
+
// src/ai/flows/auditCurriculumQualityFlow.ts
|
|
7181
7344
|
async function auditCurriculumQualityFlow(input) {
|
|
7182
7345
|
const model = getAIModel(input.modelOptions);
|
|
7183
7346
|
const prompt = buildJudgePrompt({
|
|
@@ -7193,6 +7356,43 @@ async function auditCurriculumQualityFlow(input) {
|
|
|
7193
7356
|
schema: CurriculumQualityReportSchema,
|
|
7194
7357
|
prompt: `${prompt}
|
|
7195
7358
|
|
|
7359
|
+
Respond with a valid JSON object matching the schema.`
|
|
7360
|
+
});
|
|
7361
|
+
return object;
|
|
7362
|
+
}
|
|
7363
|
+
async function auditCurriculumPlanFlow(input) {
|
|
7364
|
+
const model = getAIModel(input.modelOptions);
|
|
7365
|
+
const prompt = buildCurriculumPlanJudgePrompt({
|
|
7366
|
+
planJson: input.planJson,
|
|
7367
|
+
briefingContext: input.briefingContext,
|
|
7368
|
+
expectedLanguage: input.expectedLanguage,
|
|
7369
|
+
linterFindings: input.linterFindings
|
|
7370
|
+
});
|
|
7371
|
+
const { object } = await ai.generateObject({
|
|
7372
|
+
model,
|
|
7373
|
+
schema: MacroPedagogyPlanAuditSchema,
|
|
7374
|
+
prompt: `${prompt}
|
|
7375
|
+
|
|
7376
|
+
Respond with a valid JSON object matching the schema.`
|
|
7377
|
+
});
|
|
7378
|
+
const autoApproved = object.totalScore >= JUDGE_AUTO_APPROVE_THRESHOLD && object.overallVerdict === "PASS";
|
|
7379
|
+
return {
|
|
7380
|
+
...object,
|
|
7381
|
+
autoApproved
|
|
7382
|
+
};
|
|
7383
|
+
}
|
|
7384
|
+
async function auditProjectGraphFlow(input) {
|
|
7385
|
+
const model = getAIModel(input.modelOptions);
|
|
7386
|
+
const prompt = buildProjectGraphJudgePrompt({
|
|
7387
|
+
bundleJson: input.bundleJson,
|
|
7388
|
+
briefingContext: input.briefingContext,
|
|
7389
|
+
linterFindings: input.linterFindings
|
|
7390
|
+
});
|
|
7391
|
+
const { object } = await ai.generateObject({
|
|
7392
|
+
model,
|
|
7393
|
+
schema: ProjectGraphAuditSchema,
|
|
7394
|
+
prompt: `${prompt}
|
|
7395
|
+
|
|
7196
7396
|
Respond with a valid JSON object matching the schema.`
|
|
7197
7397
|
});
|
|
7198
7398
|
return object;
|
|
@@ -31785,6 +31985,113 @@ var DeterministicStructuralLinter = class {
|
|
|
31785
31985
|
} else if (plan.mastery_gates && plan.mastery_gates.length > 0) {
|
|
31786
31986
|
strengths.push(`${plan.mastery_gates.length} inter-unit Mastery Gates defined with remediation protocols.`);
|
|
31787
31987
|
}
|
|
31988
|
+
const maxContentMinutes = Math.floor(
|
|
31989
|
+
(plan.constraints?.session_duration_minutes || 90) * (1 - DEFAULT_OVERHEAD_RATIO)
|
|
31990
|
+
);
|
|
31991
|
+
for (const s of plan.sessions) {
|
|
31992
|
+
const contentMins = (s.knowledge_minutes || 0) + (s.practice_minutes || 0);
|
|
31993
|
+
if (contentMins > maxContentMinutes + 2) {
|
|
31994
|
+
score -= 5;
|
|
31995
|
+
findings.push({
|
|
31996
|
+
id: `PLAN_OVERSIZED_SESSION_${s.id}`,
|
|
31997
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
31998
|
+
severity: "MINOR",
|
|
31999
|
+
title: `Content Minutes Exceeded in Session ${s.id}`,
|
|
32000
|
+
description: `Session planned for ${contentMins} content minutes exceeds the ${maxContentMinutes}m budget (15% overhead reserve).`,
|
|
32001
|
+
remediationAdvice: `Reduce knowledge or practice minutes to fit within ${maxContentMinutes} minutes.`,
|
|
32002
|
+
affectedElement: s.id
|
|
32003
|
+
});
|
|
32004
|
+
}
|
|
32005
|
+
if (!s.exit_evidence || s.exit_evidence.length === 0 || !s.exit_evidence[0] || s.exit_evidence[0].trim().length < 3) {
|
|
32006
|
+
score -= 5;
|
|
32007
|
+
findings.push({
|
|
32008
|
+
id: `PLAN_VAGUE_EXIT_EVIDENCE_${s.id}`,
|
|
32009
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
32010
|
+
severity: "MINOR",
|
|
32011
|
+
title: `Vague or Missing Exit Evidence in Session ${s.id}`,
|
|
32012
|
+
description: `Session lacks a concrete, measurable user-visible deliverable.`,
|
|
32013
|
+
remediationAdvice: `Specify an explicit exit evidence deliverable (e.g. running UI screen, passing test, or hardware actuation).`,
|
|
32014
|
+
affectedElement: s.id
|
|
32015
|
+
});
|
|
32016
|
+
}
|
|
32017
|
+
}
|
|
32018
|
+
score = Math.max(0, Math.min(100, score));
|
|
32019
|
+
const passed = score >= 80 && !findings.some((f) => f.severity === "CRITICAL");
|
|
32020
|
+
return { passed, score, findings, strengths };
|
|
32021
|
+
}
|
|
32022
|
+
/**
|
|
32023
|
+
* Validates structural and environment feasibility invariants for a Project Graph bundle.
|
|
32024
|
+
*/
|
|
32025
|
+
static lintProjectGraph(bundle, expectedSessions = 12) {
|
|
32026
|
+
const findings = [];
|
|
32027
|
+
const strengths = [];
|
|
32028
|
+
let score = 100;
|
|
32029
|
+
const graph = bundle?.project_graph;
|
|
32030
|
+
const scope = bundle?.technology_scope;
|
|
32031
|
+
if (!graph || !Array.isArray(graph.features) || graph.features.length === 0) {
|
|
32032
|
+
score -= 40;
|
|
32033
|
+
findings.push({
|
|
32034
|
+
id: "GRAPH_MISSING_FEATURES",
|
|
32035
|
+
dimension: "CROSS_ARTIFACT_ZERO_DRIFT",
|
|
32036
|
+
severity: "CRITICAL",
|
|
32037
|
+
title: "Missing Features in Project Graph",
|
|
32038
|
+
description: "Project graph has no features array or empty features.",
|
|
32039
|
+
remediationAdvice: "Declare at least 3 progressive features with concrete steps."
|
|
32040
|
+
});
|
|
32041
|
+
return { passed: false, score: Math.max(0, score), findings, strengths };
|
|
32042
|
+
}
|
|
32043
|
+
const allSteps = graph.features.flatMap((f) => f.steps || []);
|
|
32044
|
+
if (allSteps.length === 0) {
|
|
32045
|
+
score -= 30;
|
|
32046
|
+
findings.push({
|
|
32047
|
+
id: "GRAPH_EMPTY_STEPS",
|
|
32048
|
+
dimension: "CROSS_ARTIFACT_ZERO_DRIFT",
|
|
32049
|
+
severity: "CRITICAL",
|
|
32050
|
+
title: "Empty Steps in Project Graph",
|
|
32051
|
+
description: "Features contain no executable steps.",
|
|
32052
|
+
remediationAdvice: "Add 2 to 4 concrete steps per feature."
|
|
32053
|
+
});
|
|
32054
|
+
}
|
|
32055
|
+
for (const step of allSteps) {
|
|
32056
|
+
const est = step.effort?.estimated_minutes || 0;
|
|
32057
|
+
if (est > 76) {
|
|
32058
|
+
score -= 10;
|
|
32059
|
+
findings.push({
|
|
32060
|
+
id: `GRAPH_OVERSIZED_STEP_${step.id || "step"}`,
|
|
32061
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
32062
|
+
severity: "MAJOR",
|
|
32063
|
+
title: `Step ${step.id || step.name} Exceeds Content Budget`,
|
|
32064
|
+
description: `Step requires ${est} minutes, which exceeds the 76-minute single-session ceiling.`,
|
|
32065
|
+
remediationAdvice: `Split step into two sequential sub-steps to prevent artificial session fragmentation.`,
|
|
32066
|
+
affectedElement: step.id
|
|
32067
|
+
});
|
|
32068
|
+
}
|
|
32069
|
+
}
|
|
32070
|
+
const allTechStrings = [
|
|
32071
|
+
scope?.platform || "",
|
|
32072
|
+
...Array.isArray(scope?.libraries_and_apis) ? scope.libraries_and_apis : [],
|
|
32073
|
+
...Array.isArray(scope?.toolchain) ? scope.toolchain : [],
|
|
32074
|
+
JSON.stringify(graph.project?.tech_stack || {})
|
|
32075
|
+
].join(" ").toLowerCase();
|
|
32076
|
+
const heavyKeywords = ["postgres", "postgresql", "docker", "kubernetes", "ros2", "oracle", "sql server"];
|
|
32077
|
+
const hasHeavyTech = heavyKeywords.some((k) => allTechStrings.includes(k));
|
|
32078
|
+
if (hasHeavyTech) {
|
|
32079
|
+
const declaredStrategy = scope?.provisioning_strategy || scope?.provisioning_model || graph.project?.provisioning_strategy;
|
|
32080
|
+
const isValidStrategy = ENVIRONMENT_PROVISIONING_MODELS.includes(declaredStrategy);
|
|
32081
|
+
if (!isValidStrategy) {
|
|
32082
|
+
score -= 15;
|
|
32083
|
+
findings.push({
|
|
32084
|
+
id: "GRAPH_UNPROVISIONED_HEAVY_TECH",
|
|
32085
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
32086
|
+
severity: "MAJOR",
|
|
32087
|
+
title: "Heavy Technology Without Declared Lab Provisioning Strategy",
|
|
32088
|
+
description: `Course uses heavy/server technology without declaring a valid provisioning strategy (PRE_INSTALLED_LAB, CLOUD_MANAGED, or DEDICATED_SETUP).`,
|
|
32089
|
+
remediationAdvice: `Specify provisioning_strategy as PRE_INSTALLED_LAB, CLOUD_MANAGED, or DEDICATED_SETUP to ensure classroom feasibility.`
|
|
32090
|
+
});
|
|
32091
|
+
} else {
|
|
32092
|
+
strengths.push(`Heavy technology stack backed by explicit provisioning model: ${declaredStrategy}`);
|
|
32093
|
+
}
|
|
32094
|
+
}
|
|
31788
32095
|
score = Math.max(0, Math.min(100, score));
|
|
31789
32096
|
const passed = score >= 80 && !findings.some((f) => f.severity === "CRITICAL");
|
|
31790
32097
|
return { passed, score, findings, strengths };
|
|
@@ -33427,6 +33734,8 @@ exports.ACT_TEMPLATE = ACT_TEMPLATE;
|
|
|
33427
33734
|
exports.ARTIFACT_DEPENDENCY_ROUTING = ARTIFACT_DEPENDENCY_ROUTING;
|
|
33428
33735
|
exports.ARTIFACT_EXECUTION_ORDER = ARTIFACT_EXECUTION_ORDER;
|
|
33429
33736
|
exports.AcademicAuditor = AcademicAuditor;
|
|
33737
|
+
exports.ActionableRepairActionSchema = ActionableRepairActionSchema;
|
|
33738
|
+
exports.ActionableRepairPromptSchema = ActionableRepairPromptSchema;
|
|
33430
33739
|
exports.ActiveLearningWorkflowSchema = ActiveLearningWorkflowSchema;
|
|
33431
33740
|
exports.ActivityLabSchema = ActivityLabSchema;
|
|
33432
33741
|
exports.ActivitySeqRowSchema = ActivitySeqRowSchema;
|
|
@@ -33473,6 +33782,7 @@ exports.DEFAULT_ENABLED_PROVIDERS = DEFAULT_ENABLED_PROVIDERS;
|
|
|
33473
33782
|
exports.DEFAULT_GATE_SETTINGS = DEFAULT_GATE_SETTINGS;
|
|
33474
33783
|
exports.DEFAULT_KX_PRIORITIES = DEFAULT_KX_PRIORITIES;
|
|
33475
33784
|
exports.DEFAULT_LESSON_PRIORITIES = DEFAULT_LESSON_PRIORITIES;
|
|
33785
|
+
exports.DEFAULT_OVERHEAD_RATIO = DEFAULT_OVERHEAD_RATIO;
|
|
33476
33786
|
exports.DEFAULT_STREAM_IDLE_MS = DEFAULT_STREAM_IDLE_MS;
|
|
33477
33787
|
exports.DEFAULT_STREAM_TOTAL_MS = DEFAULT_STREAM_TOTAL_MS;
|
|
33478
33788
|
exports.DEFAULT_VIETNAMESE_SECTION_HEADINGS = DEFAULT_VIETNAMESE_SECTION_HEADINGS;
|
|
@@ -33484,6 +33794,7 @@ exports.DeterministicStructuralLinter = DeterministicStructuralLinter;
|
|
|
33484
33794
|
exports.DiagnosticQuestionSchema = DiagnosticQuestionSchema;
|
|
33485
33795
|
exports.DiagnosticQuizSchema = DiagnosticQuizSchema;
|
|
33486
33796
|
exports.EDPPhaseEnum = EDPPhaseEnum;
|
|
33797
|
+
exports.ENVIRONMENT_PROVISIONING_MODELS = ENVIRONMENT_PROVISIONING_MODELS;
|
|
33487
33798
|
exports.EXIT_TICKET_TEMPLATE = EXIT_TICKET_TEMPLATE;
|
|
33488
33799
|
exports.EXPOSITION_REL = EXPOSITION_REL;
|
|
33489
33800
|
exports.EXT_TEMPLATE = EXT_TEMPLATE;
|
|
@@ -33519,6 +33830,8 @@ exports.HandoutSchema = HandoutSchema;
|
|
|
33519
33830
|
exports.HandoutSectionSchema = HandoutSectionSchema;
|
|
33520
33831
|
exports.InstructionSectionSchema = InstructionSectionSchema;
|
|
33521
33832
|
exports.InstructionStepSchema = InstructionStepSchema;
|
|
33833
|
+
exports.JUDGE_AUTO_APPROVE_THRESHOLD = JUDGE_AUTO_APPROVE_THRESHOLD;
|
|
33834
|
+
exports.JUDGE_ESCALATE_THRESHOLD = JUDGE_ESCALATE_THRESHOLD;
|
|
33522
33835
|
exports.JudgeCriterionSchema = JudgeCriterionSchema;
|
|
33523
33836
|
exports.LAYER_IDLE_BUDGET_MS = LAYER_IDLE_BUDGET_MS;
|
|
33524
33837
|
exports.LAYER_TOTAL_BUDGET_MS = LAYER_TOTAL_BUDGET_MS;
|
|
@@ -33534,6 +33847,11 @@ exports.LessonPlanEDPSchema = LessonPlanEDPSchema;
|
|
|
33534
33847
|
exports.LessonPlanSchema = LessonPlanSchema;
|
|
33535
33848
|
exports.LessonSectionSchema = LessonSectionSchema;
|
|
33536
33849
|
exports.LocalWorkspaceManager = LocalWorkspaceManager;
|
|
33850
|
+
exports.MAX_AUTONOMOUS_REPAIR_TURNS = MAX_AUTONOMOUS_REPAIR_TURNS;
|
|
33851
|
+
exports.MAX_IN_SESSION_SETUP_MINUTES = MAX_IN_SESSION_SETUP_MINUTES;
|
|
33852
|
+
exports.MAX_NEW_CONCEPTS_PER_SESSION_ADULT = MAX_NEW_CONCEPTS_PER_SESSION_ADULT;
|
|
33853
|
+
exports.MAX_NEW_CONCEPTS_PER_SESSION_K12 = MAX_NEW_CONCEPTS_PER_SESSION_K12;
|
|
33854
|
+
exports.MacroPedagogyPlanAuditSchema = MacroPedagogyPlanAuditSchema;
|
|
33537
33855
|
exports.MappingKindSchema = MappingKindSchema;
|
|
33538
33856
|
exports.MarpSlideSchema = MarpSlideSchema;
|
|
33539
33857
|
exports.MasteryGateSchema = MasteryGateSchema;
|
|
@@ -33556,6 +33874,7 @@ exports.PrerequisiteDecisionEntrySchema = PrerequisiteDecisionEntrySchema;
|
|
|
33556
33874
|
exports.PrerequisiteDecisionSchema = PrerequisiteDecisionSchema;
|
|
33557
33875
|
exports.ProductGoalSchema = ProductGoalSchema;
|
|
33558
33876
|
exports.ProgressiveHintsSchema = ProgressiveHintsSchema;
|
|
33877
|
+
exports.ProjectGraphAuditSchema = ProjectGraphAuditSchema;
|
|
33559
33878
|
exports.ProjectGraphSchema = ProjectGraphSchema;
|
|
33560
33879
|
exports.ProjectInstructionSchema = ProjectInstructionSchema;
|
|
33561
33880
|
exports.ProjectProfileSchema = ProjectProfileSchema;
|
|
@@ -33582,6 +33901,7 @@ exports.SLIDE_TEMPLATE = SLIDE_TEMPLATE;
|
|
|
33582
33901
|
exports.STANDARD_REF_REGEX = STANDARD_REF_REGEX;
|
|
33583
33902
|
exports.STANDARD_SOT_FILES = STANDARD_SOT_FILES;
|
|
33584
33903
|
exports.STATION_ROTATION_TEMPLATE = STATION_ROTATION_TEMPLATE;
|
|
33904
|
+
exports.STUDENT_FRICTION_MULTIPLIER = STUDENT_FRICTION_MULTIPLIER;
|
|
33585
33905
|
exports.ScaffoldDecisionEntrySchema = ScaffoldDecisionEntrySchema;
|
|
33586
33906
|
exports.ScaffoldDecisionSchema = ScaffoldDecisionSchema;
|
|
33587
33907
|
exports.ScienceLabSchema = ScienceLabSchema;
|
|
@@ -33628,13 +33948,16 @@ exports.assertAcyclic = assertAcyclic;
|
|
|
33628
33948
|
exports.assessorTools = assessorTools;
|
|
33629
33949
|
exports.assignDepths = assignDepths;
|
|
33630
33950
|
exports.atomicWriteFileSync = atomicWriteFileSync;
|
|
33951
|
+
exports.auditCurriculumPlanFlow = auditCurriculumPlanFlow;
|
|
33631
33952
|
exports.auditCurriculumQualityFlow = auditCurriculumQualityFlow;
|
|
33953
|
+
exports.auditProjectGraphFlow = auditProjectGraphFlow;
|
|
33632
33954
|
exports.auditQualityReport = auditQualityReport;
|
|
33633
33955
|
exports.buildActivityPrompt = buildActivityPrompt;
|
|
33634
33956
|
exports.buildCodeLabPrompt = buildCodeLabPrompt;
|
|
33635
33957
|
exports.buildConceptPrerequisites = buildConceptPrerequisites;
|
|
33636
33958
|
exports.buildCurriculumContext = buildCurriculumContext;
|
|
33637
33959
|
exports.buildCurriculumPlan = buildCurriculumPlan;
|
|
33960
|
+
exports.buildCurriculumPlanJudgePrompt = buildCurriculumPlanJudgePrompt;
|
|
33638
33961
|
exports.buildDeliveryPackages = buildDeliveryPackages;
|
|
33639
33962
|
exports.buildDiagnosticQuizPrompt = buildDiagnosticQuizPrompt;
|
|
33640
33963
|
exports.buildDomainLexiconGuardrail = buildDomainLexiconGuardrail;
|
|
@@ -33652,6 +33975,7 @@ exports.buildLessonExcerpt = buildLessonExcerpt;
|
|
|
33652
33975
|
exports.buildLessonMasterPrompt = buildLessonMasterPrompt;
|
|
33653
33976
|
exports.buildMarpMarkdownSlidePrompt = buildMarpMarkdownSlidePrompt;
|
|
33654
33977
|
exports.buildMasteryGates = buildMasteryGates;
|
|
33978
|
+
exports.buildProjectGraphJudgePrompt = buildProjectGraphJudgePrompt;
|
|
33655
33979
|
exports.buildProjectInstructionPrompt = buildProjectInstructionPrompt;
|
|
33656
33980
|
exports.buildSatelliteContext = buildSatelliteContext;
|
|
33657
33981
|
exports.buildSectionAwareExcerpt = buildSectionAwareExcerpt;
|