@stage5/lumine 0.2.67 → 0.2.69

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,
@@ -21,6 +22,8 @@ import {
21
22
  runManagedBuildReview,
22
23
  } from "./build-review.js";
23
24
  import { runAdminRuntimeLogWorkflow } from "./admin-runtime-logs.js";
25
+ import { readApprovedFeaturedPlan, runFeaturedWorkflow } from "./admin-featured.js";
26
+ import { FEATURED_HISTORY_BATCH_SIZE, runBatchedFeaturedHistory } from "./admin-featured-history.js";
24
27
 
25
28
  const MAX_EDITORIAL_FILE_BYTES = 256 * 1024;
26
29
  const MAX_COMPOSED_TEXT_FILE_BYTES = 64 * 1024;
@@ -270,7 +273,9 @@ export async function adminCommand(options) {
270
273
  recommendationContentTypes,
271
274
  viewFilter,
272
275
  });
273
- if (operation.name === "build.review") {
276
+ if (operation.featuredWorkflow) {
277
+ result = await runFeaturedWorkflow({ options, operation, authToken: auth.token, runId });
278
+ } else if (operation.name === "build.review") {
274
279
  result = await runManagedBuildReview({
275
280
  options,
276
281
  authToken: auth.token,
@@ -296,7 +301,10 @@ export async function adminCommand(options) {
296
301
  "Use --resume with the scan checkpoint instead of combining --all with --cursor.",
297
302
  );
298
303
  }
299
- result = await runAutomaticPagination({
304
+ const paginate = operation.name === "featured.history" &&
305
+ operation.pagination.filters.subjectIds.length > FEATURED_HISTORY_BATCH_SIZE
306
+ ? runBatchedFeaturedHistory : runAutomaticPagination;
307
+ result = await paginate({
300
308
  options,
301
309
  operation,
302
310
  runId,
@@ -325,9 +333,35 @@ export async function adminCommand(options) {
325
333
  result = transformResult(await fetchOperation());
326
334
  }
327
335
  } catch (error) {
336
+ if (operation.name === "runtime.evidence" && error.status === 404) {
337
+ error.code = "CLI_ADMIN_RUNTIME_EVIDENCE_NOT_DEPLOYED";
338
+ error.message = "The runtime evidence route is not deployed on the requested host. Evidence is unknown; deploy the matching API and activate the collector in an authorized primary-generation release. No restart or host substitution was attempted.";
339
+ error.data = {
340
+ ok: false,
341
+ status: "unavailable",
342
+ error: { code: error.code, message: error.message, details: { httpStatus: 404 } },
343
+ };
344
+ }
345
+ if (operation.featuredWorkflow && error.featuredProgress) {
346
+ const serverError = error.data?.error;
347
+ error.data = {
348
+ ok: false,
349
+ status: "partial_failure",
350
+ error: {
351
+ code: serverError?.code || error.code || "LUMINE_ADMIN_FEATURED_WORKFLOW_FAILED",
352
+ message: error.message,
353
+ details: {
354
+ ...(serverError && typeof serverError === "object" ? serverError.details : {}),
355
+ ...error.featuredProgress,
356
+ retryInstruction: "Resume the exact command with --resume; confirmed items are not replayed.",
357
+ },
358
+ },
359
+ };
360
+ }
328
361
  if (
329
362
  operation.mutates &&
330
363
  requestId &&
364
+ !operation.featuredWorkflow &&
331
365
  operation.name !== "post.skip-batch"
332
366
  ) {
333
367
  const retryInstruction = `Retry with --idempotency-key ${requestId}.`;
@@ -367,6 +401,9 @@ export async function adminCommand(options) {
367
401
  typeof operation.body.buildReviewUnderstanding === "string",
368
402
  });
369
403
  }
404
+ if (operation.name === "comment.edit") {
405
+ assertComposedCommentEditResult({ result, body: operation.body });
406
+ }
370
407
  if (operation.name === "ai-email-policy.set") {
371
408
  assertAiEmailPolicySetResult({ operation, result });
372
409
  }
@@ -402,6 +439,7 @@ function transformAdminResult({
402
439
  assertSubjectWindowResult({ operation, result: transformed });
403
440
  }
404
441
  if (operation.name === "builds.candidates") {
442
+ assertBuildWindowResult({ operation, result: transformed });
405
443
  transformed = normalizeAdminBuildCandidatesResult({
406
444
  result: transformed,
407
445
  siteUrl: options.siteUrl,
@@ -480,6 +518,14 @@ export function assertSubjectWindowResult({ operation, result }) {
480
518
 
481
519
  async function finishAdminOutput({ options, operation, result }) {
482
520
  const paginationStorage = getPaginatedResultStorage(result);
521
+ if (
522
+ options.adminOutput &&
523
+ !paginationStorage &&
524
+ operation.name !== "news.claim" &&
525
+ operation.name !== "post.skip-batch"
526
+ ) {
527
+ writeAdminResultOutput({ filePath: options.adminOutput, result, operation });
528
+ }
483
529
  if (options.json) {
484
530
  if (paginationStorage) {
485
531
  await writePaginatedResultJson({
@@ -507,13 +553,33 @@ async function finishAdminOutput({ options, operation, result }) {
507
553
  return result;
508
554
  }
509
555
 
556
+ export function writeAdminResultOutput({ filePath, result, operation }) {
557
+ try {
558
+ return writeAdminJsonFile(filePath, result, { privateFile: true });
559
+ } catch (cause) {
560
+ const error = new Error(
561
+ `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.`,
562
+ );
563
+ error.code = "LUMINE_ADMIN_OUTPUT_WRITE_FAILED";
564
+ error.data = {
565
+ ok: false,
566
+ status: "error",
567
+ error: {
568
+ code: error.code,
569
+ message: error.message,
570
+ details: { canonicalResult: result, outputPath: String(filePath) },
571
+ },
572
+ };
573
+ throw error;
574
+ }
575
+ }
576
+
510
577
  export function normalizeAdminBuildCandidatesResult({ result, siteUrl }) {
511
- const builds = Array.isArray(result?.builds) ? result.builds : [];
512
- const nextCursor = String(result?.cursor || "").trim() || null;
578
+ const builds = result.data.builds;
513
579
  return {
514
- ok: true,
515
- status: "success",
580
+ ...result,
516
581
  data: {
582
+ ...result.data,
517
583
  builds: builds.map((build) => {
518
584
  const id = Number(build?.id || 0);
519
585
  return {
@@ -530,15 +596,128 @@ export function normalizeAdminBuildCandidatesResult({ result, siteUrl }) {
530
596
  },
531
597
  };
532
598
  }),
533
- pagination: {
534
- nextCursor,
535
- hasMore: Boolean(nextCursor),
536
- exhausted: !nextCursor,
537
- },
538
599
  },
539
600
  };
540
601
  }
541
602
 
603
+ export function assertBuildWindowResult({ operation, result }) {
604
+ const p = result?.data?.pagination;
605
+ const mode = operation?.pagination?.coverageMode;
606
+ if (
607
+ result?.ok !== true ||
608
+ !Array.isArray(result?.data?.builds) ||
609
+ !p ||
610
+ p.mode !== mode ||
611
+ !Number.isSafeInteger(p.snapshotMaxId) ||
612
+ p.snapshotMaxId < 0 ||
613
+ !Number.isSafeInteger(p.snapshotTimeStamp) ||
614
+ p.snapshotTimeStamp < 0 ||
615
+ (mode === "legacy"
616
+ ? p.after !== null
617
+ : !Number.isSafeInteger(p.after) || p.after < 0) ||
618
+ (mode === "after" && p.after !== operation.pagination.after) ||
619
+ typeof p.exhausted !== "boolean" ||
620
+ p.hasMore !== !p.exhausted ||
621
+ (p.exhausted
622
+ ? p.nextCursor !== null
623
+ : typeof p.nextCursor !== "string" || !p.nextCursor)
624
+ ) {
625
+ const error = new Error(
626
+ "The API did not confirm the requested published-Build window and snapshot. Deploy the matching API; do not substitute an unbounded public browser scan.",
627
+ );
628
+ error.code = "LUMINE_ADMIN_BUILD_WINDOW_UNSUPPORTED";
629
+ throw error;
630
+ }
631
+ }
632
+
633
+ export function assertComposedCommentEditResult({ result, body }) {
634
+ const edit = result?.data?.edit;
635
+ if (
636
+ result?.ok === true &&
637
+ result?.data?.comment?.content === body.content &&
638
+ (!body.buildReviewUnderstanding ||
639
+ (edit?.buildReviewContextStored === true &&
640
+ edit?.reviewedBuildVersionId === body.reviewedBuildVersionId &&
641
+ Number.isSafeInteger(edit?.managementDraftId) &&
642
+ edit.managementDraftId > 0))
643
+ )
644
+ return;
645
+ const error = new Error(
646
+ "The API did not confirm the exact comment edit and its required Build review context. Inspect the canonical result before retrying; deploy the matching API if unsupported.",
647
+ );
648
+ error.code = "LUMINE_ADMIN_COMMENT_EDIT_UNCONFIRMED";
649
+ error.data = {
650
+ ok: false,
651
+ status: "validation_error",
652
+ error: {
653
+ code: error.code,
654
+ message: error.message,
655
+ details: { canonicalResult: result },
656
+ },
657
+ };
658
+ throw error;
659
+ }
660
+
661
+ function readAdminBuildReviewEvidence(options, parsedTarget) {
662
+ const version = options.adminReviewedBuildVersion
663
+ ? parseRequiredInteger(
664
+ options.adminReviewedBuildVersion,
665
+ "--reviewed-version",
666
+ 1,
667
+ )
668
+ : undefined;
669
+ const method = options.adminBuildReviewMethod
670
+ ? parseAdminBuildReviewMethod(options.adminBuildReviewMethod)
671
+ : undefined;
672
+ const receipt = options.adminReviewReceipt
673
+ ? parseBuildReviewReceipt(options.adminReviewReceipt)
674
+ : null;
675
+ const understanding = options.adminReviewContext
676
+ ? readBuildReviewContextFile(options.adminReviewContext)
677
+ : undefined;
678
+ if (receipt && (version || method)) {
679
+ throw cliValidationError(
680
+ "Pass either --review-receipt or manual --reviewed-version/--reviewed-via evidence, not both.",
681
+ );
682
+ }
683
+ const reviewedBuildVersionId = receipt
684
+ ? Number(receipt.publishedArtifactVersionId)
685
+ : version;
686
+ const buildReviewMethod = receipt ? "runtime" : method;
687
+ if (understanding && (!reviewedBuildVersionId || !buildReviewMethod)) {
688
+ throw cliValidationError(
689
+ "--review-context requires confirmed Build review evidence.",
690
+ );
691
+ }
692
+ if ((reviewedBuildVersionId || buildReviewMethod) && !understanding) {
693
+ throw cliValidationError(
694
+ "Build review evidence requires --review-context <context.json>.",
695
+ );
696
+ }
697
+ if (
698
+ receipt &&
699
+ parsedTarget.type === "build" &&
700
+ Number(receipt.buildId) !== parsedTarget.id
701
+ ) {
702
+ throw cliValidationError(
703
+ "The review receipt belongs to a different Build.",
704
+ );
705
+ }
706
+ if (
707
+ !["build", "comment"].includes(parsedTarget.type) &&
708
+ (reviewedBuildVersionId || buildReviewMethod)
709
+ ) {
710
+ throw cliValidationError(
711
+ "Build review evidence applies only to build:<id> or a comment:<id> inside a Build.",
712
+ );
713
+ }
714
+ return {
715
+ ...(reviewedBuildVersionId ? { reviewedBuildVersionId } : {}),
716
+ ...(buildReviewMethod ? { buildReviewMethod } : {}),
717
+ ...(understanding ? { buildReviewUnderstanding: understanding } : {}),
718
+ };
719
+ }
720
+
542
721
  export function assertComposedCommentDraftResult({
543
722
  result,
544
723
  expectedContent,
@@ -756,7 +935,7 @@ export function canonicalAdminRunScope(run) {
756
935
  const raw = run?.runScope;
757
936
  if (raw === undefined || raw === null || raw === "") return "full";
758
937
  const scope = String(raw);
759
- if (scope === "full" || scope === "featured") return scope;
938
+ if (["full", "featured", "newspaper"].includes(scope)) return scope;
760
939
  throw cliValidationError(
761
940
  "The API returned an invalid administrator run scope.",
762
941
  );
@@ -778,6 +957,12 @@ const FEATURED_RUN_OPERATIONS = new Set([
778
957
  "featured.add",
779
958
  "featured.reorder",
780
959
  "featured.rotate",
960
+ "featured.plan",
961
+ "featured.apply",
962
+ "featured.comments.scan",
963
+ "featured.comments.acknowledge",
964
+ "featured.comments.recommend",
965
+ "featured.comments.report",
781
966
  "daily-run.complete",
782
967
  "daily-run.fail",
783
968
  ]);
@@ -786,6 +971,14 @@ export function assertAdminOperationAllowedForRunScope({
786
971
  operation,
787
972
  runScope,
788
973
  }) {
974
+ if (runScope === "newspaper") {
975
+ if (
976
+ ["news.status", "news.claim", "news.submit", "news.print", "daily-run.complete", "daily-run.fail"].includes(operation.name)
977
+ ) return;
978
+ throw cliValidationError(
979
+ `A newspaper-only run does not authorize ${operation.name}.`,
980
+ );
981
+ }
789
982
  if (runScope !== "featured") return;
790
983
  const subjectCommentAlias =
791
984
  operation.name === "post.comments" &&
@@ -794,7 +987,7 @@ export function assertAdminOperationAllowedForRunScope({
794
987
  return;
795
988
  }
796
989
  throw cliValidationError(
797
- `A Featured-only run does not authorize ${operation.name}. Complete or fail it before starting a full daily review.`,
990
+ `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.`,
798
991
  );
799
992
  }
800
993
 
@@ -809,6 +1002,7 @@ function adminOperationRequiresRun(operation) {
809
1002
  "identity.use",
810
1003
  "identity.inspect",
811
1004
  "economy.trace",
1005
+ "bot.context",
812
1006
  "rescue.wordle.audit",
813
1007
  "daily-run.start",
814
1008
  "daily-run.status",
@@ -1216,17 +1410,17 @@ export function parseAdminOperation(options) {
1216
1410
  if (action === "start") {
1217
1411
  const runScope = parseDailyRunScope(options.adminScope || "full");
1218
1412
  const commentMode = parseCommentMode(options.commentMode || "off");
1219
- if (runScope === "featured" && commentMode !== "off") {
1413
+ if (runScope !== "full" && commentMode !== "off") {
1220
1414
  throw cliValidationError(
1221
- "A Featured-only run requires --comment-mode off.",
1415
+ "A scoped run requires --comment-mode off.",
1222
1416
  );
1223
1417
  }
1224
1418
  return writeOperation(
1225
1419
  "daily-run.start",
1226
1420
  "POST",
1227
- runScope === "featured"
1228
- ? "/cli/admin/daily-runs/start/featured"
1229
- : "/cli/admin/daily-runs/start",
1421
+ runScope === "full"
1422
+ ? "/cli/admin/daily-runs/start"
1423
+ : `/cli/admin/daily-runs/start/${runScope}`,
1230
1424
  {
1231
1425
  identity: options.adminIdentity
1232
1426
  ? parseIdentity(options.adminIdentity)
@@ -1381,11 +1575,13 @@ export function parseAdminOperation(options) {
1381
1575
  }
1382
1576
 
1383
1577
  if (namespace === "builds" && action === "candidates") {
1578
+ const window = parseBuildWindow(options);
1384
1579
  return readOperation(
1385
1580
  "builds.candidates",
1386
- withQuery("/build/public/list", {
1387
- sort: "recent",
1388
- scope: "all",
1581
+ withQuery("/cli/admin/builds/candidates", {
1582
+ sinceRun: window.mode === "since-run" ? "true" : "",
1583
+ after: window.mode === "after" ? window.after : "",
1584
+ includeLegacy: window.mode === "legacy" ? "true" : "",
1389
1585
  cursor: options.adminCursor,
1390
1586
  limit: options.limit,
1391
1587
  }),
@@ -1393,9 +1589,12 @@ export function parseAdminOperation(options) {
1393
1589
  pagination: {
1394
1590
  collectionKey: "builds",
1395
1591
  coverageQueue: "builds",
1396
- coverageMode: "all",
1397
- after: null,
1398
- filters: { sort: "recent", scope: "all" },
1592
+ coverageMode: window.mode,
1593
+ after:
1594
+ window.mode === "after"
1595
+ ? parseAfterForCoverage(window.after)
1596
+ : null,
1597
+ filters: { sort: "published-release", scope: "all" },
1399
1598
  },
1400
1599
  },
1401
1600
  );
@@ -1414,6 +1613,9 @@ export function parseAdminOperation(options) {
1414
1613
  body: undefined,
1415
1614
  mutates: false,
1416
1615
  buildId: parsed.id,
1616
+ // Public artifact inspection also supports a one-comment correction;
1617
+ // it never needs a full daily-management authorization envelope.
1618
+ requiresRun: false,
1417
1619
  };
1418
1620
  }
1419
1621
 
@@ -1483,6 +1685,30 @@ export function parseAdminOperation(options) {
1483
1685
  }
1484
1686
 
1485
1687
  if (namespace === "featured") {
1688
+ if (action === "comments") {
1689
+ if (!["scan", "acknowledge", "recommend", "report"].includes(target)) {
1690
+ throw cliValidationError("Usage: featured comments scan|acknowledge|recommend|report --checkpoint <file>.");
1691
+ }
1692
+ if (options.adminAll || options.adminCursor || options.adminUnviewed || options.adminViewed || options.adminAfter) {
1693
+ throw cliValidationError("The Featured review covers every comment; filtered or caller-supplied cursors are not supported.");
1694
+ }
1695
+ return { ...writeOperation(`featured.comments.${target}`, "POST", "/cli/admin/subjects/featured/reviews", {}),
1696
+ mutates: target !== "report", featuredWorkflow: target };
1697
+ }
1698
+ if (action === "plan") {
1699
+ if (!options.adminPostedAfter) throw cliValidationError("A Featured plan requires --posted-after <timestamp>.");
1700
+ return writeOperation("featured.plan", "POST", "/cli/admin/subjects/featured/plan", {
1701
+ removeIds: parseFeaturedSubjectIds(options.adminRemoveIds, "--remove-subject-ids"),
1702
+ addIds: parseFeaturedSubjectIds(options.adminAddIds, "--add-subject-ids"),
1703
+ ...(options.adminIds ? { finalIds: parseOrderedIds(options.adminIds) } : {}),
1704
+ postedAfter: options.adminPostedAfter,
1705
+ });
1706
+ }
1707
+ if (action === "apply") {
1708
+ readApprovedFeaturedPlan(options.adminFile, options.adminApprove);
1709
+ return { ...writeOperation("featured.apply", "POST", "/cli/admin/subjects/featured/plan/apply", {}),
1710
+ featuredWorkflow: "apply" };
1711
+ }
1486
1712
  if (action === "list") {
1487
1713
  return readOperation("featured.list", "/cli/admin/subjects/featured");
1488
1714
  }
@@ -1491,6 +1717,12 @@ export function parseAdminOperation(options) {
1491
1717
  options.adminIds,
1492
1718
  "--subject-ids",
1493
1719
  );
1720
+ if (subjectIds.length > 20_000) {
1721
+ throw cliValidationError("Featured history accepts at most 20000 subject IDs per CLI scan.");
1722
+ }
1723
+ if (subjectIds.length > FEATURED_HISTORY_BATCH_SIZE && !options.adminAll) {
1724
+ throw cliValidationError("Pass --all to automatically batch history reads larger than 100 subjects.");
1725
+ }
1494
1726
  return readOperation(
1495
1727
  "featured.history",
1496
1728
  withQuery("/cli/admin/subjects/featured/history", {
@@ -1501,6 +1733,7 @@ export function parseAdminOperation(options) {
1501
1733
  {
1502
1734
  pagination: {
1503
1735
  collectionKey: "events",
1736
+ summaryKeys: ["coverage", "subjects"],
1504
1737
  filters: { subjectIds },
1505
1738
  },
1506
1739
  },
@@ -1528,7 +1761,7 @@ export function parseAdminOperation(options) {
1528
1761
  if (namespace === "post") {
1529
1762
  if (action === "get") return postGetOperation(target, options);
1530
1763
  if (action === "comments") {
1531
- const parsedTarget = parseRecommendationTarget({
1764
+ const parsedTarget = parseAdminCommentTarget({
1532
1765
  target,
1533
1766
  explicitType: options.adminType,
1534
1767
  });
@@ -1729,7 +1962,9 @@ export function parseAdminOperation(options) {
1729
1962
  "ai-costs monthly uses UTC calendar months and does not accept --days.",
1730
1963
  );
1731
1964
  }
1732
- return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly");
1965
+ return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly", {
1966
+ requiresRun: false,
1967
+ });
1733
1968
  }
1734
1969
  if (action === "day" && !extra) {
1735
1970
  if (options.adminDays) {
@@ -1770,10 +2005,23 @@ export function parseAdminOperation(options) {
1770
2005
  );
1771
2006
  }
1772
2007
 
2008
+ if (namespace === "runtime") {
2009
+ if (action !== "evidence" || !["primary", "target"].includes(target) || extra) {
2010
+ throw cliValidationError("Usage: lumine admin runtime evidence primary|target [--days 1..7].");
2011
+ }
2012
+ return readOperation(
2013
+ "runtime.evidence",
2014
+ withQuery(`/cli/admin/runtime-logs/hosts/${target}/evidence`, {
2015
+ days: parseRequiredInteger(options.adminDays || "7", "--days", 1, 7),
2016
+ }),
2017
+ { requiresRun: false },
2018
+ );
2019
+ }
2020
+
1773
2021
  if (namespace === "runtime-logs") {
1774
2022
  if (
1775
2023
  (action === "start" || action === "status" || action === "read") &&
1776
- !target &&
2024
+ (!target || (action === "start" && ["primary", "target"].includes(target))) &&
1777
2025
  !extra
1778
2026
  ) {
1779
2027
  if (
@@ -1793,6 +2041,7 @@ export function parseAdminOperation(options) {
1793
2041
  mutates: action !== "status",
1794
2042
  requiresRun: false,
1795
2043
  runtimeLogAction: action === "read" ? "capture" : action,
2044
+ ...(action === "start" && target ? { runtimeLogHost: target } : {}),
1796
2045
  };
1797
2046
  }
1798
2047
  if ((action === "resume" || action === "abandon") && !target && !extra) {
@@ -1888,6 +2137,36 @@ export function parseAdminOperation(options) {
1888
2137
  });
1889
2138
  }
1890
2139
 
2140
+ if (namespace === "bot-output" && action === "context") {
2141
+ const messageId = parseRequiredInteger(target, "bot message ID", 1);
2142
+ const reason = String(options.adminReason || "").trim();
2143
+ if (!reason || reason.length > MAX_IDENTITY_INSPECTION_REASON_LENGTH) {
2144
+ throw cliValidationError(
2145
+ "Explain the private bot investigation with --reason (1–500 characters).",
2146
+ );
2147
+ }
2148
+ if (options.adminAll || options.adminDays) {
2149
+ throw cliValidationError(
2150
+ "Bot context is a narrow message-ID investigation, not an --all or --days scan.",
2151
+ );
2152
+ }
2153
+ return writeOperation(
2154
+ "bot.context",
2155
+ "POST",
2156
+ `/cli/admin/bot-output/${messageId}/context`,
2157
+ {
2158
+ reason,
2159
+ cursor: options.adminCursor || undefined,
2160
+ limit: parseRequiredInteger(
2161
+ options.adminContextLimit ?? 20,
2162
+ "--limit",
2163
+ 1,
2164
+ 40,
2165
+ ),
2166
+ },
2167
+ );
2168
+ }
2169
+
1891
2170
  if (namespace === "bot-output" && !action) {
1892
2171
  if (options.adminDays && options.adminCursor) {
1893
2172
  throw cliValidationError(
@@ -1939,58 +2218,10 @@ export function parseAdminOperation(options) {
1939
2218
  "comment reply targets a comment: lumine admin comment reply comment:<id>.",
1940
2219
  );
1941
2220
  }
1942
- const reviewedBuildVersionId = options.adminReviewedBuildVersion
1943
- ? parseRequiredInteger(
1944
- options.adminReviewedBuildVersion,
1945
- "--reviewed-version",
1946
- 1,
1947
- )
1948
- : undefined;
1949
- const buildReviewMethod = options.adminBuildReviewMethod
1950
- ? parseAdminBuildReviewMethod(options.adminBuildReviewMethod)
1951
- : undefined;
1952
- const reviewReceipt = options.adminReviewReceipt
1953
- ? parseBuildReviewReceipt(options.adminReviewReceipt)
1954
- : null;
1955
- const buildReviewUnderstanding = options.adminReviewContext
1956
- ? readBuildReviewContextFile(options.adminReviewContext)
1957
- : undefined;
1958
- if (reviewReceipt && (reviewedBuildVersionId || buildReviewMethod)) {
1959
- throw cliValidationError(
1960
- "Pass either --review-receipt or manual --reviewed-version/--reviewed-via evidence, not both.",
1961
- );
1962
- }
1963
- const confirmedBuildVersionId = reviewReceipt
1964
- ? Number(reviewReceipt.publishedArtifactVersionId)
1965
- : reviewedBuildVersionId;
1966
- const confirmedBuildReviewMethod = reviewReceipt
1967
- ? "runtime"
1968
- : buildReviewMethod;
1969
- if (
1970
- buildReviewUnderstanding &&
1971
- (!confirmedBuildVersionId || !confirmedBuildReviewMethod)
1972
- ) {
1973
- throw cliValidationError(
1974
- "--review-context requires confirmed Build review evidence.",
1975
- );
1976
- }
1977
- if (
1978
- (confirmedBuildVersionId || confirmedBuildReviewMethod) &&
1979
- !buildReviewUnderstanding
1980
- ) {
1981
- throw cliValidationError(
1982
- "Build review evidence requires --review-context <context.json>.",
1983
- );
1984
- }
1985
- if (
1986
- reviewReceipt &&
1987
- parsedTarget.type === "build" &&
1988
- Number(reviewReceipt.buildId) !== parsedTarget.id
1989
- ) {
1990
- throw cliValidationError(
1991
- "The review receipt belongs to a different Build.",
1992
- );
1993
- }
2221
+ const reviewEvidence = readAdminBuildReviewEvidence(
2222
+ options,
2223
+ parsedTarget,
2224
+ );
1994
2225
  if (parsedTarget.type === "build") {
1995
2226
  if (!options.adminFile) {
1996
2227
  throw cliValidationError(
@@ -1998,21 +2229,14 @@ export function parseAdminOperation(options) {
1998
2229
  );
1999
2230
  }
2000
2231
  if (
2001
- !confirmedBuildVersionId ||
2002
- !confirmedBuildReviewMethod ||
2003
- !buildReviewUnderstanding
2232
+ !reviewEvidence.reviewedBuildVersionId ||
2233
+ !reviewEvidence.buildReviewMethod ||
2234
+ !reviewEvidence.buildReviewUnderstanding
2004
2235
  ) {
2005
2236
  throw cliValidationError(
2006
2237
  "After reviewing the project, pass review evidence and --review-context <context.json>.",
2007
2238
  );
2008
2239
  }
2009
- } else if (
2010
- parsedTarget.type !== "comment" &&
2011
- (confirmedBuildVersionId || confirmedBuildReviewMethod)
2012
- ) {
2013
- throw cliValidationError(
2014
- "Build review evidence applies only to build:<id> or a comment:<id> inside a Build.",
2015
- );
2016
2240
  }
2017
2241
  return writeOperation(
2018
2242
  "comment.draft",
@@ -2027,13 +2251,7 @@ export function parseAdminOperation(options) {
2027
2251
  ...(options.adminFile
2028
2252
  ? { content: readComposedTextFile(options.adminFile) }
2029
2253
  : {}),
2030
- ...(confirmedBuildVersionId
2031
- ? { reviewedBuildVersionId: confirmedBuildVersionId }
2032
- : {}),
2033
- ...(confirmedBuildReviewMethod
2034
- ? { buildReviewMethod: confirmedBuildReviewMethod }
2035
- : {}),
2036
- ...(buildReviewUnderstanding ? { buildReviewUnderstanding } : {}),
2254
+ ...reviewEvidence,
2037
2255
  },
2038
2256
  );
2039
2257
  }
@@ -2058,7 +2276,13 @@ export function parseAdminOperation(options) {
2058
2276
  "comment.edit",
2059
2277
  "PUT",
2060
2278
  `/cli/admin/comments/${commentId}`,
2061
- { content: readComposedTextFile(options.adminFile) },
2279
+ {
2280
+ content: readComposedTextFile(options.adminFile),
2281
+ ...readAdminBuildReviewEvidence(options, {
2282
+ type: "comment",
2283
+ id: commentId,
2284
+ }),
2285
+ },
2062
2286
  {
2063
2287
  correctionEligible: true,
2064
2288
  correctionCommentId: commentId,
@@ -2243,6 +2467,7 @@ function featuredRotateOperation(options) {
2243
2467
  {
2244
2468
  removeIds,
2245
2469
  addIds,
2470
+ ...(options.adminPostedAfter ? { postedAfter: options.adminPostedAfter } : {}),
2246
2471
  },
2247
2472
  );
2248
2473
  }
@@ -2303,6 +2528,22 @@ export function parseSubjectWindow(options) {
2303
2528
  return { mode, after: mode === "after" ? options.adminAfter : "" };
2304
2529
  }
2305
2530
 
2531
+ export function parseBuildWindow(options) {
2532
+ const selected = [
2533
+ options.adminSinceRun ? "since-run" : "",
2534
+ options.adminAfter ? "after" : "",
2535
+ options.adminIncludeLegacy ? "legacy" : "",
2536
+ ].filter(Boolean);
2537
+ if (selected.length > 1) {
2538
+ throw cliValidationError(
2539
+ "Choose one Build window: --since-run, --after, or --include-legacy.",
2540
+ );
2541
+ }
2542
+ const mode = selected[0] || "since-run";
2543
+ if (mode === "after") parseAfterForCoverage(options.adminAfter);
2544
+ return { mode, after: mode === "after" ? options.adminAfter : "" };
2545
+ }
2546
+
2306
2547
  function parseUtcDayKey(value) {
2307
2548
  const dayKey = String(value || "").trim();
2308
2549
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dayKey);
@@ -2524,7 +2765,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
2524
2765
  throw error;
2525
2766
  }
2526
2767
  const handoff = result?.data?.carryoverTodos;
2527
- if (runScope === "featured") {
2768
+ if (runScope !== "full") {
2528
2769
  if (
2529
2770
  !runId ||
2530
2771
  !handoff ||
@@ -2536,7 +2777,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
2536
2777
  Number(handoff.newlySurfacedCount) !== 0
2537
2778
  ) {
2538
2779
  const error = cliValidationError(
2539
- "The API did not confirm that carry-over telemetry was suppressed for the Featured-only run.",
2780
+ "The API did not confirm that carry-over telemetry was suppressed for the scoped run.",
2540
2781
  );
2541
2782
  error.code = "LUMINE_ADMIN_SCOPED_RUN_UNSUPPORTED";
2542
2783
  throw error;
@@ -2617,8 +2858,8 @@ function parseDailyRunScope(value) {
2617
2858
  const scope = String(value || "full")
2618
2859
  .trim()
2619
2860
  .toLowerCase();
2620
- if (!["full", "featured"].includes(scope)) {
2621
- throw cliValidationError("--scope must be full or featured.");
2861
+ if (!["full", "featured", "newspaper"].includes(scope)) {
2862
+ throw cliValidationError("--scope must be full, featured, or newspaper.");
2622
2863
  }
2623
2864
  return scope;
2624
2865
  }
@@ -3156,6 +3397,28 @@ async function printSpooledAdminResult({ operation, result, storage }) {
3156
3397
 
3157
3398
  function printAdminResult({ operation, result }) {
3158
3399
  const data = result?.data || {};
3400
+ if (operation.name === "runtime.evidence") {
3401
+ const evidence = data.evidence || {};
3402
+ console.log(`Runtime evidence (${data.host?.requested || "unknown"}): ${evidence.status || "unknown"}.`);
3403
+ console.log(`Samples: ${evidence.coverage?.samples ?? "unknown"}; latest: ${evidence.coverage?.lastAtMs ?? "unknown"}; age ms: ${evidence.coverage?.ageMs ?? "unknown"}.`);
3404
+ for (const recycle of evidence.recycles || []) {
3405
+ console.log(` ${recycle.id}: ${recycle.outcome}; under load: ${recycle.observedUnderLoad ?? "unknown"}.`);
3406
+ }
3407
+ console.log("Missing evidence is unknown, not healthy. A recovered topology does not verify interrupted user work. Use --json for full evidence.");
3408
+ return;
3409
+ }
3410
+ if (operation.name === "featured.plan") {
3411
+ for (const pair of data.plan?.replacements || []) {
3412
+ console.log(`${pair.remove.id} ${pair.remove.title} -> ${pair.add.id} ${pair.add.title}`);
3413
+ }
3414
+ console.log(`Proposed final order: ${(data.plan?.finalIds || []).join(",")}`);
3415
+ console.log(`Plan hash: ${data.planHash}. Obtain Mikey's approval before using featured apply --file <plan.json> --approve ${data.planHash}.`);
3416
+ return;
3417
+ }
3418
+ if (operation.featuredWorkflow) {
3419
+ console.log(JSON.stringify(data, null, 2));
3420
+ return;
3421
+ }
3159
3422
  if (Array.isArray(data.applications)) {
3160
3423
  console.log(`${data.applications.length} sponsor application(s):`);
3161
3424
  for (const application of data.applications) {
@@ -3300,6 +3563,13 @@ function printAdminResult({ operation, result }) {
3300
3563
  ` ${coverage.queue}: ${coverage.candidateCount} candidate(s), ${coverage.scannedCount} row(s) scanned across ${coverage.pages} page(s).`,
3301
3564
  );
3302
3565
  }
3566
+ for (const item of report.featuredReviews || []) {
3567
+ const coverage = item.coverage;
3568
+ const counts = item.encouragement || {};
3569
+ console.log(
3570
+ ` 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.`,
3571
+ );
3572
+ }
3303
3573
  for (const escalation of report.escalations) {
3304
3574
  const target =
3305
3575
  escalation.url ||