Repository navigation
fix(installer): route setup.sh and setup.py through the launcher's scratch-and-commit install (#573) - #576
Conversation
…ratch-and-commit install (#573) Both installers ran `pip install --target` straight into the persistent deps directory. pip skipped every package directory that already existed but still wrote the new *.dist-info, so the 4.21.0 -> 4.22.0 upgrade kept sentence-transformers 5.6.1 code under 6.0.1 metadata and verification failed on tokenizers. - launcher_deps.install_requirements (also `python3 launcher_deps.py -r FILE DEPS_DIR`) installs a generated closure into scratch under the deps lock and commits it through _commit_resolved_entries. - setup.sh step 3 moves to scripts/lib/install_python_deps.sh and calls it; setup.py calls it as a subprocess. No direct --target remains. - dist_info_versions omits a distribution with several *.dist-info, so a directory an earlier upgrade left mixed is repaired whatever order the filesystem lists it in. Decision: ADR-1063. Follow-up on guard churn: #575. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
ZETETIC-REVIEW: APPROVE SummaryRoutes Concurrency contract (ADR-0749/1059)
|
Summary
scripts/setup.sh(the--postgrespath ofinstall-plugin.sh) andscripts/setup.pyranpip install --targetstraight into the persistent deps directory. pip skipped every package directory that already existed but still wrote the new*.dist-info, so the 4.21.0 → 4.22.0 upgrade kept sentence-transformers 5.6.1 code under 6.0.1 metadata and step 6/7 failed on tokenizers. Both installers now go through the launcher's scratch-and-commit install, the path ADR-1059 already named as the only one allowed to refreshdeps/. Decision recorded as ADR-1063.launcher_deps.install_requirements(alsopython3 scripts/launcher_deps.py --requirement FILE DEPS_DIR) installs a generated closure intodeps.tmp-<pid>under the launcher'sdeps.lock, with--no-deps --require-hashes, and commits through the existing_commit_resolved_entries(per-entry rollback, then pruning of superseded*.dist-info).setup.shstep 3 moves toscripts/lib/install_python_deps.shand calls it;setup.pycalls it as a subprocess. No direct--targetintodeps/remains in either installer.launcher_deps_fs.dist_info_versionsomits a distribution that has several*.dist-info. Before, it kept whichever oneos.listdirreturned last, so with the pinned one listed last the guard read the stale package directory as satisfied and skipped it. Re-runninginstall-plugin.shnow repairs a directory a 4.22.0 upgrade left mixed.Closes #573
Type of change
Test plan
pytest, 8640 passed, 8 skipped.tests_py/scripts/test_installer_upgrade_single_version.pybuilds two wheels of a probe distribution and runs real pip, offline, through thesetup.shlibrary step and throughsetup.py install_deps(). It starts from version N and from the mixed state 4.22.0 left, and asserts one*.dist-infoper distribution matching the pin, pinned code on disk, and no scratch or backup left behind. It also checks that a hash mismatch fails thesetup.shstep and leaves N in place (setup.pystill only warns on a failed install and continues, as it did before this PR), and thatsetup.shcalls the library withrequirements/setup.txt. Onorigin/main'ssetup.pythe upgrade tests fail with['cortexprobe-1.0.dist-info', 'cortexprobe-2.0.dist-info'].test_launcher_deps.py:dist_info_versionsomits a doubled distribution in both listing orders, andpip_installreplaces old code under new metadata when the pinned dist-info is listed last. All three fail onorigin/main'slauncher_deps_fs.py.test_setup_py_installs_from_lock.pynow checks the argvsetup.pyhands to the launcher (no--target) and the pip argv the launcher builds (--no-deps,--require-hashes,-r requirements/setup.txt,--target= scratch, no--upgrade).dist_info_versionsfails the three new launcher tests, andorigin/main's direct--targetinsetup.pyfails both upgrade tests. Not run:mutation_check.shover the new code. Note that the end-to-end "from 4.22.0 mix" cases pass on the old guard when the filesystem happens to list the old dist-info last (this APFS volume did, in the probe fixture), which is why the listing order is forced in the unit tests.requirements/setup.txt, Python 3.14.4, macOS 26, on an APFS clone of the maintainer's 4.22.0 deps (213 entries). I rebuilt the [bug] install-plugin.sh --postgres leaves mixed package versions in the deps directory on upgrade #573 state there (sentence-transformers 5.6.1 code, 5.6.1 and 6.0.1 dist-info, 6.0.1 listed last) and ranpython3 scripts/launcher_deps.py -r requirements/setup.txt <clone>: exit 0 in 77 s, no distribution with more than one dist-info, every pin that applies to this platform matched, code 6.0.1 / transformers 5.16.1 / tokenizers 0.23.2 / huggingface_hub 1.30.0,SentenceTransformer('all-MiniLM-L6-v2').encode→ (1, 384).ruff checkandruff format --check(0.16.6, the CI pin),check_craftsmanship.py --base origin/main,check_no_deps_invariant.py,shellcheckon the new library.Audit notes
yaml,sklearn,google,bin, …). Their content is identical and they go through the same atomic rename; numpy, torch and transformers kept their inode. This comes from the existing launcher guard and now also applies to the installers. Recorded in ADR-1063 and filed as [bug] deps idempotence guard replaces entries whose name is not their distribution's on every install #575.clean_environment: inheritedPIP_INDEX_URL/PIP_EXTRA_INDEX_URL/PIP_FIND_LINKSand pip config files ignored, indexhttps://pypi.org/simple/), the same one the runtime bootstrap already used. Recorded in ADR-1063.Coding-standards compliance
--targetcalls are removed, not kept as a fallback.Breaking changes
None for users. Anyone who relied on
PIP_INDEX_URLor a pip config file duringinstall-plugin.shnow gets PyPI, as the launcher already did at runtime.Reviewer checklist
docs/adrmirror).🤖 Generated with Claude Code