Skip to content

feat(plugin): serialize file mutations per sandbox file - #54

Merged
sanchitrk merged 1 commit into
canaryfrom
claude/sandbox-mutation-queue
Oct 9, 2026
Merged

sanchitrk merged 1 commit into
canaryfrom
claude/sandbox-mutation-queue

Conversation

@sanchitrk

Copy link
Copy Markdown
Contributor

First of three stacked PRs (1/3 → bounded scanLines → sandbox-side bash output).

What

  • SandboxIO.Mutation: a per-file FIFO lock on every mount. File-mutating tools hold it for their whole read → modify → write while parallel tool calls run.
  • A file is keyed by sandbox instance + canonical path: mounts of one instance share a queue, symlinked spellings resolve to one key, and a file that does not exist yet keys on its canonical parent.
  • SandboxIO.withMutation completes hand-built mounts (control plane, Daytona, Vercel).
  • Daytona realpath rejects with ENOENT like Vercel; the shared realpath scripts try realpath -e first so a symlinked file resolves on remote sandboxes.

Notes

  • Ownership is handed directly to the next waiter (no barging); taking the lock and installing its release happen uninterruptibly, and an interrupted waiter either leaves the queue or passes the file on.
  • Calls queue in the order their paths resolve. Process-local; not a lock against bash or other processes.

Testing

  • test/sandbox.mutation.test.ts: lost updates, spellings (relative/absolute/symlinked dir/symlinked file), missing files, FIFO order, interrupted waiters (queued behind and arriving after), failure release, two mounts of one instance, unrelated files. Artifact: __artifacts__/sandbox.mutation.json.
  • Faults injected into the lock (no chaining, no canonicalization, releasing an un-owned file) each fail the test.
  • Live Daytona e2e suite passes.

🤖 Generated with Claude Code

Add SandboxIO.Mutation, a per-file FIFO lock on every mount. A file is its
sandbox instance plus canonical path, so mounts of one instance and symlinked
spellings share a queue, and a file that does not exist yet keys on its
canonical parent. File-mutating tools hold it for their whole
read-modify-write while parallel tool calls run.

SandboxIO.withMutation completes any hand-built mount with the queue.
Daytona realpath now rejects with ENOENT like Vercel, and the shared realpath
scripts try `realpath -e` first so a symlinked file resolves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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