@stage5/lumine 0.2.68 → 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.
@@ -1,8 +1,8 @@
1
1
  # Build SDK Index
2
2
 
3
- Version: 1.39.0
4
- Updated: 2026-09-03
5
- Generated: 2026-09-03T04:17:20.106Z
3
+ Version: 1.41.0
4
+ Updated: 2026-09-08
5
+ Generated: 2026-09-08T05:12:06.333Z
6
6
 
7
7
  ## Notes
8
8
  - This SDK is injected into Build iframes via the Build preview/runtime.
@@ -30,9 +30,12 @@ Generated: 2026-09-03T04:17:20.106Z
30
30
  - Static media published through sharedDb is app-owned feed data. A public user-generated feed must provide a visible report flow and owner removal, and must not claim that Twinkle globally moderates those posts.
31
31
  - Use Twinkle.live for one-way app livestreams and Twinkle.chat for the accompanying thread. Free livestreams require a verified host, end after at most 15 minutes, and issue at most 10 private viewer grants. Twinkle keeps platform-owned live-status/end controls above active hosts, so app code cannot hide or replace the broadcaster's Stop path.
32
32
  - Media Energy is separate from AI Energy. Replace Media Energy UI only from canonical mediaEnergy/getUsage responses; never decrement, reserve, or synthesize it in app code.
33
+ - Twinkle.rewards awards real XP and Coins only in the current approved published release. Drafts, local previews, private apps and superseded releases cannot earn. The server supplies a published-runtime grant; app code cannot choose a recipient or award amount.
34
+ - Lumine agents prepare private numeric quiz rules and budgets with prepare_reward_rules (CLI: POST /build/:buildId/rewards/prepare with { config }). Creators are kids and teens: show a simple earning summary, approval status and Send for review; do not ask them to fill in technical forms. Every code or rule update that retains rewards needs a new approval before publishing. Removing the SDK automatically clears its gate and publishes without reward permission; adding it back requires a fresh approval. Other protected SDKs keep their own gates. Keep protected SDK calls explicit in project source. Existing approved live rewards continue while a draft waits; approvals never publish automatically.
35
+ - v1 verifies numeric quiz answers on the server; client scores, privateDb state, timers and completion booleans are not reward evidence. Daily limits reset at midnight in Korea. Each rule can be earned once per viewer per day, with three answer attempts per challenge. Challenge expiry is 30 minutes. Budgets apply across release changes.
33
36
 
34
37
  ## Token Scopes
35
- files:read, media:read, media:write, live:read, live:write, user:read, users:read, dailyReflections:read, content:read, content:write, sharedDb:read, sharedDb:write, privateDb:read, privateDb:write, files:write, chat:read, chat:write, notifications:read, notifications:write, notifications:emit, reminders:read, reminders:write
38
+ files:read, media:read, media:write, live:read, live:write, user:read, users:read, dailyReflections:read, content:read, content:write, sharedDb:read, sharedDb:write, privateDb:read, privateDb:write, files:write, chat:read, chat:write, notifications:read, notifications:write, notifications:emit, reminders:read, reminders:write, rewards:claim
36
39
 
37
40
  ## Namespaces
38
41
 
@@ -941,6 +944,13 @@ world.updatePresence({ x, y, z, facing });
941
944
  - Returns: { success: true, deleted: boolean }
942
945
  - Delete one key from the default private per-user JSON store.
943
946
  - Deletes one key for the current viewer.
947
+ - async compareAndSet(key, expectedValue, value, { operationId, expectedUserId }) | scopes: privateDb:write
948
+ - Returns: { item: { id, key, value, updatedAt }, applied, duplicate, conflict }
949
+ - Atomically save only when the current JSON value matches expectedValue, with a permanent idempotency receipt.
950
+ - Pass null as expectedValue for an absent/null value. Both values are limited to 16 KB. Optional expectedUserId prevents a held operation from crossing an account change.
951
+ - operationId is required: 8–64 letters, digits, underscores or hyphens. Reuse it for retries of the same logical change.
952
+ - On conflict, rebase the intent onto the returned canonical item before comparing again. Do not retry-loop a 429.
953
+ - A duplicate operation returns the current canonical item without applying again. Ordinary set/remove remain unconditional; use a dedicated key for a compare-and-save workflow.
944
954
 
945
955
  ### Twinkle.reminders
946
956
  - async list({ includeDisabled, limit } = {}) | scopes: reminders:read
@@ -962,6 +972,45 @@ world.updatePresence({ x, y, z, facing });
962
972
  - Returns reminders that are due right now for the current signed-in viewer.
963
973
  - autoAcknowledge defaults to true and prevents the same reminder from retriggering immediately.
964
974
 
975
+ ### Twinkle.arena
976
+ - async board({ ruleset, cursor, revision, limit } = {}) | scopes: sharedDb:read
977
+ - Returns: { ruleset, revision, total, fighters, me, targets, dailyUsed, cursor, hasMore }
978
+ - Load a ranked page plus your fighter and all challengeable opponents independently of the page.
979
+ - limit defaults to 50 and is at most 100. Pass returned cursor and revision together for more rows.
980
+ - A 409 means the ladder changed between pages: restart from the first page. Records are canonical and do not require replaying history.
981
+ - async publish({ ruleset, expectedUserId }) | scopes: sharedDb:write
982
+ - Returns: { fighter }
983
+ - Publish or update your own fighter from your confirmed saved career.
984
+ - The server derives identity, stats, gameplan and appearance from the viewer’s saved career. Supplied fighter snapshots or user IDs are not accepted.
985
+ - Existing rank and records are preserved; a new fighter joins at the bottom.
986
+ - async challenge({ ruleset, opponentUserId, operationId, expectedUserId }) | scopes: sharedDb:write
987
+ - Returns: { bout, duplicate }
988
+ - Issue and adjudicate one ranked match, atomically saving its result, quota usage and ranking.
989
+ - operationId must contain 8–64 letters, digits, underscores or hyphens. Preserve it across ambiguous failures and reloads.
990
+ - The server issues the seed and uses its pinned ruleset and saved fighters. Never submit a winner, seed, or fighter snapshot.
991
+ - The bout contains id, ruleset, seed, a, b, outcome, winner, reason, round, tookSpot, at and by. a/b contain userId, name and snap.
992
+ - Three challenges per UTC day, against fighters one to three ranks above you. Duplicate requests never consume another challenge.
993
+ - Subscribed defender owners receive a ruleset-bound result notification from the canonical transaction. HTTP 400/409 eligibility errors with writeStatus=not_applied are definitive rejections; retain the same operationId after an ambiguous network failure.
994
+ - async bouts({ ruleset, cursor, limit } = {}) | scopes: sharedDb:read
995
+ - Returns: { bouts, cursor, hasMore }
996
+ - Read immutable ranked bout history, newest first, with cursor pagination.
997
+ - limit defaults to 50 and is at most 100. There is no three-page history cutoff.
998
+ - async getBout({ ruleset, id, legacyEntryId }) | scopes: sharedDb:read
999
+ - Returns: { bout }
1000
+ - Read one immutable bout in this build and ruleset.
1001
+ - Supply id, or legacyEntryId for an imported legacy notification. Replay new bouts only with their exact ruleset; the stored outcome is authoritative. Legacy records explicitly identify their unversioned simulation.
1002
+
1003
+ ### Twinkle.rewards
1004
+ - await Twinkle.rewards.getStatus() | scopes: rewards:claim
1005
+ - Returns: { mode: "live", dayKey, rules, history, balances: { xp, coins } } | { mode: "preview", rules: [], history: [], message }
1006
+ - Read canonical earning rules (without answer keys), today’s receipts and balances. Drafts return preview mode. Unapproved or revoked published releases return an error.
1007
+ - await Twinkle.rewards.start({ ruleId }) | scopes: rewards:claim
1008
+ - Returns: { mode: "live", challengeId, questions: [{ prompt }], reward: { xp, coins }, attemptsRemaining, expiresAt }
1009
+ - Creates or resumes a server-issued challenge for the signed-in viewer. Render its questions and collect numeric answers in the same order. One daily challenge per rule/review; repeat starts cannot reset attempts.
1010
+ - await Twinkle.rewards.claim({ challengeId, answers: [number] }) | scopes: rewards:claim
1011
+ - Returns: { awarded: false, attemptsRemaining } | { awarded: true, duplicate, receipt, balances: { xp, coins } }
1012
+ - Twinkle verifies every answer, approval, current published artifact and budget before atomically recording XP and Coins. Retry the same challengeId after a lost response; a confirmed claim returns its original receipt without another award. Never update balance UI optimistically.
1013
+
965
1014
  ## Examples
966
1015
 
967
1016
  ### Daily reflection feed
@@ -1294,3 +1343,16 @@ await Twinkle.reminders.create({
1294
1343
  targetPath: '/focus'
1295
1344
  });
1296
1345
  ```
1346
+
1347
+ ### Claim an approved learning reward
1348
+ Keywords: xp, coins, rewards, quiz, approval
1349
+
1350
+ ```js
1351
+ const status = await Twinkle.rewards.getStatus();
1352
+ if (status.mode === 'live') {
1353
+ const challenge = await Twinkle.rewards.start({ ruleId: 'daily-question' });
1354
+ // Render challenge.questions and collect numbers in the same order.
1355
+ // const result = await Twinkle.rewards.claim({ challengeId: challenge.challengeId, answers });
1356
+ // Display only result.balances and result.receipt after awarded === true.
1357
+ }
1358
+ ```
@@ -484,6 +484,27 @@ it never authorizes unrelated daily work or generic recommendation commands.
484
484
  completed all-Featured-comment review. Include refresh progress and any
485
485
  carryovers as required in the `Featured rotation` report section below.
486
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
+
487
508
  ## Escalation to Mikey
488
509
 
489
510
  A full daily management run is not finished when the mutations are done. Curation surfaces things only
@@ -1038,6 +1059,53 @@ migration cannot quietly treat unsupported telemetry as an empty list.
1038
1059
  A Featured-only start instead returns an explicitly suppressed, empty handoff
1039
1060
  and performs no todo reads, writes, capacity checks, or surfacing increments.
1040
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
+
1041
1109
  `kind` is `task` or `experiment`. New items may start `open`, `in_progress`, or
1042
1110
  `blocked`; updates may also use `completed` or `cancelled`. A progress note is
1043
1111
  required for every update. For experiments, put the acceptance criteria in the
@@ -1215,8 +1283,10 @@ verifies the request fingerprint and confirmed spool digest before requesting
1215
1283
  another page. An interrupted request is never counted as queue coverage.
1216
1284
 
1217
1285
  Recommendations default to `--since-run`: the server uses the previous
1218
- completed run's start time (or the same bounded seven-day fallback used by the
1219
- 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
1220
1290
  at-least-once coverage when content arrives after the prior snapshot but before
1221
1291
  that run completes. `--after` supplies an explicit inclusive timestamp.
1222
1292
  All-history traversal is deliberately available only through
@@ -1224,6 +1294,12 @@ All-history traversal is deliberately available only through
1224
1294
  boundary for bounded modes, so deploying a new CLI against an older API cannot
1225
1295
  silently fall back to a million-row historical scan.
1226
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
+
1227
1303
  Subject candidates follow the same window contract. They default to the
1228
1304
  previous completed full run's start (with the seven-day first-run fallback),
1229
1305
  accept an explicit inclusive `--after`, and require `--include-legacy` for a
@@ -1231,9 +1307,16 @@ lifetime traversal. `--since-run`, `--after`, and `--include-legacy` are
1231
1307
  mutually exclusive. The CLI also requires the API to echo the bounded Subject
1232
1308
  window before accepting a page.
1233
1309
 
1234
- `builds candidates` is a management-agent discovery view over the canonical
1235
- public Build browser, ordered by the current published release. It is
1236
- 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;
1237
1320
  page until `pagination.exhausted`. Each item includes its canonical app URL,
1238
1321
  published artifact version, and whether its code is pullable. This list does
1239
1322
  not decide that an app deserves a comment. The management agent must open and
@@ -1241,6 +1324,12 @@ genuinely try the published runtime, or pull and read an open-source project,
1241
1324
  before making that judgment. Direct API/persona automation is never a review
1242
1325
  substitute.
1243
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
+
1244
1333
  `builds review` is the managed runtime path: it fetches the current published
1245
1334
  artifact identity, launches the app in an isolated temporary Chromium profile,
1246
1335
  captures a screenshot and bounded console evidence, then fetches the identity
@@ -1551,6 +1640,16 @@ after the finalized coverage boundary. `null` means the subject predates provabl
1551
1640
  coverage—never convert that unknown into “never Featured.” Both the website
1552
1641
  editor and Lumine mutations write this append-only history in the same
1553
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.
1554
1653
  For a retry whose board transaction committed but whose canonical detail reload
1555
1654
  failed, the audit-linked history event is the durable receipt: the API re-reads
1556
1655
  the current board and preserves the original changed-mutation accounting.
@@ -2108,10 +2207,23 @@ type NewsSubmit = NewsStatus; // "success"; newspaper includes revisionNumber
2108
2207
  lumine admin bot-output --json
2109
2208
  lumine admin bot-output --days 3 --json
2110
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
2111
2212
  ```
2112
2213
 
2113
2214
  **Every full daily review reads what Zero and Ciel themselves said since the
2114
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
+
2115
2227
  The bots talk to children constantly — chat replies, Daily Reflection
2116
2228
  responses, autonomous comment-assistant comments — and a harmful message must
2117
2229
  never depend on a kid being brave enough to report it (real incident,
@@ -2137,6 +2249,27 @@ right after the brief, and **read every row** — the tool deliberately does no
2137
2249
  filtering, scoring, or keyword matching, because the judgment is the reviewing
2138
2250
  agent's.
2139
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
+
2140
2273
  ### API runtime-log review (same phase, every full daily review)
2141
2274
 
2142
2275
  The bot-conduct review also owns a bounded production API log review. Bot
@@ -2145,6 +2278,24 @@ the HTTP layer while stdout records a degraded fallback/retry loop or stderr
2145
2278
  records a side-effect failure. Reviewing only `bot-output` can therefore miss
2146
2279
  the other half of what happened.
2147
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
+
2148
2299
  The current API-side files are:
2149
2300
 
2150
2301
  - `/home/ec2-user/server/logs/twinkle-api.err.log`
@@ -2157,6 +2308,27 @@ in scope so a later API-side worker is not silently omitted. Use the delegated,
2157
2308
  run-independent workflow; it holds one server lease across the review and
2158
2309
  writes private, digest-verified local artifacts:
2159
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
+
2160
2332
  ```bash
2161
2333
  lumine admin runtime-logs start --output-dir ./runtime-log-review --json
2162
2334
  # Read every file under data.artifacts.latestSnapshot.snapshotPath.
@@ -3137,11 +3309,38 @@ cannot choose or override that identity. The authorization lasts ten minutes,
3137
3309
  is bound to that exact comment, permits only reading that target and editing
3138
3310
  it, and never runs daily duties, changes the Bangkok calendar assignment, or
3139
3311
  contributes to a daily-run mutation count. A correction cannot target a human
3140
- comment, notification record, deleted comment, or Build thread. Build comments
3141
- still require a fresh version-bound correction reply after genuinely reviewing
3142
- 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.
3143
3316
  Finish it explicitly after the canonical edit is confirmed.
3144
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
+
3145
3344
  **Editing the bot's own comments.** `comment edit <commentId> --file
3146
3345
  <comment.md>` replaces the text of a comment the acting bot itself authored —
3147
3346
  for correcting a factual error, an unfulfillable claim, or outdated guidance
@@ -3153,7 +3352,8 @@ composed-comment rules (plain UTF-8, 10,000-character limit, truth about what
3153
3352
  the session actually did) and publishes through the website's canonical
3154
3353
  comment-edit pipeline — mentions are reprocessed (a newly added `@mikey`
3155
3354
  notifies him), and Earn-candidate projections resync. Submitting identical
3156
- 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
3157
3357
  session above or the `comment:post` scope of a comment-mode `post` run, and is
3158
3358
  audited as `comment.edit` with the previous content in `beforeState` and
3159
3359
  `data.edit.previousContent`. Edit sparingly:
@@ -3399,9 +3599,12 @@ sponsor pays from their own battery. Mentions elsewhere in a Build, replies to
3399
3599
  unlinked or legacy bot comments, replies to humans, and the other bot remain
3400
3600
  ineligible. If the published version has changed, the responder is told the
3401
3601
  stored understanding belongs to the reviewed older version and must say it has
3402
- not checked behavior that could have changed. The generic `comment edit`
3403
- shortcut is also disabled there; review the current version and post a
3404
- 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.
3405
3608
 
3406
3609
  **Offer a Lumine prompt when the moment invites it (Mikey's direction,
3407
3610
  2026-08-10).** Zero and Ciel may include one concrete, copy-pasteable Lumine