feat(cache): add explicit inputs config for cache fingerprinting#104
Merged
branchseer merged 32 commits intomainfrom Mar 9, 2026
Merged
feat(cache): add explicit inputs config for cache fingerprinting#104branchseer merged 32 commits intomainfrom
branchseer merged 32 commits intomainfrom
Conversation
Member
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
2068511 to
fa3e209
Compare
292e8ee to
bf60d66
Compare
d0e61ec to
379326a
Compare
419d488 to
01a285f
Compare
This was referenced Mar 5, 2026
ebb616f to
af0900f
Compare
0b05438 to
cacdc11
Compare
cacdc11 to
d36735f
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds an explicit inputs field to the task configuration for controlling cache fingerprinting. Instead of always using fspy (file system spy) to infer file dependencies, users can now specify glob patterns to explicitly declare which files should trigger cache invalidation, or use a combination of auto-inference and explicit patterns.
Changes:
- Add
UserInputEntry,UserInputsConfig, andResolvedInputConfigtypes for parsing and normalizing user input configuration, with support for glob patterns, auto-inference directives, and negative patterns - Replace the monolithic
SpawnTrackResultwith separatestd_outputsandTrackedPathAccessesto decouple output capturing from fspy tracking, and introducePreRunFingerprint(combining spawn fingerprint + globbed inputs) as the new cache key, replacing the oldSpawnFingerprint-based key - Add
glob_inputs.rsmodule for walking glob patterns and hashing files, with comprehensive unit tests and e2e test fixtures covering all input configuration combinations including subpackage and cross-package (..) scenarios
Reviewed changes
Copilot reviewed 137 out of 141 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
crates/vite_task_graph/src/config/user.rs |
Adds UserInputEntry enum, UserInputsConfig type, inputs field to EnabledCacheConfig, and unit tests |
crates/vite_task_graph/src/config/mod.rs |
Adds ResolvedInputConfig with from_user_config resolution logic and unit tests |
crates/vite_task_graph/run-config.ts |
TypeScript type definition for the inputs field |
crates/vite_task_graph/Cargo.toml |
Adds bincode dependency for ResolvedInputConfig serialization |
crates/vite_task_plan/src/cache_metadata.rs |
Adds input_config and glob_base to CacheMetadata, removes fingerprint_ignores from SpawnFingerprint |
crates/vite_task_plan/src/plan.rs |
Passes package_path to plan_spawn_execution for glob resolution base |
crates/vite_task/src/session/execute/glob_inputs.rs |
New module for glob-based input file discovery and hashing |
crates/vite_task/src/session/execute/fingerprint.rs |
Updates PostRunFingerprint to use inferred_inputs with negative glob filtering |
crates/vite_task/src/session/execute/spawn.rs |
Splits SpawnTrackResult into TrackedPathAccesses and separate std_outputs |
crates/vite_task/src/session/execute/mod.rs |
Orchestrates globbed input computation, conditional fspy tracking, and updated cache operations |
crates/vite_task/src/session/cache/mod.rs |
Introduces PreRunFingerprint as cache key, bumps DB version to 7, updates cache hit/update logic |
crates/vite_task/src/session/cache/display.rs |
Removes FingerprintIgnoreAdded/Removed change variants |
crates/vite_task/Cargo.toml |
Replaces vite_glob with wax and path-clean, adds tempfile for tests |
crates/fspy/src/unix/mod.rs |
Sets FSPY=1 env when fspy tracking is enabled |
crates/fspy/src/windows/mod.rs |
Sets FSPY=1 env when fspy tracking is enabled |
packages/tools/src/print-file.ts |
Supports reading multiple files for e2e test commands |
docs/inputs.md |
Comprehensive documentation for the inputs configuration |
crates/vite_task_bin/src/main.rs |
Adds inputs: None to default EnabledCacheConfig |
crates/vite_task_bin/src/lib.rs |
Adds inputs: None to synthesized EnabledCacheConfig instances |
| E2e fixture files | Test fixtures for inputs-cache-test, glob-base-test, inputs-negative-glob-subpackage |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
a3484e6 to
d1320a2
Compare
Add `inputs` field to task configuration supporting:
- Explicit glob patterns: `inputs: ["src/**/*.ts"]`
- Auto-inference from fspy: `inputs: [{ auto: true }]`
- Negative patterns: `inputs: ["src/**", "!**/*.test.ts"]`
- Mixed mode: `inputs: ["package.json", { auto: true }, "!dist/**"]`
- Empty array to disable file tracking: `inputs: []`
Key changes:
- Add `ResolvedInputConfig` to parse and normalize user input config
- Add `glob_inputs.rs` for walking glob patterns and hashing files
- Update `PreRunFingerprint` to include `input_config` and `glob_base`
- Bump cache DB version to 6 for new fingerprint structure
- Add comprehensive e2e tests for all input combinations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…nings Drop redundant suffixes from FingerprintMismatch variants (e.g. SpawnFingerprintMismatch → SpawnFingerprint) to fix enum_variant_names lint. Also fix if_not_else and doc_markdown warnings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… framing The cache key and value are no longer conceptually divided as pre-run vs post-run fingerprints. Update doc comments to describe what each struct contains directly, and remove stale `# Arguments` sections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the ResolvedNegativeGlob tuple type alias with a proper AnchoredGlob struct that encapsulates glob partitioning, path cleaning, and prefix-based matching behind a clean API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Walk positive globs using wax, rerooting negative globs onto a common ancestor so wax can prune entire directory subtrees via `.not()`. This handles all prefix relationship cases (equal, ancestor, descendant, unrelated) correctly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move path_bridge, rerooted_pattern, common_ancestor, and escape_glob from walk.rs into anchored.rs, exposed as AnchoredGlob::reroot() and has_related_prefix() methods. This simplifies the walk module by encapsulating glob rerooting within the type that owns the data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move AnchoredGlob and the filesystem walk logic out of vite_glob, leaving only the core glob matching and error types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…aph stage Move glob pattern resolution from execution time to task graph construction, making all glob patterns workspace-root-relative. This eliminates AnchoredGlob usage, removes glob_base from CacheMetadata/CacheEntryKey, and simplifies the execution pipeline. Key changes: - Add resolve_glob_to_workspace_relative() in vite_task_graph config - Remove glob_base field from CacheMetadata and CacheEntryKey - Update glob_inputs to work with workspace-root-relative patterns - Update spawn.rs negative glob filtering with path cleaning - Bump cache DB version from 9 to 10 - Remove vite_glob dependency from vite_task - Remove plan file https://claude.ai/code/session_01PR9yhnScRoVoHUcviV47u5
Move path_clean::PathClean normalization into the strip_path_prefix callback so all fspy-reported paths are clean from the start. This removes the need for separate cleaning in the negative glob filter and in PostRunFingerprint::create. https://claude.ai/code/session_01PR9yhnScRoVoHUcviV47u5
Move .git filtering and negative glob filtering into the strip_path_prefix callback alongside path cleaning, so rejected paths return None immediately in one pass. https://claude.ai/code/session_01PR9yhnScRoVoHUcviV47u5
The cleaned path (with `..` normalized) is used solely for matching against negative globs. The original stripped path is returned and stored in the fingerprint, keeping create/validate consistent. Restore fingerprint.rs to use the path as-is since it already contains the original fspy-reported relative path. https://claude.ai/code/session_01PR9yhnScRoVoHUcviV47u5
…irect path_clean usage Move path_clean dependency into vite_path and expose it through typed clean() methods on AbsolutePath and RelativePath, documenting the symlink limitation of purely lexical normalization. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…kspace_relative RelativePathBuf guarantees valid UTF-8 with forward slashes, so the manual to_str() check and backslash normalization are no longer needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…x .not() combinator Replace manual partition()+branch logic with direct glob.walk(workspace_root), and replace manual is_match negative filtering with wax's FileIterator::not(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fstat(fd) uses F_GETPATH on macOS which returns canonical paths, while open(path) preserves raw relative paths. This caused the same file to be recorded under two different paths, leading to non-deterministic cache miss messages via rayon's find_map_any. Also simplify glob_inputs negation handling (always use .not()) and add e2e test for glob meta characters in package paths (wax::escape). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verifies that inputs: ["src"] (a directory, not a glob) fingerprints nothing — file changes inside and folder deletion are both cache hits. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Input patterns like `"src/"` are now treated as `"src/**"`, matching all files recursively under that directory. This applies to both positive and negative globs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-8 paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bc92cfd to
4311180
Compare
fspy reports paths with `..` components (e.g. `packages/sub-pkg/../shared/src/utils.ts`) on macOS but normalized paths on Linux/Windows. Always clean `..` before storing to ensure consistent cache miss messages across platforms. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 tasks
fengmk2
approved these changes
Mar 9, 2026
Member
Author
Merge activity
|
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.

Summary
inputsfield to task configuration for explicit cache fingerprinting/in globs to/**(e.g.,"src/"→"src/**")"src"without/) match nothing — only files are fingerprintedfstatinterception in fspy (fd was already tracked viaopen)Input modes
inputs: ["src/**/*.ts"]inputs: [{ "auto": true }]inputs: ["src/**", "!**/*.test.ts"]inputs: ["src/"](expands to"src/**")inputs: ["package.json", { "auto": true }, "!dist/**"]inputs: []Test plan
inputs-trailing-slashverifiessrc/→src/**and!dist/→dist/**folder-slash-input— cache miss on direct and nested file changes, hit on outsidefolder-input— bare directory name fingerprints nothingpackages/[lib])..globs in subpackages🤖 Generated with Claude Code