emrg: packaging: disable library validation on bundled python so pip C extensions load (journal R2 scipy blocked) - #967
Conversation
…so pip C extensions load (rant: journal R2 scipy ILP blocked)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260825-060822 (1/3)
Independent review of head f6ff0f4 passed:
- Root cause sound:
--options runtime(hardened runtime) + nocom.apple.security.cs.disable-library-validationentitlement → macOS library validation blocks unsigned pip C extensions ("different Team IDs"). Standard, well-understood macOS behavior; the entitlement is the canonical plugin-loading allowance and is accepted by notarization. - Fix scope correct: entitlement applied only to
python*Mach-O binaries inside the codesign loop (python3.13matches; non-Mach-O wrappers likepython-configare filtered out by thefile/Mach-O grep). Venv pythons are symlinks to the same binary → inherit automatically. - Fail-loud guard solid: the assertion lives outside the
while readsubshell, soexit 1genuinely aborts; it greps thecodesign -d --entitlements -output (not exit code), so a missing entitlement is reliably detected in both positive and negative states. - $ROOT is defined (line 25) before the loop uses it;
bash -nclean; plist is valid XML (plutil OK). - CI green: test + test-windows both pass (run 32780579817); the change is macOS-only and does not touch the .iss render step.
No issues found.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260825-065036 (2/3)
Re-review: head f6ff0f4 unchanged since LGTM 1/3 (060822); merge state CLEAN/MERGEABLE; CI green (test + test-windows, run 32780579817). Diff reviewed again — entitlement scope (python* only), fail-loud assertion outside the subshell, plist validity, and $ROOT usage all confirmed. No issues found.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260825-065657 (3/3)
Final review: head f6ff0f4 unchanged, merge state CLEAN/MERGEABLE, CI green (test + test-windows, run 32780579817). Three consecutive LGTMs from distinct cycles (060822 → 065036 → 065657), no ❌ in between. Merging.
Fixes pip-installed C extensions failing to load under the bundled Python (blocks journal R2 scipy ILP even after the #966 venv fix).
Symptom (observed by the silicon-science-cs journal task, 2026-08-25)
pip-installed C extensions fail to import in the bundled python:
Even with a working venv (#966),
import numpy/import scipyfails — research tasks cannot install/use any C-extension dependency.Root cause
packaging/make-installer.shre-signs all runtime Mach-O binaries (required for notarization) with:--options runtime= hardened runtime. With hardened runtime and nocom.apple.security.cs.disable-library-validationentitlement, macOS enforces library validation: the main executable may only load libraries signed by the same Team ID (or Apple). PyPI wheels are unsigned/ad-hoc → "different Team IDs" on every dlopen.Reproduced locally on the real install bundle (negative + positive states):
disable-library-validationFix
packaging/assets/python-entitlements.plist(new):com.apple.security.cs.disable-library-validation = true— the standard plugin-loading entitlement; notarization accepts it.packaging/make-installer.sh: apply--entitlementsonly topython*binaries in the codesign loop (the interpreter is the process that loads plugins; .so/.dylib entries don't need it), then fail-loud: assert the signedpython3.1Xcarries the entitlement, exit 1 otherwise (prevents silent regression).The entitlement is on the interpreter itself, so venv pythons (symlink to the same binary) inherit it automatically. Linux/Windows unaffected (block is macOS-only).
Verification
codesign -d --entitlementsand loads the unsigned dylib.bash -n packaging/make-installer.shclean; the test.yml emrg.iss heredoc render step unaffected.pytest tests/: 1050 passed + 1 skipped; import check +emrg --helpOK.Host self-check (after next install):
codesign -d --entitlements - ~/.emrg/install/bin/python-dist/bin/python3.13 | grep disable-library-validationshould match; thenpython -m venv .v && .v/bin/pip install numpy && .v/bin/python -c "import numpy"works.