LunarWing v2.1.5.0 Release - Codename Bungei Fukkō
Bungei Fukkō

文芸復興
The Renaissance.
Ink long dried wakes;
old letters learn new light —
the arts rise again. 文芸復興
Yoroi built the plates.
Ō-Yoroi fitted their joints.
Kabuto guarded the mind beneath them.
But the reason to protect that mind was never to leave it standing watch forever.
There are pages waiting on the table.
There is work worth returning to.
LunarWing v2.1.5.0, Bungei Fukkō, opens the workshop.
This is a release about recovery and honest accounting. An unfinished turn needs a recorded outcome, not a convincing ending. A rejected memory write needs an explanation that helps. A mission missed during downtime needs a place in history, not an automatic replay of yesterday’s intent.
The work reaches into restart recovery, mission controls, daily logs, model failures, and the small pieces of information that disappear when a tool result is cut short.
A cursor at the bottom of a page.
A token charge behind an empty answer.
An approval still waiting when the lights return.
Revival begins by noticing what was left unfinished.
Then making it possible to continue.
The workshop door opens,
brushes wait where rust once slept —
color finds the page.
The work begins again
Highlights
-
The unfinished manuscript is not abandoned. Engine V2 boot recovery now includes threads whose project record is missing, preserves pending approvals and resumable checkpoints, and records mission fires missed during downtime. Those missed fires are surfaced for owner review rather than automatically replayed. History is persisted before acknowledgement, with thread-ID deduplication across the crash window.
-
A closed workshop leaves a record. Mission fires interrupted by graceful shutdown now retain their history and release their trigger-dedup keys. At the next boot, recovery checks the thread’s final persisted state before deciding whether the planned retry applies. Completed work is not retried merely because shutdown caught the watcher between steps.
-
Failure keeps its own name. Content-filter refusals and exhausted output budgets receive different terminal guidance. Thread token, time, and cost exhaustion return
BudgetExhaustedwithout a fresh-budget retry. Malformed outcomes and unconfirmed completion claims no longer dissolve into apparent success. Token usage billed to intercepted empty streams now reaches thread accounting and provider telemetry too. -
A crowded page can make room. Context-overflow recovery can finally use both stages of its shrink policy,
0.60xand then0.35x, under the default configuration. Per-kind and lifetime limits still bound recovery. Foreground conversation context also has explicit retention bounds instead of growing every later turn’s prompt without limit. -
One finished page is not the whole commission. A non-manual mission no longer completes merely because one run declares its goal achieved.
tool_infonow describes mission capabilities and their lease-aware availability, while resumed threads regain the appropriate mission leases after restart. Parked recurring missions return only through owner-authorizedmission_resume, not a bulk revival. -
Permission is not a signature on blank paper. Mission verbs now check permissions, request one-shot approval in supervised mode, enforce rate limits, and run hooks with webhook secrets redacted. Research children, including recursive sub-agents, cannot use the six mutating mission verbs. Separately, secret deletion requires per-call approval that an old “always allow” grant cannot bypass.
-
A damaged log need not ruin the day.
memory_write(target: "daily_log", append: false)now really replaces the log instead of silently appending. A clean append blocked by existing poisoned content can quarantine the old log and request one unchanged retry on a fresh file. Injection rejections identify matched patterns and give rephrase guidance, rather than misdiagnosing a content problem as missing permission. -
Earlier pages stay out of the writer’s reach. Prompt-file replacements gain scope-aware shadow backups. Daily logs keep up to eight generations, pinning the day’s first replaced version while later generations rotate. Backup and quarantine artifacts are reserved from memory-tool read, tree, and write access and from web writes; operator recovery remains available through direct workspace reads, the web read route, and the CLI.
-
A shortened scroll keeps its next-page mark. Oversized tool results now retain their beginning and end, with an explicit omission in the middle. Engine V2, the v1 routine loop, and the safety layer preserve the tail where list tools place
next_cursorand other continuation fields. The safety layer also adjusts cuts around detected secrets rather than slicing through them. -
The workshop keeps a readable ledger. A read-only
/tenant-logsmount exposes the daemon’s own secret-scrubbed log copy to supported sandboxes. The daemon writes and rotates that copy itself, across systemd, OpenRC, and launchd. Operators can choose ordinary diagnostics, additional debug detail, or no mount at all. -
The restoration includes the tools on the bench. Vendor refresh restores the committed rig-core patch if vendoring fails or is interrupted, and checks its markers before and after replacement. Dependency updates, a regenerated vendor tree, and wider advisory gates accompany OpenCode 2’s move to
v2.0.24. Its worker now explicitly loads the lane configuration instead of leaving the intended endpoint unused.
Upgrading
Back up the database, tenant environments, /etc/lunarwing/ports.json, workspace and channel state, rendered units, worker data, voice models, and channel state before upgrading.
SQL advances to V28. V28__revoke_secret_delete_always_grants.sql runs automatically on PostgreSQL and libSQL, removing stale secret-deletion grants. Downgrading does not restore those revoked grants. The new runtime approval check does not depend on the cleanup: it ignores those grants at execution time. The port registry remains at v17.
Deploy rebuilt components together. Rebuild the daemon, XMPP bridge, and installed WASM extensions. All four channel and nine tool registry packages advance. Channel versions are darkirc 0.1.11, multica 0.1.14, weechat 0.2.12, and xmpp 0.1.17; the channel version bumps introduce no protocol changes. The seven bundled product skills need no migration.
Prepare the OpenCode 2 worker. Rebuild opencode2 at v2.0.24 and use the protected candidate, scan, and promotion process before deployment. Because OPENCODE_CONFIG now loads the lane’s materialized configuration, its baked default endpoint actually takes effect. Set a tenant’s real endpoint with ic/scripts/lunarwing-mt-admin.sh configure-opencode2 <tenant> --base-url <url> when that default does not fit. Kimi Code 2.1.1, OpenCode v1 v1.18.25, and Pebble 2d0f3786… remain unchanged and need no rebuild unless their pins have drifted.
Review model and routine budgets. ENGINE_V2_MAX_OUTPUT_TOKENS defaults to 8192, up from a fixed 4096. When reasoning consumes the entire budget without visible text, the host retries once at double the budget. For thinking models, the release guidance suggests 16384 or more, while keeping the configured value at or below half the provider’s output cap. Restart the daemon after changing it.
Lightweight routines now receive N tool rounds plus one text-only reply for max_tool_rounds: N. The hard limit is 10. New tenants render ROUTINES_LIGHTWEIGHT_MAX_ITERATIONS=6, but this is a ceiling: the per-routine default remains 3. Existing routines gain one effective model call per run under the corrected counting.
Choose diagnostics explicitly. New tenants render SANDBOX_TENANT_LOGS=info alongside the new routine ceiling. Upgrades do not add either key to existing tenants, and re-renders preserve explicit values. Set the log option to off to disable the mount, or debug with a raised log level for per-tool-call detail.
Use the recovery contract that matches the failure. Inside Engine V2, use mission_* tools; legacy routine_* calls now explain the appropriate equivalents. Review parked missions before mission_resume, especially records that could represent an intentional legacy deletion. Missed downtime fires are recorded, not replayed; graceful-shutdown interruptions are reconciled separately at boot. For daily logs, retry unchanged only after successful quarantine of existing poison. Newly rejected content needs rephrasing, not repeated identical writes.
The release identifier is 2.1.5.0. All eleven LunarWing-owned release packages use 2.1.5. Rust 2024, MSRV 1.96.1, and Wasmtime/WASI 36.0.17 remain unchanged.
Yoroi gave the body armor.
Kabuto guarded the mind.
Bungei Fukkō gives that care somewhere to go.
Back to the unfinished page.
Back to the work that can be recovered.
Back to a record that says what happened, including what did not.
The helmet has not been discarded.
The workshop door is simply open.
What revival keeps
is not the past, but the hand
that dares to begin.
文芸復興
For full release notes, check the repository as always.