Skip to content

Make the uv bootstrap chain survive venv recreation#19

Open
Anmolnoor wants to merge 1 commit into
mainfrom
fix/bootstrap-uv-survives-sync
Open

Make the uv bootstrap chain survive venv recreation#19
Anmolnoor wants to merge 1 commit into
mainfrom
fix/bootstrap-uv-survives-sync

Conversation

@Anmolnoor

Copy link
Copy Markdown
Owner

Problem

After Homebrew upgraded Python 3.12.12 → 3.12.13, uv recreated .venv to match the lockfile exactly — which removed the unlocked pip and uv binaries. That broke both ends of the bootstrap chain:

  • foundation (the shell alias → ./scripts/uv) failed with Missing .venv/bin/uv. Run ./scripts/bootstrap.sh first.
  • ./scripts/bootstrap.sh crashed at line 150 (.venv/bin/pip: No such file or directory) because it only creates the venv when the directory is entirely missing, then assumes pip exists.

So the documented recovery path could not recover.

Fix (root cause, three parts)

  1. Declare pip and uv as dev dependencies (with a comment explaining why) — uv sync makes the environment exactly match the lockfile, so the only way the wrapper's .venv/bin/uv survives syncs and interpreter-upgrade recreations is to be in the lockfile. This also makes the system self-healing: after a future interpreter upgrade, the still-working uv binary re-syncs and reinstalls itself into the fresh venv.
  2. Teach bootstrap.sh to rebuild a venv that has neither pip nor uv (python -m venv --clear), so it can recover from the exact state users hit.
  3. Contract test (tests/test_dev_env_contract.py) asserting uv and pip stay in the dev extras — fails before the fix, passes after, and stops anyone from quietly resurrecting the footgun.

Verification

  • Reproduced the user-reported failure verbatim before the fix (./scripts/uv run … → "Missing .venv/bin/uv", bootstrap → pip not found).
  • Fixed ./scripts/bootstrap.sh run end-to-end on the broken venv: rebuilds it, installs uv, syncs — exit 0.
  • ./scripts/uv run foundation --help (the alias path) works again.
  • Probe: a subsequent exact ./scripts/uv sync --extra dev keeps pip and uv (this is the operation that used to strip them).
  • 461 tests pass, ruff clean.

🤖 Generated with Claude Code

A Homebrew Python upgrade (3.12.12 -> 3.12.13) made uv recreate .venv
against the lockfile, which removed the unlocked pip and uv binaries:
./scripts/uv hard-requires .venv/bin/uv, and bootstrap.sh assumed
.venv/bin/pip exists whenever .venv does, so its recovery path crashed
at 'pip install uv' and the user was stuck.

Declare pip and uv as dev dependencies so every sync keeps them in the
venv, teach bootstrap.sh to rebuild a venv that has neither binary, and
add a contract test so they cannot be dropped from the dev extras
again. Verified end-to-end: bootstrap heals the broken venv, and an
exact 'uv sync --extra dev' no longer strips either binary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant