fix(worktree): provision a worktree venv against constraints.lock, like CI does - #68
Merged
Merged
Conversation
…ke CI does
Every install in ci.yml passes `--constraint constraints.lock`, and ci.yml's own comment
says why: "Without it, `uv pip install -e ".[extras]"` RE-RESOLVES". scripts/worktree/
new.ps1 was the one place that omitted it, so a fresh worktree resolved freely inside
pyproject's ranges and could disagree with CI on any tool.
Not hypothetical -- it cost most of a session. A worktree created 2026-07-29 came up
with ruff 0.16.0 while constraints.lock pinned 0.15.22 (installed past pyproject's
`<0.16` cap). Two consequences, and the second is why this is a guard rather than a
tidy-up:
* it reported ~829 findings CI does not have (0.16 turned on stricter defaults), so
"lint is red" meant nothing; and
* the ruff-check pre-commit hook runs `ruff check --fix`, so it REWROTE files to
match -- stripping `# noqa` directives the pinned ruff still wants.
A venv that lints differently from CI does not merely mislead, it edits your source on
commit. The same worktree was also missing pytest-asyncio and pytest-rerunfailures, so
every async test ERRORED and a "154 passed" run silently covered only the non-async
files. Constraining the install does not by itself fix a partial install, but it
removes the version half of that class.
tests/test_worktree_venv_constraint.py pins it three ways:
1. every editable project install in new.ps1 carries --constraint;
2. constraints.lock actually EXISTS and parses to a plausible number of pins -- a
flag pointing at a missing or near-empty file constrains nothing, which is the
same outcome as omitting it, and would only surface on a developer's first run;
3. ci.yml still constrains too. Asserted in that direction deliberately: the property
is "developer provisioning agrees with CI provisioning", not "new.ps1 contains a
flag". If CI ever moves off constraints.lock this fails and forces the two to be
reconciled rather than drifting apart again.
Proven by injecting both regressions:
revert to the bare `pip install -e ".[extras]"` -> caught, "WITHOUT --constraint"
delete the install line entirely (vacuity trap) -> caught, "no longer contains an
editable project install"
A text test because nothing in the suite can run new.ps1 -- it creates a git worktree
and a venv, minutes of I/O, and mutates the repo's worktree list. The invariant is a
property of the COMMAND, so it is asserted against the command; same posture as
tests/test_ci_venv_pinning.py, which pins workflow install lines no test can execute
either.
77 passed across the worktree, scaffold, gate-wiring and DEP-1 lockstep suites.
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.
Every install in
ci.ymlpasses--constraint constraints.lock, and ci.yml's own comment says why: "Without it,uv pip install -e ".[extras]"RE-RESOLVES".scripts/worktree/new.ps1was the one place that omitted it, so a fresh worktree resolved freely insidepyproject's ranges and could disagree with CI on any tool.Not hypothetical — it cost most of a session
A worktree created 2026-07-29 came up with ruff 0.16.0 while
constraints.lockpinned 0.15.22 (installed past pyproject's<0.16cap). Two consequences, and the second is why this is a guard rather than a tidy-up:ruff-checkpre-commit hook runsruff check --fix, so it rewrote files to match — stripping# noqadirectives the pinned ruff still wants.A venv that lints differently from CI doesn't merely mislead; it edits your source on commit.
The same worktree was also missing
pytest-asyncioandpytest-rerunfailures, so every async test ERRORED and a "154 passed" run silently covered only the non-async files. Constraining the install doesn't by itself fix a partial install, but it removes the version half of that class.The guard
tests/test_worktree_venv_constraint.pypins it three ways:new.ps1carries--constraint;constraints.lockactually exists and parses to a plausible number of pins — a flag pointing at a missing or near-empty file constrains nothing, which is the same outcome as omitting it, and would only surface on a developer's first run;ci.ymlstill constrains too. Asserted in that direction deliberately: the property is "developer provisioning agrees with CI provisioning", not "new.ps1 contains a flag". If CI ever moves offconstraints.lock, this fails and forces the two to be reconciled rather than drifting apart again.Verification
Both regressions injected:
pip install -e ".[extras]"A text test because nothing in the suite can run
new.ps1— it creates a git worktree and a venv, minutes of I/O, and mutates the repo's worktree list. The invariant is a property of the command, so it's asserted against the command; same posture astests/test_ci_venv_pinning.py, which pins workflow install lines no test can execute either.77 passed across the worktree, scaffold, gate-wiring and DEP-1 lockstep suites.