GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Fix PyPI vendored to hosted takeover being refused (#328) by mikolalysenko · Pull Request #503 · SocketDev/socket-patch Conversation
|
| Test | Without fix | With fix |
|---|---|---|
requirements_vendored_to_hosted |
❌ redirect_requirements_entry_not_found, redirected 0 |
✅ |
requirements_sole_pin_vendored_to_hosted (six==1.16.0 alone, from the 2026-10-01 comment) |
❌ same | ✅ |
poetry_vendored_to_hosted |
❌ redirect_poetry_lock_unsupported |
✅ |
pipenv_vendored_to_hosted |
❌ redirect_pipenv_refused |
✅ |
uv_vendored_to_hosted |
❌ redirect_uv_project_unsupported |
✅ |
hatch_vendored_to_hosted |
❌ redirect_hatch_unsupported |
✅ |
uv_takeover_without_wheel_metadata_fails_loudly |
❌ with only the gate change: exit 0, package unpatched | ✅ exit 1, redirect_takeover_unpatched |
drifted_vendored_line_refuses_takeover |
❌ with only the gate change: ledger dropped | ✅ refused, ledger and artifact kept |
dry_run_predicts_drifted_takeover_refusal (Bugbot) |
❌ on a0863a2 | ✅ |
stranded_takeover_human_output_is_not_a_migration (Bugbot) |
❌ on a0863a2 | ✅ |
stranded_takeover_is_reported_under_silent (Bugbot) |
❌ on a0863a2 | ✅ |
ledger_update_failure_after_revert_is_stranded (review P1; Unix, skips where permissions aren't enforced) |
❌ on 0be19d0: exit 0, success |
✅ exit 1, partial_failure |
The existing covgap_commands_scan_hosted::ledger_save_failure_after_successful_revert_fails_closed now expects the stranded contract too: exit 1, partial_failure and redirect_takeover_unpatched.
Each lane test vendors the project, runs scan --mode hosted, and asserts all of: redirected: 1, redirect_takeover_reverted_vendored, no .socket/vendor/ reference in any wiring file, the hosted URL wired, and the vendored artifact reclaimed.
Local checks on aada684:
cargo clippy --workspace --all-features -- -D warnings: clean.mode_migration_pypi 12/12, mode_migration_npm 15/15, mode_migration_cargo 5/5, covgap_commands_scan_hosted 50/50, covgap_commands_vendor 44/44, covgap_commands_rollback 62/62, covgap_commands_get 75/75, in_process_redirect 104/104.cargo test -p socket-patch-cli --all-features --lib, in_process_vendor, in_process_vendor_bun_takeover, coverage_fix_scan_hosted_dryrun_vendored, scan: all pass.cargo test --workspace didn't fit in this session's disk allowance, so CI runs the rest.cargo fmt --all -- --check: fails on main already (about 460 diffs in files this PR doesn't touch; CI doesn't run it). The hunks this PR adds are rustfmt-clean.CI on aada684: all 467 checks pass (461 success, 6 skipped).
*_vendored_to_hosted tests plus requirements_sole_pin_vendored_to_hosted. The hosted → vendored direction was already fixed on main (see the issue comments).🤖 Generated with Claude Code
https://claude.ai/code/session_018kguGYyuuizF1dwKyH6oZh
Note
Medium Risk
Changes hosted scan exit semantics (exit 1 / partial_failure when revert leaves the project on unpatched registry releases) and cross-mode takeover logic; behavior is contract-tested but affects CI and migration workflows.
Overview
Fixes vendored → hosted migration for PyPI (#328) by including pkg:pypi/ in the hosted scan’s vendored takeover gate, so scan --mode hosted reverts socket-patch’s own vendored wiring (via the same per-purl vendor --revert path as cargo/npm/golang) before lock rewriters run—those rewriters previously treated vendored sources as user-authored and skipped redirect with exit 0.
Tightens takeover safety for all takeover-capable ecosystems: if revert would leave vendored wiring in place (drift-skipped records or residual artifact references), the takeover is refused with redirect_vendored_revert_failed and the ledger/artifact stay put; --dry-run uses the same signals instead of previewing a takeover.
“Stranded” takeovers—revert succeeded but the package never got a hosted pin (failed redirect, missing wheel metadata, or ledger save after revert)—now emit redirect_takeover_unpatched, set JSON status: "partial_failure", and exit 1 (including under --silent). Human output skips misleading “Migrated …” and commit/reinstall next steps for those purls.
CLI_CONTRACT.md documents PyPI takeover, revert refusal, and stranded behavior. New hermetic tests in mode_migration_pypi.rs cover requirements/Poetry/Pipenv/uv/Hatch happy paths plus drift, dry-run, stranded UX, and ledger-save failure; an existing covgap hosted test expects the new stranded contract.
Reviewed by Cursor Bugbot for commit 9d46d12. Configure here.
Generated by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
Switching a vendored Python project to hosted mode leaves it vendored: every PyPI hosted rewriter refuses the vendored source socket-patch wrote itself. Cover requirements.txt, Poetry, Pipenv, uv and Hatch (#328). Assisted-by: Claude Code:claude-opus-5-5
`scan --mode hosted` over a project socket-patch had vendored left it vendored and reported success: the takeover that reverts vendored wiring before redirecting only covered cargo, npm and Go, so the Python rewriters (requirements.txt, Poetry, Pipenv, uv, Hatch) refused socket-patch's own vendored source. PyPI packages now go through the same takeover. Two guards keep the takeover from leaving a package unpatched: - vendored wiring edited since vendoring is left in place by the revert, so the takeover now refuses and keeps the ledger entry instead of dropping it; - a package whose wiring was reverted but that the hosted rewrite then did not pin (e.g. hosted wheel metadata unavailable) now fails the run with redirect_takeover_unpatched instead of passing as success. Fixes #328 Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Follow-ups from review of the PyPI vendored-to-hosted takeover: - `--dry-run` now predicts the drifted-wiring refusal from the same drift and residual-reference signals the wet run uses, instead of previewing a takeover the wet run then refuses. - A takeover left unpatched no longer prints a "Migrated ... to hosted" line or "keep the hosted patches" next steps. - Its redirect_takeover_unpatched error also prints under --silent, so the exit 1 is explained. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent] CI: I don't think this PR caused it:
I'll re-run the failed job once when the workflow finishes, which isn't possible while other jobs are still running (403 "already running"). If it fails a second time I'll treat it as real and dig into the job artifact. Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent] Ready for review at
Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Reviewed P1 — A ledger-save failure still reports success after removing the PyPI patch ( Reproduced by vendoring Validation: 11 PyPI migration tests plus 15 npm and 5 Cargo migration tests passed. An additional review-only CLI regression test for this read-only-ledger case failed with the output above. Full workspace and real-package-manager matrices were not rerun. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
The vendored→hosted takeover for PyPI reverts the vendored patch before fetching the hosted wheel metadata (vendored_takeover at hosted.rs:802, fetch at :818+). If that fetch fails (network, a uv project whose metadata can't be fetched), the package is left patched in neither mode. The PR catches this and fails loudly (partial_failure, exit 1), and re-running recovers it. But CLI_CONTRACT promises the opposite for yarn berry ("refuses before reverting … never left unpatched in both modes"), and #470 adds exactly that check for berry. Can we file a follow-up to do the same for PyPI: fetch and validate the hosted metadata first, and only revert the vendored copy once that succeeds? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
When a vendored-to-hosted takeover reverts a package's wiring but the vendored ledger then cannot be updated, the package is refused and never redirected. Its vendored wiring and artifact are already gone, so it installs unpatched in both modes, yet the run exited 0 with status "success". It now counts as a stranded takeover: redirect_takeover_unpatched, status "partial_failure", exit 1, also printed under --silent. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018kguGYyuuizF1dwKyH6oZh
|
[agent] Replying to both review comments. P1 (ledger-save failure reported as success): fixed in 1a1f2e9. The cause is as described. The
This applies to every takeover-capable ecosystem, not only PyPI. CLI_CONTRACT.md lists the ledger-update failure as one of the stranded causes. Regression test: Tanmay Singla (@Tanmay182003), pre-validating hosted metadata before the revert: agreed. Fetching and validating the hosted wheel METADATA before reverting the vendored copy would let a PyPI takeover refuse up front with nothing written, the same way the berry gates do. It also matches the contract's "never left unpatched in both modes" wording. That reorders the takeover against the metadata fetch for every Python flavor, which is bigger than this PR, so I'd keep it as a follow-up. This PR guarantees the fallback: it fails loudly, and a re-run recovers. I'll leave filing that follow-up issue to the maintainers. Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
covgap_commands_scan_hosted pinned exit 0 for a takeover whose revert succeeded but whose ledger save failed. That case is now a stranded takeover: redirect_takeover_unpatched, status "partial_failure", exit 1. The test skips as root, so it only ran in CI. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018kguGYyuuizF1dwKyH6oZh
|
Follow-up reviewed A takeover whose vendored wiring was removed but whose ledger update failed is now included among stranded packages. It reports Validation: 12 PyPI migration tests and the original independent ledger-write-failure reproduction pass with the fix. The 7 ledger-related hosted coverage tests also pass at this head. These are focused checks; the full workspace suite was not rerun locally. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Resolve the CLI_CONTRACT.md conflict by keeping this branch's PyPI takeover paragraph and main's corrected BUNDLE_GEMFILE precedence wording (app config outranks the environment variable). Co-Authored-By: Claude <[email protected]>
|
bugbot run Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem 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 9d46d12. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Second pass reviewed Validation at this exact head: all 12 CI follow-up: this same head now has 478 successful checks and 6 skipped, with no unresolved review threads and a clean merge against main |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent] CI on 9d46d12: The job hung in I don't think this PR caused it:
No fix exists yet. I've re-run the failed job once. If it hangs again, I'll treat it as real and dig in. Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[burn-down agent] Re-verified Ready for review at
Slack announcement not sent (no Slack send tool available this run). Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Poetry hosted ⇄ vendored mode switch is refused, and blames a "user-authored" source that socket-patch wrote itself
There was an error while loading. Please reload this page.