Skip to content

fix(pacquet): byte-identical lockfile — generation-once owner records + cycle-closing edges#12365

Merged
zkochan merged 2 commits into
mainfrom
lockfile-parity5
Jun 12, 2026
Merged

fix(pacquet): byte-identical lockfile — generation-once owner records + cycle-closing edges#12365
zkochan merged 2 commits into
mainfrom
lockfile-parity5

Conversation

@zkochan

@zkochan zkochan commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary

The final two resolution-level parity fixes for #12266. With both applied, pacquet install --lockfile-only on this monorepo produces a real-lockfile document that is byte-identical to fresh pnpm 11.6.0 output (back-to-back against the live registry, deterministic across runs) — down from ~3,200 changed lines when the umbrella issue was opened.

1. Owner missing-peer records are written once per ownership generation

The pacquet side of #12362 overwrote the owner-keyed first-walk record on every owner pass. Once the owning importer hoisted a peer into its own scope (e.g. typanion under @yarnpkg/core, owned by hooks/read-package-hook), the record went empty and every other importer's hoist of that peer was suppressed — pnpm's once-per-generation missingPeersOfChildren promise keeps the owner walk's initial misses visible instead, and each importer hoists its own copy. The record now stores the recording owner: the owning importer writes once per ownership generation (later post-hoist passes never refresh it), an ownership change records afresh, and an owner's report replaces a non-owner's provisional one. Restores the (typanion@3.14.0) / (@babel/types@7.29.7) suffixes (11 → 3 lines).

2. A cycle's closing edge survives the first re-entry

pacquet's cycle break dropped the edge at the first re-entry of an ancestor package, losing snapshot lines like es-abstract: 1.24.2 under arraybuffer.prototype.slice@1.0.4. pnpm's buildTree gate (parentIdsContainSequence) only drops a direct self-edge and the second lap of the full parent … child sequence; the repeated node's pruned back-edge is restored on its graph entry by the previously-resolved-children merge — already ported in pacquet's peer pass, but dead code until this gate. Ported to the seed walk, the lockfile-reuse walk, and the lazy realization (3 → 0 lines).

Verification

  • New regression tests: owner_missing_record_is_written_once_per_generation and cycle_closing_edge_reaches_the_graph (both verified to fail without their fixes); full resolving-deps-resolver (127), package-manager + cli (781) suites pass; clippy --deny warnings, rustfmt clean.
  • Whole-monorepo: 0 changed lines vs fresh pnpm 11.6.0, byte-identical across consecutive runs.

What remains on the umbrella

Only the env-lockfile document (doc 1), which the issue originally scoped out: pacquet's first document lacks the packageManagerDependencies block and the libc: fields on the @pacquet/linux-* platform packages.


Written by an agent (Claude Code, claude-fable-5).

Summary by CodeRabbit

  • Bug Fixes

    • Improved circular dependency detection to preserve critical dependency edges while preventing infinite loops.
    • Enhanced missing peer dependency tracking across different resolution contexts for more accurate dependency resolution.
  • Tests

    • Added test coverage for peer dependency recording behavior and circular dependency handling.

zkochan added 2 commits June 12, 2026 22:13
…nership generation

The owner-keyed first-walk record was overwritten on every owner pass,
so once the owning importer hoisted a peer into its own scope (e.g.
typanion under @yarnpkg/core, owned by hooks/read-package-hook), every
other importer's hoist of that peer was suppressed — upstream's
once-per-generation missingPeersOfChildren promise keeps the owner
walk's initial misses visible instead, and each importer hoists its
own copy. The record now stores the recording owner: the owning
importer writes once per ownership generation (its later post-hoist
passes never refresh it), an ownership change records afresh, and an
owner's report replaces a non-owner's provisional one.

Restores the (typanion@3.14.0) / (@babel/types@7.29.7) suffixes that
regressed with the deterministic-owner port; whole-monorepo lockfile
diff vs fresh pnpm 11.6.0: 11 -> 3 changed lines.
Part of #12266.
…entry

pacquet's cycle break dropped the edge at the first re-entry of an
ancestor package, so a snapshot like arraybuffer.prototype.slice's
lost its cycle-closing es-abstract dependency line. pnpm's buildTree
gate (parentIdsContainSequence) only drops a direct self-edge and the
second lap of the full parent…child sequence: the first re-entry's
node exists with its own back-edge pruned, and the
previously-resolved-children merge in the peer pass — already ported,
but dead code until now — restores the pruned children on the
repeated node's graph entry. Ported the gate to the seed walk, the
lockfile-reuse walk, and the lazy realization in the peer pass.

Whole-monorepo lockfile diff vs fresh pnpm 11.6.0: 3 → 0 — the real
lockfile document is now byte-identical, deterministic across runs.
Part of #12266.
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 81700325-6344-4f58-a545-2e1f74979e38

📥 Commits

Reviewing files that changed from the base of the PR and between d2b42c2 and d207727.

📒 Files selected for processing (4)
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
📜 Recent 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: Run benchmark on ubuntu-latest
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Code Coverage
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Lint and Test (macos-latest)
  • 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/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
🧠 Learnings (8)
📚 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/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.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/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.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/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
📚 Learning: 2026-05-24T21:10:50.292Z
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:10:50.292Z
Learning: When implementing dependency “revisit”/optional-folding in pacquet, mirror pnpm’s `resolveDependencies.ts` behavior: on revisit, update the `optional` flag only for the directly visited package, and do not automatically change `optional` for transitive descendants. pnpm corrects stale optional flags later via `copyDependencySubGraph` (a BFS in `lockfile/pruner/src/index.ts`/`copyDependencySubGraph`). Until pacquet has an equivalent pruner/copy-subgraph step, be aware that the raw `node.optional` can flow through to the lockfile/virtual store via `dependencies_graph_to_lockfile.rs` → `create_virtual_store.rs` → `installability.rs`, so review changes that affect optional flag propagation for this mismatch.

Applied to files:

  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
📚 Learning: 2026-06-12T14:51:20.984Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12361
File: pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs:1338-1341
Timestamp: 2026-06-12T14:51:20.984Z
Learning: When reviewing pacquet Rust dependency-tree resolution logic that performs `landed_on_prior_entry`-style comparisons, avoid comparing raw ids that may include a `patch_hash=(...)` suffix and/or peer suffixes. `PkgNameVerPeer`’s peer-suffix handling can already absorb the patch-hash token such that `prior_key.without_peer()` represents bare `nameversion` for registry packages. The id-mismatch risk is on the normalized-id side: `build_pkg_id_with_patch_hash` may add `file:`/`git:`/`tarball:` prefixes before `name@...`. For correctness, ensure both sides are normalized by stripping patch/peer suffixes—specifically compare `prior_key.without_peer()` with `pacquet_deps_path::remove_suffix(&id)` (both stripped), ideally via the `landed_on_prior_entry` helper so the normalization rules stay consistent.

Applied to files:

  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
📚 Learning: 2026-05-24T21:10:50.292Z
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:10:50.292Z
Learning: In pacquet’s Rust resolver layer, the behavior of `ResolvedPackage.optional` “AND-folding”/revisit updates is intentionally aligned with pnpm: when a package is directly revisited, only that package’s `optional` flag is updated; transitive descendants are not re-walked/rescored in this stage. pnpm later corrects any stale optional flags downstream via its pruner/BFS logic (`copyDependencySubGraph` + `nonOptional` reachability stamping in the lockfile pruner). Since pacquet does not yet have that pruner equivalent, review should NOT flag the downstream/stale optional propagation as a bug in pacquet PRs; treat the resolver-layer optional propagation gap as expected parity until the pruning/stamping step is ported.

Applied to files:

  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.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/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
📚 Learning: 2026-06-12T20:41:57.558Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12364
File: pacquet/crates/package-manager/src/install/tests.rs:5717-5717
Timestamp: 2026-06-12T20:41:57.558Z
Learning: In the pnpm/pnpm Rust workspace (toolchain Rust 1.95.0), keep using `std::time::Duration::from_mins(...)` and `std::time::Duration::from_hours(...)` as-is. Do not flag these as invalid or suggest replacing them with `Duration::from_secs(...)`, because Clippy’s `clippy::duration_suboptimal_units` lint is denied by `-D warnings` in CI, and changing to seconds may trigger CI failures.

Applied to files:

  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/tests.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
  • pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
🔇 Additional comments (4)
pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs (1)

38-95: LGTM!

pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs (1)

584-594: LGTM!

Also applies to: 596-602, 681-717, 723-726, 1373-1379, 1655-1678, 2135-2137

pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs (1)

1548-1556: LGTM!

pacquet/crates/resolving-deps-resolver/src/tests.rs (1)

3064-3133: LGTM!


📝 Walkthrough

Walkthrough

The PR refactors missing-peer tracking to record ownership metadata and changes cycle-edge detection to preserve first re-entries while dropping only full-sequence repeats. This enables cycle-closing edges to reach the lockfile snapshot and makes peer-record writes deterministic by generation.

Changes

Missing-peer ownership tracking

Layer / File(s) Summary
Ownership-aware missing-peer state and recording
pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs, pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs
OwnerMissingRecord now stores both the missing-peer set and the ChildrenOwner generation that recorded it. record_first_walk_missing conditionally replaces non-owner provisional records when the owner makes its own record, and first_walk_missing_by_pkg() extracts the stored sets for peer/hoist consumption. Test verifies generation-based write behavior.

Cycle-closing edge preservation

Layer / File(s) Summary
Sequence detection helper
pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
New parent_ids_contain_sequence helper detects whether the ancestor chain contains pkg_id1 before a non-final pkg_id2, enabling "second-lap" cycle identification.
Fresh and reused resolve cycle-breaking
pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs
Both fresh-resolve (resolve_node_seed) and reused-subtree (resolve_reused_node) paths update their cycle-detection to drop only the second lap (detected via sequence check and last-ancestor match) instead of dropping any ancestor match.
Lazy resolve cycle-prevention alignment
pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs
Lazy children realization (realize_children) cycle gate now also skips self-edges and sequences via parent_ids_contain_sequence, aligning with eager-walk cycle logic.
Cycle-closing edge integration test
pacquet/crates/resolving-deps-resolver/src/tests.rs
Regression test constructs a two-package cycle and verifies both forward and cycle-closing edges persist in the final resolved graph after dependency and peer resolution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • pnpm/pnpm#12266: Directly addresses cyclic peer dependency collapse by preserving cycle-closing edges through cycle-detection refinement.
  • pnpm/pnpm#12358: Addresses deterministic missing-peer record ownership via generation-based writing and replacement logic.

Possibly related PRs

  • pnpm/pnpm#12349: Also refactors record_first_walk_missing and first_walk_missing_by_pkg ownership/generation semantics in WorkspaceTreeCtx.
  • pnpm/pnpm#12362: Modifies shared-children ownership and missing-peer bookkeeping around first_walk_missing_by_pkg generation records.
  • pnpm/pnpm#11915: Also refines cycle-prevention logic in resolve_dependency_tree.rs and resolve_peers.rs around ancestor/sequence-based edge dropping.

Poem

🐰 A cycle closed now gently glows,
where first re-entry guards the flow—
ownership marks who writes the truth,
one generation per move, forsooth!
Peers resolve where edges meet,
making circular deps complete.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the two main changes: generation-once owner records and cycle-closing edges, which are the core fixes described in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✏️ 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 lockfile-parity5

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.

@qodo-free-for-open-source-projects

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

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Grey Divider


Informational

1. Cycle comment mismatch 🐞 Bug ⚙ Maintainability
Description
In Walker::realize_children, the doc comment says any child whose pkg id appears in parent_ids
is skipped, but the updated gate keeps the first re-entry and only drops direct self-edges or
second-lap re-entries. This mismatch can mislead future maintenance/debugging of cycle handling.
Code

pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs[R1548-1556]

+            // Same cycle gate as the eager walk: keep the first
+            // re-entry, drop a direct self-edge or a second lap.
+            if pkg_id == edge.pkg_id
+                || crate::resolve_dependency_tree::parent_ids_contain_sequence(
+                    &parent_ids,
+                    &pkg_id,
+                    &edge.pkg_id,
+                )
+            {
Evidence
The realize_children doc comment states a broader skip condition than the code now implements; the
code explicitly keeps the first re-entry and uses parent_ids_contain_sequence to only drop direct
self-edges or second-lap cycle edges.

pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs[1515-1518]
pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs[1548-1556]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`Walker::realize_children`'s doc comment still describes the old cycle-breaking rule (skip any child already in `parent_ids`). After this PR, the implementation intentionally keeps the first re-entry and only drops self-edges or second-lap re-entries.

### Issue Context
This is documentation drift introduced by the cycle-gate behavior change; it can confuse future refactors/debugging.

### Fix Focus Areas
- pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs[1515-1518]
- pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs[1548-1556]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Fix lockfile parity: stable missing-peer recording and cycle-closing edges
🐞 Bug fix 🧪 Tests 🕐 40+ Minutes

Grey Divider

Walkthroughs

Description
• Persist owner missing-peer reports once per ownership generation to match pnpm behavior.
• Keep cycle-closing edges on first cycle re-entry across eager, reuse, and lazy walks.
• Add regression tests covering missing-peer generation semantics and cycle edge retention.
Diagram
graph TD
  A["resolve_dependency_tree"] --> B[("WorkspaceTreeCtx")] --> C[("Missing-peer cache")]
  A --> D{"Cycle gate"} --> E["Tree edges"] --> F["resolve_peers"] --> G["Lockfile graph"]
  B --> F
  subgraph Legend
    direction LR
    _p["Process"] ~~~ _d{"Decision"} ~~~ _s[("State")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use explicit ownership-generation IDs
  • ➕ Decouples cache invalidation from ChildrenOwner structural equality
  • ➕ Potentially clearer semantics for ‘new generation’ and less cloning
  • ➖ Requires threading/generating generation counters and updating multiple call sites
  • ➖ More invasive than storing recorded_by and comparing to current owner
2. Adopt full upstream cycle detection verbatim (closer port)
  • ➕ Minimizes future parity drift risk
  • ➕ Easier to diff against upstream when debugging edge cases
  • ➖ May require broader refactors to match upstream data structures
  • ➖ Less idiomatic Rust without adaptation (risk of new bugs during port)

Recommendation: Current approach (recording recorded_by: Option plus parent_ids_contain_sequence gating) is a good balance: it matches pnpm’s externally-visible behavior with minimal structural churn, and it unblocks the already-present ‘previously-resolved-children’ merge logic. If cycle/ownership rules evolve again, introducing explicit generation IDs would be the next most maintainable step.

Grey Divider

File Changes

Bug fix (2)
resolve_dependency_tree.rs Stabilize owner missing-peer records and refine cycle break gating +76/-13

Stabilize owner missing-peer records and refine cycle break gating

• Replaces the per-package missing-peer cache with an 'OwnerMissingRecord' that tracks which children-owner generation recorded the initial misses, preventing later owner hoist waves from overwriting them. Updates the cycle break logic to keep the first cycle re-entry (dropping only direct self-edges and second laps) via a new 'parent_ids_contain_sequence' helper, and applies this gate in both fresh and lockfile-reuse resolution paths.

pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree.rs


resolve_peers.rs Apply upstream-matching cycle gate during lazy child realization +9/-1

Apply upstream-matching cycle gate during lazy child realization

• Updates 'Walker::realize_children' to use the same cycle gate as the eager walk: skip direct self-edges and second-lap cycle edges, while keeping first re-entries so cycle-closing edges can appear in the graph and be restored via previously-resolved-children merging.

pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs


Tests (2)
tests.rs Add regression test for once-per-generation missing-peer recording +58/-0

Add regression test for once-per-generation missing-peer recording

• Adds a unit test asserting that (1) a non-owner provisional missing-peer report can be replaced by the owner’s first report, (2) the owner’s later post-hoist passes do not refresh the generation record, and (3) an ownership change starts a fresh record.

pacquet/crates/resolving-deps-resolver/src/resolve_dependency_tree/tests.rs


tests.rs Add integration-style test ensuring cycle-closing edge reaches graph +71/-0

Add integration-style test ensuring cycle-closing edge reaches graph

• Introduces a tokio test constructing a two-package dependency cycle and asserting that both edges (a→b and b→a) appear in the resolved graph after 'resolve_peers', preventing lockfile snapshot edge loss.

pacquet/crates/resolving-deps-resolver/src/tests.rs


Grey Divider

Qodo Logo

@github-actions

Copy link
Copy Markdown
Contributor

Micro-Benchmark Results

Linux

group                          main                                   pr
-----                          ----                                   --
tarball/download_dependency    1.00      7.8±0.15ms   552.7 KB/sec    1.01      7.9±0.28ms   546.8 KB/sec

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.34884% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.17%. Comparing base (d2b42c2) to head (d207727).

Files with missing lines Patch % Lines
...lving-deps-resolver/src/resolve_dependency_tree.rs 94.73% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12365      +/-   ##
==========================================
+ Coverage   88.15%   88.17%   +0.01%     
==========================================
  Files         295      295              
  Lines       37733    37769      +36     
==========================================
+ Hits        33265    33302      +37     
+ Misses       4468     4467       -1     

☔ View full report in Codecov by Harness.
📢 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.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: Lint and Test (macos-latest)

Failed stage: Test [❌]

Failed test name: latency_proxy::tests::slow_start_ramps_per_connection_throughput

Failure summary:

The action failed during just test because a Rust nextest test panicked and caused the test run to
exit with code 100.
- Failed test: pacquet-integrated-benchmark::bin/integrated-benchmark
latency_proxy::tests::slow_start_ramps_per_connection_throughput
- Panic location:
pacquet/tasks/integrated-benchmark/src/latency_proxy/tests.rs:173:5
- Assertion message indicates
the expected slow-start ramp-up timing difference was too small (flaky/timing-sensitive on CI): slow
start should add ramp-up time: flat 306.485042ms vs ramped 307.393667ms
- Nextest then cancelled
remaining running tests due to fail-fast, and just test reported recipe test failed on line 54 with
exit code 100.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

329:  - /Users/runner/work/pnpm/pnpm/pacquet/tasks/registry-mock/Cargo.toml
330:  - /Users/runner/work/pnpm/pnpm/pnpr/crates/pnpr-fixtures/Cargo.toml
331:  - /Users/runner/work/pnpm/pnpm/pnpr/crates/pnpr/Cargo.toml
332:  - /Users/runner/work/pnpm/pnpm/rust-toolchain.toml
333:  ##[endgroup]
334:  ... Restoring cache ...
335:  No cache found.
336:  ##[group]Run pnpm/setup@b1cac37306e39c21283b9dd6cb0ac288fb35ba6b
337:  with:
338:  install: false
339:  dest: ~/setup-pnpm
340:  cache: false
341:  cache-dependency-path: pnpm-lock.yaml
342:  package-json-file: package.json
343:  env:
344:  CACHE_ON_FAILURE: false
345:  CARGO_INCREMENTAL: 0
...

361:  Installation Completed!
362:  ##[group]Installing runtime node@26.3.0...
363:  Progress: resolved 1, reused 0, downloaded 0, added 0
364:  Packages: +1
365:  +
366:  Progress: resolved 1, reused 0, downloaded 1, added 0
367:  Progress: resolved 1, reused 0, downloaded 1, added 1, done
368:  global:
369:  + node 26.3.0
370:  Done in 3.5s using pnpm v11.6.0
371:  ##[endgroup]
372:  ##[group]Run pnpm runtime set node 22 --global
373:  �[36;1mpnpm runtime set node 22 --global�[0m
374:  shell: /bin/bash -e {0}
375:  env:
376:  CACHE_ON_FAILURE: false
377:  CARGO_INCREMENTAL: 0
...

384:  Progress: resolved 1, reused 0, downloaded 1, added 1, done
385:  global:
386:  + node 22.22.3
387:  Done in 2.4s using pnpm v11.6.0
388:  ##[group]Run actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae
389:  with:
390:  key: ci-pnpm-v11-macos-latest
391:  path: /Users/runner/setup-pnpm/node_modules/.bin/store/v11
392:  /.local/share/pnpm/store/v11
393:  
394:  enableCrossOsArchive: false
395:  fail-on-cache-miss: false
396:  lookup-only: false
397:  save-always: false
398:  env:
399:  CACHE_ON_FAILURE: false
400:  CARGO_INCREMENTAL: 0
401:  PNPM_HOME: /Users/runner/setup-pnpm/node_modules/.bin
402:  ##[endgroup]
403:  Cache not found for input keys: ci-pnpm-v11-macos-latest
404:  ##[group]Run cargo clippy --locked --workspace --all-targets -- -D warnings
405:  �[36;1mcargo clippy --locked --workspace --all-targets -- -D warnings�[0m
406:  shell: /bin/bash -e {0}
407:  env:
408:  CACHE_ON_FAILURE: false
409:  CARGO_INCREMENTAL: 0
...

412:  Updating crates.io index
413:  Downloading crates ...
414:  Downloaded allocator-api2 v0.2.21
415:  Downloaded base16ct v0.2.0
416:  Downloaded backtrace-ext v0.2.1
417:  Downloaded cfg-if v1.0.4
418:  Downloaded crc32fast v1.5.0
419:  Downloaded serdect v0.2.0
420:  Downloaded smart-default v0.7.1
421:  Downloaded strum_macros v0.28.0
422:  Downloaded snafu v0.8.9
423:  Downloaded opaque-debug v0.3.1
424:  Downloaded crossbeam-channel v0.5.15
425:  Downloaded primeorder v0.13.6
426:  Downloaded rand_chacha v0.3.1
427:  Downloaded thiserror v1.0.69
428:  Downloaded derive_builder_macro v0.20.2
429:  Downloaded rustc_version v0.4.1
430:  Downloaded rustc-hash v2.1.2
431:  Downloaded eax v0.5.0
432:  Downloaded elliptic-curve v0.13.8
433:  Downloaded fastrand v2.4.1
434:  Downloaded flate2 v1.1.9
435:  Downloaded tracing-subscriber v0.3.23
436:  Downloaded tree-sitter v0.26.9
437:  Downloaded encoding_rs v0.8.35
438:  Downloaded parking_lot v0.12.5
439:  Downloaded serde_path_to_error v0.1.20
440:  Downloaded predicates v3.1.4
...

547:  Downloaded tower v0.5.3
548:  Downloaded tinytemplate v1.2.1
549:  Downloaded tracing-serde v0.2.0
550:  Downloaded tracing-core v0.1.36
551:  Downloaded tower-service v0.3.3
552:  Downloaded tower-layer v0.3.3
553:  Downloaded tonic v0.11.0
554:  Downloaded toml_parser v1.1.2+spec-1.1.0
555:  Downloaded tokio-stream v0.1.18
556:  Downloaded tokio-rustls v0.26.4
557:  Downloaded tokio-macros v2.7.0
558:  Downloaded tokio-io-timeout v1.2.1
559:  Downloaded tinyvec_macros v0.1.1
560:  Downloaded tinystr v0.8.3
561:  Downloaded thread_local v1.1.9
562:  Downloaded thiserror-impl v2.0.18
563:  Downloaded thiserror-impl v1.0.69
564:  Downloaded thiserror v2.0.18
565:  Downloaded ring v0.17.14
...

737:  Downloaded strsim v0.11.1
738:  Downloaded streaming-iterator v0.1.9
739:  Downloaded stable_deref_trait v1.2.1
740:  Downloaded ssri v9.2.0
741:  Downloaded split-first-char v2.0.1
742:  Downloaded spki v0.7.3
743:  Downloaded smallvec v1.15.1
744:  Downloaded rand v0.9.4
745:  Downloaded rand v0.8.6
746:  Downloaded quinn-udp v0.5.14
747:  Downloaded quinn v0.11.9
748:  Downloaded prost-derive v0.12.6
749:  Downloaded prost v0.12.6
750:  Downloaded project-root v0.2.2
751:  Downloaded proc-macro2 v1.0.106
752:  Downloaded proc-macro-error2 v2.0.1
753:  Downloaded proc-macro-error-attr2 v2.0.0
754:  Downloaded proc-macro-crate v3.5.0
...

1059:  Compiling getrandom v0.4.2
1060:  Checking rand_core v0.10.1
1061:  Checking futures-sink v0.3.32
1062:  Compiling synstructure v0.13.2
1063:  Checking slab v0.4.12
1064:  Compiling zerofrom-derive v0.1.7
1065:  Checking futures-channel v0.3.32
1066:  Checking zerofrom v0.1.7
1067:  Compiling yoke-derive v0.8.2
1068:  Checking sha2 v0.10.9
1069:  Compiling futures-macro v0.3.32
1070:  Compiling getrandom v0.3.4
1071:  Checking futures-task v0.3.32
1072:  Checking stable_deref_trait v1.2.1
1073:  Checking futures-io v0.3.32
1074:  Compiling thiserror v1.0.69
1075:  Checking yoke v0.8.2
1076:  Compiling thiserror-impl v1.0.69
1077:  Compiling heck v0.5.0
1078:  Checking futures-util v0.3.32
1079:  Checking percent-encoding v2.3.2
1080:  Compiling zerovec-derive v0.11.3
1081:  Checking fnv v1.0.7
1082:  Compiling displaydoc v0.2.5
1083:  Checking zerovec v0.11.6
1084:  Compiling cmake v0.1.58
1085:  Checking tokio-util v0.7.18
1086:  Checking tower-service v0.3.3
1087:  Compiling thiserror v2.0.18
1088:  Compiling crossbeam-utils v0.8.21
1089:  Checking tinystr v0.8.3
1090:  Compiling thiserror-impl v2.0.18
1091:  Checking writeable v0.6.3
...

1461:  Checking futures-executor v0.3.32
1462:  Checking http-range-header v0.3.1
1463:  Checking cipher v0.5.2
1464:  Checking tower-http v0.4.4
1465:  Checking futures v0.3.32
1466:  Checking libsql-sys v0.9.30
1467:  Checking phf v0.11.3
1468:  Checking cbc v0.1.2
1469:  Checking libsql_replication v0.9.30
1470:  Checking tonic-web v0.11.0
1471:  Checking blowfish v0.10.0
1472:  Checking libsql-hrana v0.9.30
1473:  Checking axum-core v0.5.6
1474:  Checking quick-xml v0.38.4
1475:  Checking bincode v1.3.3
1476:  Checking serde_path_to_error v0.1.20
1477:  Checking matchit v0.8.4
...

1482:  Checking predicates-core v1.0.10
1483:  Checking pnpr-fixtures v0.0.1 (/Users/runner/work/pnpm/pnpm/pnpr/crates/pnpr-fixtures)
1484:  Checking difflib v0.4.0
1485:  Checking termtree v0.5.1
1486:  Checking similar v2.7.0
1487:  Compiling assert_cmd v2.2.2
1488:  Checking predicates-tree v1.0.13
1489:  Checking predicates v3.1.4
1490:  Checking wait-timeout v0.2.1
1491:  Checking assert-json-diff v2.0.2
1492:  Checking colored v3.1.1
1493:  Checking mockito v1.7.2
1494:  Checking text-block-macros v0.2.0
1495:  Checking command-extra v1.0.0
1496:  Checking console v0.16.3
1497:  Compiling proc-macro-error-attr2 v2.0.0
1498:  Checking insta v1.47.2
1499:  Compiling proc-macro-error2 v2.0.1
1500:  Checking pacquet-workspace-projects-graph v0.0.1 (/Users/runner/work/pnpm/pnpm/pacquet/crates/workspace-projects-graph)
...

1562:  Checking pacquet-package-manager v0.0.1 (/Users/runner/work/pnpm/pnpm/pacquet/crates/package-manager)
1563:  Checking pacquet-micro-benchmark v0.0.0 (/Users/runner/work/pnpm/pnpm/pacquet/tasks/micro-benchmark)
1564:  Checking pnpr v0.0.1 (/Users/runner/work/pnpm/pnpm/pnpr/crates/pnpr)
1565:  Checking pacquet-env-installer v0.0.1 (/Users/runner/work/pnpm/pnpm/pacquet/crates/env-installer)
1566:  Checking pacquet-cli v0.0.1 (/Users/runner/work/pnpm/pnpm/pacquet/crates/cli)
1567:  Checking pacquet-testing-utils v0.0.0 (/Users/runner/work/pnpm/pnpm/pacquet/crates/testing-utils)
1568:  Checking pacquet-workspace-projects-filter v0.0.1 (/Users/runner/work/pnpm/pnpm/pacquet/crates/workspace-projects-filter)
1569:  Checking pacquet-integrated-benchmark v0.0.0 (/Users/runner/work/pnpm/pnpm/pacquet/tasks/integrated-benchmark)
1570:  Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 20s
1571:  ##[group]Run taiki-e/install-action@873c7452cadb7c034694a1282227095d93fbdf92
1572:  with:
1573:  tool: just
1574:  checksum: true
1575:  fallback: cargo-binstall
1576:  env:
1577:  CACHE_ON_FAILURE: false
1578:  CARGO_INCREMENTAL: 0
1579:  PNPM_HOME: /Users/runner/setup-pnpm/node_modules/.bin
1580:  ##[endgroup]
1581:  ##[group]Run bail() {
1582:  �[36;1mbail() {�[0m
1583:  �[36;1m  printf '::error::install-action: %s\n' "$*"�[0m
1584:  �[36;1m  exit 1�[0m
...

1595:  �[36;1m    if command -v sudo >/dev/null; then�[0m
1596:  �[36;1m      sudo apk --no-cache add bash�[0m
1597:  �[36;1m    elif command -v doas >/dev/null; then�[0m
1598:  �[36;1m      doas apk --no-cache add bash�[0m
1599:  �[36;1m    else�[0m
1600:  �[36;1m      apk --no-cache add bash�[0m
1601:  �[36;1m    fi�[0m
1602:  �[36;1m    printf '::endgroup::\n'�[0m
1603:  �[36;1m  else�[0m
1604:  �[36;1m    bail 'this action requires bash'�[0m
1605:  �[36;1m  fi�[0m
1606:  �[36;1mfi�[0m
1607:  �[36;1mbash --noprofile --norc "${GITHUB_ACTION_PATH:?}/main.sh"�[0m
1608:  shell: /usr/bin/env -u ENV -u BASH_ENV -u CDPATH -u SHELLOPTS -u BASHOPTS /bin/sh -eu {0}
1609:  env:
1610:  CACHE_ON_FAILURE: false
1611:  CARGO_INCREMENTAL: 0
...

1617:  ACTION_USER_AGENT: taiki-e/install-action (873c7452cadb7c034694a1282227095d93fbdf92)
1618:  RUNNER_OS: macOS
1619:  RUNNER_ARCH: ARM64
1620:  ##[endgroup]
1621:  info: host platform: aarch64_macos
1622:  info: installing just@latest
1623:  info: downloading https://github.com/casey/just/releases/download/1.51.0/just-1.51.0-aarch64-apple-darwin.tar.gz
1624:  info: verifying sha256 checksum for just-1.51.0-aarch64-apple-darwin.tar.gz
1625:  info: just installed at /Users/runner/.cargo/bin/just
1626:  + just --version
1627:  just 1.51.0
1628:  ##[group]Run just install
1629:  �[36;1mjust install�[0m
1630:  shell: /bin/bash -e {0}
1631:  env:
1632:  CACHE_ON_FAILURE: false
1633:  CARGO_INCREMENTAL: 0
...

1658:  Progress: resolved 1654, reused 4, downloaded 1651, added 1654
1659:  Progress: resolved 1654, reused 4, downloaded 1651, added 1654, done
1660:  .../node_modules/fuse-native install$ node-gyp-build
1661:  .../node_modules/esbuild postinstall$ node install.js
1662:  .../node_modules/ghooks install$ node ./bin/module-install
1663:  .../node_modules/ghooks install: This does not seem to be a git project.
1664:  .../node_modules/ghooks install: Although ghooks was installed, the actual git hooks have not.
1665:  .../node_modules/ghooks install: Run "git init" and then "npm explore ghooks -- npm run install".
1666:  .../node_modules/ghooks install: 
1667:  .../node_modules/ghooks install: Please ignore this message if you are not using ghooks directly.
1668:  .../node_modules/ghooks install: Done
1669:  .../node_modules/msgpackr-extract install$ node-gyp-build-optional-packages
1670:  .../node_modules/esbuild postinstall: Done
1671:  .../node_modules/unrs-resolver postinstall$ node postinstall.js
1672:  .../node_modules/fuse-native install: node:events:497
1673:  .../node_modules/fuse-native install:       throw er; // Unhandled 'error' event
1674:  .../node_modules/fuse-native install:       ^
1675:  .../node_modules/fuse-native install: 
1676:  .../node_modules/fuse-native install: Error: spawn node-gyp ENOENT
1677:  .../node_modules/fuse-native install:     at ChildProcess._handle.onexit (node:internal/child_process:285:19)
1678:  .../node_modules/fuse-native install:     at onErrorNT (node:internal/child_process:483:16)
1679:  .../node_modules/fuse-native install:     at process.processTicksAndRejections (node:internal/process/task_queues:89:21)
1680:  .../node_modules/fuse-native install: Emitted 'error' event on ChildProcess instance at:
1681:  .../node_modules/fuse-native install:     at ChildProcess._handle.onexit (node:internal/child_process:291:12)
1682:  .../node_modules/fuse-native install:     at onErrorNT (node:internal/child_process:483:16)
1683:  .../node_modules/fuse-native install:     at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
1684:  .../node_modules/fuse-native install:   errno: -2,
1685:  .../node_modules/fuse-native install:   code: 'ENOENT',
1686:  .../node_modules/fuse-native install:   syscall: 'spawn node-gyp',
1687:  .../node_modules/fuse-native install:   path: 'node-gyp',
1688:  .../node_modules/fuse-native install:   spawnargs: [ 'rebuild' ]
1689:  .../node_modules/fuse-native install: }
1690:  .../node_modules/fuse-native install: 
1691:  .../node_modules/fuse-native install: Node.js v22.22.3
1692:  .../node_modules/fuse-native install: Failed
1693:  .../node_modules/unrs-resolver postinstall: [napi-postinstall@0.3.4] Failed to find package "@unrs/resolver-binding-darwin-arm64" on the file system
1694:  .../node_modules/unrs-resolver postinstall: 
1695:  .../node_modules/unrs-resolver postinstall: This can happen if you use the "--no-optional" flag. The "optionalDependencies"
1696:  .../node_modules/unrs-resolver postinstall: package.json feature is used by unrs-resolver to install the correct napi binary
1697:  .../node_modules/unrs-resolver postinstall: for your current platform. This install script will now attempt to work around
1698:  .../node_modules/unrs-resolver postinstall: this. If that fails, you need to remove the "--no-optional" flag to use unrs-resolver.
1699:  .../node_modules/unrs-resolver postinstall: 
1700:  .../node_modules/unrs-resolver postinstall: [napi-postinstall@0.3.4] Trying to install package "@unrs/resolver-binding-darwin-arm64" using npm
1701:  .../node_modules/unrs-resolver postinstall: [napi-postinstall@0.3.4] Failed to install package "@unrs/resolver-binding-darwin-arm64" using npm Cannot find module 'unrs-resolver/package.json'
1702:  .../node_modules/unrs-resolver postinstall: Require stack:
...

1734:  + husky 9.1.7
1735:  + jest 30.4.2
1736:  + keyv 5.6.0
1737:  + lcov-result-merger 6.0.0
1738:  + node 26.3.0
1739:  + rimraf 6.1.3
1740:  + shx 0.4.0
1741:  + typescript 6.0.3
1742:  Done in 17.4s using pnpm v11.6.0
1743:  ##[group]Run taiki-e/install-action@873c7452cadb7c034694a1282227095d93fbdf92
1744:  with:
1745:  tool: cargo-nextest
1746:  checksum: true
1747:  fallback: cargo-binstall
1748:  env:
1749:  CACHE_ON_FAILURE: false
1750:  CARGO_INCREMENTAL: 0
1751:  PNPM_HOME: /Users/runner/setup-pnpm/node_modules/.bin
1752:  ##[endgroup]
1753:  ##[group]Run bail() {
1754:  �[36;1mbail() {�[0m
1755:  �[36;1m  printf '::error::install-action: %s\n' "$*"�[0m
1756:  �[36;1m  exit 1�[0m
...

1767:  �[36;1m    if command -v sudo >/dev/null; then�[0m
1768:  �[36;1m      sudo apk --no-cache add bash�[0m
1769:  �[36;1m    elif command -v doas >/dev/null; then�[0m
1770:  �[36;1m      doas apk --no-cache add bash�[0m
1771:  �[36;1m    else�[0m
1772:  �[36;1m      apk --no-cache add bash�[0m
1773:  �[36;1m    fi�[0m
1774:  �[36;1m    printf '::endgroup::\n'�[0m
1775:  �[36;1m  else�[0m
1776:  �[36;1m    bail 'this action requires bash'�[0m
1777:  �[36;1m  fi�[0m
1778:  �[36;1mfi�[0m
1779:  �[36;1mbash --noprofile --norc "${GITHUB_ACTION_PATH:?}/main.sh"�[0m
1780:  shell: /usr/bin/env -u ENV -u BASH_ENV -u CDPATH -u SHELLOPTS -u BASHOPTS /bin/sh -eu {0}
1781:  env:
1782:  CACHE_ON_FAILURE: false
1783:  CARGO_INCREMENTAL: 0
...

1798:  + cargo-nextest nextest --version
1799:  cargo-nextest 0.9.137 (75ddba7e9 2026-05-26)
1800:  release: 0.9.137
1801:  commit-hash: 75ddba7e911b44c5c0700dac0415d824403de9bd
1802:  commit-date: 2026-05-26
1803:  host: aarch64-apple-darwin
1804:  ##[group]Run # removing env vars is a temporary workaround for unit tests in pacquet relying on external environment
1805:  �[36;1m# removing env vars is a temporary workaround for unit tests in pacquet relying on external environment�[0m
1806:  �[36;1m# this should be removed in the future�[0m
1807:  �[36;1munset PNPM_HOME�[0m
1808:  �[36;1munset XDG_DATA_HOME�[0m
1809:  �[36;1m�[0m
1810:  �[36;1mjust test�[0m
1811:  shell: /bin/bash --noprofile --norc -e -o pipefail {0}
1812:  env:
1813:  CACHE_ON_FAILURE: false
1814:  CARGO_INCREMENTAL: 0
...

1885:  Compiling lock_api v0.4.14
1886:  Compiling parking_lot_core v0.9.12
1887:  Compiling sha2-asm v0.6.4
1888:  Compiling sha2 v0.10.9
1889:  Compiling num-traits v0.2.19
1890:  Compiling parking_lot v0.12.5
1891:  Compiling signal-hook-registry v1.4.8
1892:  Compiling socket2 v0.6.3
1893:  Compiling mio v1.2.0
1894:  Compiling tokio v1.52.3
1895:  Compiling futures-core v0.3.32
1896:  Compiling minimal-lexical v0.2.1
1897:  Compiling fnv v1.0.7
1898:  Compiling getrandom v0.3.4
1899:  Compiling futures-sink v0.3.32
1900:  Compiling thiserror v1.0.69
1901:  Compiling slab v0.4.12
1902:  Compiling zerofrom v0.1.7
1903:  Compiling futures-channel v0.3.32
1904:  Compiling stable_deref_trait v1.2.1
1905:  Compiling yoke v0.8.2
1906:  Compiling futures-task v0.3.32
1907:  Compiling percent-encoding v2.3.2
1908:  Compiling futures-io v0.3.32
1909:  Compiling futures-util v0.3.32
1910:  Compiling zerovec v0.11.6
1911:  Compiling nom v7.1.3
1912:  Compiling either v1.15.0
1913:  Compiling fastrand v2.4.1
1914:  Compiling thiserror v2.0.18
1915:  Compiling tokio-util v0.7.18
...

2259:  Compiling futures v0.3.32
2260:  Compiling phf v0.11.3
2261:  Compiling cipher v0.5.2
2262:  Compiling libsql-sys v0.9.30
2263:  Compiling cbc v0.1.2
2264:  Compiling libsql_replication v0.9.30
2265:  Compiling aws-lc-rs v1.16.3
2266:  Compiling rustls v0.23.39
2267:  Compiling blowfish v0.10.0
2268:  Compiling tonic-web v0.11.0
2269:  Compiling libsql-hrana v0.9.30
2270:  Compiling axum-core v0.5.6
2271:  Compiling rustls-webpki v0.103.13
2272:  Compiling bincode v1.3.3
2273:  Compiling quick-xml v0.38.4
2274:  Compiling serde_path_to_error v0.1.20
2275:  Compiling matchit v0.8.4
...

2364:  Finished `test` profile [unoptimized + debuginfo] target(s) in 4m 03s
2365:  ────────────
2366:  Nextest run ID e19ee4cc-1f9d-44e6-b1a3-a6360c261a09 with nextest profile: default
2367:  Starting 3299 tests across 117 binaries (3 tests skipped)
2368:  PASS [   0.011s] (   1/3299) pacquet-catalogs-config tests::combines_implicit_default_and_named_catalogs
2369:  PASS [   0.011s] (   2/3299) pacquet-catalogs-config tests::combines_explicit_default_and_named_catalogs
2370:  PASS [   0.015s] (   3/3299) pacquet-catalogs-config tests::returns_empty_map_for_missing_workspace_manifest
2371:  PASS [   0.014s] (   4/3299) pacquet-catalogs-protocol-parser tests::parses_explicit_default_catalog
2372:  PASS [   0.014s] (   5/3299) pacquet-catalogs-config tests::throws_if_default_catalog_is_defined_multiple_times
2373:  PASS [   0.013s] (   6/3299) pacquet-catalogs-protocol-parser tests::parses_implicit_default_catalog
2374:  PASS [   0.013s] (   7/3299) pacquet-catalogs-protocol-parser tests::parses_named_catalog
2375:  PASS [   0.018s] (   8/3299) pacquet-catalogs-resolver tests::default_catalog_resolves_using_explicit_name
2376:  PASS [   0.031s] (   9/3299) pacquet-catalogs-protocol-parser tests::returns_none_for_specifier_not_using_catalog_protocol
2377:  PASS [   0.019s] (  10/3299) pacquet-catalogs-resolver tests::resolves_named_catalog
2378:  PASS [   0.025s] (  11/3299) pacquet-catalogs-resolver tests::default_catalog_resolves_using_implicit_name
2379:  PASS [   0.021s] (  12/3299) pacquet-catalogs-resolver tests::returns_error_for_file_protocol_in_catalog
2380:  PASS [   0.016s] (  13/3299) pacquet-catalogs-resolver tests::returns_error_for_link_protocol_in_catalog
2381:  PASS [   0.015s] (  14/3299) pacquet-catalogs-resolver tests::returns_error_for_missing_unresolved_catalog
2382:  PASS [   0.021s] (  15/3299) pacquet-catalogs-resolver tests::returns_error_for_recursive_catalog
2383:  PASS [   0.022s] (  16/3299) pacquet-catalogs-resolver tests::returns_unused_for_specifier_not_using_catalog_protocol
2384:  PASS [   0.027s] (  17/3299) pacquet-catalogs-resolver tests::returns_error_for_workspace_protocol_in_catalog
2385:  PASS [   0.022s] (  18/3299) pacquet-cli cli_args::add::tests::dependency_options_to_dependency_groups
2386:  PASS [   0.029s] (  19/3299) pacquet-cli cli_args::dlx::tests::architecture_flags_accumulate_and_default_empty
2387:  PASS [   0.024s] (  20/3299) pacquet-cli cli_args::dlx::tests::architecture_flags_do_not_consume_the_trailing_command
2388:  PASS [   0.033s] (  21/3299) pacquet-cli cli_args::dlx::tests::create_cache_key_allow_build_is_order_independent
2389:  PASS [   0.024s] (  22/3299) pacquet-cli cli_args::dlx::tests::create_cache_key_changes_with_supported_architectures
2390:  PASS [   0.024s] (  23/3299) pacquet-cli cli_args::dlx::tests::create_cache_key_changes_with_allow_build
2391:  PASS [   0.024s] (  24/3299) pacquet-cli cli_args::dlx::tests::create_cache_key_depends_on_registry
2392:  PASS [   0.031s] (  25/3299) pacquet-cli cli_args::dlx::tests::create_cache_key_is_order_independent_and_deterministic
2393:  PASS [   0.031s] (  26/3299) pacquet-cli cli_args::dlx::tests::get_bin_name_errors_on_ambiguous_bins
2394:  PASS [   0.022s] (  27/3299) pacquet-cli cli_args::dlx::tests::get_bin_name_errors_when_no_dependency
2395:  PASS [   0.019s] (  28/3299) pacquet-cli cli_args::dlx::tests::get_bin_name_returns_single_bin
...

2418:  PASS [   0.017s] (  51/3299) pacquet-cli cli_args::install::tests::resolve_workspace_concurrency_positive_flag_overrides_config
2419:  PASS [   0.019s] (  52/3299) pacquet-cli cli_args::install::tests::resolve_workspace_concurrency_negative_flag_resolves_to_offset
2420:  PASS [   0.022s] (  53/3299) pacquet-cli cli_args::install::tests::workspace_concurrency_parses_negative
2421:  PASS [   0.022s] (  54/3299) pacquet-cli cli_args::outdated::tests::classify_detects_each_bump_kind
2422:  PASS [   0.022s] (  55/3299) pacquet-cli cli_args::install::tests::workspace_concurrency_parses_positive
2423:  PASS [   0.014s] (  56/3299) pacquet-cli cli_args::outdated::tests::include_default_covers_all_three_groups
2424:  PASS [   0.014s] (  57/3299) pacquet-cli cli_args::outdated::tests::include_dev_keeps_only_dev
2425:  PASS [   0.019s] (  58/3299) pacquet-cli cli_args::outdated::tests::default_sort_orders_by_change_then_name
2426:  PASS [   0.014s] (  59/3299) pacquet-cli cli_args::outdated::tests::include_no_optional_drops_optional
2427:  PASS [   0.014s] (  60/3299) pacquet-cli cli_args::outdated::tests::include_prod_keeps_dependencies_and_optional
2428:  PASS [   0.022s] (  61/3299) pacquet-cli cli_args::outdated::tests::json_report_has_expected_shape
2429:  PASS [   0.019s] (  62/3299) pacquet-cli cli_args::outdated::tests::json_report_long_includes_latest_manifest
2430:  PASS [   0.022s] (  63/3299) pacquet-cli cli_args::outdated::tests::render_latest_outdated_and_deprecated
2431:  PASS [   0.013s] (  64/3299) pacquet-cli cli_args::outdated::tests::render_latest_outdated_and_not_deprecated
2432:  PASS [   0.010s] (  65/3299) pacquet-cli cli_args::remove::tests::dependency_options_to_save_type
2433:  PASS [   0.012s] (  66/3299) pacquet-cli cli_args::run::tests::hidden_filter_all_hidden_yields_all_hidden_error
2434:  PASS [   0.017s] (  67/3299) pacquet-cli cli_args::run::tests::hidden_filter_passes_visible_scripts
...

2451:  PASS [   0.018s] (  84/3299) pacquet-cli cli_args::update::tests::no_optional_alone_does_not_drop_optional
2452:  PASS [   0.021s] (  85/3299) pacquet-cli cli_args::update::tests::no_flags_includes_all_groups
2453:  PASS [   0.018s] (  86/3299) pacquet-cli cli_args::update::tests::prod_includes_only_dependencies
2454:  PASS [   0.015s] (  87/3299) pacquet-cli config_overrides::tests::apply_is_a_noop_when_no_overrides_set
2455:  PASS [   0.018s] (  88/3299) pacquet-cli cli_args::update::tests::prod_with_no_optional_drops_optional
2456:  PASS [   0.022s] (  89/3299) pacquet-cli config_overrides::tests::extract_applies_scoped_registry_overrides
2457:  PASS [   0.024s] (  90/3299) pacquet-cli config_overrides::tests::last_value_wins_for_repeated_keys
2458:  PASS [   0.025s] (  91/3299) pacquet-cli config_overrides::tests::extract_separates_config_tokens_from_argv
2459:  PASS [   0.017s] (  92/3299) pacquet-cli config_overrides::tests::malformed_tokens_are_dropped
2460:  PASS [   0.014s] (  93/3299) pacquet-cli config_overrides::tests::unknown_keys_are_dropped_silently
2461:  PASS [   0.019s] (  94/3299) pacquet-cli config_overrides::tests::scoped_registry_override_wins_over_existing_config
2462:  PASS [   0.012s] (  95/3299) pacquet-cli state::tests::test_call_load_lockfile
2463:  PASS [   1.285s] (  96/3299) pacquet-cli::add should_add_peer_dependency
2464:  PASS [   1.284s] (  97/3299) pacquet-cli::add should_add_to_package_json
2465:  PASS [   1.289s] (  98/3299) pacquet-cli::add should_add_dev_dependency
2466:  PASS [   0.160s] (  99/3299) pacquet-cli::catalog add_mismatched_version_strict_errors
2467:  PASS [   0.314s] ( 100/3299) pacquet-cli::add should_install_all_dependencies
2468:  PASS [   0.314s] ( 101/3299) pacquet-cli::add should_symlink_correctly
2469:  PASS [   0.170s] ( 102/3299) pacquet-cli::catalog add_prefer_catalogs_a_new_dependency
2470:  PASS [   0.145s] ( 103/3299) pacquet-cli::catalog readd_catalog_dependency_preserves_specifier
2471:  PASS [   0.165s] ( 104/3299) pacquet-cli::catalog add_strict_catalogs_a_new_dependency
2472:  PASS [   0.173s] ( 105/3299) pacquet-cli::catalog update_latest_named_catalog_bumps_the_entry
2473:  PASS [   0.114s] ( 106/3299) pacquet-cli::catalog update_latest_no_save_leaves_the_catalog_untouched
2474:  PASS [   0.303s] ( 107/3299) pacquet-cli::config_dependencies add_config_writes_workspace_yaml_and_installs
2475:  PASS [   0.286s] ( 108/3299) pacquet-cli::config_dependencies installs_configurational_dependencies
2476:  PASS [   0.250s] ( 109/3299) pacquet-cli::config_dependencies second_install_keeps_config_dependency
2477:  PASS [   0.412s] ( 110/3299) pacquet-cli::config_dependencies update_config_hook_injects_catalog
2478:  PASS [   0.412s] ( 111/3299) pacquet-cli::config_dependencies update_config_hook_mutates_config_before_install
2479:  PASS [   0.689s] ( 112/3299) pacquet-cli::custom_resolvers custom_resolver_receives_current_pkg_on_subsequent_installs
2480:  PASS [   0.362s] ( 113/3299) pacquet-cli::custom_resolvers custom_resolver_takes_precedence_over_builtin_resolvers
2481:  PASS [   0.418s] ( 114/3299) pacquet-cli::custom_resolvers failing_should_refresh_resolution_aborts_the_install
2482:  PASS [   0.109s] ( 115/3299) pacquet-cli::dedupe_direct_deps dedupe_off_by_default_keeps_shared_workspace_link
2483:  PASS [   0.299s] ( 116/3299) pacquet-cli::dedupe_direct_deps dedupe_direct_deps_disabled_keeps_per_project_symlinks
2484:  PASS [   0.185s] ( 117/3299) pacquet-cli::dedupe_direct_deps dedupe_under_shamefully_hoist
2485:  PASS [   0.539s] ( 118/3299) pacquet-cli::custom_resolvers should_refresh_resolution_forces_re_resolution_past_the_frozen_path
2486:  PASS [   0.152s] ( 119/3299) pacquet-cli::dedupe_direct_deps dedupes_direct_deps_against_workspace_root
2487:  PASS [   0.257s] ( 120/3299) pacquet-cli::dedupe_direct_deps dedupes_direct_dep_against_publicly_hoisted_root_dep
2488:  PASS [   0.093s] ( 121/3299) pacquet-cli::dedupe_direct_deps dedupes_link_deps_resolving_to_the_same_dir_via_different_segments
2489:  PASS [   0.164s] ( 122/3299) pacquet-cli::dedupe_direct_deps dedupes_direct_deps_with_frozen_lockfile
2490:  PASS [   0.135s] ( 123/3299) pacquet-cli::dedupe_direct_deps dedupes_only_overlapping_direct_deps
2491:  PASS [   0.221s] ( 124/3299) pacquet-cli::dedupe_injected_deps injected_leaf_workspace_dep_is_deduped_to_link
2492:  PASS [   0.138s] ( 125/3299) pacquet-cli::dedupe_injected_deps injected_workspace_dep_with_dedupe_off_writes_file_arm
2493:  PASS [   0.191s] ( 126/3299) pacquet-cli::dedupe_injected_deps injected_workspace_dep_with_dedupe_off_materialises_under_gvs
2494:  PASS [   0.058s] ( 127/3299) pacquet-cli::dlx dlx_errors_when_no_command_given
2495:  PASS [   0.052s] ( 128/3299) pacquet-cli::exec exec_errors_when_command_not_found
2496:  PASS [   0.026s] ( 129/3299) pacquet-cli::exec exec_errors_when_no_command_given
2497:  PASS [   0.036s] ( 130/3299) pacquet-cli::exec exec_passes_arguments_to_the_command
2498:  PASS [   0.031s] ( 131/3299) pacquet-cli::exec exec_propagates_nonzero_exit_code
2499:  PASS [   0.036s] ( 132/3299) pacquet-cli::exec exec_runs_binary_from_node_modules_bin
2500:  PASS [   0.038s] ( 133/3299) pacquet-cli::exec exec_shell_mode_runs_shell_command
2501:  PASS [   0.081s] ( 134/3299) pacquet-cli::exec exec_shell_mode_preserves_embedded_quotes
2502:  PASS [   0.035s] ( 135/3299) pacquet-cli::exec exec_stamps_pnpm_package_name_from_manifest
2503:  PASS [   0.069s] ( 136/3299) pacquet-cli::exec_recursive recursive_exec_bail_stops_at_first_failure
2504:  PASS [   0.083s] ( 137/3299) pacquet-cli::exec_recursive recursive_exec_no_bail_runs_all_then_fails
2505:  PASS [   0.049s] ( 138/3299) pacquet-cli::exec_recursive recursive_exec_report_summary_records_every_package_status
2506:  PASS [   0.058s] ( 139/3299) pacquet-cli::exec_recursive recursive_exec_runs_command_in_every_project
2507:  PASS [   0.404s] ( 140/3299) pacquet-cli::dlx dlx_installs_and_runs_packages_bin
2508:  PASS [   0.021s] ( 141/3299) pacquet-cli::hoist known_failures::combined_public_and_private_hoist_patterns_split_targets
2509:  PASS [   0.012s] ( 142/3299) pacquet-cli::hoist known_failures::hoist_by_alias
2510:  PASS [   0.023s] ( 143/3299) pacquet-cli::hoist known_failures::hoist_pattern_mismatch_throws_against_existing_modules_yaml
2511:  PASS [   0.028s] ( 144/3299) pacquet-cli::hoist known_failures::hoist_pattern_undefined_throws_against_hoisted_modules_yaml
2512:  PASS [   0.023s] ( 145/3299) pacquet-cli::hoist known_failures::hoist_workspace_packages_hoists_all_workspace_projects
2513:  PASS [   0.020s] ( 146/3299) pacquet-cli::hoist known_failures::hoisted_packages_dont_override_direct_dep_bins
2514:  PASS [   0.013s] ( 147/3299) pacquet-cli::hoist known_failures::hoisting_skips_broken_symlink_for_skipped_optional
2515:  PASS [   0.012s] ( 148/3299) pacquet-cli::hoist known_failures::modules_yaml_updated_on_prune_when_flattening
2516:  PASS [   0.013s] ( 149/3299) pacquet-cli::hoist known_failures::public_hoist_preserves_existing_root_directories
2517:  PASS [   0.014s] ( 150/3299) pacquet-cli::hoist known_failures::should_add_extra_node_paths_to_command_shims
2518:  PASS [   0.015s] ( 151/3299) pacquet-cli::hoist known_failures::should_hoist_correctly_peer_dependencies
2519:  PASS [   0.249s] ( 152/3299) pacquet-cli::hoist fresh_install_hoisted_node_linker_lands_real_directories
2520:  PASS [   0.016s] ( 153/3299) pacquet-cli::hoist known_failures::should_hoist_dependencies_repeat_install_preserves_map
2521:  PASS [   0.013s] ( 154/3299) pacquet-cli::hoist known_failures::should_not_add_extra_node_paths_when_extend_node_path_false
2522:  PASS [   0.012s] ( 155/3299) pacquet-cli::hoist known_failures::should_not_override_aliased_dependencies
2523:  PASS [   0.013s] ( 156/3299) pacquet-cli::hoist known_failures::should_not_override_root_packages_with_hoisted_deps
2524:  PASS [   0.011s] ( 157/3299) pacquet-cli::hoist known_failures::should_recreate_node_modules_with_hoisting
2525:  PASS [   0.014s] ( 158/3299) pacquet-cli::hoist known_failures::should_rehoist_after_pruning
2526:  PASS [   0.013s] ( 159/3299) pacquet-cli::hoist known_failures::should_rehoist_after_running_a_general_install
2527:  PASS [   0.013s] ( 160/3299) pacquet-cli::hoist known_failures::should_remove_aliased_hoisted_dependencies
2528:  PASS [   0.016s] ( 161/3299) pacquet-cli::hoist known_failures::should_rehoist_when_uninstalling_a_package
2529:  PASS [   0.010s] ( 162/3299) pacquet-cli::hoist known_failures::should_uninstall_correctly_peer_dependencies
2530:  PASS [   0.010s] ( 163/3299) pacquet-cli::hoist known_failures::should_remove_hoisted_dependencies
2531:  PASS [   0.011s] ( 164/3299) pacquet-cli::hoist known_failures::workspace_hoist_only_in_selected_projects_with_subdeps
2532:  PASS [   0.011s] ( 165/3299) pacquet-cli::hoist known_failures::workspace_hoist_all_to_virtual_store_node_modules
2533:  PASS [   0.011s] ( 166/3299) pacquet-cli::hoist known_failures::workspace_hoist_packages_in_selected_projects_tree
2534:  PASS [   0.011s] ( 167/3299) pacquet-cli::hoist known_failures::workspace_hoist_when_updating_one_project
2535:  PASS [   1.374s] ( 168/3299) pacquet-cli::hoist both_patterns_empty_produces_no_hoist_symlinks
2536:  PASS [   1.004s] ( 169/3299) pacquet-cli::hoist modules_yaml_public_hoist_pattern_matches_pnpm_default
2537:  PASS [   1.009s] ( 170/3299) pacquet-cli::hoist modules_yaml_records_hoisted_dependencies
2538:  PASS [   0.780s] ( 171/3299) pacquet-cli::hoist negation_pattern_excludes_alias_from_hoist
2539:  PASS [   0.833s] ( 172/3299) pacquet-cli::hoist private_hoist_default_pattern_hoists_transitives
2540:  PASS [   0.828s] ( 173/3299) pacquet-cli::hoist private_hoist_links_bins
2541:  PASS [   0.819s] ( 174/3299) pacquet-cli::hoist public_hoist_bin_is_linked_via_root_bin_dir
2542:  PASS [   0.888s] ( 175/3299) pacquet-cli::hoist public_hoist_star_hoists_to_root_node_modules
2543:  PASS [   0.960s] ( 176/3299) pacquet-cli::hoist private_hoist_pattern_filters_aliases
2544:  PASS [   0.818s] ( 177/3299) pacquet-cli::hoist shamefully_hoist_legacy_publicly_hoists_everything
2545:  PASS [   0.852s] ( 178/3299) pacquet-cli::hoist workspace_hoist_walks_every_importer
2546:  PASS [   1.289s] ( 179/3299) pacquet-cli::hoisted_node_linker external_dependencies_prevents_hoisting_to_root
2547:  PASS [   0.611s] ( 180/3299) pacquet-cli::hoisted_node_linker hoisting_limits_prevents_hoisting
2548:  PASS [   0.022s] ( 181/3299) pacquet-cli::hoisted_node_linker known_failures::adding_a_new_dependency_to_a_workspace_project
2549:  PASS [   0.013s] ( 182/3299) pacquet-cli::hoisted_node_linker known_failures::installing_same_package_with_alias_and_no_alias
2550:  PASS [   0.014s] ( 183/3299) pacquet-cli::hoisted_node_linker known_failures::linking_bins_of_local_projects
2551:  PASS [   0.017s] ( 184/3299) pacquet-cli::hoisted_node_linker known_failures::overwriting_existing_files_in_node_modules
2552:  PASS [   0.137s] ( 185/3299) pacquet-cli::hoisted_node_linker installing_with_hoisted_node_linker_and_no_lockfile
2553:  PASS [   0.020s] ( 186/3299) pacquet-cli::hoisted_node_linker known_failures::overwriting_is_positive_with_latest
2554:  PASS [   0.017s] ( 187/3299) pacquet-cli::hoisted_node_linker known_failures::package_that_is_peer_dependency_of_itself
2555:  PASS [   0.600s] ( 188/3299) pacquet-cli::hoisted_node_linker installing_with_hoisted_node_linker
2556:  PASS [   0.013s] ( 189/3299) pacquet-cli::hoisted_node_linker known_failures::run_pre_and_postinstall_scripts_and_link_bins
2557:  PASS [   0.015s] ( 190/3299) pacquet-cli::hoisted_node_linker known_failures::preserve_subdeps_on_update
2558:  PASS [   0.012s] ( 191/3299) pacquet-cli::hoisted_node_linker known_failures::running_install_scripts_in_workspace_without_root_project
2559:  PASS [   0.128s] ( 192/3299) pacquet-cli::init should_throw_on_existing_file
...

2573:  PASS [   0.094s] ( 206/3299) pacquet-cli::install install_surfaces_catalog_misconfiguration
2574:  PASS [   0.194s] ( 207/3299) pacquet-cli::install install_resolves_env_var_in_user_npmrc_registry
2575:  PASS [   0.271s] ( 208/3299) pacquet-cli::install peer_dependencies_resolve_from_aliased_subdependencies
2576:  PASS [   0.263s] ( 209/3299) pacquet-cli::install peer_dependency_prefers_highest_aliased_subdependency_version
2577:  PASS [   0.158s] ( 210/3299) pacquet-cli::install peer_dependency_prefers_highest_version_among_aliases_of_same_package
2578:  PASS [   0.108s] ( 211/3299) pacquet-cli::install peer_dependency_prefers_non_aliased_provider_over_alias
2579:  PASS [   0.132s] ( 212/3299) pacquet-cli::install peer_dependency_resolves_from_alias_that_differs_from_real_name
2580:  PASS [   0.160s] ( 213/3299) pacquet-cli::install peer_dependency_resolves_from_aliased_direct_dependency
2581:  PASS [   0.159s] ( 214/3299) pacquet-cli::install resolution_mode_highest_picks_highest_direct_version
2582:  PASS [   0.309s] ( 215/3299) pacquet-cli::install peer_shared_through_a_diamond_is_resolved_consistently
2583:  PASS [   0.149s] ( 216/3299) pacquet-cli::install resolution_mode_lowest_direct_picks_lowest_direct_version
2584:  PASS [   0.162s] ( 217/3299) pacquet-cli::install should_install_circular_dependencies
2585:  PASS [   0.281s] ( 218/3299) pacquet-cli::install should_install_dependencies
2586:  PASS [   0.265s] ( 219/3299) pacquet-cli::install should_install_exec_files
2587:  PASS [   0.236s] ( 220/3299) pacquet-cli::install should_install_index_files
2588:  PASS [   0.188s] ( 221/3299) pacquet-cli::lifecycle_scripts known_failures::headless_run_pre_postinstall_scripts
2589:  PASS [   0.209s] ( 222/3299) pacquet-cli::lifecycle_scripts known_failures::lifecycle_scripts_run_after_linking_root_deps
2590:  PASS [   0.540s] ( 223/3299) pacquet-cli::lifecycle_scripts known_failures::bins_linked_even_if_scripts_ignored
2591:  PASS [   0.297s] ( 224/3299) pacquet-cli::lifecycle_scripts known_failures::lifecycle_scripts_run_before_linking_bins
2592:  PASS [   0.220s] ( 225/3299) pacquet-cli::lifecycle_scripts known_failures::rebuild_after_allow_builds_changes
2593:  PASS [   0.147s] ( 226/3299) pacquet-cli::lifecycle_scripts known_failures::run_install_scripts
2594:  PASS [   0.204s] ( 227/3299) pacquet-cli::lifecycle_scripts known_failures::run_pre_and_postinstall_scripts
2595:  PASS [   0.314s] ( 228/3299) pacquet-cli::lifecycle_scripts known_failures::selectively_allow_scripts_by_allow_builds
2596:  PASS [   0.293s] ( 229/3299) pacquet-cli::lifecycle_scripts known_failures::selectively_allow_scripts_by_allow_builds_exact_versions
2597:  PASS [   1.560s] ( 230/3299) pacquet-cli::lifecycle_scripts known_failures::lifecycle_scripts_run_in_dependency_order
2598:  PASS [   0.133s] ( 231/3299) pacquet-cli::lifecycle_scripts project_scripts::add_does_not_run_project_lifecycle_scripts
2599:  PASS [   0.260s] ( 232/3299) pacquet-cli::lifecycle_scripts known_failures::selectively_ignore_scripts_by_allow_builds
2600:  PASS [   0.130s] ( 233/3299) pacquet-cli::lifecycle_scripts project_scripts::failing_project_script_fails_the_install
2601:  PASS [   0.195s] ( 234/3299) pacquet-cli::lifecycle_scripts project_scripts::project_script_sees_init_cwd
2602:  PASS [   0.463s] ( 235/3299) pacquet-cli::lifecycle_scripts project_scripts::runs_project_lifecycle_scripts_in_order
2603:  PASS [   0.348s] ( 236/3299) pacquet-cli::lifecycle_scripts project_scripts::runs_scripts_when_project_name_differs_from_directory
2604:  PASS [   0.302s] ( 237/3299) pacquet-cli::lockfile_only frozen_lockfile_only_rejects_a_stale_lockfile
2605:  PASS [   1.038s] ( 238/3299) pacquet-cli::lifecycle_scripts project_scripts::runs_project_lifecycle_scripts_on_frozen_install
2606:  PASS [   0.067s] ( 239/3299) pacquet-cli::lockfile_only lockfile_false_with_lockfile_only_is_a_config_conflict
2607:  PASS [   0.230s] ( 240/3299) pacquet-cli::lockfile_only frozen_lockfile_only_succeeds_without_materializing_when_fresh
2608:  PASS [   0.174s] ( 241/3299) pacquet-cli::lockfile_only lockfile_only_updates_importers_when_a_project_is_added
2609:  PASS [   6.824s] ( 242/3299) pacquet-cli::hoisted_node_linker peer_dependencies_installed_with_auto_install_peers
2610:  PASS [   0.314s] ( 243/3299) pacquet-cli::lockfile_only writes_lockfile_without_downloading_or_linking
2611:  PASS [   0.306s] ( 244/3299) pacquet-cli::lockfile_resolution_reuse reinstalling_an_unchanged_manifest_keeps_the_lockfile_byte_identical
2612:  PASS [   0.208s] ( 245/3299) pacquet-cli::lockfile_resolution_reuse reuses_unchanged_subtree_without_re_resolving_from_the_registry
2613:  PASS [   0.584s] ( 246/3299) pacquet-cli::lockfile_resolution_reuse a_reused_tree_is_structurally_identical_to_a_fresh_resolve
2614:  PASS [   0.320s] ( 247/3299) pacquet-cli::lockfile_verification install_fails_under_huge_minimum_release_age
2615:  PASS [   0.241s] ( 248/3299) pacquet-cli::outdated outdated_compatible_ignores_out_of_range_releases
2616:  PASS [   0.087s] ( 249/3299) pacquet-cli::outdated outdated_json_empty_when_up_to_date
2617:  PASS [   0.123s] ( 250/3299) pacquet-cli::outdated outdated_json_format
2618:  PASS [   0.075s] ( 251/3299) pacquet-cli::outdated outdated_list_format
2619:  PASS [   0.094s] ( 252/3299) pacquet-cli::outdated outdated_long_shows_deprecation_details
2620:  PASS [   0.047s] ( 253/3299) pacquet-cli::outdated outdated_no_dependencies_no_lockfile_is_empty
2621:  PASS [   0.105s] ( 254/3299) pacquet-cli::outdated outdated_npm_alias_reports_real_name
2622:  PASS [   0.087s] ( 255/3299) pacquet-cli::outdated outdated_pattern_filters_dependencies
2623:  PASS [   0.102s] ( 256/3299) pacquet-cli::outdated outdated_prod_dev_filtering
2624:  PASS [   0.099s] ( 257/3299) pacquet-cli::outdated outdated_recursive_is_rejected
2625:  PASS [   0.107s] ( 258/3299) pacquet-cli::outdated outdated_reports_deprecated_package
2626:  PASS [   0.098s] ( 259/3299) pacquet-cli::outdated outdated_reports_newer_version
2627:  PASS [   0.113s] ( 260/3299) pacquet-cli::outdated outdated_up_to_date_exits_zero
2628:  PASS [   0.057s] ( 261/3299) pacquet-cli::outdated outdated_without_lockfile_errors
2629:  PASS [   0.947s] ( 262/3299) pacquet-cli::pnpm_compatibility pnpm_reads_pacquet_written_rows
2630:  PASS [   0.791s] ( 263/3299) pacquet-cli::pnpm_compatibility same_file_structure
2631:  PASS [   0.724s] ( 264/3299) pacquet-cli::pnpm_compatibility same_global_virtual_store_layout_diamond
2632:  PASS [   0.790s] ( 265/3299) pacquet-cli::pnpm_compatibility same_global_virtual_store_layout_pure_js
2633:  PASS [   0.871s] ( 266/3299) pacquet-cli::pnpm_compatibility same_index_file_contents
2634:  PASS [   0.656s] ( 267/3299) pacquet-cli::pnpr_install frozen_install_via_pnpr_verifies_the_local_lockfile_without_resolving_or_redownloading
2635:  PASS [   0.142s] ( 268/3299) pacquet-cli::pnpr_install install_via_pnpr_links_node_modules
2636:  PASS [   0.077s] ( 269/3299) pacquet-cli::pnpr_install install_via_pnpr_lockfile_only_writes_lockfile_without_linking
2637:  PASS [   0.377s] ( 270/3299) pacquet-cli::remove should_accept_aliases
2638:  PASS [   0.052s] ( 271/3299) pacquet-cli::remove should_fail_when_dependency_is_missing
2639:  PASS [   0.046s] ( 272/3299) pacquet-cli::remove should_fail_when_no_package_specified
2640:  PASS [   0.104s] ( 273/3299) pacquet-cli::remove should_remove_from_package_json
2641:  PASS [   0.104s] ( 274/3299) pacquet-cli::remove should_remove_only_from_targeted_field
2642:  PASS [   0.045s] ( 275/3299) pacquet-cli::remove should_report_project_has_no_dependencies
2643:  PASS [   0.031s] ( 276/3299) pacquet-cli::run run_echoes_script_to_stderr_when_reporter_not_silent
2644:  PASS [   0.023s] ( 277/3299) pacquet-cli::run run_empty_start_script_hits_server_js_guard
2645:  PASS [   0.031s] ( 278/3299) pacquet-cli::run run_errors_on_missing_script_without_if_present
2646:  PASS [   0.030s] ( 279/3299) pacquet-cli::run run_executes_declared_script
2647:  PASS [   0.027s] ( 280/3299) pacquet-cli::run run_failing_test_script_prints_test_failed_message
2648:  PASS [   0.029s] ( 281/3299) pacquet-cli::run run_finds_local_bin_on_path
2649:  PASS [   0.014s] ( 282/3299) pacquet-cli::run run_lists_scripts_when_no_name_given
2650:  PASS [   0.022s] ( 283/3299) pacquet-cli::run run_passes_extra_arguments_to_the_script
2651:  PASS [   0.049s] ( 284/3299) pacquet-cli::run run_preserves_embedded_quotes_in_script
2652:  PASS [   0.023s] ( 285/3299) pacquet-cli::run run_propagates_failing_script_exit_code
2653:  PASS [   0.042s] ( 286/3299) pacquet-cli::run run_runs_pre_and_post_when_enabled
2654:  PASS [   0.034s] ( 287/3299) pacquet-cli::run run_start_falls_back_to_node_server_js_when_present
2655:  PASS [   0.018s] ( 288/3299) pacquet-cli::run run_start_without_script_or_server_errors
2656:  PASS [   0.019s] ( 289/3299) pacquet-cli::run run_with_if_present_is_a_noop_for_missing_script
2657:  PASS [   0.040s] ( 290/3299) pacquet-cli::run_recursive recursive_run_bail_without_report_summary_writes_no_file
2658:  PASS [   0.034s] ( 291/3299) pacquet-cli::run_recursive recursive_run_bail_writes_summary_then_stops_at_first_failure
2659:  PASS [   0.055s] ( 292/3299) pacquet-cli::run_recursive recursive_run_errors_when_no_package_has_the_script
2660:  PASS [   0.078s] ( 293/3299) pacquet-cli::run_recursive recursive_run_executes_script_in_every_project
2661:  PASS [   0.024s] ( 294/3299) pacquet-cli::run_recursive recursive_run_if_present_is_a_noop_when_no_package_has_the_script
2662:  PASS [   0.021s] ( 295/3299) pacquet-cli::run_recursive recursive_run_missing_hidden_script_reports_no_script_not_hidden
2663:  PASS [   0.031s] ( 296/3299) pacquet-cli::run_recursive recursive_run_recursion_guard_skips_originating_project
2664:  PASS [   0.019s] ( 297/3299) pacquet-cli::run_recursive recursive_run_rejects_hidden_script_name
2665:  PASS [   0.075s] ( 298/3299) pacquet-cli::run_recursive recursive_run_report_summary_records_every_package_status
2666:  PASS [   0.047s] ( 299/3299) pacquet-cli::run_recursive recursive_run_resolves_local_bin_on_path_per_project
2667:  PASS [   0.077s] ( 300/3299) pacquet-cli::run_recursive recursive_run_resume_from_starts_at_the_given_package
2668:  PASS [   0.028s] ( 301/3299) pacquet-cli::run_recursive recursive_run_resume_from_unknown_package_errors
2669:  PASS [   0.061s] ( 302/3299) pacquet-cli::run_recursive recursive_run_runs_pre_and_post_when_enabled
2670:  PASS [   0.041s] ( 303/3299) pacquet-cli::run_recursive recursive_run_skips_empty_script_body
2671:  PASS [   0.020s] ( 304/3299) pacquet-cli::run_recursive recursive_run_without_script_name_errors_with_script_name_is_required
2672:  PASS [   0.033s] ( 305/3299) pacquet-cli::store store_path_should_return_store_dir_from_pnpm_workspace_yaml
2673:  PASS [   0.449s] ( 306/3299) pacquet-cli::tarball_url_dependency remote_tarball_integrity_survives_unrelated_install
2674:  PASS [   0.119s] ( 307/3299) pacquet-cli::tarball_url_dependency remote_tarball_reresolves_from_warm_store_without_refetch
2675:  PASS [   0.246s] ( 308/3299) pacquet-cli::update update_aliases_work
2676:  PASS [   0.090s] ( 309/3299) pacquet-cli::update update_bumps_within_range
2677:  PASS [   0.121s] ( 310/3299) pacquet-cli::update update_compatible_all_direct_ignored_still_updates_indirect
2678:  PASS [   0.145s] ( 311/3299) pacquet-cli::update update_compatible_honors_ignore_dependencies
2679:  PASS [   0.098s] ( 312/3299) pacquet-cli::update update_depth_zero_unknown_package_errors
2680:  PASS [   0.105s] ( 313/3299) pacquet-cli::update update_latest_all_direct_ignored_does_not_touch_indirect
2681:  PASS [   0.110s] ( 314/3299) pacquet-cli::update update_latest_all_ignored_is_noop
2682:  PASS [   0.117s] ( 315/3299) pacquet-cli::update update_latest_honors_ignore_dependencies
2683:  PASS [   0.115s] ( 316/3299) pacquet-cli::update update_latest_no_save_keeps_manifest
2684:  PASS [   0.116s] ( 317/3299) pacquet-cli::update update_latest_rewrites_manifest
2685:  PASS [   0.098s] ( 318/3299) pacquet-cli::update update_latest_save_exact
2686:  PASS [   0.117s] ( 319/3299) pacquet-cli::update update_latest_with_negation_selector
2687:  PASS [   0.148s] ( 320/3299) pacquet-cli::update update_latest_with_selector_is_scoped
2688:  PASS [   0.124s] ( 321/3299) pacquet-cli::update update_latest_with_spec_is_rejected
2689:  PASS [   0.148s] ( 322/3299) pacquet-cli::update update_prod_scopes_and_honors_ignore
2690:  PASS [   0.053s] ( 323/3299) pacquet-cli::update update_strict_catalog_range_mismatch_errors
2691:  PASS [   0.322s] ( 324/3299) pacquet-cli::workspace_install fresh_resolve_walks_every_workspace_importer
...

2712:  PASS [   0.008s] ( 345/3299) pacquet-cmd-shim bin_resolver::tests::no_bin_field_returns_empty
2713:  PASS [   0.008s] ( 346/3299) pacquet-cmd-shim bin_resolver::tests::pkg_owns_bin_default_rule
2714:  PASS [   0.008s] ( 347/3299) pacquet-cmd-shim bin_resolver::tests::pkg_owns_bin_overrides
2715:  PASS [   0.009s] ( 348/3299) pacquet-cmd-shim bin_resolver::tests::rejects_path_traversal_outside_package_root
2716:  PASS [   0.010s] ( 349/3299) pacquet-cmd-shim bin_resolver::tests::rejects_unsafe_bin_names
2717:  PASS [   0.011s] ( 350/3299) pacquet-cmd-shim bin_resolver::tests::reserved_relative_bin_names_are_rejected
2718:  PASS [   0.010s] ( 351/3299) pacquet-cmd-shim bin_resolver::tests::scoped_bin_name_strips_scope_prefix
2719:  PASS [   0.011s] ( 352/3299) pacquet-cmd-shim bin_resolver::tests::skip_dangerous_bin_locations
2720:  PASS [   0.013s] ( 353/3299) pacquet-cmd-shim bin_resolver::tests::skip_dangerous_bin_names
2721:  PASS [   0.010s] ( 354/3299) pacquet-cmd-shim bin_resolver::tests::skip_scoped_bin_names_with_path_traversal
2722:  PASS [   0.012s] ( 355/3299) pacquet-cmd-shim link_bins::tests::direct_origin_wins_over_hoisted_regardless_of_lexical
2723:  PASS [   0.007s] ( 356/3299) pacquet-cmd-shim link_bins::tests::hoisted_origin_loses_to_existing_direct
2724:  PASS [   0.007s] ( 357/3299) pacquet-cmd-shim link_bins::tests::lexical_compare_breaks_tie_when_neither_owns
2725:  PASS [   0.006s] ( 358/3299) pacquet-cmd-shim link_bins::tests::link_bins_handles_missing_modules_dir
2726:  PASS [   0.007s] ( 359/3299) pacquet-cmd-shim link_bins::tests::link_bins_of_packages_no_op_when_no_bins
2727:  PASS [   0.007s] ( 360/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_chmod_error_via_di
2728:  PASS [   0.006s] ( 361/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_create_bin_dir_error_via_di
2729:  PASS [   0.007s] ( 362/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_modules_dir_read_error_via_di
2730:  PASS [   0.006s] ( 363/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_parse_manifest_error
2731:  PASS [   0.006s] ( 364/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_probe_shim_source_error_via_di
2732:  PASS [   0.006s] ( 365/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_read_manifest_error_via_di
2733:  PASS [   0.006s] ( 366/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_target_chmod_error_via_di
2734:  PASS [   0.006s] ( 367/3299) pacquet-cmd-shim link_bins::tests::link_bins_propagates_write_shim_error_via_di
2735:  PASS [   0.007s] ( 368/3299) pacquet-cmd-shim link_bins::tests::link_bins_skips_existing_shim_with_matching_marker
...

2750:  PASS [   0.008s] ( 383/3299) pacquet-cmd-shim shim::tests::generate_pwsh_shim_matches_pnpm_template
2751:  PASS [   0.008s] ( 384/3299) pacquet-cmd-shim shim::tests::generate_sh_shim_emits_direct_exec_when_no_runtime
2752:  PASS [   0.008s] ( 385/3299) pacquet-cmd-shim shim::tests::generate_sh_shim_matches_pnpm_typical_case
2753:  PASS [   0.008s] ( 386/3299) pacquet-cmd-shim shim::tests::generate_sh_shim_threads_args_when_prog_is_none
2754:  PASS [   0.008s] ( 387/3299) pacquet-cmd-shim shim::tests::generate_sh_shim_uses_absolute_target_when_no_common_prefix
2755:  PASS [   0.008s] ( 388/3299) pacquet-cmd-shim shim::tests::is_shim_pointing_at_round_trips_through_marker
2756:  PASS [   0.008s] ( 389/3299) pacquet-cmd-shim shim::tests::lexical_normalize_drops_curdir_components
2757:  PASS [   0.008s] ( 390/3299) pacquet-cmd-shim shim::tests::lexical_normalize_drops_curdir_segments_directly
2758:  PASS [   0.009s] ( 391/3299) pacquet-cmd-shim shim::tests::lexical_normalize_keeps_leading_parent_segments
2759:  PASS [   0.010s] ( 392/3299) pacquet-cmd-shim shim::tests::parse_shebang_from_bytes_handles_crlf_and_lossy_utf8
2760:  PASS [   0.012s] ( 393/3299) pacquet-cmd-shim shim::tests::parse_shebang_returns_none_for_empty_prog
2761:  PASS [   0.010s] ( 394/3299) pacquet-cmd-shim shim::tests::parses_direct_shebang
2762:  PASS [   0.010s] ( 395/3299) pacquet-cmd-shim shim::tests::parses_env_dash_s_shebang
2763:  PASS [   0.010s] ( 396/3299) pacquet-cmd-shim shim::tests::parses_env_node_shebang
2764:  PASS [   0.009s] ( 397/3299) pacquet-cmd-shim shim::tests::read_head_filled_accumulates_short_reads_from_fake
2765:  PASS [   0.008s] ( 398/3299) pacquet-cmd-shim shim::tests::read_head_filled_propagates_io_error_from_fake
2766:  PASS [   0.013s] ( 399/3299) pacquet-cmd-shim shim::tests::read_head_filled_real_fs_long_file_fills_buffer
2767:  PASS [   0.008s] ( 400/3299) pacquet-cmd-shim shim::tests::read_head_filled_real_fs_short_file_returns_partial
2768:  PASS [   0.008s] ( 401/3299) pacquet-cmd-shim shim::tests::read_head_filled_terminates_on_zero_byte_read_from_fake
2769:  PASS [   0.008s] ( 402/3299) pacquet-cmd-shim shim::tests::real_fs_read_head_propagates_not_found
2770:  PASS [   0.009s] ( 403/3299) pacquet-cmd-shim shim::tests::real_fs_read_head_reads_up_to_buffer_size
2771:  PASS [   0.008s] ( 404/3299) pacquet-cmd-shim shim::tests::rejects_non_shebang_lines
2772:  PASS [   0.008s] ( 405/3299) pacquet-cmd-shim shim::tests::relative_target_collapses_to_dot_when_paths_share_dir
2773:  PASS [   0.008s] ( 406/3299) pacquet-cmd-shim shim::tests::relative_target_traverses_into_sibling_package
2774:  PASS [   0.008s] ( 407/3299) pacquet-cmd-shim shim::tests::search_script_runtime_falls_back_to_extension
2775:  PASS [   0.007s] ( 408/3299) pacquet-cmd-shim shim::tests::search_script_runtime_propagates_non_not_found_io_errors
2776:  PASS [   0.008s] ( 409/3299) pacquet-cmd-shim shim::tests::search_script_runtime_reads_shebang_from_real_file
...

2825:  PASS [   0.007s] ( 458/3299) pacquet-config npmrc_auth::tests::cafile_not_found_is_silently_treated_as_unset
2826:  PASS [   0.007s] ( 459/3299) pacquet-config npmrc_auth::tests::cafile_reads_and_splits_into_per_cert_pems
2827:  PASS [   0.007s] ( 460/3299) pacquet-config npmrc_auth::tests::cafile_relative_path_loads_ca_from_disk_via_apply
2828:  PASS [   0.007s] ( 461/3299) pacquet-config npmrc_auth::tests::cafile_relative_path_resolves_against_npmrc_dir
2829:  PASS [   0.007s] ( 462/3299) pacquet-config npmrc_auth::tests::cafile_trailing_garbage_is_preserved_for_downstream_parser
2830:  PASS [   0.007s] ( 463/3299) pacquet-config npmrc_auth::tests::cascade_env_fallback_only_fires_when_npmrc_unset
2831:  PASS [   0.009s] ( 464/3299) pacquet-config npmrc_auth::tests::cascade_env_var_lowercase_lookup
2832:  PASS [   0.010s] ( 465/3299) pacquet-config npmrc_auth::tests::cascade_explicit_https_proxy_wins_over_legacy_key
2833:  PASS [   0.010s] ( 466/3299) pacquet-config npmrc_auth::tests::cascade_http_proxy_env_fallback_chain_proxy_var
2834:  PASS [   0.014s] ( 467/3299) pacquet-config npmrc_auth::tests::cascade_http_proxy_uses_resolved_https_proxy
2835:  PASS [   0.013s] ( 468/3299) pacquet-config npmrc_auth::tests::cascade_https_proxy_uses_legacy_proxy_when_unset
2836:  PASS [   0.013s] ( 469/3299) pacquet-config npmrc_auth::tests::cascade_no_proxy_comma_list_trimmed
2837:  PASS [   0.018s] ( 470/3299) pacquet-config npmrc_auth::tests::cascade_no_proxy_true_literal_becomes_bypass_variant
2838:  PASS [   0.011s] ( 471/3299) pacquet-config npmrc_auth::tests::cascade_npmrc_value_wins_over_env
2839:  PASS [   0.017s] ( 472/3299) pacquet-config npmrc_auth::tests::defaults_leave_tls_config_empty
2840:  PASS [   0.011s] ( 473/3299) pacquet-config npmrc_auth::tests::env_replace_failure_on_key_warns_and_drops_unresolved_to_empty
2841:  PASS [   0.013s] ( 474/3299) pacquet-config npmrc_auth::tests::env_replace_failure_preserves_resolved_and_default_placeholders
2842:  PASS [   0.016s] ( 475/3299) pacquet-config npmrc_auth::tests::env_replace_failure_warns_and_drops_unresolved_to_empty
2843:  PASS [   0.010s] ( 476/3299) pacquet-config npmrc_auth::tests::env_replace_substitutes_token
...

2904:  PASS [   0.011s] ( 537/3299) pacquet-config store_path::tests::resolve_store_dir_same_volume_uses_home_default
2905:  PASS [   0.012s] ( 538/3299) pacquet-config tests::auth_ini_without_registry_falls_back_to_npmjs_default
2906:  PASS [   0.009s] ( 539/3299) pacquet-config tests::empty_npm_config_workspace_dir_falls_through
2907:  PASS [   0.008s] ( 540/3299) pacquet-config tests::explicit_url_scoped_creds_pass_through
2908:  PASS [   0.010s] ( 541/3299) pacquet-config tests::fetch_retries_defaults_match_pnpm
2909:  PASS [   0.009s] ( 542/3299) pacquet-config tests::fetch_retry_keys_in_npmrc_are_ignored
2910:  PASS [   0.012s] ( 543/3299) pacquet-config tests::global_config_npmrc_auth_file_expands_env
2911:  PASS [   0.009s] ( 544/3299) pacquet-config tests::global_config_yaml_enables_gvs
2912:  PASS [   0.008s] ( 545/3299) pacquet-config tests::global_config_yaml_request_destination_values_expand_env
2913:  PASS [   0.009s] ( 546/3299) pacquet-config tests::global_config_yaml_workspace_only_keys_are_ignored
2914:  PASS [   0.010s] ( 547/3299) pacquet-config tests::global_virtual_store_dir_survives_workspace_yaml_anchor
2915:  PASS [   0.010s] ( 548/3299) pacquet-config tests::gvs_default_is_off_and_paths_derive_cleanly
2916:  PASS [   0.010s] ( 549/3299) pacquet-config tests::gvs_disabled_keeps_project_local_virtual_store
2917:  PASS [   0.011s] ( 550/3299) pacquet-config tests::gvs_user_pinned_virtual_store_routes_into_global_virtual_store_dir
2918:  PASS [   0.009s] ( 551/3299) pacquet-config tests::have_default_values
2919:  PASS [   0.009s] ( 552/3299) pacquet-config tests::invalid_workspace_yaml_propagates_error
2920:  PASS [   0.009s] ( 553/3299) pacquet-config tests::network_settings_defaults_match_pnpm
...

2951:  PASS [   0.014s] ( 584/3299) pacquet-config tests::url_scoped_env_auth_prefix_is_case_insensitive_end_to_end
2952:  PASS [   0.019s] ( 585/3299) pacquet-config tests::user_auth_token_pins_to_its_own_file_registry
2953:  PASS [   0.012s] ( 586/3299) pacquet-config tests::user_basic_auth_pins_to_its_own_file_registry
2954:  PASS [   0.012s] ( 587/3299) pacquet-config tests::user_cert_key_pin_to_its_own_file_registry
2955:  PASS [   0.011s] ( 588/3299) pacquet-config tests::user_username_password_pins_to_its_own_file_registry
2956:  PASS [   0.010s] ( 589/3299) pacquet-config tests::virtual_store_dir_max_length_defaults_to_120
2957:  PASS [   0.011s] ( 590/3299) pacquet-config tests::virtual_store_dir_max_length_env_var_overrides_yaml
2958:  PASS [   0.011s] ( 591/3299) pacquet-config tests::virtual_store_dir_max_length_from_workspace_yaml
2959:  PASS [   0.011s] ( 592/3299) pacquet-config tests::workspace_subdir_anchors_modules_at_workspace_root
2960:  PASS [   0.011s] ( 593/3299) pacquet-config tests::workspace_subdir_reads_workspace_root_npmrc
2961:  PASS [   0.014s] ( 594/3299) pacquet-config tests::workspace_unscoped_creds_pin_to_workspace_registry
2962:  PASS [   0.012s] ( 595/3299) pacquet-config tests::yaml_global_virtual_store_dir_wins_over_derivation
2963:  PASS [   0.009s] ( 596/3299) pacquet-config version_policy::tests::bare_name_expands_verbatim
2964:  PASS [   0.009s] ( 597/3299) pacquet-config version_policy::tests::create_policy_exact_version_match_returns_versions
2965:  PASS [   0.009s] ( 598/3299) pacquet-config version_policy::tests::create_policy_first_matching_rule_wins
2966:  PASS [   0.008s] ( 599/3299) pacquet-config version_policy::tests::create_policy_range_specifier_in_version_errors
2967:  PASS [   0.009s] ( 600/3299) pacquet-config version_policy::tests::create_policy_scoped_bare_name_returns_any_version
2968:  PASS [   0.008s] ( 601/3299) pacquet-config version_policy::tests::create_policy_scoped_name_at_exact_version
2969:  PASS [   0.009s] ( 602/3299) pacquet-config version_policy::tests::create_policy_version_union_handles_whitespace
2970:  PASS [   0.008s] ( 603/3299) pacquet-config version_policy::tests::create_policy_version_union_scoped
2971:  PASS [   0.008s] ( 604/3299) pacquet-config version_policy::tests::create_policy_version_union_unscoped
2972:  PASS [   0.007s] ( 605/3299) pacquet-config version_policy::tests::create_policy_wildcard_name_matches_via_matcher
2973:  PASS [   0.006s] ( 606/3299) pacquet-config version_policy::tests::create_policy_wildcard_with_version_errors
2974:  PASS [   0.008s] ( 607/3299) pacquet-config version_policy::tests::duplicate_specs_collapse_in_set
2975:  PASS [   0.007s] ( 608/3299) pacquet-config version_policy::tests::empty_input_yields_empty_set
2976:  PASS [   0.009s] ( 609/3299) pacquet-config version_policy::tests::mixed_valid_invalid_union_errors
2977:  PASS [   0.012s] ( 610/3299) pacquet-config version_policy::tests::name_at_exact_version_expands_to_one_literal
2978:  PASS [   0.014s] ( 611/3299) pacquet-config version_policy::tests::name_with_wildcard_alone_is_kept_verbatim
2979:  PASS [   0.015s] ( 612/3299) pacquet-config version_policy::tests::non_semver_version_in_union_errors
2980:  PASS [   0.014s] ( 613/3299) pacquet-config version_policy::tests::scoped_bare_name_expands_verbatim
2981:  PASS [   0.012s] ( 614/3299) pacquet-config version_policy::tests::scoped_name_at_exact_version_expands_to_one_literal
2982:  PASS [   0.016s] ( 615/3299) pacquet-config version_policy::tests::version_union_expands_into_separate_literals
2983:  PASS [   0.010s] ( 616/3299) pacquet-config version_policy::tests::version_union_trims_whitespace_around_each_version
2984:  PASS [   0.010s] ( 617/3299) pacquet-config version_policy::tests::wildcard_name_with_version_errors
2985:  PASS [   0.010s] ( 618/3299) pacquet-config workspace_yaml::tests::apply_leaves_unset_fields_alone
2986:  PASS [   0.010s] ( 619/3299) pacquet-config workspace_yaml::tests::apply_overrides_npmrc_defaults
2987:  PASS [   0.010s] ( 620/3299) pacquet-config workspace_yaml::tests::apply_pushes_patched_dependencies_and_workspace_dir
2988:  PASS [   0.010s] ( 621/3299) pacquet-config workspace_yaml::tests::apply_replaces_git_shallow_hosts_defaults
2989:  PASS [   0.010s] ( 622/3299) pacquet-config workspace_yaml::tests::apply_resolves_relative_paths_against_base_dir
2990:  PASS [   0.011s] ( 623/3299) pacquet-config workspace_yaml::tests::catalog_mode_yaml_values_round_trip
2991:  PASS [   0.011s] ( 624/3299) pacquet-config workspace_yaml::tests::config_dependencies_cleared_as_workspace_only_field
2992:  PASS [   0.010s] ( 625/3299) pacquet-config workspace_yaml::tests::empty_overrides_clears_prior_non_empty_assignment
2993:  PASS [   0.010s] ( 626/3299) pacquet-config workspace_yaml::tests::empty_overrides_map_collapses_to_none
2994:  PASS [   0.010s] ( 627/3299) pacquet-config workspace_yaml::tests::empty_package_extensions_map_collapses_to_none
2995:  PASS [   0.009s] ( 628/3299) pacquet-config workspace_yaml::tests::expands_env_vars_inside_non_registry_workspace_values
2996:  PASS [   0.008s] ( 629/3299) pacquet-config workspace_yaml::tests::find_propagates_parse_yaml_error_on_malformed_manifest
2997:  PASS [   0.008s] ( 630/3299) pacquet-config workspace_yaml::tests::find_propagates_when_manifest_path_is_a_directory
...

3050:  PASS [   0.010s] ( 683/3299) pacquet-config workspace_yaml::tests::rejects_invalid_scripts_prepend_node_path
3051:  PASS [   0.010s] ( 684/3299) pacquet-config workspace_yaml::tests::resolution_mode_yaml_values_round_trip
3052:  PASS [   0.011s] ( 685/3299) pacquet-config workspace_yaml::tests::script_shell_and_node_options_null_clears_inherited_value
3053:  PASS [   0.010s] ( 686/3299) pacquet-config workspace_yaml::tests::side_effects_cache_gates_truth_table
3054:  PASS [   0.011s] ( 687/3299) pacquet-config workspace_yaml::tests::swallows_unknown_top_level_keys
3055:  PASS [   0.011s] ( 688/3299) pacquet-config w...

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.

2 participants