@stage5/lumine 0.2.66 → 0.2.68

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
@@ -8,6 +8,7 @@ import {
8
8
  readAdminJsonFile,
9
9
  validateNewsEditorial,
10
10
  writeNewsClaimArtifacts,
11
+ writeAdminJsonFile,
11
12
  } from "./admin-news.js";
12
13
  import {
13
14
  forEachPaginatedResultItem,
@@ -20,6 +21,8 @@ import {
20
21
  parseBuildReviewReceipt,
21
22
  runManagedBuildReview,
22
23
  } from "./build-review.js";
24
+ import { runAdminRuntimeLogWorkflow } from "./admin-runtime-logs.js";
25
+ import { readApprovedFeaturedPlan, runFeaturedWorkflow } from "./admin-featured.js";
23
26
 
24
27
  const MAX_EDITORIAL_FILE_BYTES = 256 * 1024;
25
28
  const MAX_COMPOSED_TEXT_FILE_BYTES = 64 * 1024;
@@ -242,7 +245,7 @@ export async function adminCommand(options) {
242
245
  options.idempotencyKey || (operation.mutates ? `cli:${randomUUID()}` : "");
243
246
  let result;
244
247
  try {
245
- const fetchOperation = async (requestPath = operation.path) =>
248
+ const fetchOperation = async (requestPath = operation.path, signal) =>
246
249
  requestJson({
247
250
  method: operation.method,
248
251
  url: `${options.apiUrl}${requestPath}`,
@@ -252,14 +255,14 @@ export async function adminCommand(options) {
252
255
  ...(runId ? { "x-lumine-admin-run-id": String(runId) } : {}),
253
256
  ...(correctionSessionId
254
257
  ? {
255
- "x-lumine-admin-correction-session-id": String(
256
- correctionSessionId,
257
- ),
258
+ "x-lumine-admin-correction-session-id":
259
+ String(correctionSessionId),
258
260
  }
259
261
  : {}),
260
262
  ...(requestId ? { "x-lumine-idempotency-key": requestId } : {}),
261
263
  },
262
264
  timeoutMs: options.timeoutMs,
265
+ signal,
263
266
  });
264
267
  const transformResult = (rawResult) =>
265
268
  transformAdminResult({
@@ -269,7 +272,9 @@ export async function adminCommand(options) {
269
272
  recommendationContentTypes,
270
273
  viewFilter,
271
274
  });
272
- if (operation.name === "build.review") {
275
+ if (operation.featuredWorkflow) {
276
+ result = await runFeaturedWorkflow({ options, operation, authToken: auth.token, runId });
277
+ } else if (operation.name === "build.review") {
273
278
  result = await runManagedBuildReview({
274
279
  options,
275
280
  authToken: auth.token,
@@ -282,6 +287,13 @@ export async function adminCommand(options) {
282
287
  runId,
283
288
  parseTarget: parseRecommendationTarget,
284
289
  });
290
+ } else if (operation.name.startsWith("runtime-logs.")) {
291
+ result = await runAdminRuntimeLogWorkflow({
292
+ options,
293
+ operation,
294
+ authToken: auth.token,
295
+ requestId,
296
+ });
285
297
  } else if (options.adminAll) {
286
298
  if (options.adminCursor) {
287
299
  throw cliValidationError(
@@ -295,7 +307,7 @@ export async function adminCommand(options) {
295
307
  fetchPage: fetchOperation,
296
308
  transformPage: transformResult,
297
309
  recordCoverage: shouldRecordAdminQueueCoverage(runScope)
298
- ? async (coverage) =>
310
+ ? async (coverage, signal) =>
299
311
  requestJson({
300
312
  method: "POST",
301
313
  url: `${options.apiUrl}/cli/admin/daily-runs/coverage`,
@@ -306,6 +318,7 @@ export async function adminCommand(options) {
306
318
  "x-lumine-idempotency-key": `cli:queue-coverage:${runId}:${adminValueFingerprint(coverage).slice(0, 32)}`,
307
319
  },
308
320
  timeoutMs: options.timeoutMs,
321
+ signal,
309
322
  })
310
323
  : undefined,
311
324
  });
@@ -316,9 +329,26 @@ export async function adminCommand(options) {
316
329
  result = transformResult(await fetchOperation());
317
330
  }
318
331
  } catch (error) {
332
+ if (operation.featuredWorkflow && error.featuredProgress) {
333
+ const serverError = error.data?.error;
334
+ error.data = {
335
+ ok: false,
336
+ status: "partial_failure",
337
+ error: {
338
+ code: serverError?.code || error.code || "LUMINE_ADMIN_FEATURED_WORKFLOW_FAILED",
339
+ message: error.message,
340
+ details: {
341
+ ...(serverError && typeof serverError === "object" ? serverError.details : {}),
342
+ ...error.featuredProgress,
343
+ retryInstruction: "Resume the exact command with --resume; confirmed items are not replayed.",
344
+ },
345
+ },
346
+ };
347
+ }
319
348
  if (
320
349
  operation.mutates &&
321
350
  requestId &&
351
+ !operation.featuredWorkflow &&
322
352
  operation.name !== "post.skip-batch"
323
353
  ) {
324
354
  const retryInstruction = `Retry with --idempotency-key ${requestId}.`;
@@ -389,6 +419,9 @@ function transformAdminResult({
389
419
  if (operation.name === "recommendations.list") {
390
420
  assertRecommendationWindowResult({ operation, result: transformed });
391
421
  }
422
+ if (operation.name === "subjects.candidates") {
423
+ assertSubjectWindowResult({ operation, result: transformed });
424
+ }
392
425
  if (operation.name === "builds.candidates") {
393
426
  transformed = normalizeAdminBuildCandidatesResult({
394
427
  result: transformed,
@@ -438,8 +471,44 @@ export function assertRecommendationWindowResult({ operation, result }) {
438
471
  }
439
472
  }
440
473
 
474
+ export function assertSubjectWindowResult({ operation, result }) {
475
+ const mode = operation?.pagination?.coverageMode;
476
+ if (!mode || mode === "legacy") return;
477
+ const after = result?.data?.pagination?.after;
478
+ const snapshotTimeStamp = result?.data?.pagination?.snapshotTimeStamp;
479
+ if (
480
+ !Number.isSafeInteger(after) ||
481
+ after < 0 ||
482
+ !Number.isSafeInteger(snapshotTimeStamp) ||
483
+ snapshotTimeStamp < 0
484
+ ) {
485
+ const error = new Error(
486
+ "The deployed API did not confirm the bounded Subject window and snapshot. Deploy the matching API before using this CLI; use --include-legacy only for an intentional historical scan.",
487
+ );
488
+ error.code = "LUMINE_ADMIN_SUBJECT_WINDOW_UNSUPPORTED";
489
+ error.data = {
490
+ ok: false,
491
+ status: "validation_error",
492
+ error: {
493
+ code: error.code,
494
+ message: error.message,
495
+ details: { requestedMode: mode },
496
+ },
497
+ };
498
+ throw error;
499
+ }
500
+ }
501
+
441
502
  async function finishAdminOutput({ options, operation, result }) {
442
503
  const paginationStorage = getPaginatedResultStorage(result);
504
+ if (
505
+ options.adminOutput &&
506
+ !paginationStorage &&
507
+ operation.name !== "news.claim" &&
508
+ operation.name !== "post.skip-batch"
509
+ ) {
510
+ writeAdminResultOutput({ filePath: options.adminOutput, result, operation });
511
+ }
443
512
  if (options.json) {
444
513
  if (paginationStorage) {
445
514
  await writePaginatedResultJson({
@@ -467,6 +536,27 @@ async function finishAdminOutput({ options, operation, result }) {
467
536
  return result;
468
537
  }
469
538
 
539
+ export function writeAdminResultOutput({ filePath, result, operation }) {
540
+ try {
541
+ return writeAdminJsonFile(filePath, result, { privateFile: true });
542
+ } catch (cause) {
543
+ const error = new Error(
544
+ `The canonical ${operation.name} result was received, but --output could not be saved: ${cause.message}. Do not repeat a successful mutation just to save its output.`,
545
+ );
546
+ error.code = "LUMINE_ADMIN_OUTPUT_WRITE_FAILED";
547
+ error.data = {
548
+ ok: false,
549
+ status: "error",
550
+ error: {
551
+ code: error.code,
552
+ message: error.message,
553
+ details: { canonicalResult: result, outputPath: String(filePath) },
554
+ },
555
+ };
556
+ throw error;
557
+ }
558
+ }
559
+
470
560
  export function normalizeAdminBuildCandidatesResult({ result, siteUrl }) {
471
561
  const builds = Array.isArray(result?.builds) ? result.builds : [];
472
562
  const nextCursor = String(result?.cursor || "").trim() || null;
@@ -716,8 +806,10 @@ export function canonicalAdminRunScope(run) {
716
806
  const raw = run?.runScope;
717
807
  if (raw === undefined || raw === null || raw === "") return "full";
718
808
  const scope = String(raw);
719
- if (scope === "full" || scope === "featured") return scope;
720
- throw cliValidationError("The API returned an invalid administrator run scope.");
809
+ if (["full", "featured", "newspaper"].includes(scope)) return scope;
810
+ throw cliValidationError(
811
+ "The API returned an invalid administrator run scope.",
812
+ );
721
813
  }
722
814
 
723
815
  export function shouldRecordAdminQueueCoverage(runScope) {
@@ -736,6 +828,12 @@ const FEATURED_RUN_OPERATIONS = new Set([
736
828
  "featured.add",
737
829
  "featured.reorder",
738
830
  "featured.rotate",
831
+ "featured.plan",
832
+ "featured.apply",
833
+ "featured.comments.scan",
834
+ "featured.comments.acknowledge",
835
+ "featured.comments.recommend",
836
+ "featured.comments.report",
739
837
  "daily-run.complete",
740
838
  "daily-run.fail",
741
839
  ]);
@@ -744,6 +842,14 @@ export function assertAdminOperationAllowedForRunScope({
744
842
  operation,
745
843
  runScope,
746
844
  }) {
845
+ if (runScope === "newspaper") {
846
+ if (
847
+ ["news.status", "news.claim", "news.submit", "news.print", "daily-run.complete", "daily-run.fail"].includes(operation.name)
848
+ ) return;
849
+ throw cliValidationError(
850
+ `A newspaper-only run does not authorize ${operation.name}.`,
851
+ );
852
+ }
747
853
  if (runScope !== "featured") return;
748
854
  const subjectCommentAlias =
749
855
  operation.name === "post.comments" &&
@@ -752,11 +858,14 @@ export function assertAdminOperationAllowedForRunScope({
752
858
  return;
753
859
  }
754
860
  throw cliValidationError(
755
- `A Featured-only run does not authorize ${operation.name}. Complete or fail it before starting a full daily review.`,
861
+ `A Featured-only run does not authorize ${operation.name}. Use the review-bound Featured comment workflow for encouragement; do not start unrelated daily work to bypass scope.`,
756
862
  );
757
863
  }
758
864
 
759
865
  function adminOperationRequiresRun(operation) {
866
+ if (typeof operation.requiresRun === "boolean") {
867
+ return operation.requiresRun;
868
+ }
760
869
  return (
761
870
  ![
762
871
  "identity.list",
@@ -773,6 +882,14 @@ function adminOperationRequiresRun(operation) {
773
882
  "escalation.list",
774
883
  "escalation.set",
775
884
  "notable.add",
885
+ "notable.status",
886
+ "runtime-logs.start",
887
+ "runtime-logs.status",
888
+ "runtime-logs.capture",
889
+ "runtime-logs.complete",
890
+ "runtime-logs.resume",
891
+ "runtime-logs.abandon",
892
+ "energy-budget.report",
776
893
  ].includes(operation.name) &&
777
894
  !operation.name.startsWith("ai-bucket.") &&
778
895
  !operation.name.startsWith("ai-email-policy.") &&
@@ -803,7 +920,10 @@ export function parseAdminOperation(options) {
803
920
 
804
921
  if (namespace === "correction" || namespace === "corrections") {
805
922
  if (!action || action === "status") {
806
- return readOperation("correction.status", "/cli/admin/corrections/status");
923
+ return readOperation(
924
+ "correction.status",
925
+ "/cli/admin/corrections/status",
926
+ );
807
927
  }
808
928
  if (action === "start") {
809
929
  const commentId = parseRequiredInteger(target, "comment ID", 1);
@@ -1160,17 +1280,17 @@ export function parseAdminOperation(options) {
1160
1280
  if (action === "start") {
1161
1281
  const runScope = parseDailyRunScope(options.adminScope || "full");
1162
1282
  const commentMode = parseCommentMode(options.commentMode || "off");
1163
- if (runScope === "featured" && commentMode !== "off") {
1283
+ if (runScope !== "full" && commentMode !== "off") {
1164
1284
  throw cliValidationError(
1165
- "A Featured-only run requires --comment-mode off.",
1285
+ "A scoped run requires --comment-mode off.",
1166
1286
  );
1167
1287
  }
1168
1288
  return writeOperation(
1169
1289
  "daily-run.start",
1170
1290
  "POST",
1171
- runScope === "featured"
1172
- ? "/cli/admin/daily-runs/start/featured"
1173
- : "/cli/admin/daily-runs/start",
1291
+ runScope === "full"
1292
+ ? "/cli/admin/daily-runs/start"
1293
+ : `/cli/admin/daily-runs/start/${runScope}`,
1174
1294
  {
1175
1295
  identity: options.adminIdentity
1176
1296
  ? parseIdentity(options.adminIdentity)
@@ -1185,6 +1305,25 @@ export function parseAdminOperation(options) {
1185
1305
  return readOperation("daily-run.status", "/cli/admin/daily-runs/status");
1186
1306
  }
1187
1307
  if (action === "report") {
1308
+ const positionalRun = String(target || "").trim();
1309
+ const flaggedRun = String(options.adminRun || "").trim();
1310
+ if (
1311
+ extra ||
1312
+ (positionalRun && flaggedRun && positionalRun !== flaggedRun)
1313
+ ) {
1314
+ throw cliValidationError(
1315
+ "Usage: lumine admin daily-run report [--run <completed-run-id>] [--json].",
1316
+ );
1317
+ }
1318
+ const historicalRun = positionalRun || flaggedRun;
1319
+ if (historicalRun) {
1320
+ const runId = parseRequiredInteger(historicalRun, "run ID", 1);
1321
+ return readOperation(
1322
+ "daily-run.report",
1323
+ `/cli/admin/daily-runs/${runId}/report`,
1324
+ { requiresRun: false, historicalRunId: runId },
1325
+ );
1326
+ }
1188
1327
  return readOperation("daily-run.report", "/cli/admin/daily-runs/report");
1189
1328
  }
1190
1329
  if (action === "escalation" && target === "add") {
@@ -1408,6 +1547,30 @@ export function parseAdminOperation(options) {
1408
1547
  }
1409
1548
 
1410
1549
  if (namespace === "featured") {
1550
+ if (action === "comments") {
1551
+ if (!["scan", "acknowledge", "recommend", "report"].includes(target)) {
1552
+ throw cliValidationError("Usage: featured comments scan|acknowledge|recommend|report --checkpoint <file>.");
1553
+ }
1554
+ if (options.adminAll || options.adminCursor || options.adminUnviewed || options.adminViewed || options.adminAfter) {
1555
+ throw cliValidationError("The Featured review covers every comment; filtered or caller-supplied cursors are not supported.");
1556
+ }
1557
+ return { ...writeOperation(`featured.comments.${target}`, "POST", "/cli/admin/subjects/featured/reviews", {}),
1558
+ mutates: target !== "report", featuredWorkflow: target };
1559
+ }
1560
+ if (action === "plan") {
1561
+ if (!options.adminPostedAfter) throw cliValidationError("A Featured plan requires --posted-after <timestamp>.");
1562
+ return writeOperation("featured.plan", "POST", "/cli/admin/subjects/featured/plan", {
1563
+ removeIds: parseFeaturedSubjectIds(options.adminRemoveIds, "--remove-subject-ids"),
1564
+ addIds: parseFeaturedSubjectIds(options.adminAddIds, "--add-subject-ids"),
1565
+ ...(options.adminIds ? { finalIds: parseOrderedIds(options.adminIds) } : {}),
1566
+ postedAfter: options.adminPostedAfter,
1567
+ });
1568
+ }
1569
+ if (action === "apply") {
1570
+ readApprovedFeaturedPlan(options.adminFile, options.adminApprove);
1571
+ return { ...writeOperation("featured.apply", "POST", "/cli/admin/subjects/featured/plan/apply", {}),
1572
+ featuredWorkflow: "apply" };
1573
+ }
1411
1574
  if (action === "list") {
1412
1575
  return readOperation("featured.list", "/cli/admin/subjects/featured");
1413
1576
  }
@@ -1453,7 +1616,7 @@ export function parseAdminOperation(options) {
1453
1616
  if (namespace === "post") {
1454
1617
  if (action === "get") return postGetOperation(target, options);
1455
1618
  if (action === "comments") {
1456
- const parsedTarget = parseRecommendationTarget({
1619
+ const parsedTarget = parseAdminCommentTarget({
1457
1620
  target,
1458
1621
  explicitType: options.adminType,
1459
1622
  });
@@ -1630,6 +1793,23 @@ export function parseAdminOperation(options) {
1630
1793
  );
1631
1794
  }
1632
1795
 
1796
+ if (namespace === "notable" && action === "status" && !extra) {
1797
+ const rawTarget = String(target || "").trim();
1798
+ if (!rawTarget) {
1799
+ throw cliValidationError(
1800
+ "Usage: lumine admin notable status <userId|username>.",
1801
+ );
1802
+ }
1803
+ const query = /^\d+$/.test(rawTarget)
1804
+ ? { userId: parseRequiredInteger(rawTarget, "user ID", 1) }
1805
+ : { username: rawTarget };
1806
+ return readOperation(
1807
+ "notable.status",
1808
+ withQuery("/cli/admin/notable-users/status", query),
1809
+ { requiresRun: false },
1810
+ );
1811
+ }
1812
+
1633
1813
  if (namespace === "ai-costs") {
1634
1814
  if (action === "monthly" && !target && !extra) {
1635
1815
  if (options.adminDays) {
@@ -1637,9 +1817,109 @@ export function parseAdminOperation(options) {
1637
1817
  "ai-costs monthly uses UTC calendar months and does not accept --days.",
1638
1818
  );
1639
1819
  }
1640
- return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly");
1820
+ return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly", {
1821
+ requiresRun: false,
1822
+ });
1641
1823
  }
1642
- throw cliValidationError("Usage: lumine admin ai-costs monthly [--json].");
1824
+ if (action === "day" && !extra) {
1825
+ if (options.adminDays) {
1826
+ throw cliValidationError(
1827
+ "ai-costs day reads one closed UTC day and does not accept --days.",
1828
+ );
1829
+ }
1830
+ const positionalDay = String(target || "").trim();
1831
+ const flaggedDay = String(options.adminDate || "").trim();
1832
+ if (positionalDay && flaggedDay && positionalDay !== flaggedDay) {
1833
+ throw cliValidationError(
1834
+ "Pass the same UTC day once, either positionally or with --date.",
1835
+ );
1836
+ }
1837
+ const dayKey = parseUtcDayKey(positionalDay || flaggedDay);
1838
+ return readOperation(
1839
+ "ai-costs.day",
1840
+ `/cli/admin/ai-costs/day/${dayKey}`,
1841
+ { requiresRun: false },
1842
+ );
1843
+ }
1844
+ throw cliValidationError(
1845
+ "Usage: lumine admin ai-costs monthly | ai-costs day <YYYY-MM-DD> [--json].",
1846
+ );
1847
+ }
1848
+
1849
+ if (namespace === "energy-budget" && !action) {
1850
+ if (options.adminDays) {
1851
+ const days = Number(options.adminDays);
1852
+ if (!Number.isInteger(days) || days < 1 || days > 31) {
1853
+ throw cliValidationError("--days must be an integer between 1 and 31.");
1854
+ }
1855
+ }
1856
+ return readOperation(
1857
+ "energy-budget.report",
1858
+ withQuery("/cli/admin/energy-budget/report", { days: options.adminDays }),
1859
+ { requiresRun: false },
1860
+ );
1861
+ }
1862
+
1863
+ if (namespace === "runtime-logs") {
1864
+ if (
1865
+ (action === "start" || action === "status" || action === "read") &&
1866
+ !target &&
1867
+ !extra
1868
+ ) {
1869
+ if (
1870
+ action !== "start" &&
1871
+ !String(options.adminReviewSession || "").trim()
1872
+ ) {
1873
+ throw cliValidationError(
1874
+ "Pass the production-log review session with --review-session <file>.",
1875
+ );
1876
+ }
1877
+ return {
1878
+ name:
1879
+ action === "read" ? "runtime-logs.capture" : `runtime-logs.${action}`,
1880
+ method: action === "status" ? "GET" : "POST",
1881
+ path: "",
1882
+ body: undefined,
1883
+ mutates: action !== "status",
1884
+ requiresRun: false,
1885
+ runtimeLogAction: action === "read" ? "capture" : action,
1886
+ };
1887
+ }
1888
+ if ((action === "resume" || action === "abandon") && !target && !extra) {
1889
+ return {
1890
+ name: `runtime-logs.${action}`,
1891
+ method: "POST",
1892
+ path: "",
1893
+ body: undefined,
1894
+ mutates: true,
1895
+ requiresRun: false,
1896
+ runtimeLogAction: action,
1897
+ };
1898
+ }
1899
+ if ((action === "finish" || action === "complete") && !target && !extra) {
1900
+ if (!String(options.adminReviewSession || "").trim()) {
1901
+ throw cliValidationError(
1902
+ "Pass the production-log review session with --review-session <file>.",
1903
+ );
1904
+ }
1905
+ if (!options.adminReviewed) {
1906
+ throw cliValidationError(
1907
+ "Inspect every downloaded runtime-log artifact, then confirm with --reviewed.",
1908
+ );
1909
+ }
1910
+ return {
1911
+ name: "runtime-logs.complete",
1912
+ method: "POST",
1913
+ path: "",
1914
+ body: undefined,
1915
+ mutates: true,
1916
+ requiresRun: false,
1917
+ runtimeLogAction: "complete",
1918
+ };
1919
+ }
1920
+ throw cliValidationError(
1921
+ "Usage: lumine admin runtime-logs start | status|read --review-session <file> | finish --review-session <file> --reviewed | resume | abandon [--review-session <file>].",
1922
+ );
1643
1923
  }
1644
1924
 
1645
1925
  if (namespace === "media-costs") {
@@ -1891,16 +2171,19 @@ export function parseAdminOperation(options) {
1891
2171
  }
1892
2172
 
1893
2173
  throw cliValidationError(
1894
- "Usage: lumine admin identity|economy|rescue|sponsor|daily-run|escalation|todo|recommendations|builds|post|subjects|subject|featured|comment|announcement|chat|news|audit|brief|ai-costs|media-costs|bot-output|notable ...",
2174
+ "Usage: lumine admin identity|economy|rescue|sponsor|daily-run|escalation|todo|recommendations|builds|post|subjects|subject|featured|comment|announcement|chat|news|audit|brief|ai-costs|media-costs|energy-budget|runtime-logs|bot-output|notable ...",
1895
2175
  );
1896
2176
  }
1897
2177
 
1898
2178
  function subjectsListOperation(options) {
1899
2179
  const operatorView = requestedOperatorViewFilter(options);
2180
+ const subjectWindow = parseSubjectWindow(options);
1900
2181
  return readOperation(
1901
2182
  "subjects.candidates",
1902
2183
  withQuery("/cli/admin/subjects", {
1903
- after: options.adminAfter,
2184
+ sinceRun: subjectWindow.mode === "since-run" ? "true" : "",
2185
+ after: subjectWindow.mode === "after" ? subjectWindow.after : "",
2186
+ includeLegacy: subjectWindow.mode === "legacy" ? "true" : "",
1904
2187
  cursor: options.adminCursor,
1905
2188
  effort: options.adminEffort,
1906
2189
  limit: options.limit,
@@ -1909,10 +2192,11 @@ function subjectsListOperation(options) {
1909
2192
  pagination: {
1910
2193
  collectionKey: "subjects",
1911
2194
  coverageQueue: "subjects",
1912
- coverageMode: options.adminAfter ? "after" : "all",
1913
- after: options.adminAfter
1914
- ? parseAfterForCoverage(options.adminAfter)
1915
- : null,
2195
+ coverageMode: subjectWindow.mode,
2196
+ after:
2197
+ subjectWindow.mode === "after"
2198
+ ? parseAfterForCoverage(subjectWindow.after)
2199
+ : null,
1916
2200
  filters: {
1917
2201
  effort: options.adminEffort || "all",
1918
2202
  ...(operatorView ? { operatorView } : {}),
@@ -2007,10 +2291,7 @@ function featuredReorderOperation(options) {
2007
2291
  }
2008
2292
 
2009
2293
  function featuredAddOperation(options) {
2010
- const addIds = parseFeaturedSubjectIds(
2011
- options.adminIds,
2012
- "--subject-ids",
2013
- );
2294
+ const addIds = parseFeaturedSubjectIds(options.adminIds, "--subject-ids");
2014
2295
  const postedAfter = String(options.adminPostedAfter || "").trim();
2015
2296
  if (!postedAfter) {
2016
2297
  throw cliValidationError(
@@ -2052,6 +2333,7 @@ function featuredRotateOperation(options) {
2052
2333
  {
2053
2334
  removeIds,
2054
2335
  addIds,
2336
+ ...(options.adminPostedAfter ? { postedAfter: options.adminPostedAfter } : {}),
2055
2337
  },
2056
2338
  );
2057
2339
  }
@@ -2096,6 +2378,42 @@ export function parseRecommendationWindow(options) {
2096
2378
  return { mode, after: mode === "after" ? options.adminAfter : "" };
2097
2379
  }
2098
2380
 
2381
+ export function parseSubjectWindow(options) {
2382
+ const selected = [
2383
+ options.adminSinceRun ? "since-run" : "",
2384
+ options.adminAfter ? "after" : "",
2385
+ options.adminIncludeLegacy ? "legacy" : "",
2386
+ ].filter(Boolean);
2387
+ if (selected.length > 1) {
2388
+ throw cliValidationError(
2389
+ "Choose one Subject window: --since-run, --after, or --include-legacy.",
2390
+ );
2391
+ }
2392
+ const mode = selected[0] || "since-run";
2393
+ if (mode === "after") parseAfterForCoverage(options.adminAfter);
2394
+ return { mode, after: mode === "after" ? options.adminAfter : "" };
2395
+ }
2396
+
2397
+ function parseUtcDayKey(value) {
2398
+ const dayKey = String(value || "").trim();
2399
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dayKey);
2400
+ if (!match) {
2401
+ throw cliValidationError(
2402
+ "Pass a real UTC calendar date in YYYY-MM-DD format.",
2403
+ );
2404
+ }
2405
+ const parsed = new Date(`${dayKey}T00:00:00.000Z`);
2406
+ if (
2407
+ !Number.isFinite(parsed.getTime()) ||
2408
+ parsed.toISOString().slice(0, 10) !== dayKey
2409
+ ) {
2410
+ throw cliValidationError(
2411
+ "Pass a real UTC calendar date in YYYY-MM-DD format.",
2412
+ );
2413
+ }
2414
+ return dayKey;
2415
+ }
2416
+
2099
2417
  function parseAfterForCoverage(value) {
2100
2418
  const raw = String(value || "").trim();
2101
2419
  if (/^\d+$/.test(raw)) {
@@ -2297,7 +2615,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
2297
2615
  throw error;
2298
2616
  }
2299
2617
  const handoff = result?.data?.carryoverTodos;
2300
- if (runScope === "featured") {
2618
+ if (runScope !== "full") {
2301
2619
  if (
2302
2620
  !runId ||
2303
2621
  !handoff ||
@@ -2309,7 +2627,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
2309
2627
  Number(handoff.newlySurfacedCount) !== 0
2310
2628
  ) {
2311
2629
  const error = cliValidationError(
2312
- "The API did not confirm that carry-over telemetry was suppressed for the Featured-only run.",
2630
+ "The API did not confirm that carry-over telemetry was suppressed for the scoped run.",
2313
2631
  );
2314
2632
  error.code = "LUMINE_ADMIN_SCOPED_RUN_UNSUPPORTED";
2315
2633
  throw error;
@@ -2387,9 +2705,11 @@ function parseCommentMode(value) {
2387
2705
  }
2388
2706
 
2389
2707
  function parseDailyRunScope(value) {
2390
- const scope = String(value || "full").trim().toLowerCase();
2391
- if (!["full", "featured"].includes(scope)) {
2392
- throw cliValidationError("--scope must be full or featured.");
2708
+ const scope = String(value || "full")
2709
+ .trim()
2710
+ .toLowerCase();
2711
+ if (!["full", "featured", "newspaper"].includes(scope)) {
2712
+ throw cliValidationError("--scope must be full, featured, or newspaper.");
2393
2713
  }
2394
2714
  return scope;
2395
2715
  }
@@ -2698,6 +3018,48 @@ function printAdminMonthlyAiCosts(monthlyAiCosts) {
2698
3018
  }
2699
3019
  }
2700
3020
 
3021
+ function printAdminDailyAiCosts(dailyAiCosts) {
3022
+ console.log(
3023
+ `Application AI-cost ledger for ${dailyAiCosts.day.dayKey} (closed UTC day): ${formatAdminUsd(dailyAiCosts.summary?.estimatedCostUsd)} across ${Number(dailyAiCosts.summary?.requestCount || 0)} request(s).`,
3024
+ );
3025
+ for (const row of dailyAiCosts.byProviderModel || []) {
3026
+ console.log(
3027
+ ` ${row.provider || "unknown"}/${row.model || "unknown"}: ${formatAdminUsd(row.estimatedCostUsd)} · ${Number(row.totalTokens || 0)} token(s) · ${Number(row.requestCount || 0)} request(s).`,
3028
+ );
3029
+ }
3030
+ }
3031
+
3032
+ function printAdminEnergyBudget(energyBudget) {
3033
+ const headline = energyBudget.lastCompletedDay;
3034
+ if (headline) {
3035
+ console.log(
3036
+ `AI Energy budget health, last completed UTC day ${headline.dayKey}: ${formatAdminUsd(headline.chargedUsd)} charged, ${formatAdminUsd(headline.overflowUsd)} overflow, ${headline.users} user(s), ${headline.recharges} recharge(s), ${headline.runs.total.runs} run(s), ${headline.telemetry.metrics.busy_refusal.count} busy refusal(s).`,
3037
+ );
3038
+ } else {
3039
+ console.log("AI Energy budget health: no completed UTC day in the requested window.");
3040
+ }
3041
+ console.log(
3042
+ "day | charged | overflow | users | rechg | runs | calls/run avg/p90 | $/run avg/p90 | stops chg/unchg | busy | telemetry rows",
3043
+ );
3044
+ for (const day of energyBudget.byDay || []) {
3045
+ const m = day.telemetry.metrics;
3046
+ const runs = day.runs.total;
3047
+ console.log(
3048
+ `${day.dayKey}${day.inProgress ? "*" : " "}| ${formatAdminUsd(day.chargedUsd).padStart(7)} | ${formatAdminUsd(day.overflowUsd).padStart(8)} | ${String(day.users).padStart(5)} | ${String(day.recharges).padStart(5)} | ${String(runs.runs).padStart(4)} | ${String(runs.callsPerRun.avg).padStart(7)}/${String(runs.callsPerRun.p90).padEnd(9)} | ${formatAdminUsd(runs.usdPerRun.avg).padStart(6)}/${formatAdminUsd(runs.usdPerRun.p90).padEnd(6)} | ${String(m.budget_stop_changed.count).padStart(7)}/${String(m.budget_stop_unchanged.count).padEnd(7)} | ${String(m.busy_refusal.count).padStart(4)} | ${day.telemetry.rowCount}`,
3049
+ );
3050
+ }
3051
+ console.log("* = in-progress UTC day; never headline it.");
3052
+ const flags = energyBudget.flags || [];
3053
+ if (flags.length === 0) {
3054
+ console.log("Flags: none.");
3055
+ return;
3056
+ }
3057
+ console.log(`Flags (${flags.length}) — record each as a carry-over todo and escalate; never auto-enforce:`);
3058
+ for (const flag of flags) {
3059
+ console.log(` ${flag.dayKey} ${flag.code}: ${flag.message}`);
3060
+ }
3061
+ }
3062
+
2701
3063
  function formatAdminMediaUsd(value) {
2702
3064
  const amount = Number(value);
2703
3065
  if (!Number.isFinite(amount)) return "unavailable";
@@ -2885,6 +3247,18 @@ async function printSpooledAdminResult({ operation, result, storage }) {
2885
3247
 
2886
3248
  function printAdminResult({ operation, result }) {
2887
3249
  const data = result?.data || {};
3250
+ if (operation.name === "featured.plan") {
3251
+ for (const pair of data.plan?.replacements || []) {
3252
+ console.log(`${pair.remove.id} ${pair.remove.title} -> ${pair.add.id} ${pair.add.title}`);
3253
+ }
3254
+ console.log(`Proposed final order: ${(data.plan?.finalIds || []).join(",")}`);
3255
+ console.log(`Plan hash: ${data.planHash}. Obtain Mikey's approval before using featured apply --file <plan.json> --approve ${data.planHash}.`);
3256
+ return;
3257
+ }
3258
+ if (operation.featuredWorkflow) {
3259
+ console.log(JSON.stringify(data, null, 2));
3260
+ return;
3261
+ }
2888
3262
  if (Array.isArray(data.applications)) {
2889
3263
  console.log(`${data.applications.length} sponsor application(s):`);
2890
3264
  for (const application of data.applications) {
@@ -2959,6 +3333,28 @@ function printAdminResult({ operation, result }) {
2959
3333
  );
2960
3334
  return;
2961
3335
  }
3336
+ if (data.review && data.artifacts?.reviewSessionPath) {
3337
+ console.log(
3338
+ `Production-log review #${data.review.id}: ${data.completionStatus || data.review.status}.`,
3339
+ );
3340
+ console.log(`Review session: ${data.artifacts.reviewSessionPath}`);
3341
+ if (data.artifacts.latestSnapshot?.snapshotPath) {
3342
+ console.log(
3343
+ `Latest captured bytes: ${data.artifacts.latestSnapshot.snapshotPath}`,
3344
+ );
3345
+ }
3346
+ if (
3347
+ data.completionStatus === "needs_review" ||
3348
+ data.completionStatus === "post_clear_review_required"
3349
+ ) {
3350
+ console.log(
3351
+ data.completionStatus === "post_clear_review_required"
3352
+ ? "The API error log was cleared in place. Review the post-clear snapshot, then rerun finish with --reviewed to close the lease."
3353
+ : "New bytes arrived at the final boundary. Review the latest snapshot, then rerun finish with --reviewed.",
3354
+ );
3355
+ }
3356
+ return;
3357
+ }
2962
3358
  if (data.review) {
2963
3359
  console.log(
2964
3360
  `Confirmed Build #${data.review.buildId} runtime at published artifact #${data.review.publishedArtifactVersionId}.`,
@@ -2971,6 +3367,14 @@ function printAdminResult({ operation, result }) {
2971
3367
  printAdminMonthlyAiCosts(data.monthlyAiCosts);
2972
3368
  return;
2973
3369
  }
3370
+ if (data.dailyAiCosts) {
3371
+ printAdminDailyAiCosts(data.dailyAiCosts);
3372
+ return;
3373
+ }
3374
+ if (data.energyBudget) {
3375
+ printAdminEnergyBudget(data.energyBudget);
3376
+ return;
3377
+ }
2974
3378
  if (data.monthlyMediaCosts) {
2975
3379
  printAdminMonthlyMediaCosts(data.monthlyMediaCosts);
2976
3380
  return;
@@ -2990,14 +3394,22 @@ function printAdminResult({ operation, result }) {
2990
3394
  }
2991
3395
  if (data.report) {
2992
3396
  const report = data.report;
3397
+ const historical = report.basis?.kind === "historical_reconstruction";
2993
3398
  console.log(
2994
- `Run #${report.run.id}: ${report.mutations.successfulMutationCount} successful mutation(s), ${report.queueCoverage.length} queue coverage record(s), ${report.escalations.length} escalation(s), ${report.carryoverTodos?.count || 0} unfinished todo(s).`,
3399
+ `${historical ? "Historical reconstruction for run" : "Run"} #${report.run.id}: ${report.mutations.successfulMutationCount} successful mutation(s), ${report.queueCoverage.length} queue coverage record(s), ${report.escalations.length} escalation(s)${historical ? "." : `, ${report.carryoverTodos?.count || 0} unfinished todo(s).`}`,
2995
3400
  );
2996
3401
  for (const coverage of report.queueCoverage) {
2997
3402
  console.log(
2998
3403
  ` ${coverage.queue}: ${coverage.candidateCount} candidate(s), ${coverage.scannedCount} row(s) scanned across ${coverage.pages} page(s).`,
2999
3404
  );
3000
3405
  }
3406
+ for (const item of report.featuredReviews || []) {
3407
+ const coverage = item.coverage;
3408
+ const counts = item.encouragement || {};
3409
+ console.log(
3410
+ ` Featured review #${item.review?.id || coverage?.reviewId}: ${coverage?.reviewed ? `${coverage.coveredSubjectIds.length}/${coverage.subjectCount} Subjects read, ${coverage.commentsRead} comments` : "not acknowledged as read"}; ${coverage?.complete ? "complete" : "incomplete"}; ${counts.newBasicRecommendations || 0} confirmed new basic recommendations, ${counts.alreadyDone || 0} already done, ${counts.rewardEligibilityGrants || 0} reward-permission grants, ${counts.directRewardsCreated || 0} direct rewards.`,
3411
+ );
3412
+ }
3001
3413
  for (const escalation of report.escalations) {
3002
3414
  const target =
3003
3415
  escalation.url ||
@@ -3006,10 +3418,21 @@ function printAdminResult({ operation, result }) {
3006
3418
  ` ${String(escalation.severity || "attention").toUpperCase()} ${target} — ${escalation.summary}`,
3007
3419
  );
3008
3420
  }
3009
- printTodoItems(report.carryoverTodos?.items || [], "Unfinished work");
3421
+ if (historical) {
3422
+ console.log(
3423
+ "The live brief and carry-over todo state were not snapshotted for this completed run.",
3424
+ );
3425
+ } else {
3426
+ printTodoItems(report.carryoverTodos?.items || [], "Unfinished work");
3427
+ }
3010
3428
  if (report.sponsorIntegrity) {
3429
+ const pendingApplications = Number.isSafeInteger(
3430
+ report.sponsorIntegrity.pendingApplications,
3431
+ )
3432
+ ? `; ${report.sponsorIntegrity.pendingApplications} pending application(s)`
3433
+ : "; historical pending-application count unavailable";
3011
3434
  console.log(
3012
- `Sponsor integrity: ${report.sponsorIntegrity.scan?.status || "not started"}; ${report.sponsorIntegrity.cases?.open || 0} open case(s); ${report.sponsorIntegrity.pendingApplications || 0} pending application(s).`,
3435
+ `Sponsor integrity: ${report.sponsorIntegrity.scan?.status || "not started"}; ${report.sponsorIntegrity.cases?.open || 0} open case(s)${pendingApplications}.`,
3013
3436
  );
3014
3437
  }
3015
3438
  const surfaces = report.brief?.engagementPulse?.surfaces;
@@ -3029,10 +3452,12 @@ function printAdminResult({ operation, result }) {
3029
3452
  if (deltas.length)
3030
3453
  console.log(`Engagement deltas: ${deltas.join(", ")}.`);
3031
3454
  }
3032
- const notableCount = Array.isArray(report.brief?.notableCandidates)
3033
- ? report.brief.notableCandidates.length
3034
- : 0;
3035
- console.log(`Notable-user candidates in this brief: ${notableCount}.`);
3455
+ if (!historical) {
3456
+ const notableCount = Array.isArray(report.brief?.notableCandidates)
3457
+ ? report.brief.notableCandidates.length
3458
+ : 0;
3459
+ console.log(`Notable-user candidates in this brief: ${notableCount}.`);
3460
+ }
3036
3461
  return;
3037
3462
  }
3038
3463
  if (data.inspection) {
@@ -3096,6 +3521,15 @@ function printAdminResult({ operation, result }) {
3096
3521
  printTodoItems([data.todo], "Canonical todo");
3097
3522
  return;
3098
3523
  }
3524
+ if (Object.hasOwn(data, "isNotable") && data.user) {
3525
+ console.log(
3526
+ `${data.user.username} (user #${data.user.id}) is${data.isNotable ? "" : " not"} currently in Notable Users.`,
3527
+ );
3528
+ if (data.notableUser?.reason) {
3529
+ console.log(`Reason: ${data.notableUser.reason}`);
3530
+ }
3531
+ return;
3532
+ }
3099
3533
  if (data.bucket && Array.isArray(data.memberUserIds)) {
3100
3534
  const added = Array.isArray(data.accounts)
3101
3535
  ? `; added ${data.accounts.length} explicit account(s)`