Skip to content

Fix hosted to vendored takeover onto a newer patch (#1105) - #1713

Merged
Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
agent/fix-vendor-superseded-hosted-install
Oct 26, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
agent/fix-vendor-superseded-hosted-install

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #1105

Summary

A project moving from hosted to vendored mode now picks up a newer patch even when its venv still holds the old hosted patch's bytes. This covers uv sync, poetry install and uv pip install -r after a hosted scan.

Root cause

vendor / scan --mode vendored checks the installed copy of a PyPI package against the patch it is about to vendor (the release-variant probe). If the installed bytes match neither the pristine release nor this patch's output, the probe drops the package unless superseded_install says the install is an older patch generation. Before this change, superseded_install only looked at the vendor ledger.

After a hosted scan with patch A and a sync, the venv holds A's bytes and the lock carries a live hosted pin, but there is no ledger entry. So once the API served a superseding patch B, the package was dropped as package_not_installed ("no installed package found on disk"). The run exited 1 and the hosted takeover was never reached. scan --mode vendored --dry-run stops before the probe, so it previewed success.

Fix (crates/socket-patch-cli/src/commands/vendor.rs)

Tests

Issue Test Without fix With fix
#1105 (uv, Poetry, requirements.txt lanes) mode_migration_pypi::hosted_to_vendored_takes_a_superseding_patch_over_a_hosted_venv FAILED: exit 1, package_not_installed ok
#1105 (rule) commands::vendor::plan_gate_tests::hosted_pin_marks_a_pypi_install_superseded (unit) n/a (new rule) ok

Local runs (Linux, as root):

  • cargo fmt --all -- --check and cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo test --workspace --all-features, run one target at a time to fit the disk allowance: 218 of 221 targets pass, including mode_migration_pypi (70), in_process_vendor_pypi_takeover (7), hosted_superseding_pypi (4) and the CLI lib (934).
  • The 3 other targets fail identically with main's vendor.rs, so they are environmental:
    • core lib and in_process_redirect: chmod-based write-failure tests can't fail as root.
    • e2e_bun_lockb: needs the pinned bun 1.0/1.1 toolchain that CI installs.
  • No wrapper (npm/, pypi/, gem/) changes are needed: the change is internal to the Rust vendor loop.

Review notes

/code-review high findings that were fixed: any hosted pin counts (not only one at another uuid), multiple pins per purl, the planner using the same check, the gem platform guard, and a shadowed test const.

Not changed:


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
After a hosted scan with patch A and a `uv sync` or `poetry install`,
the venv holds A's patched bytes. When a newer patch B for the same
release arrived, `scan --mode vendored` / `vendor` dropped the package
as "no installed package found on disk" and exited 1, leaving the
project hosted on A, while the dry run previewed success.

The installed copy is recognised as a superseded install only through
the vendor ledger. A live hosted pin at another patch uuid now counts
too (for a sole release variant, since the pin names none), so the
takeover restores the upstream entry and vendors B from the pristine
artifact.

Fixes #1105

Assisted-by: Claude Code:claude-opus-5-5
The issue also reproduces in the uv pip requirements.txt lane, which
goes through the same check, so the regression test runs it too.

Assisted-by: Claude Code:claude-opus-5-5
A venv synced from an older hosted patch can sit under a lock a later
hosted scan already moved to the patch being vendored, and a package
can carry hosted pins at two uuids in different files. Treat any live
hosted pin as the superseded install, keep the rule to PyPI so gems
still refuse a platform gem from their installed dir, and give the
download planner the same hosted check as the vendor loop.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit ae32e91. Configure here.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 24, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Labeled Ready for review by the burn-down agent.

  • Head: ae32e918f4327516d5b18ec0b224d3e50342279e
  • CI: 37/37 non-skipped checks green (50 skipped; the one neutral check is Cursor Bugbot), no main-wide failures
  • Bugbot: reviewed ae32e91, no new issues; no review threads open
  • Mergeable against main, no CHANGELOG.md change
  • Reviewer focus: the new hosted_pinned arm of superseded_install in crates/socket-patch-cli/src/commands/vendor.rs. It counts any live hosted pin as a superseded PyPI install, but only for a sole candidate, so gems stay out. The two call sites pass different predicates (takeover_blocked vs hosted_pin_of(..).is_some()); check that they agree.

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Final review brief

What it does: When a PyPI project moves from hosted to vendored mode and the API now serves a newer patch (B) than the one the venv was synced with (A), vendor used to drop the package as package_not_installed (exit 1, project left hosted on A). Now a live hosted pin on a sole PyPI candidate counts as a superseded install, so the takeover restores the upstream entry and vendors B from the pristine artifact, as the ledger path from #769 already does.

Risk: low. One extra || clause in a predicate, limited to PyPI and to packages with a single release-variant candidate; both call sites (download planner and vendor loop) use the same hosted-pin lookup.

Look here:

  • vendor.rs:2547: the new hosted_pinned clause in superseded_install
  • vendor.rs:2623: download planner passes takeover_blocked(candidate) (= hosted_pin_of(..).is_some())
  • vendor.rs:3116: vendor loop passes the same check
  • mode_migration_pypi.rs:851:`` uv / Poetry / requirements.txt lanes
  • vendor.rs:4938: unit test for the sole-candidate and PyPI-only limits

Verified:

  • Read the full diff (2 files, +108/-5); CHANGELOG.md untouched; no debug leftovers or unrelated edits.
  • Ran mode_migration_pypi::hosted_to_vendored_takes_a_superseding_patch_over_a_hosted_venv: passes on the head, and fails with package_not_installed when vendor.rs is reverted to the merge base, so the test pins the fix.
  • Ran plan_gate_tests (3/3 pass).
  • CI on ae32e91: ci-ok and clippy green (37 success, 50 skipped, 0 failed). Bugbot: no new issues on this head. No open review threads.

Changes I made: none.

Open questions: none blocking. Known follow-ups are listed in the PR body (several variant records under a hosted pin still refuse; vendor --dry-run over a uv hosted pin previews pypi_uv_source_already_exists, which predates this PR).

Auto-merge is armed, so approving sends it straight to the merge queue.


Generated by Claude Code

Merged via the queue into main with commit 022063d Oct 26, 2026
88 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-vendor-superseded-hosted-install branch October 26, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

4 participants