fix(skills): document env setup never deletes a working env another agent published

The sandbox fallback in the document skills (microsoft-office, pdf,
excel-author, pptx-author and the two OCR blocks) read the published
venv only after its own import check failed. When another agent
published a working venv in between, this caller took it for a broken
build, swapped in its own and deleted the working one, so that agent's
running process could lose lazily imported files. A published build is
now replaced, and deleted, only while it still fails the import check;
otherwise the late caller discards its own stage. Generated skill pages
regenerated.

Introduced by dc82bec3bd (#146111, @teknium1, 2026-10-28); not a
regression, the skills had no sandbox venv before it.
This commit is contained in:
kshitijk4poor authored and kshitij committed 2026-10-31 14:33:20 +05:30
1 parent b544b82db1
commit a53acf8d3a
10 files changed
+87 -30

No files matched your search

@@ -40,14 +40,15 @@ else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
+4 -3
View File
@@ -41,14 +41,15 @@ else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
@@ -57,14 +57,15 @@ Deeper notes: `references/revisions-and-comments.md` (Word review markup) and
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
+4 -3
View File
@@ -48,14 +48,15 @@ Create PDFs from structured specs, build and fill AcroForm forms (with layout li
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
@@ -65,12 +65,12 @@ else
"$PY" -c "import pymupdf, pymupdf4llm" 2>/dev/null || (
# concurrency-safe build: see the documents block in SKILL.md
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-pdf-pymupdf-venv.XXXXXX)" || exit 1
old="$(readlink hermes-pdf-pymupdf-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-pdf-pymupdf-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check 'pymupdf>=1.26,<3' 'pymupdf4llm>=0.2,<3' &&
"$stage/bin/python" -c "import pymupdf, pymupdf4llm" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-pdf-pymupdf-venv
elif [ "$(readlink hermes-pdf-pymupdf-venv)" = "$old" ]; then
elif [ "$(readlink hermes-pdf-pymupdf-venv)" = "$old" ] && ! "$old/bin/python" -c "import pymupdf, pymupdf4llm" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-pdf-pymupdf-venv &&
case "$old" in hermes-pdf-pymupdf-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
@@ -116,12 +116,12 @@ else
"$PY" -c "import marker" 2>/dev/null || (
# concurrency-safe build: see the documents block in SKILL.md
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-pdf-marker-venv.XXXXXX)" || exit 1
old="$(readlink hermes-pdf-marker-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-pdf-marker-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check 'marker-pdf>=1.8,<3' &&
"$stage/bin/python" -c "import marker" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-pdf-marker-venv
elif [ "$(readlink hermes-pdf-marker-venv)" = "$old" ]; then
elif [ "$(readlink hermes-pdf-marker-venv)" = "$old" ] && ! "$old/bin/python" -c "import marker" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-pdf-marker-venv &&
case "$old" in hermes-pdf-marker-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
+51 -2
View File
@@ -56,9 +56,16 @@ def _script(path, body):
path.chmod(0o755)
def _sandbox(tmp_path, *, hermes=None):
def _venv(directory, healthy):
"""A stand-in venv whose interpreter passes (or fails) every import check and pip install."""
(directory / "bin").mkdir(parents=True)
_script(directory / "bin" / "python", "exit 0\n" if healthy else "exit 1\n")
def _sandbox(tmp_path, *, hermes=None, before_stage=""):
"""A HOME and a PATH for one block: ``python`` lacks every library and ``python3 -m venv``
makes a stub venv."""
makes a stub venv. ``before_stage`` runs inside the block's ``$HOME/.cache`` right before it
creates its private stage, i.e. after its own import check failed."""
system_path = _system_path()
if shutil.which("hermes", path=system_path):
pytest.skip("a hermes on the system PATH would take the PM branch")
@@ -70,6 +77,7 @@ def _sandbox(tmp_path, *, hermes=None):
if [ "$1 $2" = "-m venv" ]; then mkdir -p "$3/bin" && printf '#!/bin/sh\\nexit 0\\n' > "$3/bin/python" && chmod +x "$3/bin/python"; exit; fi
exec {shlex.quote(sys.executable)} "$@"
"""))
_script(stubs / "mktemp", f"{before_stage}\nexec {shlex.quote(shutil.which('mktemp'))} \"$@\"\n")
if hermes is not None:
_script(stubs / "hermes", f"echo {hermes}\n")
return home, {"HOME": str(home), "PATH": f"{stubs}{os.pathsep}{system_path}", "LC_ALL": "C"}
@@ -89,3 +97,44 @@ def test_block_exports_py_for_the_next_terminal_call(tmp_path, document, venv):
home, env = _sandbox(tmp_path, hermes="/side-env/bin/python")
exported = _run(_setup_block(document, venv) + "export -p\n", env, home)
assert "PY=" in exported and "/side-env/bin/python" in exported, exported
@pytest.mark.parametrize("document,venv", BLOCKS)
def test_late_builder_keeps_the_env_another_caller_just_published(tmp_path, document, venv):
# Another caller publishes a working build between this caller's failed import check and
# its stage: this caller must not replace it and delete it under that caller.
published = f"{venv}.PUBLSH"
publish = (f'[ -e {published} ] || {{ mkdir -p {published}/bin && printf "#!/bin/sh\\nexit 0\\n" '
f'> {published}/bin/python && chmod +x {published}/bin/python && ln -s {published} {venv}; }}')
home, env = _sandbox(tmp_path, before_stage=publish)
_run(_setup_block(document, venv), env, home)
cache = home / ".cache"
assert (cache / published / "bin" / "python").is_file()
assert os.readlink(cache / venv) == published
assert sorted(p.name for p in cache.iterdir()) == [venv, published]
@pytest.mark.parametrize("document,venv", BLOCKS)
def test_broken_published_env_is_replaced_and_removed(tmp_path, document, venv):
home, env = _sandbox(tmp_path)
cache = home / ".cache"
_venv(cache / f"{venv}.BROKEN", healthy=False)
(cache / venv).symlink_to(f"{venv}.BROKEN")
_run(_setup_block(document, venv), env, home)
fresh = os.readlink(cache / venv)
assert fresh.startswith(f"{venv}.") and fresh != f"{venv}.BROKEN"
assert sorted(p.name for p in cache.iterdir()) == sorted([venv, fresh])
def test_repair_still_works_when_the_test_tools_live_under_a_spaced_path(tmp_path, monkeypatch):
# The stubs exec the real interpreter and mktemp; a checkout or venv under a spaced path
# must not split those commands into words (the blocks themselves are not involved).
spaced = tmp_path / "test tools"
spaced.mkdir()
(spaced / "python").symlink_to(sys.executable)
(spaced / "mktemp").symlink_to(shutil.which("mktemp"))
real_which = shutil.which
monkeypatch.setattr(sys, "executable", str(spaced / "python"))
monkeypatch.setattr(shutil, "which",
lambda cmd, *a, **k: str(spaced / "mktemp") if cmd == "mktemp" else real_which(cmd, *a, **k))
test_broken_published_env_is_replaced_and_removed(tmp_path, *BLOCKS[1])
@@ -74,14 +74,15 @@ Deeper notes: `references/revisions-and-comments.md` (Word review markup) and
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
@@ -65,14 +65,15 @@ Create PDFs from structured specs, build and fill AcroForm forms (with layout li
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
@@ -58,14 +58,15 @@ else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
@@ -59,14 +59,15 @@ else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
# a symlink publishes the first finished one atomically, the others delete theirs;
# a published build is replaced and deleted only while it still fails to import.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
old="$(readlink hermes-docs-venv)" # the published build, if any (another agent may have just published it)
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
elif [ "$(readlink hermes-docs-venv)" = "$old" ] && ! "$old/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null