From 05cbf2269a1e4695164c1185ed6cf350d407a1fe Mon Sep 17 00:00:00 2001 From: matthew-pilot Date: Sun, 19 Jul 2026 18:50:38 +0000 Subject: [PATCH] fix(dataexchange): filter subdirs before inbox eviction early check (PILOT-183) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The evictInboxOverflow function's early-return check used the raw os.ReadDir entry count (including subdirectories) to decide whether eviction is needed. A directory at inboxMaxFiles + 1 entries (where the +1 is a subdir) would skip eviction entirely, even though only maxFiles of real files exist — allowing the real file count to grow unchecked on subsequent saves. Fix: move the IsDir() filter before the early-return len check, so both guards operate on file-only entries. The byte-based eviction path (evictInboxOverflowByBytes) was already correct. Closes PILOT-183 --- service.go | 4 +--- zz_service_errors_test.go | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/service.go b/service.go index c500d23..8f21320 100644 --- a/service.go +++ b/service.go @@ -509,9 +509,7 @@ func (s *Service) evictInboxOverflow(dir string) { slog.Debug("inbox evict: readdir", "dir", dir, "err", err) return } - if len(entries) <= maxFiles { - return - } + // Filter out subdirectories — they consume no inbox capacity. type aged struct { name string mod time.Time diff --git a/zz_service_errors_test.go b/zz_service_errors_test.go index 42beb64..12a9a06 100644 --- a/zz_service_errors_test.go +++ b/zz_service_errors_test.go @@ -212,9 +212,8 @@ func TestService_Stop_CtxCancelled(t *testing.T) { // (`len(files) <= cap`) correctly short-circuits so no real file is wrongly // evicted just because a subdirectory inflated the entry count. // -// REMOVE THIS COMMENT WHEN PILOT-183 LANDS: the fix will move the -// IsDir() filter ABOVE the first early-return so both checks operate on -// the same population. +// PILOT-183 FIX LANDED: the IsDir() filter now runs before the +// early-return check, so both guards operate on file-only entries. func TestEvictInboxOverflow_PILOT183_SubdirMixedWithFiles(t *testing.T) { t.Parallel() tmp := t.TempDir()