Skip to content

feat(embed): onefile output for island bundles, composite passes both baselines - #802

Draft
espetro wants to merge 9 commits into
work/lazyseedfrom
work/onefile
Draft

espetro wants to merge 9 commits into
work/lazyseedfrom
work/onefile

Conversation

@espetro

@espetro espetro commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Adds a onefile output for island bundles and measures it on the yt-dlp composite. Measured on the VPS (11 dimensions, geometric mean, lower is better): V-onefile scores 0.644 against B1 (uv venv) and 0.635 against B2 (PyInstaller onefile). Both are below 1.0 and no dimension is worse than 2.0x (the worst is version_s at 1.61x the venv). The frozen composite definition and weights were not changed.

  • --onefile (needs --embed-python=bundle): the staged bundle travels as one zlib payload appended to a small C stub that extracts it once into a sha256-named cache directory and execs it. The stub links zlib only.
  • --strip-runtime and --embed-stdlib minimal shrink the bundle (artifact 18.8 MB against B2 at 41 MB).
  • Two fixes to the minimal stdlib trim (duplicate zip entries, the sysconfig data module).
  • The self-compiled pyscriptc is one 14.5 MB file. It still needs a C toolchain and pyrefly on the host, documented in docs/reference/runtime-pack.md.
  • Output of the onefile -j extract matches B1 apart from the epoch key. Startup costs about 0.4 s once for extraction, then under a millisecond.

Branch note: work/onefile was cut before the CI-fix merges, so its history diverges from work/lazyseed (9 commits only here, 37 only there). Needs a rebase or merge before landing. Not verified by CI yet.

Stacked on #797.

🤖 Generated with Claude Code

Agent added 9 commits October 30, 2026 21:01
The bundle ships as a directory tree, so it loses the composite's files_n
dimension against a onefile baseline. The new --onefile flag writes the
bundle as one executable: the payload travels appended to a small C stub,
which inflates it into the cache (keyed by the payload's sha256) on the
first run and execs the extracted binary on every run.

The stub links zlib and reads our own flat record stream, so a host needs
no tar and no Python: a slim container image runs the onefile as it runs
the bundle. The cache key is the payload digest, so a rebuild extracts
beside the old tree instead of over it, and a run that races another
first run loses the atomic rename and execs the winner's tree.

--strip-runtime strips the staged libpython: plain strip keeps .dynsym,
where every PyInit_* entry point lives, and drops the debug and static
symbol tables, about 12 MB off the 32 MB Linux libpython.
V-onefile is the bundle written as one executable: the payload travels
appended to a stub, which extracts it into the cache on the first run.
The dimensions, the weights and the pass rule are untouched; the runner
only gains a candidate to measure.
A package's __init__.py answers two names (the package and the module the
closure reaches through it), so the same file landed in the zip twice. The
archive writer warns about the duplicate name and the importer reads the
entry twice; 19 of 478 sources were duplicated on the yt-dlp build.
sysconfig reads the build's configuration through a data module whose name
carries the platform and the ABI flags, imported by name at run time. The
static closure cannot see it, so the minimal trim dropped it and a
self-compiled pyscriptc failed its first sysconfig call with a
ModuleNotFoundError. The module travels whenever the trim keeps
sysconfig.

Also documents the onefile output and adds the selfbin-onefile task: the
self-compiled compiler as one executable, and the host's remaining needs
(a C toolchain, pyrefly) named as a known gap.
The onefile output gets its own fixture: the self-compile with
--onefile and --strip-runtime, checked as a single file that runs
on its own and compiles a hello world.

The stub also creates the cache root's parent directories, so a
cache root under a fresh HOME works.
…site

The 2026-11-02 run on the shared VPS replaces the pre-onefile numbers.
V-onefile is the bundle written as one 18.8 MB executable (minimal trim,
stripped runtime, zlib payload appended to the extraction stub):

| candidate | vs B1 | vs B2 |
|---|---|---|
| V-bundle | 1.009 | 0.994 |
| V-minimal | 1.010 | 0.996 |
| V-onefile | 0.644 | 0.635 |

No dimension of V-onefile is worse than 1.62x a baseline (version_s
against the venv), so the no-worse-than-2x rule holds against both, and
the composite is below 1.0 on both sides - the first PASS the composite
has produced. The earlier session's load average was 3.55 during this
run; every timing is still the min of 7 interleaved samples.
The runtime pack reference records the 2026-11-02 composite table and the
verdict (V-onefile 0.644 vs B1, 0.635 vs B2 - the first PASS), plus the
measured cold and warm starts of the onefile's first-run extraction.

The known-gap section now says what closing each gap would cost and why
both stay host tools: a onefile with a C toolchain would carry a second
compiler, and pyrefly is a separate program with its own release cadence.
The 14.5 MB self-compiled onefile runs and compiles a hello world with
only cc on PATH, which is the measured boundary of what the file carries.
@espetro espetro added this to the v0.8.0 milestone Nov 2, 2026
@espetro espetro added this to pyscriptc Nov 2, 2026
@github-project-automation github-project-automation Bot moved this to Todo in pyscriptc Nov 2, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant