You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two interpreter-resolution defects in the SKILL.md installed by graphify install --platform claude. Both are still present in v0.9.72
(graphify/skill.md at that tag: Step 1 lines 73 and 89 for the uv half,
line 673 for the guard; the only change to this file since v0.9.61 is the .graphify_root write).
Related: #1619 (A1 reports the guard half; its PR #1962 was closed without
merging), #2183 (same guard, pipx -E shebang), #513 (same head -1 on graphify.exe, but in the post-commit hook, closed). The uv-cache half below
does not appear in any of them.
1. Step 1's uv branch resolves a throwaway cache environment
Step 1 tries uv first:
_UV_PY=$(uv tool run --from graphifyy python -c "import sys; print(sys.executable)"2>/dev/null)
uv tool run does not run inside the environment created by uv tool install graphifyy. It provisions a separate, cached environment and
reports that one. On Windows 11 with graphify installed via uv tool install graphifyy:
$ uv tool run --from graphifyy python -c "import sys; print(sys.executable)"
Downloading graphifyy (1.4MiB)
Installed 30 packages in 1.84s
%LOCALAPPDATA%\uv\cache\archive-v0\<hash>\Scripts\python.exe
$ uv tool dir
%APPDATA%\uv\tools
The persistent interpreter the CLI actually runs from is %APPDATA%\uv\tools\graphifyy\Scripts\python.exe. The cache path is written to graphify-out/.graphify_python and every later step is pinned to it. Two
consequences:
The cache entry can be evicted (uv cache clean, uv cache prune), and the
sidecar then points at nothing.
It can be a different graphify version than the installed CLI: in the run
above it downloaded the latest release while the installed tool was older. The
skill steps and the graphify CLI then silently disagree on versions.
The import graphify check does not catch either case, because the cache
interpreter imports fine on the day it is resolved.
2. The subcommand guard parses a PE binary as a shebang
On Windows the launcher is a console-script .exe (first two bytes MZ). In my
run (Claude Code, Git Bash) this produced command substitution: ignored null byte in input and exit 127: the binary
bytes were executed as a command. When the allowlist does catch it, the
fallback is python3, which on Windows is often the Microsoft Store stub
(as #1619 describes). Either way nothing validates the result before it is
written to .graphify_python. Step 1 does better here: its shebang branch
gates the candidate on "$_SHEBANG" -c "import graphify" before accepting it.
The guard is the same parse without the gate, so the two blocks already
disagree.
Expected
A resolved interpreter should be the durable environment the CLI runs from, and
it should be proven to import graphify before it is persisted.
Proposal (both blocks)
Resolve the persistent tool environment directly, before any run-once
command: "$(uv tool dir)/graphifyy/Scripts/python.exe" (Windows) or "$(uv tool dir)/graphifyy/bin/python" (POSIX); likewise pipx environment --value PIPX_LOCAL_VENVS for pipx.
Only parse a shebang when the launcher is a text script: skip it if the path
ends in .exe or the first two bytes are MZ.
Reject any candidate whose path contains a uv cache segment
(/cache/archive-v0/), and drop uv tool run --from graphifyy as a source
of the interpreter path.
The find_graphify_python function in #1619 covers points 1, 2 and 4; point 3
is the new part.
Environment: observed on graphifyy 0.9.55 installed with uv tool install,
skill installed with graphify install --platform claude, Claude Code on
Windows 11 (Git Bash); now on 0.9.65. Upstream text checked against v0.9.72.
Two interpreter-resolution defects in the
SKILL.mdinstalled bygraphify install --platform claude. Both are still present in v0.9.72(
graphify/skill.mdat that tag: Step 1 lines 73 and 89 for the uv half,line 673 for the guard; the only change to this file since v0.9.61 is the
.graphify_rootwrite).Related: #1619 (A1 reports the guard half; its PR #1962 was closed without
merging), #2183 (same guard, pipx
-Eshebang), #513 (samehead -1ongraphify.exe, but in the post-commit hook, closed). The uv-cache half belowdoes not appear in any of them.
1. Step 1's uv branch resolves a throwaway cache environment
Step 1 tries uv first:
_UV_PY=$(uv tool run --from graphifyy python -c "import sys; print(sys.executable)" 2>/dev/null)uv tool rundoes not run inside the environment created byuv tool install graphifyy. It provisions a separate, cached environment andreports that one. On Windows 11 with graphify installed via
uv tool install graphifyy:The persistent interpreter the CLI actually runs from is
%APPDATA%\uv\tools\graphifyy\Scripts\python.exe. The cache path is written tographify-out/.graphify_pythonand every later step is pinned to it. Twoconsequences:
uv cache clean,uv cache prune), and thesidecar then points at nothing.
above it downloaded the latest release while the installed tool was older. The
skill steps and the
graphifyCLI then silently disagree on versions.The
import graphifycheck does not catch either case, because the cacheinterpreter imports fine on the day it is resolved.
2. The subcommand guard parses a PE binary as a shebang
"Interpreter guard for subcommands" still does:
On Windows the launcher is a console-script
.exe(first two bytesMZ). In myrun (Claude Code, Git Bash) this produced
command substitution: ignored null byte in inputand exit 127: the binarybytes were executed as a command. When the allowlist does catch it, the
fallback is
python3, which on Windows is often the Microsoft Store stub(as #1619 describes). Either way nothing validates the result before it is
written to
.graphify_python. Step 1 does better here: its shebang branchgates the candidate on
"$_SHEBANG" -c "import graphify"before accepting it.The guard is the same parse without the gate, so the two blocks already
disagree.
Expected
A resolved interpreter should be the durable environment the CLI runs from, and
it should be proven to import graphify before it is persisted.
Proposal (both blocks)
command:
"$(uv tool dir)/graphifyy/Scripts/python.exe"(Windows) or"$(uv tool dir)/graphifyy/bin/python"(POSIX); likewisepipx environment --value PIPX_LOCAL_VENVSfor pipx.ends in
.exeor the first two bytes areMZ.(
/cache/archive-v0/), and dropuv tool run --from graphifyyas a sourceof the interpreter path.
"$PY" -c "import graphify"and apply the sameresolution function in Step 1 and in the guard, so the two cannot drift again
(SKILL.md subcommand interpreter guard writes a graphify-less Python (pipx shebang carries -E); Step 1's hardening never applied #2183 shows they already have).
The
find_graphify_pythonfunction in #1619 covers points 1, 2 and 4; point 3is the new part.
Environment: observed on graphifyy 0.9.55 installed with
uv tool install,skill installed with
graphify install --platform claude, Claude Code onWindows 11 (Git Bash); now on 0.9.65. Upstream text checked against v0.9.72.