Bug
The full Go contract suite can finish mount tests before their background watcher/writeback goroutines have stopped. Go then races t.TempDir() cleanup against new writes and fails with unlinkat ...: directory not empty.
Hosted evidence
Run: https://github.com/AgentWorkforce/relayfile/actions/runs/34015241241/job/101437753162
Two independent failures occurred in one run:
cmd/relayfile-cli: TestMountLoopStartsWatcherBeforeBlockedInitialBootstrap
internal/mountsync: TestHandleLocalChangesBatchesElevenFilesAndDefersPendingReceipts
Both failed only during testing.go TempDir removal with directory not empty; surrounding package tests otherwise ran to completion. This is unrelated to the workflow-only changes in relayfile#468 and is consistent with a background lifecycle leak.
Expected
Tests cancel and join every watcher, daemon, timer, and writeback goroutine before returning, so TempDir cleanup is deterministic.
Acceptance
- Add lifecycle regressions that fail if a writer survives test teardown.
- Ensure all affected goroutines/processes expose and use a join/termination boundary.
- Run the affected tests repeatedly and with
-race where practical.
go test ./... passes repeatedly in hosted Linux CI without rerunning.
Bug
The full Go contract suite can finish mount tests before their background watcher/writeback goroutines have stopped. Go then races
t.TempDir()cleanup against new writes and fails withunlinkat ...: directory not empty.Hosted evidence
Run: https://github.com/AgentWorkforce/relayfile/actions/runs/34015241241/job/101437753162
Two independent failures occurred in one run:
cmd/relayfile-cli:TestMountLoopStartsWatcherBeforeBlockedInitialBootstrapinternal/mountsync:TestHandleLocalChangesBatchesElevenFilesAndDefersPendingReceiptsBoth failed only during
testing.goTempDir removal withdirectory not empty; surrounding package tests otherwise ran to completion. This is unrelated to the workflow-only changes in relayfile#468 and is consistent with a background lifecycle leak.Expected
Tests cancel and join every watcher, daemon, timer, and writeback goroutine before returning, so TempDir cleanup is deterministic.
Acceptance
-racewhere practical.go test ./...passes repeatedly in hosted Linux CI without rerunning.