From 9c98de94ee88e0d1f96186c8cd9f9dba69ce1cd0 Mon Sep 17 00:00:00 2001 From: faresobeid <111092724+faresobeid@users.noreply.github.com> Date: Tue, 6 Oct 2026 11:35:36 +0000 Subject: [PATCH] fix(runtime): publish uv scripts with link-if-absent instead of replacing them --- verifiers/v1/runtimes/runtime.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/verifiers/v1/runtimes/runtime.py b/verifiers/v1/runtimes/runtime.py index 0448549526..9cb82f2018 100644 --- a/verifiers/v1/runtimes/runtime.py +++ b/verifiers/v1/runtimes/runtime.py @@ -154,8 +154,13 @@ async def prepare_uv_script( if path not in self.backend._uv_interpreters: tmp = f"{path}.{uuid.uuid4().hex}.tmp" await self.write(tmp, data) + # Publish with link(2), which fails if the path exists, so a file that + # another worker may be executing is never replaced. Replacing it via + # rename(2) makes concurrent execs fail with ENOENT on shared filesystems. command = ( - f"mv -f {shlex.quote(tmp)} {shlex.quote(path)} " + f"ln {shlex.quote(tmp)} {shlex.quote(path)} 2>/dev/null; " + f"rm -f {shlex.quote(tmp)}; " + f"test -f {shlex.quote(path)} " f"&& {{ {_ENSURE_UV}; }} " f"&& uv sync --script {shlex.quote(path)} -q --no-config " f"&& uv python find --script {shlex.quote(path)} --no-config" @@ -202,8 +207,9 @@ async def run_uv_script( workspace: uv keys its per-script environment by the script's full path, so a unique path per call would mint a fresh env every rollout. A path derived from the content means identical scripts share one path → uv reuses one env, bounded by the - number of distinct scripts. Published via a unique temp + atomic `mv`, so - concurrent rollouts writing the same content never race a half-written read.""" + number of distinct scripts. Published from a unique temp file via an atomic hard link + that never replaces an existing file, so concurrent rollouts never read a half-written + script and never see the path vanish while another worker runs it.""" argv = await self.prepare_uv_script(script, env) return await self.run([*argv, *(args or [])], env or {})