Fix yarn classic rewiring git-sourced lock blocks (#363) - #710
Open
Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
Open
Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
Conversation
yarn 1 installs a git dependency (git+https:, git:, ssh:, a .git url, or a github.com/<owner>/<repo> url) with its git fetcher, and uses the lock entry's resolved value as the git remote. Hosted and vendored scans rewrote that value to a tarball, so every later yarn install failed while the scan reported success. Rollback then wrote a registry tarball in the same place, which fails the same way. Both rewriters now leave these entries byte-identical, with a warning that names them. Rollback refuses a hosted pin on such an entry and points to git checkout. Hosted codeload shorthands (owner/repo, github:) are tarballs to yarn and are still rewired. Refs #363 Assisted-by: Claude Code:claude-opus-5-5
yarn 1 installs a git-sourced yarn.lock entry from git, whatever its resolved value says, so that copy stays unpatched. vex no longer attests the package from yarn.lock while such a copy exists. A Socket wiring that an older release wrote onto a git entry is reported instead of attested, and rollback fails it closed. An end-to-end test against real yarn 1 checks that a hosted scan leaves a git dependency alone and that a frozen install still succeeds. Fixes #363 Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
force-pushed
the
agent/fix-yarn-classic-git-pattern-blocks
branch
from
October 3, 2026 18:27
a0af7a6 to
15b5702
Compare
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 3, 2026 18:30
Collaborator
Author
|
BugBot review Generated by Claude Code |
The hosted yarn classic rewriter checked for alias-only blocks before git blocks. An npm: alias of a git range was therefore reported as an alias skip, and its uuid was not excluded from the in-run --vex assumption. That let the VEX attest a package whose aliased git copy stays unpatched. The git check now runs first. Refs #363 Assisted-by: Claude Code:claude-opus-5-5
Collaborator
Author
|
BugBot review Generated by Claude Code |
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 e96a709. Configure here.
Collaborator
Author
|
[burn-down agent] Ready for review at head
Slack announcement not sent: this run has no Slack send tool. Generated by Claude Code |
Tanmay Singla (Tanmay182003)
approved these changes
Oct 5, 2026
This branch has not been deployed
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 #363
Summary
Yarn classic projects that depend on a package through git (
"left-pad": "git+https://…/left-pad.git#v1.3.0") could no longer install anything afterscan --mode hostedorscan --mode vendored. The scan reported success and the in-run VEX attestednot_affected. These entries are now left alone with a named warning and are never attested. Rollback fails closed on a git entry an older release had already rewired, instead of "restoring" it to a registry tarball that still breaks the install.Root cause
The yarn classic lock code picks a
yarn.lockblock by package name andversiononly. Three places do this: the hosted rewriter (patch::redirect::rewrite_yarn_classic), the vendored classifier (vendor::yarn_classic_lock::classify_classic_block) and the hosted restorer (upstream::npm::restore_classic). VEX discovery (vex::discover::yarn) then trusted whatever the block'sresolvedsaid.Yarn 1, however, picks its fetcher from the key's pattern. A pattern that yarn's
GitResolver.isVersionaccepts goes through the git fetcher, which usesresolvedas the git remote. Those patterns aregit+<x>:,git:,ssh:, a url whose path ends in.git, or a barehttps://github.com|gitlab.com|bitbucket.*/<owner>/<repo>. A tarball written intoresolvedmakes yarn rungit ls-remoteon a.tgz(hosted) or spawn git inside one (vendored,ENOTDIR).Fix
vendor::yarn_classic_lock::classic_block_is_git/yarn_classic_range_is_gitis one shared model of yarn 1's git detection. It checks each key pattern's range (annpm:alias's target included) and the block's ownresolved.npm:alias of a git range included, checked before the alias gate) stays byte-identical, withredirect_yarn_classic_git_skippednaming it. If another block of the same package was rewired, the uuid goes intobundled_skipped_uuids, so the in-run--vexverifies the installed tree instead of assuming the patch applied.BlockClass::GitSkipgivesvendor_yarn_classic_git_entry_skipped. A git-only lock is refused withvendor_lock_entry_not_foundbefore any write.yarn.lockref for that package (patched_ref_unattributable), and a Socket wiring on a git block is diagnosed instead of attested. Rollback, which plans from discovery, therefore fails such a pin closed with thegit checkout -- yarn.lockremedy.owner/repo,github:owner/repo) lock to a codeload tarball that yarn fetches as a tarball, so they are still rewired. The issue's 2026-10-01 evidence called this scope out.docs/ecosystems.mddocuments the behaviour.No wrapper changes:
npm/,pypi/andgem/only dispatch to the binary.Tests (red → green)
vendor::yarn_classic_lock::tests::yarn_classic_git_ranges_are_recognizedpatch::redirect::tests::yarn_classic_git_pattern_block_is_skipped(git-only, git beside registry, annpm:alias of a git range, codeload shorthand)vendor::yarn_classic_lock::tests::git_pattern_block_is_skipped_with_warning,git_only_lock_is_refused_untouched,codeload_shorthand_block_is_still_rewritten(regression guard)vex::discover::yarn::tests::classic_git_pattern_copies_are_never_attestedupstream_restore_golden::yarn_classic_git_pattern_pin_is_refusedin_process_rollback_hosted::a_git_pattern_hosted_pin_is_refused_not_restored_to_the_registrye2e_redirect_yarn_classic_build::classic_git_sourced_dependency_is_left_unrewired: localgit+file:source, hosted scan leavesyarn.lockbyte-identical, names the skip, attests nothing, freshyarn install --frozen-lockfilesucceedsLocal runs:
cargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --all-features: 4852 lib tests, 4848 pass. The 4 failures are chmod-based permission tests that cannot fail when run as root, which this sandbox is; they are untouched by this PR. Integration suites pass.e2e_redirect_yarn_classic_build(13),e2e_vendor_yarn_classic_build(11),in_process_rollback_hosted(23),e2e_vex_lockfile(286),mode_migration_npm(15),upstream_restore_golden(43): all pass. The yarn e2e suites ran withSOCKET_PATCH_YARN_E2E_REQUIRED=1.cargo fmt: the changed regions are rustfmt-clean.mainitself is not rustfmt-clean under the pinned 1.93.1 rustfmt, and CI runs no fmt job, so unrelated files were left alone.The e2e test skips on Windows, where
git+file:urls over drive-letter paths are unreliable in yarn 1. The logic is OS-independent and unit-tested.🤖 Generated with Claude Code
https://claude.ai/code/session_01HfVbURTmD44zbwytAUWMcE
Note
Medium Risk
Changes lockfile rewrite, VEX attestation, and rollback for Yarn Classic git dependencies—security-sensitive paths—but behavior is narrowly scoped, fail-closed, and heavily tested.
Overview
Fixes #363: Yarn Classic lock entries that install from git are no longer rewritten to hosted or vendored tarballs, which previously broke
yarn installbecause Yarn 1 still fetches those blocks via git usingresolvedas the remote.Shared detection (
classic_block_is_git/yarn_classic_range_is_git) mirrors Yarn 1’s git-pattern rules. Hosted redirect skips matching blocks withredirect_yarn_classic_git_skippedand treats the patch uuid like other unverified copies (bundled_skipped_uuids). Vendored flow addsGitSkip/vendor_yarn_classic_git_entry_skipped. VEX discovery does not attest packages when a live git copy exists inyarn.lock, including legacy Socket-wired git blocks (DIAG_REF_UNATTRIBUTABLE). Rollback / upstream restore refuses to “fix” git-pattern pins by swapping in registry tarballs. Codeload shorthand blocks remain rewritable.Coverage adds unit, golden, rollback, and real Yarn 1 e2e tests;
docs/ecosystems.mddocuments the behavior.Reviewed by Cursor Bugbot for commit 15b5702. Configure here.