@plasius/learning 0.1.0 → 0.2.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 +25 -6
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,14 +6,22 @@ The package does **not** provide HTTP handlers, persistence, authentication, Tok
|
|
|
6
6
|
|
|
7
7
|
## Junior Coder catalog
|
|
8
8
|
|
|
9
|
-
The initial catalog is exported as
|
|
9
|
+
The initial immutable catalog is exported as
|
|
10
|
+
`JUNIOR_CODER_ROBOT_RESCUE_PATH_V1`. The current uniformly priced pilot
|
|
11
|
+
catalog is exported as `JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1`, with
|
|
12
|
+
`JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT` available to adapters that
|
|
13
|
+
intentionally follow published successors. Each contains 19 independently
|
|
14
|
+
sellable, self-contained project modules:
|
|
10
15
|
|
|
11
16
|
- 8 original arcade game modules;
|
|
12
17
|
- 5 simulator-backed robotics modules;
|
|
13
18
|
- 3 constrained Vibe Coding modules;
|
|
14
19
|
- 3 web application modules.
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
Both catalogs remain in `pilot-grant-only` commercial state. The immutable
|
|
22
|
+
`1.1.0` modules each cost 50 Tokens (50,000 subunits), carrying a
|
|
23
|
+
non-redeemable £5 reference value. Price metadata is not authorization to
|
|
24
|
+
enable public checkout.
|
|
17
25
|
|
|
18
26
|
## Install
|
|
19
27
|
|
|
@@ -25,11 +33,11 @@ npm install @plasius/learning
|
|
|
25
33
|
|
|
26
34
|
```ts
|
|
27
35
|
import {
|
|
28
|
-
|
|
36
|
+
JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT,
|
|
29
37
|
assertValidLearningPath,
|
|
30
38
|
} from "@plasius/learning";
|
|
31
39
|
|
|
32
|
-
assertValidLearningPath(
|
|
40
|
+
assertValidLearningPath(JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT);
|
|
33
41
|
```
|
|
34
42
|
|
|
35
43
|
## Calculate an assessment
|
|
@@ -49,14 +57,21 @@ console.log(result.score, result.completed);
|
|
|
49
57
|
## Contract rules
|
|
50
58
|
|
|
51
59
|
- Published IDs and versions are immutable.
|
|
60
|
+
- Reference prices are product-copy metadata and never create cash redemption
|
|
61
|
+
rights.
|
|
52
62
|
- A module entitlement must bind to an exact module version.
|
|
63
|
+
- `admin-test-grant` is distinct from pilot, support and paid purchase sources;
|
|
64
|
+
consuming services must not attach an economy transaction to it.
|
|
53
65
|
- Learner material never contains facilitator-only solutions or protected tests.
|
|
54
66
|
- Rubric criteria total exactly 100 points.
|
|
55
67
|
- Completion requires a score of at least 80 and every mandatory criterion.
|
|
56
68
|
- Module agents may explain evidence and propose a bounded next step, but cannot assign scores or rewards.
|
|
57
69
|
- Physical requirements are disclosed by a versioned manifest before purchase.
|
|
58
70
|
|
|
59
|
-
See [the foundation design](docs/design/junior-coder-catalog-foundation.md)
|
|
71
|
+
See [the foundation design](docs/design/junior-coder-catalog-foundation.md),
|
|
72
|
+
[the uniform pricing design](docs/design/junior-coder-uniform-pricing.md),
|
|
73
|
+
[ADR 0001](docs/adrs/adr-0001-learning-domain-and-catalog-boundary.md), and
|
|
74
|
+
[ADR 0002](docs/adrs/adr-0002-immutable-module-repricing-and-admin-test-source.md).
|
|
60
75
|
|
|
61
76
|
## Development
|
|
62
77
|
|
|
@@ -70,7 +85,11 @@ npm run pack:check
|
|
|
70
85
|
```
|
|
71
86
|
|
|
72
87
|
Node.js 24 is required. Releases are published only through the approved GitHub
|
|
73
|
-
CD workflow on configurable trusted self-hosted runners.
|
|
88
|
+
CD workflow on configurable trusted self-hosted runners. Both release jobs
|
|
89
|
+
explicitly select the approved `Public CI - Quarantined` runner group by
|
|
90
|
+
default, with `CD_RUNNER_GROUP` and `CD_RUNNER_LABELS` reserved for governed
|
|
91
|
+
operator configuration. The organisation group remains restricted to
|
|
92
|
+
allowlisted workflows and selected repositories. Release coverage and
|
|
74
93
|
the CycloneDX SBOM are retained even when an external coverage or provenance
|
|
75
94
|
service is unavailable. Release tags and GitHub Releases use a current-repository
|
|
76
95
|
GitHub App token with explicit Contents and Workflows write permissions; npm
|
package/dist/index.cjs
CHANGED
|
@@ -20,7 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
JUNIOR_CODER_MODULE_PRICE_V1_1: () => JUNIOR_CODER_MODULE_PRICE_V1_1,
|
|
24
|
+
JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT: () => JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT,
|
|
23
25
|
JUNIOR_CODER_ROBOT_RESCUE_PATH_V1: () => JUNIOR_CODER_ROBOT_RESCUE_PATH_V1,
|
|
26
|
+
JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1: () => JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,
|
|
24
27
|
assertValidLearningPath: () => assertValidLearningPath,
|
|
25
28
|
calculateAssessment: () => calculateAssessment,
|
|
26
29
|
validateLearningPath: () => validateLearningPath
|
|
@@ -561,6 +564,15 @@ var modules = [
|
|
|
561
564
|
missionTitles: ["Build the Control Panel", "Simulate Telemetry", "Add Stop Confirmations", "Mission Control Challenge"]
|
|
562
565
|
})
|
|
563
566
|
];
|
|
567
|
+
var JUNIOR_CODER_MODULE_PRICE_V1_1 = Object.freeze({
|
|
568
|
+
tokenSubunits: "50000",
|
|
569
|
+
referencePrice: Object.freeze({
|
|
570
|
+
currency: "GBP",
|
|
571
|
+
minorUnits: "500",
|
|
572
|
+
basis: "nominal-reference",
|
|
573
|
+
cashRedemptionAllowed: false
|
|
574
|
+
})
|
|
575
|
+
});
|
|
564
576
|
var JUNIOR_CODER_ROBOT_RESCUE_PATH_V1 = {
|
|
565
577
|
id: "junior-coder.robot-rescue-arcade",
|
|
566
578
|
slug: "robot-rescue-arcade",
|
|
@@ -572,6 +584,21 @@ var JUNIOR_CODER_ROBOT_RESCUE_PATH_V1 = {
|
|
|
572
584
|
featureFlag: "learning.junior-coder.catalog.enabled",
|
|
573
585
|
modules
|
|
574
586
|
};
|
|
587
|
+
var JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1 = {
|
|
588
|
+
...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1,
|
|
589
|
+
version: "1.1.0",
|
|
590
|
+
modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1.modules.map((entry) => ({
|
|
591
|
+
...entry,
|
|
592
|
+
version: "1.1.0",
|
|
593
|
+
contentRevision: "2026-07-28.1",
|
|
594
|
+
pricing: {
|
|
595
|
+
...entry.pricing,
|
|
596
|
+
tokenSubunits: JUNIOR_CODER_MODULE_PRICE_V1_1.tokenSubunits,
|
|
597
|
+
referencePrice: JUNIOR_CODER_MODULE_PRICE_V1_1.referencePrice
|
|
598
|
+
}
|
|
599
|
+
}))
|
|
600
|
+
};
|
|
601
|
+
var JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1;
|
|
575
602
|
|
|
576
603
|
// src/validation.ts
|
|
577
604
|
var DIMENSION_TOTALS = {
|
|
@@ -649,6 +676,17 @@ function validateModule(module3, moduleIndex) {
|
|
|
649
676
|
)
|
|
650
677
|
);
|
|
651
678
|
}
|
|
679
|
+
const referencePrice = module3.pricing.referencePrice;
|
|
680
|
+
if (referencePrice && (referencePrice.currency !== "GBP" || !CANONICAL_TOKEN_SUBUNITS.test(referencePrice.minorUnits) || referencePrice.basis !== "nominal-reference" || referencePrice.cashRedemptionAllowed !== false)) {
|
|
681
|
+
issues.push(
|
|
682
|
+
issue(
|
|
683
|
+
"invalid-reference-price",
|
|
684
|
+
"Reference prices must use canonical GBP minor units, the nominal reference basis and prohibit cash redemption.",
|
|
685
|
+
`${base}.pricing.referencePrice`,
|
|
686
|
+
module3.id
|
|
687
|
+
)
|
|
688
|
+
);
|
|
689
|
+
}
|
|
652
690
|
const criterionIds = /* @__PURE__ */ new Set();
|
|
653
691
|
const dimensionTotals = {
|
|
654
692
|
structure: 0,
|
|
@@ -780,7 +818,10 @@ ${summary}`);
|
|
|
780
818
|
}
|
|
781
819
|
// Annotate the CommonJS export names for ESM import in node:
|
|
782
820
|
0 && (module.exports = {
|
|
821
|
+
JUNIOR_CODER_MODULE_PRICE_V1_1,
|
|
822
|
+
JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT,
|
|
783
823
|
JUNIOR_CODER_ROBOT_RESCUE_PATH_V1,
|
|
824
|
+
JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,
|
|
784
825
|
assertValidLearningPath,
|
|
785
826
|
calculateAssessment,
|
|
786
827
|
validateLearningPath
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/assessment.ts","../src/catalog.ts","../src/validation.ts"],"sourcesContent":["export * from \"./assessment.js\";\nexport * from \"./catalog.js\";\nexport * from \"./contracts.js\";\nexport * from \"./validation.js\";\n","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/** 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","import type {\n AssessmentDimensionV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n LearningValidationIssueV1,\n} from \"./contracts.js\";\n\nconst DIMENSION_TOTALS: Record<AssessmentDimensionV1, number> = {\n structure: 20,\n behaviour: 50,\n resilience: 20,\n safety: 10,\n};\n\nconst CANONICAL_TOKEN_SUBUNITS = /^(0|[1-9][0-9]*)$/u;\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 criterionIds = new Set<string>();\n const dimensionTotals: Record<AssessmentDimensionV1, number> = {\n structure: 0,\n behaviour: 0,\n resilience: 0,\n safety: 0,\n };\n let rubricTotal = 0;\n\n for (const criterion of module.assessment.criteria) {\n rubricTotal += criterion.points;\n dimensionTotals[criterion.dimension] += criterion.points;\n if (criterionIds.has(criterion.id)) {\n issues.push(\n issue(\n \"duplicate-criterion-id\",\n `Duplicate assessment criterion ${criterion.id}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n criterionIds.add(criterion.id);\n }\n\n if (rubricTotal !== 100) {\n issues.push(\n issue(\n \"rubric-total\",\n `Assessment rubric totals ${rubricTotal}; expected 100.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n\n for (const [dimension, expected] of Object.entries(DIMENSION_TOTALS) as Array<\n [AssessmentDimensionV1, number]\n >) {\n if (dimensionTotals[dimension] !== expected) {\n issues.push(\n issue(\n \"rubric-dimension-total\",\n `${dimension} criteria total ${dimensionTotals[dimension]}; expected ${expected}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n }\n\n if (\n !module.assessment.criteria.some(\n (criterion) => criterion.dimension === \"safety\" && criterion.mandatory,\n )\n ) {\n issues.push(\n issue(\n \"missing-mandatory-safety\",\n \"Every module requires a mandatory safety criterion.\",\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\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 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"],"mappings":"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","names":["rubric","module","module"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/assessment.ts","../src/catalog.ts","../src/validation.ts"],"sourcesContent":["export * from \"./assessment.js\";\nexport * from \"./catalog.js\";\nexport * from \"./contracts.js\";\nexport * from \"./validation.js\";\n","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/** 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_1;\n","import type {\n AssessmentDimensionV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n LearningValidationIssueV1,\n} from \"./contracts.js\";\n\nconst DIMENSION_TOTALS: Record<AssessmentDimensionV1, number> = {\n structure: 20,\n behaviour: 50,\n resilience: 20,\n safety: 10,\n};\n\nconst CANONICAL_TOKEN_SUBUNITS = /^(0|[1-9][0-9]*)$/u;\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 const criterionIds = new Set<string>();\n const dimensionTotals: Record<AssessmentDimensionV1, number> = {\n structure: 0,\n behaviour: 0,\n resilience: 0,\n safety: 0,\n };\n let rubricTotal = 0;\n\n for (const criterion of module.assessment.criteria) {\n rubricTotal += criterion.points;\n dimensionTotals[criterion.dimension] += criterion.points;\n if (criterionIds.has(criterion.id)) {\n issues.push(\n issue(\n \"duplicate-criterion-id\",\n `Duplicate assessment criterion ${criterion.id}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n criterionIds.add(criterion.id);\n }\n\n if (rubricTotal !== 100) {\n issues.push(\n issue(\n \"rubric-total\",\n `Assessment rubric totals ${rubricTotal}; expected 100.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n\n for (const [dimension, expected] of Object.entries(DIMENSION_TOTALS) as Array<\n [AssessmentDimensionV1, number]\n >) {\n if (dimensionTotals[dimension] !== expected) {\n issues.push(\n issue(\n \"rubric-dimension-total\",\n `${dimension} criteria total ${dimensionTotals[dimension]}; expected ${expected}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n }\n\n if (\n !module.assessment.criteria.some(\n (criterion) => criterion.dimension === \"safety\" && criterion.mandatory,\n )\n ) {\n issues.push(\n issue(\n \"missing-mandatory-safety\",\n \"Every module requires a mandatory safety criterion.\",\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\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 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"],"mappings":"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","names":["rubric","module","module"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -118,9 +118,18 @@ interface ModuleAgentFeedbackV1 {
|
|
|
118
118
|
scoreAuthority: "deterministic-assessment";
|
|
119
119
|
}
|
|
120
120
|
/** Ordinary Token subunits used as a pilot shadow or fixed price. */
|
|
121
|
+
interface ModuleReferencePriceV1 {
|
|
122
|
+
/** Reference copy only; this is never a cash balance or redemption promise. */
|
|
123
|
+
currency: "GBP";
|
|
124
|
+
/** Canonical GBP minor units. */
|
|
125
|
+
minorUnits: string;
|
|
126
|
+
basis: "nominal-reference";
|
|
127
|
+
cashRedemptionAllowed: false;
|
|
128
|
+
}
|
|
121
129
|
interface ModulePricingV1 {
|
|
122
130
|
state: CommercialStateV1;
|
|
123
131
|
tokenSubunits: string;
|
|
132
|
+
referencePrice?: ModuleReferencePriceV1;
|
|
124
133
|
includesMaterials: true;
|
|
125
134
|
includesAssessmentRetries: true;
|
|
126
135
|
includesAgents: true;
|
|
@@ -173,7 +182,7 @@ interface ModuleEntitlementV1 {
|
|
|
173
182
|
subjectAccountId: string;
|
|
174
183
|
moduleId: string;
|
|
175
184
|
moduleVersion: string;
|
|
176
|
-
source: "pilot-grant" | "module-allowance-purchase" | "support-grant";
|
|
185
|
+
source: "pilot-grant" | "module-allowance-purchase" | "support-grant" | "admin-test-grant";
|
|
177
186
|
state: "pending" | "active" | "revoked";
|
|
178
187
|
economyTransactionId?: string;
|
|
179
188
|
grantedAt: string;
|
|
@@ -210,7 +219,7 @@ interface PublishedStaticProjectSnapshotV1 {
|
|
|
210
219
|
expiresAt: string;
|
|
211
220
|
}
|
|
212
221
|
interface LearningValidationIssueV1 {
|
|
213
|
-
code: "duplicate-module-id" | "duplicate-module-slug" | "module-not-self-contained" | "paid-prerequisite" | "missing-materials" | "facilitator-material-leak" | "learner-material-leak" | "invalid-token-subunits" | "rubric-total" | "rubric-dimension-total" | "duplicate-criterion-id" | "missing-mandatory-safety" | "missing-hardware-items" | "invalid-agent-authority" | "missing-missions";
|
|
222
|
+
code: "duplicate-module-id" | "duplicate-module-slug" | "module-not-self-contained" | "paid-prerequisite" | "missing-materials" | "facilitator-material-leak" | "learner-material-leak" | "invalid-token-subunits" | "invalid-reference-price" | "rubric-total" | "rubric-dimension-total" | "duplicate-criterion-id" | "missing-mandatory-safety" | "missing-hardware-items" | "invalid-agent-authority" | "missing-missions";
|
|
214
223
|
message: string;
|
|
215
224
|
moduleId?: string;
|
|
216
225
|
path: string;
|
|
@@ -222,12 +231,37 @@ interface LearningValidationIssueV1 {
|
|
|
222
231
|
*/
|
|
223
232
|
declare function calculateAssessment(rubric: AssessmentRubricV1, results: AssessmentCheckResultV1[]): AssessmentResultV1;
|
|
224
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Uniform price for the immutable 1.1.0 pilot catalog.
|
|
236
|
+
*
|
|
237
|
+
* The GBP value is product-copy reference metadata under the published
|
|
238
|
+
* 10p-per-Token economy reference rate. It does not create redemption rights.
|
|
239
|
+
*/
|
|
240
|
+
declare const JUNIOR_CODER_MODULE_PRICE_V1_1: Readonly<{
|
|
241
|
+
tokenSubunits: "50000";
|
|
242
|
+
referencePrice: Readonly<{
|
|
243
|
+
currency: "GBP";
|
|
244
|
+
minorUnits: "500";
|
|
245
|
+
basis: "nominal-reference";
|
|
246
|
+
cashRedemptionAllowed: false;
|
|
247
|
+
}>;
|
|
248
|
+
}>;
|
|
225
249
|
/** Initial immutable Junior Coder path manifest for pilot grants and shadow pricing. */
|
|
226
250
|
declare const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1: LearningPathVersionV1;
|
|
251
|
+
/**
|
|
252
|
+
* Uniformly priced successor to the immutable 1.0.0 pilot catalog.
|
|
253
|
+
*
|
|
254
|
+
* All modules remain independently sellable and retain their existing content,
|
|
255
|
+
* manifests and safeguards. The new module and path versions bind the new price
|
|
256
|
+
* without altering previously published records.
|
|
257
|
+
*/
|
|
258
|
+
declare const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1: LearningPathVersionV1;
|
|
259
|
+
/** Current pilot catalog for server adapters that intentionally follow releases. */
|
|
260
|
+
declare const JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT: LearningPathVersionV1;
|
|
227
261
|
|
|
228
262
|
/** Return every catalog issue without throwing, suitable for authoring tools. */
|
|
229
263
|
declare function validateLearningPath(path: LearningPathVersionV1): LearningValidationIssueV1[];
|
|
230
264
|
/** Fail fast when a path is not safe to publish or consume. */
|
|
231
265
|
declare function assertValidLearningPath(path: LearningPathVersionV1): void;
|
|
232
266
|
|
|
233
|
-
export { type AssessmentCheckResultV1, type AssessmentCriterionV1, type AssessmentDimensionV1, type AssessmentResultV1, type AssessmentRubricV1, type AttemptEvidenceV1, type BadgeDefinitionV1, type CommercialStateV1, type CourseMaterialAudienceV1, type CourseMaterialKindV1, type CourseMaterialV1, type CourseMaterialsManifestV1, type GuardianAiConsentV1, type HardwareItemV1, type HardwareModeV1, type HardwareRequirementManifestV1, type HardwareVerificationStatusV1, JUNIOR_CODER_ROBOT_RESCUE_PATH_V1, type LearningGoalV1, type LearningModuleVersionV1, type LearningPathVersionV1, type LearningValidationIssueV1, type MissionV1, type ModuleAgentDefinitionV1, type ModuleAgentFeedbackV1, type ModuleAgentRoleV1, type ModuleCategoryV1, type ModuleEntitlementV1, type ModulePricingV1, type PublishedStaticProjectSnapshotV1, type ScoreBandV1, assertValidLearningPath, calculateAssessment, validateLearningPath };
|
|
267
|
+
export { type AssessmentCheckResultV1, type AssessmentCriterionV1, type AssessmentDimensionV1, type AssessmentResultV1, type AssessmentRubricV1, type AttemptEvidenceV1, type BadgeDefinitionV1, type CommercialStateV1, type CourseMaterialAudienceV1, type CourseMaterialKindV1, type CourseMaterialV1, type CourseMaterialsManifestV1, type GuardianAiConsentV1, type HardwareItemV1, type HardwareModeV1, type HardwareRequirementManifestV1, type HardwareVerificationStatusV1, JUNIOR_CODER_MODULE_PRICE_V1_1, JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT, JUNIOR_CODER_ROBOT_RESCUE_PATH_V1, JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1, type LearningGoalV1, type LearningModuleVersionV1, type LearningPathVersionV1, type LearningValidationIssueV1, type MissionV1, type ModuleAgentDefinitionV1, type ModuleAgentFeedbackV1, type ModuleAgentRoleV1, type ModuleCategoryV1, type ModuleEntitlementV1, type ModulePricingV1, type ModuleReferencePriceV1, type PublishedStaticProjectSnapshotV1, type ScoreBandV1, assertValidLearningPath, calculateAssessment, validateLearningPath };
|
package/dist/index.d.ts
CHANGED
|
@@ -118,9 +118,18 @@ interface ModuleAgentFeedbackV1 {
|
|
|
118
118
|
scoreAuthority: "deterministic-assessment";
|
|
119
119
|
}
|
|
120
120
|
/** Ordinary Token subunits used as a pilot shadow or fixed price. */
|
|
121
|
+
interface ModuleReferencePriceV1 {
|
|
122
|
+
/** Reference copy only; this is never a cash balance or redemption promise. */
|
|
123
|
+
currency: "GBP";
|
|
124
|
+
/** Canonical GBP minor units. */
|
|
125
|
+
minorUnits: string;
|
|
126
|
+
basis: "nominal-reference";
|
|
127
|
+
cashRedemptionAllowed: false;
|
|
128
|
+
}
|
|
121
129
|
interface ModulePricingV1 {
|
|
122
130
|
state: CommercialStateV1;
|
|
123
131
|
tokenSubunits: string;
|
|
132
|
+
referencePrice?: ModuleReferencePriceV1;
|
|
124
133
|
includesMaterials: true;
|
|
125
134
|
includesAssessmentRetries: true;
|
|
126
135
|
includesAgents: true;
|
|
@@ -173,7 +182,7 @@ interface ModuleEntitlementV1 {
|
|
|
173
182
|
subjectAccountId: string;
|
|
174
183
|
moduleId: string;
|
|
175
184
|
moduleVersion: string;
|
|
176
|
-
source: "pilot-grant" | "module-allowance-purchase" | "support-grant";
|
|
185
|
+
source: "pilot-grant" | "module-allowance-purchase" | "support-grant" | "admin-test-grant";
|
|
177
186
|
state: "pending" | "active" | "revoked";
|
|
178
187
|
economyTransactionId?: string;
|
|
179
188
|
grantedAt: string;
|
|
@@ -210,7 +219,7 @@ interface PublishedStaticProjectSnapshotV1 {
|
|
|
210
219
|
expiresAt: string;
|
|
211
220
|
}
|
|
212
221
|
interface LearningValidationIssueV1 {
|
|
213
|
-
code: "duplicate-module-id" | "duplicate-module-slug" | "module-not-self-contained" | "paid-prerequisite" | "missing-materials" | "facilitator-material-leak" | "learner-material-leak" | "invalid-token-subunits" | "rubric-total" | "rubric-dimension-total" | "duplicate-criterion-id" | "missing-mandatory-safety" | "missing-hardware-items" | "invalid-agent-authority" | "missing-missions";
|
|
222
|
+
code: "duplicate-module-id" | "duplicate-module-slug" | "module-not-self-contained" | "paid-prerequisite" | "missing-materials" | "facilitator-material-leak" | "learner-material-leak" | "invalid-token-subunits" | "invalid-reference-price" | "rubric-total" | "rubric-dimension-total" | "duplicate-criterion-id" | "missing-mandatory-safety" | "missing-hardware-items" | "invalid-agent-authority" | "missing-missions";
|
|
214
223
|
message: string;
|
|
215
224
|
moduleId?: string;
|
|
216
225
|
path: string;
|
|
@@ -222,12 +231,37 @@ interface LearningValidationIssueV1 {
|
|
|
222
231
|
*/
|
|
223
232
|
declare function calculateAssessment(rubric: AssessmentRubricV1, results: AssessmentCheckResultV1[]): AssessmentResultV1;
|
|
224
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Uniform price for the immutable 1.1.0 pilot catalog.
|
|
236
|
+
*
|
|
237
|
+
* The GBP value is product-copy reference metadata under the published
|
|
238
|
+
* 10p-per-Token economy reference rate. It does not create redemption rights.
|
|
239
|
+
*/
|
|
240
|
+
declare const JUNIOR_CODER_MODULE_PRICE_V1_1: Readonly<{
|
|
241
|
+
tokenSubunits: "50000";
|
|
242
|
+
referencePrice: Readonly<{
|
|
243
|
+
currency: "GBP";
|
|
244
|
+
minorUnits: "500";
|
|
245
|
+
basis: "nominal-reference";
|
|
246
|
+
cashRedemptionAllowed: false;
|
|
247
|
+
}>;
|
|
248
|
+
}>;
|
|
225
249
|
/** Initial immutable Junior Coder path manifest for pilot grants and shadow pricing. */
|
|
226
250
|
declare const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1: LearningPathVersionV1;
|
|
251
|
+
/**
|
|
252
|
+
* Uniformly priced successor to the immutable 1.0.0 pilot catalog.
|
|
253
|
+
*
|
|
254
|
+
* All modules remain independently sellable and retain their existing content,
|
|
255
|
+
* manifests and safeguards. The new module and path versions bind the new price
|
|
256
|
+
* without altering previously published records.
|
|
257
|
+
*/
|
|
258
|
+
declare const JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1: LearningPathVersionV1;
|
|
259
|
+
/** Current pilot catalog for server adapters that intentionally follow releases. */
|
|
260
|
+
declare const JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT: LearningPathVersionV1;
|
|
227
261
|
|
|
228
262
|
/** Return every catalog issue without throwing, suitable for authoring tools. */
|
|
229
263
|
declare function validateLearningPath(path: LearningPathVersionV1): LearningValidationIssueV1[];
|
|
230
264
|
/** Fail fast when a path is not safe to publish or consume. */
|
|
231
265
|
declare function assertValidLearningPath(path: LearningPathVersionV1): void;
|
|
232
266
|
|
|
233
|
-
export { type AssessmentCheckResultV1, type AssessmentCriterionV1, type AssessmentDimensionV1, type AssessmentResultV1, type AssessmentRubricV1, type AttemptEvidenceV1, type BadgeDefinitionV1, type CommercialStateV1, type CourseMaterialAudienceV1, type CourseMaterialKindV1, type CourseMaterialV1, type CourseMaterialsManifestV1, type GuardianAiConsentV1, type HardwareItemV1, type HardwareModeV1, type HardwareRequirementManifestV1, type HardwareVerificationStatusV1, JUNIOR_CODER_ROBOT_RESCUE_PATH_V1, type LearningGoalV1, type LearningModuleVersionV1, type LearningPathVersionV1, type LearningValidationIssueV1, type MissionV1, type ModuleAgentDefinitionV1, type ModuleAgentFeedbackV1, type ModuleAgentRoleV1, type ModuleCategoryV1, type ModuleEntitlementV1, type ModulePricingV1, type PublishedStaticProjectSnapshotV1, type ScoreBandV1, assertValidLearningPath, calculateAssessment, validateLearningPath };
|
|
267
|
+
export { type AssessmentCheckResultV1, type AssessmentCriterionV1, type AssessmentDimensionV1, type AssessmentResultV1, type AssessmentRubricV1, type AttemptEvidenceV1, type BadgeDefinitionV1, type CommercialStateV1, type CourseMaterialAudienceV1, type CourseMaterialKindV1, type CourseMaterialV1, type CourseMaterialsManifestV1, type GuardianAiConsentV1, type HardwareItemV1, type HardwareModeV1, type HardwareRequirementManifestV1, type HardwareVerificationStatusV1, JUNIOR_CODER_MODULE_PRICE_V1_1, JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT, JUNIOR_CODER_ROBOT_RESCUE_PATH_V1, JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1, type LearningGoalV1, type LearningModuleVersionV1, type LearningPathVersionV1, type LearningValidationIssueV1, type MissionV1, type ModuleAgentDefinitionV1, type ModuleAgentFeedbackV1, type ModuleAgentRoleV1, type ModuleCategoryV1, type ModuleEntitlementV1, type ModulePricingV1, type ModuleReferencePriceV1, type PublishedStaticProjectSnapshotV1, type ScoreBandV1, assertValidLearningPath, calculateAssessment, validateLearningPath };
|
package/dist/index.js
CHANGED
|
@@ -532,6 +532,15 @@ var modules = [
|
|
|
532
532
|
missionTitles: ["Build the Control Panel", "Simulate Telemetry", "Add Stop Confirmations", "Mission Control Challenge"]
|
|
533
533
|
})
|
|
534
534
|
];
|
|
535
|
+
var JUNIOR_CODER_MODULE_PRICE_V1_1 = Object.freeze({
|
|
536
|
+
tokenSubunits: "50000",
|
|
537
|
+
referencePrice: Object.freeze({
|
|
538
|
+
currency: "GBP",
|
|
539
|
+
minorUnits: "500",
|
|
540
|
+
basis: "nominal-reference",
|
|
541
|
+
cashRedemptionAllowed: false
|
|
542
|
+
})
|
|
543
|
+
});
|
|
535
544
|
var JUNIOR_CODER_ROBOT_RESCUE_PATH_V1 = {
|
|
536
545
|
id: "junior-coder.robot-rescue-arcade",
|
|
537
546
|
slug: "robot-rescue-arcade",
|
|
@@ -543,6 +552,21 @@ var JUNIOR_CODER_ROBOT_RESCUE_PATH_V1 = {
|
|
|
543
552
|
featureFlag: "learning.junior-coder.catalog.enabled",
|
|
544
553
|
modules
|
|
545
554
|
};
|
|
555
|
+
var JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1 = {
|
|
556
|
+
...JUNIOR_CODER_ROBOT_RESCUE_PATH_V1,
|
|
557
|
+
version: "1.1.0",
|
|
558
|
+
modules: JUNIOR_CODER_ROBOT_RESCUE_PATH_V1.modules.map((entry) => ({
|
|
559
|
+
...entry,
|
|
560
|
+
version: "1.1.0",
|
|
561
|
+
contentRevision: "2026-07-28.1",
|
|
562
|
+
pricing: {
|
|
563
|
+
...entry.pricing,
|
|
564
|
+
tokenSubunits: JUNIOR_CODER_MODULE_PRICE_V1_1.tokenSubunits,
|
|
565
|
+
referencePrice: JUNIOR_CODER_MODULE_PRICE_V1_1.referencePrice
|
|
566
|
+
}
|
|
567
|
+
}))
|
|
568
|
+
};
|
|
569
|
+
var JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1;
|
|
546
570
|
|
|
547
571
|
// src/validation.ts
|
|
548
572
|
var DIMENSION_TOTALS = {
|
|
@@ -620,6 +644,17 @@ function validateModule(module2, moduleIndex) {
|
|
|
620
644
|
)
|
|
621
645
|
);
|
|
622
646
|
}
|
|
647
|
+
const referencePrice = module2.pricing.referencePrice;
|
|
648
|
+
if (referencePrice && (referencePrice.currency !== "GBP" || !CANONICAL_TOKEN_SUBUNITS.test(referencePrice.minorUnits) || referencePrice.basis !== "nominal-reference" || referencePrice.cashRedemptionAllowed !== false)) {
|
|
649
|
+
issues.push(
|
|
650
|
+
issue(
|
|
651
|
+
"invalid-reference-price",
|
|
652
|
+
"Reference prices must use canonical GBP minor units, the nominal reference basis and prohibit cash redemption.",
|
|
653
|
+
`${base}.pricing.referencePrice`,
|
|
654
|
+
module2.id
|
|
655
|
+
)
|
|
656
|
+
);
|
|
657
|
+
}
|
|
623
658
|
const criterionIds = /* @__PURE__ */ new Set();
|
|
624
659
|
const dimensionTotals = {
|
|
625
660
|
structure: 0,
|
|
@@ -750,7 +785,10 @@ function assertValidLearningPath(path) {
|
|
|
750
785
|
${summary}`);
|
|
751
786
|
}
|
|
752
787
|
export {
|
|
788
|
+
JUNIOR_CODER_MODULE_PRICE_V1_1,
|
|
789
|
+
JUNIOR_CODER_ROBOT_RESCUE_PATH_CURRENT,
|
|
753
790
|
JUNIOR_CODER_ROBOT_RESCUE_PATH_V1,
|
|
791
|
+
JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,
|
|
754
792
|
assertValidLearningPath,
|
|
755
793
|
calculateAssessment,
|
|
756
794
|
validateLearningPath
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/assessment.ts","../src/catalog.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/** 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","import type {\n AssessmentDimensionV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n LearningValidationIssueV1,\n} from \"./contracts.js\";\n\nconst DIMENSION_TOTALS: Record<AssessmentDimensionV1, number> = {\n structure: 20,\n behaviour: 50,\n resilience: 20,\n safety: 10,\n};\n\nconst CANONICAL_TOKEN_SUBUNITS = /^(0|[1-9][0-9]*)$/u;\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 criterionIds = new Set<string>();\n const dimensionTotals: Record<AssessmentDimensionV1, number> = {\n structure: 0,\n behaviour: 0,\n resilience: 0,\n safety: 0,\n };\n let rubricTotal = 0;\n\n for (const criterion of module.assessment.criteria) {\n rubricTotal += criterion.points;\n dimensionTotals[criterion.dimension] += criterion.points;\n if (criterionIds.has(criterion.id)) {\n issues.push(\n issue(\n \"duplicate-criterion-id\",\n `Duplicate assessment criterion ${criterion.id}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n criterionIds.add(criterion.id);\n }\n\n if (rubricTotal !== 100) {\n issues.push(\n issue(\n \"rubric-total\",\n `Assessment rubric totals ${rubricTotal}; expected 100.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n\n for (const [dimension, expected] of Object.entries(DIMENSION_TOTALS) as Array<\n [AssessmentDimensionV1, number]\n >) {\n if (dimensionTotals[dimension] !== expected) {\n issues.push(\n issue(\n \"rubric-dimension-total\",\n `${dimension} criteria total ${dimensionTotals[dimension]}; expected ${expected}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n }\n\n if (\n !module.assessment.criteria.some(\n (criterion) => criterion.dimension === \"safety\" && criterion.mandatory,\n )\n ) {\n issues.push(\n issue(\n \"missing-mandatory-safety\",\n \"Every module requires a mandatory safety criterion.\",\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\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 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"],"mappings":"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","names":["rubric","module"]}
|
|
1
|
+
{"version":3,"sources":["../src/assessment.ts","../src/catalog.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/** 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_1;\n","import type {\n AssessmentDimensionV1,\n LearningModuleVersionV1,\n LearningPathVersionV1,\n LearningValidationIssueV1,\n} from \"./contracts.js\";\n\nconst DIMENSION_TOTALS: Record<AssessmentDimensionV1, number> = {\n structure: 20,\n behaviour: 50,\n resilience: 20,\n safety: 10,\n};\n\nconst CANONICAL_TOKEN_SUBUNITS = /^(0|[1-9][0-9]*)$/u;\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 const criterionIds = new Set<string>();\n const dimensionTotals: Record<AssessmentDimensionV1, number> = {\n structure: 0,\n behaviour: 0,\n resilience: 0,\n safety: 0,\n };\n let rubricTotal = 0;\n\n for (const criterion of module.assessment.criteria) {\n rubricTotal += criterion.points;\n dimensionTotals[criterion.dimension] += criterion.points;\n if (criterionIds.has(criterion.id)) {\n issues.push(\n issue(\n \"duplicate-criterion-id\",\n `Duplicate assessment criterion ${criterion.id}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n criterionIds.add(criterion.id);\n }\n\n if (rubricTotal !== 100) {\n issues.push(\n issue(\n \"rubric-total\",\n `Assessment rubric totals ${rubricTotal}; expected 100.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n\n for (const [dimension, expected] of Object.entries(DIMENSION_TOTALS) as Array<\n [AssessmentDimensionV1, number]\n >) {\n if (dimensionTotals[dimension] !== expected) {\n issues.push(\n issue(\n \"rubric-dimension-total\",\n `${dimension} criteria total ${dimensionTotals[dimension]}; expected ${expected}.`,\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\n }\n }\n\n if (\n !module.assessment.criteria.some(\n (criterion) => criterion.dimension === \"safety\" && criterion.mandatory,\n )\n ) {\n issues.push(\n issue(\n \"missing-mandatory-safety\",\n \"Every module requires a mandatory safety criterion.\",\n `${base}.assessment.criteria`,\n module.id,\n ),\n );\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 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"],"mappings":"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","names":["rubric","module"]}
|
package/package.json
CHANGED