Expand description
Mirrors packages/agent/src/harness/tools/file-mutation-queue.ts — serializes
file-mutating operations per canonical path so concurrent edits to the same
path (or a symlink + its target) don’t interleave.
The TS uses a WeakMap<ExecutionEnv, MutationQueueState> keyed by env
instance. Rust has no per-instance map keyed by trait object, so each env
impl carries an Arc<MutationQueueRegistry> field and exposes it via the
MutatingEnv accessor trait. The mutation-dependent tools (write, edit)
hold Arc<dyn MutatingEnv>; read and bash don’t need it.
Critical invariant (plan §5.4): abort does NOT unblock the queue. An
aborted caller still waits for its turn, then runs fn (which may observe
the abort and return Err(Aborted)), then releases. The lock guard is held
across fn().await; a CancellationToken only causes fn to error out —
it does NOT preempt mutex acquisition.
Structs§
- Mutation
Queue Registry - Per-env registry of canonical-path → mutex. Stored as a field on each env
impl (behind
Arcso clones share the same map).
Traits§
- Mutating
Env - Accessor used by
with_file_mutation_queueto reach the env’s registry AND itsExecutionEnvmethods. Concrete env impls (OsExecutionEnv,InMemoryExecutionEnv) implement this; the write/edit tools holdArc<dyn MutatingEnv>.
Functions§
- get_
mutation_ queue_ key - Compute the canonical-path queue key for
path. MirrorsgetMutationQueueKey: - with_
file_ mutation_ queue - Serialize
fnper canonical-path key forenv. The closurefruns while holding the per-keytokio::Mutexguard; abort/cancel during the wait does NOT skip the queue —fitself must observe the token and returnErr(FileError::aborted()).