solx 0.5.1: fix the broken .pyz installer (shebang swap corrupts the zipapp)#31
Merged
Conversation
…bang
install.sh rebound the interpreter by replacing the shebang bytes in
place, but a zipapp records central-directory offsets as absolute file
positions that include the shebang line. A different-length interpreter
path shifted every offset, so zipimport rejected the archive ("bad
central directory size or offset") and solx died on startup with
"SyntaxError: source code cannot contain null bytes". The build stamps
the CI runner's long interpreter path, so no local path matched its
length and essentially every .pyz install was broken; zipfile tolerated
the corruption on read, so the build's own check never caught it.
install.sh now extracts the payload and rebuilds the archive around the
local interpreter (regenerating the offsets), then smoke-tests the
result before reporting success, falling back to a uv-managed
interpreter when the resolved one can't run a zipapp.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The build job only uploaded solx.pyz; nothing executed it, and the release smoke check that did exist relied on zipfile, which tolerates the offset corruption a shebang swap produces. Add a step that runs the artifact in place and end-to-end through install.sh, binding it to an interpreter whose path length differs from the build shebang (a symlink under $RUNNER_TEMP) — the exact condition under which an in-place shebang swap corrupts the archive. A regression now fails the build. To let the smoke test pin that interpreter, install.sh's SOLX_PYTHON now accepts an explicit interpreter path (anything with a slash) in addition to a version, used as-is with no uv required — which also gives a no-uv machine a working install path. The managed-interpreter fallback derives its version from the chosen interpreter and errors clearly when uv is absent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
solx 0.5.1 — fix the broken
.pyzinstallerv0.5.0's
install.shproduced asolxthat can't start. It rebound thezipapp's interpreter by swapping the shebang bytes in place, but a zipapp
records its central-directory offsets as absolute file positions that include
the shebang line. Replacing the shebang with a different-length interpreter
path shifts every offset, so
zipimport(which executes the archive) rejectsit:
The build stamps the CI runner's long interpreter path
(
#!/home/runner/work/_temp/uv-python-dir/…/python3.11), so no localinterpreter path matches its length — essentially every
.pyzinstall wasbroken.
zipfiletolerates the corrupted archive on read, which is why thebuild's own check never caught it; only
zipimportis strict.Fix
install.shnow:interpreter (
python -m zipfile -e→python -m zipapp), which regeneratesthe offsets — instead of byte-swapping the shebang.
solx --version) before reporting success, so abroken install can never be reported as success again.
zipapp.
Verification
install.shrun end-to-end against the live v0.5.0 release → installedsolxruns (0.5.0).sh -nclean; full suite green (247 passed).Version
Bumps to 0.5.1 across
__init__.py,pyproject.toml,SKILL.md, anduv.lock; changelog adds[0.5.1]and relabels the released[Unreleased]block as
[0.5.0] — 2026-06-10.🤖 Generated with Claude Code