GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||
GeezerVison is showing github.com — Fix yarn classic VEX for unlocked dep ranges (#1538) by mikolalysenko · Pull Request #1548 · SocketDev/socket-patch Conversation
|
| Path | Test | red → green |
|---|---|---|
| 1. installed, changed range | vex::verify::tests::unresolved_npm_dependency_checks_the_declared_range (unit); e2e_vex_lockfile yarn::hosted_patch_adding_an_uninstalled_dependency_is_omitted ("dependency out of range" cell, all 4 yarn flavors) |
unit: left: None, right: Some("is-number") before the fix, passes after |
| 2. lock-only, added dependency | e2e_vex_lockfile yarn::hosted_classic_lock_only_checks_the_pinned_dependency_maps ("added dependency") |
before: status: success, verified not_affected (exit 0); after: dependency_not_installed |
| 3. lock-only, changed range | same test ("changed range") | same mechanism as 2; passes after |
| controls | same test: a v5 pin (sub-map rewritten, descriptor locked) attests from the API blob and from .socket/blobs only; no blob anywhere gives dependency_manifest_unverifiable |
— |
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-cli --all-features --test e2e_vex_lockfile -- yarn::: 14/14 passcargo test --workspace --all-features --no-fail-fast: 246 test binaries pass. 10 tests fail only in this sandbox. They run as root, so the write-failure / unremovable-file / permission tests can't fail a write (in_process_redirect x3, repair x2, core copy_tree / vlt_heal / pypi_poetry / pypi_requirements write-failure tests), and e2e_bun_lockb::binary_shared_bundled_record_hosted_pin_is_managed needs patches-api.socket.dev, which the sandbox proxy blocks. None of them touch vex or yarn code; CI is the authority.npm/, pypi/, gem/) only dispatch the binary, so they need no change.--no-verify skips the new lock-only gate. That matches Hosted yarn classic rescan and VEX accept a pin written by v4.0.0 whose patched package.json adds a dependency the lock doesn't have, so yarn installs the patched package without it #1462's installed dependency_not_installed check, which also runs only when verifying. --no-verify is the documented trust-the-records mode.package.json and that aren't installed reach the fetch, so the set is tiny and sequential fetching is fine.@types/x, nested npmparent>dep, parent/dep, parent/**/dep, *, padded *)formats::yarn::classic_deps::dep_maps_match (used by the hosted and vendored writers) still compares lines with values always quoted, so it rewrites a block yarn wrote as foo latest needlessly. It's harmless (the rewrite is equivalent) and left out of this PR.🤖 Generated with Claude Code
https://claude.ai/code/session_014eFQuemHsEJCBj24DTCTeq
Generated by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
A hosted yarn classic pin written by v4 can install a patched package whose package.json now asks for a newer dependency range (is-number ^7.0.0) while the lock still installs the old one (6.0.0). vex and scan --vex only checked that node_modules/<dep> existed, so they attested not_affected for a package that runs with the old dependency. The installed check now finds the copy node actually loads (the nearest node_modules/<dep>) and omits the patch with dependency_not_installed when that copy's version is outside the declared range. Ranges or versions the npm range reader can't decide, and non-registry specs, are still never evidence. The npm range reader moves from the yarn berry vendor backend to utils::npm_range so both callers share it. Refs #1538 Assisted-by: Claude Code:claude-opus-5-5
On a checkout with only package.json and yarn.lock, vex attested a hosted yarn classic pin written by v4 even when the patched package adds a dependency or bumps a range the lock never locked. Yarn 1 installs the dependencies the pinned block's sub-maps name, so such a pin installs the patched package without what it now needs. Discovery now keeps the pinned block of each hosted classic pin. When a patch changes package.json and vex would attest it from the lock alone, it reads the patched package.json (.socket/blobs, else the patch API) and requires the block's dependency sub-maps to be exactly the patched ones, each locked. Otherwise the patch is omitted with dependency_not_installed, or dependency_manifest_unverifiable when the patched package.json can't be read. Fixes #1538 Assisted-by: Claude Code:claude-opus-5-5
- Skip the installed range check for a dependency the project forces with npm overrides, pnpm.overrides or yarn resolutions: its version is the user's choice, not a sign the patch is missing. - Range-check installed optional dependencies too (absent ones are still fine), so installed and lock-only VEX agree. - Compare a yarn classic block's sub-maps with the patched package.json by value, so `foo latest` (how yarn writes it) matches. - Read the patched package.json blob from the manifest's .socket dir, accept only a 64-hex hash as its name, and check its size before reading it. - Share the package.json record-key rule and compute the lock-only candidates once. Refs #1538 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
The installed range check skipped any dependency an override key merely mentioned: a nested npm override's parent (which only scopes the overrides under it) counted as forced, and splitting keys on every `/` made `@types/react` force `react`. Keys are now read with the yarn selector parser (scope-aware), after pnpm's `>`, and a nested npm override's parent counts only when its "." entry forces it. Refs #1538 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
An npm override of "*" or "" (directly or as a nested override's "." entry) keeps the declared range, so it doesn't force the dependency's version and the installed copy is still range-checked. A "$name" reference pins the root's own spec and still counts as forced. Refs #1538 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
An override scoped under another package (yarn "mkdirp/minimist",
pnpm "mkdirp>minimist", npm {"mkdirp": {"minimist": ...}}) doesn't
touch the patched package's own copy of the dependency, so it no
longer skips the range check. Overrides are read as (parent, target)
pairs and count only when unscoped or scoped under the patched
package itself. A whitespace-padded "*" is a no-op like "*".
Refs #1538
Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
A yarn resolution "mkdirp/**/minimist" only reaches minimist under mkdirp, but the range check read the "**" as no parent and treated it as forcing minimist everywhere. The parent is now the nearest segment before the target that isn't "**"; only a leading "**/" applies everywhere. Refs #1538 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
✅ 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 2734608. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Yarn classic VEX still attests a pre-v5 hosted pin that yarn installs without the patched package's dependencies: #1463 checks only that the dependency's name is installed, and lock-onlyvex doesn't check at all
There was an error while loading. Please reload this page.