Repository navigation
Conversation
wan9chi
force-pushed
the
feat/cache-rename-targets
branch
from
October 30, 2026 03:19
430963c to
b139ee7
Compare
fspy benchmarklinuxmacoswindows |
wan9chi
force-pushed
the
feat/cache-rename-targets
branch
from
October 30, 2026 04:07
b139ee7 to
8a1becb
Compare
wan9chi
force-pushed
the
feat/cache-rename-targets
branch
from
October 30, 2026 06:31
8a1becb to
6af0c77
Compare
…t miss Two cases for a task that writes under a temporary name, renames it into place and reads it back. In `folder_renamed_into_place`, the task writes `tmp/a.js`, renames `tmp` to `deps` and reads `deps/a.js`, through `vtt fs`, which gets a `rename` operation, like Vite's dependency optimizer renaming `deps_temp_*` to `deps`. In `vitest_fs_module_cache`, Vitest 5 with `fsModuleCache` writes each transformed module to `node_modules/.vitest-cache/.tmp-*`, renames it to a hashed name in the same folder and reads it back. Today the renamed paths are plain inputs, since a rename isn't recorded as a write, so removing them, as on a clean checkout, is a cache miss, and they aren't in the cached outputs. The Vitest case removes `node_modules/.vitest-cache` and `node_modules/.vite/vitest`, not all of `node_modules/.vite`, which holds the task cache too, and recreates nothing, as on a clean checkout. Several inputs are then missing, and vt names whichever its parallel validation finds first, so the next step redacts its miss reason. The e2e harness redacts SHA-1 hex digests, since Vitest's entry names hash the module's absolute path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wan9chi
force-pushed
the
feat/cache-rename-targets
branch
from
October 30, 2026 07:08
6af0c77 to
a446e8f
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a446e8f. Configure here.
| add_files_under(&path, workspace_root, &mut written); | ||
| } else { | ||
| written.insert(path); | ||
| } |
There was a problem hiding this comment.
Failed folder rename steals existing tree
Medium Severity
Rename destinations are recorded before the syscall, and any path that is a directory after the run is expanded into written. When the rename fails and that directory already existed, every file under it is treated as a rebuildable output even though the task did not place it there.
Reviewed by Cursor Bugbot for commit a446e8f. Configure here.
A task that writes under a temporary name and renames the result into place, like Vitest's `fsModuleCache` renaming each `.tmp-*` file to its hashed name, or Vite's dependency optimizer renaming `deps_temp_*` to `deps`, left those paths as plain inputs: fspy recorded nothing for a rename, so they weren't archived, a hit didn't restore them, and removing them, as on a clean checkout, was a cache miss. fspy now records the destination of a rename as a rename target, a new access kind, since it may be a whole folder, and the destination of a hard link, always a file, as a write. Both are recorded before the call, so a failed call is recorded too. The source of a rename needs no record. - Unix preload: `rename`, `renameat`, `link` and `linkat`, plus `renameat2` on Linux and `renamex_np` and `renameatx_np` on macOS. - Linux seccomp supervisor, for static binaries: `renameat`, `renameat2` and `linkat`, plus `rename` and `link` on x86_64. - Windows: `NtSetInformationFile` with `FileRenameInformation(Ex)` or `FileLinkInformation(Ex)`, where `MoveFileExW`, `CreateHardLinkW` and `SetFileInformationByHandle` end. `Rebuildable` now takes rename targets next to writes. A rename target that is a file counts as written; one that is a folder after the run stands for every file or symlink under it, recursively, while the folder and the folders in it don't count as written. A write record on a path that is a folder, from opening it with write access, is ignored, so it can't pull in the files under it. The archive takes the written files before output exclusions and `ignoreOutput` filter them, so the files of a renamed folder are restored by a hit, may be missing on the next run, and make their folder rebuildable. The folder a task filled and renamed away, like Vite's `deps_temp_*`, is gone after the run, so a probe of it was stored as a plain `NotFound` input with a new name in every entry. A path that is gone after the run but that the task wrote in now counts as written: the task made or removed it. Validation doesn't change, since a stored `NotFound` must be missing either way. A `.DS_Store` under a renamed folder doesn't count, as in listings. Written paths aren't stat'd: a written path that is a folder only needs telling apart where the task read it, so only a read that fingerprints as a folder is checked; rename targets are, to find the folders to expand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wan9chi
force-pushed
the
feat/cache-rename-targets
branch
from
November 1, 2026 11:55
a446e8f to
67fd287
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Motivation
Many tools write under a temporary name and rename the result into place:
fsModuleCacherenames each.tmp-*file to its hashed name.deps_temp_*todeps..astro/*.tmpand renames them.fspy records nothing for a rename, so those files aren't outputs. A hit doesn't restore them, and since the task reads them back, removing them is a miss.
Changes
RenameTarget, since it may be a whole folder. A hard-link destination, always a file, is recorded as a write. Both are recorded before the call. This covers the Unix preload, the Linux seccomp supervisor and WindowsNtSetInformationFile.deps_temp_*, is gone after the run, so a probe of it was stored as a plainNotFoundinput with a new random name in every entry. A path that is gone after the run but that the task wrote in now counts as written. It is still fingerprinted as missing, so validation doesn't change.E2E cases:
folder_renamed_into_place(synthetic,vtt fs rename) andvitest_fs_module_cache(Vitest 5 withfsModuleCache, true clean checkout, its today's miss line redacted with #912'sredact).Part of a stack that lets automatic tracking cache tasks which read their own outputs and list the folders holding them, so they also hit on a clean checkout.
Closes #908.
🤖 Generated with Claude Code
Note
Medium Risk
Changes cross-platform fspy hooks and post-run fingerprint/output archiving; incorrect rename handling could cause stale cache hits or missed restores, but scope is filesystem tracking rather than auth or data exfiltration.
Overview
File-access tracking now records rename destinations as
RenameTargetand hard-link destinations as writes, on Unix (preload + seccomp), Windows (NtSetInformationFile), with IPC/schema updates and tests. Destinations are logged even when the syscall fails.Cache behavior treats a renamed file as written output; a renamed folder expands to every file/symlink underneath for archiving and “rebuildable” input logic. Spurious folder write records from opening a directory for write are ignored so reads of that folder still fingerprint correctly.
Adds
vtt fs rename, e2e coverage for folder rename-into-place (Vite-styledeps), a VitestfsModuleCachefixture, and a changelog entry: cache hits restore and tolerate missing rename/hard-link outputs on a clean checkout.Reviewed by Cursor Bugbot for commit a446e8f. Bugbot is set up for automated code reviews on this repo. Configure here.