Skip to content

Fix yarn berry hosted pin of catalog deps (#632) - #763

Open
Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
mainfrom
agent/fix-yarn-berry-catalog-resolutions
Open

Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
mainfrom
agent/fix-yarn-berry-catalog-resolutions

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

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

Fixes #632

Summary

scan --mode hosted now pins yarn berry dependencies declared through a yarn catalog ("left-pad": "catalog:"). Before this, the scan reported redirected: 1, but the next yarn install --immutable failed with YN0028 and a plain yarn install silently installed the unpatched release. This was a regression from #465.

Root cause

Since #465 the hosted yarn berry pin routes the lock entry's descriptors to the hosted tarball through root package.json resolutions, keyed name@npm:<range>. Those keys come from the lock key's expanded ranges in berry_resolutions_pin. Yarn matches resolutions against the manifest descriptor before it expands the catalog, so left-pad@npm:^1.3.0 never matches a dependency declared catalog: or catalog:<named>.

Fix

  • berry_resolutions_pin reads the .yarnrc.yml catalog: / catalogs: tables through the new berry_catalog_selectors (serde-saphyr). Some catalogs give the package a range that, normalized to yarn's npm: form, is one of the pinned ranges. For each of those, the pin also routes name@catalog: or name@catalog:<named> to the hosted tarball.
  • The npm: selectors stay: transitive dependents still ask for the expanded range, and rollback rebuilds the lock key from them.
  • Catalog selectors are derived from the final selector list. So a re-run over a pin written before this fix (lock already keyed by URL, only the npm: selector) adds the missing catalog selector and leaves the lock alone.
  • Rollback needs no change. It already drops every selector routed to the hosted URL and rebuilds the lock key from the npm: ones; a new test covers this.
  • A user-authored name@catalog: resolution still refuses with redirect_yarn_berry_resolutions_conflict.
  • docs/ecosystems.md: the yarn berry hosted notes now describe catalog pins.
  • The npm, PyPI and gem wrappers only dispatch to the binary, so they need no change.

Checked by hand with real yarn 4.12.0:

  • {"left-pad@npm:^1.3.0": X, "left-pad@catalog:": X} installs the patched bytes for a catalog: dependency, and --immutable passes.
  • On a project that defines the catalog but declares a plain range, the unused catalog: selector is harmless: the install gets the patched bytes and --immutable passes.

Per-issue checklist

Test evidence

  • Red to green: with the catalog lookup disabled, the 3 new core tests fail, and so does the real-yarn e2e (no left-pad@catalog: selector). With the fix, all pass: cargo test -p socket-patch-core --lib -- yarn_berry gives 99 passed.
  • cargo test -p socket-patch-cli --test in_process_redirect -- yarn_berry: 5 passed.
  • SOCKET_PATCH_YARN_E2E_REQUIRED=1 cargo test -p socket-patch-cli --test e2e_redirect_yarn_berry_build: 15 passed against real yarn 4.12.0.
  • New code is rustfmt-formatted (cargo fmt --all -- --check also flags pre-existing files on main). cargo clippy --workspace --all-features -- -D warnings is clean.
  • cargo test --workspace --all-features --no-fail-fast locally: 9728 passed, 14 failed. All 14 failures come from the sandbox:
    • 12 are chmod-based write-failure tests, which can't fail when running as root.
    • 2 are mode_migration_npm berry takeover fixtures. Their setup downloads from registry.npmjs.org with a client that rejects the sandbox proxy's TLS certificate.
    • None touch this change, and CI runs them for real: on f3f8ca1, 485 checks passed and 6 were skipped, with no failures. Bugbot reviewed f3f8ca1 and found no issues.
  • 55dc0cb backs out unrelated rustfmt churn. cargo fmt --all had also reformatted 127 files this PR doesn't touch, because main is not rustfmt-clean. The diff is now just the 4 files above. The targeted tests and clippy were re-run after the backout and pass (results above).
  • CI on 55dc0cb is all green: 482 checks passed and 6 were skipped. The PDM backtest native (ubuntu-latest, 2.8.2) failed once (optional hosted, rescanIdempotent) and passed when re-run. Bugbot reviewed 55dc0cb and found no issues.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DPHxnE5P1rkfCpHFFCwzFR


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
A dependency declared "catalog:" in package.json was never patched
by scan --mode hosted: the resolutions entry was keyed by the lock's
expanded npm: range, but yarn matches resolutions before it expands
the catalog. The scan reported success, then yarn install --immutable
failed (YN0028) and a plain yarn install kept the unpatched release.

Also route name@catalog: / name@catalog:<named> for every
.yarnrc.yml catalog that maps the package to a pinned range. A re-run
adds the selector to a pin written by an earlier release.

Fixes #632

Assisted-by: Claude Code:claude-opus-5-5
Add a real-yarn check that a fresh checkout of a hosted-pinned
catalog dependency installs the patched bytes under --immutable,
an in-process scan + rollback round trip, and document catalog
pins in the yarn berry hosted notes.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 4, 2026 08:03
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

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.

cargo fmt --all also reformatted 127 files this fix doesn't touch
(main isn't rustfmt-clean). Restore them and the untouched hunks of
the edited files to main, so the PR only carries the catalog fix,
its tests and the docs note.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 55dc0cb. Configure here.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

One CI check failed on 55dc0cb: native (ubuntu-latest, 2.8.2), the PDM backtest. Only the optional hosted cell failed, on rescanIdempotent. The other 35 PDM cells passed, and so did the other 481 checks.

I don't think this PR caused it:

  • The PR only changes yarn berry code: berry_resolutions_pin and berry_catalog_selectors in patch/redirect/mod.rs, plus yarn tests and docs. The PDM pdm.lock path never calls that code.
  • The same job passed on f3f8ca1. That commit has the same fix code; 55dc0cb only reverts formatting in unrelated files.

I don't have a fix to port, because I haven't found a root cause in the PDM path. I've re-run the failed job once. If it fails again, I'll treat it as a real failure and dig in.


Generated by Claude Code

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 4, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Ready for review at 55dc0cb.

  • CI: 482/482 checks green on the current head. The earlier PDM rescanIdempotent failure did not come back on re-run.
  • Bugbot: reviewed 55dc0cb and found no issues. There are no unresolved review threads.
  • Mergeable: yes, no conflicts with main.
  • For the reviewer: the core change is berry_catalog_selectors / berry_resolutions_pin in patch/redirect/mod.rs. Catalog selectors are added next to the existing npm: selectors, and rollback is unchanged.

Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

2 participants