Fix agent vex checking only one installed copy (#516) - #517
Conversation
Assisted-by: Claude Code:claude-opus-5-5
When a project holds several installed copies of the same package@version (npm nests duplicates, and a later install can add a fresh unpatched one), `vex` only hashed the first copy it found. It could then attest a patch as not_affected while another copy that a dependent loads was still unpatched. Agent-mode records are now attested only when every installed copy matches the patched bytes, the same rule `apply` follows when it patches and that hosted records already use. The vendored drift warning also checks every copy. Fixes #516 Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ 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 0f45d24. Configure here.
|
Ready for review — head
Generated by Claude Code |
|
Reviewed No actionable correctness or security regressions found. The CLI passes all discovered copies through verification; empty copy lists fail closed, hosted/vendor precedence stays intact, and the vendor drift warning covers later copies. Validation: |
|
Second review pass of The head is unchanged from the prior review, discussions introduce no unresolved finding, and it merges cleanly with current main |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #516
Root cause
vexresolves every installed copy of each manifest PURL (find_manifest_package_copies_reusing), but thencollapse_to_firstdropped all but the first before the agent-record hash check (applied_patches_with_vendor).applypatches every copy, and hosted PURLs were already judged against every copy (HostedCopies). Agent records were not. So when a later install adds a fresh, unpatched nested copy of the samename@version,vexattestednot_affectedwhenever the first crawled copy happened to be patched.Change
vex::verify::applied_patches_with_copies(new) takespurl -> Vec<PathBuf>, meaning every installed copy. An installed-tree record verifies only when every copy verifies, and the first failing copy's tag wins, using the sameverify_every_copyhelper thatHostedCopiesnow shares. An empty list meanspackage_not_found. The vendored drift probe (vendored_tree_out_of_sync) flags the PURL when any copy is out of sync.applied_patches_with_vendorstays as a one-copy wrapper, so its existing callers and tests are unchanged.commands/vex.rspasses the full copy map instead ofcollapse_to_first(...).Hosted, vendored and Go-redirect evidence are unchanged; each already has its own copy selection. The npm, PyPI and gem wrappers only dispatch to the binary, so they need no change.
Test evidence
e2e_vex::verify_mode_requires_every_installed_copy_patched: two nested copies ofdup-pkg@1.0.0, one patched; both crawl orders must omit the PURL (not_applied, non-zero exit), and all copies patched must attestcommands/vex.rsreverted tocollapse_to_first, the test panics ate2e_vex.rs:965(patched-first order attested). Green with the fix.vex::verify::tests::every_installed_copy_must_verify,empty_copy_list_is_package_not_found,vendored_drift_probe_checks_every_installed_copyCommands run locally:
cargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --lib vex::verify: 36 passed.cargo test -p socket-patch-cli --all-features --test e2e_vex --test e2e_vex_vendor --test e2e_vex_redirect --test covgap_commands_vex: all passed.cargo test --workspace --all-features --no-fail-fast: 9472 passed, 12 failed. All 12 failures are write-failure and permission fixtures (chmod 0o555/ unremovable-file tests incovgap_commands_vendor,in_process_redirect,repair, and four core lib tests). They can't fail as uid 0, which is what this sandbox runs as, and none of them touch vex. CI runs them as a non-root user.cargo fmt --checkon the touched files is clean.mainitself isn't rustfmt-clean (about 460 diffs) and CI doesn't run fmt, so this PR formats only its own hunks.CI note: Poetry 1.0.10 (macOS) crlf/hosted failed
rescanIdempotentonce. That's a hosted rescan against the live patch API, a path this diff doesn't touch. It passed on the one re-run.🤖 Generated with Claude Code
https://claude.ai/code/session_017ZjqW5PYJWkPpisnhaS4zi
Generated by Claude Code