Skip to content

fix(clean): sweep abandoned Foundation temp directories - #38

Merged
aicayzer merged 1 commit into
mainfrom
fix/sweep-foundation-item-replacement-dirs
Aug 26, 2026
Merged

fix(clean): sweep abandoned Foundation temp directories#38
aicayzer merged 1 commit into
mainfrom
fix/sweep-foundation-item-replacement-dirs

Conversation

@aicayzer

Copy link
Copy Markdown
Owner

Closes #37.

Opening a SwiftData store on a file URL makes Foundation create an item-replacement directory in the per-user temp root and never remove it — roughly six per run of a Swift test suite that touches a file-backed container. They accumulate without bound, and macOS reports that path as "System Data", so nothing an operator looks at shows them growing.

The existing sweep never sees them. Runner temp is redirected per runner and wiped wholesale, which is safe precisely because nothing else writes there; these land in the shared per-user root instead, from CI and local development alike.

So this sits with the dangling-Docker-volume prune, which is already machine-wide rather than per-runner.

What makes it safe on a shared path

  • Only entries matching Foundation's own name. A wildcard sweep of that directory would delete another process's working directory.
  • Only entries untouched for three days. These exist for the moment of an atomic file replacement, so one that has sat that long was abandoned by a process no longer running, and anything a live job created is far too recent to match.

Three days rather than something tighter is deliberate: it bounds the growth, which is what the defect is, without betting that nothing on a shared machine holds one open for a while.

Verified

Measured on the development machine: 711 entries present, 18 older than three days, 525 recent ones untouched, and nothing outside the TemporaryDirectory.* pattern matched.

The block itself was exercised against a sandbox containing two old Foundation directories, one recent one, and one old directory that is not Foundation's. It removed the two, kept the recent one, and kept the one that was not ours — which is the property that matters on a shared path.

bash -n clean. runpool clean was not run against the live pools, since it prunes real runner state and CI was active.

Opening a SwiftData store on a file URL makes Foundation create an item
replacement directory in the per-user temp root and never remove it,
roughly six per run of a Swift test suite that touches a file-backed
container. They accumulate without bound, and macOS reports that path as
"System Data", so nothing an operator looks at shows them growing. One
reading passed ten thousand entries across two gigabytes.

The existing sweep never sees them. Runner temp is redirected per runner
and wiped wholesale, which is safe precisely because nothing else writes
there; these land in the shared per-user root instead, from CI and from
local development alike.

So this sits with the docker volume prune, which is already machine-wide
housekeeping rather than per-runner. Two things keep it safe on a shared
path: only entries matching Foundation's own name are touched, and only
ones untouched for three days. These directories exist for the moment of
an atomic file replacement, so one that has sat that long was abandoned
by a process no longer running, and anything a live job created is far
too recent to match.

Three days rather than something tighter is deliberate. It bounds the
growth, which is what the defect actually is, without betting that no
process on a shared machine holds one open for a while.
@aicayzer
aicayzer merged commit cc132b4 into main Aug 26, 2026
2 checks passed
@aicayzer
aicayzer deleted the fix/sweep-foundation-item-replacement-dirs branch August 26, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

abandoned Foundation temp directories accumulate in the user temp root and the clean never sees them

1 participant