@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.
@@ -18,10 +18,16 @@ canonical structured data.
18
18
  one allowlisted run scope and one public actor. `--scope full` is the full
19
19
  daily-management review. `--scope featured` is only an authorization
20
20
  envelope for a specifically requested Featured slice; it does not authorize
21
- or imply the newspaper, queues, conduct review, logs, costs, sponsors,
21
+ or imply the newspaper, queues, conduct review, logs, costs, AI Energy
22
+ budget health, sponsors,
22
23
  carry-over work, or final full-run report. Every run-scoped CLI command loads
23
24
  the canonical active run and sends its ID; the API rejects a missing,
24
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.
25
31
  - The public content actor is Zero or Ciel. Mikey's operator ID is retained in
26
32
  private audit rows and is not embedded in public comment metadata.
27
33
  - Delegated HTTP work never authenticates as the bot, opens a bot socket, changes
@@ -43,6 +49,13 @@ canonical structured data.
43
49
  described below. The human's normal AI Energy and sponsor path applies;
44
50
  Lumine does not need to remain running.
45
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
+
46
59
  The Zero/Ciel shift is assigned by **Asia/Bangkok calendar day, not by run**.
47
60
  The schedule is anchored with 2026-08-31 assigned to Zero and alternates by
48
61
  elapsed Bangkok dates from there. Every automatic primary, supplemental,
@@ -63,8 +76,10 @@ Comment mode is stored only on the current run:
63
76
  - `draft`: server-generated drafts, no public comment.
64
77
  - `post`: drafts plus idempotent publication through the ordinary comment path.
65
78
 
66
- A Featured-only run always uses comment mode `off` and grants only Featured
67
- 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
68
83
  without a sponsor-integrity scan. Completing it does not advance any full-run
69
84
  content/cost/conduct window, queue-coverage record, last-completed identity, or
70
85
  carry-over surfacing telemetry. Start one only when Mikey requested that slice; never turn a small
@@ -72,6 +87,14 @@ request into a full review merely because the technical command needs a run.
72
87
  The API enforces these scopes, and the CLI also rejects out-of-scope operations
73
88
  before calling endpoints outside the Lumine Admin router (notably Build review).
74
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
+
75
98
  ### Private AI-bucket maintenance
76
99
 
77
100
  AI identity buckets are private operator bookkeeping, not a Zero/Ciel public
@@ -237,7 +260,11 @@ in another language; reply naturally in concise English.
237
260
 
238
261
  **Twinkle is not Reddit.** Do not rank a run's attention by popularity,
239
262
  recommendation count, or polish. Most users here are young children, and the
240
- 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.
241
268
 
242
269
  - **Look first at new, quiet, and overlooked users.** A child's first post, or a
243
270
  post from someone who rarely gets replies, is worth more of a run's attention
@@ -249,10 +276,10 @@ posts that most need Zero or Ciel are the ones nobody else answered.
249
276
  - **Zero engagement is a reason to act, not to skip.** A post sitting at no
250
277
  recommendations and no comments is the strongest signal in the queue that
251
278
  someone should notice it.
252
- - **Thought-provoking posts deserve substance, not applause — and an unnoticed
253
- one is the highest priority of all.** When a child asks a real question or
254
- makes a real argument and the thread is empty, that is the clearest case for
255
- 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,
256
283
  add a perspective or a counter-consideration, and leave the author somewhere
257
284
  to go next. A good question that nobody answered teaches a child that thinking
258
285
  hard is not worth it; that is the outcome these runs exist to prevent. This
@@ -304,21 +331,45 @@ posts that most need Zero or Ciel are the ones nobody else answered.
304
331
  - **Sincere requests for personal help are Featured material.** Posts asking
305
332
  the community for advice about school, friendships, loneliness, or other
306
333
  ordinary real-life problems embody Twinkle's purpose; being personal is never
307
- a reason to suppress or remove them. Receiving meaningful support does not
308
- make one stale or create a duty to rotate it out; keep judging what the live
309
- 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.
310
338
  - **Speculative privacy is never an editorial signal.** Do not lower, remove,
311
339
  unfeature, or escalate content because it might identify someone, mentions a
312
340
  school, city, class, or ordinary location, or invites everyday community
313
341
  context. Those possibilities carry zero weight in Featured decisions. An
314
342
  actual sensitive disclosure or an author's explicit removal request follows
315
343
  the separate concrete-safety path; it does not make the post low-quality.
316
- - **Featured values participation, continuity, and child voice—not adult
317
- polish.** Accessible questions that many children can answer and ongoing
318
- personal series such as records, journals, or recurring updates are strong
319
- Featured forms. Age, brevity, simplicity, prior recognition, or a modest
320
- description is not a removal reason. Review the whole subject and its role in
321
- 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.
322
373
  - **A "new" Featured addition has two non-negotiable eligibility gates.** When
323
374
  Mikey asks for new Featured subjects, additions, or replacements, a candidate
324
375
  must both (1) have been posted recently and (2) have never appeared on the
@@ -335,7 +386,7 @@ posts that most need Zero or Ciel are the ones nobody else answered.
335
386
  - **The live Featured board is Mikey's word.** Do not remove or reorder a
336
387
  currently Featured subject without first showing Mikey the planned removals
337
388
  and replacements and getting his go-ahead. Additions have standing approval
338
- when a fresh `featured list` is below its canonical maximum: proactively
389
+ when a fresh `featured list` is below its delegated-admin maximum: proactively
339
390
  feature genuinely reviewed, editorially strong new subjects without asking
340
391
  case by case. This is judgment, not a quota — never add filler merely because
341
392
  capacity exists. If a subject that was Featured or pinned during an earlier
@@ -350,6 +401,89 @@ Sensitive disclosures, active disputes, and anything needing crisis or medical
350
401
  judgment remain out of scope for a bot comment no matter how neglected the post
351
402
  is. Those go to Mikey.
352
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
+
353
487
  ## Escalation to Mikey
354
488
 
355
489
  A full daily management run is not finished when the mutations are done. Curation surfaces things only
@@ -619,7 +753,7 @@ type DailyRun = {
619
753
  publicActorUserId: number;
620
754
  identityMode: "auto" | "zero" | "ciel";
621
755
  commentMode: "off" | "draft" | "post";
622
- runScope: "full" | "featured";
756
+ runScope: "full" | "featured" | "newspaper";
623
757
  sessionKind: "delegated-admin";
624
758
  scopes: string[];
625
759
  status: "active" | "completed" | "failed" | "expired";
@@ -721,6 +855,7 @@ identity, or advances rotation.
721
855
  ```bash
722
856
  lumine admin daily-run start --identity auto --comment-mode off --json
723
857
  lumine admin daily-run start --scope featured --identity auto --json
858
+ lumine admin daily-run start --scope newspaper --identity auto --json
724
859
  lumine admin daily-run start --identity ciel --comment-mode draft \
725
860
  --run-key daily:2026-08-06:review --json
726
861
  lumine admin daily-run status --json
@@ -729,6 +864,7 @@ lumine admin daily-run escalation add --target subject:123 \
729
864
  lumine admin daily-run escalation add --target chatMessage:3768159 \
730
865
  --note "Concrete safety issue in a bot-authored chat message" --json
731
866
  lumine admin daily-run report --json
867
+ lumine admin daily-run report --run 123 --json
732
868
  lumine admin daily-run complete --json
733
869
  lumine admin daily-run fail --reason "operator stopped" --json
734
870
  lumine admin escalation list --status all --json
@@ -798,21 +934,37 @@ During a full review, record only qualifying escalations as they are confirmed.
798
934
  then composes the active run's canonical audit events, successful mutations,
799
935
  completed queue scans, recorded escalations, and the most useful brief deltas
800
936
  into one result. Generate it before `complete`, because run-scoped reads require
801
- the current active run. Queue coverage is written automatically only after an
937
+ the current active run. After completion,
938
+ `daily-run report --run <completed-run-id>` is the run-independent recovery
939
+ path. It reconstructs immutable run/audit/coverage/escalation evidence and the
940
+ closed-day calendar cost view at the run's completion boundary. It labels that
941
+ basis `historical_reconstruction`: later canonical ledger corrections to those
942
+ closed days are reflected, while the boundary day's then-open cost bucket is
943
+ omitted. The former live brief, carry-over-todo snapshot, and pending sponsor-
944
+ application count are returned as unavailable rather than being synthesized
945
+ from today's state; sponsor scan/case status is explicitly labeled as current
946
+ canonical state for that run's scan. Queue coverage is
947
+ written automatically only after an
802
948
  `--all` traversal reaches canonical exhaustion; an interrupted scan remains in
803
949
  its local checkpoint and cannot be misreported as complete.
804
950
 
805
951
  **Every agent-authored final full-management report includes a `Featured rotation`
806
- section.** Base it on a fresh `featured list`. When capacity exists, make and
807
- report strong additions during the run under the standing approval above; do
808
- not defer them as proposals. Then name each current Subject proposed for
809
- removal with its canonical URL and a concrete editorial reason, followed by
810
- any replacement that would require that removal. Every proposed or completed
811
- addition described as new must include its posting date and canonical evidence
812
- that it has never been Featured; omit it when either gate is unverified. Never
813
- omit the section; when no removal or reorder is honestly warranted, say `None`
814
- and explain why. Removing or reordering pins remains a proposal until Mikey
815
- gives his go-ahead.
952
+ section.** Base it on the dated starting board, a fresh `featured list`, and
953
+ canonical history. Report the target of replacing **all previous-day pins**,
954
+ the exact proposed/completed outgoing-to-incoming mapping, and each retained
955
+ pin with its reason. Rank new candidates by likely genuine member engagement,
956
+ not thoughtfulness. Include the all-Featured-comment coverage and encouragement
957
+ counts described above. When genuine capacity exists, make and report strong
958
+ additions under the standing approval above; do not defer those as proposals.
959
+ Every proposed or completed new addition must include its posting date and
960
+ canonical never-Featured evidence; omit it when either gate is unverified.
961
+ If a complete refresh is constrained, state the shortfall, including inadequate
962
+ eligible inventory, inaccessible context, specific keep instructions, or pending
963
+ approval. Do not report `None` merely because yesterday's posts are still good
964
+ or have received support. Removing or reordering pins remains a proposal until
965
+ Mikey gives his go-ahead; a pending proposal is not a completed refresh. After
966
+ approval, execute the entire approved plan and verify it without asking for
967
+ each swap again. Never omit this section from a full-run report.
816
968
 
817
969
  Creating an escalation belongs to the active run; acknowledging, annotating,
818
970
  resolving, or reopening it does not. Use the run-independent `escalation`
@@ -876,7 +1028,8 @@ Every successful full `daily-run start` response automatically includes all
876
1028
  unfinished items under `data.carryoverTodos`. The same run ID increments an
877
1029
  item's surfacing telemetry at most once, even when start is retried. This is the
878
1030
  canonical handoff: read it before discretionary new work, resume what can safely
879
- progress after the run's mandatory newspaper/brief/conduct duties, and record a
1031
+ progress after the run's mandatory newspaper/brief/conduct/log-review/cost/
1032
+ energy-budget duties, and record a
880
1033
  concrete progress note before the run closes. The daily-run report includes the
881
1034
  still-unfinished set again. Completing a daily run never silently completes its
882
1035
  todos. A CLI carrying this contract rejects a start response that does not echo
@@ -942,6 +1095,8 @@ lumine admin recommendations list --include-legacy --all --json
942
1095
  lumine admin recommendations list --unviewed --json
943
1096
  lumine admin subjects candidates --after 2026-08-01T00:00:00Z \
944
1097
  --all --checkpoint subjects.json --json
1098
+ lumine admin subjects candidates --since-run --all --json
1099
+ lumine admin subjects candidates --include-legacy --all --json
945
1100
  lumine admin subjects candidates --effort unassigned --json
946
1101
  lumine admin subjects candidates --unviewed --json
947
1102
  lumine admin builds candidates --all --limit 50 --json
@@ -1052,6 +1207,13 @@ only page/scanned/candidate counts and the private checkpoint path. A long
1052
1207
  traversal therefore no longer looks stalled, while piping stdout to `jq` or a
1053
1208
  file remains safe.
1054
1209
 
1210
+ `Ctrl+C` and `SIGTERM` abort the in-flight page request, leave the last
1211
+ server-confirmed page fsynced in the private checkpoint/spool, and release the
1212
+ adjacent process lock. The cancellation error names the checkpoint. Continue
1213
+ only by rerunning the exact same command with `--resume`; the next invocation
1214
+ verifies the request fingerprint and confirmed spool digest before requesting
1215
+ another page. An interrupted request is never counted as queue coverage.
1216
+
1055
1217
  Recommendations default to `--since-run`: the server uses the previous
1056
1218
  completed run's start time (or the same bounded seven-day fallback used by the
1057
1219
  brief on a first run). That deliberate start-to-start overlap gives the queue
@@ -1062,6 +1224,13 @@ All-history traversal is deliberately available only through
1062
1224
  boundary for bounded modes, so deploying a new CLI against an older API cannot
1063
1225
  silently fall back to a million-row historical scan.
1064
1226
 
1227
+ Subject candidates follow the same window contract. They default to the
1228
+ previous completed full run's start (with the seven-day first-run fallback),
1229
+ accept an explicit inclusive `--after`, and require `--include-legacy` for a
1230
+ lifetime traversal. `--since-run`, `--after`, and `--include-legacy` are
1231
+ mutually exclusive. The CLI also requires the API to echo the bounded Subject
1232
+ window before accepting a page.
1233
+
1065
1234
  `builds candidates` is a management-agent discovery view over the canonical
1066
1235
  public Build browser, ordered by the current published release. It is
1067
1236
  available through the `admin` namespace only while a delegated run is active;
@@ -1118,12 +1287,19 @@ website's canonical reward-level projection shape; deployment should verify
1118
1287
  (or `(contentId, ...)`) as the canonical route already requires. The joins/`NOT EXISTS` checks are necessary
1119
1288
  to preserve the normal recommendation and skip rules, but they run only for
1120
1289
  IDs in that bounded window. Subject-comment traversal uses
1121
- `idx_comments_isDeleted_subject_id`; standalone-post comments use the existing
1290
+ `idx_comments_isDeleted_subject_id`; standalone-post and Build comments use the existing
1122
1291
  `idx_content_comments_root_deleted` index (whose InnoDB entries also carry the
1123
1292
  primary ID). Recommendation identity uses
1124
1293
  `uniq_content_recommendations_active_identity`; `earn_comment_candidates` is
1125
1294
  driven by its primary key. No offset scan or new broad table scan was added.
1126
1295
 
1296
+ Featured comment review adds at most 100 per-Subject `MAX(id)` probes using
1297
+ `idx_comments_isDeleted_subject_id`, then reuses the bounded 50-comment page
1298
+ path. Receipt lookups use the audit primary key; review summaries use the
1299
+ existing `idx_laae_run_id (runId, id)` range and project only coverage/action
1300
+ outcomes, not downloaded comment bodies. Approved plans use the shared board
1301
+ lock and the history primary key for `MAX(id)`. No new schema is needed.
1302
+
1127
1303
  Deployment can verify the required existing index definitions with:
1128
1304
 
1129
1305
  ```sql
@@ -1170,8 +1346,18 @@ lumine admin subject comments 123 --cursor '<cursor>' --json
1170
1346
  lumine admin comments get 456 --json
1171
1347
  lumine admin post get https://www.twin-kle.com/ai-stories/88 --json
1172
1348
  lumine admin post comments dailyReflection:99 --cursor '<cursor>' --json
1349
+ lumine admin post comments build:884 --all --output build-comments.json --json
1173
1350
  ```
1174
1351
 
1352
+ Build comment inspection accepts `build:<id>`, a public `/app/<id>` URL, or
1353
+ `--type build`. It reads all root-thread comments and replies through a
1354
+ snapshot-bound cursor, with full text and `parentCommentId`/`replyToCommentId`
1355
+ relationships.
1356
+ Only public, published, canonical owner Builds qualify; contribution branches
1357
+ and private/unpublished Builds are rejected. This is thread inspection, not
1358
+ evidence of having reviewed the published app. Build-comment publication still
1359
+ requires its separate version-bound review evidence.
1360
+
1175
1361
  Schemas:
1176
1362
 
1177
1363
  ```ts
@@ -1271,6 +1457,9 @@ type FeaturedList = Success<{
1271
1457
  subjects: Subject[];
1272
1458
  count: number;
1273
1459
  maximum: 20;
1460
+ maximumScope: "delegated_admin";
1461
+ delegatedMaximum: 20;
1462
+ websiteMaximum: 100;
1274
1463
  }>;
1275
1464
 
1276
1465
  type FeaturedHistory = Success<{
@@ -1350,7 +1539,7 @@ effective level). Every response is reloaded from the writer.
1350
1539
 
1351
1540
  Featured reorder is a complete-set replacement: it rejects duplicates,
1352
1541
  unknown/deleted IDs, missing current members, non-subject rows, and more than
1353
- 20 subjects. Permanent pins and editorial ordering policy are deliberately not
1542
+ 100 subjects. Permanent pins and editorial ordering policy are deliberately not
1354
1543
  hardcoded.
1355
1544
 
1356
1545
  `featured history` is the compact canonical evidence path. It returns only
@@ -1394,9 +1583,12 @@ The response includes the canonical final board and the confirmed rotation
1394
1583
  IDs, so callers never synthesize Featured state locally.
1395
1584
 
1396
1585
  The two lists must have the same nonzero length, so rotation never changes the
1397
- board's count. That also lets an approved swap proceed when the website has
1398
- left a pre-existing board above the delegated maximum without growing it;
1399
- repair the inherited overflow separately with an approved `subject unfeature`.
1586
+ board's count. Up to 100 replacements are accepted, including an existing board
1587
+ above the delegated growth limit of 20. That is not an overflow to repair.
1588
+ The server also enforces live, recent, provably never-Featured additions. Pass
1589
+ `--posted-after` explicitly; for compatibility the legacy rotation command
1590
+ defaults to seven days before the current Bangkok day's midnight. The exact
1591
+ approved-plan workflow below always requires an explicit cutoff.
1400
1592
 
1401
1593
  This mutation deliberately does not choose candidates or override the
1402
1594
  editorial gates above. Before invoking it, the management agent must have
@@ -1404,11 +1596,120 @@ freshly reviewed the board, shown Mikey the removals and replacements, received
1404
1596
  his go-ahead, and verified that every proposed new addition is recent and has
1405
1597
  never previously been Featured from canonical evidence.
1406
1598
 
1599
+ ### Exact approved refresh and resumable comment encouragement
1600
+
1601
+ For the daily old-to-new proposal, prepare a canonical plan without changing pins:
1602
+
1603
+ ```bash
1604
+ lumine admin featured plan --remove-subject-ids 30,20 \
1605
+ --add-subject-ids 50,40 --subject-ids 40,50,10 \
1606
+ --posted-after 2026-09-01T00:00:00+07:00 --output featured-plan.json --json
1607
+ ```
1608
+
1609
+ Removal and addition lists are equal-size pairs. Optional `--subject-ids` is
1610
+ the **entire final ordered board**, including retained pins; without it,
1611
+ additions lead in supplied order and retained pins keep their relative order.
1612
+ The receipt contains titles, IDs, URLs, replacement pairs, final order, posting
1613
+ cutoff, run/actor identity, expected board and history revision, and `planHash`.
1614
+ Add qualitative reasons, show Mikey the exact mapping/order, and wait for his
1615
+ go-ahead. A generated hash is not itself human approval. After approval:
1616
+
1617
+ ```bash
1618
+ lumine admin featured apply --file featured-plan.json \
1619
+ --approve <exact-plan-hash> --json
1620
+ ```
1621
+
1622
+ The API loads the immutable plan from its same-run/operator/actor audit receipt,
1623
+ checks the supplied hash, and applies all swaps and ordering in one transaction.
1624
+ It rejects intervening reorders, swaps, even a changed-then-restored board, and
1625
+ newly ineligible candidates. No substitute candidates or follow-up reorder are
1626
+ inferred. The CLI then reads the live board and verifies exact membership/order.
1627
+ Retry the identical apply command after uncertain transport failure; it reuses
1628
+ the same idempotency key. If the final read fails or finds an intervening change,
1629
+ the error retains the canonical apply receipt and never restores old state.
1630
+ Expired/different runs require a fresh plan and renewed approval.
1631
+
1632
+ Use the following workflow for full daily comment review, or only when Mikey's
1633
+ Featured slice includes comment encouragement:
1634
+
1635
+ ```bash
1636
+ lumine admin featured comments scan --checkpoint featured-read.json --json
1637
+ # On interruption: repeat with --resume, in the same active run.
1638
+ # Read ALL pageFiles, including full root context and nested replies.
1639
+ lumine admin featured comments acknowledge \
1640
+ --checkpoint featured-read.json --reviewed --json
1641
+ ```
1642
+
1643
+ The scan snapshots every current Featured Subject (up to 100) and its maximum
1644
+ comment ID, includes already-viewed and older comments, and downloads full-text
1645
+ pages of 50 through server-owned receipt chains. It rejects filtered scans;
1646
+ there is no popularity, length, language, or keyword selection heuristic.
1647
+ Each private mode-0600 page file has a checkpointed hash; resume verifies the
1648
+ complete chain and uses stable request keys after lost responses. Concurrent
1649
+ use of a checkpoint is locked. Deleted/unavailable Subjects and locked secrets
1650
+ remain explicitly incomplete; an empty thread still requires a terminal page.
1651
+ The scanner never automatically reveals secrets. If reveal is authorized, use
1652
+ the ordinary explicit reveal command and resume. New comments above the saved
1653
+ boundary belong to a fresh scan, not a silently expanded claim of coverage.
1654
+
1655
+ `acknowledge --reviewed` is the agent's explicit confirmation that it read the
1656
+ downloaded terminal chains. The API validates those chains, records covered and
1657
+ missing Subject IDs and comment counts, and distinguishes complete from partial
1658
+ coverage. A download alone never counts as a read or grants recommendations.
1659
+ After a resumed scan fills a gap, read those pages and acknowledge again.
1660
+
1661
+ Compose a decisions JSON file from the genuinely reviewed comments, using the
1662
+ returned review ID, coverage receipt ID, and each selected comment's page ID:
1663
+
1664
+ ```json
1665
+ {
1666
+ "reviewId": 100,
1667
+ "coverageId": 1050,
1668
+ "selections": [
1669
+ { "commentId": 120, "pageId": 1001 },
1670
+ { "commentId": 119, "pageId": 1001, "anyoneCanReward": true },
1671
+ { "commentId": 118, "pageId": 1001, "anyoneCanReward": true, "rewardTwinkles": 3 }
1672
+ ]
1673
+ }
1674
+ ```
1675
+
1676
+ The agent chooses comments by context under the generous encouragement policy;
1677
+ the tool never auto-selects them. Reward permission defaults off; the only
1678
+ direct reward option is an explicitly selected 3-Twinkle pairing. Existing
1679
+ permissions are not revoked by a basic recommendation. Then apply and report:
1680
+
1681
+ ```bash
1682
+ lumine admin featured comments recommend --file featured-decisions.json \
1683
+ --checkpoint featured-recommend.json --json
1684
+ # Retry exactly this file/checkpoint with --resume after interruption.
1685
+ lumine admin featured comments report --checkpoint featured-read.json --json
1686
+ ```
1687
+
1688
+ Use separate scan and recommendation checkpoints. Selection files are capped at
1689
+ 20,000 unique comments/2 MiB; split larger work into explicit batches. Each
1690
+ target must belong to the reviewed page and an acknowledged Subject chain in
1691
+ this same run. The API re-reads it, rejects changed/hidden/deleted comments,
1692
+ system notifications and Zero/Ciel's own comments, and uses the normal canonical
1693
+ recommendation/reward/deduplication path. A blocked Subject does not prevent
1694
+ encouragement on acknowledged Subjects. Batches stop at a failed decision,
1695
+ retain confirmed receipts, and resume without replaying completed decisions.
1696
+ These recommendations are independent per-comment mutations, not an atomic
1697
+ batch; report partial completion honestly.
1698
+
1699
+ The review report and full/historical daily reports' `featuredReviews` expose
1700
+ acknowledged coverage, confirmed new/basic recommendations, already-done
1701
+ actions, selective reward-permission grants, and created direct rewards. The
1702
+ counts describe canonical outcomes, not attempted commands or downloaded rows.
1703
+ Read comments that are already recommended too; use the page evidence for
1704
+ already-recommended and skipped-category totals rather than treating the
1705
+ report's selected `alreadyDone` actions as all previously recommended comments.
1706
+
1407
1707
  ## Recommendation, Karma approval, and Twinkle rewards
1408
1708
 
1409
1709
  ```bash
1410
1710
  lumine admin post recommend 123 --json
1411
1711
  lumine admin post recommend https://www.twin-kle.com/ai-stories/88 --json
1712
+ lumine admin post recommend comment:456 --json
1412
1713
  lumine admin post recommend comment:456 --anyone-can-reward \
1413
1714
  --reward-twinkles 3 --idempotency-key review-456-v1 --json
1414
1715
  lumine admin post reward comment:456 --twinkles 3 --json
@@ -1418,6 +1719,15 @@ Numeric targets default to `subject`. Use `subject:<id>`, `comment:<id>`,
1418
1719
  `aiStory:<id>`, `dailyReflection:<id>`, a canonical URL, or the corresponding
1419
1720
  `--type`.
1420
1721
 
1722
+ For daily Featured-comment encouragement, prefer the review-bound
1723
+ `featured comments` workflow above so coverage and outcomes remain linked.
1724
+ The generic bare comment recommendation has the same basic default, but is
1725
+ not available in a Featured-only run. `--anyone-can-reward` and
1726
+ `--reward-twinkles` are separate, selective judgments, not required flags for an
1727
+ ordinary worthwhile comment.
1728
+ Follow **Daily Featured comments and refresh** for full-thread coverage and
1729
+ the intentionally generous basic-recommendation threshold.
1730
+
1421
1731
  ```ts
1422
1732
  type PriorRecommendationApproval = {
1423
1733
  recommendationId: number;
@@ -1524,7 +1834,7 @@ If recommendation succeeds but reward fails, the command exits nonzero with
1524
1834
 
1525
1835
  ```bash
1526
1836
  lumine admin post skip dailyReflection:99 --json
1527
- lumine admin post skip comment:456 --reason "one-line answer, nothing to add" --json
1837
+ lumine admin post skip comment:456 --reason "duplicate coin-begging spam" --json
1528
1838
  lumine admin post skip-batch --target-file skip-targets.json \
1529
1839
  --checkpoint skip-progress.json --json
1530
1840
  lumine admin post skip-batch --target-file skip-targets.json \
@@ -1843,27 +2153,97 @@ The current API-side files are:
1843
2153
  - `/home/ec2-user/server/logs/twinkle-image-optimizer.out.log`
1844
2154
 
1845
2155
  Treat every current `/home/ec2-user/server/logs/*.err.log` and `*.out.log` as
1846
- in scope so a later API-side worker is not silently omitted. Use the production
1847
- SSH endpoint and key from the repository agent guide; all inspection commands
1848
- are read-only.
1849
-
1850
- 1. Immediately after `daily-run start`, record each matching file's inode and
1851
- byte size, inspect its current tail to establish service health, and read
1852
- every non-empty error log before accepting that position as the run
1853
- baseline. The prior run is supposed to leave the live API error log empty,
1854
- so unexplained pre-existing stderr is evidence, not a reason to skip ahead.
1855
- 2. Run and fully paginate `bot-output`, reading every row as required above.
1856
- In this same phase, read every byte appended to both error and normal-output
1857
- files since the recorded baseline. Refresh the offsets after inspection.
1858
- Do not rely on a fixed-line `tail`: a busy or multiline failure can begin
1859
- before that arbitrary window.
1860
- 3. Immediately before `daily-run report` and `daily-run complete`, inspect the
1861
- delta again. This catches failures caused by the curation actions performed
1862
- after the first conduct/log review. If a file's inode changed or its size
1863
- shrank, do not assume the missing range was clean: inspect the replacement
1864
- from byte zero, check the relevant `twinkle-api.service` or
1865
- `twinkle-image-optimizer.service` journal interval, and report the lost
1866
- boundary.
2156
+ in scope so a later API-side worker is not silently omitted. Use the delegated,
2157
+ run-independent workflow; it holds one server lease across the review and
2158
+ writes private, digest-verified local artifacts:
2159
+
2160
+ ```bash
2161
+ lumine admin runtime-logs start --output-dir ./runtime-log-review --json
2162
+ # Read every file under data.artifacts.latestSnapshot.snapshotPath.
2163
+
2164
+ # After bot-output and again after later management actions:
2165
+ lumine admin runtime-logs read \
2166
+ --review-session <data.artifacts.reviewSessionPath> --json
2167
+ # Read every newly returned snapshot artifact.
2168
+
2169
+ # Immediately before the daily report/completion:
2170
+ lumine admin runtime-logs finish \
2171
+ --review-session <data.artifacts.reviewSessionPath> --reviewed --json
2172
+ ```
2173
+
2174
+ `start` captures every byte of each non-empty error log and a bounded 64 KiB
2175
+ health tail of each normal-output log. `read` captures every error byte
2176
+ appended after the last immutable server boundary and at most an 8 MiB tail
2177
+ of each normal-output log's growth; a segment whose start was moved forward by
2178
+ that cap carries `tailOnly: true` and `omittedBytes` in the manifest, so treat
2179
+ the omitted stdout range as unreviewed operational chatter, never as missing
2180
+ error evidence (error streams are never tail-capped). Each snapshot fixes file
2181
+ inode, offset, byte length, and SHA-256 before the CLI downloads it in bounded chunks;
2182
+ the CLI acknowledges only matching local bytes. If an inode changes, a file
2183
+ shrinks, or a new/missing file crosses the boundary, the manifest says so and
2184
+ captures the replacement from byte zero. Review that evidence and the relevant
2185
+ service journal interval; never assume the missing range was clean.
2186
+
2187
+ Only one operator can own the production-log boundary. The API's database
2188
+ lease and filesystem guard serialize starts, captures, and the eventual clear;
2189
+ every legacy service clear (API stdout/stderr and image-optimizer stderr)
2190
+ refuses to cross an active or starting Lumine review. A dropped CLI response
2191
+ is recoverable from the private `--review-session`: the next command
2192
+ materializes and acknowledges the pending
2193
+ snapshot, returns it as `needs_review`, and stops before taking another action.
2194
+
2195
+ A dropped `start` response is the one case with no session file yet. The CLI
2196
+ persists its start request key (`runtime-log-review-start-intent.json` under
2197
+ `--output-dir`, next to `--review-session`, or — with neither flag — a
2198
+ per-account file in the OS temp directory) before sending, so simply rerunning
2199
+ the same `start` command replays that key and the API answers with the same
2200
+ review. The key survives only transport failures, timeouts, and 5xx answers; a
2201
+ definitive 4xx clears it, and a key that belongs to a finished review is
2202
+ replaced once automatically. Every replayed `start` rotates the lease token the
2203
+ same way `resume` does, so if two shells of the same account raced, only the
2204
+ last responder holds a valid token and the other gets 403 until it runs
2205
+ `resume`. Two further owner-only recovery commands exist:
2206
+
2207
+ ```bash
2208
+ # Your own active review, with a freshly rotated lease token (the old token
2209
+ # stops working) and its latest snapshot materialized into a new session.
2210
+ lumine admin runtime-logs resume --output-dir ./runtime-log-review --json
2211
+
2212
+ # Release your own active review: database state, filesystem lease, a start
2213
+ # guard left by a dead start, and preserved artifacts. Never clears a log.
2214
+ lumine admin runtime-logs abandon [--review-session <file>] --json
2215
+ ```
2216
+
2217
+ Prefer `resume` (it keeps the reviewed boundary); use `abandon` only when the
2218
+ review cannot continue. A review lives at most 24 hours regardless of how
2219
+ often it captures; after that the API reports `CLI_ADMIN_RUNTIME_LOG_REVIEW_EXPIRED`
2220
+ and the next `start` supersedes it without clearing anything.
2221
+
2222
+ `finish --reviewed` confirms that every artifact returned by prior invocations
2223
+ was actually read. If any error log changed since the last artifact, it returns
2224
+ a new `needs_review` snapshot and does not clear. At a stable error boundary it
2225
+ clears only `twinkle-api.err.log`; lease verification, exact device/inode/size
2226
+ checking, and in-place truncation occur on the same open descriptor. It then
2227
+ returns `post_clear_review_required` with another immutable snapshot. That
2228
+ snapshot also captures normal-output bytes that arrived after the prior
2229
+ acknowledged cutoff, so routine stdout traffic cannot make the review infinite.
2230
+ Read it and run the same `finish --reviewed` command again. A review clears
2231
+ `twinkle-api.err.log` at most once. The lease closes when the reviewed error
2232
+ boundary is still stable, i.e. every byte now in the API error log arrived
2233
+ after that clear and was captured and acknowledged; errors that arrive before
2234
+ the boundary settles produce another `needs_review` snapshot first. Bytes still
2235
+ in the file at completion were reviewed but not cleared — the response reports
2236
+ them as `retainedErrorBytes` and the next review's baseline captures them
2237
+ again — which is what keeps a steadily erroring service from turning the
2238
+ review into an endless clear/capture/acknowledge loop. Normal output after the
2239
+ acknowledged post-clear snapshot is outside that finite review cutoff and
2240
+ belongs to the next review. The `needs_review` loop itself is bounded only by
2241
+ the review's 24-hour lifetime: if errors arrive faster than a finish
2242
+ round-trip, every `finish` returns another snapshot and the boundary never
2243
+ settles. `abandon` is the escape in that case — it releases the review without
2244
+ clearing anything, and the next review's baseline picks the bytes up again.
2245
+ Never delete, recreate, editor-save, or manually truncate a live log, and never
2246
+ clear stdout or optimizer logs through this workflow.
1867
2247
 
1868
2248
  For each warning, fallback, retry loop, or failure, correlate timestamps and
1869
2249
  request/target IDs with the canonical CLI response and private audit event.
@@ -1883,25 +2263,10 @@ carry-over todo with the exact finding and acceptance criteria, and tell Mikey
1883
2263
  in the run report. Do not mark that todo complete until the fix is verified
1884
2264
  live.
1885
2265
 
1886
- Preserve all log evidence while any finding remains. Once every issue found in
1887
- `/home/ec2-user/server/logs/twinkle-api.err.log` has been fixed and verified
1888
- live, or conclusively classified as expected/non-defective, clear that exact
1889
- live API stderr log through the only safe path:
1890
-
1891
- ```bash
1892
- ssh -i /Users/mikey/twinkle-api.pem -o IdentitiesOnly=yes \
1893
- ec2-user@api.twinkle.network \
1894
- 'cd /home/ec2-user/server && npm run logs:clear-errors'
1895
- ```
1896
-
1897
- That command truncates the file through the service's inode-safe lifecycle; it
1898
- does not restart the API. Never delete, recreate, editor-save, or manually
1899
- truncate any log. Do not clear normal stdout or the optimizer logs. After the
1900
- safe clear, inspect the error file and all bytes appended to the normal logs
1901
- once more, and include the reviewed file set, boundaries, findings/fixes,
1902
- live-verification result, clear result, and any remaining todo in the final run
1903
- report. If any error-log issue remains unresolved or unverified, do not clear
1904
- the error log.
2266
+ Preserve all downloaded evidence while any finding remains. Include the
2267
+ reviewed file set, boundary-loss notices, findings/fixes, live-verification
2268
+ result, clear result, and any remaining todo in the final run report. If any
2269
+ error-log issue remains unresolved or unverified, do not invoke `finish`.
1905
2270
 
1906
2271
  **Purpose and privacy boundary:** this audits how Twinkle's bots treated
1907
2272
  members; it is not thought-policing or a moderation queue for members' private
@@ -2006,6 +2371,7 @@ lumine admin brief --json
2006
2371
  lumine admin brief --days 3 --json
2007
2372
  lumine admin ai-costs monthly --json
2008
2373
  lumine admin media-costs monthly --json
2374
+ lumine admin notable status Stealth --json
2009
2375
  lumine admin notable add 12647 --note "Top authored-activity kid of the window: 11 subjects, 61 comments." --json
2010
2376
  lumine admin notable add Minecrarft_guy --note "Helped three new builders debug their projects and gave detailed feedback on five posts." --json
2011
2377
  ```
@@ -2021,8 +2387,8 @@ dump raw sections at him.
2021
2387
  ### Application AI calendar-month cost (standing duty, every full daily review)
2022
2388
 
2023
2389
  Run `lumine admin ai-costs monthly --json` during every full daily management
2024
- review. This read-only command requires the active delegated run and returns one
2025
- server-owned calendar summary from the canonical deduplicated application AI-
2390
+ review. This read-only command does not require or attach to a delegated run.
2391
+ It returns one server-owned calendar summary from the canonical deduplicated application AI-
2026
2392
  cost ledger. It deliberately takes no `--days`: all boundaries are UTC calendar
2027
2393
  months, so the result is directly comparable from one run to the next.
2028
2394
 
@@ -2049,6 +2415,20 @@ from a billing provider. All ledger values are pricing-based estimates rather
2049
2415
  than invoices and can change if canonical usage attribution or pricing is
2050
2416
  corrected.
2051
2417
 
2418
+ For an exact provider/model/operation breakdown after the run has already
2419
+ closed, use the run-independent closed-day drilldown:
2420
+
2421
+ ```bash
2422
+ lumine admin ai-costs day 2026-09-03 --json
2423
+ ```
2424
+
2425
+ The date is a UTC `YYYY-MM-DD` key and must be earlier than the current UTC
2426
+ day. `data.dailyAiCosts` uses the same canonical deduplicated ledger as the
2427
+ monthly report and returns the exact closed-day summary plus `byDay`,
2428
+ `bySurface`, `byProviderModel`, `byBillingPolicy`, `byOperation`, and Lumine
2429
+ provider status/model telemetry. It never includes a still-filling day or
2430
+ reconstructs totals client-side.
2431
+
2052
2432
  The stable JSON payload is `data.monthlyAiCosts`:
2053
2433
 
2054
2434
  ```ts
@@ -2115,10 +2495,47 @@ type MonthlyAiCostProjection = {
2115
2495
  };
2116
2496
  ```
2117
2497
 
2118
- Release boundary: `/cli/admin/ai-costs/monthly` and all calendar math are API-
2119
- owned. Deploy and verify the compatible `twinkle-api` route before publishing
2120
- or installing the Lumine CLI release that invokes it; an older API will reject
2121
- the new command instead of synthesizing figures locally.
2498
+ Release boundary: `/cli/admin/ai-costs/monthly`, `/cli/admin/ai-costs/day/:day`,
2499
+ `/cli/admin/energy-budget/report`, the historical daily-run report, exact
2500
+ notable-user status, Subject-window resolution, and the runtime-log
2501
+ lease/snapshot workflow are API-owned. Apply the runtime-log review and energy
2502
+ telemetry migrations, then deploy and verify the compatible `twinkle-api`
2503
+ routes before publishing or installing the Lumine CLI release that invokes
2504
+ them. An older API will reject the new commands instead of synthesizing
2505
+ figures locally.
2506
+
2507
+ ### AI Energy budget health (standing duty, every full daily review)
2508
+
2509
+ Read the report at run start, before any other duty, so the day confirms the
2510
+ AI Energy budget system (one live Lumine run per user, per-run energy ceiling
2511
+ with an exact round cap, settled stops) is still behaving:
2512
+
2513
+ ```bash
2514
+ lumine admin energy-budget --json # last 7 UTC days (max --days 31)
2515
+ ```
2516
+
2517
+ It is owner-only and run-independent. Every UTC day carries the canonical
2518
+ energy ledger (`chargedUsd`, `overflowUsd`, `users`, `recharges`; 1,000,000
2519
+ units = $1), every telemetry counter (`busy_refusal`, `autofix_yielded`,
2520
+ `autofix_superseded`, `reservation_admitted` with `avgRunBudgetUsd`,
2521
+ `budget_stop_changed` / `budget_stop_unchanged` / `run_completed` with a
2522
+ per-model breakdown, `stop_settled`, `tool_limit_settled`) and per-model
2523
+ per-run usage stats (`runs`, `callsPerRun`, `usdPerRun`, each avg and
2524
+ nearest-rank p90). The current UTC day is returned with `inProgress: true`.
2525
+ **Headline `lastCompletedDay` (its exact `dayKey`) — never the in-progress
2526
+ day**, exactly as the closed-day AI-cost duty does.
2527
+
2528
+ `flags` lists every tripped check with its exact numbers: `overflow_usd`
2529
+ (overflow above $1 on a completed day), `budget_stop_unchanged_ratio` (more
2530
+ than 30% of at least 5 budget stops ended with nothing saved),
2531
+ `busy_refusals` (more than 20 in a day), and `telemetry_missing` (runs
2532
+ recorded usage while the telemetry table has no rows for that day — the
2533
+ writer is broken). Record every tripped flag, and any anomaly you judge from
2534
+ the numbers (a per-run p90 far above the average run budget, a sudden drop in
2535
+ `run_completed` while runs still record usage, recharges climbing), as a
2536
+ carry-over todo with the exact figures and day. **Never auto-enforce** —
2537
+ escalate to Mikey; this duty observes, it does not change budgets, caps, or
2538
+ user state.
2122
2539
 
2123
2540
  ### Lumine media feature cost and cleanup watch (standing duty, every full daily review)
2124
2541
 
@@ -2362,6 +2779,11 @@ farm-signal sections added that day; AI Card summon watch added 2026-08-24):
2362
2779
  service). It can therefore record Mikey's approval after the daily run has
2363
2780
  closed without opening another delegated run. Without his approval the run
2364
2781
  only proposes.
2782
+ Check an exact current username or user ID without opening a run using
2783
+ `lumine admin notable status <userId|username> --json`. This reads the
2784
+ canonical writer and returns only the resolved public account identity,
2785
+ current membership, and the roster rationale/timestamps when present; it
2786
+ does not expose the private roster fields.
2365
2787
  **Always pass `--note`** with a concrete one-or-two-sentence record of what
2366
2788
  made them notable — real numbers and specifics from the brief window, not
2367
2789
  "active user". It lands in the management page's reason column, which is
@@ -3160,6 +3582,16 @@ Deploy and verify the API's `/cli/admin/subjects/featured/rotation` route before
3160
3582
  publishing a CLI release that exposes `featured rotate`; an older API rejects
3161
3583
  the command without changing Featured state.
3162
3584
 
3585
+ The approved-plan and Featured-comment workflows require the new
3586
+ `/subjects/featured/plan`, `/plan/apply` (under that same Featured base), and
3587
+ `/subjects/featured/reviews` routes. Deploy the API before releasing the CLI;
3588
+ there is no fallback to unbound writes or a full daily run on an older API.
3589
+ Existing runs remain readable/completable with their original scopes, but are
3590
+ not silently granted `featured:comments`; start a fresh scoped/full run as
3591
+ appropriate after finishing the existing authorized work. No new migration is
3592
+ required for these workflows: server receipts reuse the existing audit table
3593
+ and full-board mutation history.
3594
+
3163
3595
  For scoped runs and Featured history, also apply
3164
3596
  `add-lumine-admin-run-scope.sql` and `add-featured-subject-history.sql` before
3165
3597
  the API release. After every serving API worker is verified on that release