GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix yarn classic VEX for unlocked dep ranges (#1538) by mikolalysenko · Pull Request #1548 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 14, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #1538

Summary

A yarn.lock pin written by v4.0.0 can lock a patched package whose
patched package.json adds a dependency or changes a range the lock
never locked. Yarn 1 installs what the lock names, so the patched
package runs beside the old dependency. #1463 made the hosted rescan
flag such a pin, but three VEX paths still attested it not_affected.
They now omit it.

Root cause

Hosted yarn classic VEX never compared what the patched package.json
asks for with what the install or the lock actually provides:

  1. Installed vex / in-run scan --vex (changed range).
    vex/verify.rs unresolved_npm_dependency only checked that
    node_modules/<dep> existed. (The in-run path verifies like
    standalone vex for a pin the run reported redirect_unconfirmed,
    since refused uuids never enter the assumed-applied set, so it shared
    this gap.)
  2. Lock-only vex (added dependency) and 3. lock-only vex
    (changed range).
    The lockfile basis excused package_not_found
    without looking at the pinned block's dependencies: sub-map.

Fix

  • Installed: find the copy node actually loads (the nearest
    node_modules/<dep>) and require its version to satisfy the declared
    range (utils::npm_range, moved from the yarn berry backend so both
    callers share it). Installed optional dependencies are range-checked
    too. A dependency the project forces for this package (npm
    overrides, pnpm.overrides, yarn resolutions, either unscoped or
    scoped under the patched package itself; not * or empty) is not
    range-checked, because its version is the user's choice. Undecidable ranges or versions and
    non-registry specs are never evidence (same as before).
  • Lock-only: discovery keeps each hosted classic pin's block
    (PatchedRef::yarn_classic_block). When vex would attest from the
    lock alone and the patch changes package.json, it reads the patched
    package.json (.socket/blobs, else GET /patch/blob/<afterHash>)
    and requires the block's sub-maps to declare exactly those dependencies
    (compared by value, whichever way yarn quoted them), each one locked.
    Otherwise the patch is omitted:
    • dependency_not_installed when the sub-maps differ, or
    • new dependency_manifest_unverifiable when the patched
      package.json can't be read (--offline without the local blob, or
      a fetch failure). This fails closed and is documented in
      CLI_CONTRACT.md.

Per-issue checklist (#1538)

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 —

Test evidence (local, Linux, rust 1.93.1)

  • cargo fmt --all -- --check: clean
  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo test -p socket-patch-cli --all-features --test e2e_vex_lockfile -- yarn::: 14/14 pass
  • cargo 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.
  • Wrappers (npm/, pypi/, gem/) only dispatch the binary, so they need no change.

Code review (/code-review high) findings not fixed

  • --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.
  • Patched manifests are fetched one purl at a time. Only hosted yarn classic pins whose patch changes package.json and that aren't installed reach the fetch, so the set is tiny and sequential fetching is fine.

Review rounds

  • /code-review high: fixed overrides, optional deps, sub-map quoting
    (compared by value), blob path / hash validation, and the shared
    record-key helper; the two not fixed are explained above.
  • Bugbot / reviewer findings on scoped overrides (@types/x, nested npm
    parents, parent>dep, parent/dep, parent/**/dep, *, padded *)
    were all fixed, each with a unit case, and every thread is resolved.
    Bugbot's review of 2734608 found no issues.

Follow-ups

  • 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.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@claude
Start fix for #1538
e4193a2
Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 14, 2026
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-only vex doesn't check at all #1538
Closed
Claude (claude) added 2 commits October 14, 2026 20:45
@claude
Check installed npm deps against declared range
f28e8f2
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
@claude
Check yarn classic lock deps in lock-only VEX
41855ff
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
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 14, 2026
Swarm health manager log #1382
Open
@claude
Tighten #1538 checks after code review
0b42c38
- 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
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 14, 2026 21:31
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 14, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for 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.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/socket-patch-core/src/vex/verify.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@claude
Match override keys by their last selector
e8accad
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
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 14, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for 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.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/socket-patch-core/src/vex/verify.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

Tanmay182003
Tanmay Singla (Tanmay182003) reviewed Oct 14, 2026
View reviewed changes
Comment thread crates/socket-patch-core/src/vex/verify.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@claude
Ignore no-op npm overrides in the range check
a12e919
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
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 14, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for 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.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/socket-patch-core/src/vex/verify.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@claude
Only count overrides that reach the patched copy
354d977
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
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 14, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for 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.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/socket-patch-core/src/vex/verify.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@claude
Scope parent/**/dep resolutions to the parent
2734608
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
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 14, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for 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.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Tanmay182003
Tanmay Singla (Tanmay182003) approved these changes Oct 14, 2026
View reviewed changes
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit e719a9b Oct 14, 2026
54 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-yarn-classic-vex-dep-ranges branch October 14, 2026 23:56
This was referenced Oct 15, 2026
CI perf (settings): slow Depot 16-core hosts since 10-13 15:20 add ~1.5–2.5 min to the merge-queue critical path (~0.6k Linux job-min/day) #1512
Open
CI performance dashboard #1182
Open
Lock-only yarn classic VEX wrongly omits a correctly pinned patch with dependency_not_installed when the patched package.json has a "" range or a dependency yarn de-duplicates (regression from #1548) #1558
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments
@Tanmay182003 Tanmay Singla (Tanmay182003) Tanmay182003 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

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-only vex doesn't check at all

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@mikolalysenko @Tanmay182003 @claude
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.