Expand description
The one way to write into an agent’s working directory (docs/specs/SPEC_WORKDIR_SAFE_WRITES_2026_10_01.md).
An agent’s workdir isn’t wholly AgentMux’s: it can hold the user’s own
files, a cloned repo, and symlinks. Every write AgentMux makes into it —
CLAUDE.md and the other instructions files, .claude/*, .mcp.json,
skill files, manifests, backups — goes through Workdir, which:
- keeps the path inside the workdir, lexically (
safe_join_within_base) and through symlinked folders (verify_no_symlink_escape); - never writes through a symlinked file, dangling or not (a dangling link
passes the folder check, and
fs::writewould follow it); - replaces files atomically (temp file in the same folder,
sync_all, rename), so a crash or a full disk leaves the old file or the new one, never half of each. A rename replaces a link entry rather than following it, so a link appearing between the check and the write still can’t send the write outside.
A refusal is an io::ErrorKind::PermissionDenied naming the path and
the reason; callers keep their own policy (fail the launch, or log and
go on). scripts/check-workdir-writes.mjs keeps raw filesystem writes
out of the files that write into workdirs.
Structs§
- Workdir
- An agent’s working directory, resolved once.
Constants§
- RENAME_
RETRY_ 🔒DELAY - RENAME_
TRIES 🔒 - How many times an atomic replace retries a rename that Windows refused (the target held open without delete-sharing), and how long it waits between tries.
Functions§
- is_
symlink 🔒 - refused 🔒
- rename_
with_ 🔒retry fs::rename, retried briefly when Windows refuses to replace a file another process holds open; never falls back to a non-atomic write.- temp_
path 🔒 - A fresh temporary name beside
path, so a rename or link stays on one filesystem.