The lease heartbeat and settle failures, the log sink and rotation
fallbacks, the runtime env getters, the public API summary edges, the
admin-only permission level and the WebSocket handler rejection had no
spec, which took six domains under their coverage floor.
Every log line ran existsSync, statSync and appendFileSync on the event
loop before it returned. On a slow data volume (an SMB or NFS bind mount
on a NAS) that stalled every request that logged, and rotation renamed
files without checking whether another process sharing data/logs had
rotated already.
The file half of the logger is now BufferedLogFile: a line is queued in
memory and the queue goes out with one appendFile per batch, through a
single serial chain, so no append runs while files are being renamed. The
files and the rotation are the same as before (trek.log rotates to .1 at
10 MB, five files in total), but the size is re-read before a rotation
and a file another process already rotated is left alone. A stalled disk
costs dropped lines with a count instead of unbounded memory, a failed
write is reported instead of thrown, and index.ts writes whatever is
still queued synchronously when the process exits.