Skip to content

feat: skip caching tasks that modify their inputs#248

Merged
branchseer merged 4 commits intomainfrom
feat/dedup-postrun-fingerprint
Mar 15, 2026
Merged

feat: skip caching tasks that modify their inputs#248
branchseer merged 4 commits intomainfrom
feat/dedup-postrun-fingerprint

Conversation

@branchseer
Copy link
Member

@branchseer branchseer commented Mar 14, 2026

Summary

Tasks like formatters (prettier --write) and auto-fix linters (eslint --fix) read and write the same files. Caching these tasks doesn't work — the stored input hash goes stale after every run, causing the cache to always miss next time.

We now detect when a task reads and writes the same file (via fspy) and skip caching it entirely. The user sees a clear message explaining why.

Also, files already covered by explicit glob inputs (input: ["src/**"]) are no longer fingerprinted again in the post-run check, saving storage and I/O.

Output examples

Single task that modifies its input:

---
vp run: app#format not cached because it modified its input. (Run `vp run --last-details` for full details)

Multiple tasks, one modifies its input:

---
vp run: 1/2 cache hit (50%), 102ms saved. app#format not cached because it modified its input. (Run `vp run --last-details` for full details)

Multiple tasks, several modify their inputs:

---
vp run: 1/3 cache hit (33%), 85ms saved. app#format (and 1 more) not cached because they modified their inputs. (Run `vp run --last-details` for full details)

--verbose / --last-details shows the specific file in the full summary:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Vite+ Task Runner • Execution Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Statistics:   1 tasks • 0 cache hits • 1 cache misses
Performance:  0% cache hit rate

Task Details:
────────────────────────────────────────────────
  [1] app#format: ~/packages/app$ prettier --write src/index.ts ✓
      → Not cached: read and wrote 'packages/app/src/index.ts'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Test plan

  • cargo test -p vite_task — unit tests
  • cargo test -p vite_task_bin --test e2e_snapshots — E2E snapshot tests covering:
    • Single read-write task (separate read+write opens)
    • Single O_RDWR open (single syscall)
    • Multi-task with mixed cacheable and non-cacheable tasks
    • Verbose output showing the overlapping path
  • cargo clippy -- -D warnings — no new warnings

🤖 Generated with Claude Code

@branchseer branchseer changed the title feat: skip caching tasks that modify their inputs and deduplicate postrun fingerprint feat: skip caching tasks that modify their inputs Mar 14, 2026
Copy link
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@branchseer branchseer marked this pull request as ready for review March 14, 2026 13:30
branchseer and others added 3 commits March 14, 2026 21:33
…trun fingerprint

Two changes to improve cache correctness and performance:

1. If fspy detects a task both read and wrote the same file, skip cache
   storage (InputModified). Caching such tasks is unsound because the
   prerun glob hashes become stale.

2. Skip paths already in globbed_inputs when building the postrun
   fingerprint. This avoids redundant storage and double-validation on
   cache hit checks. Safe because rule 1 guarantees no input was modified.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Surface the read-write overlap detection in both compact and full
summaries so users understand why their task wasn't cached.

Compact: "app#build not cached because it modified its input."
Full:    "→ Not cached: read and wrote 'src/data.txt'"

Thread CacheUpdateStatus through the reporter so InputModified
(with the overlapping path) reaches SpawnOutcome::Success and
the summary rendering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a `touch-file` tool that opens a file with O_RDWR in a single
syscall (unlike replace-file-content which uses separate read/write
opens). This tests that fspy correctly detects a single O_RDWR open
as both READ and WRITE for the input-modified cache skip.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@branchseer branchseer force-pushed the feat/dedup-postrun-fingerprint branch from cd16a68 to eec87f0 Compare March 14, 2026 13:33
@branchseer branchseer requested review from cpojer and fengmk2 March 14, 2026 13:36
@branchseer branchseer merged commit 665d553 into main Mar 15, 2026
21 of 25 checks passed
@branchseer branchseer deleted the feat/dedup-postrun-fingerprint branch March 15, 2026 02:00
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.

2 participants