Repository navigation
Bug hunt ledger: uv #310
Replies: 30 comments
|
[agent] 2026-09-30: handover from the Poetry bug-hunt routine (ledger #311) While checking Poetry mode switches I hit the same defect on a uv project. I filed it as #328 with the Poetry evidence. Here's the uv side so you can add a uv comment to that issue, or file a uv-specific one if the root cause differs. hosted → vendored on a uv project is refused as a "user-authored" source. main printf '[project]\nname = "uvp"\nversion = "0.1.0"\nrequires-python = ">=3.9"\ndependencies = ["six==1.16.0"]\n' > pyproject.toml
uv lock && uv sync
socket-patch scan --mode hosted --json --yes # redirected: 1
uv sync
socket-patch scan --mode vendored --json --yes
# -> failed pypi_uv_source_already_exists "[tool.uv.sources] already declares a source for six; refusing to overwrite a user-authored source"
# uv.lock still: source = { url = "http://127.0.0.1:18080/patch/pypi/six/1.16.0/<token>/<uuid>/six-1.16.0-py2.py3-none-any.whl" }Root cause (shared): Not yet checked for uv: vendored → hosted, and lock-only hosted → vendored (on Poetry that fails Also unconfirmed for uv: on Poetry, vendored |
|
[agent] 2026-09-30: uv bug-hunt run This is the first run. The ledger started empty and there were no Tested: main Setup: the sandbox blocks the Socket patch hosts, so a local mock of the authenticated patch API ( Cells (Linux unless noted)
Issues
False positives ruled out
Probe runs
I couldn't delete either probe branch: the git proxy silently ignores ref deletes ("Everything up-to-date"), the same as for the siblings. A maintainer needs to delete Next
|
|
[agent] 2026-09-30: handover from the PDM bug-hunt routine (ledger #312) While filing #382 (hosted PDM rollback/remove stuck once the patched package leaves This may already be covered by #379 (uv drift after |
|
[agent] 2026-10-01: uv bug-hunt run Tested: main Harness changes for v5: hosted mode now keeps no ledger. Rollback/remove re-derive the upstream entry from PyPI's JSON API, and they need Re-triage
Cells (Linux 0.12.21 unless noted)
Issues
False positives ruled out
Probe runs
Branch deletes are still silently ignored by the git proxy. A maintainer needs to delete Next
|
|
[agent] 2026-10-01: maintainer note: test global ( This is a maintainer request, not a run report. Add it to the top of the backlog and keep it there until the cells below are covered. Ask: make sure we correctly scan global installs when Where uv puts global installs: What to check (prove each with a real global install, not by reading source):
Add OS × uv version cells for |
|
[agent] 2026-10-01: uv bug-hunt run Tested: main Re-triageMain hasn't moved since #407, #408 and #411 were filed, so they're still open and unchanged. No re-test was needed. Cells (global mode)
Issues
False positives ruled out
Probe runs
Branch deletes are still silently ignored by the git proxy. A maintainer needs to delete Next
|
|
[agent] 2026-10-01: uv bug-hunt run Tested: main Re-triage
Cells (Linux 0.8.17 unless noted)
Issues
False positives ruled out
Probe runs
The git proxy still silently ignores branch deletes. A maintainer needs to delete Operator note: a failed Next
|
|
[agent] 2026-10-01: uv bug-hunt run Tested: main The harness is new this run. It uses a Python mock patch API: the wheel is deterministic (fixed zip dates), Re-triage
Cells (Linux 0.8.17 unless noted)
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-02: uv bug-hunt run Tested: main Re-triageMain hasn't moved, so nothing needed re-running. Fixes are in flight: #512 (#407, #408), #481 (#474), and #449 is claimed (agent/fix-python-global-tool-roots). Cells (Linux, uv 0.8.17 unless noted)
Issues
False positives ruled out
Probe runsNone this run (everything new was OS-independent text edits or Linux env-var probing). No branches pushed. Next
|
|
[agent] 2026-10-02: uv bug-hunt run Tested: main Re-triageMain hasn't moved, so I re-ran nothing. Open fix PRs: #540 (#525 and the env discovery issues), #512 (#407, #408), #481 (#474). Cells (Linux)
Issues
False positives ruled out
Probe runsNone this run. #525 already has a fix PR (#540), and the new finding is a CLI text match that doesn't depend on the OS. Next
|
|
[agent] 2026-10-02: uv bug-hunt run Tested: main Re-triageMain hasn't moved, so nothing was re-run on main. I tested PR #545 against the new #544 spellings (below): fixed. Cells (Linux)
Issues
False positives ruled out
Probe runsNone this run. #564 is driven by config, not the OS. No branches pushed. Next
|
|
[agent] 2026-10-02: uv bug-hunt run Tested: main Re-triage (current main)
Cells (Linux)
Issues
False positives ruled out
Probe runsNone. #606 is OS-independent TOML logic. No branches were pushed. Next
|
|
[agent] 2026-10-03: uv bug-hunt run Tested: main Re-triage
Cells (Linux)
Issues
False positives ruled out
Probe runsNone. #639 is OS-independent TOML logic. Next
|
|
[agent] 2026-10-03: uv bug-hunt run Tested: main Re-triageMain hasn't moved since run 9, and PR #625 is still open, so nothing was re-run for #606 / #473 / #411 / #564 / #639.
Cells (Linux unless noted)
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-03: uv bug-hunt run Tested: main Re-triageMain hasn't moved and no uv fix PR has merged (#672 and #625 are still open), so there was nothing to re-run. #606, #473, #411, #564, #639, #670 and #701 are unchanged. Cells (Linux)
Issues
False positives ruled out
Probe runsNone. The new cells are lock-text routing, which doesn't depend on the OS. Earlier probe branches still need maintainer cleanup (see 20261003T085904Z). Next
|
|
[agent] 2026-10-04: uv bug-hunt run Tested: main Re-triageMain hasn't moved, and no uv fix PR has merged (#672, #625 and #708 are still open; #730, which fixes Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-04: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-04: uv bug-hunt run Tested: main Re-triageMain has had no new commits since run 15, and PRs #743 / #672 / #625 have the same heads, so I re-checked no issues (results would be identical). Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-04: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-05: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-05: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] Janitor: ledger drift. This ledger was last updated on main
Please re-verify those cells on main Generated by Claude Code |
|
[agent] 2026-10-05: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-05: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-06: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-06: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-06: uv bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-06 15:37Z: handover from the Pipenv bug-hunt routine (#313) On main Worth checking in your lane: a lock-only checkout (no |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
[agent] Progress ledger for the scheduled uv bug-hunt routine (label pm:uv).
Last run: 2026-10-06 (run 24) on main
9c43dfc(main unchanged since run 21. New #944: the hosted → vendored takeover (scan/get --mode vendored) restores six to PyPI BEFORE the uv vendored refusals run, so an inline[tool.uv] sources = {…}table (pypi_uv_lock_parse_failed) or a #928 marker-split requirements.txt (pypi_requirement_not_pinned) leaves six unpatched in both modes, exit 1, while--dry-runpreviewswould_vendor; Linux × 0.5.31 / 0.8.17 / 0.12.23. Standalonevendorkeeps it hosted (pass). #928 commented: the split across a-rinclude refuses the same way). Run 23 on main9c43dfc(main unchanged since run 21. New #928: vendoredrequirements.txtfromuv pip compile --universalwith a marker-split package (six==1.16.0 ; python<3.12+six==1.17.0 ; python>=3.12) refusespypi_requirement_not_pinned("not pinned to ==1.16.0", which is false) while--dry-runpreviewswould_vendor; hosted and vendored pylock handle the same split; Linux × 0.5.31 / 0.8.17 / 0.12.23. Universal pylock (hosted + vendored), the vendored pylock lifecycle with vex and a regenerated lock, and a forked script lock refusal all pass). Run 22 on main9c43dfc(main unchanged since run 21. macOS confirms #890 and #891, so both now fail on all 3 OS. #890 also hits the project lane: a deleteduv.lockblocks revert / remove / rollback, and the takeover exits 0.--cwd(relative, absolute,.., space in the path), VEX after partial unwiring, agent mode on uv 0.2.37–0.12.23, a vendored pyproject-variant sweep andlistall pass). Run 21 on main9c43dfc(main moved: #858 atomic-write core, #802 vendored symlink refusal, #807 pip pylock rollback and others. New #890: once the user deletes one of several vendored PEP 723 scripts (or its.py.lock, or one of two pylocks),vendor --revert/remove/rollbackfail oncannot readfor the whole entry, and the V→H takeover exits 0 telling the user to run that same revert; Linux × 0.8.17 / 0.12.23 and Windows × 0.12.23. New #891: the vendored dry run (scan / get) gives novendor_would_refuse_symlinked_filefor a symlinkeds.py,s.py.lock,pylock.tomlorpylock.<name>.toml, although the wet run refuses (exit 1); Linux × 0.8.17 / 0.12.23 and Windows × 0.12.23. #723 and #767 (vendored half) re-checked: still fail. File modes, symlink refusals (hosted + vendored, no residue), uv-exported pylock hosted rollback, script-lock constraint / CRLF / index-source variants andvendor --checkafter unwiring all pass). Run 20 on main99f61d2(main moved: #789, #743, #822, #841, #625 and #672 merged, and #788 / #806 / #821 / #840 / #670 / #606 / #473 are closed. New #869: the #840 shape on PEP 723 script locks, where vendoredvendor --revert/remove/rollbackwrite the stale==1.16.0back intos.py.lockafter a specifier edit anduv run --lockedfails with exit 0; Linux × 0.5.31 / 0.8.17 / 0.12.23 and Windows. #411 and #564 re-checked: still fail. The #841 project-lane fix passes on 5 versions × deps / extra / dev × 11 specifier spellings). Run 19 on main045d7ec(new #840: after the user changes the vendored package's own specifier (uv add "six>=1.16,<1.17"), uv.lock stays byte-identical, because path sources carry no specifier, sovendor --revert/remove/rollbackwrite the stale pre-vendor==1.16.0back anduv sync --lockedfails with exit 0; 3 OS × 0.5.31 / 0.8.17 / 0.12.23, and not fixed by PR #822. PR #822 verified to fix #806 / #821 and their neighbours (two groups, include-group, deps + dev, user constraint-dependencies edit)). Run 18 (new #821: vendored package in a dependency group; afteruv add --dev/uv remove --dev,vendor --revert/remove/rollback/ V→H takeover revert pyproject.toml but keep uv.lock's whole-linerequires-devfragment, souv sync --lockedfails; 3 OS × 0.8.17 / 0.12.23, plus 0.2.37 / 0.4.30 / 0.5.31 on Linux. Script lock with a user override drift-keeps both files (consistent)). Run 17 on main045d7ec(new #806: vendored transitive override + a user-authoredoverride-dependencies; after a relock,vendor --revert/remove/rollbackrevert pyproject.toml but drift-keep uv.lock's[manifest] overrides, souv sync --lockedfails; 3 OS × 0.8.17 / 0.12.23. PR #789 verified to fix #788. Agent mode on a project.venvpasses on 3 OS × 3 link modes; script-lock CRLF / BOM,uv pip compileflavours, git / path / url siblings, name normalization and--dry-runall pass). Run 16 (new #788: uv 0.6.15–0.6.17 locks spellupload_time, so hosted rollback / remove / H→V takeover always refuse; 3 OS. Version sweep 0.6.17 / 0.7.22 / 0.9.30 / 0.10.12 / 0.11.33 otherwise passes; grant-token rotation passes; #767 extended to optional-dependencies and constraint-dependencies; requirements direct reference handed to pip). Run 15 (new #767: a PEP 508 direct-reference dependency (six @ https://…/git+…) gets vendored into a lock thatuv sync --lockedrejects while vex attests, and hosted overrides the user's URL and then refuses rollback; 3 OS × 3 uv versions. PR #743 verified to fix the hosted half of #742.-glifecycle passes on macOS / Windows via a probe. A uv lockless-pyproject shape was added to #638). Run 14 (new #742: a superseding patch uuid is never applied on uv. Hosted re-scan refuses its own[tool.uv.sources]pin with exit 0 while listing the upgrade; vendored failspypi_uv_source_already_exists. #701 extended to theuv pip compile --universalrequirements lane and to script locks. 0.12.23 baseline passes on 3 OS via a probe). Run 13 (new #723 V→H takeover strands a version-pinned-down vendored package while the dry run previews success; uv evidence added to #612, where vendored uv.lock + an exported requirements.txt is left silently unpatched; uv 0.12.23 baseline passes). Run 12 (#670 verified fixed on PR #672; new #701 hosted platform-specific wheel narrows the universal uv.lock; vendoredrepairwith two packages and a vendored platform wheel pass). Run 11 was on main045d7ec(new multi-package harness: requests / urllib3 / click / dateutil / jsonschema patches; hosted with deps / extras / partial unwind all pass; new #670 vendored multi-package revert residue; #449 Windows verified fixed on a probe). Run 10 was 2026-10-03 on main045d7ec+ draft PR #625 (new #639dynamic = ["dependencies"];conflicts,required-environments,dependency-metadatapass; PR #625 verified fixing #606 / #473). Run 9 was on main045d7ec(re-verified #525, #407, #408, #474 and #449-Linux as fixed; #473 and #411 still fail; new #606;[tool.uv]resolution settings, symlink link-mode). Run 8 was on main61cfb9b(unchanged; this run addedno-sources(#564), root-level dotted sources (#544, verified fixed on PR #545), vendored script dotted sources andrepairon dotted / CRLF). Run 7 added path/git siblings, legacy dev-dependencies, constraint-dependencies, vendored sources spellings and uv 0.12.22). Run 6 was also on61cfb9b(the dotted-name, sources-spelling, lock-only and UV_PROJECT_ENVIRONMENT cells). Run 5 was also on main61cfb9b(v5; CLI reports 4.0.0, and the released 4.0.0 predates both the v4 uv rewriter and the v5 upstream restore). Earlier cells are from2463257/6e7ef74. Linux runs use real uv against a local mock patch API (withintegrity.sha512in SRI form, a deterministic wheel, the/blob/route and--patch-server-url), plusSOCKET_PYPI_JSON_API→ a local pypi.org pass-through that must not rewrite file URLs. uv 0.1.x needsSSL_CERT_FILE; uv 0.0.5 needsPUFFIN_INDEX_URL→ a local/simple/proxy. macOS and Windows runs use probe branches.Coverage matrix
H = hosted, V = vendored, A = agent. "pass/fail" is Linux unless an OS is named. Results are from v5 main (
2463257/6e7ef74) unless marked (v4).[[distribution]])--frozen/--locked)uv add(Linux, macOS, Windows); fail #411 user override (Linux, Windows); fail #477uv synckeeps patched wheel after rollbackuv add(3 OS); fail #411 (3 OS); fail #473 (3 OS); fail #477 stale after rollback (uv.lock anduv pip sync)package = false,environments, self-ref extras, hashed-requirements variants, uv.lock + exported requirements.txt, two pylocks)uv remove/uv lock --upgrade-package; fail #407; fail #408 (re-confirmed on61cfb9b); fail #411; fail #473 include-group (3 OS); fail #477 stale after rollback/revertpylock.dev.toml, include-group); fail #474 script revert afteruv add --script(3 OS)uv syncafter rollback reinstalls upstream (uv-side fix in 0.8.18)--locked/--frozen/plain, inline sources, BOM, odd-case name, idempotent, VEX, pylock, script lock, CRLF, hashed requirements, markers, ranges, groups, extras, transitive override)uv add(3 OS), script lock, hashed requirements, CRLF, multi-file; fail #411 (3 OS); fail #407; fail #408; fail #473 (3 OS);uv pip syncafter requirements unwind fail #477 (3 OS)backports.tarfilein 3 spellings; dotted / root / inline sources spellings; lock-only checkout with space + unicode path,--frozencold cache, idempotent re-scan[tool.uv.sources.<name>]sub-table leaves an empty header (rollback, remove; also 0.5.31)UV_PROJECT_ENVIRONMENTignored (abs + relative)dev-dependencies(0.4.30 / 0.5.31 / 0.8.17),constraint-dependencies(0.8.17 / 0.9.5 / 0.12.22), inline[tool] uv = {…}/ roottool = {…}/sources.x.path--frozen --offline),[tool.uv.sources]before[project], CRLF; fail #544 dotted[tool.uv] sources.x/[tool] uv.sources.x: revert / remove half-revert (0.5.31, 0.8.17, 0.12.22)not a standard table)| 0.5.31 / 0.8.17 / 0.12.22 (run 8) | fail #564
[tool.uv] no-sources = true(alsouv.toml) | – | pass: script# [tool.uv]dotted sources,repairon dotted / CRLF; fail #544 root-leveltool.uv.sources.x(fixed on PR #545); existing{ index }source refused | pass (dotted, CRLF) | – | || 0.4.30 / 0.5.31 / 0.8.17 / 0.12.22 (run 9, main
045d7ec) | pass:exclude-newer-package,required-version,index-strategy,reinstall-package, default mirror index, pylock (compile + export; #407/#408 fixed); fail #606 six declared with different specifiers (deps + extra, two extras, marker split) | fail #606 (rollback, remove, takeover); fail #473 and #411 still reproduce; no-binary / no-build refused (documented) | pass: #606 pyproject; #474 script revert afteruv add --script(fixed) | – | pass:UV_PROJECT_ENVIRONMENTabs + relative (#525 fixed);UV_LINK_MODE=symlinkon 0.5.31 / 0.8.17 / 0.12.22 |-gUV_TOOL_DIRwith space + unicode: scan + agent apply pass (#449 Linux fixed) || 0.4.30 / 0.5.31 / 0.8.17 / 0.12.22 (run 10, main
045d7ec) | pass:[tool.uv] conflicts(extras),required-environments,dependency-metadata; fail #639dynamic = ["dependencies"](scan wires it) | fail #639 (rollback, remove, takeover; also on PR #625); #606 / #473 pass on PR #625 | pass: conflicts / required-environments / dependency-metadata (0.8.17, 0.12.22);dynamicrefused by design (pypi_uv_dynamic_dependencies) | – | – | || 0.5.31 / 0.8.17 / 0.12.22 (run 11, main
045d7ec) | pass: patched packages with deps / extras / markers (requests[socks], urllib3[socks,brotli], click, jsonschema[format] + transitive dateutil), two patched packages at once,uv pip compile --emit-*hashed requirements, pylock +pylock.dev.tomlwith deps | pass: full and partial rollback / remove (both orders), byte-identical | pass for a single package with deps; fail #670 two or more packages →vendor --revertleaves empty[tool.uv.sources](also hosted→vendored takeover); script locksdistreorder (cosmetic) | – | VEX after partial unwind pass | V→H takeover with 2 packages pass (#503) || 0.5.31 / 0.8.17 / 0.12.22 (run 12, main
045d7ec) | fail #701 platform-specific patched wheel (MarkupSafe cp311 manylinux) wired with no warning:uv sync --lockedfails on py3.12 and on macOS / Windows (--python-platform); pylock too | refused (documented: release has non-pure wheels) | pass: platform wheel (vendor_platform_locked), two packages afteruv add; #670 fixed on PR #672 (3 versions) | pass: two packages, one wheel deleted | – | || 0.5.31 / 0.8.17 / 0.12.22 / 0.12.23 (run 13, main
045d7ec) | pass: 0.12.23 baseline (uv.lock + exported requirements,--locked/ cold--frozen/uv pip sync, rollback byte-identical); V→H takeover with exported requirements | fail #723 V→H takeover after a vendored version pin-down (transitive / direct; 0.5.31, 0.8.17, 0.12.23; also on PR #708) | fail #612 (uv comment) uv.lock +uv exportrequirements.txt: requirements left unpatched with no warning (4 versions); script lock + uv.lock warns (documented) | – | pass (0.12.23 agent scan) | || 0.5.31 / 0.8.17 / 0.12.23 (run 14, main
045d7ec) | fail #742 patch upgrade (new uuid) not applied: project + script lock, exit 0; fail #701 (comment)uv pip compile --universalrequirements + script lock with a cp311 wheel; 0.12.23 baseline pass on Linux / macOS / Windows (probe) | pass: rollback byte-identical (3 OS); requirements platform-wheel rollback byte-identical | fail #742 re-vendor on a new uuid (pypi_uv_source_already_exists); baseline pass on 3 OS (unicode + space dir); H→V takeover with exported requirements: uv.lock pass, requirements.txt unpatched (#612) | – | – | V→H takeover pass on 3 OS || 0.5.31 / 0.8.17 / 0.12.23 (run 15, main
045d7ec) | fail #767 PEP 508 direct reference (six @ https://…): overrides the user URL; pylockarchiverollback becomes a registry entry; lockless pyproject is silent (#638 comment); pass: cross-version--locked, re-lock across revisions, trailing-slash index,resolution-markerslock,get(purl / uuid / name), concurrent scans; PR #743 fixes the #742 upgrade (project / override / script,--max-new-patches 0) | fail #767 (rollback refuses "direct reference", 3 OS) | fail #767 (requires-distgetsurl+path→--lockedfails, vex attests; also git refs, dependency groups; 3 OS); pass:get, forked lock | – | pass:UV_COMPILE_BYTECODE, 0.5.31 / 0.12.23 × hardlink / copy,get| script with space + unicode name pass || 0.6.15–0.6.17 / 0.7.22 / 0.9.30 / 0.10.12 / 0.11.33 (run 16, main
045d7ec) | pass: round trip on all; grant-token rotation (0.5.31 / 0.8.17 / 0.12.23); comments / editable path source formatting;build-constraint-dependencies;pylock.<name>.tomlnames; fail #767 direct ref in optional-dependencies / constraint-dependencies | fail #788 on 0.6.15–0.6.17 (upload_time: rollback, remove, takeover, script lock; 3 OS); pass on 0.7.x+ (3 OS for 0.7.22) | pass on all; fail #767 optional / constraint direct ref (--lockedfails, vex attests) | – | – | hosted write failure mid-commit leaves pyproject.toml half-written (recoverable by re-scan; candidate) || 0.5.31 / 0.8.17 / 0.12.21 / 0.12.23 (run 17, main
045d7ec) | pass: git / editable-path / URL siblings, marker-split sources arrays, script lock LF / CRLF / BOM,uv pip compileflavours,typing_extensionsname spellings, version spellings (==3.7.0,==3.7.*,~=),--dry-runwrites nothing | pass byte-identical (same cells);===refused (conservative);==3.07restores the user's spelling (cosmetic) | pass (same cells); fail #806 useroverride-dependencies+ transitive override, thenuv add/uv lock --upgrade-package→ half revert (3 OS × 0.8.17 / 0.12.23; 0.5.31 Linux) | – | pass: project.venvon Linux / macOS / Windows × default / hardlink / copy (probe), symlinked.venv; uv cache never polluted | lockless PEP 723 script: scanned 0 (unsupported input) || 0.2.37 / 0.4.30 / 0.5.31 / 0.8.17 / 0.12.23 (run 18, main
045d7ec) | pass: user constraint-dependencies + relock; script lock with user override / constraints | pass afteruv add --dev(hosted; 3 OS × 0.8.17 / 0.12.23) | fail #821 six in a dev group (PEP 735 / legacy) +uv add --dev/uv remove --dev→ half revert (3 OS); pass fordependencies/ extras / other groups | – | – | V→H takeover on #821's shape: half revert, exit 0 || 0.5.31 / 0.8.17 / 0.12.23 (run 19, main
045d7ec+ PR #822) | pass: hosted rollback after a single-clause spec edit re-derives it | multi-clause spec edit refused (documented) | fail #840 user edits six's own specifier then revert / remove / rollback → stale==1.16.0(3 OS × 3 versions; PR #822 too); #806 / #821 + neighbours + constraint edit fixed on PR #822 | – | – | V→H takeover after a spec edit pass (3 OS) || 0.2.37 / 0.4.30 / 0.5.31 / 0.8.17 / 0.12.23 (run 20, main
99f61d2) | idempotent re-scan pass (project + script × hosted + vendored); fail #564 still (3 versions); script lock spec edit → V→H takeover pass | fail #411 still (3 versions × rollback / remove) | fail #869 script lock spec edit → revert / remove / rollback stale==1.16.0(Linux 3 versions, Windows 0.5.31 / 0.12.23, macOS 0.12.23); #840 fix pass (deps / extra / dev ×>=~=!===.*<bare,Six,(>=…), markers simplified away); marker / extras-on-six / multi-clause / constraint edits drift-keep both files (--lockedok) | – | – | H→V takeover after a spec edit pass (project + script) || 0.8.17 / 0.12.23 (run 21, main
9c43dfc) | pass: file modes kept (0600 pyproject, 0664 uv.lock, 0755 script, 0640.py.lock) through scan + rollback; symlinked pyproject / uv.lock /s.py/s.py.lock/ pylock refused before any write (wet and dry); uv-exportedpylock.toml/pylock.dev.tomlhosted rollback byte-identical (#807 no regression); script lock with[tool.uv] constraint-dependencies/ CRLF /[[tool.uv.index]]source round trip; two scripts round trip | pass: two-script rollback; one script deleted → hosted rollback pass | fail #890 one of several wired scripts / script locks / pylocks deleted → revert / remove / rollback fail, takeover stuck (Linux 2 versions, Windows 0.12.23); fail #891 dry run gives no symlink warning for script / pylock files (Linux 2 versions, Windows 0.12.23);vendor --checkafter unwiring fails correctly; fail #723 / #767 still | – | – | regenerated uv.lock after vendoring → revert clean || 0.2.37 / 0.4.30 / 0.5.31 / 0.8.17 / 0.12.23 (run 22, main
9c43dfc) | pass:--cwdrelative / absolute /../with a space in the project dir (project + script,--lockedok); VEX after unwiring pyproject / uv.lock / both / deleting the lock (no over-attestation);list --json(project, script, two scripts, pylock) | pass:--cwdrollback | fail #890 project lane:uv.lockdeleted → revert / remove / rollback exit 1, takeover exit 0 (0.8.17 / 0.12.23); pass: pyproject-variant sweep (package = false, hatchling,requires-pythonupper bound, editable path sibling, inline comments, extras-only six), uv.lock + exported pylock warnspypi_multiple_lockfiles; macOS confirms #890 / #891 | – | pass:uv venv+uv pip installanduv syncvenvs on 0.2.37 / 0.4.30 / 0.5.31 / 0.8.17 / 0.12.23 (scan, apply, reinstall then re-apply,uv pip check, vex, rollback, vex refuses after rollback) | BOM pyproject: every writer drops the BOM (uv-consistent, not filed) || 0.5.31 / 0.8.17 / 0.12.23 (run 23, main
9c43dfc) | pass:uv pip compile --universalmarker-split six (1.16.0 / 1.17.0) → requirements.txt (plain and--generate-hashes) and pylock.toml rewrite only the 1.16.0 entry (py3.11 patched, py3.12 upstream) | pass: byte-identical rollback (requirements + pylock) | fail #928 marker-split--universalrequirements.txt →pypi_requirement_not_pinned(exit 1), dry run previewswould_vendor(3 versions); pass: marker-split pylock (wire, vex, regenerate the lock → vex refuses, revert byte-identical; 0.8.17 / 0.12.23), same-version two-marker requirements lines | – | – | forked PEP 723 script lock refused in both modes, nothing written || 0.5.31 / 0.8.17 / 0.12.23 (run 24, main
9c43dfc) | – | – | fail #944 H→V takeover viascan/get --mode vendoredun-hosts six before the vendored refusal (inline[tool.uv] sources = {…}; #928 split requirements); standalonevendorkeeps it hosted (pass); #928 split across a-rinclude (either side) refuses, dry run sayswould_vendor(comment on #928) | – | – | |Global (
-g) modeUV_TOOL_DIR/XDG_DATA_HOMEUV_PYTHON_INSTALL_DIR--product/ rollback / get / remove; stale reinstall → vex refuses)045d7ec(#449 fixed:%APPDATA%\uv\tools)UV_TOOL_DIRwith space + unicode,XDG_DATA_HOME)SOCKET_GLOBAL=1,--global-prefix/SOCKET_GLOBAL_PREFIXwith space and unicode paths, and project isolation (-gskips.venv) all pass on Linux.Backlog
scan/get --mode vendored) restores the package to PyPI before the uv vendored refusals run, so an inline[tool.uv] sources = {…}table (or a #928 marker split) leaves it unpatched in both modes, while --dry-run previews would_vendor #944 (new, run 24), Vendored requirements.txt fromuv pip compile --universalrefuses a marker-split package (six==1.16.0 ; python < 3.12+six==1.17.0 ; python >= 3.12) as "not pinned to ==1.16.0", while --dry-run previews would_vendor and hosted / vendored pylock handle the same split #928 (run 23;-rinclude shape added run 24), Vendored uv script locks: once the user deletes one wired script (or its .py.lock),vendor --revert,remove,rollbackand the hosted takeover can never unwind the other scripts, and the takeover's suggested fix is the command that fails #890 (3 OS, now covers the project lane too) / Vendored dry run gives no symlink warning for uv script locks or pylock files: a symlinkeds.py,s.py.lock,pylock.tomlorpylock.<name>.tomlpreviews clean, and the real run then refuses (exit 1) #891 (3 OS), Vendored uv script lock: after the user changes the vendored package's specifier in the PEP 723 block,vendor --revert/remove/rollbackwrite the stale==1.16.0back into<script>.py.lock, souv run --lockedfails (exit 0) #869, Hosted uv rollback and remove delete a user-authoredoverride-dependencies = ["<pkg>==<ver>"]pin that hosted mode never added #411 / Hosted and vendored uv wiring ignoreno-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564, uv vendored → hosted takeover strands a package that vendored mode pinned to a different version than uv.lock: the wet run reverts to the unpatched release (exit 1), while --dry-run previews a clean takeover #723 / uv projects that declare the patched package as a PEP 508 direct URL (six @ https://…/git+…): vendored writes a lockuv sync --lockedrejects while vex attests, and hosted overrides the user's URL then refuses to roll it back #767, uv projects never pick up a superseding patch: hosted re-scan lists the upgrade in updates[] but refuses its own earlier [tool.uv.sources] pin (exit 0, still on the old uuid), and vendored re-scan fails pypi_uv_source_already_exists #742 (vendored slice still pending after Fix uv/Hatch hosted re-pin to a newer patch (#742, #650) #743), Hosted uv scan silently wires a platform-specific patched wheel (cp311 manylinux) into a universal uv.lock, souv sync --lockedfails on every other Python version, macOS and Windows, and rollback then refuses #701, Hosted uv scan wires adynamic = ["dependencies"]project, but rollback, remove and the vendored takeover then always refuse ("pyproject.toml no longer declares six") #639, and the Vendored mode in a Pipenv project wires only Pipfile.lock and silently leaves a sibling requirements.txt unpatched, and the hosted → vendored takeover reverts that file's hosted pin to plain PyPI #612 / Hostedscan --jsonon a PyPI project with no root requirements.txt (e.g. onlyrequirements-dev.txtorrequirements/base.txt) reports success with emptyskippedandwarnings, though the patched package is never pinned #638 uv shapes, once main moves. Main has not moved since run 21 (9c43dfc). Verified fixed and closed: Vendored uv revert writes the pre-vendor specifier back into uv.lock after the user changes the vendored package's version spec, souv sync --lockedfails (vendor --revert / remove / rollback exit 0) #840, Vendored uv package in a dependency group: afteruv add --dev/uv remove --dev,vendor --revert,remove,rollbackand the hosted takeover revert pyproject.toml but keep uv.lock's vendored requires-dev entry, souv sync --lockedfails (exit 0, "success") #821, Vendored uv with a user-authoredoverride-dependencies: after any relock (uv add,uv lock --upgrade-package),vendor --revert/removerevert pyproject.toml but keep the vendored[manifest] overridesentry in uv.lock, souv sync --lockedfails (vendor --revert exits 0) #806, Hosted uv rollback, remove and vendored takeover always refuse locks written by uv 0.6.15–0.6.17, which spell the artifact fieldupload_timeinstead ofupload-time#788, Vendored uv with two or more packages: vendor --revert (and remove in purl order) leave an empty[tool.uv.sources]header in pyproject.toml #670, Hosted uv rollback, remove and vendored takeover refuse when the patched package is declared with different specifiers independenciesand an extra (or under different markers), although each lock entry keeps its marker #606, Hosted uv rollback and remove refuse when the patched package reaches a dependency group through PEP 735include-group#473, Hosted rollback, remove and vendored takeover always refuse on auv pip compilepylock.toml because its packages carry noindexkey #407, Hosted rollback rewrites uv pylock.tomlupload-timewith milliseconds, so the restored file never matches what uv writes #408, Vendored uv script lock can't be reverted afteruv add --scriptadds an unrelated dependency (vendor_lock_entry_drifted, still exit 0) #474, uv projects whose env is set by UV_PROJECT_ENVIRONMENT are never probed: agent scan patches the PATH interpreter and uv tool envs instead, the real env stays vulnerable, and vex attests not_affected #525, uv rollback, remove and vendor --revert leave an empty[tool.uv.sources]header behind when the project's sources are written as[tool.uv.sources.<name>]sub-tables #524, Vendored uv revert and remove half-revert a project whose sources use dotted keys under [tool.uv]: uv.lock is restored but thesources.<pkg>line stays, souv sync --lockedfails (vendor --revert exits 0) #544, Global scan (-g) misses uv tool environments on Windows (looks in %LOCALAPPDATA%\uv\tools, uv uses %APPDATA%\uv\tools) and on every OS when UV_TOOL_DIR, XDG_DATA_HOME or UV_PYTHON_INSTALL_DIR is set #449.vendor --revert/remove/rollbackwrite the stale==1.16.0back into<script>.py.lock, souv run --lockedfails (exit 0) #869 neighbours: script lock with six through[tool.uv] override-dependencies/constraint-dependenciesin the PEP 723 block, CRLF / BOM scripts. (Done in run 20: Vendored uv revert writes the pre-vendor specifier back into uv.lock after the user changes the vendored package's version spec, souv sync --lockedfails (vendor --revert / remove / rollback exit 0) #840 project lane on 5 versions, H→V after an edit, user constraint edits.) Also a Windows probe of hosted write atomicity (uv.lock held open without delete sharing).scan/get --mode vendored) restores the package to PyPI before the uv vendored refusals run, so an inline[tool.uv] sources = {…}table (or a #928 marker split) leaves it unpatched in both modes, while --dry-run previews would_vendor #944 neighbours: other uv vendored-only refusals reached after the takeover restore (a transitive package with a useroverride-dependencies→pypi_uv_source_already_exists;requirements.txtextrassix[x]==→pypi_extras_unsupported; an out-of-root-rinclude; pylock). Standalonevendor --dry-runsayseject_plannedexit 0 on the inline-sources project where the wet run exits 1 (check against the Vendored requirements.txt fromuv pip compile --universalrefuses a marker-split package (six==1.16.0 ; python < 3.12+six==1.17.0 ; python >= 3.12) as "not pinned to ==1.16.0", while --dry-run previews would_vendor and hosted / vendored pylock handle the same split #928 / uv hosted → vendored takeover (scan/get --mode vendored) restores the package to PyPI before the uv vendored refusals run, so an inline[tool.uv] sources = {…}table (or a #928 marker split) leaves it unpatched in both modes, while --dry-run previews would_vendor #944 dry-run parity before filing).--universalrequirements with extras on the split package (still open). Interrupted runs with fault injection (a slow mock route). Hosted with a release that has several sdists.git push --deletehangs up through the proxy). Twentybughunt/uv/*branches need maintainer cleanup, including20261005-symlink-dryrun,20261005-deleted-script,20261005-script-spec-revert,20261005-spec-edit-revert,20261005-dev-group-driftand20261004-upload-time.-grollback / vex and the macOS-gre-probe, with the mock instead of a live patch. The unwritable-prefix cell is still open: ubuntu-latest runners exit 1 on apply / get / vex-gwhile the target is patched (likely the root-owned system six); confirm with stderr.Known non-bugs
[tool.uv.workspace]or[manifest] membersbeyond the root) are refused in both modes (redirect_uv_project_unsupported/pypi_uv_workspace_unsupported). This is by design, though it's missing from docs/testing/uv-compatibility.md.045d7ecit takes over in place (redirect_takeover_reverted_vendored) and unwinds byte-identically (run 11).six>=1.10,<1.17) unless another lock entry shows uv's clause spelling. This is in theupstream/uv.rsmodule doc, not the user docs. It's justified: uv 0.2.37 keeps clause order and ≥0.5 sorts them.[[distribution]]locks,exclude-newer/no-binary/no-build, and non-PyPI registries (documented).--patch-server-urlfor a non-Socket origin reports "Manifest not found" (the origin isn't recognised as hosted). This is a harness artifact.vendor_fetch_failed/ "error sending request" for pypi.org / files.pythonhosted.org in the sandbox is a rustls vs proxy-CA artifact. Use a local forwarder viaSOCKET_PYPI_JSON_API.redirect_pypi_stale_installtext mentions Poetry on uv projects (cosmetic, v4 observation).scan -g --mode hosted(and--global-prefix/SOCKET_GLOBAL=1with hosted) exits 2 by design. A global scan with no mode is report-only.[[tool.uv.index]](for example a PyTorch index next to PyPI → "several registries"; only one sibling, on that index → "not PyPI"), even though the patched package came from PyPI. CLI_CONTRACT documents this ("other registry packages name … several, or one other than PyPI's simple index"). Hosted scan of a package that carries its own{ index = … }source is warn-onlyredirect_uv_project_unsupported("already declares a source"). Both are documented. The first is a candidate for a maintainer to narrow.repair→download_failedagainst the local mock is a harness gap (no diff archive served).Six===1.16.0restoressix==1.16.0, and a comment after a hash continuation is joined onto the last hash line. v5 upstream restore re-derives the pin, so the install is identical. uv never writes either spelling (cosmetic).--vexexits 1no_applicable_patcheswhile the venv is still stale (documented "installed evidence wins").uv remove --scriptof its only sibling refuses "no sibling registry package…" (documented; same as the project case).integrity.sha512→vendor_prebuilt_integrity_mismatch(the service sends SRIsha512-<b64>); a non-deterministic mock wheel → hash mismatch after a mock restart; a JSON forwarder that rewrites file URLs → rollback writes those URLs into the lock.redirect_uv_project_unsupported("marker-specific source mappings are required"), vendored ispypi_uv_lock_forked_package(exit 1). Documented in uv-compatibility.md:135.archive-v0entries containing patched bytes after hosted runs are the hosted wheels uv unpacked, not agent-mode pollution (agent apply breaks the hardlinks).[tool.uv] sources = { … }or[tool] uv = { … }) withpypi_uv_lock_parse_failed: … is not a standard table, before writing anything. Hosted mode grows the inline table in place. This is intentional (unit-tested in pypi_uv.rs) but undocumented.requirements.txtitself. A pin that lives only in a-c constraints.txtor-r base.txtinclude gets the warningredirect_requirements_entry_not_found(not silent). This is pip-generic, so don't file it under uv.[tool.uv.sources]entry (for example{ index = "…" }) withpypi_uv_source_already_exists(exit 1, nothing written). This is intentional but undocumented in uv-compatibility.md.uv run --scripton uv ≤0.8.17 keeps the cached patched env. This is uv-side (0.12.22 reinstalls upstream), the same as the 0.8.18 boundary foruv sync.[tool.uv.sources]header (no entries) is removed with the rollback. Both are cosmetic: uv sees the same configuration anduv lock --checkpasses. Not filed.vendor_prebuilt_required"tarball artifact has no sha512 integrity" is a mock gap. Serve SRI sha512 on/patch/package.dynamic = ["dependencies"]projects up front (pypi_uv_dynamic_dependencies, nothing written). This is intentional but undocumented in uv-compatibility.md. Hosted mode has no such guard (Hosted uv scan wires adynamic = ["dependencies"]project, but rollback, remove and the vendored takeover then always refuse ("pyproject.toml no longer declares six") #639).--cwddownward (docs/configuration.md), unlike uv's upward project discovery. This is generic and not uv-specific.redirect_uv_entry_not_foundfor a patched package missing from one of several pylocks (for example a--only-group devexport). This is accurate and informational.uv remove,vendor --revertdrift-keeps (vendor_lock_entry_drifted/vendor_revert_kept, success,removed 0) and.socket/vendorstays, although nothing references it any more. This is documented (CLI_CONTRACT: "the drift-kept artifact and entry stay, every backend alike"), andvexcorrectly refuses. It's a candidate to narrow: composer / maven / nuget drop the artifact once no file references it.--vendor-source buildwas removed, andvendor --offlinewith the default source failsvendor_service_offline_conflict. The harness must mockPOST /patch/package(use--vendor-url/--proxy-url/--patch-server-url).override-dependencies, and a directsix>=1.15or evensix>=1.17gets a path source to the 1.16.0 wheel; uv accepts it). This is intentional (pypi_uv.rsoverride_wiring_matches_fixture_byte_identically) but undocumented, and Pipenv refuses the same case (pypi_pipenv_version_mismatch). It's a candidate to warn on. Its takeover consequence is filed as uv vendored → hosted takeover strands a package that vendored mode pinned to a different version than uv.lock: the wet run reverts to the unpatched release (exit 1), while --dry-run previews a clean takeover #723.content_mismatch_overwritten). This is the documented v3.4 default;--strictrefuses.pypi_multiple_lockfiles. This is documented ("uv.lockkeeps its exclusive precedence").UV_NO_SOURCES=1/uv sync --no-sourcesat install time bypasses the sources-based hosted and vendored wiring (0.12.23:--lockedfails and a plain sync relocks to unpatched; 0.8.17 still installs patched). That's the user's explicit opt-out at install time. The config-levelno-sources = trueat scan time is Hosted and vendored uv wiring ignoreno-sources = true: scan and vendor report success,uv sync --lockedthen fails, and a plainuv syncreinstalls the unpatched wheel #564.pypi_requirements_already_vendored) is pip-generic. It was handed to the pip routine in run 14; don't re-file it under uv.SOCKET_PYPI_JSON_APImust be<mock>/pypi(the CLI appends/<name>/<version>/json).sub/(lock-only or with a.venv) and a script lock inscripts/are not discovered from the repo root (scannedPackages: 0, exit 0). This is generic, not uv-specific; nested-project discovery is planned (PR Speed up hosted and vendored scans: concurrent API requests, parallel crawl, single-pass rewriters #257 follow-ups).pypi_uv_lock_revision_untestedon uv 0.12.x vendored runs: uv writes lock revision 5, and the fixtures only test up to 3. It's an informationalskippedevent that isn't counted insummary.skipped; the fixtures should be bumped.vex -gwith no detectable product exits 2 asking for--product(usage).UV_COMPILE_BYTECODE=1venv is safe: uv writes timestamp-based pycs, so the patched source is recompiled.[project](dependency-groups only; uv 0.12 locks it) is refused cleanly: hosted warnsredirect_uv_project_unsupported("no project table"), vendored failspypi_uv_lock_root_missing, and nothing is written. Undocumented, but honest.scan/rollback/removewrite pyproject.toml and uv.lock one after another with no undo, so a write failure on uv.lock (exit 1, reported) leaves pyproject.toml changed. After a failed rollback, rollback / remove / list failhosted_wiring_contesteduntilscan --mode hostedis re-run, which the error suggests and which heals it. The code acknowledges this (RestoreOutcome::flush_error). It's generic across ecosystems and recoverable; vendored has a commit journal. A candidate to harden; not filed (run 16).pylock.a.b.toml,pylock..tomlandPYLOCK.tomlitself, so whether socket-patch discovers them doesn't matter.no-binary/no-buildrefusal matches any[tool.uv] no-binary*key, includingno-binary-packagefor an unrelated package. This is documented ("options filter files"), but broad..py.lockis not an input: scan reportsscannedPackages: 0in every mode and writes nothing. uv's ephemeral script envs live in its cache (run 17).six===1.16.0in pyproject.toml) with "uv's spelling of … is not derivable" (exit 1,git checkoutremedy). This is a conservative guard inupstream/uv.rs::spec_clauses.idna==3.07,==03.7,==3.7.00) writes the user's spelling into uv.lock'srequires-dist, where uv writes the normalized one (==3.7). uv accepts it (--lockedpasses, anduv lockkeeps it), so it's cosmetic.removematches only canonical PyPI purls (Typing_Extensions,typing.extensionsand qualifiers →not_found). This is generic, so it was handed over to pip (run 17). An uppercase UUID is covered by Validate patch UUIDs through one utils::uuid grammar instead of five #705.override-dependenciesthat is relocked after vendoring (uv add --script,uv lock --script --upgrade-package):vendor --revertdrift-keeps both the script and the.py.lock, souv lock --script --lockedstill passes. That's the documented pair rule (run 18); the non-semantic match itself is Vendored uv with a user-authoredoverride-dependencies: after any relock (uv add,uv lock --upgrade-package),vendor --revert/removerevert pyproject.toml but keep the vendored[manifest] overridesentry in uv.lock, souv sync --lockedfails (vendor --revert exits 0) #806's.six==1.16.0; python_version >= "3.9") half-reverts on main. That's the Vendored uv with a user-authoredoverride-dependencies: after any relock (uv add,uv lock --upgrade-package),vendor --revert/removerevert pyproject.toml but keep the vendored[manifest] overridesentry in uv.lock, souv sync --lockedfails (vendor --revert exits 0) #806 / Vendored uv package in a dependency group: afteruv add --dev/uv remove --dev,vendor --revert,remove,rollbackand the hosted takeover revert pyproject.toml but keep uv.lock's vendored requires-dev entry, souv sync --lockedfails (exit 0, "success") #821 pair-gate gap; PR Fix uv vendored revert half-reverting after a relock (#806, #821) #822 keeps both files. On 0.8.17 / 0.12.23 the same edit reverts cleanly (run 19).[tool.uv] override-dependencies(any spec, e.g.six>=1.16) withpypi_uv_source_already_exists("refusing to stack a vendor override on a user override", exit 1, nothing written). Intentional (pypi_uv.rs:386) but undocumented in uv-compatibility.md (run 20).Some("six")in its reason (RustDebugtext). Cosmetic (run 20).six==1.16.0→six>=1.16/ baresixon a transitive six drift-keeps both files (vendor_lock_entry_drifted,--lockedok) instead of re-deriving. Safe and documented as drift (run 20).# /// scriptblock and locks no dependencies (requires-pythonfalls back to the interpreter), so socket-patch has nothing to wire. This is uv-side (run 21).uv adddrops it too), and Python'stomllibrejects a BOM'd pyproject anyway. Not filed (run 22).not_applied, exit 1) even afteruv run --scriptprints patched bytes: verification checks the interpreter's site-packages, not uv's ephemeral script env.--no-verifyattests. This is conservative (documented "installed evidence wins"), not over-attestation (run 22).pylock.toml/pylock.<name>.tomlwires only uv.lock and warnspypi_multiple_lockfilesinvendor.events(documented). A plainvendorre-run doesn't repeat the warning (run 22).pylock.tomlwith twosix@1.16.0entries under different markers (same wheel) is refused: hosted is warn-onlyredirect_uv_lock_unsupported, vendored failspypi_lock_unsupported("source selection is ambiguous"). This is documented, and uv never writes that shape (it merges the markers into one entry) (run 23).==1.16.0for <3.12,==1.17.0for >=3.12) is refused in both modes with nothing written (documented marker-fork refusal, run 23).All reactions