Repository navigation
Fix residual-reference keep reported as drift (#1184) - #1311
Merged
Mikola Lysenko (mikolalysenko) merged 6 commits intoOct 10, 2026
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
When a vendored PyPI revert restored its recorded wiring but kept the wheel because another project file (a `pipenv requirements` export) still installs from it, `remove` and `rollback` reported the keep as "lockfile wiring drifted" and told the user to re-run `scan --mode vendored` to normalize, then remove. That remedy loops: the re-vendor re-wires Pipfile.lock and the next remove keeps the entry again. The keep now carries its cause. `vendor_artifact_kept`, the remove warning, skip reason and top-level error, rollback's vendoredKept reason and `vendor --revert` / reconcile skips say a project file still installs from the artifact, and the remedy is to point that file back at the registry release (or re-export it from the restored lock) and run the unwind again. A hosted takeover refused for the same reason names the file instead of a wiring edit. Drift keeps keep their existing wording. Fixes #1184 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 9, 2026 18:31
Collaborator
Author
|
BugBot review |
Mikola Lysenko (mikolalysenko)
enabled auto-merge
October 9, 2026 18:31
2 tasks done
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 060e1c2. Configure here.
Tanmay Singla (Tanmay182003)
approved these changes
Oct 9, 2026
The refusal leaves the lock vendored, so re-exporting the requirements file from it would name the wheel again and the next hosted scan would refuse again. Tell the user to pin the file to <name>==<version> by hand, re-run the hosted scan, and only then re-export; the takeover test now follows that remedy through to a completed takeover. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mikola Lysenko (mikolalysenko)
deleted the
agent/v5-vendor-residual-keep
branch
October 10, 2026 14:37
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.

LLM Description written by Claude Code:claude-opus-5-5
Fixes #1184
Summary
Since #997, a vendored PyPI revert keeps the wheel and ledger entry while another root project file still installs from it (
vendor_revert_residual_reference). The everyday shape is apipenv requirements > requirements.txtexport made after vendoring. The keep itself is correct, butremove/rollback/vendor --revertreported it as drift:vendor_artifact_keptsaid "undo the drift".removeprintedKept vendored state …: lockfile wiring drifted.vendor_revert_kepterror told the user to "re-runscan --mode vendoredto normalize, then remove".rollbackgavevendoredKept[].reason: "lockfile wiring drifted…".Following that remedy loops. The re-vendor re-wires Pipfile.lock, and the next remove keeps the entry again. The hosted takeover lane had the same mislabel ("part of its vendored wiring was edited since vendoring"), and its
vendor --revertremedy left the project unpatched.Root cause
revert_pypi_opts(corevendor/pypi.rs) handled the residual-reference keep through the genericRevertOutcome::keep_artifact, which emits drift wording. The CLI'sVendorRevertStep::Keptcarried no cause, so every caller printed the drift text and the normalize remedy.Fix
Core:
RevertOutcome::keep_artifact_for_referenceemitsvendor_artifact_keptwith the real cause and remedy.kept_for_residual_reference()reports a keep whose only signal isRESIDUAL_REFERENCE_CODE. The residual warning's remedy now names every unwind (vendor --revert,remove,rollback).CLI:
VendorRevertStep::Kept(KeepCause::{Drift, Reference}). ForReference, the following all say that a project file still installs from the vendored artifact and give the remedy "point the file named by vendor_revert_residual_reference back at the registry release (or re-export it from the restored lock), then again":vendoredKeptreasonvendor --revertand the manifest-reconcile skipsThe JSON error code stays
vendor_revert_kept, so the contract code is unchanged. Drift keeps keep their exact existing wording.Takeover: a refusal whose only cause is a residual reference now names the file. Its remedy is to point that file back at the registry release and re-run
scan --mode hosted.CLI_CONTRACT.md
vendor_revert_keptrow updated.Tests (per issue)
removeandrollbackcall a vendored PyPI residual-reference keep "lockfile wiring drifted", and their "re-runscan --mode vendoredto normalize, then remove" remedy loops (Pipenvpipenv requirementsexport) #1184:mode_migration_pypi::pipenv_residual_export_keep_is_not_reported_as_driftvendors a Pipenv project and then writes apipenv requirements-shaped export naming the vendored wheel. It runsremove(JSON and human),rollbackandvendor --revert. Nothing says "drift" or "normalize", the remedy says "re-export", and Pipfile.lock is restored while the wheel is kept. After the prescribed re-export, the same command finishes and reclaims the wheel.removeandrollbackcall a vendored PyPI residual-reference keep "lockfile wiring drifted", and their "re-runscan --mode vendoredto normalize, then remove" remedy loops (Pipenvpipenv requirementsexport) #1184 takeover lane:pipenv_residual_export_takeover_refusal_names_the_export. Theredirect_vendored_revert_faileddetail names requirements.txt and "re-export", not "edited since vendoring" orvendor --revert, and the package stays vendored.Red→green: before the fix the first test failed on
"reason":"lockfile wiring drifted; vendored state and manifest entry kept"and the normalize error. Both pass now.Commands run
cargo test -p socket-patch-core --lib vendor::: 2498 passedcargo test -p socket-patch-cli --all-features --test cli_remove_silent --test remove --test rollback --test covgap_commands_rollback --test covgap_commands_vendor --test in_process_rollback_vendored --test mode_migration_pypi --test scan_vendor_e2e --test in_process_vendor_pypi_takeover --test e2e_vendor_pypi_build --test vendor --test in_process_vendor --test coverage_fix_scan_hosted_dryrun_vendored: all passcargo clippy --workspace --all-features -- -D warningsandcargo fmt --all -- --check: cleanCoordination: #1188 rewrites Pipfile.lock writing, and this PR doesn't touch the Pipfile.lock writers.
mode_migration_pypi.rsalso gets a test from the #477 PR, which appends at the end of the file, so the two may need a trivial rebase.🤖 Generated with Claude Code