@stage5/lumine 0.3.29 → 0.3.30

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/lib/admin.js CHANGED
@@ -370,7 +370,7 @@ function buildApprovalOperation({ action, target, options }) {
370
370
  // Code agent passes wrote (no model is called), then review what they could
371
371
  // not settle (Mikey 2026-10-06: bulk AI work runs on Claude Code agents).
372
372
  const ENGLISH_USAGE =
373
- "Use: lumine admin english import <verdicts.json> --pass a|b | adjudicate <verdicts.json> | add-questions <questions.json> | relevel <moves.json> | mastery <userId> --reason <why> | backfill-distractors | summary | review [--limit <n>] | accept|retire <questionId> [--reason <text>] | retag <questionId> --skill <code> [--reason <text>] | build-candidates [--after <questionId>] [--limit <n>] | build-import <verdicts.json> | check-candidates [--after <questionId>] [--limit <n>] | check-import <verdicts.json> | check-broken [--after <questionId>] [--limit <n>] | check-apply <fixes.json> | check-verify <checked.json>";
373
+ "Use: lumine admin english import <verdicts.json> --pass a|b | adjudicate <verdicts.json> | add-questions <questions.json> | relevel <moves.json> | mastery <userId> --reason <why> | backfill-distractors | summary | review [--limit <n>] | accept|retire <questionId> [--reason <text>] [--fault] | retag <questionId> --skill <code> [--reason <text>] | build-candidates [--after <questionId>] [--limit <n>] | build-import <verdicts.json> | check-candidates [--after <questionId>] [--limit <n>] | check-import <verdicts.json> | check-broken [--after <questionId>] [--limit <n>] | check-apply <fixes.json> | check-verify <checked.json> | check-follow-faulty [--after <next>] [--limit <n>]";
374
374
  const ENGLISH_IMPORT_MAX = 500;
375
375
 
376
376
  function buildEnglishOperation({ action, target, options }) {
@@ -444,6 +444,14 @@ function buildEnglishOperation({ action, target, options }) {
444
444
  }
445
445
  return writeOperation("english.check_verify", "POST", "/cli/admin/english/item-checks/verify", { items }, { requiresRun: false, timeoutMs: 300000 });
446
446
  }
447
+ // the round-21 catch-up (boss misses uncounted, versions found at fault
448
+ // broken for every learner, every check followed again): one page per
449
+ // call, repeat with the reply's `next` until it is null
450
+ if (action === "check-follow-faulty") {
451
+ const after = options.adminAfter ? String(options.adminAfter) : "";
452
+ if (after && !/^(?:[ufc]:)?\d+:\d+$/.test(after)) throw cliValidationError("--after takes the last reply's next (<phase:id:version>).");
453
+ return writeOperation("english.check_follow_faulty", "POST", "/cli/admin/english/item-checks/follow-faulty", { after, limit: limitOf(200, 100) }, { requiresRun: false, timeoutMs: 300000 });
454
+ }
447
455
  if (action === "check-apply") {
448
456
  if (!target) throw cliValidationError(ENGLISH_USAGE);
449
457
  const raw = readAdminJsonFile(target, "<fixes.json>", { maxBytes: 4 * 1024 * 1024 });
@@ -487,7 +495,14 @@ function buildEnglishOperation({ action, target, options }) {
487
495
  "english.decide",
488
496
  "POST",
489
497
  `/cli/admin/english/review/${ref}`,
490
- { action, skillCode: options.adminSkill || undefined, reason: String(options.adminReason || "").trim() || undefined },
498
+ {
499
+ action,
500
+ skillCode: options.adminSkill || undefined,
501
+ reason: String(options.adminReason || "").trim() || undefined,
502
+ // retire --fault (Mikey 10-11): the question was at fault, so Grammar
503
+ // Quest forgives every miss on it; a duplicate or off-topic retire isn't
504
+ ...(action === "retire" && options.adminFault ? { fault: true } : {}),
505
+ },
491
506
  { requiresRun: false },
492
507
  );
493
508
  }
package/lib/commands.js CHANGED
@@ -2440,6 +2440,7 @@ export function parseArgs(args) {
2440
2440
  const positional = [];
2441
2441
  const booleanFlags = new Set([
2442
2442
  "remove",
2443
+ "fault",
2443
2444
  "noAnnounce",
2444
2445
  "noLeaseKeeper",
2445
2446
  "noOpen",
@@ -2759,6 +2760,8 @@ export function parseArgs(args) {
2759
2760
  twinkles: raw.twinkles ? String(raw.twinkles) : "",
2760
2761
  adminReason: raw.reason ? String(raw.reason) : "",
2761
2762
  adminSkill: raw.skill ? String(raw.skill) : "",
2763
+ // admin english retire --fault: the question was at fault (Grammar Quest forgives its misses)
2764
+ adminFault: Boolean(raw.fault),
2762
2765
  // --branch may repeat (a building two branches share); --branches A,B too
2763
2766
  adminBranch: [raw.branch, raw.branches].filter(Boolean).join(","),
2764
2767
  adminPass: raw.pass ? String(raw.pass) : "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stage5/lumine",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
4
4
  "description": "Command line tools for launching Lumine builds on Twinkle.",
5
5
  "type": "module",
6
6
  "bin": {