Two PR #94 validation findings.
1. (High, blocking) GPU stuck after leaving a panel: the GPU only
swaps its displayed buffer on BufferSnapshot, and the daemon only
sent one on the first CRDT upgrade (F29's ensure returns None for
an already-backed buffer). A panel's q / RET switched the daemon's
active buffer back to the already-known source and sent nothing --
the GPU kept rendering the panel while input targeted the source: a
typing-into-a-buffer-you-can't-see hazard. Fix: the per-tick loop
now FOLLOWS each replica frontend's own active buffer -- when it
differs from the last snapshot sent to that frontend, ship that
buffer's snapshot to that frontend only (the F29 broadcast records
itself so the upgrade tick doesn't double-send). First-tick send
also repairs the attach-time last-snapshot-wins ambiguity. Snapshot
export extracted and shared with the F29 broadcast; per-fid state
cleaned on both detach paths.
2. (High, wider than reported) 'LSP doesn't activate on navigate':
switch_active_buffer clears the window's overlays, and the runtime
dedup tables (highlighted_buffers, styled_buffers,
diag_viewed_buffers) blocked re-attachment -- so EVERY buffer
switch (plain C-x b included, long-latent) permanently stripped
syntax color, LSP semantic style, and diagnostic underlines;
verified: overlay kinds [syntax-highlight, lsp-style, diagnostic]
-> [] after one away-and-back. Fix: a new additive
buffer.after-switch hook, fired by the window.switch_buffer binding
and find_or_open's existing-buffer branch; syntax.lua and lsp.lua
subscribe and re-push their views (the just-cleared window makes
that exactly-once per switch; fresh loads keep firing after-load).
Regression: tests/overlay_reattach_acceptance.rs (double round-trip
counts exactly one highlight overlay; panel q restores styling).
The daemon follow path is validated live (daemon + GPU) -- its unit
seam is the shared export helper.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>