ENG-1646: self-heal scratchpad venv creation instead of retrying an identical failure - #359
Open
torrmal wants to merge 1 commit into
Open
ENG-1646: self-heal scratchpad venv creation instead of retrying an identical failure#359torrmal wants to merge 1 commit into
torrmal wants to merge 1 commit into
Conversation
…dentical failure
uv venv occasionally writes bin/python as a copied, merely ad-hoc-signed
launcher instead of a symlink to the base interpreter, and the copy is
missing its own libpythonX.Y.dylib. macOS's AMFI kills it outright
("Unrecoverable CT signature issue"), and since the failure is deterministic
per environment, all 3 retries repeated the identical uv call and failed
identically.
- _create_venv() now repairs a copied launcher into a direct symlink after
uv reports success, since every symlinked interpreter we observed worked.
- _ensure_venv()'s final retry escalates to the stdlib venv.create fallback
instead of repeating the same uv invocation a third time.
- The venv directory is preserved after the final failed attempt (previously
nuked unconditionally), and the raised error now includes symlink/size/
codesign detail via _diagnose_broken_interpreter() instead of going silent
once _last_verify_error is unset.
Co-Authored-By: Claude Sonnet 5 <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.
Summary
Fixes ENG-1646.
uv venvnormally symlinks a new venv'sbin/pythonstraight to the base interpreter. On at least one real machine, when invoked from inside the packaged Cowork desktop app's process tree,uvinstead wrotebin/pythonas a freshly-copied, merely ad-hoc-signed launcher — missing its ownlibpythonX.Y.dylib— and macOS's AMFI killed it outright the moment anything tried to run it:Because the failure is deterministic per environment (not transient), all 3 of
_ensure_venv()'s retries repeated the identicaluv venvcall and failed identically — so restarting the app, renaming the scratchpad, or waiting and retrying never helped. The full repro/diagnosis is in the Linear issue.Changes
_create_venv()now checks whether uv actually produced a symlink forbin/python; if it instead wrote a copy,_repair_copied_launcher()replaces it with a direct symlink to the resolved base interpreter. Every symlinked interpreter observed in testing worked; every copied one was killed by AMFI._ensure_venv()'s retry loop now escalates strategy instead of repeating the same doomed call: the final attempt bypassesuventirely and falls back to stdlibvenv.create(symlinks=True), which has been reliable in every environment this was tested against._diagnose_broken_interpreter(): symlink vs. copy, file size, and codesign status on macOS) instead of going silent whenever_last_verify_errorwas never set (e.g. the interpreter file simply doesn't exist).Test plan
uv run pytest tests/test_local_venv_provisioning.py -v— 23 passed (6 new, covering the repair, the escalation order, directory preservation, and the new diagnostic detail)uv run pytest tests/test_scratchpad.py tests/test_chat_scratchpad.py tests/test_scratchpad_flavor.py tests/test_scratchpad_utf8.py tests/test_scratchpad_watchdog_contracts.py tests/test_scratchpad_observer_dispatch.py -q— 211 passed, no regressions🤖 Generated with Claude Code