Repository navigation
Fix vendored npm VEX beside a file: dir copy (#1511) - #1513
Merged
Mikola Lysenko (mikolalysenko) merged 3 commits intoOct 14, 2026
Merged
Conversation
Assisted-by: Claude Code:claude-opus-5-5
Vendored `scan --vex`, a standalone `vex` and `vendor --check` read the npm lock through discovery, which skipped a `file:` directory dependency: npm records it as a link entry with no version, so discovery never saw that it holds the patched release. VEX then said `not_affected` while that workspace member loaded the unpatched directory. Discovery now resolves such a link to its source directory's entry, as the hosted rewriter does since #1482, and withholds the reference with `patched_ref_unattributable`. The lookup moves to vendor::npm_origin so both readers share it. Fixes #1511 Assisted-by: Claude Code:claude-opus-5-5
With the #1511 fix, `vendor --check` on a project whose vendored npm package also installs from a `file:` directory failed with "wiring missing: no lockfile or config references ... re-run socket-patch vendor". The lock does reference the artifact, and re-vendoring cannot reach that copy, so the advice looped. The same held for a bundled, git, url or `file:` tarball copy. The check now reports `copy unpatched:` with the lock entry that installs the unpatched copy, and says to depend on the registry release there instead. Discovery's link lookup is also limited to entries npm installs from a `file:` spec, as in the hosted rewriter, and the regression tests gain a workspace-member control and assert the in-run VEX warning. Refs #1511 Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 14, 2026 01:06
Collaborator
Author
|
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 7b7f58c. Configure here.
Tanmay Singla (Tanmay182003)
approved these changes
Oct 14, 2026
Mikola Lysenko (mikolalysenko)
deleted the
agent/fix-npm-vendored-file-dir-copy
branch
October 14, 2026 01:57
This was referenced Oct 14, 2026
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 #1511
Summary
In an npm workspace under
install-strategy=nested, memberauses registryleft-pad@1.3.0and memberbdepends on afile:directory that holds the same release. A vendoredscan --vexand a standalonevexboth saidnot_affected, andvendor --checkpassed. Butb's copy is a symlink to that directory, which no rewrite reaches, so it stays unpatched.After this PR:
--vexand a standalonevexattest nothing. They warnpatched_ref_unattributableand namepackages/b/node_modules/left-pad, as they already did for thefile:tarball and URL shapes. Hosted mode has refused this shape since Fix npm file: copy attested by in-run VEX (#1481) #1482.vendor --check: fails withcopy unpatched: …naming that lock entry. Before this PR it passed. Without the second commit it would have failed with the false "wiring missing … re-runsocket-patch vendor".Root cause
vex::discover::npm::drop_non_registry_installswithholds a Socket-wired ref when a non-registry copy of the samename@versioninstalls beside it. It read the copy's identity only from the entry'sversion. npm records afile:directory dependency as a versionless link entry ("resolved": "lpdir", "link": true), and only the directory's own entry carries the version. So the loop skipped it and the ref stayed attested. #1482 added that link → source lookup (npm_link_source_identity) to the hosted rewriter only. Discovery, which vendored VEX andvendor --checkread, never got it.Changes
npm_link_source_identitymoves frompatch/redirect/mod.rstovendor::npm_origin, next tonpm_non_registry_entries. It now takes the link entry rather than a JSON pointer. The hosted rewriter and discovery both call it.file:spec through that lookup. As in the hosted rewriter, only entries innpm_non_registry_entriesqualify, so a plain workspace-member link is still first-party source.Discovery::vendored_shadow: when a vendored claim died because its ref was moved toshadowed(an unpatched copy beside it),vendor --checkquotes the diagnostic that names the copy. It no longer says nothing wires the artifact or tells the user to re-vendor. This also corrects the message for the existing bundled / git / url /file:tarball shapes.CLI_CONTRACT.md'svendor --checkparagraph documents the newcopy unpatchedreason.Tests (red → green)
socket-patch-corevex::discover::npm::tests::a_file_directory_link_copy_of_the_same_release_is_not_attestedvendor --vex, standalonevex,vendor --checksocket-patch-cli--test in_process_vendor vendor_npm_file_directory_copy_is_not_attested"vex":{"statements":1}(the issue's exact symptom)Not changed (review notes)
file:directory's own source entryvendor_workspace_member_skipped. That label comes from npm vendored refuses a registry package with vendor_workspace_member whenever a local file: directory (or workspace member) has the same name@version, and the hosted→vendored takeover then un-hosts it, leaving it unpatched #688 and is documented in the contract's error-code table, andnamesake_local_directory_does_not_block_registry_copiespins it. Renaming it to a loudvendor_non_registry_entry_skippedis a contract change, so I've left it as a possible follow-up. The run's own--vexwarning andvendor --checknow name the unpatched copy, so the outcome is no longer silent./code-review highflagged a scoped (@scope/name) folder-name case with no test. That branch ofnpm_link_source_identityis unchanged code from Fix npm file: copy attested by in-run VEX (#1481) #1482.Local verification (head 7b7f58c)
cargo fmt --all -- --check: clean.cargo clippy --workspace --all-features -- -D warnings: clean.cargo test --workspace --all-features(run in chunks because of the sandbox's disk allowance): every suite passes except 10 write-failure tests that rely on read-only permissions (relax_loop_must_not_traverse_symlinked_root,an_unremovable_hidden_lock_keeps_every_store_entry,wire_write_failure_*,wire_failure_rolls_back_*,*_state_write_failure_*,partial_lockfile_write_failure_*,redirect_json_mode_write_failures_*,scan_redirect_vlt_heal_invalidation_failure_warns). The sandbox runs as root, which bypasses those permissions. The tests are unrelated to this diff, and CI runs them as a non-root user.e2e_vendor_npm_buildande2e_redirect_npm_buildwith--include-ignoredon real npm 10.9.4: 36 and 43 passed./code-review highran on the diff. Fixed from it: thevendor --checkfalse "wiring missing" diagnosis, the link lookup gated tofile:entries, the vacuous in-run VEX assertion, the missing workspace-member control, and the split name derivation. Not fixed, with reasons under "Not changed".npm/,pypi/andgem/only dispatch to the binary.🤖 Generated with Claude Code
Generated by Claude Code