Skip to main content

Module workdir_fs

Module workdir_fs 

Source
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::write would 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.