Zanshin

Zanshin

残心

After the cut, the mind stays.

The strike already finished.
Still the hand does not lower.

There is a moment after the blade has passed.

The movement is finished.

The opponent is no longer in front of you.

And yet the swordsman does not relax.

The eyes remain open.

The posture remains ready.

The mind remains where it needs to be.

This is Zanshin.

残心 is the awareness that remains after an action has ended. It is not another strike. It is what prevents the strike from becoming the end of your attention.

LunarWing v2.1.1.0 is built around that idea.

After Ma-ai taught the engine to act within the space between decisions, Zanshin turns its attention toward what remains after those decisions.

What did the system actually receive?

What did it write down?

Did the memory index follow the document?

Did a cancelled action really stay cancelled?

Did the connection lose something while everyone assumed it was still speaking?

Did the worker come back after the tenant restarted?

Did the knowledge store remain alive after its first snapshot?

The answers now have somewhere to go.

Zanshin keeps watch.

The largest piece is memory integrity. Retrieved memory is no longer allowed to quietly masquerade as trusted instruction, and memory written through the engine receives explicit provenance. A new outbox marker lets LunarWing recognize when its document index has fallen behind and repair the discrepancy automatically, both at startup and during heartbeat hygiene.

The engine also closes a subtle race where an interrupt could arrive while a prompt was still waiting in the scheduler. The interruption now reaches that queued work instead of watching it slip through the gate.

Elsewhere, knowledge refresh becomes continuous rather than snapshot-bound. Coordination knowledge reaches the XMPP wire. Workers recover properly after tenant restarts. Lost stream events become visible instead of disappearing into the floorboards. Voice gains a gateway path for the desktop client.

And the release machinery itself becomes more exact.

Because vigilance is not only something the agent needs.

It is something the system needs.

After the strike

Highlights

  • Memory learns what it can trust. Retrieved memory is now explicitly treated as untrusted content and labeled accordingly, while __save_memory_doc__ forces trusted provenance and strips fields that could turn stored content into pending instructions. System-role prompt injection is neutralized at both LLM adapter boundaries, closing the explicit-System seam through __llm_complete__.

  • The index can heal itself. A new memory_documents.indexed_at outbox marker tracks index freshness. Startup and heartbeat hygiene sweeps can detect stale or desynchronized memory documents and repair their indexes without requiring manual intervention.

  • The interrupt reaches the waiting turn. A priority /interrupt can now overtake a prompt that is still queued in the scheduler. Instead of reporting Nothing to interrupt. and allowing the cancelled prompt to run anyway, LunarWing cancels it in its conversation lane and answers Interrupted..

  • Knowledge stops living in a snapshot. The knowledge seeder gains a cadence runner and additive refresh scans, allowing hosted study knowledge to stay current instead of depending entirely on a static checkout.

  • Coordination knowledge reaches the wire. The KNOW: coordination path is implemented and live-verified across isolated XMPP tenants, giving cooperating engines a durable path for sharing coordination knowledge while keeping production activation behind explicit operator controls.

  • Pebble comes back after a restart. mt-admin tenant stop/start now preserves Pebble worker availability and clears restart-limit lockouts when necessary, preventing a tenant bounce from quietly leaving its worker behind.

  • Lost stream events announce themselves. SSE and WebSocket lag is now surfaced as an explicit stream_gap event. The browser can discard incomplete live-stream state and reload persisted history rather than silently presenting a conversation with pieces missing.

  • Workers tell us why they failed. Connection failures no longer recommend recreating or upgrading a worker for every HTTP 4xx. The rolling-upgrade hint is now restricted to actual protocol-mismatch responses such as 400 Bad Request and 426 Upgrade Required.

  • Voice has a gateway door. Authenticated /api/voice/status, /api/voice/transcribe, and /api/voice/synthesize routes now proxy the LunarVoice sidecar behind the gateway’s existing authentication boundary, with bounded request sizes and per-user rate limiting.

  • Threads can announce themselves. Best-effort engine/thread_start events now provide generic subscribers with the source thread, project, thread type, and goal for top-level foreground threads.

  • CI becomes less willing to look the other way. Worker pins, CI tool images, and manifest job names receive stronger validation. Clippy and architecture-boundary checks become blocking ratchets, while classified deliverables and test reports tighten the release gate.

  • The knowledge path gets safer under concurrency. Seeder save-state filenames now carry a nanosecond nonce alongside the process ID, preventing concurrent CLI invocations from colliding, while healthy import skips no longer poison failure/backoff state.

  • The contributor path is finally marked. A dedicated contributor onboarding guide now lives under docs/guides/ and is indexed from the main documentation guide table.

Upgrading

Back up PostgreSQL, tenant environment files, /etc/lunarwing/ports.json, workspace state, rendered units, worker data, voice models, and channel state before upgrading.

Unlike v2.1.0.0, v2.1.1.0 introduces one SQL migration:

V27__memory_index_outbox.sql

The migration applies to both PostgreSQL and libSQL. Existing memory documents are backfilled so an upgrade does not trigger a mass re-embedding operation.

The multi-tenant port registry remains at v16.

Rebuild the daemon and installed WASM extensions through the normal deployment path. All four channel registry packages have advanced:

  • darkirc 0.1.7
  • multica 0.1.10
  • weechat 0.2.8
  • xmpp 0.1.13

Tool registry versions remain unchanged from v2.1.0.0.

The ic/ dependency tree continues to resolve crates.io through the committed ic/vendor/ snapshot.

If additive knowledge synchronization is desired, enable the documented KNOWLEDGE_SYNC_* environment variables or the mt-admin knowledge-sync module. Otherwise, the existing behavior remains unchanged.

For coordination knowledge, participating tenants must join the intended MUC, authorize the appropriate occupants through COORD_KNOWLEDGE_PUBLISHERS, and restart both engines.

Worker tool pins remain unchanged:

opencode v1.18.25

kimi-code 0.41.0

Do not restore OpenCode v1.18.29 until the documented upstream regressions are resolved.

The release identifier is 2.1.1.0. LunarWing-owned Rust crates and channel packages use 2.1.1. Rust 2024 and MSRV 1.96.1 remain unchanged.


A blade does not become safe because the cut is finished.

The hand stays ready.

The eyes stay open.

The system remembers what happened.

Ma-ai found the distance.

Zanshin remains after the strike.

Memory is no longer simply something LunarWing retrieves.

It knows where that memory came from.

It knows when its index has fallen behind.

And when something slips between one moment and the next, the system has a better chance of noticing.

The strike is finished.

The work is not.

残心