Skip to content

feat: reclaim temporary workspace dependencies - #327

Open
seonghobae wants to merge 11 commits into
feat/darwin-user-temp-reclaim-v1from
feat/temp-workspace-artifact-reclaim-v1
Open

feat: reclaim temporary workspace dependencies#327
seonghobae wants to merge 11 commits into
feat/darwin-user-temp-reclaim-v1from
feat/temp-workspace-artifact-reclaim-v1

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Outcome

  • treats lockfile-reproducible node_modules and uv .venv subtrees as separate generated objects
  • preserves the complete temporary Git workspace and every dirty source change
  • binds plans to workspace registration/dirty evidence, open handles, live commands, content fingerprint, fresh approval, atomic staging, and immutable receipt
  • rejects workspace roots, source trees, missing-lockfile directories, symlinks, provider, Photos, and VM boundaries

Live read-only evidence

  • five Bandscope temporary workspaces are registered against the primary repository and retain a dirty .Jules/palette.md
  • five uv environments allocate 4,421,312 KiB
  • three top-level node_modules trees allocate 1,088,308 KiB
  • repository roots and dirty files were not mutated

Validation

  • rustfmt --edition 2021 src-tauri/src/generated_cache_reclaim.rs
  • git diff --check
  • focused Cargo test was stopped during a cold dependency build after no reusable target was available; the 752.5 MiB partial target was immediately cleaned

Devin Review

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6fa5a287-a6ea-4013-a4a7-59e15d881d95

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 6 potential issues.

Devin Review

Comment thread src-tauri/src/generated_cache_reclaim.rs Outdated
Comment thread src-tauri/src/generated_cache_reclaim.rs
Comment thread src-tauri/src/generated_cache_reclaim.rs
Comment on lines +530 to 553
let git_probe = match contract {
RegenerationContract::TemporaryGitWorkspace => Some(path.to_path_buf()),
RegenerationContract::TemporaryWorkspaceNodeModules
| RegenerationContract::TemporaryWorkspaceUvEnvironment => temporary_workspace_root(path),
_ => None,
};
if let Some(git_probe) = git_probe {
let git_probe = std::fs::canonicalize(&git_probe).unwrap_or(git_probe);
match bounded_git(
path,
&git_probe,
&["rev-parse", "--path-format=absolute", "--git-common-dir"],
) {
Ok(common) => {
evidence.git_common_dir = Some(common.trim().into());
evidence.git_worktree_registered =
bounded_git(path, &["worktree", "list", "--porcelain"]).is_ok_and(|output| {
output
.lines()
.any(|line| line.strip_prefix("worktree ") == path.to_str())
});
evidence.git_dirty = bounded_git(path, &["status", "--porcelain=v1"])
bounded_git(&git_probe, &["worktree", "list", "--porcelain"]).is_ok_and(
|output| {
output
.lines()
.any(|line| line.strip_prefix("worktree ") == git_probe.to_str())
},
);
evidence.git_dirty = bounded_git(&git_probe, &["status", "--porcelain=v1"])
.map_or(true, |output| !output.is_empty());

@devin-ai-integration devin-ai-integration Bot Aug 30, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Dirty state does not authorize source removal

Dependency plans fingerprint Git registration and dirty state without blocking on either. Execution still targets only the separately fingerprinted dependency subtree.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +205 to +228
fn temporary_workspace_artifact_contract(path: &Path) -> Option<RegenerationContract> {
let workspace = temporary_workspace_root(path)?;
let parent = path.parent()?;
match path.file_name()?.to_str()? {
"node_modules"
if is_regular_file(&parent.join("package.json"))
&& ["package-lock.json", "pnpm-lock.yaml", "yarn.lock"]
.iter()
.any(|name| {
is_regular_file(&parent.join(name))
|| is_regular_file(&workspace.join(name))
}) =>
{
Some(RegenerationContract::TemporaryWorkspaceNodeModules)
}
".venv"
if is_regular_file(&parent.join("pyproject.toml"))
&& (is_regular_file(&parent.join("uv.lock"))
|| is_regular_file(&workspace.join("uv.lock"))) =>
{
Some(RegenerationContract::TemporaryWorkspaceUvEnvironment)
}
_ => None,
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Candidate symlinks fail during observation

Contract discovery can classify a symlink named node_modules or .venv. observe_tree rejects that root before producing an approvable plan.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src-tauri/src/generated_cache_reclaim.rs

@devin-ai-integration devin-ai-integration Bot 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 1 new potential issue.

Devin Review

assert_eq!(
receipt.execution_issue.as_deref(),
Some("podman-storage-repair-command-failed")
Some("podman-storage-repair-provider-exit-status-unexpected")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Status-one classification remains covered

The fixture exits with status 1, which storage_repair_provider_issue classifies as unexpected. The revised assertion preserves exact receipt validation.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration devin-ai-integration Bot 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 2 new potential issues.

Devin Review

Comment on lines +723 to +729
if fingerprint != plan.content_fingerprint
|| (!locks.is_empty()
&& !matches!(
plan.contract,
RegenerationContract::TemporaryWorkspaceUvEnvironment
))
{

@devin-ai-integration devin-ai-integration Bot Aug 30, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Lock changes remain fingerprinted

The uv exemption only removes the pathname-based blocker. observe_tree still fingerprints every lock entry, so post-approval lock changes abort removal.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src-tauri/src/generated_cache_reclaim.rs
devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 1 new potential issue.

Devin Review

Comment on lines +223 to +233
"node_modules"
if is_regular_file(&parent.join("package.json"))
&& ["package-lock.json", "pnpm-lock.yaml", "yarn.lock"]
.iter()
.any(|name| is_regular_file(&parent.join(name))) =>
{
Some(RegenerationContract::TemporaryWorkspaceNodeModules)
}
".venv"
if is_regular_file(&parent.join("pyproject.toml"))
&& is_regular_file(&parent.join("uv.lock")) =>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Nested projects require local lockfiles

Top-level artifacts remain eligible because the workspace is their parent. Nested projects cannot borrow an unrelated root lockfile for removal authority.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration devin-ai-integration Bot 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 1 new potential issue.

Devin Review

Comment on lines +728 to +730
let active = crate::git_worktree::active_use_evidence_with_command_path(
&staged, path, 5_000, 128, true,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Staged probes retain both identities

active_use_evidence_with_command_path checks handles under the staged object and commands naming the original path. The existing shell exclusion still prevents self-blocking.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration devin-ai-integration Bot 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.

Devin Review found 1 new potential issue.

Devin Review

Comment on lines +728 to +730
let active = crate::git_worktree::active_use_evidence_with_command_path(
&staged, path, 5_000, 128, true,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Staging preserves both activity identities

active_use_evidence_with_command_path probes staged handles while matching commands against the original path. The rename therefore hides neither activity signal.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant