Skip to content

Share directory manifest loading and local spec satisfaction across resolver, freshness, and repeat-install #159

Closed
pnpm/pnpm
#17133

Description

@zkochan

Found by the defect-hotspots skill on 2026-10-19 over 90 days of main (c43ba554b7), following up on #145 and #147.

Loop: Injected workspace dependencies & pnpm deploy workspace-to-file: synthesis (23 fixes, 4 regressions)

Property. Every consumer of a directory-resolved (file:) workspace package—the resolver, --frozen-lockfile freshness verification, the repeat-install fast path, pnpm deploy lockfile synthesis, and the four injected-copy sync paths—derives the same manifest, child/peer set, and packed file tree.

Recent members.

Remaining Flaws after #145 & #147

  1. Manifest resolution & hooking is still duplicated in v12. unhooked_manifest, manifest_of_project_publishing_from, and read_and_override_manifest in pnpm/crates/package-manager/src/install/lockfile_freshness/directory_deps.rs and hooked_injected_manifests in pnpm/crates/package-manager/src/install/lockfile_freshness/injected_manifests.rs re-implement how a local directory's package.json is located (in-memory vs. publishConfig.directory project manifest vs. <dir>/package.json on disk vs. { name: dirname } fallback) and hooked (packageExtensions → readPackage → VersionsOverrider), separately from pnpm-resolving-local-resolver and pnpm-resolving-deps-resolver.
  2. Duplicate local/workspace/npm: specifier satisfaction parsers. pnpm/crates/package-manager/src/install/lockfile_freshness/directory_deps/spec.rs (file_or_link_spec_satisfies, workspace_spec_satisfies, parse_workspace_range, parse_npm_spec) and pnpm/crates/package-manager/src/optimistic_repeat_install/manifest_agreement.rs (linked_dep_is_up_to_date, version_range_of_spec, semver_satisfies_loosely) each implement their own workspace: and npm: specifier parsers.
  3. Dedicated-lockfile repeat-install bail-out. injected_deps_block_fast_path in pnpm/crates/package-manager/src/optimistic_repeat_install/local_file_deps.rs unconditionally skips the repeat-install fast path whenever !config.shared_workspace_lockfile and lockfile.injected_dependencies(...) is non-empty, instead of recording injected directory manifest digests in .pnpm-workspace-state-v1.json.
  4. pnpm deploy synthesizes file: lockfile entries and binds peers by hand. pnpm/crates/cli/src/cli_args/deploy/lockfile.rs + deploy/peers.rs (v12) and pnpm11/releasing/commands/src/deploy/createDeployFiles.ts + deployPackageGraph.ts (v11) convert linked workspace importers into file: snapshots with a custom graph/peer binder, without verifying that the resulting deployed lockfile passes --frozen-lockfile.

Design Change

  1. Extract directory manifest lookup + packageExtensions/readPackage/VersionsOverrider hooking and workspace:/file:/link:/npm: specifier satisfaction into shared helpers used by the resolver, directory_deps.rs, and manifest_agreement.rs.
  2. Record lockfile.injected_dependencies(...) target manifest digests in Validation (pnpm/crates/package-manager/src/optimistic_repeat_install/validation.rs) when sharedWorkspaceLockfile: false and delete injected_deps_block_fast_path.
  3. Add a post-deploy --frozen-lockfile verification assertion to pnpm deploy tests across both stacks.

Tests


Written by an agent (Antigravity, Gemini 4 Argon).

Activity

  1. zkochan commented on Oct 19, 2026

    @zkochan
    MemberAuthor

    Opened pnpm/pnpm#17133 to address this:

    • Extracted pnpm_package_manifest::publishes_from_directory so resolving-local-resolver::find_parent_publish_manifest and lockfile_freshness::directory_deps::manifest_of_project_publishing_from share the same publishConfig.directory / root.package.json check, and allowed file: directory dependencies (declared_as_file) outside workspace_root to walk ancestor manifests during lockfile freshness verification.
    • Shared is_declared_local_directory and spec_target_and_range across lockfile_freshness::directory_deps and optimistic_repeat_install::manifest_agreement, fixing aliased workspace specifiers (workspace:<pkg>@<range>) in linked_dep_is_up_to_date and normalizing empty trailing @ ranges in parse_npm_spec.
    • Added mark_importers_of_unproven_directory_deps in optimistic_repeat_install::freshness::drift so Proven importers that have a VersionPart::File dependency on an edited workspace project are marked ManifestChanged and re-verified on repeat install.
    • Added matrix tests across install, install --frozen-lockfile, and optimistic repeat install.

    Written by an agent (Antigravity, Gemini 4 Argon).

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions