Skip to content

feat(cache): restore output files on cache hit - #321

Closed
wan9chi wants to merge 2 commits into
mainfrom
feat/output-restoration
Closed

feat(cache): restore output files on cache hit#321
wan9chi wants to merge 2 commits into
mainfrom
feat/output-restoration

Conversation

@wan9chi

@wan9chiwan9chi commented Apr 6, 2026

Copy link
Copy Markdown
Member

Previously, a cache hit only replayed terminal output (stdout/stderr). Build artifacts like dist/ were not restored, so downstream tasks or users had to re-run even on a cache hit.

Now, output files written during task execution are archived and restored automatically. The output field reuses the same config types and resolution logic as input (renamed ResolvedInputConfigResolvedGlobConfig to reflect this).

Config examples:

// Default: auto-detect written files (same as input default)
{ "command": "tsc --outDir dist" }
// Explicit globs
{ "command": "tsc", "output": ["dist/**"] }
// Auto with exclusions
{ "command": "webpack", "output": [{ "auto": true }, "!dist/cache/**"] }
// Disable output restoration
{ "command": "vitest run", "output": [] }

Test plan

  • E2E: auto output detection restores files on cache hit
  • E2E: glob output only restores matched files
  • E2E: auto output works with non-auto input
  • E2E: negative output globs exclude files from restoration
  • E2E: changing output config invalidates cache
  • All existing E2E and plan snapshot tests pass
  • cargo clippy -- -D warnings clean

🤖 Generated with Claude Code

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:79f428a501

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +410 to +411
let needs_fspy = cache_metadata.input_config.includes_auto
|| cache_metadata.output_config.includes_auto;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Separate input/output negative filters for auto tracking

This now enables fspy whenever output_config.includes_auto is true, but the filter passed to path tracking is still derived only from input_config.negative_globs, so writes that match input negatives are dropped before output archiving. In execute_spawn, a config like input: [{auto:true}, "!dist/**"] with default auto output will never record dist/** writes in path_writes, causing cache hits to replay logs but fail to restore expected output files.

Useful? React with 👍 / 👎.

sorted_files.sort();

// Create archive with UUID filename
let archive_name: Str = vite_str::format!("{}.tar.zst", uuid::Uuid::new_v4());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clean up superseded output archives on cache overwrite

A fresh UUID archive filename is generated on every successful cache write, but the previous archive file is never removed when the same cache key is updated, so old tarballs become orphaned. Re-running tasks over time will continuously accumulate stale *.tar.zst files in the cache directory and can cause unbounded disk growth even though only the latest archive is reachable from cache.db.

Useful? React with 👍 / 👎.

@wan9chi
wan9chi marked this pull request as draft April 13, 2026 07:25
wan9chi added a commit that referenced this pull request Apr 19, 2026
Archives output files after a successful run and restores them on cache hit. Defaults to automatically tracking files the task writes; accepts globs (e.g. `"dist/**"`), `{ "auto": true }`, and negative patterns (`"!dist/cache/**"`).
Squashed rebase of #321 onto main after the spawn decompose refactor and wincode migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wan9chi
wan9chiforce-pushed the feat/output-restoration branch from 9de20eb to b020bf5CompareApril 19, 2026 14:38
@wan9chi

Copy link
Copy Markdown
MemberAuthor

@codex review

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:b020bf53ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +48 to +51
pub input_config: ResolvedGlobConfig,
/// Resolved output configuration that affects cache restoration.
/// Glob patterns are workspace-root-relative.
pub output_config: ResolvedGlobConfig,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bump cache schema version after key/value layout change

Adding output_config to CacheEntryKey and output_archive to CacheEntryValue changes the serialized blob format, but load_from_path still treats schema version 11 as current. On upgrade with an existing cache.db, old rows are deserialized with the new schema in get_cache_key_by_execution_key/get_by_cache_key, which can fail and surface as a cache lookup error that fails task execution instead of cleanly missing. Please version-bump and reset/migrate old cache rows.

Useful? React with 👍 / 👎.

Comment on lines +433 to +434
if metadata.input_config.includes_auto || metadata.output_config.includes_auto {
// Resolve input negative globs for fspy path filtering

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid inferring input reads when only output auto is enabled

This enables fspy whenever output auto-tracking is on (which is the default when output is omitted), even if input auto-tracking is disabled. The later post-run fingerprint path still consumes path_reads, so tasks that set input: [] or explicit-only inputs unexpectedly regain inferred input dependencies and can miss cache hits due to unrelated reads. Read fingerprinting should remain gated by input_config.includes_auto.

Useful? React with 👍 / 👎.

Comment on lines +438 to +440
.input_config
.negative_globs
.iter()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Stop filtering output auto writes with input negatives

The fspy filter is built from input_config.negative_globs, but TrackedPathAccesses::from_raw applies that filter to writes as well as reads. If a task excludes dist/** from inputs (a common pattern) and relies on default output auto-tracking, writes under dist are dropped before archiving, so cache hits won't restore those outputs. Output write collection needs filtering based on output_config negatives, not input negatives.

Useful? React with 👍 / 👎.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds output file archiving/restoration to the task execution cache so cache hits can restore build artifacts (e.g., dist/) in addition to replaying stdout/stderr.

Changes:

  • Introduces an output cache config (same glob/auto/negative semantics as input) and includes it in cache keys/metadata.
  • Archives resolved output files into tar.zst on successful cache updates and extracts them on cache hits.
  • Updates docs and regenerates plan/e2e snapshots to reflect the new cache behavior and schema.

Reviewed changes

Copilot reviewed 102 out of 103 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
docs/output-restoration.mdNew user-facing documentation for output restoration.
docs/output-restoration-research.mdResearch notes on build-tool compatibility/edge cases.
crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_self_reference/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_no_package_json/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_mutual_recursion/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_multi_command/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_depends_on_passthrough/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_cd_no_skip/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/vpr_shorthand/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/transitive_skip_intermediate/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_in_subpackage/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_in_subpackage/snapshots/query_synthetic_in_subpackage.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_task_with_cache_true_enables_synthetic_cache.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_task_untrackedEnv_inherited_by_synthetic.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_script_cache_false_does_not_affect_expanded_synthetic_cache.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_parent_cache_false_does_not_affect_expanded_query_tasks.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/shell_fallback/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/shell_fallback/snapshots/query_shell_fallback_for_pipe_command.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks_task_no_hook/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks_nested_run/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks_disabled/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/recursive_topological_workspace/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/pnpm_workspace_packages_optional/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/parallel_and_concurrency/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/package_self_dependency/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_tasks/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/query_outer___no_cache_does_not_propagate_into_nested___cache.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/query_outer___cache_propagates_to_nested_run_without_flags.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/query_nested___cache_enables_inner_task_caching.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/input_workspace_base/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/input_trailing_slash/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/filter_workspace/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/extra_args_not_forwarded_to_depends_on/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/extra_args_not_forwarded_to_depends_on/snapshots/query_extra_args_only_reach_requested_task.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/explicit_deps_workspace/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/empty_package_test/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/duplicate_package_names/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/dependency_both_topo_and_explicit/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cycle_dependency/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/conflict_test/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/comprehensive_task_graph/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cd_in_scripts/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cd_in_scripts/snapshots/query_cd_before_vt_run_should_not_affect_expanded_task_cwd.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cd_in_scripts/snapshots/query_cd_before_vt_lint_should_put_synthetic_task_under_cwd.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_true_no_force_enable/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_true_no_force_enable/snapshots/query_task_cached_when_global_cache_true.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_true_no_force_enable/snapshots/query_script_cached_when_global_cache_true.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_tasks_disabled/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_subcommand/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_sharing/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_task_override/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_task_override/snapshots/query_task_cached_by_default.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_task_override/snapshots/query_another_task_cached_by_default.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_enabled/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_default/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_synthetic_task_with_extra_args_in_user_task.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_synthetic_task_in_user_task_with_cwd.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_synthetic_task_in_user_task.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_normal_task_with_extra_args.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_lint_and_echo_with_extra_args.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_echo_and_lint_with_extra_args.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/query___cache_on_task_with_per_task_cache_true_enables_caching.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/query___cache_enables_task_caching_even_when_cache_tasks_is_false.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/query___cache_enables_script_caching.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/additional_env/snapshots/task_graph.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/tests/plan_snapshots/fixtures/additional_env/snapshots/query_tool_synthetic_task_in_user_task.jsoncSnapshot updated to include output_config.
crates/vite_task_plan/src/plan.rsPlumbs output_config into planned cache metadata.
crates/vite_task_plan/src/cache_metadata.rsAdds output_config to CacheMetadata.
crates/vite_task_graph/src/config/user.rsAdds user-facing output field to cache config.
crates/vite_task_graph/src/config/mod.rsResolves output_config; renames to ResolvedGlobConfig.
crates/vite_task_graph/run-config.tsUpdates TS run-config schema to include output.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/vite-task.jsonNew e2e fixture covering output restoration modes.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/src/main.tsFixture source file for cache invalidation tests.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/output_config_change_invalidates_cache.mdNew snapshot: output config change invalidates cache.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/negative_output___excluded_files_not_restored.mdNew snapshot: negative output globs exclude restoration.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/glob_output___only_matched_files_restored.mdNew snapshot: glob outputs restore matched files only.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/auto_output_with_non_auto_input.mdNew snapshot: auto output with explicit input globs.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/auto_output___files_restored_on_cache_hit.mdNew snapshot: auto output restored on cache hit.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots.tomlAdds e2e scenarios for output restoration.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/package.jsonAdds fixture package manifest.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/positive_globs___hit_on_read_but_unmatched_file.mdSnapshot updated for new cache behavior.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/fspy_env___not_set_when_auto_inference_disabled.mdSnapshot updated for new FSPY behavior.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/folder_input___hit_despite_file_changes_and_folder_deletion.mdSnapshot updated for new cache behavior.
crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/empty_input___hit_despite_file_changes.mdSnapshot updated for new cache behavior.
crates/vite_task_bin/src/vtt/write_file.rsEnsures parent dirs exist before writing fixture files.
crates/vite_task_bin/src/lib.rsAdds output: None to default task cache config.
crates/vite_task/src/session/reporter/summary.rsTreats OutputConfig mismatch as config-changed in summary.
crates/vite_task/src/session/mod.rsPasses cache directory path into execution layer.
crates/vite_task/src/session/execute/mod.rsImplements archive creation/extraction and output collection.
crates/vite_task/src/session/execute/glob_inputs.rsAdds helper to collect globbed paths for outputs.
crates/vite_task/src/session/cache/mod.rsAdds output_config to cache keys; stores output_archive.
crates/vite_task/src/session/cache/display.rsDisplays output-config cache-miss reason inline.
crates/vite_task/src/session/cache/archive.rsNew tar+zstd archive create/extract helpers.
crates/vite_task/docs/task-cache.mdPartially updates cache docs for ResolvedGlobConfig.
crates/vite_task/Cargo.tomlAdds dependencies for archiving (tar/uuid/zstd).
Cargo.tomlAdds workspace dependency for zstd.
Cargo.lockUpdates lockfile for new deps and version bumps.
CHANGELOG.mdNotes new output field and output restoration behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +432 to +456
let fspy =
if metadata.input_config.includes_auto || metadata.output_config.includes_auto {
// Resolve input negative globs for fspy path filtering
// (already workspace-root-relative). Output negatives are applied
// later in `collect_and_archive_outputs`.
match metadata
.input_config
.negative_globs
.iter()
.map(|p| Ok(wax::Glob::new(p.as_str())?.into_owned()))
.collect::<anyhow::Result<Vec<_>>>()
{
Ok(negs) => Some(negs),
Err(err) => {
leaf_reporter.finish(
None,
CacheUpdateStatus::NotUpdated(CacheNotUpdatedReason::CacheDisabled),
Some(ExecutionError::PostRunFingerprint(err)),
);
return SpawnOutcome::Failed;
}
}
}
} else {
None
};
} else {
None
};

CopilotAIApr 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fspy is enabled when either input_config.includes_auto or output_config.includes_auto is true, but the cache update path still fingerprints all fspy reads. This makes "output auto" implicitly re-enable inferred input tracking even when the user disabled input auto, causing unexpected cache misses (and contradicting the stated input/output independence). Consider only using fspy reads for post-run fingerprinting when input_config.includes_auto is true, while still using fspy writes for output archiving.

Copilot uses AI. Check for mistakes.
@wan9chiGraphite App

Copy link
Copy Markdown
MemberAuthor

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

@wan9chiwan9chi mentioned this pull request Apr 20, 2026
9 tasks
@wan9chi
wan9chiforce-pushed the feat/output-restoration branch from 0008bd7 to 994624aCompareApril 20, 2026 04:20
wan9chi added a commit that referenced this pull request Apr 23, 2026
Archives output files after a successful run and restores them on cache hit. Defaults to automatically tracking files the task writes; accepts globs (e.g. `"dist/**"`), `{ "auto": true }`, and negative patterns (`"!dist/cache/**"`).
Squashed rebase of #321 onto main after the spawn decompose refactor and wincode migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wan9chi
wan9chiforce-pushed the feat/output-restoration branch 2 times, most recently from 589a626 to 9df3054CompareApril 23, 2026 08:00
@wan9chi
wan9chiforce-pushed the feat/output-restoration branch from 9df3054 to 3a8b605CompareMay 7, 2026 08:08
wan9chi added a commit that referenced this pull request May 7, 2026
Squashed rebase of 51 commits from runner-aware-tools branch onto
feat/output-restoration. Original commit history preserved on the
ras-backup ref for reference.
Key features bundled:
- vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr)
- vite_task_server: per-task IPC server (Handler trait + Recorder)
- vite_task_client: sync Rust client
- vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper
- vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH;
bundle with fspy via Tracking struct; materialize .node addon on first use
- consume runner-aware tool reports for cache decisions:
* disableCache() short-circuits via ToolRequested
* ignoreInput / ignoreOutput filter fspy reads/writes
* tracked: true env / env-glob records folded into PostRunFingerprint
- IPC server failure surfaces via IpcServerError; cache update is skipped
- schema bumped to user_version = 13 (CacheEntryKey carries output_config,
CacheEntryValue carries output_archive + tracked envs)
Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321
output archiving, input-negative reads-only filter): TrackingOutcome
post-run summary preserved alongside Tracking pre-run handle; auto-input
reads gated on input_config.includes_auto and filtered by input negatives
+ ignoreInput; auto-output writes filtered by negatives + ignoreOutput.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wan9chi
wan9chi changed the base branch from main to feat/output-globsMay 7, 2026 08:08
Adds an `output` field to cached tasks: archives files matching the
configured globs after a successful run and restores them on cache hit.
Supports glob patterns, negative patterns, and `{pattern, base}` form
with explicit base directory. When `output` is omitted or empty, no
output archiving happens (matches prior behavior).
Schema version bumped to 12 (CacheEntryKey carries output_config,
CacheEntryValue carries output_archive). Old caches are reset on upgrade.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wan9chi
wan9chiforce-pushed the feat/output-globs branch from 9dbd5b8 to 6d03bc0CompareMay 7, 2026 08:22
Adds `{ auto: true }` support to the `output` field, plus the implicit
default: when `output` is omitted, automatically tracks files the task
writes (via fspy) and archives them. Explicit globs and `auto` can be
mixed in the same array.
Also includes:
- `read_write_overlap` check: if a task writes to a file it also read
(auto-inferred), the cache update is skipped (`InputModified`).
Prerun input hashes would otherwise be stale.
- Input negatives apply to reads only, not writes — keeps `input: ["!dist/**"]`
from accidentally dropping writes to `dist/**` during archiving.
- Input-auto gating: when `input_config.includes_auto` is false, fspy
reads do not contribute to the post-run fingerprint, even when fspy
is enabled solely for output tracking.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wan9chi
wan9chiforce-pushed the feat/output-restoration branch from 3a8b605 to 6198f6bCompareMay 7, 2026 08:23
wan9chi added a commit that referenced this pull request May 7, 2026
Squashed rebase of 51 commits from runner-aware-tools branch onto
feat/output-restoration. Original commit history preserved on the
ras-backup ref for reference.
Key features bundled:
- vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr)
- vite_task_server: per-task IPC server (Handler trait + Recorder)
- vite_task_client: sync Rust client
- vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper
- vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH;
bundle with fspy via Tracking struct; materialize .node addon on first use
- consume runner-aware tool reports for cache decisions:
* disableCache() short-circuits via ToolRequested
* ignoreInput / ignoreOutput filter fspy reads/writes
* tracked: true env / env-glob records folded into PostRunFingerprint
- IPC server failure surfaces via IpcServerError; cache update is skipped
- schema bumped to user_version = 13 (CacheEntryKey carries output_config,
CacheEntryValue carries output_archive + tracked envs)
Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321
output archiving, input-negative reads-only filter): TrackingOutcome
post-run summary preserved alongside Tracking pre-run handle; auto-input
reads gated on input_config.includes_auto and filtered by input negatives
+ ignoreInput; auto-output writes filtered by negatives + ignoreOutput.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wan9chi added a commit that referenced this pull request May 7, 2026
Squashed rebase of 51 commits from runner-aware-tools branch onto
feat/output-restoration. Original commit history preserved on the
ras-backup ref for reference.
Key features bundled:
- vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr)
- vite_task_server: per-task IPC server (Handler trait + Recorder)
- vite_task_client: sync Rust client
- vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper
- vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH;
bundle with fspy via Tracking struct; materialize .node addon on first use
- consume runner-aware tool reports for cache decisions:
* disableCache() short-circuits via ToolRequested
* ignoreInput / ignoreOutput filter fspy reads/writes
* tracked: true env / env-glob records folded into PostRunFingerprint
- IPC server failure surfaces via IpcServerError; cache update is skipped
- schema bumped to user_version = 13 (CacheEntryKey carries output_config,
CacheEntryValue carries output_archive + tracked envs)
Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321
output archiving, input-negative reads-only filter): TrackingOutcome
post-run summary preserved alongside Tracking pre-run handle; auto-input
reads gated on input_config.includes_auto and filtered by input negatives
+ ignoreInput; auto-output writes filtered by negatives + ignoreOutput.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wan9chi added a commit that referenced this pull request May 7, 2026
Squashed rebase of 51 commits from runner-aware-tools branch onto
feat/output-restoration. Original commit history preserved on the
ras-backup ref for reference.
Key features bundled:
- vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr)
- vite_task_server: per-task IPC server (Handler trait + Recorder)
- vite_task_client: sync Rust client
- vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper
- vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH;
bundle with fspy via Tracking struct; materialize .node addon on first use
- consume runner-aware tool reports for cache decisions:
* disableCache() short-circuits via ToolRequested
* ignoreInput / ignoreOutput filter fspy reads/writes
* tracked: true env / env-glob records folded into PostRunFingerprint
- IPC server failure surfaces via IpcServerError; cache update is skipped
- schema bumped to user_version = 13 (CacheEntryKey carries output_config,
CacheEntryValue carries output_archive + tracked envs)
Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321
output archiving, input-negative reads-only filter): TrackingOutcome
post-run summary preserved alongside Tracking pre-run handle; auto-input
reads gated on input_config.includes_auto and filtered by input negatives
+ ignoreInput; auto-output writes filtered by negatives + ignoreOutput.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wan9chi added a commit that referenced this pull request May 11, 2026
## Summary
Adds an `output` field to cached tasks: archives files matching the configured globs after a successful run and restores them on cache hit.
- Omitted or `[]`: no output archiving (matches existing behavior)
- `["dist/**"]`: archive matching files; restore on cache hit
- `[{"pattern": "...", "base": "workspace" | "package"}]`: explicit base directory
- `["!dist/cache/**"]`: negative patterns exclude files
- This PR does **not** support `{auto: true}` — that comes in the follow-up #321
Schema bumped to v12 (`CacheEntryKey` carries `output_config`, `CacheEntryValue` carries `output_archive`). Old caches reset on upgrade.
## Test plan
- [ ] CI green
- [ ] New e2e fixture `output_cache_test/` covers archive+restore and negative-pattern exclusion
- [ ] All 87 plan snapshots updated to include the new `output_config` field (default empty)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Base automatically changed from feat/output-globs to mainMay 11, 2026 07:43
wan9chi added a commit that referenced this pull request May 14, 2026
Squashed rebase of 51 commits from runner-aware-tools branch onto
feat/output-restoration. Original commit history preserved on the
ras-backup ref for reference.
Key features bundled:
- vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr)
- vite_task_server: per-task IPC server (Handler trait + Recorder)
- vite_task_client: sync Rust client
- vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper
- vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH;
bundle with fspy via Tracking struct; materialize .node addon on first use
- consume runner-aware tool reports for cache decisions:
* disableCache() short-circuits via ToolRequested
* ignoreInput / ignoreOutput filter fspy reads/writes
* tracked: true env / env-glob records folded into PostRunFingerprint
- IPC server failure surfaces via IpcServerError; cache update is skipped
- schema bumped to user_version = 13 (CacheEntryKey carries output_config,
CacheEntryValue carries output_archive + tracked envs)
Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321
output archiving, input-negative reads-only filter): TrackingOutcome
post-run summary preserved alongside Tracking pre-run handle; auto-input
reads gated on input_config.includes_auto and filtered by input negatives
+ ignoreInput; auto-output writes filtered by negatives + ignoreOutput.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wan9chi

Copy link
Copy Markdown
MemberAuthor

Superseded: the manual output config was merged in #375, and the auto output-inference work is now folded directly into #346 (runner-aware-tools), which is rebased onto main. This branch is no longer needed.

@wan9chiwan9chi closed this May 14, 2026
@wan9chi
wan9chi deleted the feat/output-restoration branch May 14, 2026 10:52
Sign up for freeto 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

@wan9chi