Skip to content

Commit ad96d42

Browse files
wan9chiclaude
andcommitted
refactor(cache): move the task fs story into crates/vt_fs_fingerprint
The task_fs module already mirrors a standalone crate: lift it out of the engine wholesale so the unsettled read-write-overlap policy has a home that is tested with synthetic traces instead of whole-engine runs. The engine keeps storage, archiving, env tracking, and spawning; rayon, twox-hash, and wax leave its dependency list with the moved code. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent b0276d8 commit ad96d42

19 files changed

Lines changed: 117 additions & 20 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ A monorepo task runner (like Nx/Turbo) with intelligent caching and dependency r
99
- `crates/vt_graph` — Task dependency graph construction and config loading
1010
- `crates/vt_plan` — Execution planning (resolves env vars, working dirs, commands)
1111
- `crates/vt_workspace` — Workspace detection and package dependency graph
12+
- `crates/vt_fs_fingerprint` — Filesystem fingerprinting for task caching (pre-run snapshot, traced-access judgment, cache-entry validation)
1213
- `crates/fspy*` — File system access tracing (9 crates: supervisor, preload libs, platform backends)
1314
- `crates/pty_terminal*` — Cross-platform headless terminal emulator (3 crates)
1415
- `crates/vt_path` — Type-safe absolute/relative path system

Cargo.lock

Lines changed: 23 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ tui-term = "0.3.1"
149149
twox-hash = "2.1.1"
150150
uuid = "1.18.1"
151151
vec1 = "1.12.1"
152+
vt_fs_fingerprint = { path = "crates/vt_fs_fingerprint" }
152153
vt_glob = { path = "crates/vt_glob" }
153154
vt_graph_ser = { path = "crates/vt_graph_ser" }
154155
vt_path = { path = "crates/vt_path" }

crates/vt/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ once_cell = { workspace = true }
2525
owo-colors = { workspace = true }
2626
petgraph = { workspace = true }
2727
pty_terminal_test_client = { workspace = true }
28-
rayon = { workspace = true }
2928
rusqlite = { workspace = true, features = ["bundled"] }
3029
rustc-hash = { workspace = true }
3130
serde = { workspace = true, features = ["derive", "rc"] }
@@ -43,9 +42,9 @@ tokio = { workspace = true, features = [
4342
] }
4443
tokio-util = { workspace = true }
4544
tracing = { workspace = true }
46-
twox-hash = { workspace = true }
4745
materialized_artifact = { workspace = true }
4846
uuid = { workspace = true, features = ["v4"] }
47+
vt_fs_fingerprint = { workspace = true }
4948
vt_glob = { workspace = true }
5049
vt_path = { workspace = true }
5150
vt_select = { workspace = true }
@@ -55,7 +54,6 @@ vt_ipc_shared = { workspace = true }
5554
vt_plan = { workspace = true }
5655
vt_server = { workspace = true }
5756
vt_workspace = { workspace = true }
58-
wax = { workspace = true }
5957
zstd = { workspace = true }
6058

6159
# Artifact build-deps must be unconditional: cargo's resolver panics when

crates/vt/docs/task-cache.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -567,18 +567,19 @@ Each `&&` separated command is cached independently. If only terser config chang
567567
### Core Cache Components
568568

569569
```
570+
crates/vt_fs_fingerprint/src/ # The run's filesystem story (own crate)
571+
├── task_run.rs # TaskFs (pre_run/post_run), Conclusion
572+
├── fingerprint.rs # InputFingerprints, PathFingerprint, InputChange
573+
├── tracked_accesses.rs # fspy access normalization
574+
├── glob.rs # Glob walking + input hashing
575+
└── hash.rs # Content hashing
576+
570577
crates/vt/src/session/
571578
├── cache/
572579
│ ├── mod.rs # ExecutionCache, CacheEntryKey/Value, FingerprintMismatch
573580
│ └── display.rs # Cache status display formatting
574581
├── execute/
575582
│ ├── mod.rs # execute_spawn, SpawnOutcome
576-
│ ├── task_fs/ # The run's filesystem story
577-
│ │ ├── task_run.rs # TaskFs (pre_run/post_run), Conclusion
578-
│ │ ├── fingerprint.rs # InputFingerprints, PathFingerprint, InputChange
579-
│ │ ├── tracked_accesses.rs # fspy access normalization
580-
│ │ ├── glob.rs # Glob walking + input hashing
581-
│ │ └── hash.rs # Content hashing
582583
│ ├── cache_update.rs # Post-run cache update decision
583584
│ ├── post_run.rs # TrackedEnvFingerprints (tracked env validation)
584585
│ └── spawn.rs # spawn_with_tracking, fspy integration

crates/vt/src/session/cache/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub use display::{
1414
use rusqlite::{Connection, OptionalExtension as _};
1515
use serde::{Deserialize, Serialize};
1616
use tokio::sync::Mutex;
17+
pub use vt_fs_fingerprint::InputChangeKind;
18+
use vt_fs_fingerprint::{InputChange, InputFingerprints};
1719
use vt_graph::config::ResolvedGlobConfig;
1820
use vt_path::{AbsolutePath, RelativePathBuf};
1921
use vt_plan::cache_metadata::{CacheMetadata, ExecutionCacheKey, SpawnFingerprint};
@@ -25,11 +27,9 @@ use wincode::{
2527
io::{Reader, Writer},
2628
};
2729

28-
pub use super::execute::task_fs::InputChangeKind;
2930
use super::execute::{
3031
pipe::StdOutput,
3132
post_run::{PostRunMismatch, TrackedEnvFingerprints, TrackedEnvQuery},
32-
task_fs::{InputChange, InputFingerprints},
3333
};
3434

3535
const TASK_CACHE_PREALLOCATION_SIZE_LIMIT: usize = 256 * 1024 * 1024;

crates/vt/src/session/execute/cache_update.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::{collections::BTreeMap, sync::Arc, time::Duration};
55

66
use rustc_hash::FxHashSet;
7+
use vt_fs_fingerprint::{Conclusion, PostRunError};
78
use vt_path::{AbsolutePath, RelativePathBuf};
89
use vt_plan::cache_metadata::{CacheMetadata, EnvValueHash};
910
use vt_server::Reports;
@@ -13,7 +14,6 @@ use super::{
1314
CacheState,
1415
post_run::{TrackedEnvFingerprints, TrackedEnvQuery},
1516
spawn::ChildOutcome,
16-
task_fs::{Conclusion, PostRunError},
1717
};
1818
use crate::session::{
1919
cache::{CacheEntryValue, ExecutionCache, archive},

crates/vt/src/session/execute/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ pub mod pipe;
33
pub mod post_run;
44
mod scheduler;
55
pub mod spawn;
6-
pub mod task_fs;
76
#[cfg(windows)]
87
mod win_job;
98

@@ -15,6 +14,7 @@ use std::{
1514

1615
use futures_util::future::LocalBoxFuture;
1716
use tokio_util::sync::CancellationToken;
17+
use vt_fs_fingerprint::TaskFs;
1818
use vt_ipc_shared::NODE_CLIENT_PATH_ENV_NAME;
1919
use vt_path::AbsolutePath;
2020
use vt_plan::{SpawnExecution, cache_metadata::CacheMetadata};
@@ -23,7 +23,6 @@ use vt_server::{Recorder, Reports, ServerHandle, StopAccepting, serve};
2323
use self::{
2424
pipe::{PipeSinks, StdOutput, pipe_stdio},
2525
spawn::{ChildHandle, ChildOutcome, SpawnStdio, spawn},
26-
task_fs::TaskFs,
2726
};
2827
use super::{
2928
cache::{CacheEntryValue, CacheMiss, ExecutionCache, archive},

crates/vt/src/session/execute/post_run.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Post-run environment fingerprinting: env values and bulk env queries
22
//! observed by runner-aware tools during execution, validated again at cache
33
//! lookup. The filesystem half of post-run fingerprinting lives in
4-
//! [`super::task_fs`].
4+
//! [`vt_fs_fingerprint`].
55
66
use std::{collections::BTreeMap, ffi::OsStr, sync::Arc};
77

crates/vt/src/session/execute/spawn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! [`spawn`] does one thing: hand back the child's stdio pipes plus a
44
//! cancellation-aware `wait` future. Draining the pipes is [`super::pipe`]'s
5-
//! job; the raw path accesses are judged by [`super::task_fs`] during the
5+
//! job; the raw path accesses are judged by [`vt_fs_fingerprint`] during the
66
//! cache update.
77
88
use std::{ffi::OsStr, io, process::Stdio};

0 commit comments

Comments
 (0)