Skip to content

fix(resolver): match pnpm peer suffix identities and providers - #5

Draft
mwolson wants to merge 1 commit into
contrib/pnpm-lock-rewrite-metadatafrom
contrib/pnpm-lock-peer-suffix-shape
Draft

mwolson wants to merge 1 commit into
contrib/pnpm-lock-rewrite-metadatafrom
contrib/pnpm-lock-peer-suffix-shape

Conversation

@mwolson

@mwolson mwolson commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

Peer suffixes in aube-written pnpm-lock.yaml now match pnpm 12 for peer cycles
and multi-version providers, and local peer providers keep their real identities
through reloads. Upstream
#1849 peer-suffix-alias-optional
covers aliased and out-of-range optional peers, and
#1859 peer-suffix-cycle writes
cyclic providers bare. Upstream discussion:
#1823 pnpm-lock-peer-suffix-shape.

Problem and Fix

Problem and Why it Happened Fix
An unrelated add contextualized a cyclic peer provider that pnpm keeps bare (changing hashed suffixes under peersSuffixMaxLength), and collapsed a consumer that pnpm keeps once per provider version, so one aube add in t3code rewrote about 1,300 lines. peer_context applies pnpm 12's cycle cut and bare cyclic providers, retains eligible locked providers per importer and parent position, and keeps child dedupe from adding peers to an unchanged bare parent's suffix.
Peer semver checks read storage identities for tarball, git and file: providers, and patch hashes leaked into Bun's patch-path map. Version checks use the provider's manifest version, local file: references resolve through the shared lockfile mapping after a reload, contextual local peer links resolve against real graph keys with or without the global virtual store, and peer-identity patch hashes stay separate from per-format patch maps.

Validation

  • Repro pnpm-lock-peer-suffix-shape with pnpm 12.14.0 and 11.10.0.
  • Repro pnpm-lock-peer-cycle-shape (cycle, hashed cycle and multi-version
    provider fixtures) passes; its multi-version provider fixture fails on
    upstream v2.8.4.
  • Tests for provided incompatible peers, cycles, hash parity, strict optional
    peers from tarball/git/file: providers, Bun patch paths (with a native Bun
    frozen install), and large importers.
  • t3code: aube add is-number@7.0.0 in apps/mobile now writes a project
    lockfile byte-identical to pnpm 12.14.0's.

@mwolson
mwolson added this pull request to stack #9 October 24, 2026 23:01
@mwolson
mwolson removed this pull request from stack #9 October 25, 2026 00:54
@mwolson
mwolson force-pushed the contrib/pnpm-lock-peer-suffix-shape branch from b344ffc to 7caf9d4 Compare October 25, 2026 00:55
@mwolson
mwolson added this pull request to stack #17 October 25, 2026 00:55
@mwolson
mwolson removed this pull request from stack #17 October 25, 2026 03:08
@mwolson
mwolson force-pushed the contrib/pnpm-lock-peer-suffix-shape branch from 7caf9d4 to 817f21d Compare October 25, 2026 03:08
@mwolson
mwolson added this pull request to stack #19 October 25, 2026 03:08
@mwolson
mwolson removed this pull request from stack #19 October 25, 2026 17:27
@mwolson
mwolson added this pull request to stack #20 October 25, 2026 17:27
jdx added a commit to aubepkg/aube that referenced this pull request Oct 25, 2026
…optional peers (#1849)

<!-- entire-trail-link-start -->
https://entire.com/gh/aubepkg/-/trails/206/changes/aube/206
<!-- entire-trail-link-end -->

Two peer-suffix keys that aube wrote differently from pnpm, so an
unrelated `aube add` rewrote lockfile lines pnpm would leave alone
(reported in [discussion
1823](#1823)). Both are fixed
here; installs were never broken, this removes lockfile churn.

```text
typescript aliased to npm:@tsc-rs/typescript@0.8.0, ts-api-utils peers on typescript:
  before: ts-api-utils@2.1.0(typescript@0.8.0)
  after:  ts-api-utils@2.1.0(@tsc-rs/typescript@0.8.0)     # matches pnpm

ws@7.5.11 declares optional peer utf-8-validate@^5.0.2, root provides utf-8-validate@6.0.6:
  before: ws@7.5.11
  after:  ws@7.5.11(utf-8-validate@6.0.6)                   # matches pnpm
```

- A peer suffix now names the provider's registry package (`alias_of`)
instead of the alias it is installed under.
- An optional peer that is actually provided (by an ancestor, the
package's own deps, or the workspace root) is bound even when its
version is outside the declared range, like a required peer. The
graph-wide scan for optional peers is still range-gated and still off
without `dedupe-peer-dependents`, so unprovided optional peers stay
bare.

Out of scope: the other rules from the discussion's follow-up comment
(peer cycle suffix shape, optional peer with multiple versions). Those
are larger changes to `peer_context.rs` and will be separate PRs.

Validation: two new unit tests in `peer_context.rs` for the examples
above; `cargo test -p aube-resolver` (all pass), `cargo test -p aube
--test e2e`, `cargo fmt --check`, and `cargo clippy -p aube-resolver
--all-targets -- -D warnings` are clean. I did not run the bats suite,
and did not run the pnpm comparison repro from the discussion end to
end.

Based on the fix in mwolson's fork PR
(mwolson#5), narrowed to these two rules.

*AI-assisted — Tool: Claude Code; model: anthropic/claude-sonnet-5-5;
version: unavailable.*

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

<!-- coderabbit-ai-generated:v1 -->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved peer dependency matching for aliased, directory, link, and
portal packages.
* Optional peer dependencies can now bind to available providers in
ancestors, package dependencies, or the workspace root, even when the
provider’s version falls outside the declared range.
* Peer suffixes for aliased dependencies now use the package’s registry
name.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Mike Olson <mwolson@member.fsf.org>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
@mwolson
mwolson removed this pull request from stack #20 October 25, 2026 21:33
@mwolson
mwolson force-pushed the contrib/pnpm-lock-peer-suffix-shape branch from 817f21d to 62108ef Compare October 25, 2026 21:33
@mwolson
mwolson added this pull request to stack #21 October 25, 2026 21:33
@mwolson
mwolson removed this pull request from stack #21 October 26, 2026 01:06
@mwolson
mwolson force-pushed the contrib/pnpm-lock-peer-suffix-shape branch from 62108ef to 4d0ff42 Compare October 26, 2026 01:07
@mwolson
mwolson added this pull request to stack #22 October 26, 2026 01:07
@mwolson
mwolson removed this pull request from stack #22 October 26, 2026 02:36
@mwolson
mwolson added this pull request to stack #24 October 26, 2026 02:36
@mwolson
mwolson removed this pull request from stack #24 October 26, 2026 11:35
@mwolson
mwolson added this pull request to stack #26 October 26, 2026 11:36
Match pnpm 12's dependency-cycle cuts while retaining upstream's
per-context peer-cycle membership. Include full provider patch identities
and local source contexts before hashing, while retaining the full
provider targets on snapshot edges.

Retain eligible locked providers per importer and parent position. Keep
child dedupe from adding peers to an unchanged bare parent's suffix.

Keep peer patch hashes separate from output metadata and validate source
providers against manifest versions. Index prior importer providers and
compute provider changes once per iteration.

Resolve serialized local providers through shared graph-key mapping.
Retain contextualized file targets on parse and prefer their actual graph
keys when linking, with bare importer keys as a compatibility fallback.
Cover strict optional directory and tarball peers through clean frozen
installs, including incompatible manifest-version rejection.

Resolve materialization and cached link targets against the package graph
without requiring GVS hashes, including Expo's project-local layout.
@mwolson
mwolson force-pushed the contrib/pnpm-lock-peer-suffix-shape branch from 4d0ff42 to d3d00ac Compare October 30, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant