RepoWatch / GitHub signal
uv 0.12 tightens Python project and package safety boundaries
uv 0.12 is a worthwhile safety upgrade, but its deliberate behaviour changes deserve a staged rollout across agent projects.
Hermes, OpenClaw and other Python-heavy agent systems depend on repeatable environments; safer package handling helps, while changed resolution and project-discovery rules can alter unattended jobs.
What changed
astral-sh/uv 0.12.0 is a deliberate compatibility boundary rather than a routine patch. Astral says most users should upgrade without making changes, but the release collects correctness, safety and specification changes that can break workflows relying on older behaviour.
The most visible change is what happens when a project is created. uv init now produces a packaged project by default: it declares uv_build, places application code under src/, and creates a project script. Existing projects are unaffected, and uv init --no-package preserves the old unpackaged layout.
The operational changes are more important than the new scaffold:
- wheels that could overwrite a virtual environment’s Python interpreter are rejected, including case variants and files hidden under wheel data directories;
- a
--require-hashesdirective insiderequirements.txtnow actually enables hash checking instead of merely producing a warning; - MD5-only requirements are rejected when hash checking is required;
- malformed
pylock.tomlfiles and artifact-size mismatches now fail rather than being interpreted permissively; uv venv --clearrefuses to delete a directory that is not a recognised virtual environment unless--forceis explicit;- broken
.venvsymlinks stop environment discovery instead of allowing uv to walk upwards and potentially modify an unrelated parent environment; - invalid certificate overrides now cause HTTPS to fail rather than silently falling back to default trust roots;
- pre-release handling now prefers stable versions and falls back to pre-releases when necessary, including when a transitive dependency introduces the requirement;
uv run path/to/script.pydiscovers the project relative to the script rather than the current working directory.
The follow-up default-branch commit prunes superseded workspace artefacts on macOS and Windows, but that commit is newer than the tagged 0.12.0 release and should not be confused with the release contents.
Why it matters
Agent systems turn package-manager edge cases into operations problems. A human notices when a command selects the wrong environment, resolves an unexpected pre-release or clears the wrong directory. A scheduled worker may simply keep going until the failure appears several steps later.
Several uv 0.12 changes replace permissive behaviour with an explicit stop. That is good policy for Hermes, OpenClaw and similar automation:
- refusing interpreter replacement reduces the damage a hostile or malformed wheel can cause;
- enforcing requested hashes closes a gap between the apparent and actual supply-chain policy;
- failing on a broken
.venvsymlink avoids quietly targeting an ancestor environment; - requiring
--forcebefore clearing an ordinary directory makes destructive intent machine-readable; - strict certificate overrides prevent a bad private-CA configuration from silently changing the trust model.
Those are meaningful improvements when agents install tools, create disposable environments or run code from repositories they did not author.
The same strictness also creates migration risk. A job that depended on current-working-directory project discovery may now select a different environment. A constraints graph can resolve differently under the new pre-release policy. Internal packages with legacy archives, weak hashes or unusual wheel layouts may stop installing. None of those is a reason to avoid the release; they are reasons not to replace uv everywhere without replaying real jobs first.
My read
Worth a staged update, not a blind global upgrade. The safety changes are directionally right and unusually relevant to unattended Python work. The release also announces its compatibility boundary honestly, so treating it like an invisible patch would be operator error rather than an Astral surprise.
A sensible rollout is to pin 0.12.0 in one non-production agent environment and exercise the tasks most likely to cross the changed boundaries:
- create both packaged and deliberately unpackaged projects;
- run scripts inside and outside their project directories;
- sync lockfiles and hashed requirements used by deployed services;
- rebuild disposable virtual environments and test cleanup paths;
- install private packages through any custom index or certificate configuration;
- replay scheduled jobs that call
uv run, especially from generic working directories.
Compare resulting lockfiles and selected package versions before promoting the upgrade. If an agent image or bootstrap script expects the old uv init layout, make --no-package explicit rather than depending on historical defaults.
The broader lesson is useful: safe automation needs commands that refuse ambiguity. uv 0.12 contains several examples of a tool choosing a hard error over a plausible but dangerous guess. Agent platforms should apply the same principle to filesystem writes, credentials and production changes.
Bottom line
uv 0.12 is more than a version bump. It hardens package installation, hash enforcement, certificate handling, environment discovery and destructive virtual-environment operations, while changing a handful of behaviours that unattended jobs may rely on.
For Python-based agent infrastructure, the right call is to test it now and roll it out with an explicit pin after workload replay. The safety gain is real; so is the need to inspect dependency resolution and project selection before making it the default everywhere.