Add len(b.data) > 0 guard to prevent infinite loop when an empty linked
buffer is reachable. With the guard false, the normal path handles empty
buffers safely via the existing t < b.start || idx >= len(b.data) check.
Add regression test TestStatsFastPathThenPartialTail to pin the boundary:
three-buffer chain where earlier buffers are fully covered (fast path) and
the last buffer is partially covered (normal path).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MemoryUsageTracker freed all buffers older than the retention cutoff on
every tick whenever the last retention pass had excluded used nodes,
regardless of memory pressure — discarding the history kept in memory
for long-running jobs. Buffers are now only reclaimed by the existing
emergency path once memory usage exceeds the configured cap. The
now-unused selectorsExcluded state is removed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Setting the provider after Init left the checkpoint restore inside Init
without job information and forced callers to pre-call InitMetrics and
SetNodeProvider in the right order. Init now receives the provider as a
parameter and injects it before the restore, so the ordering is enforced
by the signature. SetNodeProvider remains for callers that do not run
Init (tests, -cleanup-checkpoints).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The -cleanup-checkpoints CLI flag called CleanupCheckpoints without
initializing the MemoryStore singleton or setting its NodeProvider,
so it silently fell back to legacy clean-everything behavior and
could delete checkpoints for hosts with running jobs. Inject the job
repository as NodeProvider the same way runServer does, so the CLI
path also skips used hosts. Also update SetNodeProvider's doc comment,
which only mentioned Free but is now also consulted by FromCheckpoint
and CleanupCheckpoints.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>