Skip to content

perf(pacquet): share virtual-store slot linking pass#12251

Merged
zkochan merged 1 commit into
mainfrom
codex/pacquet-parallel-cold-linking
Jun 7, 2026
Merged

perf(pacquet): share virtual-store slot linking pass#12251
zkochan merged 1 commit into
mainfrom
codex/pacquet-parallel-cold-linking

Conversation

@zkochan

@zkochan zkochan commented Jun 6, 2026

Copy link
Copy Markdown
Member

Summary

  • share warm/cold virtual-store slot linking through one parallel helper
  • emit structured pacquet install phase metrics for virtual-store partition sizes and link-slot elapsed time
  • generate integrated-benchmark diagnostics artifacts and use them for the fresh pnpr cold-batch and pnpr-vs-direct guardrails
  • split client registry latency/bandwidth from pnpr server registry latency, while rewriting server-origin tarball URLs back to the measured client registry path
  • keep the benchmark PR comment focused on scenario tables and collapsed raw JSON; diagnostics stay available as artifacts instead of inline report noise

Tests

  • cargo test -p pacquet-integrated-benchmark
  • cargo test -p pacquet-integrated-benchmark work_env
  • cargo test -p pacquet-cli registry_rewrite
  • cargo test -p pacquet-package-manager cold_batch_links_slots_in_parallel
  • cargo check -p pacquet-cli --all-targets
  • cargo check -p pacquet-integrated-benchmark --all-targets
  • cargo check -p pacquet-package-manager --all-targets
  • cargo clippy -p pacquet-integrated-benchmark -p pacquet-cli -p pacquet-package-manager -p pacquet-diagnostics --all-targets -- --deny warnings
  • RUSTFLAGS="-D warnings" cargo dylint --all -- --all-targets --workspace
  • ruby -e 'require "yaml"; YAML.load_file(".github/workflows/pacquet-integrated-benchmark.yml")'
  • git diff --check
  • pre-push hook: TypeScript compile/bundle/lint/spellcheck/meta checks, Rust fmt/doc/dylint, Taplo check

Refs #12250


Written by an agent (Codex, GPT-5).

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a benchmark-only pnpr registry/tarball rewrite, threads a test-only link-concurrency probe through linking paths and centralizes parallel slot linking with timing logs, enables JSON tracing format selection, and extends integrated-benchmark orchestration, proxies, diagnostics, and tests.

Changes

Benchmark Registry Rewrite for pnpr

Layer / File(s) Summary
Registry rewrite implementation and integration
pacquet/crates/cli/src/cli_args/install.rs, pacquet/crates/cli/src/cli_args/install/tests.rs
Adds env-driven resolve_registry selection and optional server→client tarball URL rewriting; applies mapping to ResolveOptions, streaming TarballPrefetcher inputs, and mutates returned lockfile resolution URL/tarball fields. Unit tests validate normalization and rewrite behavior.

Virtual Store Concurrency Testing and Slot Linking Refactor

Layer / File(s) Summary
Concurrency testing probe infrastructure
pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot.rs, pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot/tests.rs
Adds LinkConcurrencyProbe and guard types to observe overlapping link operations; exposes test module and updates tests to include link_concurrency_probe wiring.
Centralized slot linking with parallel execution
pacquet/crates/package-manager/src/create_virtual_store.rs
Extracts warm/cold slot linking into link_slots_parallel helper that consolidates rayon parallelism, warm progress emission, invocation of CreateVirtualDirBySnapshot, and link-phase elapsed logging.
Probe threading through install stack
pacquet/crates/package-manager/src/create_virtual_store.rs, pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot.rs, pacquet/crates/package-manager/src/install_package_by_snapshot.rs, pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs, pacquet/crates/package-manager/src/install_package_by_snapshot/tests.rs
Adds #[cfg(test)] link_concurrency_probe fields to structs, destructures and forwards the probe into link-phase helpers and dir creation, and updates call sites to include None where appropriate.
CreateVirtualStore timing and phase logging
pacquet/crates/package-manager/src/install_frozen_lockfile.rs, pacquet/crates/package-manager/src/create_virtual_store.rs
Records wall-clock start and emits tracing::info! with elapsed ms for the create_virtual_store phase; emits partition summary log after warm/cold partitioning.
Store and package tests updates
pacquet/crates/package-manager/src/create_virtual_store/tests.rs
Adds async test cold_batch_links_slots_in_parallel that constructs cached snapshots, runs CreateVirtualStore with a probe, waits for index writer completion, and asserts observed parallel link-slot overlap.

JSON Tracing Format Support

Layer / File(s) Summary
JSON tracing format selection
pacquet/crates/diagnostics/Cargo.toml, pacquet/crates/diagnostics/src/local_tracing.rs
Enables tracing-subscriber json feature and switches enable_tracing_by_env to initialize JSON formatting when TRACE_FORMAT == "json", otherwise uses pretty formatting with file/span-close options.

Integrated Benchmark Enhancements

Layer / File(s) Summary
CLI arguments for split latency configuration
pacquet/tasks/integrated-benchmark/Cargo.toml, pacquet/tasks/integrated-benchmark/src/cli_args.rs, pacquet/tasks/integrated-benchmark/src/main.rs
Adds serde_json dependency; introduces --pnpr-server-registry-latency-ms distinct from client registry latency; updates BenchmarkScenario derives and adds expects_pnpr_not_slower_than_direct(); wires new field into WorkEnv.
Benchmark run orchestration with dual proxies
pacquet/tasks/integrated-benchmark/src/work_env.rs
Refactors run to start a client-facing registry proxy and a pnpr-server-only registry latency proxy, computes client vs pnpr_server registry URLs, and passes pnpr_server_registry into benchmark() and pnpr server startup.
Diagnostics collection, parsing, and rendering
pacquet/tasks/integrated-benchmark/src/work_env.rs
Adds parsing of hyperfine JSON and ndjson phase logs, aggregates partition/link-slot metrics, renders markdown diagnostics, and verifies pnpr/direct timing ratios.
Target-aware install script generation with metrics
pacquet/tasks/integrated-benchmark/src/work_env.rs
Makes install script creation id-driven: pnpr targets source .pnpr-env, pacquet-like targets enable tracing/ndjson metrics; updates .pnpr-env exports and adds BenchId::is_pacquet_like().
Benchmark work environment unit tests
pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
Adds unit tests for NDJSON phase event parsing (including nested fields), phase summarization, pnpr/direct ratio collection, cold-batch predicate logic, and diagnostics markdown rendering.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • pnpm/pnpm#12237: Related — touches pnpr streaming resolution and TarballPrefetcher interactions used by the registry/tarball rewrite.
  • pnpm/pnpm#12144: Related — overlaps the pnpr install/lockfile handling area.
  • pnpm/pnpm#12154: Related — integrates .pnpr-env generation and registry/tarball-rewrite overrides exercised by this PR.

Suggested reviewers

  • KSXGitHub

Poem

"I’m a rabbit who hops through CI and code,
Rewriting registries down the bench-lined road.
Probes count my hops as slot links race,
Proxies add latency to the benchmarked chase.
Tests cheer loud — the metrics keep pace!" 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'perf(pacquet): share virtual-store slot linking pass' accurately summarizes the main change: consolidating warm and cold virtual-store slot linking into a single shared parallel helper pass.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
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 codex/pacquet-parallel-cold-linking

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.

@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Micro-Benchmark Results

Linux

group                          main                                   pr
-----                          ----                                   --
tarball/download_dependency    1.01      7.5±0.23ms   578.8 KB/sec    1.00      7.4±0.16ms   583.6 KB/sec

@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Integrated-Benchmark Report (Linux)

Each scenario reports direct installs and pnpr installs. Bencher consumes pacquet@HEAD and pnpr@HEAD.

Scenario: Isolated linker: fresh restore, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 10.107 ± 0.248 9.811 10.586 1.87 ± 0.07
pacquet@main 9.919 ± 0.119 9.837 10.247 1.83 ± 0.05
pnpr@HEAD 5.407 ± 0.139 5.320 5.789 1.00
pnpr@main 5.420 ± 0.171 5.324 5.886 1.00 ± 0.04
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 10.10742467804,
      "stddev": 0.24771083872370722,
      "median": 10.06821879244,
      "user": 3.0160945999999997,
      "system": 3.283233479999999,
      "min": 9.81051913044,
      "max": 10.58556251944,
      "times": [
        10.34321325844,
        10.58556251944,
        9.97435805344,
        10.16207953144,
        9.86519447944,
        9.92358949744,
        10.20076830444,
        9.93420784444,
        9.81051913044,
        10.27475416144
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 9.91871000874,
      "stddev": 0.11945012909018315,
      "median": 9.87802299644,
      "user": 3.0326915999999993,
      "system": 3.2814273799999993,
      "min": 9.83683363844,
      "max": 10.24651838444,
      "times": [
        9.93267071344,
        9.93096309244,
        9.90323228344,
        10.24651838444,
        9.88165115844,
        9.87439483444,
        9.86255761944,
        9.83683363844,
        9.86549050944,
        9.85278785344
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 5.4072509692400015,
      "stddev": 0.13893532749821835,
      "median": 5.36670294344,
      "user": 2.4717998999999997,
      "system": 2.97998188,
      "min": 5.31988622644,
      "max": 5.78871115044,
      "times": [
        5.38671463244,
        5.3360645164400005,
        5.31988622644,
        5.32238976944,
        5.78871115044,
        5.35348303144,
        5.3499752884400005,
        5.43712574044,
        5.37992285544,
        5.398236481440001
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 5.419942248540001,
      "stddev": 0.17111792625386782,
      "median": 5.35386271544,
      "user": 2.4873548999999993,
      "system": 2.99608698,
      "min": 5.32368925344,
      "max": 5.88557039544,
      "times": [
        5.36362260144,
        5.45181836944,
        5.3287190224400005,
        5.46546859344,
        5.88557039544,
        5.33708260644,
        5.33572621244,
        5.36346757644,
        5.34425785444,
        5.32368925344
      ]
    }
  ]
}

Scenario: Isolated linker: fresh restore, hot cache + hot store

Command Mean [ms] Min [ms] Max [ms] Relative
pacquet@HEAD 658.2 ± 12.3 636.2 681.9 1.00
pacquet@main 663.1 ± 10.4 642.6 681.4 1.01 ± 0.02
pnpr@HEAD 801.7 ± 65.8 747.5 946.4 1.22 ± 0.10
pnpr@main 771.8 ± 37.8 740.3 860.3 1.17 ± 0.06
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 0.6582168511600001,
      "stddev": 0.0123438763353049,
      "median": 0.6551027892600001,
      "user": 0.39899574,
      "system": 1.3234386799999998,
      "min": 0.63621652526,
      "max": 0.68194219426,
      "times": [
        0.65237403926,
        0.6532887202600001,
        0.6708332972600001,
        0.68194219426,
        0.65534464026,
        0.6516043652600001,
        0.66228990326,
        0.63621652526,
        0.65486093826,
        0.66341388826
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 0.66307116986,
      "stddev": 0.010429697641303583,
      "median": 0.6624982502600001,
      "user": 0.39964063999999994,
      "system": 1.3214157800000002,
      "min": 0.6425683572600001,
      "max": 0.68135404026,
      "times": [
        0.6666704882600001,
        0.65452075426,
        0.6600526022600001,
        0.66763101026,
        0.6628226772600001,
        0.65995556326,
        0.6621738232600001,
        0.68135404026,
        0.67296238226,
        0.6425683572600001
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 0.80169335186,
      "stddev": 0.06576995324230636,
      "median": 0.7831345252600002,
      "user": 0.4112595399999999,
      "system": 1.3360134799999996,
      "min": 0.7474769962600001,
      "max": 0.9463955552600001,
      "times": [
        0.7474769962600001,
        0.75237372026,
        0.7733533882600001,
        0.8872469432600001,
        0.80988947326,
        0.7929156622600001,
        0.75293506426,
        0.9463955552600001,
        0.79684552326,
        0.75750119226
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 0.7717830724600001,
      "stddev": 0.03778895464687638,
      "median": 0.75305596226,
      "user": 0.40551013999999996,
      "system": 1.3281680799999998,
      "min": 0.7403401932600001,
      "max": 0.86034679826,
      "times": [
        0.7560326942600001,
        0.7770332162600001,
        0.8036590132600001,
        0.74830938026,
        0.79015459426,
        0.86034679826,
        0.75007923026,
        0.7419002382600001,
        0.74997536626,
        0.7403401932600001
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 9.262 ± 0.040 9.211 9.345 1.81 ± 0.02
pacquet@main 9.254 ± 0.056 9.176 9.361 1.81 ± 0.02
pnpr@HEAD 5.175 ± 0.101 5.068 5.412 1.01 ± 0.02
pnpr@main 5.108 ± 0.038 5.059 5.184 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 9.262485679940001,
      "stddev": 0.039720206988149015,
      "median": 9.26635241564,
      "user": 3.5621686399999994,
      "system": 3.31340558,
      "min": 9.211357598640001,
      "max": 9.345278392640001,
      "times": [
        9.27082761464,
        9.27407049064,
        9.23518455464,
        9.345278392640001,
        9.288497173640001,
        9.214759475640001,
        9.26187721664,
        9.211357598640001,
        9.241195748640001,
        9.281808533640001
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 9.254298441940001,
      "stddev": 0.05623893582922244,
      "median": 9.238333495640001,
      "user": 3.56563444,
      "system": 3.32569168,
      "min": 9.175630529640001,
      "max": 9.36095030164,
      "times": [
        9.246219591640001,
        9.22552474864,
        9.236519818640001,
        9.34157654464,
        9.26565860464,
        9.24014717264,
        9.219323389640001,
        9.175630529640001,
        9.36095030164,
        9.23143371764
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 5.174829378339999,
      "stddev": 0.10089554108071215,
      "median": 5.1497013016399995,
      "user": 2.2889357400000003,
      "system": 2.83936598,
      "min": 5.0678077546399996,
      "max": 5.41169316164,
      "times": [
        5.19545905664,
        5.16682026964,
        5.41169316164,
        5.11585047264,
        5.2474154536399995,
        5.132582333639999,
        5.08435344464,
        5.0678077546399996,
        5.2110144926399995,
        5.11529734364
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 5.1083628996399995,
      "stddev": 0.038222407950493864,
      "median": 5.10206979514,
      "user": 2.3250702399999996,
      "system": 2.86269248,
      "min": 5.058807519639999,
      "max": 5.1837656996399994,
      "times": [
        5.16287737764,
        5.10110123364,
        5.058807519639999,
        5.112332879639999,
        5.11022097564,
        5.092725048639999,
        5.10303835664,
        5.0816783676399995,
        5.1837656996399994,
        5.07708153764
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, hot cache + hot store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 1.400 ± 0.024 1.375 1.459 2.07 ± 0.07
pacquet@main 1.430 ± 0.017 1.410 1.474 2.12 ± 0.07
pnpr@HEAD 0.684 ± 0.025 0.662 0.750 1.01 ± 0.05
pnpr@main 0.675 ± 0.019 0.651 0.724 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 1.3995526249800003,
      "stddev": 0.023847186287828403,
      "median": 1.3992949869800002,
      "user": 1.5996816600000001,
      "system": 1.7471438999999997,
      "min": 1.37454612948,
      "max": 1.4592937814800002,
      "times": [
        1.40165676548,
        1.37552272148,
        1.40837126048,
        1.4592937814800002,
        1.4009351194800002,
        1.37454612948,
        1.3864405964800002,
        1.3982397124800001,
        1.40035026148,
        1.3901699014800002
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 1.4299248472800001,
      "stddev": 0.017227779342374495,
      "median": 1.4274783109800002,
      "user": 1.5952622599999997,
      "system": 1.8110581999999997,
      "min": 1.4098401664800002,
      "max": 1.4740638894800002,
      "times": [
        1.4369991104800002,
        1.42762955048,
        1.4288570904800002,
        1.4252560604800002,
        1.4273270714800002,
        1.4098401664800002,
        1.4285113124800002,
        1.42540169948,
        1.4740638894800002,
        1.41536252148
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 0.6843193590800001,
      "stddev": 0.02529109425345209,
      "median": 0.6768065804800001,
      "user": 0.35486996,
      "system": 1.2810299,
      "min": 0.66248631148,
      "max": 0.74998840148,
      "times": [
        0.74998840148,
        0.6783826684800001,
        0.70178708448,
        0.67454036748,
        0.6813251234800001,
        0.67403772848,
        0.67523049248,
        0.67839583948,
        0.6670195734800001,
        0.66248631148
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 0.6752268878800001,
      "stddev": 0.019416507960863146,
      "median": 0.6708404879800001,
      "user": 0.34659466,
      "system": 1.2777208999999998,
      "min": 0.65143943348,
      "max": 0.7237249854800001,
      "times": [
        0.66227762848,
        0.66527393548,
        0.6693173704800001,
        0.7237249854800001,
        0.6723636054800001,
        0.68247284448,
        0.65143943348,
        0.66767390648,
        0.6750386324800001,
        0.68268653648
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, cold cache + hot store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 5.023 ± 0.016 5.002 5.052 7.47 ± 0.20
pacquet@main 5.003 ± 0.025 4.960 5.042 7.44 ± 0.20
pnpr@HEAD 0.683 ± 0.037 0.658 0.784 1.02 ± 0.06
pnpr@main 0.672 ± 0.018 0.656 0.713 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 5.02334878786,
      "stddev": 0.01565333000312761,
      "median": 5.01912082506,
      "user": 1.8077726199999997,
      "system": 1.9216217199999999,
      "min": 5.00221060656,
      "max": 5.05226199756,
      "times": [
        5.02767112756,
        5.00221060656,
        5.04165656756,
        5.01225763056,
        5.01000956456,
        5.05226199756,
        5.01757338756,
        5.02066826256,
        5.01400589756,
        5.03517283656
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 5.00290764996,
      "stddev": 0.02477857679288716,
      "median": 5.00773784056,
      "user": 1.7722343200000001,
      "system": 1.9240475199999998,
      "min": 4.96008013356,
      "max": 5.04183261056,
      "times": [
        4.96008013356,
        5.00749488856,
        4.98986283256,
        4.97156993056,
        4.99187376256,
        5.04183261056,
        5.01475163156,
        5.02133881156,
        5.02229110556,
        5.00798079256
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 0.6829979362600002,
      "stddev": 0.036769141972170474,
      "median": 0.6716380720600001,
      "user": 0.36491332,
      "system": 1.26038912,
      "min": 0.65767951556,
      "max": 0.78436643756,
      "times": [
        0.78436643756,
        0.66904131456,
        0.65767951556,
        0.6738278105600001,
        0.6745800845600001,
        0.6803897425600001,
        0.69069094356,
        0.6694483335600001,
        0.66389327356,
        0.6660619065600001
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 0.67209412776,
      "stddev": 0.017916819518746196,
      "median": 0.66355375806,
      "user": 0.35268982,
      "system": 1.27713492,
      "min": 0.65572164956,
      "max": 0.7132971865600001,
      "times": [
        0.67156296256,
        0.66332898756,
        0.6908373025600001,
        0.65572164956,
        0.66016961056,
        0.66092915856,
        0.67945624656,
        0.7132971865600001,
        0.6637785285600001,
        0.66185964456
      ]
    }
  ]
}

@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

Branchpr/12251
Testbedpacquet

🚨 2 Alerts

BenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Upper Boundary
(Limit %)
isolated-linker.fresh-install.cold-cache.cold-storeLatency
seconds (s)
📈 plot
🚷 threshold
🚨 alert (🔔)
9.26 s
(+172.87%)Baseline: 3.39 s
4.07 s
(227.39%)

isolated-linker.fresh-restore.cold-cache.cold-storeLatency
seconds (s)
📈 plot
🚷 threshold
🚨 alert (🔔)
10.11 s
(+56.97%)Baseline: 6.44 s
7.73 s
(130.81%)

Click to view all benchmark results
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
isolated-linker.fresh-install.cold-cache.cold-store📈 view plot
🚷 view threshold
🚨 view alert (🔔)
9,262.49 ms
(+172.87%)Baseline: 3,394.44 ms
4,073.33 ms
(227.39%)

isolated-linker.fresh-install.cold-cache.hot-store📈 view plot
🚷 view threshold
5,023.35 ms
isolated-linker.fresh-install.hot-cache.hot-store📈 view plot
🚷 view threshold
1,399.55 ms
(+4.62%)Baseline: 1,337.69 ms
1,605.22 ms
(87.19%)
isolated-linker.fresh-restore.cold-cache.cold-store📈 view plot
🚷 view threshold
🚨 view alert (🔔)
10,107.42 ms
(+56.97%)Baseline: 6,439.02 ms
7,726.82 ms
(130.81%)

isolated-linker.fresh-restore.hot-cache.hot-store📈 view plot
🚷 view threshold
658.22 ms
(-3.95%)Baseline: 685.30 ms
822.36 ms
(80.04%)
🐰 View full continuous benchmarking report in Bencher

@zkochan zkochan force-pushed the codex/pacquet-parallel-cold-linking branch from dedb73e to 26b989d Compare June 7, 2026 00:42
@zkochan zkochan marked this pull request as ready for review June 7, 2026 00:56
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 7, 2026

Copy link
Copy Markdown

Review Summary by Qodo

(Agentic_describe updated until commit 9f78bab)

Share virtual-store slot linking pass and add benchmark diagnostics

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Share warm/cold virtual-store slot linking through unified parallel helper
• Add benchmark-only registry URL rewriting for pnpr server resolution
• Emit structured install phase metrics with JSON tracing support
• Extend integrated benchmark with diagnostics, pnpr-vs-direct ratios, cold-batch canary
• Split pnpr server registry latency from client registry latency measurement
Diagram
flowchart LR
  A["Install via pnpr"] -->|registry override| B["PnprBenchmarkRegistryOverride"]
  B -->|resolve registry| C["Server resolution"]
  B -->|tarball rewrite| D["Client tarball URLs"]
  E["CreateVirtualStore"] -->|warm/cold slots| F["link_slots_parallel"]
  F -->|concurrent linking| G["CreateVirtualDirBySnapshot"]
  H["Phase events"] -->|JSON tracing| I["Benchmark diagnostics"]
  I -->|pnpr/direct ratios| J["Markdown report"]

Loading

Grey Divider

File Changes

1. pacquet/crates/cli/src/cli_args/install.rs ✨ Enhancement +126/-4

Add benchmark registry override and tarball URL rewriting

pacquet/crates/cli/src/cli_args/install.rs


2. pacquet/crates/cli/src/cli_args/install/tests.rs 🧪 Tests +87/-1

Test registry rewrite and benchmark override logic

pacquet/crates/cli/src/cli_args/install/tests.rs


3. pacquet/crates/diagnostics/src/local_tracing.rs ✨ Enhancement +11/-5

Support JSON format for tracing output

pacquet/crates/diagnostics/src/local_tracing.rs


View more (15)
4. pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot.rs 🧪 Tests +9/-1

Add link concurrency probe for testing

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


5. pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot/tests.rs 🧪 Tests +76/-1

Implement link concurrency measurement infrastructure

pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot/tests.rs


6. pacquet/crates/package-manager/src/create_virtual_store.rs ✨ Enhancement +155/-87

Refactor warm/cold linking into shared parallel helper

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


7. pacquet/crates/package-manager/src/create_virtual_store/tests.rs 🧪 Tests +117/-4

Add cold-batch parallel linking concurrency test

pacquet/crates/package-manager/src/create_virtual_store/tests.rs


8. pacquet/crates/package-manager/src/install_frozen_lockfile.rs ✨ Enhancement +9/-0

Emit create_virtual_store phase metrics

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


9. pacquet/crates/package-manager/src/install_package_by_snapshot.rs ✨ Enhancement +7/-0

Thread link concurrency probe through snapshot installation

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


10. pacquet/crates/package-manager/src/install_package_by_snapshot/tests.rs 🧪 Tests +3/-0

Update tests with link concurrency probe parameter

pacquet/crates/package-manager/src/install_package_by_snapshot/tests.rs


11. pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs ✨ Enhancement +2/-0

Add link concurrency probe to fresh lockfile install

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


12. pacquet/tasks/integrated-benchmark/src/cli_args.rs ✨ Enhancement +39/-19

Add pnpr server registry latency parameter

pacquet/tasks/integrated-benchmark/src/cli_args.rs


13. pacquet/tasks/integrated-benchmark/src/main.rs ✨ Enhancement +3/-1

Thread pnpr server registry latency through benchmark

pacquet/tasks/integrated-benchmark/src/main.rs


14. pacquet/tasks/integrated-benchmark/src/work_env.rs ✨ Enhancement +481/-31

Implement benchmark diagnostics collection and verification

pacquet/tasks/integrated-benchmark/src/work_env.rs


15. pacquet/tasks/integrated-benchmark/src/work_env/tests.rs 🧪 Tests +206/-0

Test phase event parsing and diagnostics rendering

pacquet/tasks/integrated-benchmark/src/work_env/tests.rs


16. pacquet/crates/diagnostics/Cargo.toml Dependencies +1/-1

Enable JSON feature for tracing-subscriber

pacquet/crates/diagnostics/Cargo.toml


17. pacquet/tasks/integrated-benchmark/Cargo.toml Dependencies +1/-0

Add serde_json dependency for diagnostics

pacquet/tasks/integrated-benchmark/Cargo.toml


18. .github/workflows/pacquet-integrated-benchmark.yml 📝 Documentation +3/-5

Update benchmark report documentation

.github/workflows/pacquet-integrated-benchmark.yml


Grey Divider

Qodo Logo

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

Actionable comments posted: 2

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

Inline comments:
In `@pacquet/crates/package-manager/src/create_virtual_store/tests.rs`:
- Around line 137-142: The assertion currently requires probe.max_concurrent()
>= 2 unconditionally which fails when Rayon is configured with a single thread;
update the test to gate the expectation by rayon::current_num_threads(): if
rayon::current_num_threads() >= 2 assert probe.max_concurrent() >= 2 (preserving
the existing error message), otherwise assert probe.max_concurrent() >= 1 (or
skip the stronger expectation) so the test is resilient in single-thread Rayon
environments; locate the assertion using probe.max_concurrent() and
rayon::current_num_threads() and change the single hard-coded check into the
conditional described.

In `@pacquet/tasks/integrated-benchmark/src/work_env.rs`:
- Around line 570-575: The PNPR tarball env currently uses self.registry
(upstream) instead of the emulated client path, so thread the computed
client_registry through benchmark -> start_pnpr_servers -> start_pnpr_server and
change the export in the format string to use the passed-in client_registry
value (export PNPR_TARBALL_REGISTRY_ENV={client_registry}) rather than
self.registry; update function signatures for start_pnpr_servers and
start_pnpr_server to accept client_registry and ensure the value is propagated
from where client_registry is computed to the place that formats the environment
string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 10ad5ae6-362e-4cdc-a144-fd413bc9a8a6

📥 Commits

Reviewing files that changed from the base of the PR and between 75bf4bf and 26b989d.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • pacquet/crates/cli/src/cli_args/install.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/diagnostics/Cargo.toml
  • pacquet/crates/diagnostics/src/local_tracing.rs
  • pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot.rs
  • pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot/tests.rs
  • pacquet/crates/package-manager/src/create_virtual_store.rs
  • pacquet/crates/package-manager/src/create_virtual_store/tests.rs
  • pacquet/crates/package-manager/src/install_frozen_lockfile.rs
  • pacquet/crates/package-manager/src/install_package_by_snapshot.rs
  • pacquet/crates/package-manager/src/install_package_by_snapshot/tests.rs
  • pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs
  • pacquet/tasks/integrated-benchmark/Cargo.toml
  • pacquet/tasks/integrated-benchmark/src/cli_args.rs
  • pacquet/tasks/integrated-benchmark/src/main.rs
  • pacquet/tasks/integrated-benchmark/src/work_env.rs
  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs

Comment thread pacquet/crates/package-manager/src/create_virtual_store/tests.rs
Comment thread pacquet/tasks/integrated-benchmark/src/work_env.rs
@zkochan zkochan force-pushed the codex/pacquet-parallel-cold-linking branch from 26b989d to 11c8d30 Compare June 7, 2026 01:14
@zkochan zkochan marked this pull request as draft June 7, 2026 01:14
@zkochan

zkochan commented Jun 7, 2026

Copy link
Copy Markdown
Member Author

Follow-up for the integrated-benchmark failure in Run benchmark on ubuntu-latest: fixed in 11c8d30b05.

The cold-batch metrics canary now only requires create_virtual_store_partition from pnpr@HEAD. Comparison targets such as pnpr@main do not contain this PR's new tracing instrumentation yet, so requiring that metric from them made the benchmark fail even though the current revision emitted the expected data.


Written by an agent (Codex, GPT-5).

@zkochan zkochan marked this pull request as ready for review June 7, 2026 01:16

@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 (1)
pacquet/tasks/integrated-benchmark/src/work_env/tests.rs (1)

10-25: ⚡ Quick win

Use a test-managed temp fixture instead of PID-named files.

The manual temp_dir + pid path and cleanup is more brittle than a scoped temp fixture. Prefer tempfile-managed lifecycle to avoid cross-test interference and leaked artifacts.

Based on learnings: “Prefer real fixtures over dependency-injection seams — use tempfile::TempDir … for happy paths and most error paths.”

Suggested patch
 use super::{
     HyperfineCommand, PhaseEvent, collect_pnpr_direct_ratios, non_trivial_cold_batch,
     read_phase_events, render_diagnostics_markdown, requires_fresh_pnpr_cold_batch_metrics,
     summarize_phase_events,
 };
 use std::{collections::HashMap, fs};
+use tempfile::NamedTempFile;

 #[test]
 fn phase_event_parser_reads_flat_and_nested_json_trace_fields() {
-    let path = std::env::temp_dir()
-        .join(format!("pacquet-integrated-benchmark-phase-events-{}.ndjson", std::process::id()));
+    let file = NamedTempFile::new().expect("create phase fixture");
+    let path = file.path().to_path_buf();
     fs::write(
         &path,
         r#"{"target":"pacquet::install::phase","phase":"create_virtual_store_partition","warm":3,"cold":7,"skipped":1,"total":11}"#
@@
     )
     .expect("write phase fixture");

     let events = read_phase_events(&path);
-    let _ = fs::remove_file(path);

     assert_eq!(events.len(), 2);
🤖 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 `@pacquet/tasks/integrated-benchmark/src/work_env/tests.rs` around lines 10 -
25, Replace the manual temp file creation (std::env::temp_dir() + process::id(),
fs::write, fs::remove_file) with a tempfile-managed fixture: create a
tempfile::NamedTempFile, write the NDJSON contents into it (e.g., write_all on
NamedTempFile), pass named_tempfile.path() to read_phase_events, and drop the
NamedTempFile (no manual remove). Update imports and ensure the test uses the
NamedTempFile variable so the file lives for the duration of the test; reference
the symbols read_phase_events and the Temp file variable (e.g., named_tempfile)
when applying the change.

Source: Learnings

🤖 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 `@pacquet/tasks/integrated-benchmark/src/work_env/tests.rs`:
- Around line 10-25: Replace the manual temp file creation (std::env::temp_dir()
+ process::id(), fs::write, fs::remove_file) with a tempfile-managed fixture:
create a tempfile::NamedTempFile, write the NDJSON contents into it (e.g.,
write_all on NamedTempFile), pass named_tempfile.path() to read_phase_events,
and drop the NamedTempFile (no manual remove). Update imports and ensure the
test uses the NamedTempFile variable so the file lives for the duration of the
test; reference the symbols read_phase_events and the Temp file variable (e.g.,
named_tempfile) when applying the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d8e0d1d7-7cab-4496-a164-f59dd0c8846e

📥 Commits

Reviewing files that changed from the base of the PR and between 26b989d and 11c8d30.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • pacquet/crates/cli/src/cli_args/install.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/diagnostics/Cargo.toml
  • pacquet/crates/diagnostics/src/local_tracing.rs
  • pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot.rs
  • pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot/tests.rs
  • pacquet/crates/package-manager/src/create_virtual_store.rs
  • pacquet/crates/package-manager/src/create_virtual_store/tests.rs
  • pacquet/crates/package-manager/src/install_frozen_lockfile.rs
  • pacquet/crates/package-manager/src/install_package_by_snapshot.rs
  • pacquet/crates/package-manager/src/install_package_by_snapshot/tests.rs
  • pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs
  • pacquet/tasks/integrated-benchmark/Cargo.toml
  • pacquet/tasks/integrated-benchmark/src/cli_args.rs
  • pacquet/tasks/integrated-benchmark/src/main.rs
  • pacquet/tasks/integrated-benchmark/src/work_env.rs
  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
✅ Files skipped from review due to trivial changes (2)
  • pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs
  • pacquet/crates/diagnostics/Cargo.toml
🚧 Files skipped from review as they are similar to previous changes (12)
  • pacquet/crates/package-manager/src/install_package_by_snapshot/tests.rs
  • pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot.rs
  • pacquet/tasks/integrated-benchmark/src/main.rs
  • pacquet/crates/package-manager/src/install_frozen_lockfile.rs
  • pacquet/crates/diagnostics/src/local_tracing.rs
  • pacquet/tasks/integrated-benchmark/Cargo.toml
  • pacquet/crates/package-manager/src/create_virtual_store/tests.rs
  • pacquet/tasks/integrated-benchmark/src/cli_args.rs
  • pacquet/crates/package-manager/src/install_package_by_snapshot.rs
  • pacquet/crates/package-manager/src/create_virtual_dir_by_snapshot/tests.rs
  • pacquet/crates/package-manager/src/create_virtual_store.rs
  • pacquet/tasks/integrated-benchmark/src/work_env.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). (7)
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Lint and Test (macos-latest)
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Code Coverage
  • GitHub Check: Compile & Lint
🧰 Additional context used
📓 Path-based instructions (1)
pacquet/**/*.rs

📄 CodeRabbit inference engine (pacquet/AGENTS.md)

pacquet/**/*.rs: Log emissions are part of matching pnpm — when porting a function that fires pnpm:<channel> events through globalLogger, logger.debug(...), or streamParser.write(...), mirror the call site, payload, and ordering so @pnpm/cli.default-reporter parses pacquet's NDJSON the same way
Declare a newtype wrapper for branded string types instead of collapsing the brand into a plain String or &str in Rust
If upstream TypeScript always validates before construction of a branded string, validate in the Rust wrapper too via TryFrom<String> and/or FromStr and do not provide an infallible public constructor
If upstream TypeScript never validates a branded string, just brand for type-safety in Rust by exposing an infallible From<String> constructor
If upstream TypeScript occasionally constructs a branded string without validation, expose from_str_unchecked in Rust as an escape hatch alongside the validating constructor
Match upstream serde behavior for branded strings crossing JSON, YAML, or INI boundaries by using #[serde(try_from = "String")] for deserialization and #[serde(into = "String")] for serialization
Derive simple conversions for branded strings using #[derive(derive_more::From)] and #[derive(derive_more::Into)] instead of handwriting impl blocks; use manual impl only when conversion needs custom logic
Model TypeScript string literal unions (like 'auto' | 'always' | 'never') as Rust enums instead of newtype wrappers, since the set of valid values is closed
Treat TypeScript string template literal types (like `${string}@${string}`) the same as branded string types in Rust, using a newtype wrapper with validation
Follow the code style guide in CODE_STYLE_GUIDE.md — imports, modules, naming, ownership and borrowing, parameter type selection, trait bounds, pattern matching, pipe-trait, error handling, test layout, and cloning of Arc and Rc
Choose owned vs. borrowed parameters to minimize copies; widen to t...

Files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
🧠 Learnings (33)
📓 Common learnings
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-06-06T22:48:27.363Z
Learning: Keep pnpm and pacquet in sync — any user-visible change (CLI flags, defaults, environment-variable handling, lockfile/manifest/state-file format, error codes and messages, log emissions, store layout, hook semantics) must land in both the TypeScript pnpm CLI and the Rust pacquet port in the same PR
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11915
File: pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs:553-617
Timestamp: 2026-05-24T21:11:04.272Z
Learning: In the pacquet Rust port (pnpm/pnpm repo), the `ResolvedPackage.optional` AND-folding on revisit intentionally mirrors pnpm's `resolveDependencies.ts:1627-1648` behavior: only the directly-revisited package's `optional` flag is updated; transitive descendants are not re-walked. pnpm CLI corrects stale optional flags downstream via `copyDependencySubGraph` BFS in `lockfile/pruner/src/index.ts:160-205`, which tracks a `nonOptional` set and re-stamps any package reachable by an all-non-optional path. Pacquet does not yet have this pruner equivalent, so the stale flags flow directly through `dependencies_graph_to_lockfile.rs:409` → `create_virtual_store.rs:762` → `installability.rs:394`. A follow-up to port `copyDependencySubGraph` is planned; until then, do not flag the resolver-layer optional propagation gap as a bug in pacquet PRs — it is intentional parity with pnpm's resolver layer.
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11915
File: pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs:553-617
Timestamp: 2026-05-24T21:11:04.272Z
Learning: In pacquet (pnpm/pnpm repo), `ResolvedPackage.optional` AND-folding intentionally mirrors pnpm's resolveDependencies.ts:1627-1648 revisit behavior: only the directly-visited package's `optional` flag is updated on revisit, not transitive descendants. pnpm CLI corrects stale optional flags via `copyDependencySubGraph` BFS in `lockfile/pruner/src/index.ts:160-205`. Pacquet does not yet have this pruner equivalent, so raw `node.optional` flows directly into snapshot/virtual-store via `dependencies_graph_to_lockfile.rs:409` → `create_virtual_store.rs:762` → `installability.rs:394`. A follow-up issue to port `copyDependencySubGraph` is planned.
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11784
File: pacquet/crates/resolving-deps-resolver/src/hoist_peers.rs:120-133
Timestamp: 2026-05-20T23:08:06.093Z
Learning: Pacquet (pnpm's Rust port) has a cardinal rule: "match pnpm exactly — do not fix pnpm quirks unless the same fix has landed in pnpm first." Review comments should not suggest behavioral deviations from upstream pnpm, even when the upstream behavior appears buggy. If a real bug is identified, it must be fixed upstream first.
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12181
File: worker/src/start.ts:504-520
Timestamp: 2026-06-04T06:04:05.107Z
Learning: In pnpm/pnpm's pnpr install accelerator, the `/v1/install` response has a two-level framing structure:
1. **Outer layer** (full HTTP body): `[u32 outer header length][outer header JSON][files payload]` — `fetchFromPnpmRegistry` (pnpr/client/src/fetchFromPnpmRegistry.ts) strips the outer layer with `body.subarray(4 + headerLength)` and passes the remaining bytes to `writeCafsFiles`.
2. **Inner layer** (files payload): the files payload itself starts with its own `[u32 inner json length][inner header JSON]` prefix (built by the server's `build_files_payload` / `empty_files_payload_prefix`), followed by `[64-byte digest][u32 size][1-byte exec][content]` frames and a 64-zero-byte end marker.

`writeCafsFiles` in `worker/src/start.ts` is correct to read `jsonLen = payload.readUInt32BE(0)` and start frames at `offset = 4 + jsonLen` — this skips the inner header. The same two-level structure is mirrored in the Rust reference client (`parse_inline_response` + `write_files_payload`). Do not fla...
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Match how the same feature is implemented in the TypeScript pnpm CLI — any change in pacquet must match pnpm's behavior, logic, edge cases, config resolution, error messages, file/lockfile formats, and existing tests
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12189
File: pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs:435-439
Timestamp: 2026-06-04T14:40:29.444Z
Learning: In `pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs` (pnpm/pnpm repo), the pnpr install accelerator always invokes `Install` with `lockfile_only: true` (hard-coded in `pnpr/crates/pnpr/src/install_accelerator/resolve.rs`). Under `lockfile_only: true`:
1. The `PrefetchingResolver` wrapper is skipped — the bare `inner_resolver` is used instead, so `PrefetchContext { config }` is never constructed.
2. The function returns before `CreateVirtualStore` is reached, so `install_package_by_snapshot` and its `config.auth_headers` fetch path are never hit.
pnpr's tarball fetch is handled separately in `resolve::fetch_uncached`, which independently receives the request-scoped `auth_headers`. Therefore, `auth_override` only needs to be threaded into the resolver-side components (NpmResolver, TarballResolver, NamedRegistryResolver) — not into PrefetchingResolver or CreateVirtualStore — on the pnpr path. For local installs (`lockfile_only: false`), `auth_override` is always `None` a...
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11867
File: pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs:726-730
Timestamp: 2026-05-23T09:14:43.635Z
Learning: In `pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs`, the fresh-lockfile path intentionally does not invoke `BuildModules` and discards `side_effects_maps_by_snapshot` from `CreateVirtualStoreOutput`. This is pre-existing, documented behavior (mirroring upstream `link.ts:167-170`): `importing_done` fires once extraction and symlink linking are complete, and the fresh-lockfile path does not run lifecycle scripts. The frozen-lockfile path wires `BuildModules` end-to-end as normal. Do not flag this omission as a bug; wiring lifecycle scripts into the fresh-lockfile path is tracked as future work separate from perf refactors.
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Reference the upstream pnpm commit/PR when porting code from pnpm in commit messages
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11867
File: pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs:726-730
Timestamp: 2026-05-23T09:14:43.635Z
Learning: In `pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs`, the fresh-lockfile path intentionally does not run lifecycle scripts (`BuildModules` is not invoked, and `side_effects_maps_by_snapshot` from `CreateVirtualStoreOutput` is discarded). This is pre-existing behavior documented by an in-code comment mirroring upstream `link.ts:167-170`. The frozen-lockfile path wires `BuildModules` end-to-end as normal. Wiring lifecycle scripts into the fresh-lockfile path is tracked as future work, separate from this file's concern.
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Tests that need the mocked registry should start `pnpr` through `pacquet-testing-utils`; `cargo test` / `cargo nextest run` should not require a separate `just registry-mock launch` step
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12154
File: pacquet/tasks/integrated-benchmark/src/work_env.rs:401-423
Timestamp: 2026-06-03T09:27:50.473Z
Learning: In `pnpm/pnpm` (pacquet Rust port), `pick_unused_port()` from `pacquet-registry-mock` is the established repo-wide pattern for choosing a port when spawning child processes (pnpr server, registry mock) in tests and benchmarks. The alternative of `--listen 127.0.0.1:0` (ephemeral port) is not currently viable because pnpr's `serve()` logs the *requested* `config.listen` address rather than `listener.local_addr()`, so the actual bound port cannot be discovered without a pnpr-side change. Do not flag `pick_unused_port()` usage in benchmark orchestration code as a TOCTOU bug without acknowledging this constraint.
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Port relevant pnpm tests to Rust tests whenever they translate when porting behavior from pnpm

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/*.rs : Tests are documentation — do not duplicate test scenarios, edge cases, failure modes, or worked examples in prose when they are already captured by tests

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Use snapshot tests with `insta` and carefully review diffs when intentional changes alter snapshots; accept with `cargo insta review` only after careful review

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Prefer real fixtures over dependency-injection seams — use `tempfile::TempDir`, the mocked registry, or integration tests spawning the actual binary for happy paths and most error paths; use the DI seam only for filesystem error kinds, deterministic time, shared process-global state, or external-service happy paths

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Follow test-logging guidance — log before non-`assert_eq!` assertions, `dbg!` complex structures, skip logging for simple scalar `assert_eq!`

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Tests that need the mocked registry should start `pnpr` through `pacquet-testing-utils`; `cargo test` / `cargo nextest run` should not require a separate `just registry-mock launch` step

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Consult `plans/TEST_PORTING.md` before adding ported tests and update its checkboxes as items land; use `known_failures` modules and `pacquet_testing_utils::allow_known_failure!` at the not-yet-implemented boundary

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Prefer `#[cfg_attr(target_os = "windows", ignore = "...")]` (or matching `#[cfg(unix)]` gates) over runtime probe-and-skip helpers for platform-locked tools

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-29T18:03:15.372Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pacquet/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:15.372Z
Learning: Applies to pacquet/**/tests/**/*.rs : Tests must not be tolerant of missing build/runtime environment by silently returning early when a tool isn't found — let the test panic when a required tool is absent

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
📚 Learning: 2026-05-29T18:03:24.797Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pnpr/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:24.797Z
Learning: Applies to pnpr/**/pnpr/**/*.rs : Follow the pacquet contributing guide (../pacquet/CONTRIBUTING.md) for test layout and Rust conventions

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-06-01T08:59:48.719Z
Learnt from: KSXGitHub
Repo: pnpm/pnpm PR: 12093
File: pacquet/crates/cli/src/cli_args/run/recursive.rs:290-315
Timestamp: 2026-06-01T08:59:48.719Z
Learning: In pacquet's recursive run implementation (`pacquet/crates/cli/src/cli_args/run/recursive.rs`), the `pnpm-exec-summary.json` format for failed package entries correctly includes `prefix` and `message` fields in addition to `status` and `duration`. This matches pnpm's `ActionFailure` variant in `cli/utils/src/recursiveSummary.ts` and the direct serialization in `exec/commands/src/exec.ts`. There is no `ExecutionStatusInSummary` type in pnpm. The only intentional divergence is omitting the JS `error` field, whose `JSON.stringify` output is non-deterministic due to non-enumerable `Error` properties.

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
📚 Learning: 2026-05-23T16:55:36.507Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11878
File: pacquet/crates/cli/tests/lockfile_verification.rs:158-162
Timestamp: 2026-05-23T16:55:36.507Z
Learning: In `pacquet/crates/cli/tests/lockfile_verification.rs`, the `trust_lockfile_skips_verification` and `trust_lockfile_cli_flag_skips_verification` tests intentionally do NOT assert `output.status.success()`. The hand-rolled fixture lockfile uses a placeholder integrity hash (`sha512-AAA…`), so the install always fails the downstream tarball integrity check regardless of the supply-chain gate. The contract being tested is "gate-skipped, not install-succeeded"; asserting success would require generating a real lockfile via the `generate_lockfile` pattern (see `hoist.rs`) which is considered not worth the extra wiring for an opt-out smoke test.

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-20T23:07:58.444Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11784
File: pacquet/crates/resolving-deps-resolver/src/hoist_peers.rs:120-133
Timestamp: 2026-05-20T23:07:58.444Z
Learning: When reviewing code in this pacquet Rust port, follow the upstream pnpm compatibility rule: only match pnpm’s behavior exactly. Do not propose review changes that intentionally deviate from pnpm’s documented/observed behavior, even if pnpm appears buggy. If you identify a real bug in pnpm behavior, the review should prioritize fixing it upstream in pnpm first, and avoid implementing a pnpm-behavior workaround here unless the same fix has already landed upstream.

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-06-06T18:58:37.156Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12243
File: pacquet/crates/package-manager/src/install_package_by_snapshot.rs:319-322
Timestamp: 2026-06-06T18:58:37.156Z
Learning: When reviewing Rust code, do not assume `matches!(expr, Pattern(_))` will move out of `expr` if `Pattern(_)` contains no by-value bindings. `matches!` desugars to a `match` that auto-borrows the scrutinee for discrimination, so even if `expr` is a non-`Copy` value behind a shared reference (e.g., `&T`), the macro should not move-out of the borrowed data purely due to `matches!`. Treat `matches!(&expr, Pattern(_))` as a readability/clarity improvement, not a correctness requirement. Only flag potential move-out-of-borrow risks when the pattern includes by-value bindings that would require moving the matched value.

Applied to files:

  • pacquet/tasks/integrated-benchmark/src/work_env/tests.rs
  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-20T21:18:56.391Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11778
File: pacquet/crates/resolving-local-resolver/tests/resolve.rs:365-372
Timestamp: 2026-05-20T21:18:56.391Z
Learning: In `pacquet/crates/resolving-local-resolver/tests/resolve.rs`, the test `fail_when_resolving_from_not_existing_directory_an_injected_dependency` intentionally uses `injected: false`. The test is a verbatim port of the upstream pnpm TypeScript test (resolving/local-resolver/test/index.ts at ef87f3ccff). The `injected` flag only affects the file/link protocol choice for plain directory paths; when the `file:` scheme is explicit in the bare specifier, the flag has no effect on the resolution code path. The misleading test name is inherited from upstream.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
📚 Learning: 2026-06-04T14:40:29.444Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12189
File: pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs:435-439
Timestamp: 2026-06-04T14:40:29.444Z
Learning: In `pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs` (pnpm/pnpm repo), the pnpr install accelerator always invokes `Install` with `lockfile_only: true` (hard-coded in `pnpr/crates/pnpr/src/install_accelerator/resolve.rs`). Under `lockfile_only: true`:
1. The `PrefetchingResolver` wrapper is skipped — the bare `inner_resolver` is used instead, so `PrefetchContext { config }` is never constructed.
2. The function returns before `CreateVirtualStore` is reached, so `install_package_by_snapshot` and its `config.auth_headers` fetch path are never hit.
pnpr's tarball fetch is handled separately in `resolve::fetch_uncached`, which independently receives the request-scoped `auth_headers`. Therefore, `auth_override` only needs to be threaded into the resolver-side components (NpmResolver, TarballResolver, NamedRegistryResolver) — not into PrefetchingResolver or CreateVirtualStore — on the pnpr path. For local installs (`lockfile_only: false`), `auth_override` is always `None` a...

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-06-04T14:55:52.163Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12189
File: pacquet/crates/cli/src/cli_args/install.rs:0-0
Timestamp: 2026-06-04T14:55:52.163Z
Learning: In `pacquet/crates/cli/src/cli_args/install.rs` (pnpm/pnpm repo), the `install_via_pnpr` function intentionally forwards the **full** `state.config.auth_headers` map to the pnpr server (not filtered to only the declared default/named registries). This is required for correctness: transitive dependencies can be scope-routed to registries not in the explicit registry list, or pinned to tarball URLs on hosts present in `.npmrc` but not a declared registry. Filtering to the declared registries silently drops tokens those sub-dependencies need, causing 401s on the server. pnpr uses the forwarded map to attach the right token per fetched URL exactly as a local install does (`AuthHeaders::for_url`). The pnpr-server's own credential is sent separately in the `Authorization` header and is excluded from the body map. Do NOT flag this as a credential-leakage issue — the rationale is documented in a comment at both call sites.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-29T18:03:24.797Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pnpr/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:24.797Z
Learning: Prefer existing pacquet-* crates over writing new code; check pacquet-tarball, pacquet-crypto-hash, pacquet-crypto-shasums-file, pacquet-package-manifest, pacquet-network, pacquet-registry, pacquet-fs, and pacquet-diagnostics before implementing non-trivial functionality

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
📚 Learning: 2026-05-20T20:41:50.322Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11773
File: pacquet/crates/package-manager/src/install_package_from_registry.rs:111-114
Timestamp: 2026-05-20T20:41:50.322Z
Learning: In pacquet (pnpm/pnpm repo, Rust codebase), `install_package_from_registry` is the npm-only install path. The npm resolver always stamps `ResolveResult.id` (a `PkgResolutionId`) as `nameversion`. Parsing it back through `PkgNameVer` with `.expect()` is intentional — a parse failure means a mis-dispatch bug, not malformed external input. Per pacquet's CLAUDE.md: "Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees." Do not suggest replacing such `.expect()` calls with graceful error handling.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-24T21:11:04.272Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11915
File: pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs:553-617
Timestamp: 2026-05-24T21:11:04.272Z
Learning: In the pacquet Rust port (pnpm/pnpm repo), the `ResolvedPackage.optional` AND-folding on revisit intentionally mirrors pnpm's `resolveDependencies.ts:1627-1648` behavior: only the directly-revisited package's `optional` flag is updated; transitive descendants are not re-walked. pnpm CLI corrects stale optional flags downstream via `copyDependencySubGraph` BFS in `lockfile/pruner/src/index.ts:160-205`, which tracks a `nonOptional` set and re-stamps any package reachable by an all-non-optional path. Pacquet does not yet have this pruner equivalent, so the stale flags flow directly through `dependencies_graph_to_lockfile.rs:409` → `create_virtual_store.rs:762` → `installability.rs:394`. A follow-up to port `copyDependencySubGraph` is planned; until then, do not flag the resolver-layer optional propagation gap as a bug in pacquet PRs — it is intentional parity with pnpm's resolver layer.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-29T18:03:24.797Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pnpr/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:24.797Z
Learning: Applies to pnpr/**/pnpr/**/*.rs : Follow the pacquet code-style guide (../pacquet/CODE_STYLE_GUIDE.md) for Rust-level conventions including imports, naming, ownership, and error handling

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
📚 Learning: 2026-05-24T21:11:04.272Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11915
File: pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs:553-617
Timestamp: 2026-05-24T21:11:04.272Z
Learning: In pacquet (pnpm/pnpm repo), `ResolvedPackage.optional` AND-folding intentionally mirrors pnpm's resolveDependencies.ts:1627-1648 revisit behavior: only the directly-visited package's `optional` flag is updated on revisit, not transitive descendants. pnpm CLI corrects stale optional flags via `copyDependencySubGraph` BFS in `lockfile/pruner/src/index.ts:160-205`. Pacquet does not yet have this pruner equivalent, so raw `node.optional` flows directly into snapshot/virtual-store via `dependencies_graph_to_lockfile.rs:409` → `create_virtual_store.rs:762` → `installability.rs:394`. A follow-up issue to port `copyDependencySubGraph` is planned.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
📚 Learning: 2026-05-24T08:18:06.019Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11895
File: pnpm/test/deploy.ts:91-95
Timestamp: 2026-05-24T08:18:06.019Z
Learning: In the pnpm/pnpm repository, integration tests that hit the real `registry.npmjs.org` (e.g., for `pacquet` or `pnpm/pacquet`) do NOT use a runtime env-var gate (such as `PNPM_RUN_PUBLIC_REGISTRY_TESTS`). They simply pass `--config.registry=https://registry.npmjs.org/` directly to `execPnpm` and set a higher timeout. This is the established pattern, as seen in `pnpm/test/install/pacquet.ts` and `pnpm/test/deploy.ts`. Do not suggest adding env-var guards for these tests.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-25T14:58:11.105Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11931
File: pacquet/crates/resolving-npm-resolver/src/create_npm_resolution_verifier.rs:560-589
Timestamp: 2026-05-25T14:58:11.105Z
Learning: In `pacquet/crates/resolving-npm-resolver/src/create_npm_resolution_verifier.rs`, all per-`(registry, name[, version])` caches in `NpmResolutionVerifier` (`published_at`, `full_meta`, `full_meta_for_trust`, `abbreviated_meta`, `local_meta`) intentionally use the same pattern: lock → miss-check → release lock → await fetch/load → re-acquire lock → insert. This uniform pattern is deliberate; do not flag individual caches for using it. The known follow-up improvement (replacing the pattern with `tokio::sync::OnceCell` per key inside a `Mutex<HashMap<…>>`) is tracked as a future structural change to cover all five caches simultaneously.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-20T20:41:30.632Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11773
File: pacquet/crates/resolving-tarball-resolver/src/tarball_resolver.rs:115-117
Timestamp: 2026-05-20T20:41:30.632Z
Learning: In the pacquet Rust port of pnpm, the `is_http_url` helper in `pacquet/crates/resolving-tarball-resolver/src/tarball_resolver.rs` intentionally uses `bare.starts_with("http:") || bare.starts_with("https:")` (not `"http://"` / `"https://"`) to match upstream pnpm's `startsWith('http:')` / `startsWith('https:')` check byte-for-byte. Pacquet's cardinal rule (pacquet/AGENTS.md) requires matching pnpm even on quirks; malformed non-URL inputs are rejected downstream by `reqwest::Url::parse` as a `ResolveError`.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-20T19:40:55.051Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11774
File: pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs:0-0
Timestamp: 2026-05-20T19:40:55.051Z
Learning: In the pacquet Rust code, ensure the semver implementation uses the `node-semver` crate (not `nodejs-semver`). `node-semver`’s public API does not include a `satisfies_with_prerelease`-style method; prerelease-tolerant matching should be implemented inline by first calling `Range::satisfies`, and when it rejects a prerelease version, retry matching against a stripped `MAJOR.MINOR.PATCH` base of the prerelease version.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-22T00:08:44.646Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11837
File: pacquet/crates/resolving-npm-resolver/src/pick_package.rs:33-51
Timestamp: 2026-05-22T00:08:44.646Z
Learning: In the pnpm/pnpm repo’s pacquet Rust crates, do not flag Unicode ellipsis characters (U+2026, `…`) in Rust doc comments (`///` / `/** */`) as a lint violation. The pacquet crate’s `dylint.toml` only enables `perfectionist::derive_ordering`, and the Dylint `unicode-ellipsis` rule is not enabled for this project—so `…` in doc comments is an intentional, repo-consistent style.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install/tests.rs
  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-06-02T13:18:30.659Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12134
File: pacquet/crates/resolving-npm-resolver/src/create_npm_resolution_verifier.rs:311-325
Timestamp: 2026-06-02T13:18:30.659Z
Learning: In pacquet's lockfile resolution verifier (`pacquet/crates/resolving-npm-resolver/src/create_npm_resolution_verifier.rs`), URL-keyed tarball dependencies do NOT need a separate `non_semver_version` field in `VerifyCtx`. Unlike the TypeScript side (which derives `version` from `snapshot.version` and threads `nonSemverVersion` separately), pacquet's `collect_candidates` takes `version` from the lockfile key suffix. For a URL-keyed dep the key is `name@<url>`, so `ctx.version` is the URL string, which fails `node_semver::Version::parse(ctx.version)` and the existing guard `if node_semver::Version::parse(ctx.version).is_err() { return ResolutionVerification::Ok; }` already skips the registry lookup correctly. Adding a `non_semver_version` field to `VerifyCtx` for this purpose would be inert.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-29T18:03:24.797Z
Learnt from: CR
Repo: pnpm/pnpm PR: 0
File: pnpr/AGENTS.md:0-0
Timestamp: 2026-05-29T18:03:24.797Z
Learning: Applies to pnpr/**/pnpr/crates/**/Cargo.toml : New registry-only crates must be placed under pnpr/crates/<short-name>/ and named pnpr-<short-name> in Cargo.toml, never using the pacquet- prefix

Applied to files:

  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-23T09:14:43.635Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11867
File: pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs:726-730
Timestamp: 2026-05-23T09:14:43.635Z
Learning: In `pacquet/crates/package-manager/src/install_with_fresh_lockfile.rs`, the fresh-lockfile path intentionally does not invoke `BuildModules` and discards `side_effects_maps_by_snapshot` from `CreateVirtualStoreOutput`. This is pre-existing, documented behavior (mirroring upstream `link.ts:167-170`): `importing_done` fires once extraction and symlink linking are complete, and the fresh-lockfile path does not run lifecycle scripts. The frozen-lockfile path wires `BuildModules` end-to-end as normal. Do not flag this omission as a bug; wiring lifecycle scripts into the fresh-lockfile path is tracked as future work separate from perf refactors.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-06-02T16:13:39.456Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12144
File: pnpr/crates/pnpr/src/install_accelerator/verdict_cache.rs:57-61
Timestamp: 2026-06-02T16:13:39.456Z
Learning: In `pnpr/crates/pnpr/src/install_accelerator/verdict_cache.rs`, the `lockfile_verdicts` SQLite table intentionally uses `hash` alone (not a composite `(hash, policy)` key) as the primary key — last-write-wins per hash. This mirrors the local `lockfile-verified.jsonl` cache design in pnpm. A looser current policy can trust a stricter cached pass via `can_trust_past_check`; alternating-policy re-verification is an accepted trade-off. A composite key was explicitly rejected to maintain parity with the local cache model.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install.rs
📚 Learning: 2026-05-20T01:42:44.958Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11755
File: pacquet/crates/resolving-npm-resolver/src/pick_package.rs:370-380
Timestamp: 2026-05-20T01:42:44.958Z
Learning: In `pacquet/crates/resolving-npm-resolver/src/pick_package.rs`, the fetch-error fallback that returns `Ok(PickPackageResult { meta: disk, picked_package: picked })` — even when `picked` is `None` — is intentional upstream parity with pnpm's `pickPackage.ts` catch block (https://github.com/pnpm/pnpm/blob/f657b5cb44/resolving/npm-resolver/src/pickPackage.ts#L420-L431). When a fetch fails and a disk mirror exists, the stale-mirror pick (including null/None) is returned verbatim; the transport error is logged via `tracing::debug!`. Do not flag this as a bug.

Applied to files:

  • pacquet/crates/cli/src/cli_args/install.rs
🔇 Additional comments (3)
pacquet/tasks/integrated-benchmark/src/work_env/tests.rs (1)

1-9: LGTM!

Also applies to: 27-157

pacquet/crates/cli/src/cli_args/install.rs (1)

5-5: LGTM!

Also applies to: 11-12, 467-568, 631-736

pacquet/crates/cli/src/cli_args/install/tests.rs (1)

1-8: LGTM!

Also applies to: 213-293

@zkochan zkochan marked this pull request as draft June 7, 2026 02:00
@zkochan zkochan force-pushed the codex/pacquet-parallel-cold-linking branch 4 times, most recently from cfa9f71 to dd68b11 Compare June 7, 2026 11:55
@zkochan zkochan force-pushed the codex/pacquet-parallel-cold-linking branch from dd68b11 to 9f78bab Compare June 7, 2026 20:25
@zkochan zkochan marked this pull request as ready for review June 7, 2026 21:17
@zkochan zkochan merged commit 0dc770a into main Jun 7, 2026
27 of 28 checks passed
@zkochan zkochan deleted the codex/pacquet-parallel-cold-linking branch June 7, 2026 21:27
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