@plasius/learning 0.2.1 → 0.2.3

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 CHANGED
@@ -64,19 +64,37 @@ the exact catalog module that owns its rubric, mission and badges.
64
64
  import {
65
65
  JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,
66
66
  ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1,
67
+ ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1,
68
+ SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1,
67
69
  assertValidMissionAuthoringBundle,
68
70
  } from "@plasius/learning";
69
71
 
70
72
  const roadHopper = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.find(
71
73
  (module) => module.slug === "road-hopper-rally",
72
74
  );
75
+ const robotMaze = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.find(
76
+ (module) => module.slug === "robot-maze-dash",
77
+ );
78
+ const skywing = JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1.modules.find(
79
+ (module) => module.slug === "skywing-sprint",
80
+ );
73
81
 
74
- if (!roadHopper) throw new Error("Road Hopper Rally is missing");
82
+ if (!roadHopper || !robotMaze || !skywing) {
83
+ throw new Error("Junior Coder module is missing");
84
+ }
75
85
 
76
86
  assertValidMissionAuthoringBundle(
77
87
  ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1,
78
88
  roadHopper,
79
89
  );
90
+ assertValidMissionAuthoringBundle(
91
+ ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1,
92
+ robotMaze,
93
+ );
94
+ assertValidMissionAuthoringBundle(
95
+ SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1,
96
+ skywing,
97
+ );
80
98
  ```
81
99
 
82
100
  ## Contract rules
@@ -92,6 +110,9 @@ assertValidMissionAuthoringBundle(
92
110
  → explain → reward`, and readiness checks never affect the score.
93
111
  - Learner evidence and rewards can bind only to visible goals; protected goal
94
112
  IDs stay in the facilitator projection.
113
+ - Visual-programming missions must provide an equivalent labelled control for
114
+ every drag interaction so learners can complete the same work with keyboard
115
+ or pointer buttons.
95
116
  - Rubric criteria total exactly 100 points.
96
117
  - Completion requires a score of at least 80 and every mandatory criterion.
97
118
  - Module agents may explain evidence and propose a bounded next step, but cannot assign scores or rewards.
package/dist/index.cjs CHANGED
@@ -27,6 +27,8 @@ __export(index_exports, {
27
27
  JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1: () => JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,
28
28
  MISSION_AUTHORING_CONTRACT_VERSION_V1: () => MISSION_AUTHORING_CONTRACT_VERSION_V1,
29
29
  ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1: () => ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1,
30
+ ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1: () => ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1,
31
+ SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1: () => SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1,
30
32
  assertValidLearningPath: () => assertValidLearningPath,
31
33
  assertValidMissionAuthoringBundle: () => assertValidMissionAuthoringBundle,
32
34
  calculateAssessment: () => calculateAssessment,
@@ -1126,6 +1128,440 @@ function assertValidMissionAuthoringBundle(bundle, module3) {
1126
1128
  throw new Error(`Invalid mission authoring bundle:
1127
1129
  ${summary}`);
1128
1130
  }
1131
+ var ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1 = {
1132
+ version: MISSION_AUTHORING_CONTRACT_VERSION_V1,
1133
+ moduleId: "junior-coder.robot-maze-dash",
1134
+ moduleVersion: "1.1.0",
1135
+ missionId: "robot-maze-dash-mission-1",
1136
+ learner: {
1137
+ estimatedMinutes: 20,
1138
+ stages: [
1139
+ {
1140
+ kind: "learn",
1141
+ instruction: "Meet the move, turn-left and turn-right action blocks and read what each command does.",
1142
+ artifactIds: ["robot-maze-dash-m1-art"]
1143
+ },
1144
+ {
1145
+ kind: "predict",
1146
+ instruction: "Predict where the robot will stop after it follows the blocks from top to bottom.",
1147
+ artifactIds: []
1148
+ },
1149
+ {
1150
+ kind: "build",
1151
+ instruction: "Arrange the action blocks so the rescue robot can reach the beacon.",
1152
+ artifactIds: ["robot-maze-dash-m1-program"]
1153
+ },
1154
+ {
1155
+ kind: "run",
1156
+ instruction: "Use the Run action button to watch the robot follow your visual program.",
1157
+ artifactIds: ["robot-maze-dash-m1-program"]
1158
+ },
1159
+ {
1160
+ kind: "assess",
1161
+ instruction: "Run the visible and protected deterministic mission checks.",
1162
+ artifactIds: []
1163
+ },
1164
+ {
1165
+ kind: "inspect",
1166
+ instruction: "Compare the highlighted block with the first goal that did not pass.",
1167
+ artifactIds: []
1168
+ },
1169
+ {
1170
+ kind: "fix",
1171
+ instruction: "Move, add or remove one action block, then run the mission again.",
1172
+ artifactIds: ["robot-maze-dash-m1-program"]
1173
+ },
1174
+ {
1175
+ kind: "explain",
1176
+ instruction: "Explain how the order of your blocks changed the robot path.",
1177
+ artifactIds: []
1178
+ },
1179
+ {
1180
+ kind: "reward",
1181
+ instruction: "Collect the evidence-bound badge when the score and safety check pass.",
1182
+ artifactIds: []
1183
+ }
1184
+ ],
1185
+ readinessChecks: [
1186
+ {
1187
+ id: "robot-maze-dash-m1-read-order",
1188
+ prompt: "Point to the first action the robot will follow.",
1189
+ scored: false
1190
+ }
1191
+ ],
1192
+ artifacts: [
1193
+ {
1194
+ id: "robot-maze-dash-m1-program",
1195
+ kind: "starter-code",
1196
+ audience: "learner",
1197
+ solutionBearing: false
1198
+ },
1199
+ {
1200
+ id: "robot-maze-dash-m1-art",
1201
+ kind: "starter-assets",
1202
+ audience: "learner",
1203
+ solutionBearing: false
1204
+ },
1205
+ {
1206
+ id: "robot-maze-dash-m1-printable",
1207
+ kind: "printable",
1208
+ audience: "learner",
1209
+ solutionBearing: false
1210
+ }
1211
+ ],
1212
+ goals: [
1213
+ {
1214
+ id: "robot-maze-dash-m1-starts",
1215
+ statement: "The visual program is structurally valid and starts.",
1216
+ visibility: "visible",
1217
+ criterionIds: ["robot-maze-dash-build"],
1218
+ completionRequired: true,
1219
+ aiRequired: false
1220
+ },
1221
+ {
1222
+ id: "robot-maze-dash-m1-reaches-beacon",
1223
+ statement: "The robot follows the action order and reaches the rescue beacon.",
1224
+ visibility: "visible",
1225
+ criterionIds: [
1226
+ "robot-maze-dash-goal-one",
1227
+ "robot-maze-dash-goal-two"
1228
+ ],
1229
+ completionRequired: true,
1230
+ aiRequired: false
1231
+ },
1232
+ {
1233
+ id: "robot-maze-dash-m1-safe-preview",
1234
+ statement: "The robot stays inside the private maze simulator boundary.",
1235
+ visibility: "visible",
1236
+ criterionIds: ["robot-maze-dash-safety"],
1237
+ completionRequired: true,
1238
+ aiRequired: false
1239
+ }
1240
+ ],
1241
+ interactions: [
1242
+ {
1243
+ id: "robot-maze-dash-m1-reorder-blocks",
1244
+ description: "Change the order of visual action blocks.",
1245
+ primaryMode: "drag",
1246
+ alternativeIds: ["robot-maze-dash-m1-button-reorder"]
1247
+ },
1248
+ {
1249
+ id: "robot-maze-dash-m1-run-control",
1250
+ description: "Start the private maze simulation.",
1251
+ primaryMode: "pointer",
1252
+ alternativeIds: ["robot-maze-dash-m1-keyboard-run"]
1253
+ }
1254
+ ],
1255
+ accessibilityAlternatives: [
1256
+ {
1257
+ id: "robot-maze-dash-m1-button-reorder",
1258
+ modes: ["keyboard", "pointer"],
1259
+ equivalentOutcome: true,
1260
+ description: "Use labelled Move up and Move down buttons instead of dragging a block."
1261
+ },
1262
+ {
1263
+ id: "robot-maze-dash-m1-keyboard-run",
1264
+ modes: ["keyboard"],
1265
+ equivalentOutcome: true,
1266
+ description: "Start the same simulation by pressing Enter or Space on the Run button."
1267
+ }
1268
+ ],
1269
+ evidenceRequirements: [
1270
+ {
1271
+ id: "robot-maze-dash-m1-assessment",
1272
+ goalIds: [
1273
+ "robot-maze-dash-m1-starts",
1274
+ "robot-maze-dash-m1-reaches-beacon",
1275
+ "robot-maze-dash-m1-safe-preview"
1276
+ ],
1277
+ kind: "assessment-result",
1278
+ retention: "entitlement",
1279
+ containsPersonalData: false
1280
+ },
1281
+ {
1282
+ id: "robot-maze-dash-m1-explanation",
1283
+ goalIds: ["robot-maze-dash-m1-reaches-beacon"],
1284
+ kind: "learner-explanation",
1285
+ retention: "attempt",
1286
+ containsPersonalData: false
1287
+ }
1288
+ ],
1289
+ sideAdventures: [
1290
+ {
1291
+ id: "robot-maze-dash-m1-remix",
1292
+ prompt: "Invent a different safe route and describe which action block must change first.",
1293
+ completionRequired: false
1294
+ }
1295
+ ],
1296
+ rewardBindings: [
1297
+ {
1298
+ id: "robot-maze-dash-m1-badge",
1299
+ badgeId: "robot-maze-dash-mission-complete",
1300
+ goalIds: [
1301
+ "robot-maze-dash-m1-starts",
1302
+ "robot-maze-dash-m1-reaches-beacon",
1303
+ "robot-maze-dash-m1-safe-preview"
1304
+ ],
1305
+ deterministic: true,
1306
+ random: false,
1307
+ tokenConvertible: false
1308
+ }
1309
+ ]
1310
+ },
1311
+ facilitator: {
1312
+ artifacts: [
1313
+ {
1314
+ id: "robot-maze-dash-m1-answer-key",
1315
+ kind: "answer-key",
1316
+ audience: "facilitator",
1317
+ solutionBearing: true
1318
+ },
1319
+ {
1320
+ id: "robot-maze-dash-m1-protected-tests",
1321
+ kind: "protected-test",
1322
+ audience: "facilitator",
1323
+ solutionBearing: true
1324
+ }
1325
+ ],
1326
+ protectedGoals: [
1327
+ {
1328
+ id: "robot-maze-dash-m1-protected-bounds",
1329
+ statement: "The interpreter stops safely at walls, bounds and its action limit.",
1330
+ visibility: "protected",
1331
+ criterionIds: [
1332
+ "robot-maze-dash-edge-one",
1333
+ "robot-maze-dash-edge-two"
1334
+ ],
1335
+ completionRequired: false,
1336
+ aiRequired: false
1337
+ }
1338
+ ],
1339
+ prompts: [
1340
+ "Ask the learner to point to the first action block before suggesting a change.",
1341
+ "Use the command reference and visible goal; never reveal the protected route or expected block list."
1342
+ ]
1343
+ }
1344
+ };
1345
+ var SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1 = {
1346
+ version: MISSION_AUTHORING_CONTRACT_VERSION_V1,
1347
+ moduleId: "junior-coder.skywing-sprint",
1348
+ moduleVersion: "1.1.0",
1349
+ missionId: "skywing-sprint-mission-1",
1350
+ learner: {
1351
+ estimatedMinutes: 20,
1352
+ stages: [
1353
+ {
1354
+ kind: "learn",
1355
+ instruction: "Read how lift, gravity and gate-gap functions change Skywing's flight.",
1356
+ artifactIds: ["skywing-sprint-m1-art"]
1357
+ },
1358
+ {
1359
+ kind: "predict",
1360
+ instruction: "Predict whether Skywing will rise or fall after one lift pulse.",
1361
+ artifactIds: []
1362
+ },
1363
+ {
1364
+ kind: "build",
1365
+ instruction: "Adjust the three documented settings in the starter JavaScript.",
1366
+ artifactIds: ["skywing-sprint-m1-code"]
1367
+ },
1368
+ {
1369
+ kind: "run",
1370
+ instruction: "Use the Run action button to start the private flight preview.",
1371
+ artifactIds: ["skywing-sprint-m1-code"]
1372
+ },
1373
+ {
1374
+ kind: "assess",
1375
+ instruction: "Run the visible and protected deterministic flight checks.",
1376
+ artifactIds: []
1377
+ },
1378
+ {
1379
+ kind: "inspect",
1380
+ instruction: "Compare the highlighted setting with the first goal that did not pass.",
1381
+ artifactIds: []
1382
+ },
1383
+ {
1384
+ kind: "fix",
1385
+ instruction: "Change one setting, run again and observe the flight telemetry.",
1386
+ artifactIds: ["skywing-sprint-m1-code"]
1387
+ },
1388
+ {
1389
+ kind: "explain",
1390
+ instruction: "Explain how lift and gravity changed Skywing's vertical speed.",
1391
+ artifactIds: []
1392
+ },
1393
+ {
1394
+ kind: "reward",
1395
+ instruction: "Collect the evidence-bound badge when the score and safety check pass.",
1396
+ artifactIds: []
1397
+ }
1398
+ ],
1399
+ readinessChecks: [
1400
+ {
1401
+ id: "skywing-sprint-m1-predict-velocity",
1402
+ prompt: "Point to the setting that changes Skywing's upward push.",
1403
+ scored: false
1404
+ }
1405
+ ],
1406
+ artifacts: [
1407
+ {
1408
+ id: "skywing-sprint-m1-code",
1409
+ kind: "starter-code",
1410
+ audience: "learner",
1411
+ solutionBearing: false
1412
+ },
1413
+ {
1414
+ id: "skywing-sprint-m1-art",
1415
+ kind: "starter-assets",
1416
+ audience: "learner",
1417
+ solutionBearing: false
1418
+ },
1419
+ {
1420
+ id: "skywing-sprint-m1-printable",
1421
+ kind: "printable",
1422
+ audience: "learner",
1423
+ solutionBearing: false
1424
+ }
1425
+ ],
1426
+ goals: [
1427
+ {
1428
+ id: "skywing-sprint-m1-starts",
1429
+ statement: "The JavaScript settings are valid and the private preview starts.",
1430
+ visibility: "visible",
1431
+ criterionIds: ["skywing-sprint-build"],
1432
+ completionRequired: true,
1433
+ aiRequired: false
1434
+ },
1435
+ {
1436
+ id: "skywing-sprint-m1-safe-flight",
1437
+ statement: "Lift and gravity create a controllable flight through the rescue gate.",
1438
+ visibility: "visible",
1439
+ criterionIds: [
1440
+ "skywing-sprint-goal-one",
1441
+ "skywing-sprint-goal-two"
1442
+ ],
1443
+ completionRequired: true,
1444
+ aiRequired: false
1445
+ },
1446
+ {
1447
+ id: "skywing-sprint-m1-private-runtime",
1448
+ statement: "The game stays inside the private educational preview boundary.",
1449
+ visibility: "visible",
1450
+ criterionIds: ["skywing-sprint-safety"],
1451
+ completionRequired: true,
1452
+ aiRequired: false
1453
+ }
1454
+ ],
1455
+ interactions: [
1456
+ {
1457
+ id: "skywing-sprint-m1-run-control",
1458
+ description: "Start the private flight simulation.",
1459
+ primaryMode: "pointer",
1460
+ alternativeIds: ["skywing-sprint-m1-keyboard-run"]
1461
+ },
1462
+ {
1463
+ id: "skywing-sprint-m1-flight-control",
1464
+ description: "Send a lift pulse while the preview is running.",
1465
+ primaryMode: "keyboard",
1466
+ alternativeIds: []
1467
+ },
1468
+ {
1469
+ id: "skywing-sprint-m1-flight-motion",
1470
+ description: "Observe Skywing moving through the animated gate preview.",
1471
+ primaryMode: "motion",
1472
+ alternativeIds: ["skywing-sprint-m1-reduced-motion"]
1473
+ }
1474
+ ],
1475
+ accessibilityAlternatives: [
1476
+ {
1477
+ id: "skywing-sprint-m1-keyboard-run",
1478
+ modes: ["keyboard"],
1479
+ equivalentOutcome: true,
1480
+ description: "Press Enter or Space on the play-icon Run button to start the same preview."
1481
+ },
1482
+ {
1483
+ id: "skywing-sprint-m1-reduced-motion",
1484
+ modes: ["text"],
1485
+ equivalentOutcome: true,
1486
+ description: "Use the position, velocity and gate-status text instead of animation."
1487
+ }
1488
+ ],
1489
+ evidenceRequirements: [
1490
+ {
1491
+ id: "skywing-sprint-m1-assessment",
1492
+ goalIds: [
1493
+ "skywing-sprint-m1-starts",
1494
+ "skywing-sprint-m1-safe-flight",
1495
+ "skywing-sprint-m1-private-runtime"
1496
+ ],
1497
+ kind: "assessment-result",
1498
+ retention: "entitlement",
1499
+ containsPersonalData: false
1500
+ },
1501
+ {
1502
+ id: "skywing-sprint-m1-explanation",
1503
+ goalIds: ["skywing-sprint-m1-safe-flight"],
1504
+ kind: "learner-explanation",
1505
+ retention: "attempt",
1506
+ containsPersonalData: false
1507
+ }
1508
+ ],
1509
+ sideAdventures: [
1510
+ {
1511
+ id: "skywing-sprint-m1-remix",
1512
+ prompt: "Invent a new gate name and choose one setting to make the flight gentler.",
1513
+ completionRequired: false
1514
+ }
1515
+ ],
1516
+ rewardBindings: [
1517
+ {
1518
+ id: "skywing-sprint-m1-badge",
1519
+ badgeId: "skywing-sprint-mission-complete",
1520
+ goalIds: [
1521
+ "skywing-sprint-m1-starts",
1522
+ "skywing-sprint-m1-safe-flight",
1523
+ "skywing-sprint-m1-private-runtime"
1524
+ ],
1525
+ deterministic: true,
1526
+ random: false,
1527
+ tokenConvertible: false
1528
+ }
1529
+ ]
1530
+ },
1531
+ facilitator: {
1532
+ artifacts: [
1533
+ {
1534
+ id: "skywing-sprint-m1-answer-key",
1535
+ kind: "answer-key",
1536
+ audience: "facilitator",
1537
+ solutionBearing: true
1538
+ },
1539
+ {
1540
+ id: "skywing-sprint-m1-protected-tests",
1541
+ kind: "protected-test",
1542
+ audience: "facilitator",
1543
+ solutionBearing: true
1544
+ }
1545
+ ],
1546
+ protectedGoals: [
1547
+ {
1548
+ id: "skywing-sprint-m1-protected-resilience",
1549
+ statement: "The runtime clamps unsafe values and terminates bounded simulations.",
1550
+ visibility: "protected",
1551
+ criterionIds: [
1552
+ "skywing-sprint-edge-one",
1553
+ "skywing-sprint-edge-two"
1554
+ ],
1555
+ completionRequired: false,
1556
+ aiRequired: false
1557
+ }
1558
+ ],
1559
+ prompts: [
1560
+ "Ask the learner which direction a positive velocity moves Skywing before suggesting a setting change.",
1561
+ "Use the visible telemetry and function reference; never reveal protected numeric targets or expected source fragments."
1562
+ ]
1563
+ }
1564
+ };
1129
1565
  var ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1 = {
1130
1566
  version: MISSION_AUTHORING_CONTRACT_VERSION_V1,
1131
1567
  moduleId: "junior-coder.road-hopper-rally",
@@ -1482,6 +1918,8 @@ ${summary}`);
1482
1918
  JUNIOR_CODER_ROBOT_RESCUE_PATH_V1_1,
1483
1919
  MISSION_AUTHORING_CONTRACT_VERSION_V1,
1484
1920
  ROAD_HOPPER_RALLY_MISSION_ONE_AUTHORING_V1,
1921
+ ROBOT_MAZE_DASH_MISSION_ONE_AUTHORING_V1,
1922
+ SKYWING_SPRINT_MISSION_ONE_AUTHORING_V1,
1485
1923
  assertValidLearningPath,
1486
1924
  assertValidMissionAuthoringBundle,
1487
1925
  calculateAssessment,