Files
ServerKit/backend/app
Juan DenisandClaude Opus 4.7 5541504ef8 Fix the systemic silent failures: empty log, dead WS, locked-out agents
Four real root causes that produced the symptoms we've been chasing:

1. agent.log was 0 bytes because io.MultiWriter aborts the entire
   write chain on the first writer error. On Windows services where
   os.Stdout writes can transiently fail, the lumberjack file writer
   never got the slog records — events.json (direct os.File) worked
   fine while agent.log silently stayed empty for the entire process
   lifetime. Replace io.MultiWriter with resilientWriter that
   independently writes to each underlying writer and swallows
   per-writer errors. Also surface logger init failures (MkdirAll,
   OpenFile) instead of silently falling back to stdout-only, and
   emit an explicit "logger initialized" startup line so an empty
   file is now an obvious bug rather than ambiguous.

2. WS connections appeared to "drop every 2-3 minutes" but actually
   the read loop had no ReadDeadline at all — ReadMessage() blocked
   forever on a network-killed connection until the OS-level TCP
   timeout fired, which is exactly what produced the
   ws_connected → ws_disconnected pattern in events.json. Add
   readWait = pingInterval*2.5 + 5s, reset it on every successful
   read AND in SetPongHandler. Now CF/ngrok killing the conn at the
   network layer (without sending a WS close frame) is detected
   within seconds, the read errors out cleanly, the Manager's flap
   detector counts it, and we fall back to polling far faster.

3. Newly-registered servers defaulted to permissions=[] which made
   every action 403. The user hit "Permission denied" on
   docker:image:list, system:info, agent:recapabilities, and probably
   half the rest. Default to ['*'] when no profile or list is
   specified — single-tenant deployments shouldn't need to manually
   open a profile editor before anything works.

4. Migration 006 retroactively fixes already-stuck servers: any row
   with permissions=[] gets ['*']. Non-empty admin-defined ACLs are
   left alone. Solves "I registered before this fix and now I can't
   do anything" without bulldozing legitimate configurations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 07:06:58 -04:00
..