You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] @deepseek-ai/dsh-workspace-changes causes massive disk consumption and orphan residue leaks
#11496
@deepseek-ai/dsh-workspace-changes exhibits two critical resource issues during normal use:
Severe Disk Bloat: A single turn can generate multiple gigabytes of temporary objects in $TMPDIR/dsh-workspace-changes-*.
Permanent Orphan Leaks: When the DSH Host crashes, is SIGTERMed/killed, or the machine restarts, the temporary directories are never cleaned up, permanently consuming tens of gigabytes of disk space.
Root Cause Analysis (Code Level)
Unbounded git add --all in snapshotTree
The snapshot captures the entire work tree using:
Although config.maxFileBytes exists, it is only enforced when generating diffs or capturing file-tool copies. In snapshotTree, git add --all unconditionally writes Git blob objects for all untracked, unignored files into GIT_OBJECT_DIRECTORY.
If a repository lacks a .gitignore or contains build outputs, node_modules, .venv, or SQLite databases, Git packages tens of thousands of files into blobs within the temporary directory on the very first turn.
Fragile Disposal Lifecycle
Directory cleanup is strictly bound to session/disposed and Cordis ctx.effect().
In real-world environments, developers frequently terminate the host via SIGINT (Ctrl+C), SIGTERM (hot restart scripts/supervisor), or experience host crashes. Under these conditions, the async cleanup rm(scratch) never completes, and the OS does not auto-reclaim custom temporary directory prefixes.
Production Evidence: On a single machine, we observed 35 orphaned dsh-workspace-changes-* directories accumulating 45.9 GB of leaked storage, with individual directories measuring up to 3.04 GB.
No Turn Eviction / LRU
Temporary snapshot objects remain on disk for the entire lifetime of a Session across dozens of turns, with no sliding window (e.g. keeping only the last 3 turns).
Suggested Fixes
Built-in Ignore Defense in snapshotTree:
Add built-in exclude pathspecs to git add for common non-source directories (e.g., :(exclude)node_modules, :(exclude).venv, :(exclude)dist, :(exclude)build, binary archives), or respect a configurable excludePatterns option.
Crash-Safe Host Recovery / Orphan Reaper:
Write a lightweight PID / session metadata marker inside $TMPDIR/dsh-workspace-changes-*.
On plugin startup, scan $TMPDIR and prune any dsh-workspace-changes-* directories whose owning PID is no longer alive.
Rolling Turn Snapshots (Sliding Window):
Retain tree snapshots and file copies only for the most recent N turns (e.g., 3 turns), pruning older snapshot objects periodically instead of waiting for session/disposed.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Environment
@deepseek-ai/dsh-workspace-changes(v0.2.2-alpha.2)packages/deliverables/workspace-changesProblem Description
@deepseek-ai/dsh-workspace-changesexhibits two critical resource issues during normal use:$TMPDIR/dsh-workspace-changes-*.Root Cause Analysis (Code Level)
Unbounded
git add --allinsnapshotTreeThe snapshot captures the entire work tree using:
config.maxFileBytesexists, it is only enforced when generating diffs or capturing file-tool copies. InsnapshotTree,git add --allunconditionally writes Git blob objects for all untracked, unignored files intoGIT_OBJECT_DIRECTORY..gitignoreor contains build outputs,node_modules,.venv, or SQLite databases, Git packages tens of thousands of files into blobs within the temporary directory on the very first turn.Fragile Disposal Lifecycle
session/disposedand Cordisctx.effect().SIGINT(Ctrl+C),SIGTERM(hot restart scripts/supervisor), or experience host crashes. Under these conditions, the async cleanuprm(scratch)never completes, and the OS does not auto-reclaim custom temporary directory prefixes.dsh-workspace-changes-*directories accumulating 45.9 GB of leaked storage, with individual directories measuring up to 3.04 GB.No Turn Eviction / LRU
Temporary snapshot objects remain on disk for the entire lifetime of a Session across dozens of turns, with no sliding window (e.g. keeping only the last 3 turns).
Suggested Fixes
snapshotTree:Add built-in exclude pathspecs to
git addfor common non-source directories (e.g.,:(exclude)node_modules,:(exclude).venv,:(exclude)dist,:(exclude)build, binary archives), or respect a configurableexcludePatternsoption.$TMPDIR/dsh-workspace-changes-*.$TMPDIRand prune anydsh-workspace-changes-*directories whose owning PID is no longer alive.Retain tree snapshots and file copies only for the most recent N turns (e.g., 3 turns), pruning older snapshot objects periodically instead of waiting for
session/disposed.All reactions