fix(vendor): carry berry lock original across patch updates - #190
Open
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Open
fix(vendor): carry berry lock original across patch updates#190Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Conversation
Re-vendoring a yarn berry project under a new patch uuid dropped the pre-vendor registry lock entry from the ledger: the berry lock wiring key is the file: locator key, which embeds the uuid, so the carry-forward in persist_vendor_entry never matched the record being replaced. A later `vendor --revert` then deleted the artifact dir but left the dangling file: entry in yarn.lock, breaking `yarn install --immutable` until a plain install re-resolved it. Wiring identity is now uuid-agnostic (wiring_key_matches normalizes the embedded .socket/vendor/<eco>/<uuid> level), so revert restores the pristine registry entry byte-for-byte; old ledgers parse and match unchanged. Also: post-pack wiring failures in the yarn berry and classic backends now unwind the freshly created .socket/vendor uuid dir (previously orphaned with no ledger entry, so revert could never remove it), and berry vendoring surfaces npm-alias descriptors of the patched package - a loud vendor_alias_entry_skipped warning when a plain entry also vendors, and an alias-aware refusal detail when the alias is the only consumer - instead of silently leaving that copy on the unpatched bytes. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Wenxin Jiang (Wenxin-Jiang)
approved these changes
Aug 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.
Problem
Three audit findings (2026-08-13 vendored-mode audit) against the yarn berry vendor backend:
High — berry wiring key embeds the patch uuid, breaking the pre-vendor-original carry-forward. Re-vendoring after a patch update (new uuid) rewrites our own stale
file:lock entry and recordsoriginal: None; the ledger carry-forward inpersist_vendor_entrymatched wiring records by byte-equal(file, kind, key), and berry's lock key is thefile:locator key embedding.socket/vendor/npm/<uuid>/…— so the uuid change that caused the re-vendor also broke the match, and the registry original recorded at first vendoring was dropped. A latervendor --revertthen deleted the artifact dir but left the danglingfile:entry in yarn.lock (vendor_lock_entry_drifted), permanently breakingyarn install --immutableuntil a plain install re-resolved it.Low — post-pack wiring failures orphan
.socket/vendorartifacts. Failures afterstage_patch_packwrote the tarball (berry: tarball re-read, cache-checksum refusal such as a non-ASCII filename, package.json serialize, commit; classic: lock block vanished, lock write) returneddone_failurewithout removing the freshly created uuid dir. No ledger entry exists for a failed wiring, so--revertcould never clean it up — contradicting the module contract that a failure leaves the project byte-untouched.Medium — berry vendoring silently skipped npm-alias descriptors of the patched package. An
alias@npm:<name>@…lock entry resolving the patched version is semantically out of reach for a name-keyed resolutions entry, but the skip was silent: with both a plain and an aliased entry, only the plain one vendored and the aliased copy kept installing the unpatched bytes with zero warnings; with only the alias entry, the genericvendor_lock_entry_not_found("make sure the package is installed") sent users to ayarn installthat changes nothing.Fix
Wiring identity is now uuid-agnostic: new
vendor::path::wiring_key_matches()treats keys as equal when they are byte-equal, or when they are equal after normalizing every embedded canonical.socket/vendor/<eco>/<uuid>level (normalize_vendor_uuids, gated on known ecosystem dirs and canonical uuids — non-vendored keys still only match byte-equal).persist_vendor_entryuses it for the carry-forward, which is already scoped to the same candidate purl, so no cross-package matching is possible. No ledger schema change; old ledgers parse and match unchanged. Revert after a patch update now restores yarn.lock and package.json byte-for-byte.New
done_failure_unstage()innpm_commonunwinds the uuid dir at every post-pack wiring-failure site in the berry and classic backends — but only when this run created the dir (a preexisting same-uuid dir may still be referenced by live wiring), with non-recursive empty-parent pruning so sibling artifacts are untouched. Deliberate scope: failures insidestage_patch_packare unchanged — the audited finding covered post-pack wiring sites.scan_berry_targetnow collects alias-descriptor entries resolving the patched version (via classic'spattern_real_name). When a plain entry also vendors, each aliased entry gets a loudvendor_alias_entry_skippedwarning naming the unreachable copy; when the alias is the only consumer, thevendor_lock_entry_not_foundrefusal explains that berry resolutions are name-keyed and cannot reach aliased descriptors. Aliases of other versions stay quiet (out of the patch's scope).No findings were skipped.
Testing
revendor_new_uuid_carries_original_forward_yarn_berry(in_process_vendor): vendor under uuid A → bump manifest to uuid B → re-vendor → assert the lock wiring record regained the registry original →--revert→ assert yarn.lock and package.json byte-exact. Independently re-verified RED on the pre-fix carry-forward (fails at exactly the original-carry assertion withoriginal: null).wiring_key_matching_is_uuid_agnostic_for_vendored_paths(path.rs),alias_descriptor_entry_warns_and_stays_untouched+alias_only_lock_refuses_with_alias_detail(berry),post_pack_wiring_failure_unwinds_the_staged_artifact(berry, non-ASCII-filename vector),lock_write_failure_unwinds_the_staged_artifact(classic, unix read-only-root vector).cargo test -p socket-patch-core --lib(2080 passed),cargo test -p socket-patch-cli --test in_process_vendor(28 passed),cargo test -p socket-patch-cli --test e2e_vendor_yarn_berry_build(6 passed, real corepack yarn capstone incl. immutable fresh-checkout install + revert), pluse2e_vendor_yarn_classic_build,repair_vendor_flavors_e2e,repair_vendor_e2e,scan_vendor_e2eduring implementation.🤖 Generated with Claude Code
Note
Medium Risk
Changes yarn berry and classic vendor lock/wiring and artifact cleanup paths that affect revert and failure semantics; scoped to vendor backends with substantial regression tests, but incorrect uuid key matching could still mis-revert lockfiles.
Overview
Fixes three yarn berry vendor audit issues around re-vendor after a patch uuid change, failed wiring cleanup, and npm alias lock entries.
Re-vendor / revert: Berry lock wiring keys embed
.socket/vendor/.../<uuid>/, so a patch update broke byte-equal carry-forward of the pre-vendororiginalinpersist_vendor_entry. Matching now useswiring_key_matches(uuid-normalized keys for embedded vendor paths), so--revertcan restoreyarn.lockandpackage.jsonbyte-for-byte after re-vendor.Post-pack failures: Yarn berry and classic backends call
done_failure_unstageafter tarball staging when later wiring steps fail, removing a newly created uuid artifact dir (not pre-existing dirs) so failures do not leave orphan.socket/vendortrees without ledger entries.Berry aliases:
scan_berry_targetcollectsalias@npm:<name>@…entries for the patched version—warnings when a plain entry still vendors, and a clearer refusal when aliases are the only consumer (name-keyed resolutions cannot reach them).Reviewed by Cursor Bugbot for commit c9e29bb. Configure here.