@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.
@@ -23,6 +23,11 @@ canonical structured data.
23
23
  carry-over work, or final full-run report. Every run-scoped CLI command loads
24
24
  the canonical active run and sends its ID; the API rejects a missing,
25
25
  expired, scope-mismatched, or actor-mismatched run.
26
+ - `--scope newspaper` is a newspaper-only authorization envelope. It grants
27
+ newspaper status/claim/submit/print and completion only, with comment mode
28
+ `off`. It cannot inspect queues, conduct, logs, Builds, or Featured.
29
+ Completion does not advance full-review windows or carry-over telemetry.
30
+ Its distinct `/daily-runs/start/newspaper` endpoint fails closed on older APIs.
26
31
  - The public content actor is Zero or Ciel. Mikey's operator ID is retained in
27
32
  private audit rows and is not embedded in public comment metadata.
28
33
  - Delegated HTTP work never authenticates as the bot, opens a bot socket, changes
@@ -44,6 +49,13 @@ canonical structured data.
44
49
  described below. The human's normal AI Energy and sponsor path applies;
45
50
  Lumine does not need to remain running.
46
51
 
52
+ `--output <file.json>` saves the canonical JSON result for ordinary admin
53
+ commands, whether or not `--json` is also used. Files are atomically replaced
54
+ with mode `0600`. Paginated scans keep their existing streaming-to-file path;
55
+ `news claim` keeps its claim/scaffold contract. If saving fails after a server
56
+ mutation, the structured error includes `canonicalResult`: inspect it rather
57
+ than repeating a successful mutation to recover an output file.
58
+
47
59
  The Zero/Ciel shift is assigned by **Asia/Bangkok calendar day, not by run**.
48
60
  The schedule is anchored with 2026-08-31 assigned to Zero and alternates by
49
61
  elapsed Bangkok dates from there. Every automatic primary, supplemental,
@@ -64,8 +76,10 @@ Comment mode is stored only on the current run:
64
76
  - `draft`: server-generated drafts, no public comment.
65
77
  - `post`: drafts plus idempotent publication through the ordinary comment path.
66
78
 
67
- A Featured-only run always uses comment mode `off` and grants only Featured
68
- subject inspection, subject reveal, Featured mutation, and run completion. It can complete
79
+ A Featured-only run always uses comment mode `off` and grants Featured
80
+ subject inspection, subject reveal, Featured mutation, review-bound Featured
81
+ comment encouragement (`featured:comments`), and run completion. It does not
82
+ grant generic recommendation/reward authority or comment publication. It can complete
69
83
  without a sponsor-integrity scan. Completing it does not advance any full-run
70
84
  content/cost/conduct window, queue-coverage record, last-completed identity, or
71
85
  carry-over surfacing telemetry. Start one only when Mikey requested that slice; never turn a small
@@ -73,6 +87,14 @@ request into a full review merely because the technical command needs a run.
73
87
  The API enforces these scopes, and the CLI also rejects out-of-scope operations
74
88
  before calling endpoints outside the Lumine Admin router (notably Build review).
75
89
 
90
+ Featured capacity and delegated addition authority are separate policies:
91
+ the website editor supports 100 Subjects, while delegated additions are limited
92
+ to a board of 20. `maximum` remains the delegated limit for compatibility;
93
+ `maximumScope`, `delegatedMaximum`, and `websiteMaximum` label the distinction.
94
+ A board of 25 is not a website overflow or an instruction to remove five pins.
95
+ Equal-size replacements and complete-set reorders accept up to the website's
96
+ 100-Subject capacity without exercising delegated growth authority.
97
+
76
98
  ### Private AI-bucket maintenance
77
99
 
78
100
  AI identity buckets are private operator bookkeeping, not a Zero/Ciel public
@@ -238,7 +260,11 @@ in another language; reply naturally in concise English.
238
260
 
239
261
  **Twinkle is not Reddit.** Do not rank a run's attention by popularity,
240
262
  recommendation count, or polish. Most users here are young children, and the
241
- posts that most need Zero or Ciel are the ones nobody else answered.
263
+ posts that most need Zero or Ciel are the ones nobody else answered. These
264
+ outreach priorities do not replace the full daily Featured-comment review
265
+ below: active threads need encouragement too. Featured selection has its own
266
+ primary objective: invite genuine member-to-member engagement, not assemble
267
+ the most thought-provoking posts.
242
268
 
243
269
  - **Look first at new, quiet, and overlooked users.** A child's first post, or a
244
270
  post from someone who rarely gets replies, is worth more of a run's attention
@@ -250,10 +276,10 @@ posts that most need Zero or Ciel are the ones nobody else answered.
250
276
  - **Zero engagement is a reason to act, not to skip.** A post sitting at no
251
277
  recommendations and no comments is the strongest signal in the queue that
252
278
  someone should notice it.
253
- - **Thought-provoking posts deserve substance, not applause — and an unnoticed
254
- one is the highest priority of all.** When a child asks a real question or
255
- makes a real argument and the thread is empty, that is the clearest case for
256
- a Zero/Ciel comment on the whole site. Engage with the idea itself: answer it,
279
+ - **Thought-provoking posts deserve substantive replies.** When a child asks
280
+ a real question or makes a real argument and the thread is empty, it is a
281
+ strong case for a Zero/Ciel reply, not an automatic top Featured ranking.
282
+ Engage with the idea itself: answer it,
257
283
  add a perspective or a counter-consideration, and leave the author somewhere
258
284
  to go next. A good question that nobody answered teaches a child that thinking
259
285
  hard is not worth it; that is the outcome these runs exist to prevent. This
@@ -305,21 +331,45 @@ posts that most need Zero or Ciel are the ones nobody else answered.
305
331
  - **Sincere requests for personal help are Featured material.** Posts asking
306
332
  the community for advice about school, friendships, loneliness, or other
307
333
  ordinary real-life problems embody Twinkle's purpose; being personal is never
308
- a reason to suppress or remove them. Receiving meaningful support does not
309
- make one stale or create a duty to rotate it out; keep judging what the live
310
- board contributes now, and never use prior recognition as a removal proxy.
334
+ a reason to suppress them or judge them unsuitable. Receiving meaningful
335
+ support does not reduce their value. They still participate in the daily
336
+ Featured refresh below: rotating the spotlight is not withdrawing support,
337
+ and a good post does not require an indefinite pin.
311
338
  - **Speculative privacy is never an editorial signal.** Do not lower, remove,
312
339
  unfeature, or escalate content because it might identify someone, mentions a
313
340
  school, city, class, or ordinary location, or invites everyday community
314
341
  context. Those possibilities carry zero weight in Featured decisions. An
315
342
  actual sensitive disclosure or an author's explicit removal request follows
316
343
  the separate concrete-safety path; it does not make the post low-quality.
317
- - **Featured values participation, continuity, and child voice—not adult
318
- polish.** Accessible questions that many children can answer and ongoing
319
- personal series such as records, journals, or recurring updates are strong
320
- Featured forms. Age, brevity, simplicity, prior recognition, or a modest
321
- description is not a removal reason. Review the whole subject and its role in
322
- the community instead of grading its opening text like an essay.
344
+ - **Featured prioritizes engagement, participation, and child voice.** Choose
345
+ the recent eligible Subjects most likely to get members commenting on other
346
+ members' Subjects and responding to one another. Accessible questions,
347
+ everyday experiences, playful prompts, drawings, invitations, personal help,
348
+ and ongoing records or creative series can outperform a polished essay for
349
+ this purpose. Being thought-provoking is a bonus, not the primary ranking
350
+ criterion. Explain the concrete invitation to participate, using the full
351
+ Subject and thread as context; do not rank by adult polish, intellectual
352
+ depth, existing popularity, or raw recommendation counts. Genuine engagement
353
+ does not mean bait, spam, or reward farming. Age, brevity, simplicity, prior
354
+ recognition, or a modest description does not make a Subject low-quality.
355
+ Daily rotation is an independent editorial reason to refresh a good post's
356
+ slot; do not invent a defect to justify it.
357
+ - **Aim to replace all of yesterday's Featured Subjects each day.** During a
358
+ full daily management review, plan a complete refresh of the previous day's
359
+ board with recent, never-before-Featured Subjects, ordered by likely genuine
360
+ engagement. A small handful of swaps is not the default target. Use the
361
+ Bangkok calendar day, not the number of runs: do not churn pins newly added
362
+ today because a follow-up starts another session. Quality and eligibility
363
+ still apply. If there are too few eligible candidates, a current explicit
364
+ keep instruction, an unread thread, or another concrete constraint, explain
365
+ each retained pin and the shortfall; do not pad the list or silently settle
366
+ for a partial refresh. An earlier positive assessment is not a permanent
367
+ keep instruction. New installments can carry a series forward without
368
+ treating earlier ones as noise. This daily target changes editorial judgment,
369
+ not mutation authority: show the full proposed rotation and obtain Mikey's
370
+ go-ahead before removing or reordering any pins. One go-ahead for that exact
371
+ complete plan authorizes executing all its swaps, not just the first one;
372
+ carry it through and verify the final board without seeking per-item approval.
323
373
  - **A "new" Featured addition has two non-negotiable eligibility gates.** When
324
374
  Mikey asks for new Featured subjects, additions, or replacements, a candidate
325
375
  must both (1) have been posted recently and (2) have never appeared on the
@@ -336,7 +386,7 @@ posts that most need Zero or Ciel are the ones nobody else answered.
336
386
  - **The live Featured board is Mikey's word.** Do not remove or reorder a
337
387
  currently Featured subject without first showing Mikey the planned removals
338
388
  and replacements and getting his go-ahead. Additions have standing approval
339
- when a fresh `featured list` is below its canonical maximum: proactively
389
+ when a fresh `featured list` is below its delegated-admin maximum: proactively
340
390
  feature genuinely reviewed, editorially strong new subjects without asking
341
391
  case by case. This is judgment, not a quota — never add filler merely because
342
392
  capacity exists. If a subject that was Featured or pinned during an earlier
@@ -351,6 +401,110 @@ Sensitive disclosures, active disputes, and anything needing crisis or medical
351
401
  judgment remain out of scope for a bot comment no matter how neglected the post
352
402
  is. Those go to Mikey.
353
403
 
404
+ ### Daily Featured comments and refresh
405
+
406
+ This is a standing duty for every **full daily management review**, after the
407
+ newspaper duty. It is not an instruction to start or repeat a full run when
408
+ Mikey requests a small edit, proposal, or other scoped action. A request only
409
+ to discuss Featured candidates authorizes discussion, not recommendations or
410
+ pin changes. The technical `--scope featured` envelope permits the review-bound
411
+ comment workflow below only when encouragement is in Mikey's requested slice;
412
+ it never authorizes unrelated daily work or generic recommendation commands.
413
+
414
+ 1. **Read all comments on every current Featured Subject each day.** Start
415
+ from a fresh `featured list`, save the dated board, and inspect each full
416
+ Subject and all top-level comments and nested replies. Include old and
417
+ already-viewed comments, not just new ones, the recommendation queue, or a
418
+ sample of the thread. Review outgoing Subjects before their approved
419
+ rotation so their commenters are not missed; review any newly added
420
+ Subjects' threads too. Use `featured comments scan --checkpoint <file>` to
421
+ download every snapshot-bound page, then actually read every listed page
422
+ file before `featured comments acknowledge --checkpoint <file> --reviewed`.
423
+ Fetching does not acknowledge reading. A fresh scan after rotation covers
424
+ the incoming board. `commentsIncluded: false` or a locked secret is not
425
+ an empty thread: use the ordinary authorized reveal path, never bypass
426
+ secret semantics, and report any inaccessible or unfinished coverage.
427
+ Preserve the reviewed snapshot boundaries so "all" describes actual reads.
428
+ 2. **At least recommend most comments that are not genuinely worthless.**
429
+ The purpose is to encourage members to comment on other users' Subjects and
430
+ to give those contributions visibility. A sincere answer, friendly reaction,
431
+ relevant joke, question, attempt to help, or conversational follow-up is
432
+ usually enough; it need not be profound, long, polished, or Twinkle-worthy.
433
+ Read in context and lean toward encouragement. A one-line or emoji response
434
+ can be worthwhile; brevity or "nothing for the bot to add" is not a reason
435
+ to withhold a recommendation. Do not restrict recognition to a few standout
436
+ replies. Do not mechanically approve everything: genuine spam, meaningless
437
+ noise, harassment, or exploit promotion is not deserving merely because it
438
+ appears on Featured. System/view notifications and the bots' own comments
439
+ are context to read, not user participation to boost or count toward this
440
+ duty. Leave narrow concrete-safety cases for Mikey under the existing rules.
441
+ 3. **Separate encouragement from reward eligibility.** The ordinary action is
442
+ a selected item in `featured comments recommend --file <decisions.json>`,
443
+ omitting `anyoneCanReward` and `rewardTwinkles` (defaults: `false` and `0`).
444
+ Turn on the UI's "everyone can
445
+ reward" option (`anyoneCanReward: true`) only when the comment independently
446
+ deserves that stronger endorsement; direct Twinkle rewards are selective
447
+ too. Do not withhold a basic recommendation just because rewards are not
448
+ deserved, and do not mass-enable rewards to satisfy this duty. Honor
449
+ canonical Zero/Ciel deduplication: already-recommended comments still get
450
+ read, but do not need a second recommendation or daily reward. A bare
451
+ recommend does not revoke an existing reward permission; never claim it
452
+ switched one off. This duty is not authority to downgrade past decisions.
453
+ 4. **Propose the whole daily refresh, get approval, then execute it.** Identify carryover
454
+ pins from the saved board and canonical Featured history, without assuming
455
+ missing pins should be restored. Review replacements under the recency and
456
+ never-Featured gates above and rank them by the engagement they invite.
457
+ Show Mikey a specific old-Subject -> new-Subject mapping with titles, IDs,
458
+ canonical URLs, reasons, and the proposed final order, plus any retained
459
+ pins and specific constraints. Explicitly ask for his go-ahead and wait
460
+ before performing the proposed rotation. Daily freshness
461
+ and giving new conversations a turn are sufficient editorial reasons; a
462
+ prior Subject need not become bad or unsuitable first. Keep existing
463
+ removal/reorder approval and addition-capacity boundaries intact. After
464
+ Mikey approves the exact plan, autonomously perform **all approved swaps
465
+ and the approved ordering**, without per-item approval or asking him to
466
+ operate the website. Prepare the server-stored `featured plan` before
467
+ presenting it, then use `featured apply --file <plan.json> --approve <hash>`
468
+ only after that exact plan gets his go-ahead. Membership and final ordering
469
+ commit together; the server rechecks the original board, history revision,
470
+ and new-candidate eligibility inside the board transaction.
471
+ Verify the exact final membership and order from the server, then report
472
+ completion. Recover retryable failures within the approved scope; if
473
+ intervening owner changes, eligibility changes, or an API limit require a
474
+ materially different plan, preserve the new state, report what actually
475
+ completed, and seek approval for that difference instead of substituting
476
+ candidates or overwriting changes. Report proposals separately from
477
+ completed actions. Approval is for the presented plan, not future boards.
478
+ 5. **Make coverage and encouragement auditable.** In the final full-run report,
479
+ state Subjects covered, comments read, new basic recommendations,
480
+ already-recommended comments, selective reward-eligibility grants/direct
481
+ rewards, and genuinely skipped categories. Use canonical results, not
482
+ attempted commands, for action counts. Report any unread Subjects/pages
483
+ explicitly; never call a sample, a filtered queue, or a blocked thread a
484
+ completed all-Featured-comment review. Include refresh progress and any
485
+ carryovers as required in the `Featured rotation` report section below.
486
+
487
+ ## Math Lab content duty in full daily management
488
+
489
+ Mikey added Math Lab question design and publishing to the full daily workflow
490
+ on 2026-09-08. Follow [Math Lab daily question publishing](../../agent-guides/math-lab-daily.md)
491
+ for the canonical Build 2460, owner account, 12-grade/36-question editorial
492
+ process, verification, repeat-run recovery, release gates, and final reporting.
493
+ This is not part of Featured-only or newspaper-only work and is not a new
494
+ scheduler, delegated API scope, or automatic extension of admin permissions.
495
+ Use the expressly authorized owner Build workflow for Math Lab; retain the
496
+ normal Zero/Ciel actor separation for other administration.
497
+
498
+ The initial private draft must remain unpublished until Mikey authorizes its
499
+ launch. After launch, routine content releases follow the standing duty but
500
+ cannot bypass a reward-enabled app's exact-version approval gate. Local edits
501
+ and draft saves do not require release approval. Real XP/Coins may be changed
502
+ only by the currently published, approved artifact through server-verified
503
+ reward claims; private builds, previews, local tests, unpublished branches, and
504
+ superseded versions cannot award real balances. These reward controls are a
505
+ required design contract, not a claim that a reward SDK or server enforcement
506
+ has already been implemented. See the guide before adding reward capabilities.
507
+
354
508
  ## Escalation to Mikey
355
509
 
356
510
  A full daily management run is not finished when the mutations are done. Curation surfaces things only
@@ -620,7 +774,7 @@ type DailyRun = {
620
774
  publicActorUserId: number;
621
775
  identityMode: "auto" | "zero" | "ciel";
622
776
  commentMode: "off" | "draft" | "post";
623
- runScope: "full" | "featured";
777
+ runScope: "full" | "featured" | "newspaper";
624
778
  sessionKind: "delegated-admin";
625
779
  scopes: string[];
626
780
  status: "active" | "completed" | "failed" | "expired";
@@ -722,6 +876,7 @@ identity, or advances rotation.
722
876
  ```bash
723
877
  lumine admin daily-run start --identity auto --comment-mode off --json
724
878
  lumine admin daily-run start --scope featured --identity auto --json
879
+ lumine admin daily-run start --scope newspaper --identity auto --json
725
880
  lumine admin daily-run start --identity ciel --comment-mode draft \
726
881
  --run-key daily:2026-08-06:review --json
727
882
  lumine admin daily-run status --json
@@ -815,16 +970,22 @@ written automatically only after an
815
970
  its local checkpoint and cannot be misreported as complete.
816
971
 
817
972
  **Every agent-authored final full-management report includes a `Featured rotation`
818
- section.** Base it on a fresh `featured list`. When capacity exists, make and
819
- report strong additions during the run under the standing approval above; do
820
- not defer them as proposals. Then name each current Subject proposed for
821
- removal with its canonical URL and a concrete editorial reason, followed by
822
- any replacement that would require that removal. Every proposed or completed
823
- addition described as new must include its posting date and canonical evidence
824
- that it has never been Featured; omit it when either gate is unverified. Never
825
- omit the section; when no removal or reorder is honestly warranted, say `None`
826
- and explain why. Removing or reordering pins remains a proposal until Mikey
827
- gives his go-ahead.
973
+ section.** Base it on the dated starting board, a fresh `featured list`, and
974
+ canonical history. Report the target of replacing **all previous-day pins**,
975
+ the exact proposed/completed outgoing-to-incoming mapping, and each retained
976
+ pin with its reason. Rank new candidates by likely genuine member engagement,
977
+ not thoughtfulness. Include the all-Featured-comment coverage and encouragement
978
+ counts described above. When genuine capacity exists, make and report strong
979
+ additions under the standing approval above; do not defer those as proposals.
980
+ Every proposed or completed new addition must include its posting date and
981
+ canonical never-Featured evidence; omit it when either gate is unverified.
982
+ If a complete refresh is constrained, state the shortfall, including inadequate
983
+ eligible inventory, inaccessible context, specific keep instructions, or pending
984
+ approval. Do not report `None` merely because yesterday's posts are still good
985
+ or have received support. Removing or reordering pins remains a proposal until
986
+ Mikey gives his go-ahead; a pending proposal is not a completed refresh. After
987
+ approval, execute the entire approved plan and verify it without asking for
988
+ each swap again. Never omit this section from a full-run report.
828
989
 
829
990
  Creating an escalation belongs to the active run; acknowledging, annotating,
830
991
  resolving, or reopening it does not. Use the run-independent `escalation`
@@ -898,6 +1059,53 @@ migration cannot quietly treat unsupported telemetry as an empty list.
898
1059
  A Featured-only start instead returns an explicitly suppressed, empty handoff
899
1060
  and performs no todo reads, writes, capacity checks, or surfacing increments.
900
1061
 
1062
+ Evidence-dependent investigations must have a durable collection plan. Do not
1063
+ carry “still no recycle-under-load evidence” forward without checking the
1064
+ collector and recording new observations. Full starts and reports return
1065
+ `runtimeEvidence` with a scoped read command; this handoff is suppressed for
1066
+ Featured/newspaper slices. During a full daily run with pending runtime
1067
+ investigations, use:
1068
+
1069
+ ```sh
1070
+ lumine admin runtime evidence primary --days 7 --json
1071
+ # Only when the investigation also covers the configured target host:
1072
+ lumine admin runtime evidence target --days 7 --json
1073
+ ```
1074
+
1075
+ This is a read-only, run-independent command. It does not acquire/clear a log
1076
+ lease, trigger a recycle, or authorize an unrelated management review. Host
1077
+ routing is explicit and never silently substitutes primary for target. An
1078
+ older API without this endpoint is unsupported, not “no incidents.”
1079
+
1080
+ The cluster primary samples existing worker health snapshots once per minute
1081
+ and records memory-guard/operator recycle lifecycle events. Records survive
1082
+ restarts in the health directory's `evidence/` subdirectory (seven UTC calendar
1083
+ days, at most 2 MiB/day; 256 KiB/day reserved for events). Work is recorded as
1084
+ counts by kind, not user IDs, request labels, messages or tokens. Evidence is
1085
+ passive: never force production load, a worker recycle or a restart merely to
1086
+ complete an experiment. New collector code requires activation of the new
1087
+ **primary generation**, not just a rolling worker reload; verify a fresh live
1088
+ sample before saying collection is running.
1089
+
1090
+ For each affected todo, persist the checked host/runtime identity, previous and
1091
+ new evidence cutoff, sample count/gaps/freshness, qualifying event IDs and the
1092
+ next safe action. `unavailable`, `stale` or `incomplete` means investigate the
1093
+ collection gap. A healthy collector with no qualifying recycle means keep
1094
+ collecting, not stall or claim a failure. Save the relevant summary in the todo
1095
+ before the seven-day retention window passes. Missing/stale active-work or OOM
1096
+ observations remain unknown; they are never zero or idle by default.
1097
+
1098
+ Set investigation-specific acceptance criteria before interpreting results.
1099
+ For memory/recycle investigations, distinguish a long-lived steady-memory
1100
+ baseline from a recycle observed under load. Require the requested/signalled/
1101
+ recovered sequence, fresh pre-recycle work evidence, replacement identity,
1102
+ bounded recovery time, and no OOM-counter increase across the same primary
1103
+ generation. “Topology recovered” does **not** prove each interrupted user task
1104
+ completed: correlate those tasks' existing canonical outcomes before closing
1105
+ a user-work continuity investigation. Never close based only on deployed code,
1106
+ a current healthy snapshot, or an unobserved event. Daily runs collect evidence
1107
+ and update todos; fixes and releases follow the project's existing authority rules.
1108
+
901
1109
  `kind` is `task` or `experiment`. New items may start `open`, `in_progress`, or
902
1110
  `blocked`; updates may also use `completed` or `cancelled`. A progress note is
903
1111
  required for every update. For experiments, put the acceptance criteria in the
@@ -1075,8 +1283,10 @@ verifies the request fingerprint and confirmed spool digest before requesting
1075
1283
  another page. An interrupted request is never counted as queue coverage.
1076
1284
 
1077
1285
  Recommendations default to `--since-run`: the server uses the previous
1078
- completed run's start time (or the same bounded seven-day fallback used by the
1079
- brief on a first run). That deliberate start-to-start overlap gives the queue
1286
+ completed full run's start time, even if that gap exceeds 30 days. On a first
1287
+ run, the fallback begins seven days before the current run's stored start, so
1288
+ it cannot drift between pages. Insight reports retain their separate 30-day
1289
+ limit. That deliberate start-to-start overlap gives the queue
1080
1290
  at-least-once coverage when content arrives after the prior snapshot but before
1081
1291
  that run completes. `--after` supplies an explicit inclusive timestamp.
1082
1292
  All-history traversal is deliberately available only through
@@ -1084,6 +1294,12 @@ All-history traversal is deliberately available only through
1084
1294
  boundary for bounded modes, so deploying a new CLI against an older API cannot
1085
1295
  silently fall back to a million-row historical scan.
1086
1296
 
1297
+ After upgrading the API and CLI to the stable run-start window, start a fresh
1298
+ `--since-run` scan with a new checkpoint path, without `--resume`. Older
1299
+ since-run checkpoints are rejected even when already exhausted: they may have
1300
+ captured the former 30-day reporting cap. They are left intact as evidence.
1301
+ Explicit `--after` and `--include-legacy` checkpoints retain their contracts.
1302
+
1087
1303
  Subject candidates follow the same window contract. They default to the
1088
1304
  previous completed full run's start (with the seven-day first-run fallback),
1089
1305
  accept an explicit inclusive `--after`, and require `--include-legacy` for a
@@ -1091,9 +1307,16 @@ lifetime traversal. `--since-run`, `--after`, and `--include-legacy` are
1091
1307
  mutually exclusive. The CLI also requires the API to echo the bounded Subject
1092
1308
  window before accepting a page.
1093
1309
 
1094
- `builds candidates` is a management-agent discovery view over the canonical
1095
- public Build browser, ordered by the current published release. It is
1096
- available through the `admin` namespace only while a delegated run is active;
1310
+ `builds candidates` uses the admin publication-window endpoint, ordered by
1311
+ `publishedAt` and Build ID, not workspace `updatedAt`. Like Subject discovery,
1312
+ it defaults to the previous completed full run's start (seven-day first-run
1313
+ fallback), accepts inclusive `--after`, and requires `--include-legacy` for
1314
+ all history. These flags are mutually exclusive. The first page freezes the
1315
+ time boundary and an artifact-version high-water mark; the cursor and local
1316
+ checkpoint retain both. An old public-browser checkpoint cannot be reused.
1317
+ The CLI fails closed if the API does not confirm this publication window.
1318
+
1319
+ It is available through the `admin` namespace only while a delegated run is active;
1097
1320
  page until `pagination.exhausted`. Each item includes its canonical app URL,
1098
1321
  published artifact version, and whether its code is pullable. This list does
1099
1322
  not decide that an app deserves a comment. The management agent must open and
@@ -1101,6 +1324,12 @@ genuinely try the published runtime, or pull and read an open-source project,
1101
1324
  before making that judgment. Direct API/persona automation is never a review
1102
1325
  substitute.
1103
1326
 
1327
+ Only current public Main releases are candidates. Workspace-only saves and
1328
+ unchanged reactivations do not become new releases. A Build republished during
1329
+ paging can leave the snapshot; its new release is reconsidered by the next
1330
+ overlapping start-to-start window. Always recheck the current artifact before
1331
+ reviewing; this is not a frozen copy of an app or an immutable release archive.
1332
+
1104
1333
  `builds review` is the managed runtime path: it fetches the current published
1105
1334
  artifact identity, launches the app in an isolated temporary Chromium profile,
1106
1335
  captures a screenshot and bounded console evidence, then fetches the identity
@@ -1147,12 +1376,19 @@ website's canonical reward-level projection shape; deployment should verify
1147
1376
  (or `(contentId, ...)`) as the canonical route already requires. The joins/`NOT EXISTS` checks are necessary
1148
1377
  to preserve the normal recommendation and skip rules, but they run only for
1149
1378
  IDs in that bounded window. Subject-comment traversal uses
1150
- `idx_comments_isDeleted_subject_id`; standalone-post comments use the existing
1379
+ `idx_comments_isDeleted_subject_id`; standalone-post and Build comments use the existing
1151
1380
  `idx_content_comments_root_deleted` index (whose InnoDB entries also carry the
1152
1381
  primary ID). Recommendation identity uses
1153
1382
  `uniq_content_recommendations_active_identity`; `earn_comment_candidates` is
1154
1383
  driven by its primary key. No offset scan or new broad table scan was added.
1155
1384
 
1385
+ Featured comment review adds at most 100 per-Subject `MAX(id)` probes using
1386
+ `idx_comments_isDeleted_subject_id`, then reuses the bounded 50-comment page
1387
+ path. Receipt lookups use the audit primary key; review summaries use the
1388
+ existing `idx_laae_run_id (runId, id)` range and project only coverage/action
1389
+ outcomes, not downloaded comment bodies. Approved plans use the shared board
1390
+ lock and the history primary key for `MAX(id)`. No new schema is needed.
1391
+
1156
1392
  Deployment can verify the required existing index definitions with:
1157
1393
 
1158
1394
  ```sql
@@ -1199,8 +1435,18 @@ lumine admin subject comments 123 --cursor '<cursor>' --json
1199
1435
  lumine admin comments get 456 --json
1200
1436
  lumine admin post get https://www.twin-kle.com/ai-stories/88 --json
1201
1437
  lumine admin post comments dailyReflection:99 --cursor '<cursor>' --json
1438
+ lumine admin post comments build:884 --all --output build-comments.json --json
1202
1439
  ```
1203
1440
 
1441
+ Build comment inspection accepts `build:<id>`, a public `/app/<id>` URL, or
1442
+ `--type build`. It reads all root-thread comments and replies through a
1443
+ snapshot-bound cursor, with full text and `parentCommentId`/`replyToCommentId`
1444
+ relationships.
1445
+ Only public, published, canonical owner Builds qualify; contribution branches
1446
+ and private/unpublished Builds are rejected. This is thread inspection, not
1447
+ evidence of having reviewed the published app. Build-comment publication still
1448
+ requires its separate version-bound review evidence.
1449
+
1204
1450
  Schemas:
1205
1451
 
1206
1452
  ```ts
@@ -1300,6 +1546,9 @@ type FeaturedList = Success<{
1300
1546
  subjects: Subject[];
1301
1547
  count: number;
1302
1548
  maximum: 20;
1549
+ maximumScope: "delegated_admin";
1550
+ delegatedMaximum: 20;
1551
+ websiteMaximum: 100;
1303
1552
  }>;
1304
1553
 
1305
1554
  type FeaturedHistory = Success<{
@@ -1379,7 +1628,7 @@ effective level). Every response is reloaded from the writer.
1379
1628
 
1380
1629
  Featured reorder is a complete-set replacement: it rejects duplicates,
1381
1630
  unknown/deleted IDs, missing current members, non-subject rows, and more than
1382
- 20 subjects. Permanent pins and editorial ordering policy are deliberately not
1631
+ 100 subjects. Permanent pins and editorial ordering policy are deliberately not
1383
1632
  hardcoded.
1384
1633
 
1385
1634
  `featured history` is the compact canonical evidence path. It returns only
@@ -1391,6 +1640,16 @@ after the finalized coverage boundary. `null` means the subject predates provabl
1391
1640
  coverage—never convert that unknown into “never Featured.” Both the website
1392
1641
  editor and Lumine mutations write this append-only history in the same
1393
1642
  transaction as the canonical board replacement.
1643
+ Each API read accepts up to **100 subject IDs**, independently of the
1644
+ 20-subject delegated addition policy. `--all` automatically batches larger
1645
+ lists (up to 20,000 IDs), exhausts every batch's event pages, and retains all
1646
+ per-subject summaries. Use the exact command with `--resume` after interruption;
1647
+ confirmed pages are not replayed. Single-batch `--cursor` remains available,
1648
+ but cannot be combined with `--all`. Multi-batch results explicitly use
1649
+ `pagination.snapshotScope: "per-batch"`; events are ordered by input batch,
1650
+ then descending event ID within that batch—not by one global snapshot.
1651
+ `data.scan.batches` records each batch's coverage, snapshot and private spool.
1652
+ Deploy the matching API before using the expanded read bound.
1394
1653
  For a retry whose board transaction committed but whose canonical detail reload
1395
1654
  failed, the audit-linked history event is the durable receipt: the API re-reads
1396
1655
  the current board and preserves the original changed-mutation accounting.
@@ -1423,9 +1682,12 @@ The response includes the canonical final board and the confirmed rotation
1423
1682
  IDs, so callers never synthesize Featured state locally.
1424
1683
 
1425
1684
  The two lists must have the same nonzero length, so rotation never changes the
1426
- board's count. That also lets an approved swap proceed when the website has
1427
- left a pre-existing board above the delegated maximum without growing it;
1428
- repair the inherited overflow separately with an approved `subject unfeature`.
1685
+ board's count. Up to 100 replacements are accepted, including an existing board
1686
+ above the delegated growth limit of 20. That is not an overflow to repair.
1687
+ The server also enforces live, recent, provably never-Featured additions. Pass
1688
+ `--posted-after` explicitly; for compatibility the legacy rotation command
1689
+ defaults to seven days before the current Bangkok day's midnight. The exact
1690
+ approved-plan workflow below always requires an explicit cutoff.
1429
1691
 
1430
1692
  This mutation deliberately does not choose candidates or override the
1431
1693
  editorial gates above. Before invoking it, the management agent must have
@@ -1433,11 +1695,120 @@ freshly reviewed the board, shown Mikey the removals and replacements, received
1433
1695
  his go-ahead, and verified that every proposed new addition is recent and has
1434
1696
  never previously been Featured from canonical evidence.
1435
1697
 
1698
+ ### Exact approved refresh and resumable comment encouragement
1699
+
1700
+ For the daily old-to-new proposal, prepare a canonical plan without changing pins:
1701
+
1702
+ ```bash
1703
+ lumine admin featured plan --remove-subject-ids 30,20 \
1704
+ --add-subject-ids 50,40 --subject-ids 40,50,10 \
1705
+ --posted-after 2026-09-01T00:00:00+07:00 --output featured-plan.json --json
1706
+ ```
1707
+
1708
+ Removal and addition lists are equal-size pairs. Optional `--subject-ids` is
1709
+ the **entire final ordered board**, including retained pins; without it,
1710
+ additions lead in supplied order and retained pins keep their relative order.
1711
+ The receipt contains titles, IDs, URLs, replacement pairs, final order, posting
1712
+ cutoff, run/actor identity, expected board and history revision, and `planHash`.
1713
+ Add qualitative reasons, show Mikey the exact mapping/order, and wait for his
1714
+ go-ahead. A generated hash is not itself human approval. After approval:
1715
+
1716
+ ```bash
1717
+ lumine admin featured apply --file featured-plan.json \
1718
+ --approve <exact-plan-hash> --json
1719
+ ```
1720
+
1721
+ The API loads the immutable plan from its same-run/operator/actor audit receipt,
1722
+ checks the supplied hash, and applies all swaps and ordering in one transaction.
1723
+ It rejects intervening reorders, swaps, even a changed-then-restored board, and
1724
+ newly ineligible candidates. No substitute candidates or follow-up reorder are
1725
+ inferred. The CLI then reads the live board and verifies exact membership/order.
1726
+ Retry the identical apply command after uncertain transport failure; it reuses
1727
+ the same idempotency key. If the final read fails or finds an intervening change,
1728
+ the error retains the canonical apply receipt and never restores old state.
1729
+ Expired/different runs require a fresh plan and renewed approval.
1730
+
1731
+ Use the following workflow for full daily comment review, or only when Mikey's
1732
+ Featured slice includes comment encouragement:
1733
+
1734
+ ```bash
1735
+ lumine admin featured comments scan --checkpoint featured-read.json --json
1736
+ # On interruption: repeat with --resume, in the same active run.
1737
+ # Read ALL pageFiles, including full root context and nested replies.
1738
+ lumine admin featured comments acknowledge \
1739
+ --checkpoint featured-read.json --reviewed --json
1740
+ ```
1741
+
1742
+ The scan snapshots every current Featured Subject (up to 100) and its maximum
1743
+ comment ID, includes already-viewed and older comments, and downloads full-text
1744
+ pages of 50 through server-owned receipt chains. It rejects filtered scans;
1745
+ there is no popularity, length, language, or keyword selection heuristic.
1746
+ Each private mode-0600 page file has a checkpointed hash; resume verifies the
1747
+ complete chain and uses stable request keys after lost responses. Concurrent
1748
+ use of a checkpoint is locked. Deleted/unavailable Subjects and locked secrets
1749
+ remain explicitly incomplete; an empty thread still requires a terminal page.
1750
+ The scanner never automatically reveals secrets. If reveal is authorized, use
1751
+ the ordinary explicit reveal command and resume. New comments above the saved
1752
+ boundary belong to a fresh scan, not a silently expanded claim of coverage.
1753
+
1754
+ `acknowledge --reviewed` is the agent's explicit confirmation that it read the
1755
+ downloaded terminal chains. The API validates those chains, records covered and
1756
+ missing Subject IDs and comment counts, and distinguishes complete from partial
1757
+ coverage. A download alone never counts as a read or grants recommendations.
1758
+ After a resumed scan fills a gap, read those pages and acknowledge again.
1759
+
1760
+ Compose a decisions JSON file from the genuinely reviewed comments, using the
1761
+ returned review ID, coverage receipt ID, and each selected comment's page ID:
1762
+
1763
+ ```json
1764
+ {
1765
+ "reviewId": 100,
1766
+ "coverageId": 1050,
1767
+ "selections": [
1768
+ { "commentId": 120, "pageId": 1001 },
1769
+ { "commentId": 119, "pageId": 1001, "anyoneCanReward": true },
1770
+ { "commentId": 118, "pageId": 1001, "anyoneCanReward": true, "rewardTwinkles": 3 }
1771
+ ]
1772
+ }
1773
+ ```
1774
+
1775
+ The agent chooses comments by context under the generous encouragement policy;
1776
+ the tool never auto-selects them. Reward permission defaults off; the only
1777
+ direct reward option is an explicitly selected 3-Twinkle pairing. Existing
1778
+ permissions are not revoked by a basic recommendation. Then apply and report:
1779
+
1780
+ ```bash
1781
+ lumine admin featured comments recommend --file featured-decisions.json \
1782
+ --checkpoint featured-recommend.json --json
1783
+ # Retry exactly this file/checkpoint with --resume after interruption.
1784
+ lumine admin featured comments report --checkpoint featured-read.json --json
1785
+ ```
1786
+
1787
+ Use separate scan and recommendation checkpoints. Selection files are capped at
1788
+ 20,000 unique comments/2 MiB; split larger work into explicit batches. Each
1789
+ target must belong to the reviewed page and an acknowledged Subject chain in
1790
+ this same run. The API re-reads it, rejects changed/hidden/deleted comments,
1791
+ system notifications and Zero/Ciel's own comments, and uses the normal canonical
1792
+ recommendation/reward/deduplication path. A blocked Subject does not prevent
1793
+ encouragement on acknowledged Subjects. Batches stop at a failed decision,
1794
+ retain confirmed receipts, and resume without replaying completed decisions.
1795
+ These recommendations are independent per-comment mutations, not an atomic
1796
+ batch; report partial completion honestly.
1797
+
1798
+ The review report and full/historical daily reports' `featuredReviews` expose
1799
+ acknowledged coverage, confirmed new/basic recommendations, already-done
1800
+ actions, selective reward-permission grants, and created direct rewards. The
1801
+ counts describe canonical outcomes, not attempted commands or downloaded rows.
1802
+ Read comments that are already recommended too; use the page evidence for
1803
+ already-recommended and skipped-category totals rather than treating the
1804
+ report's selected `alreadyDone` actions as all previously recommended comments.
1805
+
1436
1806
  ## Recommendation, Karma approval, and Twinkle rewards
1437
1807
 
1438
1808
  ```bash
1439
1809
  lumine admin post recommend 123 --json
1440
1810
  lumine admin post recommend https://www.twin-kle.com/ai-stories/88 --json
1811
+ lumine admin post recommend comment:456 --json
1441
1812
  lumine admin post recommend comment:456 --anyone-can-reward \
1442
1813
  --reward-twinkles 3 --idempotency-key review-456-v1 --json
1443
1814
  lumine admin post reward comment:456 --twinkles 3 --json
@@ -1447,6 +1818,15 @@ Numeric targets default to `subject`. Use `subject:<id>`, `comment:<id>`,
1447
1818
  `aiStory:<id>`, `dailyReflection:<id>`, a canonical URL, or the corresponding
1448
1819
  `--type`.
1449
1820
 
1821
+ For daily Featured-comment encouragement, prefer the review-bound
1822
+ `featured comments` workflow above so coverage and outcomes remain linked.
1823
+ The generic bare comment recommendation has the same basic default, but is
1824
+ not available in a Featured-only run. `--anyone-can-reward` and
1825
+ `--reward-twinkles` are separate, selective judgments, not required flags for an
1826
+ ordinary worthwhile comment.
1827
+ Follow **Daily Featured comments and refresh** for full-thread coverage and
1828
+ the intentionally generous basic-recommendation threshold.
1829
+
1450
1830
  ```ts
1451
1831
  type PriorRecommendationApproval = {
1452
1832
  recommendationId: number;
@@ -1553,7 +1933,7 @@ If recommendation succeeds but reward fails, the command exits nonzero with
1553
1933
 
1554
1934
  ```bash
1555
1935
  lumine admin post skip dailyReflection:99 --json
1556
- lumine admin post skip comment:456 --reason "one-line answer, nothing to add" --json
1936
+ lumine admin post skip comment:456 --reason "duplicate coin-begging spam" --json
1557
1937
  lumine admin post skip-batch --target-file skip-targets.json \
1558
1938
  --checkpoint skip-progress.json --json
1559
1939
  lumine admin post skip-batch --target-file skip-targets.json \
@@ -1827,10 +2207,23 @@ type NewsSubmit = NewsStatus; // "success"; newspaper includes revisionNumber
1827
2207
  lumine admin bot-output --json
1828
2208
  lumine admin bot-output --days 3 --json
1829
2209
  lumine admin bot-output --cursor '<pagination.nextCursor>' --json
2210
+ lumine admin bot-output context 3797910 --reason "Review reported bot conduct in its conversation context" --json
2211
+ lumine admin bot-output context 3797910 --reason "Continue the same bot-conduct review" --cursor '<pagination.nextCursor>' --json
1830
2212
  ```
1831
2213
 
1832
2214
  **Every full daily review reads what Zero and Ciel themselves said since the
1833
2215
  last completed full review.**
2216
+
2217
+ **Ordinary wrong answers and hallucinations are expected model limitations,
2218
+ not website incidents.** A factual error, mistaken puzzle answer, or imperfect
2219
+ reasoning alone does not warrant an escalation, engineering todo, or a code
2220
+ patch. Model quality improves through LLM upgrades; do not add hard-coded
2221
+ answer validators, secondary graders, forced research, correctness retry loops,
2222
+ or subject-specific rules to compensate. A normal conversational correction is
2223
+ enough when appropriate. This does not excuse actual harmful conduct or
2224
+ application failures, nor weaken security, permissions, billing, or canonical
2225
+ server-state checks: investigate those distinct problems on concrete evidence.
2226
+
1834
2227
  The bots talk to children constantly — chat replies, Daily Reflection
1835
2228
  responses, autonomous comment-assistant comments — and a harmful message must
1836
2229
  never depend on a kid being brave enough to report it (real incident,
@@ -1856,6 +2249,27 @@ right after the brief, and **read every row** — the tool deliberately does no
1856
2249
  filtering, scoring, or keyword matching, because the judgment is the reviewing
1857
2250
  agent's.
1858
2251
 
2252
+ Chat output now also includes `messageKind`, `attachment`, and the stored
2253
+ `generation` outcome (success, failure, cancelled, generating, or unresolved).
2254
+ This is stored-message evidence, not a live request-guard check: do not call
2255
+ an empty row an orphan solely from its text. Hidden attachment locations and
2256
+ arbitrary settings/request keys are never returned. `source: voice` identifies
2257
+ newly recorded voice transcripts, while typed input during a call says `typed`;
2258
+ older replies correctly say `not-recorded`
2259
+ because the historical schema did not distinguish typed text from voice.
2260
+
2261
+ `bot-output context <messageId>` is a private, **run-independent** investigation.
2262
+ It requires a 1–500 character reason and records a minimized access receipt,
2263
+ not the private message text, in the audit. It returns the specified existing
2264
+ Zero/Ciel output plus preceding messages in that bot's own two-person
2265
+ conversation and exact topic/subchannel, oldest first within each page.
2266
+ Default 20, maximum 40 messages per page; continue manually with the cursor.
2267
+ The complete scope is bounded to 100 prior rows, 24 hours, and 10,000 message
2268
+ IDs before the anchor. `boundedLimitReached` means stop and report that bound,
2269
+ not that all channel history was reviewed. Deleted messages and hidden
2270
+ attachments remain hidden. Group-channel browsing, `--all`, and `--days` are
2271
+ not supported. Never start an entire daily run just to investigate one reply.
2272
+
1859
2273
  ### API runtime-log review (same phase, every full daily review)
1860
2274
 
1861
2275
  The bot-conduct review also owns a bounded production API log review. Bot
@@ -1864,6 +2278,24 @@ the HTTP layer while stdout records a degraded fallback/retry loop or stderr
1864
2278
  records a side-effect failure. Reviewing only `bot-output` can therefore miss
1865
2279
  the other half of what happened.
1866
2280
 
2281
+ For passive RSS/recycle investigations, use the read-only command independently
2282
+ of a daily run or production-log review:
2283
+
2284
+ ```bash
2285
+ lumine admin runtime evidence primary --days 7 --output ./runtime-evidence.json --json
2286
+ # Use target explicitly only when investigating a configured second host.
2287
+ ```
2288
+
2289
+ It performs no restart, log clear, review lease acquisition, or fallback to a
2290
+ different host. `collecting`, `incomplete`, `stale`, and `unavailable` describe
2291
+ evidence coverage, not a verdict that the system is healthy. A 404 means the
2292
+ API route is not deployed; an old primary generation can also lack collector
2293
+ samples after workers update. Record that activation gap and arrange an
2294
+ authorized release—do not silently close the investigation or force a recycle.
2295
+ An observed topology recovery alone does not prove interrupted user work
2296
+ survived. Keep the evidence cutoff, gaps and actual outcomes in the relevant
2297
+ todo so the next run can continue.
2298
+
1867
2299
  The current API-side files are:
1868
2300
 
1869
2301
  - `/home/ec2-user/server/logs/twinkle-api.err.log`
@@ -1876,6 +2308,27 @@ in scope so a later API-side worker is not silently omitted. Use the delegated,
1876
2308
  run-independent workflow; it holds one server lease across the review and
1877
2309
  writes private, digest-verified local artifacts:
1878
2310
 
2311
+ For the deploy-time two-API topology, `runtime-logs start primary` and
2312
+ `runtime-logs start target` explicitly select the host. Omitted host means
2313
+ primary; pre-migration NULL owners also mean primary. Use a separate private
2314
+ output/session directory for each completed review. Review-ID/session operations
2315
+ route back to the recorded owner; never treat a peer's files as that review's
2316
+ bytes. An unresolved start key cannot be replayed against a different host.
2317
+ The additive host-owner migration and compatible API must be live before this
2318
+ CLI capability is published.
2319
+
2320
+ Review every participating host, including primary private-helper logs. A
2321
+ primary review does not cover the target. Finish the exclusive review before
2322
+ that host is held; a held/unavailable owner returns an explicit retryable failure,
2323
+ not another host's snapshots or an independent log service. Do not abandon its
2324
+ lease merely to bypass a deployment guard. After a planned hold, final shutdown
2325
+ deltas are reviewed via management SSH outside any active lease, recorded, and
2326
+ API stderr is cleared only with the existing guarded `npm run logs:clear-errors`
2327
+ plus post-clear re-read. This is the deployment runbook's final boundary, not
2328
+ permission to bypass an active Lumine lease. A stopped target whose final logs
2329
+ were reviewed does not need to be started for daily management; starting EC2
2330
+ requires separate authority. See `twinkle-api/DEPLOY_TIME_HANDOFF.md`.
2331
+
1879
2332
  ```bash
1880
2333
  lumine admin runtime-logs start --output-dir ./runtime-log-review --json
1881
2334
  # Read every file under data.artifacts.latestSnapshot.snapshotPath.
@@ -2106,8 +2559,8 @@ dump raw sections at him.
2106
2559
  ### Application AI calendar-month cost (standing duty, every full daily review)
2107
2560
 
2108
2561
  Run `lumine admin ai-costs monthly --json` during every full daily management
2109
- review. This read-only command requires the active delegated run and returns one
2110
- server-owned calendar summary from the canonical deduplicated application AI-
2562
+ review. This read-only command does not require or attach to a delegated run.
2563
+ It returns one server-owned calendar summary from the canonical deduplicated application AI-
2111
2564
  cost ledger. It deliberately takes no `--days`: all boundaries are UTC calendar
2112
2565
  months, so the result is directly comparable from one run to the next.
2113
2566
 
@@ -2856,11 +3309,38 @@ cannot choose or override that identity. The authorization lasts ten minutes,
2856
3309
  is bound to that exact comment, permits only reading that target and editing
2857
3310
  it, and never runs daily duties, changes the Bangkok calendar assignment, or
2858
3311
  contributes to a daily-run mutation count. A correction cannot target a human
2859
- comment, notification record, deleted comment, or Build thread. Build comments
2860
- still require a fresh version-bound correction reply after genuinely reviewing
2861
- the published app. Starting a newer correction supersedes an older active one.
3312
+ comment, notification record, or deleted comment. A Build comment must belong
3313
+ to a public, published canonical owner Build; editing it requires a fresh review
3314
+ of the exact published version and private review context. Starting a newer
3315
+ correction supersedes an older active one.
2862
3316
  Finish it explicitly after the canonical edit is confirmed.
2863
3317
 
3318
+ For a Build, inspect the current app and its full discussion first. Managed
3319
+ runtime review does not require a daily run and does not start one:
3320
+
3321
+ ```bash
3322
+ lumine admin builds review build:884 --output-dir ./build-review --json
3323
+ lumine admin correction start 456 --json
3324
+ lumine admin comment edit 456 --file corrected.md \
3325
+ --review-receipt ./build-review/<returned-review-directory>/review.json \
3326
+ --review-context context.json --json
3327
+ lumine admin correction complete <sessionId> --json
3328
+ ```
3329
+
3330
+ Use the exact receipt path returned by `builds review`, or pass manual
3331
+ `--reviewed-version <artifactId> --reviewed-via runtime|code` evidence instead.
3332
+ The private context file contains only `{"understanding":"What you actually reviewed"}`.
3333
+ The API locks the Build and comment, verifies the current version and ownership,
3334
+ and commits the text, mention updates, and a new immutable review record together.
3335
+ Only the edited comment's context link moves; older bot replies retain their
3336
+ historical review context. Changed/deleted comments, changed versions, and
3337
+ private/noncanonical Builds fail without a partial edit. A fresh review can be
3338
+ stored even if the public text is unchanged. The CLI requires the exact edited
3339
+ text plus `edit.buildReviewContextStored: true`, the reviewed version, and a
3340
+ canonical review record ID before claiming success. Older APIs that still block
3341
+ Build edits must be deployed first; do not silently substitute a duplicate reply
3342
+ when Mikey requested an edit.
3343
+
2864
3344
  **Editing the bot's own comments.** `comment edit <commentId> --file
2865
3345
  <comment.md>` replaces the text of a comment the acting bot itself authored —
2866
3346
  for correcting a factual error, an unfulfillable claim, or outdated guidance
@@ -2872,7 +3352,8 @@ composed-comment rules (plain UTF-8, 10,000-character limit, truth about what
2872
3352
  the session actually did) and publishes through the website's canonical
2873
3353
  comment-edit pipeline — mentions are reprocessed (a newly added `@mikey`
2874
3354
  notifies him), and Earn-candidate projections resync. Submitting identical
2875
- text returns `already_done`. It requires either the exact active correction
3355
+ text returns `already_done` for non-Build comments; a Build edit can still save
3356
+ a fresh review without changing its text. It requires either the exact active correction
2876
3357
  session above or the `comment:post` scope of a comment-mode `post` run, and is
2877
3358
  audited as `comment.edit` with the previous content in `beforeState` and
2878
3359
  `data.edit.previousContent`. Edit sparingly:
@@ -3118,9 +3599,12 @@ sponsor pays from their own battery. Mentions elsewhere in a Build, replies to
3118
3599
  unlinked or legacy bot comments, replies to humans, and the other bot remain
3119
3600
  ineligible. If the published version has changed, the responder is told the
3120
3601
  stored understanding belongs to the reviewed older version and must say it has
3121
- not checked behavior that could have changed. The generic `comment edit`
3122
- shortcut is also disabled there; review the current version and post a
3123
- version-bound correction reply instead.
3602
+ not checked behavior that could have changed. Editing the acting bot's own
3603
+ Build comment is supported with the same fresh reviewed-version/method and
3604
+ private-context flags, including managed review receipts. It updates the
3605
+ existing comment, not a duplicate reply. See the narrow correction workflow
3606
+ above; a version-bound follow-up remains appropriate when the conversation
3607
+ calls for an additional reply instead of an edit.
3124
3608
 
3125
3609
  **Offer a Lumine prompt when the moment invites it (Mikey's direction,
3126
3610
  2026-08-10).** Zero and Ciel may include one concrete, copy-pasteable Lumine
@@ -3301,6 +3785,16 @@ Deploy and verify the API's `/cli/admin/subjects/featured/rotation` route before
3301
3785
  publishing a CLI release that exposes `featured rotate`; an older API rejects
3302
3786
  the command without changing Featured state.
3303
3787
 
3788
+ The approved-plan and Featured-comment workflows require the new
3789
+ `/subjects/featured/plan`, `/plan/apply` (under that same Featured base), and
3790
+ `/subjects/featured/reviews` routes. Deploy the API before releasing the CLI;
3791
+ there is no fallback to unbound writes or a full daily run on an older API.
3792
+ Existing runs remain readable/completable with their original scopes, but are
3793
+ not silently granted `featured:comments`; start a fresh scoped/full run as
3794
+ appropriate after finishing the existing authorized work. No new migration is
3795
+ required for these workflows: server receipts reuse the existing audit table
3796
+ and full-board mutation history.
3797
+
3304
3798
  For scoped runs and Featured history, also apply
3305
3799
  `add-lumine-admin-run-scope.sql` and `add-featured-subject-history.sql` before
3306
3800
  the API release. After every serving API worker is verified on that release