@plasius/learning 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/chunk-UNPCTBNK.js +43 -0
- package/dist/chunk-UNPCTBNK.js.map +1 -0
- package/dist/course-suggestions-CBs5swU6.d.ts +17 -0
- package/dist/course-suggestions-mK2MPB7e.d.cts +17 -0
- package/dist/courses/adventure-mission-planner.cjs +436 -0
- package/dist/courses/adventure-mission-planner.cjs.map +1 -0
- package/dist/courses/adventure-mission-planner.d.cts +6 -0
- package/dist/courses/adventure-mission-planner.d.ts +6 -0
- package/dist/courses/adventure-mission-planner.js +210 -0
- package/dist/courses/adventure-mission-planner.js.map +1 -0
- package/dist/courses/creature-care-dashboard.cjs +425 -0
- package/dist/courses/creature-care-dashboard.cjs.map +1 -0
- package/dist/courses/creature-care-dashboard.d.cts +6 -0
- package/dist/courses/creature-care-dashboard.d.ts +6 -0
- package/dist/courses/creature-care-dashboard.js +199 -0
- package/dist/courses/creature-care-dashboard.js.map +1 -0
- package/dist/courses/robot-mission-control.cjs +428 -0
- package/dist/courses/robot-mission-control.cjs.map +1 -0
- package/dist/courses/robot-mission-control.d.cts +6 -0
- package/dist/courses/robot-mission-control.d.ts +6 -0
- package/dist/courses/robot-mission-control.js +202 -0
- package/dist/courses/robot-mission-control.js.map +1 -0
- package/dist/courses/vibe-bug-detective.cjs +416 -0
- package/dist/courses/vibe-bug-detective.cjs.map +1 -0
- package/dist/courses/vibe-bug-detective.d.cts +8 -0
- package/dist/courses/vibe-bug-detective.d.ts +8 -0
- package/dist/courses/vibe-bug-detective.js +221 -0
- package/dist/courses/vibe-bug-detective.js.map +1 -0
- package/dist/courses/vibe-game-remix-lab.cjs +424 -0
- package/dist/courses/vibe-game-remix-lab.cjs.map +1 -0
- package/dist/courses/vibe-game-remix-lab.d.cts +8 -0
- package/dist/courses/vibe-game-remix-lab.d.ts +8 -0
- package/dist/courses/vibe-game-remix-lab.js +229 -0
- package/dist/courses/vibe-game-remix-lab.js.map +1 -0
- package/dist/courses/vibe-idea-studio.cjs +386 -0
- package/dist/courses/vibe-idea-studio.cjs.map +1 -0
- package/dist/courses/vibe-idea-studio.d.cts +8 -0
- package/dist/courses/vibe-idea-studio.d.ts +8 -0
- package/dist/courses/vibe-idea-studio.js +191 -0
- package/dist/courses/vibe-idea-studio.js.map +1 -0
- package/dist/index.cjs +41 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -1
- package/package.json +32 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/assessment.ts","../src/catalog.ts","../src/course-progress.ts","../src/contextual-help.ts","../src/publishing.ts","../src/validation.ts"],"sourcesContent":["import type {\n AssessmentCheckResultV1,\n AssessmentResultV1,\n AssessmentRubricV1,\n ScoreBandV1,\n} from \"./contracts.js\";\n\nfunction scoreBand(score: number): ScoreBandV1 {\n if (score >= 95) return \"mastered\";\n if (score >= 80) return \"mission-complete\";\n if (score >= 60) return \"nearly-there\";\n return \"keep-exploring\";\n}\n\n/**\n * Calculate a score solely from rubric criteria and objective check results.\n * Missing criteria fail closed; unknown and duplicate result IDs are rejected.\n */\nexport function calculateAssessment(\n rubric: AssessmentRubricV1,\n results: AssessmentCheckResultV1[],\n): AssessmentResultV1 {\n const knownIds = new Set(rubric.criteria.map((criterion) => criterion.id));\n const resultById = new Map<string, AssessmentCheckResultV1>();\n\n for (const result of results) {\n if (!knownIds.has(result.criterionId)) {\n throw new Error(`Unknown assessment criterion: ${result.criterionId}`);\n }\n if (resultById.has(result.criterionId)) {\n throw new Error(`Duplicate assessment result: ${result.criterionId}`);\n }\n resultById.set(result.criterionId, result);\n }\n\n let score = 0;\n const passedCriterionIds: string[] = [];\n const failedCriterionIds: string[] = [];\n const failedMandatoryCriterionIds: string[] = [];\n\n for (const criterion of rubric.criteria) {\n const passed = resultById.get(criterion.id)?.passed === true;\n if (passed) {\n score += criterion.points;\n passedCriterionIds.push(criterion.id);\n continue;\n }\n\n failedCriterionIds.push(criterion.id);\n if (criterion.mandatory) failedMandatoryCriterionIds.push(criterion.id);\n }\n\n return {\n score,\n band: scoreBand(score),\n completed:\n score >= rubric.completionScore && failedMandatoryCriterionIds.length === 0,\n passedCriterionIds,\n failedCriterionIds,\n failedMandatoryCriterionIds,\n };\n}\n","import type {\n AssessmentRubricV1,\n CourseMaterialsManifestV1,\n HardwareItemV1,\n HardwareRequirementManifestV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n MissionV1,\n ModuleAgentDefinitionV1,\n ModuleCategoryV1,\n} from \"./contracts.js\";\n\nconst SOFTWARE_HARDWARE: HardwareRequirementManifestV1 = {\n requirementsVersion: \"1.0.0\",\n mode: \"none\",\n hardwareIncluded: false,\n simulatorAvailable: true,\n verificationStatus: \"not-applicable\",\n publicSaleBlocked: false,\n preparationMinutes: 0,\n items: [],\n warnings: [\"No specialist physical equipment is required.\"],\n supportedPlatforms: [\"Current Chromium, Firefox or Safari browser\"],\n};\n\nconst CORE_ROBOT_ITEMS: HardwareItemV1[] = [\n {\n id: \"pico-2-w\",\n label: \"Raspberry Pi Pico 2 W\",\n quantity: 1,\n requirement: \"required\",\n exactSpecification: \"Raspberry Pi Pico 2 W with soldered headers\",\n adultOnly: false,\n stage: \"core\",\n },\n {\n id: \"breadboard\",\n label: \"Solderless breadboard\",\n quantity: 1,\n requirement: \"required\",\n exactSpecification: \"400-point or larger solderless breadboard\",\n adultOnly: false,\n stage: \"core\",\n },\n {\n id: \"usb-data-cable\",\n label: \"USB data cable\",\n quantity: 1,\n requirement: \"required\",\n exactSpecification: \"Data-capable USB cable compatible with the Pico 2 W\",\n adultOnly: false,\n stage: \"core\",\n },\n {\n id: \"jumper-wires\",\n label: \"Jumper wires\",\n quantity: 12,\n requirement: \"required\",\n exactSpecification: \"Insulated male-to-male breadboard jumper wires\",\n adultOnly: false,\n stage: \"core\",\n },\n];\n\nconst ROBOT_WARNING =\n \"Physical publication is blocked until every listed actuator, driver, sensor and power configuration passes an adult bench test.\";\n\nfunction physicalHardware(\n requirementsVersion: string,\n preparationMinutes: number,\n items: HardwareItemV1[],\n platforms: string[],\n): HardwareRequirementManifestV1 {\n return {\n requirementsVersion,\n mode: \"physical-first\",\n hardwareIncluded: false,\n simulatorAvailable: true,\n verificationStatus: \"pending-bench-test\",\n publicSaleBlocked: true,\n preparationMinutes,\n items: [...CORE_ROBOT_ITEMS, ...items],\n warnings: [ROBOT_WARNING, \"An adult must disconnect actuator power before changing wiring.\"],\n supportedPlatforms: platforms,\n };\n}\n\nfunction materials(slug: string, robot = false): CourseMaterialsManifestV1 {\n return {\n version: \"1.0.0\",\n learner: [\n { id: `${slug}-child-guide`, kind: \"child-guide\", audience: \"learner\" },\n { id: `${slug}-mission-cards`, kind: \"mission-cards\", audience: \"learner\" },\n { id: `${slug}-starter`, kind: \"starter-project\", audience: \"learner\" },\n { id: `${slug}-assets`, kind: \"asset-pack\", audience: \"learner\" },\n { id: `${slug}-printable`, kind: \"printable\", audience: \"learner\" },\n ],\n facilitator: [\n { id: `${slug}-facilitator`, kind: \"facilitator-guide\", audience: \"facilitator\" },\n { id: `${slug}-answers`, kind: \"answer-key\", audience: \"facilitator\" },\n { id: `${slug}-tests`, kind: \"protected-tests\", audience: \"facilitator\" },\n ...(robot\n ? [\n {\n id: `${slug}-hardware`,\n kind: \"hardware-guide\" as const,\n audience: \"facilitator\" as const,\n },\n ]\n : []),\n ],\n };\n}\n\nfunction agents(slug: string): ModuleAgentDefinitionV1[] {\n return [\n {\n id: `${slug}-assessor`,\n role: \"assessor\",\n evidenceBound: true,\n maySuggestSingleFix: false,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n {\n id: `${slug}-debugger`,\n role: \"debugger\",\n evidenceBound: true,\n maySuggestSingleFix: false,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n {\n id: `${slug}-fix-guide`,\n role: \"fix-guide\",\n evidenceBound: true,\n maySuggestSingleFix: true,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n {\n id: `${slug}-concept-explainer`,\n role: \"concept-explainer\",\n evidenceBound: true,\n maySuggestSingleFix: false,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n ];\n}\n\nfunction rubric(slug: string): AssessmentRubricV1 {\n return {\n version: \"1.0.0\",\n completionScore: 80,\n criteria: [\n {\n id: `${slug}-build`,\n label: \"The project is structurally valid and starts successfully.\",\n dimension: \"structure\",\n points: 20,\n mandatory: true,\n visibility: \"visible\",\n },\n {\n id: `${slug}-goal-one`,\n label: \"The first published project behaviour works.\",\n dimension: \"behaviour\",\n points: 20,\n mandatory: true,\n visibility: \"visible\",\n },\n {\n id: `${slug}-goal-two`,\n label: \"The second published project behaviour works.\",\n dimension: \"behaviour\",\n points: 20,\n mandatory: true,\n visibility: \"visible\",\n },\n {\n id: `${slug}-goal-three`,\n label: \"The complete project challenge works.\",\n dimension: \"behaviour\",\n points: 10,\n mandatory: false,\n visibility: \"visible\",\n },\n {\n id: `${slug}-edge-one`,\n label: \"The project handles its first protected edge case.\",\n dimension: \"resilience\",\n points: 10,\n mandatory: false,\n visibility: \"protected\",\n },\n {\n id: `${slug}-edge-two`,\n label: \"The project handles its second protected edge case.\",\n dimension: \"resilience\",\n points: 10,\n mandatory: false,\n visibility: \"protected\",\n },\n {\n id: `${slug}-safety`,\n label: \"The project obeys its mandatory safety and privacy boundary.\",\n dimension: \"safety\",\n points: 10,\n mandatory: true,\n visibility: \"visible\",\n },\n ],\n };\n}\n\nfunction mission(\n slug: string,\n index: number,\n title: string,\n concepts: string[],\n statement: string,\n sideAdventure: string,\n): MissionV1 {\n return {\n id: `${slug}-mission-${index}`,\n title,\n estimatedMinutes: index === 4 ? 25 : 20,\n concepts,\n goals: [\n {\n id: `${slug}-goal-${index}`,\n statement,\n evidence: \"assessment\",\n },\n ],\n sideAdventure,\n };\n}\n\ninterface ModuleInput {\n slug: string;\n title: string;\n category: ModuleCategoryV1;\n summary: string;\n tools: string[];\n concepts: string[];\n tokenSubunits: string;\n hosting?: boolean;\n hardware?: HardwareRequirementManifestV1;\n missionTitles: [string, string, string, string];\n}\n\nfunction module(input: ModuleInput): LearningModuleVersionV1 {\n const isRobot = input.category === \"robot\";\n return {\n id: `junior-coder.${input.slug}`,\n slug: input.slug,\n version: \"1.0.0\",\n contentRevision: \"2026-07-21.1\",\n title: input.title,\n category: input.category,\n summary: input.summary,\n estimatedMinutes: 90,\n tools: input.tools,\n concepts: input.concepts,\n selfContained: true,\n prerequisiteModuleIds: [],\n pricing: {\n state: \"pilot-grant-only\",\n tokenSubunits: input.tokenSubunits,\n includesMaterials: true,\n includesAssessmentRetries: true,\n includesAgents: true,\n includesHostingAllowance: input.hosting ?? false,\n },\n materials: materials(input.slug, isRobot),\n hardware: input.hardware ?? SOFTWARE_HARDWARE,\n missions: input.missionTitles.map((title, index) =>\n mission(\n input.slug,\n index + 1,\n title,\n input.concepts.slice(0, 3),\n `Complete ${title.toLocaleLowerCase(\"en-GB\")} and explain the observed result.`,\n `Invent one safe remix for ${title.toLocaleLowerCase(\"en-GB\")}.`,\n ),\n ),\n assessment: rubric(input.slug),\n agents: agents(input.slug),\n badges: [\n {\n id: `${input.slug}-mission-complete`,\n title: `${input.title} Champion`,\n evidence: \"module-score\",\n tradeable: false,\n tokenConvertible: false,\n },\n ...(isRobot\n ? [\n {\n id: `${input.slug}-physical-builder`,\n title: `${input.title} Physical Builder`,\n evidence: \"adult-physical-signoff\" as const,\n tradeable: false as const,\n tokenConvertible: false as const,\n },\n ]\n : []),\n ],\n };\n}\n\nconst modules: LearningModuleVersionV1[] = [\n module({\n slug: \"robot-maze-dash\",\n title: \"Robot Maze Dash\",\n category: \"game\",\n summary: \"Guide rescue robots through original mazes with visual programs and side-by-side text code.\",\n tools: [\"Visual blocks\", \"JavaScript view\", \"Python view\", \"C++ view\"],\n concepts: [\"sequence\", \"variables\", \"loops\", \"conditions\", \"functions\"],\n tokenSubunits: \"8000\",\n missionTitles: [\"Meet Your Robot\", \"Repeat the Rescue\", \"Choose the Safe Path\", \"Lost Robot Challenge\"],\n }),\n module({\n slug: \"road-hopper-rally\",\n title: \"Road Hopper Rally\",\n category: \"game\",\n summary: \"Build an original road-crossing game with changing lanes and rescue targets.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"events\", \"coordinates\", \"animation\", \"collision\", \"scoring\"],\n tokenSubunits: \"10000\",\n missionTitles: [\"Draw the Rescue Road\", \"Move the Hopper\", \"Add Moving Traffic\", \"Rally Challenge\"],\n }),\n module({\n slug: \"skywing-sprint\",\n title: \"Skywing Sprint\",\n category: \"game\",\n summary: \"Fly a rescue craft through procedurally changing sky gates.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"velocity\", \"gravity\", \"timing\", \"randomness\", \"obstacles\"],\n tokenSubunits: \"10000\",\n missionTitles: [\"Give Skywing Lift\", \"Build a Gate\", \"Score a Safe Flight\", \"Sky Sprint Challenge\"],\n }),\n module({\n slug: \"paddle-pulse\",\n title: \"Paddle Pulse\",\n category: \"game\",\n summary: \"Create a paddle-and-energy-ball arcade game with levels and original power-ups.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"angles\", \"collision response\", \"levels\", \"power-ups\", \"state\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Move the Pulse Paddle\", \"Bounce the Energy Ball\", \"Build a Target Wall\", \"Power-Up Challenge\"],\n }),\n module({\n slug: \"meteor-shield\",\n title: \"Meteor Shield\",\n category: \"game\",\n summary: \"Protect rescue bases with careful targeting and limited shield energy.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"targeting\", \"projectiles\", \"timers\", \"waves\", \"resources\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Mark the Rescue Bases\", \"Launch a Shield\", \"Create Meteor Waves\", \"Last Base Challenge\"],\n }),\n module({\n slug: \"rescue-crew-commander\",\n title: \"Rescue Crew Commander\",\n category: \"game\",\n summary: \"Assign safe jobs, routes and priorities to a team of original helper creatures.\",\n tools: [\"Visual blocks\", \"JavaScript\"],\n concepts: [\"state machines\", \"routes\", \"priorities\", \"group behaviour\", \"debugging\"],\n tokenSubunits: \"14000\",\n missionTitles: [\"Meet the Rescue Crew\", \"Give a Crew Job\", \"Choose a Safe Route\", \"Commander Challenge\"],\n }),\n module({\n slug: \"pixel-trail-challenge\",\n title: \"Pixel Trail Challenge\",\n category: \"game\",\n summary: \"Use Python lists and grid movement to grow a safe energy trail.\",\n tools: [\"Python\", \"Pyodide\", \"Educational drawing API\"],\n concepts: [\"lists\", \"grid movement\", \"spawning\", \"collision\", \"score\"],\n tokenSubunits: \"10000\",\n missionTitles: [\"Move the Pixel\", \"Grow the Trail\", \"Place Energy Orbs\", \"Trail Challenge\"],\n }),\n module({\n slug: \"star-defender-squadron\",\n title: \"Star Defender Squadron\",\n category: \"game\",\n summary: \"Build a multi-level space-rescue finale with original entities and enemy patterns.\",\n tools: [\"Python\", \"JavaScript\", \"Educational drawing API\"],\n concepts: [\"entities\", \"projectiles\", \"patterns\", \"health\", \"levels\"],\n tokenSubunits: \"16000\",\n missionTitles: [\"Launch the Squadron\", \"Build a Rescue Wave\", \"Add Shields and Health\", \"Star Defender Finale\"],\n }),\n module({\n slug: \"beacon-bot\",\n title: \"Beacon Bot\",\n category: \"robot\",\n summary: \"Program visible and infrared rescue signals with C++ and a Pico 2 W.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"digital output\", \"timing\", \"functions\", \"signals\", \"sensor input\"],\n tokenSubunits: \"8000\",\n hardware: physicalHardware(\"1.0.0\", 30, [\n { id: \"led-pack\", label: \"Visible LEDs\", quantity: 3, requirement: \"required\", exactSpecification: \"5 mm low-current red, amber and green LEDs\", adultOnly: false, stage: \"core\" },\n { id: \"led-resistors\", label: \"LED current-limiting resistors\", quantity: 3, requirement: \"required\", exactSpecification: \"330 ohm, 0.25 W resistors\", adultOnly: false, stage: \"core\" },\n { id: \"ir-pair\", label: \"Infrared emitter and receiver\", quantity: 1, requirement: \"required\", exactSpecification: \"Matched 940 nm IR LED and 3.3 V-compatible digital receiver pair; exact reference model pending bench verification\", adultOnly: true, stage: \"sensor\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Blink a Rescue Signal\", \"Build a Signal Function\", \"Send an IR Message\", \"Beacon Challenge\"],\n }),\n module({\n slug: \"servo-creature\",\n title: \"Servo Creature\",\n category: \"robot\",\n summary: \"Give a servo creature safe movements, moods and sensor reactions.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"PWM\", \"angles\", \"sequences\", \"limits\", \"interaction\"],\n tokenSubunits: \"10000\",\n hardware: physicalHardware(\"1.0.0\", 40, [\n { id: \"micro-servo\", label: \"Micro servo\", quantity: 1, requirement: \"required\", exactSpecification: \"3.3 V signal-compatible micro servo; exact reference model and external power arrangement pending bench verification\", adultOnly: true, stage: \"servo\" },\n { id: \"servo-power\", label: \"Servo power supply\", quantity: 1, requirement: \"required\", exactSpecification: \"Switched regulated supply sized for the verified servo, with common signal ground\", adultOnly: true, stage: \"servo\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Wake the Creature\", \"Make a Movement Sequence\", \"Choose a Mood\", \"Creature Show Challenge\"],\n }),\n module({\n slug: \"dance-rover\",\n title: \"Dance Rover\",\n category: \"robot\",\n summary: \"Build reusable movement functions and a fail-safe rover dance.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"motor direction\", \"PWM speed\", \"functions\", \"sequences\", \"emergency stop\"],\n tokenSubunits: \"14000\",\n hardware: physicalHardware(\"1.0.0\", 90, [\n { id: \"dual-motor-driver\", label: \"Dual motor driver\", quantity: 1, requirement: \"required\", exactSpecification: \"3.3 V logic-compatible dual H-bridge; exact reference model pending bench verification\", adultOnly: true, stage: \"rover\" },\n { id: \"geared-motors\", label: \"Matching geared motors\", quantity: 2, requirement: \"required\", exactSpecification: \"Matching low-voltage geared DC motors compatible with the verified driver and supply\", adultOnly: true, stage: \"rover\" },\n { id: \"rover-chassis\", label: \"Rover chassis set\", quantity: 1, requirement: \"required\", exactSpecification: \"Two-wheel chassis with matching wheels and caster or skid\", adultOnly: true, stage: \"rover\" },\n { id: \"motor-power\", label: \"Switched motor power supply\", quantity: 1, requirement: \"required\", exactSpecification: \"Fused or protected switched supply within verified driver and motor ratings\", adultOnly: true, stage: \"rover\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Lifted-Wheel Safety Test\", \"Drive and Turn\", \"Build Movement Functions\", \"Rover Dance Challenge\"],\n }),\n module({\n slug: \"obstacle-explorer\",\n title: \"Obstacle Explorer\",\n category: \"robot\",\n summary: \"Use IR sensing, state and watchdogs to navigate and stop safely.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"booleans\", \"state\", \"navigation\", \"watchdogs\", \"fail-safe stop\"],\n tokenSubunits: \"14000\",\n hardware: physicalHardware(\"1.0.0\", 60, [\n { id: \"verified-rover\", label: \"Verified Dance Rover build\", quantity: 1, requirement: \"required\", exactSpecification: \"Bench-signed rover matching the published Dance Rover reference build\", adultOnly: true, stage: \"rover\" },\n { id: \"obstacle-sensors\", label: \"Digital IR obstacle sensors\", quantity: 2, requirement: \"required\", exactSpecification: \"3.3 V-compatible digital IR obstacle sensors; exact reference model pending bench verification\", adultOnly: true, stage: \"sensor\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Read an Obstacle\", \"Choose a Safe Response\", \"Add a Watchdog\", \"Explorer Maze Challenge\"],\n }),\n module({\n slug: \"rainbow-rescue-rover\",\n title: \"Rainbow Rescue Rover\",\n category: \"robot\",\n summary: \"Recognise local colour targets and send bounded serial commands to a safe rover.\",\n tools: [\"Python\", \"C++\", \"Pico 2 W\", \"Pi Zero 2 W\", \"Camera Module 3\", \"Simulator\"],\n concepts: [\"colour recognition\", \"coordinates\", \"serial protocol\", \"heartbeats\", \"integration\"],\n tokenSubunits: \"18000\",\n hardware: physicalHardware(\"1.0.0\", 120, [\n { id: \"verified-explorer\", label: \"Verified Obstacle Explorer build\", quantity: 1, requirement: \"required\", exactSpecification: \"Bench-signed rover matching the published Obstacle Explorer reference build\", adultOnly: true, stage: \"rover\" },\n { id: \"pi-zero-2-w\", label: \"Raspberry Pi Zero 2 W\", quantity: 1, requirement: \"required\", exactSpecification: \"Raspberry Pi Zero 2 W with supported Raspberry Pi OS image\", adultOnly: true, stage: \"camera\" },\n { id: \"camera-3\", label: \"Raspberry Pi Camera Module 3\", quantity: 1, requirement: \"required\", exactSpecification: \"Raspberry Pi Camera Module 3 with the correct Zero-series camera ribbon\", adultOnly: true, stage: \"camera\" },\n { id: \"pi-storage-power\", label: \"Pi storage and power\", quantity: 1, requirement: \"required\", exactSpecification: \"Supported microSD card and regulated Raspberry Pi power supply\", adultOnly: true, stage: \"camera\" },\n ], [\"Current Raspberry Pi OS\", \"Pico SDK\"]),\n missionTitles: [\"Find a Colour Target\", \"Report Left Centre or Right\", \"Send Safe Serial Commands\", \"Rainbow Rescue Challenge\"],\n }),\n module({\n slug: \"vibe-game-remix-lab\",\n title: \"Vibe Game Remix Lab\",\n category: \"vibe\",\n summary: \"Transform a supplied mini-game through structured, evidence-bound AI suggestions.\",\n tools: [\"Structured prompt builder\", \"Diff review\", \"JavaScript sandbox\"],\n concepts: [\"intent\", \"constraints\", \"diffs\", \"testing\", \"explanation\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Describe the Remix\", \"Constrain the Change\", \"Review One Diff\", \"Remix Challenge\"],\n }),\n module({\n slug: \"vibe-bug-detective\",\n title: \"Vibe Bug Detective\",\n category: \"vibe\",\n summary: \"Repair an intentionally broken project using assessment evidence and focused suggestions.\",\n tools: [\"Structured prompt builder\", \"Diff review\", \"Assessment runner\"],\n concepts: [\"diagnostics\", \"hypotheses\", \"minimal fixes\", \"regression tests\", \"reflection\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Read the Evidence\", \"Ask a Focused Question\", \"Inspect a Suggested Fix\", \"Regression Challenge\"],\n }),\n module({\n slug: \"vibe-idea-studio\",\n title: \"Vibe Idea Studio\",\n category: \"vibe\",\n summary: \"Turn a bounded original idea into goals, acceptance tests and a working prototype.\",\n tools: [\"Intent cards\", \"Structured prompt builder\", \"Diff review\", \"Sandbox\"],\n concepts: [\"goals\", \"acceptance tests\", \"iteration\", \"trade-offs\", \"explanation\"],\n tokenSubunits: \"16000\",\n missionTitles: [\"Shape the Idea\", \"Write Success Tests\", \"Build One Step\", \"Prototype Showcase\"],\n }),\n module({\n slug: \"adventure-mission-planner\",\n title: \"Adventure Mission Planner\",\n category: \"web-app\",\n summary: \"Build an accessible planner for fictional quests and activities.\",\n tools: [\"HTML\", \"CSS\", \"JavaScript\", \"Private preview\"],\n concepts: [\"semantic HTML\", \"forms\", \"validation\", \"arrays\", \"local persistence\"],\n tokenSubunits: \"10000\",\n hosting: true,\n missionTitles: [\"Make a Semantic Page\", \"Add a Mission Form\", \"Save Fictional Missions\", \"Accessible Planner Challenge\"],\n }),\n module({\n slug: \"creature-care-dashboard\",\n title: \"Creature Care Dashboard\",\n category: \"web-app\",\n summary: \"Create a responsive dashboard for a fictional digital creature.\",\n tools: [\"HTML\", \"CSS\", \"JavaScript\", \"Private preview\"],\n concepts: [\"components\", \"events\", \"timers\", \"status displays\", \"reduced motion\"],\n tokenSubunits: \"12000\",\n hosting: true,\n missionTitles: [\"Design the Creature Card\", \"Update Creature State\", \"Add a Safe Timer\", \"Care Dashboard Challenge\"],\n }),\n module({\n slug: \"robot-mission-control\",\n title: \"Robot Mission Control\",\n category: \"web-app\",\n summary: \"Build a simulated control and telemetry interface with safety confirmations.\",\n tools: [\"HTML\", \"CSS\", \"JavaScript\", \"Serial simulator\", \"Private preview\"],\n concepts: [\"commands\", \"state machines\", \"confirmations\", \"charts\", \"responsive controls\"],\n tokenSubunits: \"14000\",\n hosting: true,\n missionTitles: [\"Build the Control Panel\", \"Simulate Telemetry\", \"Add Stop Confirmations\", \"Mission Control Challenge\"],\n }),\n];\n\n/**\n * Uniform price for the immutable 1.1.0 pilot catalog.\n *\n * The GBP value is product-copy reference metadata under the published\n * 10p-per-Token economy reference rate. It does not create redemption rights.\n */\nexport const JUNIOR_CODER_MODULE_PRICE_V1_1 = Object.freeze({\n tokenSubunits: \"50000\",\n referencePrice: Object.freeze({\n currency: \"GBP\" as const,\n minorUnits: \"500\",\n basis: \"nominal-reference\" as const,\n cashRedemptionAllowed: false as const,\n }),\n});\n\n/** Initial immutable Junior Coder path manifest for pilot grants and shadow pricing. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1: LearningPathVersionV1 = {\n id: \"junior-coder.robot-rescue-arcade\",\n slug: \"robot-rescue-arcade\",\n version: \"1.0.0\",\n title: \"Junior Coder: Robot Rescue Arcade\",\n description: \"Nineteen self-contained game, robotics, Vibe Coding and web-app projects for young programmers.\",\n catalogState: \"pilot\",\n publicLaunchAtomic: true,\n featureFlag: \"learning.junior-coder.catalog.enabled\",\n modules,\n};\n\n/**\n * Uniformly priced successor to the immutable 1.0.0 pilot catalog.\n *\n * All modules remain independently sellable and retain their existing content,\n * manifests and safeguards. The new module and path versions bind the new price\n * without altering previously published records.\n */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1,\n version: \"1.1.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1.modules.map((entry) => ({\n ...entry,\n version: \"1.1.0\",\n contentRevision: \"2026-07-28.1\",\n pricing: {\n ...entry.pricing,\n tokenSubunits: JUNIOR_CODER_MODULE_PRICE_V1_1.tokenSubunits,\n referencePrice: JUNIOR_CODER_MODULE_PRICE_V1_1.referencePrice,\n },\n })),\n};\n\n/** Digest-pinned content package for the independently released 54-stage course. */\nexport const ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V1 = Object.freeze({\n packageName: \"@plasius/learning-road-hopper-rally\",\n packageVersion: \"1.0.0\",\n exportName: \"ROAD_HOPPER_RALLY_COURSE_V2\",\n schemaVersion: \"2\",\n sha256: \"1a20741beba028004e0be527d05aae2b2881082d3b578e0d62308a59bf1323f0\",\n});\n\n/** Digest-pinned evidence-led successor; the immutable v2 reference remains available. */\nexport const ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V2 = Object.freeze({\n packageName: \"@plasius/learning-road-hopper-rally\",\n packageVersion: \"1.1.0\",\n exportName: \"ROAD_HOPPER_RALLY_COURSE_V3\",\n schemaVersion: \"3\",\n sha256: \"f73b90f5f0e483b96724f978f2977435a5e6a1333f5f45fd0fc803b55ad21187\",\n});\n\nconst roadHopperV1_1 = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.find(\n (entry) => entry.id === \"junior-coder.road-hopper-rally\",\n)!;\n\nconst ROAD_HOPPER_RALLY_V2_MISSIONS = [\n {\n id: \"board\",\n title: \"Build the Rally Board\",\n concepts: [\"coordinate grids\", \"arrays\", \"entity state\", \"rendering\"],\n statement: \"Create the road, median, river and five distinct home bays in board.js.\",\n sideAdventure: \"Design an original high-contrast board palette without changing its mechanics.\",\n },\n {\n id: \"hopper\",\n title: \"Move the Hopper\",\n concepts: [\"events\", \"bounded movement\", \"keyboard input\", \"touch input\", \"respawning\"],\n statement: \"Implement four-direction tile movement, bounds, equivalent inputs and respawning in hopper.js.\",\n sideAdventure: \"Add an accessible movement status phrase for every successful hop.\",\n },\n {\n id: \"traffic\",\n title: \"Create Rally Traffic\",\n concepts: [\"spawning\", \"fixed-step updates\", \"wrapping\", \"collision detection\", \"difficulty\"],\n statement: \"Implement five deterministic traffic lanes, collisions, lives and difficulty in traffic.js.\",\n sideAdventure: \"Invent an original vehicle type while preserving the entity and collision limits.\",\n },\n {\n id: \"river\",\n title: \"Cross the Moving River\",\n concepts: [\"moving platforms\", \"carrying\", \"hazards\", \"state machines\", \"off-screen bounds\"],\n statement: \"Implement logs, carrying, water deaths, diving platforms and edge hazards in river.js.\",\n sideAdventure: \"Create an original visual warning for a platform that is about to dive.\",\n },\n {\n id: \"rules\",\n title: \"Add Rally Rules\",\n concepts: [\"timers\", \"lives\", \"scoring\", \"bonuses\", \"levels\", \"game over\"],\n statement: \"Implement homes, occupied and blocked bays, timer, scoring, bonuses and level progression in rules.js.\",\n sideAdventure: \"Tune a practice-speed preset that keeps every rule deterministic.\",\n },\n {\n id: \"game\",\n title: \"Complete Road Hopper Rally\",\n concepts: [\"system assembly\", \"pause and restart\", \"alternating players\", \"audio\", \"accessibility\", \"testing\"],\n statement: \"Assemble the systems, accessibility modes and alternating-player finale in game.js, then pass the protected challenge.\",\n sideAdventure: \"Polish the finished game with original captions, visual cues and reduced-motion feedback.\",\n },\n] as const;\n\n/** Road Hopper Rally 2.0 catalog record; course data stays in the referenced package. */\nexport const JUNIOR_CODER_ROAD_HOPPER_RALLY_V2: LearningModuleVersionV1 = {\n ...roadHopperV1_1,\n version: \"2.0.0\",\n contentRevision: \"2026-08-11.1\",\n summary: \"Recreate the systems behind a classic road-and-river crossing game using original Road Hopper Rally code, art, audio and presentation.\",\n estimatedMinutes: 450,\n tools: [\n \"JavaScript\",\n \"QuickJS sandbox\",\n \"Deterministic 30 Hz engine\",\n \"Road Hopper renderer\",\n ],\n concepts: [\n \"coordinates\",\n \"arrays and entity state\",\n \"events and input\",\n \"fixed-step update and render\",\n \"spawning and movement\",\n \"collision detection\",\n \"state machines\",\n \"timers, lives and scoring\",\n \"difficulty progression\",\n \"audio integration\",\n \"debugging\",\n \"deterministic testing\",\n ],\n missions: ROAD_HOPPER_RALLY_V2_MISSIONS.map((missionDefinition, index) => ({\n id: `road-hopper-rally-mission-${index + 1}-${missionDefinition.id}`,\n title: missionDefinition.title,\n estimatedMinutes: 75,\n concepts: [...missionDefinition.concepts],\n goals: [\n {\n id: `road-hopper-rally-v2-${missionDefinition.id}`,\n statement: missionDefinition.statement,\n evidence: \"assessment\",\n },\n ],\n sideAdventure: missionDefinition.sideAdventure,\n })),\n assessment: {\n version: \"2.0.0\",\n completionScore: 80,\n criteria: [\n { id: \"road-hopper-v2-structure\", label: \"All six bounded JavaScript files compile and assemble.\", dimension: \"structure\", points: 20, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-road\", label: \"Board, input and traffic behaviours pass deterministic scenarios.\", dimension: \"behaviour\", points: 15, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-river\", label: \"River platforms, carrying and hazards pass deterministic scenarios.\", dimension: \"behaviour\", points: 15, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-rules\", label: \"Homes, timer, lives, scoring, bonuses and levels behave correctly.\", dimension: \"behaviour\", points: 20, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-final\", label: \"The complete game passes the server-only protected final challenge.\", dimension: \"resilience\", points: 20, mandatory: true, visibility: \"protected\" },\n { id: \"road-hopper-v2-safety\", label: \"The project stays within the sandbox, resource and privacy boundaries.\", dimension: \"safety\", points: 10, mandatory: true, visibility: \"visible\" },\n ],\n },\n badges: [\n {\n id: \"road-hopper-rally-v2-complete\",\n title: \"Road Hopper Rally Champion\",\n evidence: \"module-score\",\n tradeable: false,\n tokenConvertible: false,\n },\n ],\n externalContent: ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V1,\n};\n\nconst ROAD_HOPPER_RALLY_V2_1_MISSION_TITLES = [\n \"Map the Rally Route\",\n \"Move the Hopper\",\n \"Build the Traffic Rally\",\n \"Ride the Rescue River\",\n \"Score the Rescue\",\n \"Road Hopper Rally Challenge\",\n] as const;\n\n/** Evidence-led Road Hopper 2.1 record; the executable course remains external. */\nexport const JUNIOR_CODER_ROAD_HOPPER_RALLY_V2_1: LearningModuleVersionV1 = {\n ...JUNIOR_CODER_ROAD_HOPPER_RALLY_V2,\n version: \"2.1.0\",\n contentRevision: \"2026-08-24.1\",\n summary: \"Build Road Hopper Rally through 54 evidence-led activities: predict, edit, run, inspect, repair, explain and prove each deterministic game system.\",\n missions: JUNIOR_CODER_ROAD_HOPPER_RALLY_V2.missions.map((mission, index) => ({\n ...mission,\n title: ROAD_HOPPER_RALLY_V2_1_MISSION_TITLES[index]!,\n })),\n assessment: {\n ...JUNIOR_CODER_ROAD_HOPPER_RALLY_V2.assessment,\n version: \"2.1.0\",\n },\n externalContent: ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V2,\n};\n\n/** Mixed-version successor: Road Hopper 2.0 plus every other immutable 1.1 module. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_2: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,\n version: \"1.2.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.map((entry) =>\n entry.id === JUNIOR_CODER_ROAD_HOPPER_RALLY_V2.id\n ? JUNIOR_CODER_ROAD_HOPPER_RALLY_V2\n : entry),\n};\n\n/** Digest-pinned Paddle Pulse 2.0 reference-module content. */\nexport const PADDLE_PULSE_EXTERNAL_CONTENT_V1 = Object.freeze({\n packageName: \"@plasius/learning-paddle-pulse\",\n packageVersion: \"0.1.0\",\n exportName: \"PADDLE_PULSE_MODULE_V2\",\n schemaVersion: \"2\",\n sha256: \"19f3666bdb523a3faf069341b0bc748996b3db282f89171e3c9f0a373a8c8f7e\",\n});\n\nconst paddlePulseV1_1 = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.find(\n (entry) => entry.id === \"junior-coder.paddle-pulse\",\n)!;\n\nconst PADDLE_PULSE_V2_MISSIONS = [\n {\n id: \"court-coordinates\",\n title: \"Court & Coordinates\",\n concepts: [\"coordinates\", \"canvas primitives\", \"game loops\", \"bounds\"],\n statement: \"Build a responsive 640 × 480 logical court with a bounded paddle and ball.\",\n sideAdventure: \"Create an original high-contrast court palette without changing its geometry.\",\n },\n {\n id: \"paddle-controls\",\n title: \"Paddle Controls\",\n concepts: [\"input state\", \"Pointer Events\", \"keyboard input\", \"clamping\"],\n statement: \"Implement equivalent Arrow/A/D and direct horizontal pointer-drag controls.\",\n sideAdventure: \"Add a semantic movement trace that does not rely on animation.\",\n },\n {\n id: \"ball-motion\",\n title: \"Ball Motion & Bounces\",\n concepts: [\"velocity\", \"fixed timesteps\", \"reflection\", \"contact normals\", \"paddle angles\"],\n statement: \"Implement deterministic ball motion plus controlled wall and paddle reflections.\",\n sideAdventure: \"Design a reduced-motion trajectory inspector for one rally.\",\n },\n {\n id: \"bricks-collisions\",\n title: \"Bricks & Collisions\",\n concepts: [\"arrays\", \"loops\", \"brick grids\", \"AABB collision\", \"resolution\"],\n statement: \"Create an original brick grid whose bricks score once and disappear on impact.\",\n sideAdventure: \"Invent a new visual brick pattern using the same bounded collision rules.\",\n },\n {\n id: \"score-lives-states\",\n title: \"Score, Lives & States\",\n concepts: [\"state machines\", \"invariants\", \"scoring\", \"lives\", \"HUD state\"],\n statement: \"Implement serve, pause, life loss, level clear, game over, score and HUD states.\",\n sideAdventure: \"Add a printable state-transition table for a facilitator or screen-reader user.\",\n },\n {\n id: \"levels-final-game\",\n title: \"Levels, Sound & Final Game\",\n concepts: [\"level data\", \"difficulty\", \"responsive rendering\", \"accessible audio\", \"testing\"],\n statement: \"Assemble multiple original levels, optional generated cues and the integrated final game.\",\n sideAdventure: \"After completion, add an optional original power-up without changing core assessment.\",\n },\n] as const;\n\n/** Paddle Pulse 2.0 catalog record; executable content stays in its package. */\nexport const JUNIOR_CODER_PADDLE_PULSE_V2: LearningModuleVersionV1 = {\n ...paddlePulseV1_1,\n version: \"2.0.0\",\n contentRevision: \"2026-08-11.1\",\n summary: \"Build an original Plasius brick-breaker while learning rendering, equivalent input, deterministic physics, collisions, score, lives, states, levels, accessible sound and testing.\",\n estimatedMinutes: 360,\n tools: [\n \"JavaScript\",\n \"QuickJS sandbox\",\n \"Deterministic 60 Hz engine\",\n \"Responsive Paddle Pulse renderer\",\n ],\n concepts: [\n \"coordinates and rendering\",\n \"game loops and fixed timesteps\",\n \"keyboard and pointer input\",\n \"velocity and reflection\",\n \"collision detection and resolution\",\n \"arrays and brick grids\",\n \"scoring, lives and state machines\",\n \"level data and difficulty\",\n \"accessible generated audio\",\n \"debugging and deterministic testing\",\n ],\n missions: PADDLE_PULSE_V2_MISSIONS.map((missionDefinition, index) => ({\n id: `paddle-pulse-mission-${index + 1}-${missionDefinition.id}`,\n title: missionDefinition.title,\n estimatedMinutes: 60,\n concepts: [...missionDefinition.concepts],\n goals: [{\n id: `paddle-pulse-v2-${missionDefinition.id}`,\n statement: missionDefinition.statement,\n evidence: \"assessment\",\n }],\n sideAdventure: missionDefinition.sideAdventure,\n })),\n assessment: {\n version: \"2.0.0\",\n completionScore: 80,\n criteria: [\n { id: \"paddle-pulse-v2-court\", label: \"The logical court, paddle and initial scene are finite, responsive and bounded.\", dimension: \"structure\", points: 20, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-controls\", label: \"Keyboard and pointer paths produce equivalent clamped paddle input.\", dimension: \"behaviour\", points: 15, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-motion\", label: \"Ball motion and wall/paddle reflections pass deterministic trajectories.\", dimension: \"behaviour\", points: 15, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-bricks\", label: \"Brick face, corner and adjacent impacts resolve without double-scoring.\", dimension: \"behaviour\", points: 20, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-states\", label: \"Score, lives, serve, pause, level-clear and game-over transitions preserve invariants.\", dimension: \"resilience\", points: 10, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-final\", label: \"Multiple original levels and the integrated game pass protected deterministic scenarios.\", dimension: \"resilience\", points: 10, mandatory: false, visibility: \"protected\" },\n { id: \"paddle-pulse-v2-safety\", label: \"Source, commands, runtime resources and assessment remain inside sandbox limits.\", dimension: \"safety\", points: 10, mandatory: true, visibility: \"visible\" },\n ],\n },\n badges: [\n { id: \"paddle-pulse-v2-court-builder\", title: \"Court Builder\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-paddle-pilot\", title: \"Paddle Pilot\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-rally-master\", title: \"Rally Master\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-brick-breaker\", title: \"Brick Breaker\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-game-keeper\", title: \"Game Keeper\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-complete\", title: \"Paddle Pulse Champion\", evidence: \"module-score\", tradeable: false, tokenConvertible: false },\n ],\n externalContent: PADDLE_PULSE_EXTERNAL_CONTENT_V1,\n};\n\n/** Mixed-version successor adding Paddle Pulse 2.0 without mutating v1.1. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_3: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_2,\n version: \"1.3.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_2.modules.map((entry) =>\n entry.id === JUNIOR_CODER_PADDLE_PULSE_V2.id\n ? JUNIOR_CODER_PADDLE_PULSE_V2\n : entry),\n};\n\n/** Mixed-version successor adding evidence-led Road Hopper without mutating v1.3. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_4: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_3,\n version: \"1.4.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_3.modules.map((entry) =>\n entry.id === JUNIOR_CODER_ROAD_HOPPER_RALLY_V2_1.id\n ? JUNIOR_CODER_ROAD_HOPPER_RALLY_V2_1\n : entry),\n};\n\n/** Current pilot catalog for server adapters that intentionally follow releases. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT =\n JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_4;\n","import { calculateAssessment } from \"./assessment.js\";\nimport { validateAssessmentRubric } from \"./rubric-validation.js\";\nimport type { AssessmentCheckResultV1, AssessmentResultV1, AssessmentRubricV1 } from \"./contracts.js\";\nimport { LearningCourseInputError, validateLearningCourse, type LearningCourseV1 } from \"./course-contracts.js\";\n\n/** Stored host-issued assessment. No browser-supplied result may construct this authority. */\nexport interface LearningCourseAssessmentRecordV1 {\n missionId: string;\n assessmentId: string;\n referenceId: string;\n sourceDigest: string;\n result: AssessmentResultV1;\n}\n/** Account and timestamps are supplied by the storage adapter, not the contract. */\nexport interface LearningCourseProgressV1 {\n schemaVersion: \"1\";\n moduleId: string;\n moduleVersion: string;\n completedStageIds: string[];\n completedMissionIds: string[];\n assessments: LearningCourseAssessmentRecordV1[];\n completion: { referenceId: string; sourceDigest: string; bestScore: number } | null;\n}\n/** Construct only after the host validates the activity-specific learner input. */\nexport interface VerifiedLearningActivityV1 {\n stageId: string;\n sourceDigest: string;\n accepted: boolean;\n}\n/** Rubric and check results come from trusted assessment execution, never a save body. */\nexport interface LearningCourseAssessmentAuthorityV1 {\n missionId: string;\n assessmentId: string;\n referenceId: string;\n sourceDigest: string;\n rubric: AssessmentRubricV1;\n checks: AssessmentCheckResultV1[];\n}\nconst DIGEST = /^[a-f0-9]{64}$/u;\nconst REFERENCE = /^[a-z0-9][a-z0-9.-]{0,159}$/u;\nconst stages = (course: LearningCourseV1) => course.missions.flatMap(mission => mission.stages);\nconst record = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst keys = (value: Record<string, unknown>, expected: string[]) => Object.keys(value).length === expected.length && expected.every(key => Object.hasOwn(value, key));\nconst identifier = (value: unknown): value is string => typeof value === \"string\" && REFERENCE.test(value);\nconst digest = (value: unknown): value is string => typeof value === \"string\" && DIGEST.test(value);\n\nfunction validResult(value: unknown): value is AssessmentResultV1 {\n if (!record(value) || !keys(value, [\"score\", \"band\", \"completed\", \"passedCriterionIds\", \"failedCriterionIds\", \"failedMandatoryCriterionIds\"])\n || typeof value.score !== \"number\" || !Number.isInteger(value.score) || value.score < 0 || value.score > 100) return false;\n const arrays = [value.passedCriterionIds, value.failedCriterionIds, value.failedMandatoryCriterionIds];\n if (arrays.some(items => !Array.isArray(items) || items.length > 64 || !items.every(identifier) || new Set(items).size !== items.length)) return false;\n const passed = value.passedCriterionIds as string[];\n const failed = value.failedCriterionIds as string[];\n const mandatory = value.failedMandatoryCriterionIds as string[];\n const band = value.score >= 95 ? \"mastered\" : value.score >= 80 ? \"mission-complete\" : value.score >= 60 ? \"nearly-there\" : \"keep-exploring\";\n return value.band === band && value.completed === (value.score >= 80 && mandatory.length === 0)\n && !passed.some(id => failed.includes(id)) && mandatory.every(id => failed.includes(id));\n}\n\nfunction assertProgress(course: LearningCourseV1, progress: LearningCourseProgressV1): void {\n const ordered = stages(course);\n if (progress.schemaVersion !== \"1\" || progress.moduleId !== course.moduleId || progress.moduleVersion !== course.moduleVersion\n || !Array.isArray(progress.completedStageIds) || progress.completedStageIds.length > ordered.length\n || progress.completedStageIds.some((id, index) => id !== ordered[index]!.id)\n || !Array.isArray(progress.completedMissionIds)\n || progress.completedMissionIds.length !== Math.floor(progress.completedStageIds.length / 9)\n || progress.completedMissionIds.some((id, index) => id !== course.missions[index]!.id)\n || !Array.isArray(progress.assessments) || progress.assessments.length > 7\n || progress.assessments.some(item => {\n if (!record(item) || !keys(item, [\"missionId\", \"assessmentId\", \"referenceId\", \"sourceDigest\", \"result\"])\n || !identifier(item.referenceId) || !digest(item.sourceDigest) || !validResult(item.result)) return true;\n const mission = course.missions.find(candidate => candidate.id === item.missionId);\n return item.missionId === \"final\"\n ? progress.completedMissionIds.length !== 6 || item.assessmentId !== course.completionAssessmentId\n : !mission || item.assessmentId !== mission.assessmentId;\n })\n || new Set(progress.assessments.map(item => item.missionId)).size !== progress.assessments.length\n || new Set(progress.assessments.map(item => item.referenceId)).size !== progress.assessments.length) throw new LearningCourseInputError();\n if (progress.completion !== null && (!record(progress.completion)\n || !keys(progress.completion, [\"referenceId\", \"sourceDigest\", \"bestScore\"])\n || progress.completedMissionIds.length !== 6 || !identifier(progress.completion.referenceId)\n || !digest(progress.completion.sourceDigest) || !Number.isInteger(progress.completion.bestScore)\n || progress.completion.bestScore < 80 || progress.completion.bestScore > 100)) throw new LearningCourseInputError();\n}\n\n/** Parse storage-owned progress. This is not an accepted browser mutation shape. */\nexport function parseLearningCourseProgress(course: LearningCourseV1, value: unknown): LearningCourseProgressV1 {\n if (!record(value) || !keys(value, [\"schemaVersion\", \"moduleId\", \"moduleVersion\", \"completedStageIds\", \"completedMissionIds\", \"assessments\", \"completion\"])) throw new LearningCourseInputError();\n assertProgress(course, value as unknown as LearningCourseProgressV1);\n return structuredClone(value as unknown as LearningCourseProgressV1);\n}\n\n/** Fresh course progress cannot inherit completion from project files or an old version. */\nexport function createLearningCourseProgress(course: LearningCourseV1): LearningCourseProgressV1 {\n if (validateLearningCourse(course).length) throw new LearningCourseInputError();\n return { schemaVersion: \"1\", moduleId: course.moduleId, moduleVersion: course.moduleVersion,\n completedStageIds: [], completedMissionIds: [], assessments: [], completion: null };\n}\n\n/** Saved navigation may revisit earned activities but cannot unlock later activities. */\nexport function resolveLearningCourseStage(course: LearningCourseV1, progress: LearningCourseProgressV1, requestedId: string): string {\n assertProgress(course, progress);\n const ordered = stages(course);\n const maximum = Math.min(progress.completedStageIds.length, ordered.length - 1);\n const requestedIndex = ordered.findIndex(stage => stage.id === requestedId);\n return requestedIndex >= 0 && requestedIndex <= maximum ? requestedId : ordered[maximum]!.id;\n}\n\n/**\n * Record checks from a host-owned deterministic runner using the existing rubric\n * calculator. A final assessment must cover the whole accumulated project.\n * Hosts bind reference IDs and source digests to their authenticated transaction.\n */\nexport function recordLearningCourseAssessment(\n course: LearningCourseV1, progress: LearningCourseProgressV1, authority: LearningCourseAssessmentAuthorityV1,\n): LearningCourseProgressV1 {\n assertProgress(course, progress);\n const final = authority.missionId === \"final\";\n const missionIndex = course.missions.findIndex(mission => mission.id === authority.missionId);\n if (!DIGEST.test(authority.sourceDigest) || !REFERENCE.test(authority.referenceId)\n || (final ? progress.completedMissionIds.length !== course.missions.length\n : missionIndex < 0 || missionIndex > progress.completedMissionIds.length)\n || authority.assessmentId !== (final ? course.completionAssessmentId : course.missions[missionIndex]?.assessmentId)\n || authority.rubric.version !== course.moduleVersion\n || authority.rubric.criteria.length > 64 || authority.checks.length > 64\n || authority.checks.some(check => typeof check.passed !== \"boolean\")\n || validateAssessmentRubric(authority.rubric).length) throw new LearningCourseInputError();\n let result: AssessmentResultV1;\n try { result = calculateAssessment(authority.rubric, authority.checks); }\n catch { throw new LearningCourseInputError(); }\n const assessment: LearningCourseAssessmentRecordV1 = {\n missionId: authority.missionId, assessmentId: authority.assessmentId, referenceId: authority.referenceId,\n sourceDigest: authority.sourceDigest, result,\n };\n const duplicate = progress.assessments.find(item => item.referenceId === authority.referenceId);\n if (duplicate && JSON.stringify(duplicate) !== JSON.stringify(assessment)) throw new LearningCourseInputError();\n const next = structuredClone(progress);\n next.assessments = [...next.assessments.filter(item => item.missionId !== authority.missionId), assessment];\n if (final && result.completed) {\n next.completion = next.completion\n ? { ...next.completion, bestScore: Math.max(next.completion.bestScore, result.score) }\n : { referenceId: authority.referenceId, sourceDigest: authority.sourceDigest, bestScore: result.score };\n }\n return next;\n}\n\n/**\n * Advance one verified activity. Acknowledgements alone never earn a mission or\n * badge. Failed assessments can be inspected, but repair and reward need passing\n * evidence for the current project. Storage must never accept this proof as-is\n * from a browser: the host validates each activity before constructing it.\n */\nexport function completeVerifiedLearningActivity(\n course: LearningCourseV1, progress: LearningCourseProgressV1, proof: VerifiedLearningActivityV1,\n): LearningCourseProgressV1 {\n assertProgress(course, progress);\n if (proof.accepted !== true || !DIGEST.test(proof.sourceDigest)) throw new LearningCourseInputError();\n const ordered = stages(course);\n const index = ordered.findIndex(stage => stage.id === proof.stageId);\n if (index < 0 || index > progress.completedStageIds.length) throw new LearningCourseInputError();\n if (index < progress.completedStageIds.length) return structuredClone(progress);\n const stage = ordered[index]!;\n const mission = course.missions[Math.floor(index / 9)]!;\n if ([\"assess\", \"inspect\", \"fix\", \"reward\"].includes(stage.kind)) {\n const assessment = progress.assessments.find(item => item.missionId === mission.id);\n if (!assessment || assessment.sourceDigest !== proof.sourceDigest\n || ((stage.kind === \"fix\" || stage.kind === \"reward\") && !assessment.result.completed)) throw new LearningCourseInputError();\n }\n const next = structuredClone(progress);\n next.completedStageIds.push(proof.stageId);\n if (stage.kind === \"reward\") next.completedMissionIds.push(mission.id);\n return next;\n}\n","/** Additive contract version for touch-first and spoken contextual help. */\nexport const CONTEXTUAL_HELP_CONTRACT_VERSION_V1 = \"1.0.0\" as const;\n\nexport const CONTEXTUAL_HELP_KINDS_V1 = Object.freeze([\n \"command\",\n \"visual-block\",\n \"generated-code\",\n \"assessment-diagnostic\",\n] as const);\n\nexport type ContextualHelpKindV1 = (typeof CONTEXTUAL_HELP_KINDS_V1)[number];\n\n/**\n * Opaque, manifest-bound identifier. It contains no source, transcript,\n * learner identity or arbitrary synthesis text.\n */\nexport interface ContextualHelpIdentifierV1 {\n readonly schemaVersion: \"1\";\n readonly contractVersion: typeof CONTEXTUAL_HELP_CONTRACT_VERSION_V1;\n readonly kind: ContextualHelpKindV1;\n readonly moduleId: string;\n readonly moduleVersion: string;\n readonly manifestVersion: string;\n readonly helpId: string;\n}\n\nexport type GuardianVoiceConsentStateV1 = \"granted\" | \"withdrawn\";\nexport type GuardianVoiceProcessingRouteV1 = \"private-edge-only\";\n\n/** Voice consent is deliberately separate from general AI consent. */\nexport interface GuardianVoiceConsentV1 {\n readonly schemaVersion: \"1\";\n readonly actorAccountId: string;\n readonly subjectAccountId: string;\n readonly policyVersion: string;\n readonly state: GuardianVoiceConsentStateV1;\n readonly permittedProcessingRoute: GuardianVoiceProcessingRouteV1;\n readonly recordedAt: string;\n}\n\nexport type VoiceHelpAvailabilityReasonV1 =\n | \"available\"\n | \"module-access-required\"\n | \"guardian-consent-required\"\n | \"guardian-consent-withdrawn\"\n | \"age-or-safeguarding-gate\"\n | \"capability-disabled\"\n | \"rollout-disabled\"\n | \"private-edge-unavailable\";\n\n/** Read-aloud and microphone availability are evaluated independently. */\nexport interface VoiceHelpAvailabilityV1 {\n readonly schemaVersion: \"1\";\n readonly readAloudAvailable: boolean;\n readonly microphoneAvailable: boolean;\n readonly microphoneReason: VoiceHelpAvailabilityReasonV1;\n readonly questionProcessingRoute: GuardianVoiceProcessingRouteV1;\n readonly guardianVoiceConsentRequired: true;\n readonly maximumRecordingDurationMs: 10_000;\n readonly maximumAudioBytes: 2_097_152;\n readonly rawAudioRetention: \"request-memory-only\";\n readonly transcriptRetention: \"request-memory-only\";\n}\n\n/** Metadata accepted beside an authenticated multipart audio upload. */\nexport interface ContextualVoiceQuestionMetadataV1 {\n readonly schemaVersion: \"1\";\n readonly help: ContextualHelpIdentifierV1;\n readonly locale: string;\n readonly mediaType: string;\n readonly durationMs: number;\n readonly audioBytes: number;\n readonly assessmentEvidenceId?: string;\n}\n\nexport const CONTEXTUAL_VOICE_INTENTS_V1 = Object.freeze([\n \"describe-command\",\n \"describe-inputs\",\n \"show-example\",\n \"explain-assessment-failure\",\n \"suggest-next-experiment\",\n \"repeat\",\n \"stop\",\n \"unresolved\",\n] as const);\n\nexport type ContextualVoiceIntentV1 =\n (typeof CONTEXTUAL_VOICE_INTENTS_V1)[number];\n\nexport type ContextualVoiceSuggestedActionV1 =\n | \"open-help\"\n | \"insert-example\"\n | \"show-inputs\"\n | \"show-assessment-evidence\"\n | \"try-next-experiment\"\n | \"repeat\"\n | \"stop\"\n | \"type-question\";\n\nexport const CONTEXTUAL_VOICE_SUGGESTED_ACTIONS_V1 = Object.freeze([\n \"open-help\",\n \"insert-example\",\n \"show-inputs\",\n \"show-assessment-evidence\",\n \"try-next-experiment\",\n \"repeat\",\n \"stop\",\n \"type-question\",\n] as const satisfies readonly ContextualVoiceSuggestedActionV1[]);\n\nexport interface ContextualVoiceAnswerV1 {\n readonly helpId: string;\n readonly source:\n | \"module-documentation\"\n | \"assessment-evidence\"\n | \"authored-fallback\";\n /** Server-resolved visible answer; never a model-authored open response. */\n readonly text: string;\n}\n\n/**\n * The transcript is returned only so the learner can verify recognition. The\n * request boundary must use no-store and discard it after the current view.\n */\nexport interface ContextualVoiceQuestionResultV1 {\n readonly schemaVersion: \"1\";\n readonly help: ContextualHelpIdentifierV1;\n readonly intent: ContextualVoiceIntentV1;\n readonly status: \"resolved\" | \"suggestions\" | \"stopped\";\n readonly transientTranscript: string;\n readonly transcriptRetention: \"request-memory-only\";\n readonly answer?: ContextualVoiceAnswerV1;\n readonly suggestedActions: ContextualVoiceSuggestedActionV1[];\n readonly mayAssignScore: false;\n readonly mayAwardReward: false;\n readonly mayPublish: false;\n readonly mayControlHardware: false;\n}\n\n/** Canonical audio lookup metadata. Authoritative speech text stays server-side. */\nexport interface CanonicalSpokenHelpDescriptorV1 {\n readonly schemaVersion: \"1\";\n readonly help: ContextualHelpIdentifierV1;\n readonly canonicalTextId: string;\n readonly authoritativeTextDigest: `sha256:${string}`;\n readonly locale: string;\n readonly voiceProfile: string;\n readonly pronunciationVersion: string;\n readonly utteranceClass: \"system-generic\";\n readonly sharingScope: \"global\";\n readonly reuse: \"exact-only\";\n readonly containsPersonalData: false;\n readonly containsLearnerContent: false;\n}\n\nconst OPAQUE_ID = /^[a-z0-9]+(?:[._:-][a-z0-9]+)*$/u;\nconst SEMVER = /^[0-9]+\\.[0-9]+\\.[0-9]+(?:[-+][A-Za-z0-9.-]+)?$/u;\nconst SHA_256 = /^sha256:[a-f0-9]{64}$/u;\nconst LOCALE = /^[a-z]{2,3}(?:-[A-Z]{2})?$/u;\nconst MEDIA_TYPE = /^audio\\/[a-z0-9.+-]+$/u;\n\nfunction containsDisallowedControlCharacter(value: string): boolean {\n return [...value].some((character) => {\n const code = character.codePointAt(0) ?? 0;\n return code <= 8 || code === 11 || code === 12\n || (code >= 14 && code <= 31) || code === 127;\n });\n}\n\nfunction requireOpaqueId(value: string, label: string, maximum = 160): void {\n if (value.length === 0 || value.length > maximum || !OPAQUE_ID.test(value)) {\n throw new Error(`${label} must be a bounded opaque identifier.`);\n }\n}\n\nfunction requireSemver(value: string, label: string): void {\n if (!SEMVER.test(value)) {\n throw new Error(`${label} must be an immutable semantic version.`);\n }\n}\n\nfunction requireIsoTimestamp(value: string, label: string): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}T/u.test(value) || !Number.isFinite(Date.parse(value))) {\n throw new Error(`${label} must be an ISO-8601 timestamp.`);\n }\n}\n\nexport function assertValidContextualHelpIdentifier(\n value: ContextualHelpIdentifierV1,\n): void {\n if (value.schemaVersion !== \"1\") {\n throw new Error(\"schemaVersion must be 1.\");\n }\n if (value.contractVersion !== CONTEXTUAL_HELP_CONTRACT_VERSION_V1) {\n throw new Error(\"contractVersion is unsupported.\");\n }\n if (!CONTEXTUAL_HELP_KINDS_V1.includes(value.kind)) {\n throw new Error(\"kind is unsupported.\");\n }\n requireOpaqueId(value.moduleId, \"moduleId\");\n requireSemver(value.moduleVersion, \"moduleVersion\");\n requireSemver(value.manifestVersion, \"manifestVersion\");\n requireOpaqueId(value.helpId, \"helpId\");\n}\n\nexport function assertValidGuardianVoiceConsent(\n value: GuardianVoiceConsentV1,\n): void {\n if (value.schemaVersion !== \"1\") {\n throw new Error(\"schemaVersion must be 1.\");\n }\n requireOpaqueId(value.actorAccountId, \"actorAccountId\");\n requireOpaqueId(value.subjectAccountId, \"subjectAccountId\");\n requireSemver(value.policyVersion, \"policyVersion\");\n if (value.state !== \"granted\" && value.state !== \"withdrawn\") {\n throw new Error(\"state must be granted or withdrawn.\");\n }\n if (value.permittedProcessingRoute !== \"private-edge-only\") {\n throw new Error(\"permittedProcessingRoute must be private-edge-only.\");\n }\n requireIsoTimestamp(value.recordedAt, \"recordedAt\");\n}\n\nexport function assertValidContextualVoiceQuestionMetadata(\n value: ContextualVoiceQuestionMetadataV1,\n): void {\n assertValidContextualHelpIdentifier(value.help);\n if (!LOCALE.test(value.locale)) throw new Error(\"locale is invalid.\");\n if (!MEDIA_TYPE.test(value.mediaType)) throw new Error(\"mediaType is invalid.\");\n if (!Number.isInteger(value.durationMs) || value.durationMs < 1 || value.durationMs > 10_000) {\n throw new Error(\"durationMs must be between 1 and 10000.\");\n }\n if (!Number.isInteger(value.audioBytes) || value.audioBytes < 1 || value.audioBytes > 2_097_152) {\n throw new Error(\"audioBytes must be between 1 and 2097152.\");\n }\n if (value.assessmentEvidenceId !== undefined) {\n requireOpaqueId(value.assessmentEvidenceId, \"assessmentEvidenceId\");\n }\n}\n\nexport function assertValidVoiceHelpAvailability(\n value: VoiceHelpAvailabilityV1,\n): void {\n if (value.schemaVersion !== \"1\") throw new Error(\"schemaVersion must be 1.\");\n if (value.questionProcessingRoute !== \"private-edge-only\") {\n throw new Error(\"questionProcessingRoute must be private-edge-only.\");\n }\n if (value.guardianVoiceConsentRequired !== true) {\n throw new Error(\"guardianVoiceConsentRequired must remain true.\");\n }\n if (\n value.maximumRecordingDurationMs !== 10_000\n || value.maximumAudioBytes !== 2_097_152\n || value.rawAudioRetention !== \"request-memory-only\"\n || value.transcriptRetention !== \"request-memory-only\"\n ) {\n throw new Error(\"Voice limits and transient retention are immutable in version one.\");\n }\n if (value.microphoneAvailable !== (value.microphoneReason === \"available\")) {\n throw new Error(\"microphoneReason must match microphone availability.\");\n }\n}\n\nexport function assertValidCanonicalSpokenHelpDescriptor(\n value: CanonicalSpokenHelpDescriptorV1,\n): void {\n if (value.schemaVersion !== \"1\") throw new Error(\"schemaVersion must be 1.\");\n assertValidContextualHelpIdentifier(value.help);\n requireOpaqueId(value.canonicalTextId, \"canonicalTextId\");\n if (!SHA_256.test(value.authoritativeTextDigest)) {\n throw new Error(\"authoritativeTextDigest must be a SHA-256 digest.\");\n }\n if (!LOCALE.test(value.locale)) throw new Error(\"locale is invalid.\");\n requireOpaqueId(value.voiceProfile, \"voiceProfile\");\n requireSemver(value.pronunciationVersion, \"pronunciationVersion\");\n if (\n value.utteranceClass !== \"system-generic\"\n || value.sharingScope !== \"global\"\n || value.reuse !== \"exact-only\"\n || value.containsPersonalData !== false\n || value.containsLearnerContent !== false\n ) {\n throw new Error(\"Canonical spoken help must use global system-generic exact-only reuse.\");\n }\n}\n\nexport function assertValidContextualVoiceQuestionResult(\n value: ContextualVoiceQuestionResultV1,\n): void {\n if (value.schemaVersion !== \"1\") throw new Error(\"schemaVersion must be 1.\");\n assertValidContextualHelpIdentifier(value.help);\n if (!CONTEXTUAL_VOICE_INTENTS_V1.includes(value.intent)) {\n throw new Error(\"intent is unsupported.\");\n }\n if (value.transcriptRetention !== \"request-memory-only\") {\n throw new Error(\"transcriptRetention must be request-memory-only.\");\n }\n if (value.status !== \"resolved\" && value.status !== \"suggestions\" && value.status !== \"stopped\") {\n throw new Error(\"status is unsupported.\");\n }\n if (\n value.transientTranscript.length > 500\n || containsDisallowedControlCharacter(value.transientTranscript)\n ) {\n throw new Error(\"transientTranscript is invalid.\");\n }\n if (value.answer) {\n requireOpaqueId(value.answer.helpId, \"answer.helpId\");\n if (\n (value.answer.source !== \"module-documentation\"\n && value.answer.source !== \"assessment-evidence\"\n && value.answer.source !== \"authored-fallback\")\n ||\n value.answer.text.length === 0\n || value.answer.text.length > 800\n || containsDisallowedControlCharacter(value.answer.text)\n ) {\n throw new Error(\"answer.text is invalid.\");\n }\n }\n if (value.suggestedActions.some(\n (action) => !CONTEXTUAL_VOICE_SUGGESTED_ACTIONS_V1.includes(action),\n )) {\n throw new Error(\"suggestedActions contains an unsupported action.\");\n }\n if (\n value.mayAssignScore !== false\n || value.mayAwardReward !== false\n || value.mayPublish !== false\n || value.mayControlHardware !== false\n ) {\n throw new Error(\"mayAssignScore, reward, publish and hardware authority must remain false.\");\n }\n}\n","/** Versioned, infrastructure-neutral contracts for Guardian-approved static projects. */\nexport const STATIC_PROJECT_PUBLISHING_CONTRACT_VERSION_V1 = \"1.0.0\" as const;\nexport const STATIC_PROJECT_SCANNER_VERSION_V1 = \"junior-coder-static-scan-v1\" as const;\nexport const STATIC_PROJECT_APPROVAL_STATEMENT_VERSION_V1 =\n \"guardian-static-publication-v1\" as const;\nexport const STATIC_PROJECT_DEFAULT_LIFETIME_DAYS_V1 = 90 as const;\nexport const STATIC_PROJECT_MAX_SOURCE_CHARACTERS_V1 = 8_000 as const;\n\nexport const STATIC_PROJECT_SAFETY_CHECK_IDS_V1 = [\n \"allow-listed-source\",\n \"no-personal-details\",\n \"no-external-network\",\n \"no-executable-markup\",\n \"no-transmitting-forms\",\n \"no-uploads-or-embeds\",\n \"no-trackers-or-advertising\",\n \"no-account-identifiers\",\n] as const;\n\nexport type StaticProjectSafetyCheckIdV1 =\n (typeof STATIC_PROJECT_SAFETY_CHECK_IDS_V1)[number];\n\nexport type StaticProjectModuleSlugV1 =\n | \"adventure-mission-planner\"\n | \"creature-care-dashboard\"\n | \"robot-mission-control\";\n\nexport interface StaticProjectSafetyCheckV1 {\n id: StaticProjectSafetyCheckIdV1;\n passed: true;\n}\n\n/** Evidence emitted by the deterministic scanner before adult review. */\nexport interface StaticProjectSafetyScanV1 {\n schemaVersion: \"1\";\n scannerVersion: typeof STATIC_PROJECT_SCANNER_VERSION_V1;\n passed: true;\n checks: StaticProjectSafetyCheckV1[];\n}\n\nexport interface AdventureMissionPlannerSafeRenderV1 {\n kind: \"adventure-mission-planner\";\n heading: \"Moonbase Missions\" | \"Forest Rescue Plans\" | \"Ocean Quest Board\";\n missions: {\n title: \"Find the moon crystal\" | \"Guide the lost firefly\" | \"Map the coral garden\";\n day: \"Saturday\" | \"Sunday\" | \"School holiday\";\n }[];\n validationMessage: \"Choose a day\" | \"Add a mission title\" | \"Mission ready!\";\n savedAcrossRestart: true;\n accessibleSummaryEnabled: true;\n}\n\nexport interface CreatureCareDashboardSafeRenderV1 {\n kind: \"creature-care-dashboard\";\n creature: \"Moon Moth\" | \"Cloud Cat\" | \"Pebble Dragon\";\n status: \"Resting\" | \"Ready to play\" | \"Snack time\";\n timerSeconds: 5 | 10 | 15;\n layout: \"single\" | \"cosy-grid\" | \"wide-grid\";\n reducedMotion: true;\n}\n\nexport interface RobotMissionControlSafeRenderV1 {\n kind: \"robot-mission-control\";\n command: \"scan\" | \"hold-position\" | \"return-to-base\";\n safetyConfirmed: true;\n telemetryRate: 1 | 2 | 4;\n chartMode: \"line\" | \"bars\" | \"text-only\";\n serialSimulation: true;\n state: \"SCANNING\" | \"HOLDING\" | \"RETURNING\";\n}\n\n/** The complete public render allow-list. Learner source is never a render model. */\nexport type StaticProjectSafeRenderV1 =\n | AdventureMissionPlannerSafeRenderV1\n | CreatureCareDashboardSafeRenderV1\n | RobotMissionControlSafeRenderV1;\n\n/** Immutable private snapshot awaiting an adult's exact-hash approval. */\nexport interface StaticProjectSnapshotV1 {\n schemaVersion: \"1\";\n contractVersion: typeof STATIC_PROJECT_PUBLISHING_CONTRACT_VERSION_V1;\n snapshotId: string;\n subjectAccountId: string;\n moduleId: string;\n moduleSlug: StaticProjectModuleSlugV1;\n moduleVersion: string;\n missionId: string;\n sourceDigest: string;\n snapshotDigest: string;\n sourceCharacterCount: number;\n assessmentScore: number;\n mandatorySafetyPassed: true;\n scan: StaticProjectSafetyScanV1;\n renderModel: StaticProjectSafeRenderV1;\n state: \"pending-review\";\n createdAt: string;\n}\n\n/** Adult approval is evidence only and cannot mutate the reviewed snapshot. */\nexport interface StaticProjectGuardianApprovalV1 {\n schemaVersion: \"1\";\n approvalId: string;\n snapshotId: string;\n snapshotDigest: string;\n guardianActorAccountId: string;\n statementVersion: typeof STATIC_PROJECT_APPROVAL_STATEMENT_VERSION_V1;\n approvedAt: string;\n}\n\n/** An unlisted public pointer whose lifecycle never changes the source snapshot. */\nexport interface StaticProjectPublicationV1 {\n schemaVersion: \"1\";\n publicationId: string;\n snapshotId: string;\n snapshotDigest: string;\n approvalId: string;\n randomSlug: string;\n publicUrl: string;\n state: \"published\" | \"expired\" | \"unpublished\";\n publishedAt: string;\n expiresAt: string;\n renewedAt?: string;\n unpublishedAt?: string;\n}\n\nexport type StaticProjectContractIssueV1 =\n | \"invalid-schema-version\"\n | \"invalid-contract-version\"\n | \"invalid-identifier\"\n | \"invalid-module\"\n | \"invalid-version\"\n | \"invalid-source-digest\"\n | \"invalid-snapshot-digest\"\n | \"invalid-source-size\"\n | \"assessment-score-incomplete\"\n | \"mandatory-safety-missing\"\n | \"scan-not-passed\"\n | \"scan-checks-incomplete\"\n | \"module-render-model-mismatch\"\n | \"unsafe-render-model\"\n | \"invalid-created-at\"\n | \"invalid-approval-statement\"\n | \"invalid-approved-at\"\n | \"invalid-random-slug\"\n | \"invalid-public-url\"\n | \"public-url-slug-mismatch\"\n | \"published-state-required\"\n | \"invalid-published-at\"\n | \"invalid-publication-expiry\"\n | \"invalid-lifecycle-timestamp\";\n\nconst DIGEST_PATTERN = /^sha256:[a-f0-9]{64}$/u;\nconst IDENTIFIER_PATTERN = /^(?:account|approval|publication|snapshot)_[A-Za-z0-9_-]{20,128}$/u;\nconst VERSION_PATTERN = /^[0-9]+\\.[0-9]+\\.[0-9]+(?:[-+][A-Za-z0-9.-]+)?$/u;\nconst RANDOM_SLUG_PATTERN = /^[A-Za-z0-9_-]{40,128}$/u;\n\nfunction validDate(value: string): boolean {\n return typeof value === \"string\" && Number.isFinite(Date.parse(value));\n}\n\nfunction allSafetyChecksPresent(scan: StaticProjectSafetyScanV1): boolean {\n if (!Array.isArray(scan.checks) || scan.checks.length !== STATIC_PROJECT_SAFETY_CHECK_IDS_V1.length) {\n return false;\n }\n const supplied = new Set(scan.checks.map((check) => check.id));\n return STATIC_PROJECT_SAFETY_CHECK_IDS_V1.every((id) => supplied.has(id))\n && scan.checks.every((check) => check.passed === true);\n}\n\nfunction safeAdventureRender(value: AdventureMissionPlannerSafeRenderV1): boolean {\n const headings = [\"Moonbase Missions\", \"Forest Rescue Plans\", \"Ocean Quest Board\"];\n const titles = [\"Find the moon crystal\", \"Guide the lost firefly\", \"Map the coral garden\"];\n const days = [\"Saturday\", \"Sunday\", \"School holiday\"];\n const messages = [\"Choose a day\", \"Add a mission title\", \"Mission ready!\"];\n return headings.includes(value.heading)\n && Array.isArray(value.missions)\n && value.missions.length >= 1\n && value.missions.length <= 3\n && value.missions.every((mission) => titles.includes(mission.title) && days.includes(mission.day))\n && messages.includes(value.validationMessage)\n && value.savedAcrossRestart === true\n && value.accessibleSummaryEnabled === true;\n}\n\nfunction safeCreatureRender(value: CreatureCareDashboardSafeRenderV1): boolean {\n return [\"Moon Moth\", \"Cloud Cat\", \"Pebble Dragon\"].includes(value.creature)\n && [\"Resting\", \"Ready to play\", \"Snack time\"].includes(value.status)\n && [5, 10, 15].includes(value.timerSeconds)\n && [\"single\", \"cosy-grid\", \"wide-grid\"].includes(value.layout)\n && value.reducedMotion === true;\n}\n\nfunction safeRobotRender(value: RobotMissionControlSafeRenderV1): boolean {\n return [\"scan\", \"hold-position\", \"return-to-base\"].includes(value.command)\n && value.safetyConfirmed === true\n && [1, 2, 4].includes(value.telemetryRate)\n && [\"line\", \"bars\", \"text-only\"].includes(value.chartMode)\n && value.serialSimulation === true\n && [\"SCANNING\", \"HOLDING\", \"RETURNING\"].includes(value.state);\n}\n\n/** Validate a snapshot without throwing so authoring and adapters can show every issue. */\nexport function validateStaticProjectSnapshot(\n value: StaticProjectSnapshotV1,\n): StaticProjectContractIssueV1[] {\n const issues: StaticProjectContractIssueV1[] = [];\n if (value.schemaVersion !== \"1\") issues.push(\"invalid-schema-version\");\n if (value.contractVersion !== STATIC_PROJECT_PUBLISHING_CONTRACT_VERSION_V1) {\n issues.push(\"invalid-contract-version\");\n }\n if (!IDENTIFIER_PATTERN.test(value.snapshotId) || !IDENTIFIER_PATTERN.test(value.subjectAccountId)) {\n issues.push(\"invalid-identifier\");\n }\n if (!value.moduleId.startsWith(\"junior-coder.\") || value.moduleId !== `junior-coder.${value.moduleSlug}`) {\n issues.push(\"invalid-module\");\n }\n if (!VERSION_PATTERN.test(value.moduleVersion)) issues.push(\"invalid-version\");\n if (!DIGEST_PATTERN.test(value.sourceDigest)) issues.push(\"invalid-source-digest\");\n if (!DIGEST_PATTERN.test(value.snapshotDigest)) issues.push(\"invalid-snapshot-digest\");\n if (!Number.isInteger(value.sourceCharacterCount)\n || value.sourceCharacterCount < 1\n || value.sourceCharacterCount > STATIC_PROJECT_MAX_SOURCE_CHARACTERS_V1) {\n issues.push(\"invalid-source-size\");\n }\n if (!Number.isInteger(value.assessmentScore)\n || value.assessmentScore < 80\n || value.assessmentScore > 100) {\n issues.push(\"assessment-score-incomplete\");\n }\n if (value.mandatorySafetyPassed !== true) issues.push(\"mandatory-safety-missing\");\n if (value.scan?.passed !== true || value.scan?.scannerVersion !== STATIC_PROJECT_SCANNER_VERSION_V1) {\n issues.push(\"scan-not-passed\");\n }\n if (!value.scan || !allSafetyChecksPresent(value.scan)) issues.push(\"scan-checks-incomplete\");\n if (value.moduleSlug !== value.renderModel?.kind) issues.push(\"module-render-model-mismatch\");\n const renderSafe = value.renderModel?.kind === \"adventure-mission-planner\"\n ? safeAdventureRender(value.renderModel)\n : value.renderModel?.kind === \"creature-care-dashboard\"\n ? safeCreatureRender(value.renderModel)\n : value.renderModel?.kind === \"robot-mission-control\"\n ? safeRobotRender(value.renderModel)\n : false;\n if (!renderSafe) issues.push(\"unsafe-render-model\");\n if (value.state !== \"pending-review\" || !validDate(value.createdAt)) issues.push(\"invalid-created-at\");\n return [...new Set(issues)];\n}\n\n/** Fail closed when a persistence or publishing adapter constructs an invalid snapshot. */\nexport function assertValidStaticProjectSnapshot(value: StaticProjectSnapshotV1): void {\n const issues = validateStaticProjectSnapshot(value);\n if (issues.length > 0) throw new Error(`Invalid static project snapshot: ${issues.join(\", \")}`);\n}\n\nexport function validateStaticProjectGuardianApproval(\n value: StaticProjectGuardianApprovalV1,\n): StaticProjectContractIssueV1[] {\n const issues: StaticProjectContractIssueV1[] = [];\n if (value.schemaVersion !== \"1\") issues.push(\"invalid-schema-version\");\n if (!IDENTIFIER_PATTERN.test(value.approvalId)\n || !IDENTIFIER_PATTERN.test(value.snapshotId)\n || !IDENTIFIER_PATTERN.test(value.guardianActorAccountId)) {\n issues.push(\"invalid-identifier\");\n }\n if (!DIGEST_PATTERN.test(value.snapshotDigest)) issues.push(\"invalid-snapshot-digest\");\n if (value.statementVersion !== STATIC_PROJECT_APPROVAL_STATEMENT_VERSION_V1) {\n issues.push(\"invalid-approval-statement\");\n }\n if (!validDate(value.approvedAt)) issues.push(\"invalid-approved-at\");\n return [...new Set(issues)];\n}\n\nexport function assertValidStaticProjectGuardianApproval(\n value: StaticProjectGuardianApprovalV1,\n): void {\n const issues = validateStaticProjectGuardianApproval(value);\n if (issues.length > 0) throw new Error(`Invalid static project approval: ${issues.join(\", \")}`);\n}\n\nexport function validateStaticProjectPublication(\n value: StaticProjectPublicationV1,\n): StaticProjectContractIssueV1[] {\n const issues: StaticProjectContractIssueV1[] = [];\n if (value.schemaVersion !== \"1\") issues.push(\"invalid-schema-version\");\n if (!IDENTIFIER_PATTERN.test(value.publicationId)\n || !IDENTIFIER_PATTERN.test(value.snapshotId)\n || !IDENTIFIER_PATTERN.test(value.approvalId)) {\n issues.push(\"invalid-identifier\");\n }\n if (!DIGEST_PATTERN.test(value.snapshotDigest)) issues.push(\"invalid-snapshot-digest\");\n if (!RANDOM_SLUG_PATTERN.test(value.randomSlug)) issues.push(\"invalid-random-slug\");\n let parsedUrl: URL | undefined;\n try {\n parsedUrl = new URL(value.publicUrl);\n } catch {\n parsedUrl = undefined;\n }\n if (!parsedUrl || parsedUrl.protocol !== \"https:\" || parsedUrl.username || parsedUrl.password) {\n issues.push(\"invalid-public-url\");\n }\n if (!parsedUrl?.pathname.endsWith(`/${value.randomSlug}`)) issues.push(\"public-url-slug-mismatch\");\n if (value.state !== \"published\") issues.push(\"published-state-required\");\n if (!validDate(value.publishedAt)) issues.push(\"invalid-published-at\");\n if (!validDate(value.expiresAt)\n || (validDate(value.publishedAt) && Date.parse(value.expiresAt) <= Date.parse(value.publishedAt))) {\n issues.push(\"invalid-publication-expiry\");\n }\n if ((value.renewedAt !== undefined && !validDate(value.renewedAt))\n || (value.unpublishedAt !== undefined && !validDate(value.unpublishedAt))) {\n issues.push(\"invalid-lifecycle-timestamp\");\n }\n return [...new Set(issues)];\n}\n\nexport function assertValidStaticProjectPublication(value: StaticProjectPublicationV1): void {\n const issues = validateStaticProjectPublication(value);\n if (issues.length > 0) throw new Error(`Invalid static project publication: ${issues.join(\", \")}`);\n}\n","import type {\n ExternalLearningContentReferenceV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n LearningValidationIssueV1,\n} from \"./contracts.js\";\nimport { validateAssessmentRubric } from \"./rubric-validation.js\";\n\nconst CANONICAL_TOKEN_SUBUNITS = /^(0|[1-9][0-9]*)$/u;\nconst EXACT_PACKAGE_NAME = /^@plasius\\/[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/u;\nconst EXACT_SEMVER = /^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$/u;\nconst EXPORT_NAME = /^[A-Za-z_$][A-Za-z0-9_$]*$/u;\nconst CONTENT_SCHEMA_VERSION = /^(0|[1-9][0-9]*)$/u;\nconst SHA256 = /^[a-f0-9]{64}$/u;\n\n/** Runtime guard for digest-pinned external learning content references. */\nexport function isExternalLearningContentReferenceV1(\n value: unknown,\n): value is ExternalLearningContentReferenceV1 {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as Partial<ExternalLearningContentReferenceV1>;\n return (\n Object.keys(value).length === 5\n && typeof candidate.packageName === \"string\"\n && EXACT_PACKAGE_NAME.test(candidate.packageName)\n && typeof candidate.packageVersion === \"string\"\n && EXACT_SEMVER.test(candidate.packageVersion)\n && typeof candidate.exportName === \"string\"\n && EXPORT_NAME.test(candidate.exportName)\n && typeof candidate.schemaVersion === \"string\"\n && CONTENT_SCHEMA_VERSION.test(candidate.schemaVersion)\n && typeof candidate.sha256 === \"string\"\n && SHA256.test(candidate.sha256)\n );\n}\n\nfunction issue(\n code: LearningValidationIssueV1[\"code\"],\n message: string,\n path: string,\n moduleId?: string,\n): LearningValidationIssueV1 {\n return { code, message, path, ...(moduleId ? { moduleId } : {}) };\n}\n\nfunction validateModule(\n module: LearningModuleVersionV1,\n moduleIndex: number,\n): LearningValidationIssueV1[] {\n const issues: LearningValidationIssueV1[] = [];\n const base = `modules[${moduleIndex}]`;\n\n if (!module.selfContained) {\n issues.push(\n issue(\n \"module-not-self-contained\",\n \"Every sellable module must be self-contained.\",\n `${base}.selfContained`,\n module.id,\n ),\n );\n }\n\n if (module.prerequisiteModuleIds.length > 0) {\n issues.push(\n issue(\n \"paid-prerequisite\",\n \"A sellable module cannot require another paid module.\",\n `${base}.prerequisiteModuleIds`,\n module.id,\n ),\n );\n }\n\n if (\n module.materials.learner.length === 0 ||\n module.materials.facilitator.length === 0\n ) {\n issues.push(\n issue(\n \"missing-materials\",\n \"Learner and facilitator material manifests are both required.\",\n `${base}.materials`,\n module.id,\n ),\n );\n }\n\n if (module.materials.learner.some((material) => material.audience !== \"learner\")) {\n issues.push(\n issue(\n \"facilitator-material-leak\",\n \"Learner material contains a facilitator-only record.\",\n `${base}.materials.learner`,\n module.id,\n ),\n );\n }\n\n if (\n module.materials.facilitator.some(\n (material) => material.audience !== \"facilitator\",\n )\n ) {\n issues.push(\n issue(\n \"learner-material-leak\",\n \"Facilitator material contains a learner record.\",\n `${base}.materials.facilitator`,\n module.id,\n ),\n );\n }\n\n if (!CANONICAL_TOKEN_SUBUNITS.test(module.pricing.tokenSubunits)) {\n issues.push(\n issue(\n \"invalid-token-subunits\",\n \"Token subunits must be a canonical non-negative base-10 integer string.\",\n `${base}.pricing.tokenSubunits`,\n module.id,\n ),\n );\n }\n\n const referencePrice = module.pricing.referencePrice;\n if (\n referencePrice\n && (\n referencePrice.currency !== \"GBP\"\n || !CANONICAL_TOKEN_SUBUNITS.test(referencePrice.minorUnits)\n || referencePrice.basis !== \"nominal-reference\"\n || referencePrice.cashRedemptionAllowed !== false\n )\n ) {\n issues.push(\n issue(\n \"invalid-reference-price\",\n \"Reference prices must use canonical GBP minor units, the nominal reference basis and prohibit cash redemption.\",\n `${base}.pricing.referencePrice`,\n module.id,\n ),\n );\n }\n\n issues.push(\n ...validateAssessmentRubric(module.assessment, `${base}.assessment`, module.id),\n );\n\n if (module.hardware.mode === \"physical-first\" && module.hardware.items.length === 0) {\n issues.push(\n issue(\n \"missing-hardware-items\",\n \"Physical-first modules require an exact hardware item list.\",\n `${base}.hardware.items`,\n module.id,\n ),\n );\n }\n\n if (\n module.agents.some(\n (agent) =>\n agent.mayAssignScore !== false ||\n agent.mayAwardReward !== false ||\n agent.mayPublish !== false ||\n agent.mayControlHardware !== false,\n )\n ) {\n issues.push(\n issue(\n \"invalid-agent-authority\",\n \"Module agents cannot own scores, rewards, publishing or hardware control.\",\n `${base}.agents`,\n module.id,\n ),\n );\n }\n\n if (module.missions.length === 0) {\n issues.push(\n issue(\n \"missing-missions\",\n \"A module requires at least one mission.\",\n `${base}.missions`,\n module.id,\n ),\n );\n }\n\n\n const externalContent = module.externalContent;\n if (\n externalContent\n && !isExternalLearningContentReferenceV1(externalContent)\n ) {\n issues.push(\n issue(\n \"invalid-external-content-reference\",\n \"External content must use an exact @plasius package, stable semantic version, named export, schema version and lower-case SHA-256 digest.\",\n `${base}.externalContent`,\n module.id,\n ),\n );\n }\n\n return issues;\n}\n\n/** Return every catalog issue without throwing, suitable for authoring tools. */\nexport function validateLearningPath(\n path: LearningPathVersionV1,\n): LearningValidationIssueV1[] {\n const issues: LearningValidationIssueV1[] = [];\n const moduleIds = new Set<string>();\n const moduleSlugs = new Set<string>();\n\n for (const [index, module] of path.modules.entries()) {\n if (moduleIds.has(module.id)) {\n issues.push(\n issue(\n \"duplicate-module-id\",\n `Duplicate module id ${module.id}.`,\n `modules[${index}].id`,\n module.id,\n ),\n );\n }\n moduleIds.add(module.id);\n\n if (moduleSlugs.has(module.slug)) {\n issues.push(\n issue(\n \"duplicate-module-slug\",\n `Duplicate module slug ${module.slug}.`,\n `modules[${index}].slug`,\n module.id,\n ),\n );\n }\n moduleSlugs.add(module.slug);\n issues.push(...validateModule(module, index));\n }\n\n return issues;\n}\n\n/** Fail fast when a path is not safe to publish or consume. */\nexport function assertValidLearningPath(path: LearningPathVersionV1): void {\n const issues = validateLearningPath(path);\n if (issues.length === 0) return;\n\n const summary = issues\n .map((entry) => `${entry.code} at ${entry.path}: ${entry.message}`)\n .join(\"\\n\");\n throw new Error(`Invalid learning path:\\n${summary}`);\n}\n\nexport { validateAssessmentRubric } from \"./rubric-validation.js\";\nexport {\n ADVENTURE_MISSION_PLANNER_MISSION_ONE_AUTHORING_V1,\n BEACON_BOT_MISSION_ONE_AUTHORING_V1,\n CREATURE_CARE_DASHBOARD_MISSION_ONE_AUTHORING_V1,\n DANCE_ROVER_MISSION_ONE_AUTHORING_V1,\n JUNIOR_CODER_MISSION_STAGE_ORDER_V1,\n METEOR_SHIELD_MISSION_ONE_AUTHORING_V1,\n OBSTACLE_EXPLORER_MISSION_ONE_AUTHORING_V1,\n PADDLE_PULSE_MISSION_ONE_AUTHORING_V1,\n PIXEL_TRAIL_CHALLENGE_MISSION_ONE_AUTHORING_V1,\n RAINBOW_RESCUE_ROVER_MISSION_ONE_AUTHORING_V1,\n RESCUE_CREW_COMMANDER_MISSION_ONE_AUTHORING_V1,\n ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1,\n ROBOT_MISSION_CONTROL_MISSION_ONE_AUTHORING_V1,\n ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1,\n SERVO_CREATURE_MISSION_ONE_AUTHORING_V1,\n SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1,\n STAR_DEFENDER_SQUADRON_MISSION_ONE_AUTHORING_V1,\n VIBE_BUG_DETECTIVE_MISSION_ONE_AUTHORING_V1,\n VIBE_GAME_REMIX_LAB_MISSION_ONE_AUTHORING_V1,\n VIBE_IDEA_STUDIO_MISSION_ONE_AUTHORING_V1,\n assertValidMissionAuthoringBundle,\n validateMissionAuthoringBundle,\n} from \"./mission-authoring.js\";\n"],"mappings":"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","names":["rubric","mission","mission","stage","mission","module"]}
|
|
1
|
+
{"version":3,"sources":["../src/assessment.ts","../src/catalog.ts","../src/course-progress.ts","../src/course-suggestions.ts","../src/contextual-help.ts","../src/publishing.ts","../src/validation.ts"],"sourcesContent":["import type {\n AssessmentCheckResultV1,\n AssessmentResultV1,\n AssessmentRubricV1,\n ScoreBandV1,\n} from \"./contracts.js\";\n\nfunction scoreBand(score: number): ScoreBandV1 {\n if (score >= 95) return \"mastered\";\n if (score >= 80) return \"mission-complete\";\n if (score >= 60) return \"nearly-there\";\n return \"keep-exploring\";\n}\n\n/**\n * Calculate a score solely from rubric criteria and objective check results.\n * Missing criteria fail closed; unknown and duplicate result IDs are rejected.\n */\nexport function calculateAssessment(\n rubric: AssessmentRubricV1,\n results: AssessmentCheckResultV1[],\n): AssessmentResultV1 {\n const knownIds = new Set(rubric.criteria.map((criterion) => criterion.id));\n const resultById = new Map<string, AssessmentCheckResultV1>();\n\n for (const result of results) {\n if (!knownIds.has(result.criterionId)) {\n throw new Error(`Unknown assessment criterion: ${result.criterionId}`);\n }\n if (resultById.has(result.criterionId)) {\n throw new Error(`Duplicate assessment result: ${result.criterionId}`);\n }\n resultById.set(result.criterionId, result);\n }\n\n let score = 0;\n const passedCriterionIds: string[] = [];\n const failedCriterionIds: string[] = [];\n const failedMandatoryCriterionIds: string[] = [];\n\n for (const criterion of rubric.criteria) {\n const passed = resultById.get(criterion.id)?.passed === true;\n if (passed) {\n score += criterion.points;\n passedCriterionIds.push(criterion.id);\n continue;\n }\n\n failedCriterionIds.push(criterion.id);\n if (criterion.mandatory) failedMandatoryCriterionIds.push(criterion.id);\n }\n\n return {\n score,\n band: scoreBand(score),\n completed:\n score >= rubric.completionScore && failedMandatoryCriterionIds.length === 0,\n passedCriterionIds,\n failedCriterionIds,\n failedMandatoryCriterionIds,\n };\n}\n","import type {\n AssessmentRubricV1,\n CourseMaterialsManifestV1,\n HardwareItemV1,\n HardwareRequirementManifestV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n MissionV1,\n ModuleAgentDefinitionV1,\n ModuleCategoryV1,\n} from \"./contracts.js\";\n\nconst SOFTWARE_HARDWARE: HardwareRequirementManifestV1 = {\n requirementsVersion: \"1.0.0\",\n mode: \"none\",\n hardwareIncluded: false,\n simulatorAvailable: true,\n verificationStatus: \"not-applicable\",\n publicSaleBlocked: false,\n preparationMinutes: 0,\n items: [],\n warnings: [\"No specialist physical equipment is required.\"],\n supportedPlatforms: [\"Current Chromium, Firefox or Safari browser\"],\n};\n\nconst CORE_ROBOT_ITEMS: HardwareItemV1[] = [\n {\n id: \"pico-2-w\",\n label: \"Raspberry Pi Pico 2 W\",\n quantity: 1,\n requirement: \"required\",\n exactSpecification: \"Raspberry Pi Pico 2 W with soldered headers\",\n adultOnly: false,\n stage: \"core\",\n },\n {\n id: \"breadboard\",\n label: \"Solderless breadboard\",\n quantity: 1,\n requirement: \"required\",\n exactSpecification: \"400-point or larger solderless breadboard\",\n adultOnly: false,\n stage: \"core\",\n },\n {\n id: \"usb-data-cable\",\n label: \"USB data cable\",\n quantity: 1,\n requirement: \"required\",\n exactSpecification: \"Data-capable USB cable compatible with the Pico 2 W\",\n adultOnly: false,\n stage: \"core\",\n },\n {\n id: \"jumper-wires\",\n label: \"Jumper wires\",\n quantity: 12,\n requirement: \"required\",\n exactSpecification: \"Insulated male-to-male breadboard jumper wires\",\n adultOnly: false,\n stage: \"core\",\n },\n];\n\nconst ROBOT_WARNING =\n \"Physical publication is blocked until every listed actuator, driver, sensor and power configuration passes an adult bench test.\";\n\nfunction physicalHardware(\n requirementsVersion: string,\n preparationMinutes: number,\n items: HardwareItemV1[],\n platforms: string[],\n): HardwareRequirementManifestV1 {\n return {\n requirementsVersion,\n mode: \"physical-first\",\n hardwareIncluded: false,\n simulatorAvailable: true,\n verificationStatus: \"pending-bench-test\",\n publicSaleBlocked: true,\n preparationMinutes,\n items: [...CORE_ROBOT_ITEMS, ...items],\n warnings: [ROBOT_WARNING, \"An adult must disconnect actuator power before changing wiring.\"],\n supportedPlatforms: platforms,\n };\n}\n\nfunction materials(slug: string, robot = false): CourseMaterialsManifestV1 {\n return {\n version: \"1.0.0\",\n learner: [\n { id: `${slug}-child-guide`, kind: \"child-guide\", audience: \"learner\" },\n { id: `${slug}-mission-cards`, kind: \"mission-cards\", audience: \"learner\" },\n { id: `${slug}-starter`, kind: \"starter-project\", audience: \"learner\" },\n { id: `${slug}-assets`, kind: \"asset-pack\", audience: \"learner\" },\n { id: `${slug}-printable`, kind: \"printable\", audience: \"learner\" },\n ],\n facilitator: [\n { id: `${slug}-facilitator`, kind: \"facilitator-guide\", audience: \"facilitator\" },\n { id: `${slug}-answers`, kind: \"answer-key\", audience: \"facilitator\" },\n { id: `${slug}-tests`, kind: \"protected-tests\", audience: \"facilitator\" },\n ...(robot\n ? [\n {\n id: `${slug}-hardware`,\n kind: \"hardware-guide\" as const,\n audience: \"facilitator\" as const,\n },\n ]\n : []),\n ],\n };\n}\n\nfunction agents(slug: string): ModuleAgentDefinitionV1[] {\n return [\n {\n id: `${slug}-assessor`,\n role: \"assessor\",\n evidenceBound: true,\n maySuggestSingleFix: false,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n {\n id: `${slug}-debugger`,\n role: \"debugger\",\n evidenceBound: true,\n maySuggestSingleFix: false,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n {\n id: `${slug}-fix-guide`,\n role: \"fix-guide\",\n evidenceBound: true,\n maySuggestSingleFix: true,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n {\n id: `${slug}-concept-explainer`,\n role: \"concept-explainer\",\n evidenceBound: true,\n maySuggestSingleFix: false,\n mayAssignScore: false,\n mayAwardReward: false,\n mayPublish: false,\n mayControlHardware: false,\n },\n ];\n}\n\nfunction rubric(slug: string): AssessmentRubricV1 {\n return {\n version: \"1.0.0\",\n completionScore: 80,\n criteria: [\n {\n id: `${slug}-build`,\n label: \"The project is structurally valid and starts successfully.\",\n dimension: \"structure\",\n points: 20,\n mandatory: true,\n visibility: \"visible\",\n },\n {\n id: `${slug}-goal-one`,\n label: \"The first published project behaviour works.\",\n dimension: \"behaviour\",\n points: 20,\n mandatory: true,\n visibility: \"visible\",\n },\n {\n id: `${slug}-goal-two`,\n label: \"The second published project behaviour works.\",\n dimension: \"behaviour\",\n points: 20,\n mandatory: true,\n visibility: \"visible\",\n },\n {\n id: `${slug}-goal-three`,\n label: \"The complete project challenge works.\",\n dimension: \"behaviour\",\n points: 10,\n mandatory: false,\n visibility: \"visible\",\n },\n {\n id: `${slug}-edge-one`,\n label: \"The project handles its first protected edge case.\",\n dimension: \"resilience\",\n points: 10,\n mandatory: false,\n visibility: \"protected\",\n },\n {\n id: `${slug}-edge-two`,\n label: \"The project handles its second protected edge case.\",\n dimension: \"resilience\",\n points: 10,\n mandatory: false,\n visibility: \"protected\",\n },\n {\n id: `${slug}-safety`,\n label: \"The project obeys its mandatory safety and privacy boundary.\",\n dimension: \"safety\",\n points: 10,\n mandatory: true,\n visibility: \"visible\",\n },\n ],\n };\n}\n\nfunction mission(\n slug: string,\n index: number,\n title: string,\n concepts: string[],\n statement: string,\n sideAdventure: string,\n): MissionV1 {\n return {\n id: `${slug}-mission-${index}`,\n title,\n estimatedMinutes: index === 4 ? 25 : 20,\n concepts,\n goals: [\n {\n id: `${slug}-goal-${index}`,\n statement,\n evidence: \"assessment\",\n },\n ],\n sideAdventure,\n };\n}\n\ninterface ModuleInput {\n slug: string;\n title: string;\n category: ModuleCategoryV1;\n summary: string;\n tools: string[];\n concepts: string[];\n tokenSubunits: string;\n hosting?: boolean;\n hardware?: HardwareRequirementManifestV1;\n missionTitles: [string, string, string, string];\n}\n\nfunction module(input: ModuleInput): LearningModuleVersionV1 {\n const isRobot = input.category === \"robot\";\n return {\n id: `junior-coder.${input.slug}`,\n slug: input.slug,\n version: \"1.0.0\",\n contentRevision: \"2026-07-21.1\",\n title: input.title,\n category: input.category,\n summary: input.summary,\n estimatedMinutes: 90,\n tools: input.tools,\n concepts: input.concepts,\n selfContained: true,\n prerequisiteModuleIds: [],\n pricing: {\n state: \"pilot-grant-only\",\n tokenSubunits: input.tokenSubunits,\n includesMaterials: true,\n includesAssessmentRetries: true,\n includesAgents: true,\n includesHostingAllowance: input.hosting ?? false,\n },\n materials: materials(input.slug, isRobot),\n hardware: input.hardware ?? SOFTWARE_HARDWARE,\n missions: input.missionTitles.map((title, index) =>\n mission(\n input.slug,\n index + 1,\n title,\n input.concepts.slice(0, 3),\n `Complete ${title.toLocaleLowerCase(\"en-GB\")} and explain the observed result.`,\n `Invent one safe remix for ${title.toLocaleLowerCase(\"en-GB\")}.`,\n ),\n ),\n assessment: rubric(input.slug),\n agents: agents(input.slug),\n badges: [\n {\n id: `${input.slug}-mission-complete`,\n title: `${input.title} Champion`,\n evidence: \"module-score\",\n tradeable: false,\n tokenConvertible: false,\n },\n ...(isRobot\n ? [\n {\n id: `${input.slug}-physical-builder`,\n title: `${input.title} Physical Builder`,\n evidence: \"adult-physical-signoff\" as const,\n tradeable: false as const,\n tokenConvertible: false as const,\n },\n ]\n : []),\n ],\n };\n}\n\nconst modules: LearningModuleVersionV1[] = [\n module({\n slug: \"robot-maze-dash\",\n title: \"Robot Maze Dash\",\n category: \"game\",\n summary: \"Guide rescue robots through original mazes with visual programs and side-by-side text code.\",\n tools: [\"Visual blocks\", \"JavaScript view\", \"Python view\", \"C++ view\"],\n concepts: [\"sequence\", \"variables\", \"loops\", \"conditions\", \"functions\"],\n tokenSubunits: \"8000\",\n missionTitles: [\"Meet Your Robot\", \"Repeat the Rescue\", \"Choose the Safe Path\", \"Lost Robot Challenge\"],\n }),\n module({\n slug: \"road-hopper-rally\",\n title: \"Road Hopper Rally\",\n category: \"game\",\n summary: \"Build an original road-crossing game with changing lanes and rescue targets.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"events\", \"coordinates\", \"animation\", \"collision\", \"scoring\"],\n tokenSubunits: \"10000\",\n missionTitles: [\"Draw the Rescue Road\", \"Move the Hopper\", \"Add Moving Traffic\", \"Rally Challenge\"],\n }),\n module({\n slug: \"skywing-sprint\",\n title: \"Skywing Sprint\",\n category: \"game\",\n summary: \"Fly a rescue craft through procedurally changing sky gates.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"velocity\", \"gravity\", \"timing\", \"randomness\", \"obstacles\"],\n tokenSubunits: \"10000\",\n missionTitles: [\"Give Skywing Lift\", \"Build a Gate\", \"Score a Safe Flight\", \"Sky Sprint Challenge\"],\n }),\n module({\n slug: \"paddle-pulse\",\n title: \"Paddle Pulse\",\n category: \"game\",\n summary: \"Create a paddle-and-energy-ball arcade game with levels and original power-ups.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"angles\", \"collision response\", \"levels\", \"power-ups\", \"state\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Move the Pulse Paddle\", \"Bounce the Energy Ball\", \"Build a Target Wall\", \"Power-Up Challenge\"],\n }),\n module({\n slug: \"meteor-shield\",\n title: \"Meteor Shield\",\n category: \"game\",\n summary: \"Protect rescue bases with careful targeting and limited shield energy.\",\n tools: [\"JavaScript\", \"Educational canvas API\"],\n concepts: [\"targeting\", \"projectiles\", \"timers\", \"waves\", \"resources\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Mark the Rescue Bases\", \"Launch a Shield\", \"Create Meteor Waves\", \"Last Base Challenge\"],\n }),\n module({\n slug: \"rescue-crew-commander\",\n title: \"Rescue Crew Commander\",\n category: \"game\",\n summary: \"Assign safe jobs, routes and priorities to a team of original helper creatures.\",\n tools: [\"Visual blocks\", \"JavaScript\"],\n concepts: [\"state machines\", \"routes\", \"priorities\", \"group behaviour\", \"debugging\"],\n tokenSubunits: \"14000\",\n missionTitles: [\"Meet the Rescue Crew\", \"Give a Crew Job\", \"Choose a Safe Route\", \"Commander Challenge\"],\n }),\n module({\n slug: \"pixel-trail-challenge\",\n title: \"Pixel Trail Challenge\",\n category: \"game\",\n summary: \"Use Python lists and grid movement to grow a safe energy trail.\",\n tools: [\"Python\", \"Pyodide\", \"Educational drawing API\"],\n concepts: [\"lists\", \"grid movement\", \"spawning\", \"collision\", \"score\"],\n tokenSubunits: \"10000\",\n missionTitles: [\"Move the Pixel\", \"Grow the Trail\", \"Place Energy Orbs\", \"Trail Challenge\"],\n }),\n module({\n slug: \"star-defender-squadron\",\n title: \"Star Defender Squadron\",\n category: \"game\",\n summary: \"Build a multi-level space-rescue finale with original entities and enemy patterns.\",\n tools: [\"Python\", \"JavaScript\", \"Educational drawing API\"],\n concepts: [\"entities\", \"projectiles\", \"patterns\", \"health\", \"levels\"],\n tokenSubunits: \"16000\",\n missionTitles: [\"Launch the Squadron\", \"Build a Rescue Wave\", \"Add Shields and Health\", \"Star Defender Finale\"],\n }),\n module({\n slug: \"beacon-bot\",\n title: \"Beacon Bot\",\n category: \"robot\",\n summary: \"Program visible and infrared rescue signals with C++ and a Pico 2 W.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"digital output\", \"timing\", \"functions\", \"signals\", \"sensor input\"],\n tokenSubunits: \"8000\",\n hardware: physicalHardware(\"1.0.0\", 30, [\n { id: \"led-pack\", label: \"Visible LEDs\", quantity: 3, requirement: \"required\", exactSpecification: \"5 mm low-current red, amber and green LEDs\", adultOnly: false, stage: \"core\" },\n { id: \"led-resistors\", label: \"LED current-limiting resistors\", quantity: 3, requirement: \"required\", exactSpecification: \"330 ohm, 0.25 W resistors\", adultOnly: false, stage: \"core\" },\n { id: \"ir-pair\", label: \"Infrared emitter and receiver\", quantity: 1, requirement: \"required\", exactSpecification: \"Matched 940 nm IR LED and 3.3 V-compatible digital receiver pair; exact reference model pending bench verification\", adultOnly: true, stage: \"sensor\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Blink a Rescue Signal\", \"Build a Signal Function\", \"Send an IR Message\", \"Beacon Challenge\"],\n }),\n module({\n slug: \"servo-creature\",\n title: \"Servo Creature\",\n category: \"robot\",\n summary: \"Give a servo creature safe movements, moods and sensor reactions.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"PWM\", \"angles\", \"sequences\", \"limits\", \"interaction\"],\n tokenSubunits: \"10000\",\n hardware: physicalHardware(\"1.0.0\", 40, [\n { id: \"micro-servo\", label: \"Micro servo\", quantity: 1, requirement: \"required\", exactSpecification: \"3.3 V signal-compatible micro servo; exact reference model and external power arrangement pending bench verification\", adultOnly: true, stage: \"servo\" },\n { id: \"servo-power\", label: \"Servo power supply\", quantity: 1, requirement: \"required\", exactSpecification: \"Switched regulated supply sized for the verified servo, with common signal ground\", adultOnly: true, stage: \"servo\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Wake the Creature\", \"Make a Movement Sequence\", \"Choose a Mood\", \"Creature Show Challenge\"],\n }),\n module({\n slug: \"dance-rover\",\n title: \"Dance Rover\",\n category: \"robot\",\n summary: \"Build reusable movement functions and a fail-safe rover dance.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"motor direction\", \"PWM speed\", \"functions\", \"sequences\", \"emergency stop\"],\n tokenSubunits: \"14000\",\n hardware: physicalHardware(\"1.0.0\", 90, [\n { id: \"dual-motor-driver\", label: \"Dual motor driver\", quantity: 1, requirement: \"required\", exactSpecification: \"3.3 V logic-compatible dual H-bridge; exact reference model pending bench verification\", adultOnly: true, stage: \"rover\" },\n { id: \"geared-motors\", label: \"Matching geared motors\", quantity: 2, requirement: \"required\", exactSpecification: \"Matching low-voltage geared DC motors compatible with the verified driver and supply\", adultOnly: true, stage: \"rover\" },\n { id: \"rover-chassis\", label: \"Rover chassis set\", quantity: 1, requirement: \"required\", exactSpecification: \"Two-wheel chassis with matching wheels and caster or skid\", adultOnly: true, stage: \"rover\" },\n { id: \"motor-power\", label: \"Switched motor power supply\", quantity: 1, requirement: \"required\", exactSpecification: \"Fused or protected switched supply within verified driver and motor ratings\", adultOnly: true, stage: \"rover\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Lifted-Wheel Safety Test\", \"Drive and Turn\", \"Build Movement Functions\", \"Rover Dance Challenge\"],\n }),\n module({\n slug: \"obstacle-explorer\",\n title: \"Obstacle Explorer\",\n category: \"robot\",\n summary: \"Use IR sensing, state and watchdogs to navigate and stop safely.\",\n tools: [\"C++\", \"Pico 2 W\", \"Simulator\"],\n concepts: [\"booleans\", \"state\", \"navigation\", \"watchdogs\", \"fail-safe stop\"],\n tokenSubunits: \"14000\",\n hardware: physicalHardware(\"1.0.0\", 60, [\n { id: \"verified-rover\", label: \"Verified Dance Rover build\", quantity: 1, requirement: \"required\", exactSpecification: \"Bench-signed rover matching the published Dance Rover reference build\", adultOnly: true, stage: \"rover\" },\n { id: \"obstacle-sensors\", label: \"Digital IR obstacle sensors\", quantity: 2, requirement: \"required\", exactSpecification: \"3.3 V-compatible digital IR obstacle sensors; exact reference model pending bench verification\", adultOnly: true, stage: \"sensor\" },\n ], [\"Pico SDK on Raspberry Pi OS or supported desktop toolchain\"]),\n missionTitles: [\"Read an Obstacle\", \"Choose a Safe Response\", \"Add a Watchdog\", \"Explorer Maze Challenge\"],\n }),\n module({\n slug: \"rainbow-rescue-rover\",\n title: \"Rainbow Rescue Rover\",\n category: \"robot\",\n summary: \"Recognise local colour targets and send bounded serial commands to a safe rover.\",\n tools: [\"Python\", \"C++\", \"Pico 2 W\", \"Pi Zero 2 W\", \"Camera Module 3\", \"Simulator\"],\n concepts: [\"colour recognition\", \"coordinates\", \"serial protocol\", \"heartbeats\", \"integration\"],\n tokenSubunits: \"18000\",\n hardware: physicalHardware(\"1.0.0\", 120, [\n { id: \"verified-explorer\", label: \"Verified Obstacle Explorer build\", quantity: 1, requirement: \"required\", exactSpecification: \"Bench-signed rover matching the published Obstacle Explorer reference build\", adultOnly: true, stage: \"rover\" },\n { id: \"pi-zero-2-w\", label: \"Raspberry Pi Zero 2 W\", quantity: 1, requirement: \"required\", exactSpecification: \"Raspberry Pi Zero 2 W with supported Raspberry Pi OS image\", adultOnly: true, stage: \"camera\" },\n { id: \"camera-3\", label: \"Raspberry Pi Camera Module 3\", quantity: 1, requirement: \"required\", exactSpecification: \"Raspberry Pi Camera Module 3 with the correct Zero-series camera ribbon\", adultOnly: true, stage: \"camera\" },\n { id: \"pi-storage-power\", label: \"Pi storage and power\", quantity: 1, requirement: \"required\", exactSpecification: \"Supported microSD card and regulated Raspberry Pi power supply\", adultOnly: true, stage: \"camera\" },\n ], [\"Current Raspberry Pi OS\", \"Pico SDK\"]),\n missionTitles: [\"Find a Colour Target\", \"Report Left Centre or Right\", \"Send Safe Serial Commands\", \"Rainbow Rescue Challenge\"],\n }),\n module({\n slug: \"vibe-game-remix-lab\",\n title: \"Vibe Game Remix Lab\",\n category: \"vibe\",\n summary: \"Transform a supplied mini-game through structured, evidence-bound AI suggestions.\",\n tools: [\"Structured prompt builder\", \"Diff review\", \"JavaScript sandbox\"],\n concepts: [\"intent\", \"constraints\", \"diffs\", \"testing\", \"explanation\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Describe the Remix\", \"Constrain the Change\", \"Review One Diff\", \"Remix Challenge\"],\n }),\n module({\n slug: \"vibe-bug-detective\",\n title: \"Vibe Bug Detective\",\n category: \"vibe\",\n summary: \"Repair an intentionally broken project using assessment evidence and focused suggestions.\",\n tools: [\"Structured prompt builder\", \"Diff review\", \"Assessment runner\"],\n concepts: [\"diagnostics\", \"hypotheses\", \"minimal fixes\", \"regression tests\", \"reflection\"],\n tokenSubunits: \"12000\",\n missionTitles: [\"Read the Evidence\", \"Ask a Focused Question\", \"Inspect a Suggested Fix\", \"Regression Challenge\"],\n }),\n module({\n slug: \"vibe-idea-studio\",\n title: \"Vibe Idea Studio\",\n category: \"vibe\",\n summary: \"Turn a bounded original idea into goals, acceptance tests and a working prototype.\",\n tools: [\"Intent cards\", \"Structured prompt builder\", \"Diff review\", \"Sandbox\"],\n concepts: [\"goals\", \"acceptance tests\", \"iteration\", \"trade-offs\", \"explanation\"],\n tokenSubunits: \"16000\",\n missionTitles: [\"Shape the Idea\", \"Write Success Tests\", \"Build One Step\", \"Prototype Showcase\"],\n }),\n module({\n slug: \"adventure-mission-planner\",\n title: \"Adventure Mission Planner\",\n category: \"web-app\",\n summary: \"Build an accessible planner for fictional quests and activities.\",\n tools: [\"HTML\", \"CSS\", \"JavaScript\", \"Private preview\"],\n concepts: [\"semantic HTML\", \"forms\", \"validation\", \"arrays\", \"local persistence\"],\n tokenSubunits: \"10000\",\n hosting: true,\n missionTitles: [\"Make a Semantic Page\", \"Add a Mission Form\", \"Save Fictional Missions\", \"Accessible Planner Challenge\"],\n }),\n module({\n slug: \"creature-care-dashboard\",\n title: \"Creature Care Dashboard\",\n category: \"web-app\",\n summary: \"Create a responsive dashboard for a fictional digital creature.\",\n tools: [\"HTML\", \"CSS\", \"JavaScript\", \"Private preview\"],\n concepts: [\"components\", \"events\", \"timers\", \"status displays\", \"reduced motion\"],\n tokenSubunits: \"12000\",\n hosting: true,\n missionTitles: [\"Design the Creature Card\", \"Update Creature State\", \"Add a Safe Timer\", \"Care Dashboard Challenge\"],\n }),\n module({\n slug: \"robot-mission-control\",\n title: \"Robot Mission Control\",\n category: \"web-app\",\n summary: \"Build a simulated control and telemetry interface with safety confirmations.\",\n tools: [\"HTML\", \"CSS\", \"JavaScript\", \"Serial simulator\", \"Private preview\"],\n concepts: [\"commands\", \"state machines\", \"confirmations\", \"charts\", \"responsive controls\"],\n tokenSubunits: \"14000\",\n hosting: true,\n missionTitles: [\"Build the Control Panel\", \"Simulate Telemetry\", \"Add Stop Confirmations\", \"Mission Control Challenge\"],\n }),\n];\n\n/**\n * Uniform price for the immutable 1.1.0 pilot catalog.\n *\n * The GBP value is product-copy reference metadata under the published\n * 10p-per-Token economy reference rate. It does not create redemption rights.\n */\nexport const JUNIOR_CODER_MODULE_PRICE_V1_1 = Object.freeze({\n tokenSubunits: \"50000\",\n referencePrice: Object.freeze({\n currency: \"GBP\" as const,\n minorUnits: \"500\",\n basis: \"nominal-reference\" as const,\n cashRedemptionAllowed: false as const,\n }),\n});\n\n/** Initial immutable Junior Coder path manifest for pilot grants and shadow pricing. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1: LearningPathVersionV1 = {\n id: \"junior-coder.robot-rescue-arcade\",\n slug: \"robot-rescue-arcade\",\n version: \"1.0.0\",\n title: \"Junior Coder: Robot Rescue Arcade\",\n description: \"Nineteen self-contained game, robotics, Vibe Coding and web-app projects for young programmers.\",\n catalogState: \"pilot\",\n publicLaunchAtomic: true,\n featureFlag: \"learning.junior-coder.catalog.enabled\",\n modules,\n};\n\n/**\n * Uniformly priced successor to the immutable 1.0.0 pilot catalog.\n *\n * All modules remain independently sellable and retain their existing content,\n * manifests and safeguards. The new module and path versions bind the new price\n * without altering previously published records.\n */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1,\n version: \"1.1.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1.modules.map((entry) => ({\n ...entry,\n version: \"1.1.0\",\n contentRevision: \"2026-07-28.1\",\n pricing: {\n ...entry.pricing,\n tokenSubunits: JUNIOR_CODER_MODULE_PRICE_V1_1.tokenSubunits,\n referencePrice: JUNIOR_CODER_MODULE_PRICE_V1_1.referencePrice,\n },\n })),\n};\n\n/** Digest-pinned content package for the independently released 54-stage course. */\nexport const ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V1 = Object.freeze({\n packageName: \"@plasius/learning-road-hopper-rally\",\n packageVersion: \"1.0.0\",\n exportName: \"ROAD_HOPPER_RALLY_COURSE_V2\",\n schemaVersion: \"2\",\n sha256: \"1a20741beba028004e0be527d05aae2b2881082d3b578e0d62308a59bf1323f0\",\n});\n\n/** Digest-pinned evidence-led successor; the immutable v2 reference remains available. */\nexport const ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V2 = Object.freeze({\n packageName: \"@plasius/learning-road-hopper-rally\",\n packageVersion: \"1.1.0\",\n exportName: \"ROAD_HOPPER_RALLY_COURSE_V3\",\n schemaVersion: \"3\",\n sha256: \"f73b90f5f0e483b96724f978f2977435a5e6a1333f5f45fd0fc803b55ad21187\",\n});\n\nconst roadHopperV1_1 = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.find(\n (entry) => entry.id === \"junior-coder.road-hopper-rally\",\n)!;\n\nconst ROAD_HOPPER_RALLY_V2_MISSIONS = [\n {\n id: \"board\",\n title: \"Build the Rally Board\",\n concepts: [\"coordinate grids\", \"arrays\", \"entity state\", \"rendering\"],\n statement: \"Create the road, median, river and five distinct home bays in board.js.\",\n sideAdventure: \"Design an original high-contrast board palette without changing its mechanics.\",\n },\n {\n id: \"hopper\",\n title: \"Move the Hopper\",\n concepts: [\"events\", \"bounded movement\", \"keyboard input\", \"touch input\", \"respawning\"],\n statement: \"Implement four-direction tile movement, bounds, equivalent inputs and respawning in hopper.js.\",\n sideAdventure: \"Add an accessible movement status phrase for every successful hop.\",\n },\n {\n id: \"traffic\",\n title: \"Create Rally Traffic\",\n concepts: [\"spawning\", \"fixed-step updates\", \"wrapping\", \"collision detection\", \"difficulty\"],\n statement: \"Implement five deterministic traffic lanes, collisions, lives and difficulty in traffic.js.\",\n sideAdventure: \"Invent an original vehicle type while preserving the entity and collision limits.\",\n },\n {\n id: \"river\",\n title: \"Cross the Moving River\",\n concepts: [\"moving platforms\", \"carrying\", \"hazards\", \"state machines\", \"off-screen bounds\"],\n statement: \"Implement logs, carrying, water deaths, diving platforms and edge hazards in river.js.\",\n sideAdventure: \"Create an original visual warning for a platform that is about to dive.\",\n },\n {\n id: \"rules\",\n title: \"Add Rally Rules\",\n concepts: [\"timers\", \"lives\", \"scoring\", \"bonuses\", \"levels\", \"game over\"],\n statement: \"Implement homes, occupied and blocked bays, timer, scoring, bonuses and level progression in rules.js.\",\n sideAdventure: \"Tune a practice-speed preset that keeps every rule deterministic.\",\n },\n {\n id: \"game\",\n title: \"Complete Road Hopper Rally\",\n concepts: [\"system assembly\", \"pause and restart\", \"alternating players\", \"audio\", \"accessibility\", \"testing\"],\n statement: \"Assemble the systems, accessibility modes and alternating-player finale in game.js, then pass the protected challenge.\",\n sideAdventure: \"Polish the finished game with original captions, visual cues and reduced-motion feedback.\",\n },\n] as const;\n\n/** Road Hopper Rally 2.0 catalog record; course data stays in the referenced package. */\nexport const JUNIOR_CODER_ROAD_HOPPER_RALLY_V2: LearningModuleVersionV1 = {\n ...roadHopperV1_1,\n version: \"2.0.0\",\n contentRevision: \"2026-08-11.1\",\n summary: \"Recreate the systems behind a classic road-and-river crossing game using original Road Hopper Rally code, art, audio and presentation.\",\n estimatedMinutes: 450,\n tools: [\n \"JavaScript\",\n \"QuickJS sandbox\",\n \"Deterministic 30 Hz engine\",\n \"Road Hopper renderer\",\n ],\n concepts: [\n \"coordinates\",\n \"arrays and entity state\",\n \"events and input\",\n \"fixed-step update and render\",\n \"spawning and movement\",\n \"collision detection\",\n \"state machines\",\n \"timers, lives and scoring\",\n \"difficulty progression\",\n \"audio integration\",\n \"debugging\",\n \"deterministic testing\",\n ],\n missions: ROAD_HOPPER_RALLY_V2_MISSIONS.map((missionDefinition, index) => ({\n id: `road-hopper-rally-mission-${index + 1}-${missionDefinition.id}`,\n title: missionDefinition.title,\n estimatedMinutes: 75,\n concepts: [...missionDefinition.concepts],\n goals: [\n {\n id: `road-hopper-rally-v2-${missionDefinition.id}`,\n statement: missionDefinition.statement,\n evidence: \"assessment\",\n },\n ],\n sideAdventure: missionDefinition.sideAdventure,\n })),\n assessment: {\n version: \"2.0.0\",\n completionScore: 80,\n criteria: [\n { id: \"road-hopper-v2-structure\", label: \"All six bounded JavaScript files compile and assemble.\", dimension: \"structure\", points: 20, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-road\", label: \"Board, input and traffic behaviours pass deterministic scenarios.\", dimension: \"behaviour\", points: 15, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-river\", label: \"River platforms, carrying and hazards pass deterministic scenarios.\", dimension: \"behaviour\", points: 15, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-rules\", label: \"Homes, timer, lives, scoring, bonuses and levels behave correctly.\", dimension: \"behaviour\", points: 20, mandatory: true, visibility: \"visible\" },\n { id: \"road-hopper-v2-final\", label: \"The complete game passes the server-only protected final challenge.\", dimension: \"resilience\", points: 20, mandatory: true, visibility: \"protected\" },\n { id: \"road-hopper-v2-safety\", label: \"The project stays within the sandbox, resource and privacy boundaries.\", dimension: \"safety\", points: 10, mandatory: true, visibility: \"visible\" },\n ],\n },\n badges: [\n {\n id: \"road-hopper-rally-v2-complete\",\n title: \"Road Hopper Rally Champion\",\n evidence: \"module-score\",\n tradeable: false,\n tokenConvertible: false,\n },\n ],\n externalContent: ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V1,\n};\n\nconst ROAD_HOPPER_RALLY_V2_1_MISSION_TITLES = [\n \"Map the Rally Route\",\n \"Move the Hopper\",\n \"Build the Traffic Rally\",\n \"Ride the Rescue River\",\n \"Score the Rescue\",\n \"Road Hopper Rally Challenge\",\n] as const;\n\n/** Evidence-led Road Hopper 2.1 record; the executable course remains external. */\nexport const JUNIOR_CODER_ROAD_HOPPER_RALLY_V2_1: LearningModuleVersionV1 = {\n ...JUNIOR_CODER_ROAD_HOPPER_RALLY_V2,\n version: \"2.1.0\",\n contentRevision: \"2026-08-24.1\",\n summary: \"Build Road Hopper Rally through 54 evidence-led activities: predict, edit, run, inspect, repair, explain and prove each deterministic game system.\",\n missions: JUNIOR_CODER_ROAD_HOPPER_RALLY_V2.missions.map((mission, index) => ({\n ...mission,\n title: ROAD_HOPPER_RALLY_V2_1_MISSION_TITLES[index]!,\n })),\n assessment: {\n ...JUNIOR_CODER_ROAD_HOPPER_RALLY_V2.assessment,\n version: \"2.1.0\",\n },\n externalContent: ROAD_HOPPER_RALLY_EXTERNAL_CONTENT_V2,\n};\n\n/** Mixed-version successor: Road Hopper 2.0 plus every other immutable 1.1 module. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_2: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,\n version: \"1.2.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.map((entry) =>\n entry.id === JUNIOR_CODER_ROAD_HOPPER_RALLY_V2.id\n ? JUNIOR_CODER_ROAD_HOPPER_RALLY_V2\n : entry),\n};\n\n/** Digest-pinned Paddle Pulse 2.0 reference-module content. */\nexport const PADDLE_PULSE_EXTERNAL_CONTENT_V1 = Object.freeze({\n packageName: \"@plasius/learning-paddle-pulse\",\n packageVersion: \"0.1.0\",\n exportName: \"PADDLE_PULSE_MODULE_V2\",\n schemaVersion: \"2\",\n sha256: \"19f3666bdb523a3faf069341b0bc748996b3db282f89171e3c9f0a373a8c8f7e\",\n});\n\nconst paddlePulseV1_1 = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.find(\n (entry) => entry.id === \"junior-coder.paddle-pulse\",\n)!;\n\nconst PADDLE_PULSE_V2_MISSIONS = [\n {\n id: \"court-coordinates\",\n title: \"Court & Coordinates\",\n concepts: [\"coordinates\", \"canvas primitives\", \"game loops\", \"bounds\"],\n statement: \"Build a responsive 640 × 480 logical court with a bounded paddle and ball.\",\n sideAdventure: \"Create an original high-contrast court palette without changing its geometry.\",\n },\n {\n id: \"paddle-controls\",\n title: \"Paddle Controls\",\n concepts: [\"input state\", \"Pointer Events\", \"keyboard input\", \"clamping\"],\n statement: \"Implement equivalent Arrow/A/D and direct horizontal pointer-drag controls.\",\n sideAdventure: \"Add a semantic movement trace that does not rely on animation.\",\n },\n {\n id: \"ball-motion\",\n title: \"Ball Motion & Bounces\",\n concepts: [\"velocity\", \"fixed timesteps\", \"reflection\", \"contact normals\", \"paddle angles\"],\n statement: \"Implement deterministic ball motion plus controlled wall and paddle reflections.\",\n sideAdventure: \"Design a reduced-motion trajectory inspector for one rally.\",\n },\n {\n id: \"bricks-collisions\",\n title: \"Bricks & Collisions\",\n concepts: [\"arrays\", \"loops\", \"brick grids\", \"AABB collision\", \"resolution\"],\n statement: \"Create an original brick grid whose bricks score once and disappear on impact.\",\n sideAdventure: \"Invent a new visual brick pattern using the same bounded collision rules.\",\n },\n {\n id: \"score-lives-states\",\n title: \"Score, Lives & States\",\n concepts: [\"state machines\", \"invariants\", \"scoring\", \"lives\", \"HUD state\"],\n statement: \"Implement serve, pause, life loss, level clear, game over, score and HUD states.\",\n sideAdventure: \"Add a printable state-transition table for a facilitator or screen-reader user.\",\n },\n {\n id: \"levels-final-game\",\n title: \"Levels, Sound & Final Game\",\n concepts: [\"level data\", \"difficulty\", \"responsive rendering\", \"accessible audio\", \"testing\"],\n statement: \"Assemble multiple original levels, optional generated cues and the integrated final game.\",\n sideAdventure: \"After completion, add an optional original power-up without changing core assessment.\",\n },\n] as const;\n\n/** Paddle Pulse 2.0 catalog record; executable content stays in its package. */\nexport const JUNIOR_CODER_PADDLE_PULSE_V2: LearningModuleVersionV1 = {\n ...paddlePulseV1_1,\n version: \"2.0.0\",\n contentRevision: \"2026-08-11.1\",\n summary: \"Build an original Plasius brick-breaker while learning rendering, equivalent input, deterministic physics, collisions, score, lives, states, levels, accessible sound and testing.\",\n estimatedMinutes: 360,\n tools: [\n \"JavaScript\",\n \"QuickJS sandbox\",\n \"Deterministic 60 Hz engine\",\n \"Responsive Paddle Pulse renderer\",\n ],\n concepts: [\n \"coordinates and rendering\",\n \"game loops and fixed timesteps\",\n \"keyboard and pointer input\",\n \"velocity and reflection\",\n \"collision detection and resolution\",\n \"arrays and brick grids\",\n \"scoring, lives and state machines\",\n \"level data and difficulty\",\n \"accessible generated audio\",\n \"debugging and deterministic testing\",\n ],\n missions: PADDLE_PULSE_V2_MISSIONS.map((missionDefinition, index) => ({\n id: `paddle-pulse-mission-${index + 1}-${missionDefinition.id}`,\n title: missionDefinition.title,\n estimatedMinutes: 60,\n concepts: [...missionDefinition.concepts],\n goals: [{\n id: `paddle-pulse-v2-${missionDefinition.id}`,\n statement: missionDefinition.statement,\n evidence: \"assessment\",\n }],\n sideAdventure: missionDefinition.sideAdventure,\n })),\n assessment: {\n version: \"2.0.0\",\n completionScore: 80,\n criteria: [\n { id: \"paddle-pulse-v2-court\", label: \"The logical court, paddle and initial scene are finite, responsive and bounded.\", dimension: \"structure\", points: 20, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-controls\", label: \"Keyboard and pointer paths produce equivalent clamped paddle input.\", dimension: \"behaviour\", points: 15, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-motion\", label: \"Ball motion and wall/paddle reflections pass deterministic trajectories.\", dimension: \"behaviour\", points: 15, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-bricks\", label: \"Brick face, corner and adjacent impacts resolve without double-scoring.\", dimension: \"behaviour\", points: 20, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-states\", label: \"Score, lives, serve, pause, level-clear and game-over transitions preserve invariants.\", dimension: \"resilience\", points: 10, mandatory: false, visibility: \"visible\" },\n { id: \"paddle-pulse-v2-final\", label: \"Multiple original levels and the integrated game pass protected deterministic scenarios.\", dimension: \"resilience\", points: 10, mandatory: false, visibility: \"protected\" },\n { id: \"paddle-pulse-v2-safety\", label: \"Source, commands, runtime resources and assessment remain inside sandbox limits.\", dimension: \"safety\", points: 10, mandatory: true, visibility: \"visible\" },\n ],\n },\n badges: [\n { id: \"paddle-pulse-v2-court-builder\", title: \"Court Builder\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-paddle-pilot\", title: \"Paddle Pilot\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-rally-master\", title: \"Rally Master\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-brick-breaker\", title: \"Brick Breaker\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-game-keeper\", title: \"Game Keeper\", evidence: \"mission-score\", tradeable: false, tokenConvertible: false },\n { id: \"paddle-pulse-v2-complete\", title: \"Paddle Pulse Champion\", evidence: \"module-score\", tradeable: false, tokenConvertible: false },\n ],\n externalContent: PADDLE_PULSE_EXTERNAL_CONTENT_V1,\n};\n\n/** Mixed-version successor adding Paddle Pulse 2.0 without mutating v1.1. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_3: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_2,\n version: \"1.3.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_2.modules.map((entry) =>\n entry.id === JUNIOR_CODER_PADDLE_PULSE_V2.id\n ? JUNIOR_CODER_PADDLE_PULSE_V2\n : entry),\n};\n\n/** Mixed-version successor adding evidence-led Road Hopper without mutating v1.3. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_4: LearningPathVersionV1 = {\n ...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_3,\n version: \"1.4.0\",\n modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_3.modules.map((entry) =>\n entry.id === JUNIOR_CODER_ROAD_HOPPER_RALLY_V2_1.id\n ? JUNIOR_CODER_ROAD_HOPPER_RALLY_V2_1\n : entry),\n};\n\n/** Current pilot catalog for server adapters that intentionally follow releases. */\nexport const JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT =\n JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_4;\n","import { calculateAssessment } from \"./assessment.js\";\nimport { validateAssessmentRubric } from \"./rubric-validation.js\";\nimport type { AssessmentCheckResultV1, AssessmentResultV1, AssessmentRubricV1 } from \"./contracts.js\";\nimport { LearningCourseInputError, validateLearningCourse, type LearningCourseV1 } from \"./course-contracts.js\";\n\n/** Stored host-issued assessment. No browser-supplied result may construct this authority. */\nexport interface LearningCourseAssessmentRecordV1 {\n missionId: string;\n assessmentId: string;\n referenceId: string;\n sourceDigest: string;\n result: AssessmentResultV1;\n}\n/** Account and timestamps are supplied by the storage adapter, not the contract. */\nexport interface LearningCourseProgressV1 {\n schemaVersion: \"1\";\n moduleId: string;\n moduleVersion: string;\n completedStageIds: string[];\n completedMissionIds: string[];\n assessments: LearningCourseAssessmentRecordV1[];\n completion: { referenceId: string; sourceDigest: string; bestScore: number } | null;\n}\n/** Construct only after the host validates the activity-specific learner input. */\nexport interface VerifiedLearningActivityV1 {\n stageId: string;\n sourceDigest: string;\n accepted: boolean;\n}\n/** Rubric and check results come from trusted assessment execution, never a save body. */\nexport interface LearningCourseAssessmentAuthorityV1 {\n missionId: string;\n assessmentId: string;\n referenceId: string;\n sourceDigest: string;\n rubric: AssessmentRubricV1;\n checks: AssessmentCheckResultV1[];\n}\nconst DIGEST = /^[a-f0-9]{64}$/u;\nconst REFERENCE = /^[a-z0-9][a-z0-9.-]{0,159}$/u;\nconst stages = (course: LearningCourseV1) => course.missions.flatMap(mission => mission.stages);\nconst record = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && !Array.isArray(value);\nconst keys = (value: Record<string, unknown>, expected: string[]) => Object.keys(value).length === expected.length && expected.every(key => Object.hasOwn(value, key));\nconst identifier = (value: unknown): value is string => typeof value === \"string\" && REFERENCE.test(value);\nconst digest = (value: unknown): value is string => typeof value === \"string\" && DIGEST.test(value);\n\nfunction validResult(value: unknown): value is AssessmentResultV1 {\n if (!record(value) || !keys(value, [\"score\", \"band\", \"completed\", \"passedCriterionIds\", \"failedCriterionIds\", \"failedMandatoryCriterionIds\"])\n || typeof value.score !== \"number\" || !Number.isInteger(value.score) || value.score < 0 || value.score > 100) return false;\n const arrays = [value.passedCriterionIds, value.failedCriterionIds, value.failedMandatoryCriterionIds];\n if (arrays.some(items => !Array.isArray(items) || items.length > 64 || !items.every(identifier) || new Set(items).size !== items.length)) return false;\n const passed = value.passedCriterionIds as string[];\n const failed = value.failedCriterionIds as string[];\n const mandatory = value.failedMandatoryCriterionIds as string[];\n const band = value.score >= 95 ? \"mastered\" : value.score >= 80 ? \"mission-complete\" : value.score >= 60 ? \"nearly-there\" : \"keep-exploring\";\n return value.band === band && value.completed === (value.score >= 80 && mandatory.length === 0)\n && !passed.some(id => failed.includes(id)) && mandatory.every(id => failed.includes(id));\n}\n\nfunction assertProgress(course: LearningCourseV1, progress: LearningCourseProgressV1): void {\n const ordered = stages(course);\n if (progress.schemaVersion !== \"1\" || progress.moduleId !== course.moduleId || progress.moduleVersion !== course.moduleVersion\n || !Array.isArray(progress.completedStageIds) || progress.completedStageIds.length > ordered.length\n || progress.completedStageIds.some((id, index) => id !== ordered[index]!.id)\n || !Array.isArray(progress.completedMissionIds)\n || progress.completedMissionIds.length !== Math.floor(progress.completedStageIds.length / 9)\n || progress.completedMissionIds.some((id, index) => id !== course.missions[index]!.id)\n || !Array.isArray(progress.assessments) || progress.assessments.length > 7\n || progress.assessments.some(item => {\n if (!record(item) || !keys(item, [\"missionId\", \"assessmentId\", \"referenceId\", \"sourceDigest\", \"result\"])\n || !identifier(item.referenceId) || !digest(item.sourceDigest) || !validResult(item.result)) return true;\n const mission = course.missions.find(candidate => candidate.id === item.missionId);\n return item.missionId === \"final\"\n ? progress.completedMissionIds.length !== 6 || item.assessmentId !== course.completionAssessmentId\n : !mission || item.assessmentId !== mission.assessmentId;\n })\n || new Set(progress.assessments.map(item => item.missionId)).size !== progress.assessments.length\n || new Set(progress.assessments.map(item => item.referenceId)).size !== progress.assessments.length) throw new LearningCourseInputError();\n if (progress.completion !== null && (!record(progress.completion)\n || !keys(progress.completion, [\"referenceId\", \"sourceDigest\", \"bestScore\"])\n || progress.completedMissionIds.length !== 6 || !identifier(progress.completion.referenceId)\n || !digest(progress.completion.sourceDigest) || !Number.isInteger(progress.completion.bestScore)\n || progress.completion.bestScore < 80 || progress.completion.bestScore > 100)) throw new LearningCourseInputError();\n}\n\n/** Parse storage-owned progress. This is not an accepted browser mutation shape. */\nexport function parseLearningCourseProgress(course: LearningCourseV1, value: unknown): LearningCourseProgressV1 {\n if (!record(value) || !keys(value, [\"schemaVersion\", \"moduleId\", \"moduleVersion\", \"completedStageIds\", \"completedMissionIds\", \"assessments\", \"completion\"])) throw new LearningCourseInputError();\n assertProgress(course, value as unknown as LearningCourseProgressV1);\n return structuredClone(value as unknown as LearningCourseProgressV1);\n}\n\n/** Fresh course progress cannot inherit completion from project files or an old version. */\nexport function createLearningCourseProgress(course: LearningCourseV1): LearningCourseProgressV1 {\n if (validateLearningCourse(course).length) throw new LearningCourseInputError();\n return { schemaVersion: \"1\", moduleId: course.moduleId, moduleVersion: course.moduleVersion,\n completedStageIds: [], completedMissionIds: [], assessments: [], completion: null };\n}\n\n/** Saved navigation may revisit earned activities but cannot unlock later activities. */\nexport function resolveLearningCourseStage(course: LearningCourseV1, progress: LearningCourseProgressV1, requestedId: string): string {\n assertProgress(course, progress);\n const ordered = stages(course);\n const maximum = Math.min(progress.completedStageIds.length, ordered.length - 1);\n const requestedIndex = ordered.findIndex(stage => stage.id === requestedId);\n return requestedIndex >= 0 && requestedIndex <= maximum ? requestedId : ordered[maximum]!.id;\n}\n\n/**\n * Record checks from a host-owned deterministic runner using the existing rubric\n * calculator. A final assessment must cover the whole accumulated project.\n * Hosts bind reference IDs and source digests to their authenticated transaction.\n */\nexport function recordLearningCourseAssessment(\n course: LearningCourseV1, progress: LearningCourseProgressV1, authority: LearningCourseAssessmentAuthorityV1,\n): LearningCourseProgressV1 {\n assertProgress(course, progress);\n const final = authority.missionId === \"final\";\n const missionIndex = course.missions.findIndex(mission => mission.id === authority.missionId);\n if (!DIGEST.test(authority.sourceDigest) || !REFERENCE.test(authority.referenceId)\n || (final ? progress.completedMissionIds.length !== course.missions.length\n : missionIndex < 0 || missionIndex > progress.completedMissionIds.length)\n || authority.assessmentId !== (final ? course.completionAssessmentId : course.missions[missionIndex]?.assessmentId)\n || authority.rubric.version !== course.moduleVersion\n || authority.rubric.criteria.length > 64 || authority.checks.length > 64\n || authority.checks.some(check => typeof check.passed !== \"boolean\")\n || validateAssessmentRubric(authority.rubric).length) throw new LearningCourseInputError();\n let result: AssessmentResultV1;\n try { result = calculateAssessment(authority.rubric, authority.checks); }\n catch { throw new LearningCourseInputError(); }\n const assessment: LearningCourseAssessmentRecordV1 = {\n missionId: authority.missionId, assessmentId: authority.assessmentId, referenceId: authority.referenceId,\n sourceDigest: authority.sourceDigest, result,\n };\n const duplicate = progress.assessments.find(item => item.referenceId === authority.referenceId);\n if (duplicate && JSON.stringify(duplicate) !== JSON.stringify(assessment)) throw new LearningCourseInputError();\n const next = structuredClone(progress);\n next.assessments = [...next.assessments.filter(item => item.missionId !== authority.missionId), assessment];\n if (final && result.completed) {\n next.completion = next.completion\n ? { ...next.completion, bestScore: Math.max(next.completion.bestScore, result.score) }\n : { referenceId: authority.referenceId, sourceDigest: authority.sourceDigest, bestScore: result.score };\n }\n return next;\n}\n\n/**\n * Advance one verified activity. Acknowledgements alone never earn a mission or\n * badge. Failed assessments can be inspected, but repair and reward need passing\n * evidence for the current project. Storage must never accept this proof as-is\n * from a browser: the host validates each activity before constructing it.\n */\nexport function completeVerifiedLearningActivity(\n course: LearningCourseV1, progress: LearningCourseProgressV1, proof: VerifiedLearningActivityV1,\n): LearningCourseProgressV1 {\n assertProgress(course, progress);\n if (proof.accepted !== true || !DIGEST.test(proof.sourceDigest)) throw new LearningCourseInputError();\n const ordered = stages(course);\n const index = ordered.findIndex(stage => stage.id === proof.stageId);\n if (index < 0 || index > progress.completedStageIds.length) throw new LearningCourseInputError();\n if (index < progress.completedStageIds.length) return structuredClone(progress);\n const stage = ordered[index]!;\n const mission = course.missions[Math.floor(index / 9)]!;\n if ([\"assess\", \"inspect\", \"fix\", \"reward\"].includes(stage.kind)) {\n const assessment = progress.assessments.find(item => item.missionId === mission.id);\n if (!assessment || assessment.sourceDigest !== proof.sourceDigest\n || ((stage.kind === \"fix\" || stage.kind === \"reward\") && !assessment.result.completed)) throw new LearningCourseInputError();\n }\n const next = structuredClone(progress);\n next.completedStageIds.push(proof.stageId);\n if (stage.kind === \"reward\") next.completedMissionIds.push(mission.id);\n return next;\n}\n","import type { MissionBoundedSuggestionV1 } from \"./contracts.js\";\nimport { parseLearningProject, type LearningCourseV1, type LearningProjectV1 } from \"./course-contracts.js\";\n\n/** Learner-safe authored diff; the artifact ID is a declared course project path. */\nexport interface LearningCourseSuggestionV1 {\n stageId: string;\n proposal: MissionBoundedSuggestionV1;\n}\n\nconst record = (value: unknown): value is Record<string, unknown> => value !== null && typeof value === \"object\" && !Array.isArray(value);\nconst keys = (value: Record<string, unknown>, expected: readonly string[]) => Object.keys(value).length === expected.length\n && expected.every(key => Object.hasOwn(value, key));\nconst text = (value: unknown, maximum: number): value is string => typeof value === \"string\"\n && value.trim().length > 0 && value.length <= maximum && !value.includes(\"\\0\");\n\n/** Validate a reviewed proposal without executing, applying or approving it. */\nexport function parseLearningCourseSuggestion(course: LearningCourseV1, value: unknown): LearningCourseSuggestionV1 {\n if (!record(value) || !keys(value, [\"stageId\", \"proposal\"]) || !text(value.stageId, 128)\n || !course.missions.some(mission => mission.stages.some(stage => stage.id === value.stageId)) || !record(value.proposal)) {\n throw new Error(\"Invalid course suggestion.\");\n }\n const proposal = value.proposal;\n if (!keys(proposal, [\"id\", \"source\", \"intent\", \"constraints\", \"permittedArtifactId\", \"originalSnippet\", \"replacementSnippet\",\n \"explanationPrompt\", \"aiOptional\", \"learnerApprovalRequired\", \"alternatives\"])\n || !text(proposal.id, 128) || proposal.source !== \"authored-fallback\" || !text(proposal.intent, 1000)\n || !Array.isArray(proposal.constraints) || proposal.constraints.length < 1 || proposal.constraints.length > 8\n || !proposal.constraints.every(constraint => text(constraint, 400))\n || !course.projectFiles.some(file => file.path === proposal.permittedArtifactId)\n || !text(proposal.originalSnippet, 8000) || !text(proposal.replacementSnippet, 8000)\n || proposal.originalSnippet === proposal.replacementSnippet || !text(proposal.explanationPrompt, 1000)\n || proposal.aiOptional !== false || proposal.learnerApprovalRequired !== true\n || !Array.isArray(proposal.alternatives) || proposal.alternatives.length !== 2\n || proposal.alternatives[0] !== \"accept\" || proposal.alternatives[1] !== \"reject\") throw new Error(\"Invalid course suggestion.\");\n return structuredClone(value) as unknown as LearningCourseSuggestionV1;\n}\n\n/**\n * Build the proposed project after an explicit learner choice in the host.\n * This pure function grants no approval, writes no storage and awards no evidence.\n * Stale or ambiguous snippets must be reviewed again rather than applied fuzzily.\n */\nexport function applyLearningCourseSuggestion(course: LearningCourseV1, project: unknown, suggestion: unknown): LearningProjectV1 {\n const parsed = parseLearningProject(course, project);\n const { proposal } = parseLearningCourseSuggestion(course, suggestion);\n const file = parsed.files.find(candidate => candidate.path === proposal.permittedArtifactId)!;\n const start = file.source.indexOf(proposal.originalSnippet);\n if (start < 0 || file.source.indexOf(proposal.originalSnippet, start + 1) >= 0) {\n throw new Error(\"Suggestion does not match exactly one source location.\");\n }\n file.source = file.source.slice(0, start) + proposal.replacementSnippet + file.source.slice(start + proposal.originalSnippet.length);\n return parseLearningProject(course, parsed);\n}\n","/** Additive contract version for touch-first and spoken contextual help. */\nexport const CONTEXTUAL_HELP_CONTRACT_VERSION_V1 = \"1.0.0\" as const;\n\nexport const CONTEXTUAL_HELP_KINDS_V1 = Object.freeze([\n \"command\",\n \"visual-block\",\n \"generated-code\",\n \"assessment-diagnostic\",\n] as const);\n\nexport type ContextualHelpKindV1 = (typeof CONTEXTUAL_HELP_KINDS_V1)[number];\n\n/**\n * Opaque, manifest-bound identifier. It contains no source, transcript,\n * learner identity or arbitrary synthesis text.\n */\nexport interface ContextualHelpIdentifierV1 {\n readonly schemaVersion: \"1\";\n readonly contractVersion: typeof CONTEXTUAL_HELP_CONTRACT_VERSION_V1;\n readonly kind: ContextualHelpKindV1;\n readonly moduleId: string;\n readonly moduleVersion: string;\n readonly manifestVersion: string;\n readonly helpId: string;\n}\n\nexport type GuardianVoiceConsentStateV1 = \"granted\" | \"withdrawn\";\nexport type GuardianVoiceProcessingRouteV1 = \"private-edge-only\";\n\n/** Voice consent is deliberately separate from general AI consent. */\nexport interface GuardianVoiceConsentV1 {\n readonly schemaVersion: \"1\";\n readonly actorAccountId: string;\n readonly subjectAccountId: string;\n readonly policyVersion: string;\n readonly state: GuardianVoiceConsentStateV1;\n readonly permittedProcessingRoute: GuardianVoiceProcessingRouteV1;\n readonly recordedAt: string;\n}\n\nexport type VoiceHelpAvailabilityReasonV1 =\n | \"available\"\n | \"module-access-required\"\n | \"guardian-consent-required\"\n | \"guardian-consent-withdrawn\"\n | \"age-or-safeguarding-gate\"\n | \"capability-disabled\"\n | \"rollout-disabled\"\n | \"private-edge-unavailable\";\n\n/** Read-aloud and microphone availability are evaluated independently. */\nexport interface VoiceHelpAvailabilityV1 {\n readonly schemaVersion: \"1\";\n readonly readAloudAvailable: boolean;\n readonly microphoneAvailable: boolean;\n readonly microphoneReason: VoiceHelpAvailabilityReasonV1;\n readonly questionProcessingRoute: GuardianVoiceProcessingRouteV1;\n readonly guardianVoiceConsentRequired: true;\n readonly maximumRecordingDurationMs: 10_000;\n readonly maximumAudioBytes: 2_097_152;\n readonly rawAudioRetention: \"request-memory-only\";\n readonly transcriptRetention: \"request-memory-only\";\n}\n\n/** Metadata accepted beside an authenticated multipart audio upload. */\nexport interface ContextualVoiceQuestionMetadataV1 {\n readonly schemaVersion: \"1\";\n readonly help: ContextualHelpIdentifierV1;\n readonly locale: string;\n readonly mediaType: string;\n readonly durationMs: number;\n readonly audioBytes: number;\n readonly assessmentEvidenceId?: string;\n}\n\nexport const CONTEXTUAL_VOICE_INTENTS_V1 = Object.freeze([\n \"describe-command\",\n \"describe-inputs\",\n \"show-example\",\n \"explain-assessment-failure\",\n \"suggest-next-experiment\",\n \"repeat\",\n \"stop\",\n \"unresolved\",\n] as const);\n\nexport type ContextualVoiceIntentV1 =\n (typeof CONTEXTUAL_VOICE_INTENTS_V1)[number];\n\nexport type ContextualVoiceSuggestedActionV1 =\n | \"open-help\"\n | \"insert-example\"\n | \"show-inputs\"\n | \"show-assessment-evidence\"\n | \"try-next-experiment\"\n | \"repeat\"\n | \"stop\"\n | \"type-question\";\n\nexport const CONTEXTUAL_VOICE_SUGGESTED_ACTIONS_V1 = Object.freeze([\n \"open-help\",\n \"insert-example\",\n \"show-inputs\",\n \"show-assessment-evidence\",\n \"try-next-experiment\",\n \"repeat\",\n \"stop\",\n \"type-question\",\n] as const satisfies readonly ContextualVoiceSuggestedActionV1[]);\n\nexport interface ContextualVoiceAnswerV1 {\n readonly helpId: string;\n readonly source:\n | \"module-documentation\"\n | \"assessment-evidence\"\n | \"authored-fallback\";\n /** Server-resolved visible answer; never a model-authored open response. */\n readonly text: string;\n}\n\n/**\n * The transcript is returned only so the learner can verify recognition. The\n * request boundary must use no-store and discard it after the current view.\n */\nexport interface ContextualVoiceQuestionResultV1 {\n readonly schemaVersion: \"1\";\n readonly help: ContextualHelpIdentifierV1;\n readonly intent: ContextualVoiceIntentV1;\n readonly status: \"resolved\" | \"suggestions\" | \"stopped\";\n readonly transientTranscript: string;\n readonly transcriptRetention: \"request-memory-only\";\n readonly answer?: ContextualVoiceAnswerV1;\n readonly suggestedActions: ContextualVoiceSuggestedActionV1[];\n readonly mayAssignScore: false;\n readonly mayAwardReward: false;\n readonly mayPublish: false;\n readonly mayControlHardware: false;\n}\n\n/** Canonical audio lookup metadata. Authoritative speech text stays server-side. */\nexport interface CanonicalSpokenHelpDescriptorV1 {\n readonly schemaVersion: \"1\";\n readonly help: ContextualHelpIdentifierV1;\n readonly canonicalTextId: string;\n readonly authoritativeTextDigest: `sha256:${string}`;\n readonly locale: string;\n readonly voiceProfile: string;\n readonly pronunciationVersion: string;\n readonly utteranceClass: \"system-generic\";\n readonly sharingScope: \"global\";\n readonly reuse: \"exact-only\";\n readonly containsPersonalData: false;\n readonly containsLearnerContent: false;\n}\n\nconst OPAQUE_ID = /^[a-z0-9]+(?:[._:-][a-z0-9]+)*$/u;\nconst SEMVER = /^[0-9]+\\.[0-9]+\\.[0-9]+(?:[-+][A-Za-z0-9.-]+)?$/u;\nconst SHA_256 = /^sha256:[a-f0-9]{64}$/u;\nconst LOCALE = /^[a-z]{2,3}(?:-[A-Z]{2})?$/u;\nconst MEDIA_TYPE = /^audio\\/[a-z0-9.+-]+$/u;\n\nfunction containsDisallowedControlCharacter(value: string): boolean {\n return [...value].some((character) => {\n const code = character.codePointAt(0) ?? 0;\n return code <= 8 || code === 11 || code === 12\n || (code >= 14 && code <= 31) || code === 127;\n });\n}\n\nfunction requireOpaqueId(value: string, label: string, maximum = 160): void {\n if (value.length === 0 || value.length > maximum || !OPAQUE_ID.test(value)) {\n throw new Error(`${label} must be a bounded opaque identifier.`);\n }\n}\n\nfunction requireSemver(value: string, label: string): void {\n if (!SEMVER.test(value)) {\n throw new Error(`${label} must be an immutable semantic version.`);\n }\n}\n\nfunction requireIsoTimestamp(value: string, label: string): void {\n if (!/^\\d{4}-\\d{2}-\\d{2}T/u.test(value) || !Number.isFinite(Date.parse(value))) {\n throw new Error(`${label} must be an ISO-8601 timestamp.`);\n }\n}\n\nexport function assertValidContextualHelpIdentifier(\n value: ContextualHelpIdentifierV1,\n): void {\n if (value.schemaVersion !== \"1\") {\n throw new Error(\"schemaVersion must be 1.\");\n }\n if (value.contractVersion !== CONTEXTUAL_HELP_CONTRACT_VERSION_V1) {\n throw new Error(\"contractVersion is unsupported.\");\n }\n if (!CONTEXTUAL_HELP_KINDS_V1.includes(value.kind)) {\n throw new Error(\"kind is unsupported.\");\n }\n requireOpaqueId(value.moduleId, \"moduleId\");\n requireSemver(value.moduleVersion, \"moduleVersion\");\n requireSemver(value.manifestVersion, \"manifestVersion\");\n requireOpaqueId(value.helpId, \"helpId\");\n}\n\nexport function assertValidGuardianVoiceConsent(\n value: GuardianVoiceConsentV1,\n): void {\n if (value.schemaVersion !== \"1\") {\n throw new Error(\"schemaVersion must be 1.\");\n }\n requireOpaqueId(value.actorAccountId, \"actorAccountId\");\n requireOpaqueId(value.subjectAccountId, \"subjectAccountId\");\n requireSemver(value.policyVersion, \"policyVersion\");\n if (value.state !== \"granted\" && value.state !== \"withdrawn\") {\n throw new Error(\"state must be granted or withdrawn.\");\n }\n if (value.permittedProcessingRoute !== \"private-edge-only\") {\n throw new Error(\"permittedProcessingRoute must be private-edge-only.\");\n }\n requireIsoTimestamp(value.recordedAt, \"recordedAt\");\n}\n\nexport function assertValidContextualVoiceQuestionMetadata(\n value: ContextualVoiceQuestionMetadataV1,\n): void {\n assertValidContextualHelpIdentifier(value.help);\n if (!LOCALE.test(value.locale)) throw new Error(\"locale is invalid.\");\n if (!MEDIA_TYPE.test(value.mediaType)) throw new Error(\"mediaType is invalid.\");\n if (!Number.isInteger(value.durationMs) || value.durationMs < 1 || value.durationMs > 10_000) {\n throw new Error(\"durationMs must be between 1 and 10000.\");\n }\n if (!Number.isInteger(value.audioBytes) || value.audioBytes < 1 || value.audioBytes > 2_097_152) {\n throw new Error(\"audioBytes must be between 1 and 2097152.\");\n }\n if (value.assessmentEvidenceId !== undefined) {\n requireOpaqueId(value.assessmentEvidenceId, \"assessmentEvidenceId\");\n }\n}\n\nexport function assertValidVoiceHelpAvailability(\n value: VoiceHelpAvailabilityV1,\n): void {\n if (value.schemaVersion !== \"1\") throw new Error(\"schemaVersion must be 1.\");\n if (value.questionProcessingRoute !== \"private-edge-only\") {\n throw new Error(\"questionProcessingRoute must be private-edge-only.\");\n }\n if (value.guardianVoiceConsentRequired !== true) {\n throw new Error(\"guardianVoiceConsentRequired must remain true.\");\n }\n if (\n value.maximumRecordingDurationMs !== 10_000\n || value.maximumAudioBytes !== 2_097_152\n || value.rawAudioRetention !== \"request-memory-only\"\n || value.transcriptRetention !== \"request-memory-only\"\n ) {\n throw new Error(\"Voice limits and transient retention are immutable in version one.\");\n }\n if (value.microphoneAvailable !== (value.microphoneReason === \"available\")) {\n throw new Error(\"microphoneReason must match microphone availability.\");\n }\n}\n\nexport function assertValidCanonicalSpokenHelpDescriptor(\n value: CanonicalSpokenHelpDescriptorV1,\n): void {\n if (value.schemaVersion !== \"1\") throw new Error(\"schemaVersion must be 1.\");\n assertValidContextualHelpIdentifier(value.help);\n requireOpaqueId(value.canonicalTextId, \"canonicalTextId\");\n if (!SHA_256.test(value.authoritativeTextDigest)) {\n throw new Error(\"authoritativeTextDigest must be a SHA-256 digest.\");\n }\n if (!LOCALE.test(value.locale)) throw new Error(\"locale is invalid.\");\n requireOpaqueId(value.voiceProfile, \"voiceProfile\");\n requireSemver(value.pronunciationVersion, \"pronunciationVersion\");\n if (\n value.utteranceClass !== \"system-generic\"\n || value.sharingScope !== \"global\"\n || value.reuse !== \"exact-only\"\n || value.containsPersonalData !== false\n || value.containsLearnerContent !== false\n ) {\n throw new Error(\"Canonical spoken help must use global system-generic exact-only reuse.\");\n }\n}\n\nexport function assertValidContextualVoiceQuestionResult(\n value: ContextualVoiceQuestionResultV1,\n): void {\n if (value.schemaVersion !== \"1\") throw new Error(\"schemaVersion must be 1.\");\n assertValidContextualHelpIdentifier(value.help);\n if (!CONTEXTUAL_VOICE_INTENTS_V1.includes(value.intent)) {\n throw new Error(\"intent is unsupported.\");\n }\n if (value.transcriptRetention !== \"request-memory-only\") {\n throw new Error(\"transcriptRetention must be request-memory-only.\");\n }\n if (value.status !== \"resolved\" && value.status !== \"suggestions\" && value.status !== \"stopped\") {\n throw new Error(\"status is unsupported.\");\n }\n if (\n value.transientTranscript.length > 500\n || containsDisallowedControlCharacter(value.transientTranscript)\n ) {\n throw new Error(\"transientTranscript is invalid.\");\n }\n if (value.answer) {\n requireOpaqueId(value.answer.helpId, \"answer.helpId\");\n if (\n (value.answer.source !== \"module-documentation\"\n && value.answer.source !== \"assessment-evidence\"\n && value.answer.source !== \"authored-fallback\")\n ||\n value.answer.text.length === 0\n || value.answer.text.length > 800\n || containsDisallowedControlCharacter(value.answer.text)\n ) {\n throw new Error(\"answer.text is invalid.\");\n }\n }\n if (value.suggestedActions.some(\n (action) => !CONTEXTUAL_VOICE_SUGGESTED_ACTIONS_V1.includes(action),\n )) {\n throw new Error(\"suggestedActions contains an unsupported action.\");\n }\n if (\n value.mayAssignScore !== false\n || value.mayAwardReward !== false\n || value.mayPublish !== false\n || value.mayControlHardware !== false\n ) {\n throw new Error(\"mayAssignScore, reward, publish and hardware authority must remain false.\");\n }\n}\n","/** Versioned, infrastructure-neutral contracts for Guardian-approved static projects. */\nexport const STATIC_PROJECT_PUBLISHING_CONTRACT_VERSION_V1 = \"1.0.0\" as const;\nexport const STATIC_PROJECT_SCANNER_VERSION_V1 = \"junior-coder-static-scan-v1\" as const;\nexport const STATIC_PROJECT_APPROVAL_STATEMENT_VERSION_V1 =\n \"guardian-static-publication-v1\" as const;\nexport const STATIC_PROJECT_DEFAULT_LIFETIME_DAYS_V1 = 90 as const;\nexport const STATIC_PROJECT_MAX_SOURCE_CHARACTERS_V1 = 8_000 as const;\n\nexport const STATIC_PROJECT_SAFETY_CHECK_IDS_V1 = [\n \"allow-listed-source\",\n \"no-personal-details\",\n \"no-external-network\",\n \"no-executable-markup\",\n \"no-transmitting-forms\",\n \"no-uploads-or-embeds\",\n \"no-trackers-or-advertising\",\n \"no-account-identifiers\",\n] as const;\n\nexport type StaticProjectSafetyCheckIdV1 =\n (typeof STATIC_PROJECT_SAFETY_CHECK_IDS_V1)[number];\n\nexport type StaticProjectModuleSlugV1 =\n | \"adventure-mission-planner\"\n | \"creature-care-dashboard\"\n | \"robot-mission-control\";\n\nexport interface StaticProjectSafetyCheckV1 {\n id: StaticProjectSafetyCheckIdV1;\n passed: true;\n}\n\n/** Evidence emitted by the deterministic scanner before adult review. */\nexport interface StaticProjectSafetyScanV1 {\n schemaVersion: \"1\";\n scannerVersion: typeof STATIC_PROJECT_SCANNER_VERSION_V1;\n passed: true;\n checks: StaticProjectSafetyCheckV1[];\n}\n\nexport interface AdventureMissionPlannerSafeRenderV1 {\n kind: \"adventure-mission-planner\";\n heading: \"Moonbase Missions\" | \"Forest Rescue Plans\" | \"Ocean Quest Board\";\n missions: {\n title: \"Find the moon crystal\" | \"Guide the lost firefly\" | \"Map the coral garden\";\n day: \"Saturday\" | \"Sunday\" | \"School holiday\";\n }[];\n validationMessage: \"Choose a day\" | \"Add a mission title\" | \"Mission ready!\";\n savedAcrossRestart: true;\n accessibleSummaryEnabled: true;\n}\n\nexport interface CreatureCareDashboardSafeRenderV1 {\n kind: \"creature-care-dashboard\";\n creature: \"Moon Moth\" | \"Cloud Cat\" | \"Pebble Dragon\";\n status: \"Resting\" | \"Ready to play\" | \"Snack time\";\n timerSeconds: 5 | 10 | 15;\n layout: \"single\" | \"cosy-grid\" | \"wide-grid\";\n reducedMotion: true;\n}\n\nexport interface RobotMissionControlSafeRenderV1 {\n kind: \"robot-mission-control\";\n command: \"scan\" | \"hold-position\" | \"return-to-base\";\n safetyConfirmed: true;\n telemetryRate: 1 | 2 | 4;\n chartMode: \"line\" | \"bars\" | \"text-only\";\n serialSimulation: true;\n state: \"SCANNING\" | \"HOLDING\" | \"RETURNING\";\n}\n\n/** The complete public render allow-list. Learner source is never a render model. */\nexport type StaticProjectSafeRenderV1 =\n | AdventureMissionPlannerSafeRenderV1\n | CreatureCareDashboardSafeRenderV1\n | RobotMissionControlSafeRenderV1;\n\n/** Immutable private snapshot awaiting an adult's exact-hash approval. */\nexport interface StaticProjectSnapshotV1 {\n schemaVersion: \"1\";\n contractVersion: typeof STATIC_PROJECT_PUBLISHING_CONTRACT_VERSION_V1;\n snapshotId: string;\n subjectAccountId: string;\n moduleId: string;\n moduleSlug: StaticProjectModuleSlugV1;\n moduleVersion: string;\n missionId: string;\n sourceDigest: string;\n snapshotDigest: string;\n sourceCharacterCount: number;\n assessmentScore: number;\n mandatorySafetyPassed: true;\n scan: StaticProjectSafetyScanV1;\n renderModel: StaticProjectSafeRenderV1;\n state: \"pending-review\";\n createdAt: string;\n}\n\n/** Adult approval is evidence only and cannot mutate the reviewed snapshot. */\nexport interface StaticProjectGuardianApprovalV1 {\n schemaVersion: \"1\";\n approvalId: string;\n snapshotId: string;\n snapshotDigest: string;\n guardianActorAccountId: string;\n statementVersion: typeof STATIC_PROJECT_APPROVAL_STATEMENT_VERSION_V1;\n approvedAt: string;\n}\n\n/** An unlisted public pointer whose lifecycle never changes the source snapshot. */\nexport interface StaticProjectPublicationV1 {\n schemaVersion: \"1\";\n publicationId: string;\n snapshotId: string;\n snapshotDigest: string;\n approvalId: string;\n randomSlug: string;\n publicUrl: string;\n state: \"published\" | \"expired\" | \"unpublished\";\n publishedAt: string;\n expiresAt: string;\n renewedAt?: string;\n unpublishedAt?: string;\n}\n\nexport type StaticProjectContractIssueV1 =\n | \"invalid-schema-version\"\n | \"invalid-contract-version\"\n | \"invalid-identifier\"\n | \"invalid-module\"\n | \"invalid-version\"\n | \"invalid-source-digest\"\n | \"invalid-snapshot-digest\"\n | \"invalid-source-size\"\n | \"assessment-score-incomplete\"\n | \"mandatory-safety-missing\"\n | \"scan-not-passed\"\n | \"scan-checks-incomplete\"\n | \"module-render-model-mismatch\"\n | \"unsafe-render-model\"\n | \"invalid-created-at\"\n | \"invalid-approval-statement\"\n | \"invalid-approved-at\"\n | \"invalid-random-slug\"\n | \"invalid-public-url\"\n | \"public-url-slug-mismatch\"\n | \"published-state-required\"\n | \"invalid-published-at\"\n | \"invalid-publication-expiry\"\n | \"invalid-lifecycle-timestamp\";\n\nconst DIGEST_PATTERN = /^sha256:[a-f0-9]{64}$/u;\nconst IDENTIFIER_PATTERN = /^(?:account|approval|publication|snapshot)_[A-Za-z0-9_-]{20,128}$/u;\nconst VERSION_PATTERN = /^[0-9]+\\.[0-9]+\\.[0-9]+(?:[-+][A-Za-z0-9.-]+)?$/u;\nconst RANDOM_SLUG_PATTERN = /^[A-Za-z0-9_-]{40,128}$/u;\n\nfunction validDate(value: string): boolean {\n return typeof value === \"string\" && Number.isFinite(Date.parse(value));\n}\n\nfunction allSafetyChecksPresent(scan: StaticProjectSafetyScanV1): boolean {\n if (!Array.isArray(scan.checks) || scan.checks.length !== STATIC_PROJECT_SAFETY_CHECK_IDS_V1.length) {\n return false;\n }\n const supplied = new Set(scan.checks.map((check) => check.id));\n return STATIC_PROJECT_SAFETY_CHECK_IDS_V1.every((id) => supplied.has(id))\n && scan.checks.every((check) => check.passed === true);\n}\n\nfunction safeAdventureRender(value: AdventureMissionPlannerSafeRenderV1): boolean {\n const headings = [\"Moonbase Missions\", \"Forest Rescue Plans\", \"Ocean Quest Board\"];\n const titles = [\"Find the moon crystal\", \"Guide the lost firefly\", \"Map the coral garden\"];\n const days = [\"Saturday\", \"Sunday\", \"School holiday\"];\n const messages = [\"Choose a day\", \"Add a mission title\", \"Mission ready!\"];\n return headings.includes(value.heading)\n && Array.isArray(value.missions)\n && value.missions.length >= 1\n && value.missions.length <= 3\n && value.missions.every((mission) => titles.includes(mission.title) && days.includes(mission.day))\n && messages.includes(value.validationMessage)\n && value.savedAcrossRestart === true\n && value.accessibleSummaryEnabled === true;\n}\n\nfunction safeCreatureRender(value: CreatureCareDashboardSafeRenderV1): boolean {\n return [\"Moon Moth\", \"Cloud Cat\", \"Pebble Dragon\"].includes(value.creature)\n && [\"Resting\", \"Ready to play\", \"Snack time\"].includes(value.status)\n && [5, 10, 15].includes(value.timerSeconds)\n && [\"single\", \"cosy-grid\", \"wide-grid\"].includes(value.layout)\n && value.reducedMotion === true;\n}\n\nfunction safeRobotRender(value: RobotMissionControlSafeRenderV1): boolean {\n return [\"scan\", \"hold-position\", \"return-to-base\"].includes(value.command)\n && value.safetyConfirmed === true\n && [1, 2, 4].includes(value.telemetryRate)\n && [\"line\", \"bars\", \"text-only\"].includes(value.chartMode)\n && value.serialSimulation === true\n && [\"SCANNING\", \"HOLDING\", \"RETURNING\"].includes(value.state);\n}\n\n/** Validate a snapshot without throwing so authoring and adapters can show every issue. */\nexport function validateStaticProjectSnapshot(\n value: StaticProjectSnapshotV1,\n): StaticProjectContractIssueV1[] {\n const issues: StaticProjectContractIssueV1[] = [];\n if (value.schemaVersion !== \"1\") issues.push(\"invalid-schema-version\");\n if (value.contractVersion !== STATIC_PROJECT_PUBLISHING_CONTRACT_VERSION_V1) {\n issues.push(\"invalid-contract-version\");\n }\n if (!IDENTIFIER_PATTERN.test(value.snapshotId) || !IDENTIFIER_PATTERN.test(value.subjectAccountId)) {\n issues.push(\"invalid-identifier\");\n }\n if (!value.moduleId.startsWith(\"junior-coder.\") || value.moduleId !== `junior-coder.${value.moduleSlug}`) {\n issues.push(\"invalid-module\");\n }\n if (!VERSION_PATTERN.test(value.moduleVersion)) issues.push(\"invalid-version\");\n if (!DIGEST_PATTERN.test(value.sourceDigest)) issues.push(\"invalid-source-digest\");\n if (!DIGEST_PATTERN.test(value.snapshotDigest)) issues.push(\"invalid-snapshot-digest\");\n if (!Number.isInteger(value.sourceCharacterCount)\n || value.sourceCharacterCount < 1\n || value.sourceCharacterCount > STATIC_PROJECT_MAX_SOURCE_CHARACTERS_V1) {\n issues.push(\"invalid-source-size\");\n }\n if (!Number.isInteger(value.assessmentScore)\n || value.assessmentScore < 80\n || value.assessmentScore > 100) {\n issues.push(\"assessment-score-incomplete\");\n }\n if (value.mandatorySafetyPassed !== true) issues.push(\"mandatory-safety-missing\");\n if (value.scan?.passed !== true || value.scan?.scannerVersion !== STATIC_PROJECT_SCANNER_VERSION_V1) {\n issues.push(\"scan-not-passed\");\n }\n if (!value.scan || !allSafetyChecksPresent(value.scan)) issues.push(\"scan-checks-incomplete\");\n if (value.moduleSlug !== value.renderModel?.kind) issues.push(\"module-render-model-mismatch\");\n const renderSafe = value.renderModel?.kind === \"adventure-mission-planner\"\n ? safeAdventureRender(value.renderModel)\n : value.renderModel?.kind === \"creature-care-dashboard\"\n ? safeCreatureRender(value.renderModel)\n : value.renderModel?.kind === \"robot-mission-control\"\n ? safeRobotRender(value.renderModel)\n : false;\n if (!renderSafe) issues.push(\"unsafe-render-model\");\n if (value.state !== \"pending-review\" || !validDate(value.createdAt)) issues.push(\"invalid-created-at\");\n return [...new Set(issues)];\n}\n\n/** Fail closed when a persistence or publishing adapter constructs an invalid snapshot. */\nexport function assertValidStaticProjectSnapshot(value: StaticProjectSnapshotV1): void {\n const issues = validateStaticProjectSnapshot(value);\n if (issues.length > 0) throw new Error(`Invalid static project snapshot: ${issues.join(\", \")}`);\n}\n\nexport function validateStaticProjectGuardianApproval(\n value: StaticProjectGuardianApprovalV1,\n): StaticProjectContractIssueV1[] {\n const issues: StaticProjectContractIssueV1[] = [];\n if (value.schemaVersion !== \"1\") issues.push(\"invalid-schema-version\");\n if (!IDENTIFIER_PATTERN.test(value.approvalId)\n || !IDENTIFIER_PATTERN.test(value.snapshotId)\n || !IDENTIFIER_PATTERN.test(value.guardianActorAccountId)) {\n issues.push(\"invalid-identifier\");\n }\n if (!DIGEST_PATTERN.test(value.snapshotDigest)) issues.push(\"invalid-snapshot-digest\");\n if (value.statementVersion !== STATIC_PROJECT_APPROVAL_STATEMENT_VERSION_V1) {\n issues.push(\"invalid-approval-statement\");\n }\n if (!validDate(value.approvedAt)) issues.push(\"invalid-approved-at\");\n return [...new Set(issues)];\n}\n\nexport function assertValidStaticProjectGuardianApproval(\n value: StaticProjectGuardianApprovalV1,\n): void {\n const issues = validateStaticProjectGuardianApproval(value);\n if (issues.length > 0) throw new Error(`Invalid static project approval: ${issues.join(\", \")}`);\n}\n\nexport function validateStaticProjectPublication(\n value: StaticProjectPublicationV1,\n): StaticProjectContractIssueV1[] {\n const issues: StaticProjectContractIssueV1[] = [];\n if (value.schemaVersion !== \"1\") issues.push(\"invalid-schema-version\");\n if (!IDENTIFIER_PATTERN.test(value.publicationId)\n || !IDENTIFIER_PATTERN.test(value.snapshotId)\n || !IDENTIFIER_PATTERN.test(value.approvalId)) {\n issues.push(\"invalid-identifier\");\n }\n if (!DIGEST_PATTERN.test(value.snapshotDigest)) issues.push(\"invalid-snapshot-digest\");\n if (!RANDOM_SLUG_PATTERN.test(value.randomSlug)) issues.push(\"invalid-random-slug\");\n let parsedUrl: URL | undefined;\n try {\n parsedUrl = new URL(value.publicUrl);\n } catch {\n parsedUrl = undefined;\n }\n if (!parsedUrl || parsedUrl.protocol !== \"https:\" || parsedUrl.username || parsedUrl.password) {\n issues.push(\"invalid-public-url\");\n }\n if (!parsedUrl?.pathname.endsWith(`/${value.randomSlug}`)) issues.push(\"public-url-slug-mismatch\");\n if (value.state !== \"published\") issues.push(\"published-state-required\");\n if (!validDate(value.publishedAt)) issues.push(\"invalid-published-at\");\n if (!validDate(value.expiresAt)\n || (validDate(value.publishedAt) && Date.parse(value.expiresAt) <= Date.parse(value.publishedAt))) {\n issues.push(\"invalid-publication-expiry\");\n }\n if ((value.renewedAt !== undefined && !validDate(value.renewedAt))\n || (value.unpublishedAt !== undefined && !validDate(value.unpublishedAt))) {\n issues.push(\"invalid-lifecycle-timestamp\");\n }\n return [...new Set(issues)];\n}\n\nexport function assertValidStaticProjectPublication(value: StaticProjectPublicationV1): void {\n const issues = validateStaticProjectPublication(value);\n if (issues.length > 0) throw new Error(`Invalid static project publication: ${issues.join(\", \")}`);\n}\n","import type {\n ExternalLearningContentReferenceV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n LearningValidationIssueV1,\n} from \"./contracts.js\";\nimport { validateAssessmentRubric } from \"./rubric-validation.js\";\n\nconst CANONICAL_TOKEN_SUBUNITS = /^(0|[1-9][0-9]*)$/u;\nconst EXACT_PACKAGE_NAME = /^@plasius\\/[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/u;\nconst EXACT_SEMVER = /^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$/u;\nconst EXPORT_NAME = /^[A-Za-z_$][A-Za-z0-9_$]*$/u;\nconst CONTENT_SCHEMA_VERSION = /^(0|[1-9][0-9]*)$/u;\nconst SHA256 = /^[a-f0-9]{64}$/u;\n\n/** Runtime guard for digest-pinned external learning content references. */\nexport function isExternalLearningContentReferenceV1(\n value: unknown,\n): value is ExternalLearningContentReferenceV1 {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as Partial<ExternalLearningContentReferenceV1>;\n return (\n Object.keys(value).length === 5\n && typeof candidate.packageName === \"string\"\n && EXACT_PACKAGE_NAME.test(candidate.packageName)\n && typeof candidate.packageVersion === \"string\"\n && EXACT_SEMVER.test(candidate.packageVersion)\n && typeof candidate.exportName === \"string\"\n && EXPORT_NAME.test(candidate.exportName)\n && typeof candidate.schemaVersion === \"string\"\n && CONTENT_SCHEMA_VERSION.test(candidate.schemaVersion)\n && typeof candidate.sha256 === \"string\"\n && SHA256.test(candidate.sha256)\n );\n}\n\nfunction issue(\n code: LearningValidationIssueV1[\"code\"],\n message: string,\n path: string,\n moduleId?: string,\n): LearningValidationIssueV1 {\n return { code, message, path, ...(moduleId ? { moduleId } : {}) };\n}\n\nfunction validateModule(\n module: LearningModuleVersionV1,\n moduleIndex: number,\n): LearningValidationIssueV1[] {\n const issues: LearningValidationIssueV1[] = [];\n const base = `modules[${moduleIndex}]`;\n\n if (!module.selfContained) {\n issues.push(\n issue(\n \"module-not-self-contained\",\n \"Every sellable module must be self-contained.\",\n `${base}.selfContained`,\n module.id,\n ),\n );\n }\n\n if (module.prerequisiteModuleIds.length > 0) {\n issues.push(\n issue(\n \"paid-prerequisite\",\n \"A sellable module cannot require another paid module.\",\n `${base}.prerequisiteModuleIds`,\n module.id,\n ),\n );\n }\n\n if (\n module.materials.learner.length === 0 ||\n module.materials.facilitator.length === 0\n ) {\n issues.push(\n issue(\n \"missing-materials\",\n \"Learner and facilitator material manifests are both required.\",\n `${base}.materials`,\n module.id,\n ),\n );\n }\n\n if (module.materials.learner.some((material) => material.audience !== \"learner\")) {\n issues.push(\n issue(\n \"facilitator-material-leak\",\n \"Learner material contains a facilitator-only record.\",\n `${base}.materials.learner`,\n module.id,\n ),\n );\n }\n\n if (\n module.materials.facilitator.some(\n (material) => material.audience !== \"facilitator\",\n )\n ) {\n issues.push(\n issue(\n \"learner-material-leak\",\n \"Facilitator material contains a learner record.\",\n `${base}.materials.facilitator`,\n module.id,\n ),\n );\n }\n\n if (!CANONICAL_TOKEN_SUBUNITS.test(module.pricing.tokenSubunits)) {\n issues.push(\n issue(\n \"invalid-token-subunits\",\n \"Token subunits must be a canonical non-negative base-10 integer string.\",\n `${base}.pricing.tokenSubunits`,\n module.id,\n ),\n );\n }\n\n const referencePrice = module.pricing.referencePrice;\n if (\n referencePrice\n && (\n referencePrice.currency !== \"GBP\"\n || !CANONICAL_TOKEN_SUBUNITS.test(referencePrice.minorUnits)\n || referencePrice.basis !== \"nominal-reference\"\n || referencePrice.cashRedemptionAllowed !== false\n )\n ) {\n issues.push(\n issue(\n \"invalid-reference-price\",\n \"Reference prices must use canonical GBP minor units, the nominal reference basis and prohibit cash redemption.\",\n `${base}.pricing.referencePrice`,\n module.id,\n ),\n );\n }\n\n issues.push(\n ...validateAssessmentRubric(module.assessment, `${base}.assessment`, module.id),\n );\n\n if (module.hardware.mode === \"physical-first\" && module.hardware.items.length === 0) {\n issues.push(\n issue(\n \"missing-hardware-items\",\n \"Physical-first modules require an exact hardware item list.\",\n `${base}.hardware.items`,\n module.id,\n ),\n );\n }\n\n if (\n module.agents.some(\n (agent) =>\n agent.mayAssignScore !== false ||\n agent.mayAwardReward !== false ||\n agent.mayPublish !== false ||\n agent.mayControlHardware !== false,\n )\n ) {\n issues.push(\n issue(\n \"invalid-agent-authority\",\n \"Module agents cannot own scores, rewards, publishing or hardware control.\",\n `${base}.agents`,\n module.id,\n ),\n );\n }\n\n if (module.missions.length === 0) {\n issues.push(\n issue(\n \"missing-missions\",\n \"A module requires at least one mission.\",\n `${base}.missions`,\n module.id,\n ),\n );\n }\n\n\n const externalContent = module.externalContent;\n if (\n externalContent\n && !isExternalLearningContentReferenceV1(externalContent)\n ) {\n issues.push(\n issue(\n \"invalid-external-content-reference\",\n \"External content must use an exact @plasius package, stable semantic version, named export, schema version and lower-case SHA-256 digest.\",\n `${base}.externalContent`,\n module.id,\n ),\n );\n }\n\n return issues;\n}\n\n/** Return every catalog issue without throwing, suitable for authoring tools. */\nexport function validateLearningPath(\n path: LearningPathVersionV1,\n): LearningValidationIssueV1[] {\n const issues: LearningValidationIssueV1[] = [];\n const moduleIds = new Set<string>();\n const moduleSlugs = new Set<string>();\n\n for (const [index, module] of path.modules.entries()) {\n if (moduleIds.has(module.id)) {\n issues.push(\n issue(\n \"duplicate-module-id\",\n `Duplicate module id ${module.id}.`,\n `modules[${index}].id`,\n module.id,\n ),\n );\n }\n moduleIds.add(module.id);\n\n if (moduleSlugs.has(module.slug)) {\n issues.push(\n issue(\n \"duplicate-module-slug\",\n `Duplicate module slug ${module.slug}.`,\n `modules[${index}].slug`,\n module.id,\n ),\n );\n }\n moduleSlugs.add(module.slug);\n issues.push(...validateModule(module, index));\n }\n\n return issues;\n}\n\n/** Fail fast when a path is not safe to publish or consume. */\nexport function assertValidLearningPath(path: LearningPathVersionV1): void {\n const issues = validateLearningPath(path);\n if (issues.length === 0) return;\n\n const summary = issues\n .map((entry) => `${entry.code} at ${entry.path}: ${entry.message}`)\n .join(\"\\n\");\n throw new Error(`Invalid learning path:\\n${summary}`);\n}\n\nexport { validateAssessmentRubric } from \"./rubric-validation.js\";\nexport {\n ADVENTURE_MISSION_PLANNER_MISSION_ONE_AUTHORING_V1,\n BEACON_BOT_MISSION_ONE_AUTHORING_V1,\n CREATURE_CARE_DASHBOARD_MISSION_ONE_AUTHORING_V1,\n DANCE_ROVER_MISSION_ONE_AUTHORING_V1,\n JUNIOR_CODER_MISSION_STAGE_ORDER_V1,\n METEOR_SHIELD_MISSION_ONE_AUTHORING_V1,\n OBSTACLE_EXPLORER_MISSION_ONE_AUTHORING_V1,\n PADDLE_PULSE_MISSION_ONE_AUTHORING_V1,\n PIXEL_TRAIL_CHALLENGE_MISSION_ONE_AUTHORING_V1,\n RAINBOW_RESCUE_ROVER_MISSION_ONE_AUTHORING_V1,\n RESCUE_CREW_COMMANDER_MISSION_ONE_AUTHORING_V1,\n ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1,\n ROBOT_MISSION_CONTROL_MISSION_ONE_AUTHORING_V1,\n ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1,\n SERVO_CREATURE_MISSION_ONE_AUTHORING_V1,\n SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1,\n STAR_DEFENDER_SQUADRON_MISSION_ONE_AUTHORING_V1,\n VIBE_BUG_DETECTIVE_MISSION_ONE_AUTHORING_V1,\n VIBE_GAME_REMIX_LAB_MISSION_ONE_AUTHORING_V1,\n VIBE_IDEA_STUDIO_MISSION_ONE_AUTHORING_V1,\n assertValidMissionAuthoringBundle,\n validateMissionAuthoringBundle,\n} from \"./mission-authoring.js\";\n"],"mappings":"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","names":["rubric","mission","mission","stage","record","keys","mission","mission","module"]}
|