Skip to content

fix(graph-hasher): resolve GVS engine per-snapshot for runtime-pinned deps#11693

Merged
zkochan merged 5 commits into
mainfrom
fix-11690
May 17, 2026
Merged

fix(graph-hasher): resolve GVS engine per-snapshot for runtime-pinned deps#11693
zkochan merged 5 commits into
mainfrom
fix-11690

Conversation

@zkochan

@zkochan zkochan commented May 17, 2026

Copy link
Copy Markdown
Member

Summary

Closes #11690.

A dependency that declares engines.runtime in its manifest carries the desugared dependencies.node: 'runtime:<version>' pin in the lockfile, and pnpm's bin linker spawns that dep's lifecycle scripts through the pinned Node downloaded into <pkgDir>/node_modules/node/. The GVS hash and the side-effects-cache key prefix were still anchored to the install-wide runtime — so the pinning snapshot's slot encoded the wrong Node major, and a reinstall on the same host could read the cached side-effects under a key whose <platform>;<arch>;node<major> triple disagreed with the Node the build actually ran on.

Per-snapshot resolution now matches what bins/linker already does on a per-package basis: a snapshot's own pin wins; the install-wide value (from #11689's findRuntimeNodeVersion) is the fallback.

TypeScript

  • deps/graph-hasher/src/index.ts:72-77 — adds readSnapshotRuntimePin(children): pulls the bare Node version from a graph node's children.node entry when that points at a node@runtime:<version> snapshot. Factors out a small extractRuntimeNodeVersion(snapshotKey) parser shared with findRuntimeNodeVersion.
  • deps/graph-hasher/src/index.ts:115-116,245-246calcDepState and calcGraphNodeHash consult readSnapshotRuntimePin(graph[depPath].children) first and only fall back to the install-wide nodeVersion parameter when the snapshot doesn't pin its own Node. No caller changes required — install-wide fallback continues to be computed via findRuntimeNodeVersion(Object.keys(graph)) at each call site.
  • Refactor (separate commit): findRuntimeNodeVersion moved from @pnpm/engine.runtime.system-node-version to @pnpm/deps.graph-hasher (along with the new readSnapshotRuntimePin). system-node-version is about probing the host Node — getSystemNodeVersion, engineName. The lockfile-shape parsers fit better next to the package that actually composes the engine string. Every caller already depended on graph-hasher, so no new deps; six packages drop the now-unused dependency on system-node-version.

Pacquet

  • pacquet/crates/package-manager/src/install_frozen_lockfile.rs:1309-1345 — new find_own_runtime_node_major(snapshot) reads a snapshot's dependencies for a node entry with Prefix::Runtime, returning the bare major.
  • pacquet/crates/package-manager/src/virtual_store_layout.rs:178-205VirtualStoreLayout::new resolves engine per-snapshot inside the hash loop via engine_name(own_major, None, None) when the snapshot pins, otherwise inherits the install-wide engine argument.

Migration

Snapshots of dependencies that declare their own engines.runtime re-hash under that dep's pinned Node instead of the install-wide value. Old slots become prune-eligible on next install.

Test plan

  • pnpm --filter @pnpm/deps.graph-hasher test — 33 tests pass (6 new: findRuntimeNodeVersion extraction, readSnapshotRuntimePin extraction, own-pin precedence in calcGraphNodeHash, fallback path, cross-pinning siblings produce distinct slots, own-pin precedence in calcDepState)
  • pnpm --filter @pnpm/engine.runtime.system-node-version test — 5 tests pass (unchanged; engineName/getSystemNodeVersion only)
  • pnpm --filter @pnpm/installing.deps-resolver test — 60 tests pass
  • pnpm --filter @pnpm/building.during-install test — 3 tests pass
  • cargo nextest run -p pacquet-package-manager — 273 tests pass (5 new: 4 covering find_own_runtime_node_major's extraction rule + cross_pinning_siblings_get_distinct_slots at the layout level)
  • cargo nextest run -p pacquet-graph-hasher — 32 tests pass
  • cargo clippy -p pacquet-package-manager --tests -- --deny warnings — no new lints in the touched files (pre-existing clippy errors in hoist/tests.rs and link_hoisted_modules/tests.rs are unrelated)
  • Manual GVS parity test with a fixture where two siblings declare different engines.runtime pins — would need the mocked registry to host packages with engines.runtime manifest fields; tracked as a follow-up to extend pacquet/crates/cli/tests/pnpm_compatibility.rs

Written by an agent (Claude Code, claude-opus-4-7).

… deps

A dependency that declares `engines.runtime` carries the desugared
`dependencies.node: 'runtime:<version>'` pin, and the bin linker spawns
that dep's lifecycle scripts through the pinned Node — but the GVS hash
and side-effects-cache key prefix still anchored to the install-wide
runtime, mis-keying the cache for cross-pinning installs. Per-snapshot
resolution now reads each snapshot's own pin from its graph children,
falling back to the install-wide value only when absent. Closes #11690.
Copilot AI review requested due to automatic review settings May 17, 2026 00:13
@coderabbitai

coderabbitai Bot commented May 17, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Per-snapshot engine pinning: snapshots that contain a node@runtime:<version> child now contribute that pinned Node major to engine-name hashing; otherwise the install-wide fallback is used. Hashing, graph state, and VirtualStoreLayout slot paths now reflect per-snapshot runtime pins.

Changes

Per-snapshot engine pinning for GVS hash

Layer / File(s) Summary
Runtime pin extraction infrastructure
deps/graph-hasher/src/index.ts, deps/graph-hasher/test/index.ts, engine/runtime/system-node-version/src/index.ts, engine/runtime/system-node-version/test/getSystemNodeVersion.test.ts
Adds parsing and exported helpers (findRuntimeNodeVersion, readSnapshotRuntimePin) to parse node@runtime: snapshot keys and extract per-snapshot pins from a graph node's children.node; updates tests and JSDoc.
Graph-hasher per-snapshot engine integration
deps/graph-hasher/src/index.ts, deps/graph-hasher/test/calcGraphNodeHash.test.ts
calcDepState and calcGraphNodeHash now call readSnapshotRuntimePin(...) and prefer a snapshot's pin over the install-wide nodeVersion; adds tests for pin-preference, fallback, and sibling cross-pinning.
Pacquet per-snapshot engine slot computation
pacquet/crates/package-manager/src/install_frozen_lockfile.rs, pacquet/crates/package-manager/src/virtual_store_layout.rs
Adds find_own_runtime_node_major() to read dependencies.node: "runtime:<ver>" per snapshot and passes per-snapshot snapshot_engine into calc_graph_node_hash, plus tests asserting distinct GVS slots for differently pinned siblings.
Import/tsconfig & package.json dependency migrations
building/*, deps/graph-builder/*, installing/*, deps/graph-builder/src/iteratePkgsForVirtualStore.ts, building/after-install/src/index.ts, etc.
Move findRuntimeNodeVersion consumers to @pnpm/deps.graph-hasher, remove @pnpm/engine.runtime.system-node-version workspace deps and related TS project references across multiple packages.
Changesets, docs, and misc updates
.changeset/*, cspell.json, exec/commands/test/dlx.e2e.ts
Adds changeset entries documenting the version bumps and per-snapshot fix, updates spell list, and adjusts an inline test mock comment.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

  • pnpm/pnpm#11689: Moves hashing to use a project-level runtime; this PR extends that pipeline to prefer per-snapshot node@runtime:* pins.

Poem

🐰 I hop through snapshots, sniffing pins with care,
Each package's node major now tells me where,
Hashes chase the runner that actually ran,
No stale builds reused — a tidy plan! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: resolving the GVS engine per-snapshot for runtime-pinned dependencies, which is the core fix implemented across the changeset.
Linked Issues check ✅ Passed The PR implements all primary coding requirements from #11690: per-snapshot engine resolution in both TypeScript (via readSnapshotRuntimePin and calcGraphNodeHash/calcDepState updates) and Rust (via find_own_runtime_node_major and VirtualStoreLayout changes), with comprehensive test coverage for distinct slots and cache-key behavior.
Out of Scope Changes check ✅ Passed All changes are within scope of the linked issue #11690: core engine resolution refactoring, moving findRuntimeNodeVersion to graph-hasher, updating callers, removing unneeded dependencies, and adding tests—with no extraneous modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-11690

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions

github-actions Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Micro-Benchmark Results

Linux

group                          main                                   pr
-----                          ----                                   --
tarball/download_dependency    1.01      5.1±0.07ms   856.4 KB/sec    1.00      5.0±0.10ms   861.2 KB/sec

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (2)
.changeset/gvs-engine-per-snapshot-runtime-pin.md (2)

9-9: 💤 Low value

Consider rephrasing for clarity.

The phrase "triple disagreed with the Node" is slightly awkward. Consider:

  • "triple that disagreed with the Node the build actually ran on"
  • "triple mismatched the Node the build actually ran on"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.changeset/gvs-engine-per-snapshot-runtime-pin.md at line 9, Reword the
awkward phrase "triple disagreed with the Node" to a clearer alternative;
replace it with one of the suggested phrasings such as "triple that disagreed
with the Node the build actually ran on" or "triple mismatched the Node the
build actually ran on" in the changelog text so the sentence reads smoothly and
unambiguously.

11-11: 💤 Low value

Clarify the path reference.

The backticked `bins/linker` suggests a code reference but isn't a complete package name. Consider either:

  • Using the full package name if referring to a specific package (e.g., @pnpm/bins/linker)
  • Removing backticks if describing functionality generically: "the bin linker"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.changeset/gvs-engine-per-snapshot-runtime-pin.md at line 11, The reference
to `bins/linker` is ambiguous; update the text to either use the full package
name (for example, `@pnpm/bins/linker`) if you mean that specific module, or
remove the backticks and rephrase to a descriptive term like "the bin linker" if
you mean the functionality generically; ensure the chosen form replaces
`bins/linker` wherever it appears so the reference is clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.changeset/gvs-engine-per-snapshot-runtime-pin.md:
- Line 9: Reword the awkward phrase "triple disagreed with the Node" to a
clearer alternative; replace it with one of the suggested phrasings such as
"triple that disagreed with the Node the build actually ran on" or "triple
mismatched the Node the build actually ran on" in the changelog text so the
sentence reads smoothly and unambiguously.
- Line 11: The reference to `bins/linker` is ambiguous; update the text to
either use the full package name (for example, `@pnpm/bins/linker`) if you mean
that specific module, or remove the backticks and rephrase to a descriptive term
like "the bin linker" if you mean the functionality generically; ensure the
chosen form replaces `bins/linker` wherever it appears so the reference is
clear.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f103bf90-b5e8-4c48-968f-cd7b313a07f1

📥 Commits

Reviewing files that changed from the base of the PR and between 3ddde2b and b3e2432.

📒 Files selected for processing (8)
  • .changeset/gvs-engine-per-snapshot-runtime-pin.md
  • deps/graph-hasher/src/index.ts
  • deps/graph-hasher/test/calcGraphNodeHash.test.ts
  • deps/graph-hasher/test/index.ts
  • engine/runtime/system-node-version/src/index.ts
  • engine/runtime/system-node-version/test/getSystemNodeVersion.test.ts
  • pacquet/crates/package-manager/src/install_frozen_lockfile.rs
  • pacquet/crates/package-manager/src/virtual_store_layout.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Agent
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Code Coverage
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Lint and Test (macos-latest)
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Compile & Lint
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use Standard Style with modifications: trailing commas are used, functions are preferred over classes, functions are declared after they are used (hoisting is relied upon).
Functions should have no more than two or three arguments. If a function needs more parameters, use a single options object instead.
Maintain import order: (1) Standard libraries, (2) External dependencies (sorted alphabetically), (3) Relative imports.

Files:

  • engine/runtime/system-node-version/test/getSystemNodeVersion.test.ts
  • deps/graph-hasher/test/index.ts
  • engine/runtime/system-node-version/src/index.ts
  • deps/graph-hasher/test/calcGraphNodeHash.test.ts
  • deps/graph-hasher/src/index.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not use instanceof Error for error type checking in Jest tests. Use util.types.isNativeError() instead, as Jest runs tests in a VM context where instanceof checks can fail across realms.

Files:

  • engine/runtime/system-node-version/test/getSystemNodeVersion.test.ts
  • deps/graph-hasher/test/calcGraphNodeHash.test.ts
pacquet/**/*.rs

📄 CodeRabbit inference engine (pacquet/AGENTS.md)

No star imports inside module bodies — write use super::{Foo, bar} instead of use super::*; and the same for any other glob. Exception: external-crate preludes like use rayon::prelude::*; and root-of-module re-exports like pub use submodule::*; in lib.rs

Files:

  • pacquet/crates/package-manager/src/install_frozen_lockfile.rs
  • pacquet/crates/package-manager/src/virtual_store_layout.rs
🧠 Learnings (1)
📚 Learning: 2026-05-14T09:04:00.133Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11622
File: resolving/npm-resolver/test/publishedBy.test.ts:350-354
Timestamp: 2026-05-14T09:04:00.133Z
Learning: In the pnpm/pnpm repository, ESLint is the authoritative style linter. Do not raise review findings for missing trailing commas in multiline function calls (e.g., `fs.writeFileSync(...)`) when this repo’s ESLint configuration does not report them and lint passes. Prefer deferring to the ESLint results for this specific trailing-comma rule rather than enforcing it manually in code review.

Applied to files:

  • engine/runtime/system-node-version/test/getSystemNodeVersion.test.ts
  • deps/graph-hasher/test/index.ts
  • engine/runtime/system-node-version/src/index.ts
  • deps/graph-hasher/test/calcGraphNodeHash.test.ts
  • deps/graph-hasher/src/index.ts
🪛 GitHub Check: Spell Check
pacquet/crates/package-manager/src/install_frozen_lockfile.rs

[warning] 1325-1325:
"mis" should be "miss" or "mist".

pacquet/crates/package-manager/src/virtual_store_layout.rs

[warning] 606-606:
"mis" should be "miss" or "mist".

🔇 Additional comments (8)
.changeset/gvs-engine-per-snapshot-runtime-pin.md (1)

1-18: LGTM!

engine/runtime/system-node-version/src/index.ts (1)

56-71: LGTM!

Also applies to: 94-95, 100-122

engine/runtime/system-node-version/test/getSystemNodeVersion.test.ts (1)

14-14: LGTM!

Also applies to: 79-93

deps/graph-hasher/src/index.ts (1)

3-3: LGTM!

Also applies to: 34-41, 46-47, 113-122, 171-177

deps/graph-hasher/test/calcGraphNodeHash.test.ts (1)

359-476: LGTM!

deps/graph-hasher/test/index.ts (1)

59-81: LGTM!

pacquet/crates/package-manager/src/install_frozen_lockfile.rs (1)

1309-1345: LGTM!

Also applies to: 1347-1408

pacquet/crates/package-manager/src/virtual_store_layout.rs (1)

23-27: LGTM!

Also applies to: 100-115, 191-210, 343-347, 597-694

@github-actions

github-actions Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Integrated-Benchmark Report (Linux)

Scenario: Frozen Lockfile

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 2.518 ± 0.076 2.400 2.597 1.03 ± 0.04
pacquet@main 2.446 ± 0.064 2.371 2.602 1.00
pnpm 4.956 ± 0.060 4.856 5.065 2.03 ± 0.06
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 2.5177451582000003,
      "stddev": 0.0758590309601731,
      "median": 2.5517359694,
      "user": 2.6484907399999993,
      "system": 3.8197028599999996,
      "min": 2.3996839374,
      "max": 2.5967945164,
      "times": [
        2.5853663294,
        2.5578381394,
        2.4507052474,
        2.3996839374,
        2.5456337994,
        2.5948562204,
        2.5967945164,
        2.4551837234,
        2.4274328324,
        2.5639568364
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 2.4461827885999994,
      "stddev": 0.06359939201817398,
      "median": 2.4427604969,
      "user": 2.70078094,
      "system": 3.7900567599999997,
      "min": 2.3711333324,
      "max": 2.6023979624,
      "times": [
        2.4524917964,
        2.3711333324,
        2.4571728644,
        2.4360800964,
        2.3898370073999997,
        2.6023979624,
        2.4746132134,
        2.4494408973999997,
        2.4207641274,
        2.4078965884
      ]
    },
    {
      "command": "pnpm",
      "mean": 4.9564477562,
      "stddev": 0.06032096692470123,
      "median": 4.9619811869,
      "user": 8.34159854,
      "system": 4.33348946,
      "min": 4.8563210113999995,
      "max": 5.0647666984,
      "times": [
        5.0075585384,
        4.9552289114,
        4.9718653094,
        5.0008929233999995,
        4.9284650984,
        4.9046698833999995,
        4.8563210113999995,
        4.9687334624,
        4.9059757254,
        5.0647666984
      ]
    }
  ]
}

Scenario: Frozen Lockfile (Hot Cache)

Command Mean [ms] Min [ms] Max [ms] Relative
pacquet@HEAD 691.8 ± 42.5 673.4 812.1 1.00
pacquet@main 701.3 ± 19.0 674.2 728.2 1.01 ± 0.07
pnpm 2741.8 ± 66.0 2687.8 2899.9 3.96 ± 0.26
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 0.6917548530200001,
      "stddev": 0.042461631515393186,
      "median": 0.6787576726200001,
      "user": 0.38742965999999995,
      "system": 1.5733559399999997,
      "min": 0.67338222962,
      "max": 0.8121499536200001,
      "times": [
        0.8121499536200001,
        0.67338222962,
        0.6860581926200001,
        0.6813038386200001,
        0.6795592586200001,
        0.6769356986200001,
        0.6779560866200001,
        0.6739249996200001,
        0.6797635126200001,
        0.6765147596200001
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 0.7013323051200001,
      "stddev": 0.01896591474959654,
      "median": 0.6964362541200001,
      "user": 0.38630285999999997,
      "system": 1.5892413399999996,
      "min": 0.6742326606200001,
      "max": 0.7281796756200001,
      "times": [
        0.7272794616200001,
        0.6854834106200001,
        0.6984137506200001,
        0.7251570196200001,
        0.6988009256200001,
        0.6944587576200001,
        0.6904368416200001,
        0.7281796756200001,
        0.6908805476200001,
        0.6742326606200001
      ]
    },
    {
      "command": "pnpm",
      "mean": 2.7418156945199996,
      "stddev": 0.06596700206934673,
      "median": 2.72181855962,
      "user": 3.30502186,
      "system": 2.3022015399999995,
      "min": 2.68777647862,
      "max": 2.89992904662,
      "times": [
        2.69457079062,
        2.75428717862,
        2.68777647862,
        2.89992904662,
        2.74132961162,
        2.7964874806199997,
        2.69595215962,
        2.69558157062,
        2.70230750762,
        2.74993512062
      ]
    }
  ]
}

- Widen `readSnapshotRuntimePin`'s parameter to `Record<string, string>`
  so callers can pass arbitrary graph children, not just `{node?}`.
- Replace "mis-key" wording (flagged by typos) with explicit phrasing.
- Demote the doc link to `find_own_runtime_node_major` to plain code
  since the helper is `pub(crate)` (private-intra-doc-links lint).
- Apply `cargo fmt` to the new tests in install_frozen_lockfile.rs.
@zkochan zkochan added area: supply chain security Issues related to minimumReleaseAge, blockExoticSubdeps, build script safety, and trust policies. and removed area: supply chain security Issues related to minimumReleaseAge, blockExoticSubdeps, build script safety, and trust policies. labels May 17, 2026
@codecov-commenter

codecov-commenter commented May 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.94%. Comparing base (3ddde2b) to head (506aedc).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #11693      +/-   ##
==========================================
+ Coverage   88.83%   88.94%   +0.10%     
==========================================
  Files         129      129              
  Lines       14705    14824     +119     
==========================================
+ Hits        13063    13185     +122     
+ Misses       1642     1639       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Add `desugars` / `desugared` to the cspell dictionary — standard
  programming jargon, used in the new doc comments and changeset.
- Drop the trailing comma inside a single-line `assert_ne!` macro
  invocation (perfectionist::macro-trailing-comma lint).
Copilot AI review requested due to automatic review settings May 17, 2026 09:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

zkochan added 2 commits May 17, 2026 12:05
`exec/commands/test/dlx.e2e.ts` mocks `@pnpm/engine.runtime.system-node-version`
and re-exports every public symbol so transitive consumers keep working
under the mock. The new `readSnapshotRuntimePin` export needs the same
forward — without it `@pnpm/deps.graph-hasher`'s dynamic import sees an
empty binding and the test suite fails to load.
…pm/deps.graph-hasher

`@pnpm/engine.runtime.system-node-version`'s purpose is probing the
*host* Node — `getSystemNodeVersion`, `engineName`. The two lockfile-
shape parsers (`findRuntimeNodeVersion`, `readSnapshotRuntimePin`)
were a poor fit there and are now exported from the package that
actually composes the engine string: `@pnpm/deps.graph-hasher`. Every
caller already depended on graph-hasher, so no new deps are introduced;
six packages drop the now-unused dependency on system-node-version.

The pre-existing `.changeset/gvs-engine-name-shell-node.md` (#11689,
not yet released) is updated to reflect the new home for
`findRuntimeNodeVersion`.
Copilot AI review requested due to automatic review settings May 17, 2026 10:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results

# Scenario main branch
1 Headless (warm store+cache) 2.100s ± 0.068s 2.058s ± 0.036s
2 Re-resolution (add dep, warm) 5.396s ± 0.062s 5.334s ± 0.041s
3 Full resolution (warm, no lockfile) 5.641s ± 0.055s 5.618s ± 0.040s
4 Headless (cold store+cache) 5.062s ± 0.068s 5.057s ± 0.066s
5 Cold install (nothing warm) 11.476s ± 0.132s 11.561s ± 0.142s
6 GVS warm reinstall (warm global store) 1.005s ± 0.065s 0.970s ± 0.014s

Run 25988659855 · 10 runs per scenario · triggered by @zkochan

@zkochan zkochan merged commit 5dc8be8 into main May 17, 2026
31 of 32 checks passed
@zkochan zkochan deleted the fix-11690 branch May 17, 2026 11:25
@coderabbitai coderabbitai Bot mentioned this pull request May 18, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GVS engine field should resolve per-snapshot for deps with engines.runtime pins

3 participants