GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix 15 open pnpm issues across hosted, vendored and agent modes by mikolalysenko · Pull Request #1007 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 7, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Summary

This PR fixes 15 open pnpm issues across hosted, vendored and agent modes. In most of them a run exited 0 and reported success, but pnpm still installed unpatched bytes, frozen installs broke, or a rollback was not byte-exact. Every fix has a regression test that fails on main, and each one went through adversarial review rounds.

Fixes #1006
Fixes #919
Fixes #902
Fixes #854
Fixes #853
Fixes #830
Fixes #778
Fixes #734
Fixes #714
Fixes #713
Fixes #633
Fixes #556
Fixes #492
Fixes #466
Fixes #435

Issues at a glance

Issue Root cause Fix Key regression test
#1006 governing_workspace_file took the nearest ancestor pnpm-workspace.yaml without checking that its packages: globs list the project (regression from #888) The ancestor file governs only if its globs list the project, matched the way pnpm does: negations anywhere, no dot directories, packages: ~/empty means root-only hosted::governing_root::tests::pnpm_project_outside_the_workspace_globs_is_not_refused, in_process_redirect_pnpm::hosted_scan_from_pnpm_project_outside_workspace_globs_pins_and_nests_trust
#919 The pnpm restore fetched dists from the default registry, never from the .npmrc / workspace mirror New pnpm_lookup_registry follows the pnpm major's rules (@scope:registry, registry, workspace registries/registry:) and is used for both the fetch and the tarball decision in_process_redirect::pnpm_rollback_reads_the_npmrc_mirror_document_for_an_offpath_tarball
#902 The lockfileIncludeTarballUrl policy read both settings files whatever pnpm wrote the lock, and pnpm 11's env document gave false evidence Decided by the lock's own evidence first, then the settings file the installed or pinned pnpm major reads, then pnpm 10's reading with a warning in_process_redirect::pnpm_rollback_stays_bare_when_pnpm11_ignores_npmrc_include_tarball_url (plus pnpm 9 and pnpm 12 twins)
#854 Vendored pnpm classified only package.json overrides and compared raw YAML text Shared classify_override_entries also covers pnpm-workspace.yaml overrides:; values are compared as YAML reads them (quotes and comments ignored), and revert restores the original text byte for byte vendor::pnpm_lock::tests::ws_bare_key_exact_pin_is_taken_over_and_revert_restores_it
#853 The scan/get --mode vendored --dry-run preview never asked the pnpm backend about hosted pins The preview runs the pnpm lock-text gates on hosted candidates and lists refusals as would_refuse. preflight_refused_purls matches in_process_vendor_pnpm_takeover::scan_vendored_over_hosted_pnpm_catalog_dep_keeps_the_hosted_pin, vendor_flow::preview_tests::preview_refuses_hosted_pnpm_catalog_pin
#830 Reverting a vendored parent spliced its whole pre-vendor block back, and child ref records were keyed only by the parent's old key Three-way merge (merge_live_dep_refs) keeps refs that another entry moved, and ref lookup follows the parent's rekey (v9, 5.4, 6.0) in_process_vendor_pnpm_parent_child::remove_parent_keeps_the_vendored_child_wired
#778 The crawler keeps one copy per name@version, and the agent scan's PATH filter tested only that one path Purls that miss the first pass are resolved to every installed copy (find_all_packages_for_rollback_reusing), the same way rollback does scan_paths_e2e::paths_scope_selects_pnpm_member_linked_copy
#734 The root-only packages: ['.'] scaffold turns a project into a workspace on pnpm 9.0-10.4 (ERR_PNPM_ADDING_TO_ROOT) Neither mode creates the scaffold when every pnpm pin names 9.0-10.4. With no evidence it is still created, with a caveat warning (see decisions) in_process_redirect_pnpm::hosted_pnpm_9_through_10_4_project_gets_no_root_only_workspace, hosted_memory_engine::pnpm_9_pin_gets_no_root_only_workspace_in_memory
#714 redirect_rush_repo_state_stale was gated on the single common repo-state.json path Each rewritten Rush lock is paired with the repo-state.json beside it, in both the disk and memory engines in_process_redirect::rush_subspace_repo_state_stale_warning_fires_for_subspace_repo_state
#713 pnpm_trust didn't know which spliced locks were Rush locks, so it gave the generic remedy, which never reaches rush install A Rush-specific redirect_pnpm_trust_lockfile remedy (pnpm_config_trust_lockfile=true rush install, usePnpmFrozenLockfileForRushInstall), re-issued on re-runs over locks that are already redirected in_process_redirect::rush_pnpm_trust_warning_gives_rush_remedy
#633 merge_npm_copies deduped by literal path, so the store entry and the member link to it were visited twice Copies are collapsed to distinct real directories at the apply and rollback per-copy loops (distinct_npm_copies) in_process_npm_multicopy::apply_and_rollback_visit_a_pnpm_workspace_member_link_once
#556 Nothing knew about gitBranchLockfile, so the stale pnpm-lock.yaml was pinned Both modes refuse when the setting is on and a branch lock exists, at the root or in a member, reading the setting from the governing ancestor in_process_redirect_pnpm::hosted_scan_refuses_a_git_branch_lockfile_project
#492 The hosted engine and discovery read only root-relative locks and ignored sharedWorkspaceLockfile: false member locks member_locks reads the setting the way pnpm does and expands packages:. Member locks are pinned, discovered and rolled back. The trust key goes to the root. Ported to the in-memory engine in_process_redirect_pnpm::hosted_scan_pins_every_member_lock_with_shared_workspace_lockfile_false, hosted_memory_parity member-lock cases
#466 pnpm >= 11 two-document locks: section lookups landed in the env document split_project_document edits only the project document and writes the env document back byte for byte. Unrecognised multi-document locks are refused vendor::pnpm_lock::tests::two_document_lock_vendors_and_reverts_the_project_document, real-pnpm e2e_vendor_pnpm_build::pnpm12_package_manager_two_document_lock_vendors_and_reverts
#435 pnpm 11+ per-install global dirs were walked as one root, and the walk-wide store filter skipped later installs global/v<N> is split into one root per install for both --global and --global-prefix npm_crawler::tests::global_prefix_finds_every_pnpm_isolated_install_copy, in_process_npm_multicopy::apply_global_prefix_patches_every_pnpm_isolated_global_install

New contract codes

All of these are documented in CLI_CONTRACT.md. Hosted refusals keep the existing hosted semantics: they are warnings, the status stays success with exit 0 and redirected: 0, the same as redirect_pnpm_unsupported and the other existing refusals.

Refusals

  • redirect_pnpm_git_branch_lockfile (hosted, Hosted scan with pnpm gitBranchLockfile pins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml #556): gitBranchLockfile is on and a root or member pnpm-lock.<branch>.yaml exists. No pnpm lock is touched. A vendored to hosted takeover of such a project is refused with the same code and keeps the vendored wiring.
  • vendor_pnpm_git_branch_lockfile (vendored, Hosted scan with pnpm gitBranchLockfile pins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml #556): the same condition, refused before any write. A hosted to vendored takeover keeps the hosted pin.
  • redirect_pnpm_member_locks_unresolved (hosted, Hosted scan on a pnpm workspace with sharedWorkspaceLockfile: false ignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing #492): the member list can't be resolved, so all pnpm pins are withheld instead of pinning a subset. Causes: no packages: key, an unmodeled glob, a glob that hits the 4096-directory walk cap, or an unreadable member lock.
  • vendor_pnpm_lock_multi_document (vendored, Vendored pnpm 12 with packageManager set: the two-document pnpm-lock.yaml makes vendor refuse, and vendor --revert, rollback and the hosted takeover half-revert the project and break frozen installs #466): a multi-document lock that isn't pnpm's env-plus-project layout. Remedy: --mode hosted. A revert over such a lock fails before touching anything, dry run included.

Warnings

  • upstream_pnpm_tarball_setting_guessed (Hosted pnpm rollback/remove adds registry tarball: URLs the lock never had when lockfileIncludeTarballUrl sits in a settings file the installed pnpm ignores (workspace file on pnpm 9, .npmrc on pnpm 11/12) #902): the restore had no evidence of which pnpm wrote the lock, so it followed pnpm 10's reading, and pnpm 9 or pnpm >= 11 would read the setting differently. Emitted once per lock. It names the entries, the setting it followed and the pnpm that disagrees, and says how to fix it (pin pnpm, or give both files the same value; for Rush, rush.json pnpmVersion).
  • vendor_config_dependency_unpatched (Vendored pnpm 12 with packageManager set: the two-document pnpm-lock.yaml makes vendor refuse, and vendor --revert, rollback and the hosted takeover half-revert the project and break frozen installs #466): the vendored package is also a pnpm config dependency. Its env-document copy stays the registry's.
  • pnpm_member_lock_ignored (Hosted scan on a pnpm workspace with sharedWorkspaceLockfile: false ignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing #492, in-memory engine): a member is named in projectRoots without its workspace root.
  • redirect_pnpm_trust_lockfile gains new variants. Hosted scan on a Rush repo with pnpm 11/12 reports success, but rush install then fails with ERR_PNPM_TARBALL_URL_MISMATCH, or (pnpm 11.0.0) silently installs the upstream package #713 adds a Rush remedy. Hosted and vendored modes create a packages: ['.'] pnpm-workspace.yaml that turns a single-package project into a workspace, so pnpm add <pkg> fails with ERR_PNPM_ADDING_TO_ROOT on pnpm 9.0–10.4 #734 adds three: one for when the scaffold is skipped on pnpm 9.0-10.4, the pnpm add -w caveat on a created scaffold, and a delete-it note when a re-scan of a pinned 9.0-10.4 project finds an earlier scaffold.

Narrowed

  • redirect_pnpm_settings_elsewhere / vendor_pnpm_settings_elsewhere (Hosted and vendored pnpm 11/12 refuse a standalone project nested under an unrelated pnpm-workspace.yaml (not in its packages: globs) as a "workspace member", and the suggested fix doesn't work (regression from #888) #1006) now fire only for projects that the ancestor's packages: globs actually list. A file that doesn't parse, or a glob syntax we don't model, still counts as listing the project, so Hosted scan from a pnpm 11/12 workspace member with its own lock writes trustLockfile into a nested member pnpm-workspace.yaml that pnpm ignores, so the root install fails with ERR_PNPM_TARBALL_URL_MISMATCH #880 and Vendored scan from a pnpm 11/12 workspace member with its own lock writes the override into a nested member pnpm-workspace.yaml that pnpm ignores, so the root frozen install fails and a plain pnpm install silently reinstalls the unpatched package #881 stay refused.

Maintainer decisions

  • Hosted and vendored modes create a packages: ['.'] pnpm-workspace.yaml that turns a single-package project into a workspace, so pnpm add <pkg> fails with ERR_PNPM_ADDING_TO_ROOT on pnpm 9.0–10.4 #734, no pnpm version evidence: the root-only scaffold is still created, so pnpm >= 11 never loses trustLockfile. The warning names the pnpm add -w caveat and the remedy: a packageManager pin naming pnpm 9.0-10.4, with every other pnpm pin also inside that range.
  • Hosted pnpm rollback/remove adds registry tarball: URLs the lock never had when lockfileIncludeTarballUrl sits in a settings file the installed pnpm ignores (workspace file on pnpm 9, .npmrc on pnpm 11/12) #902, no version evidence (no unpinned registry entry, no .modules.yaml, no packageManager): the restore keeps pnpm 10's reading and emits upstream_pnpm_tarball_setting_guessed. Rush locks take the major from rush.json pnpmVersion.

Behavior changes worth a close look

  • Shared glob and membership code (Hosted and vendored pnpm 11/12 refuse a standalone project nested under an unrelated pnpm-workspace.yaml (not in its packages: globs) as a "workspace member", and the suggested fix doesn't work (regression from #888) #1006, Hosted scan on a pnpm workspace with sharedWorkspaceLockfile: false ignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing #492): utils/pnpm_workspace::lists_member is now the single membership rule used by both governing_workspace_file and member_dirs. As a side effect, governing_workspace_file now applies pnpm's default ignores, so packages/test under packages/* is no longer a member.
    • cargo_workspace::expand_glob now lets a dot-prefixed pattern segment (packages/.*) match dot directories. This also affects Cargo workspace globs.
    • The glob matcher moved to utils/workspace_globs.rs.
  • In-memory hosted engine (Hosted scan on a pnpm workspace with sharedWorkspaceLockfile: false ignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing #492): a member lock is demoted into its workspace root only when the root's own files confirm that the root reads that lock. Unconfirmed candidates stay roots of their own and are refused under the trust auto-config instead of being dropped.
    • The shared lock inventory now reads member locks, so their dependencies are found on a fresh clone with no installed tree.
    • Path selection fetches the ancestor pnpm-workspace.yaml, member locks and branch locks, but only in directories that hold a package manifest.
  • pnpm registry selection (Hosted pnpm rollback/remove restores pnpm-lock.yaml from npmjs's version document instead of the project's .npmrc registry, so a mirror project loses its tarball: URL (cold frozen install 404s) or is moved to npmjs #919) depends on the pnpm major: <= 9 reads .npmrc only; 10 lets a workspace registries map replace .npmrc wholesale; 11+ or unknown merges the two, with the workspace winning per key. A value with an unexpanded ${VAR} is read as unset.
  • The tarball policy (Hosted pnpm rollback/remove adds registry tarball: URLs the lock never had when lockfileIncludeTarballUrl sits in a settings file the installed pnpm ignores (workspace file on pnpm 9, .npmrc on pnpm 11/12) #902) reads only the main lock document, after the last ---. A workspace lockfileIncludeTarballUrl is true in any case (True, TRUE), as js-yaml reads it. .npmrc needs a lowercase true, as ini/nopt reads it (e866e1a, from a Bugbot finding).
  • Vendored scaffold (Hosted and vendored modes create a packages: ['.'] pnpm-workspace.yaml that turns a single-package project into a workspace, so pnpm add <pkg> fails with ERR_PNPM_ADDING_TO_ROOT on pnpm 9.0–10.4 #734): on pnpm 9.0-10.4 the workspace overrides: mirror is skipped. package.json pnpm.overrides and the lock are wired as before. packageManager parsing moved to utils/package_manager.rs, shared with the yarn migration check.
  • Agent scan <path> (Agent-mode scan packages/<member> finds nothing in a pnpm workspace (exit 0), while rollback packages/<member> selects the same packages #778): a path-scoped run keeps the npm crawl snapshot and resolves the purls that missed the first pass to every installed copy. In a large monorepo this costs one extra enumeration, and only for scoped runs. Unscoped scans are unchanged.
  • Merge with main: preview_vendor_json takes both the patch-server origins (pnpm hosted-to-vendored scan/get dry-run previews success for a refused takeover #853) and main's gem takeover refusals. Our BOM callers now use main's formats::text::strip_bom.
  • Second merge with main (dabab5f, 2026-10-08): main's Fix workspace-member refusal for vlt and brace/class globs (#1071, #942) #1073 taught the npm/yarn/Bun workspaces matcher brace sets, sequences and character classes inline in governing_root.rs. This branch had moved that matcher into utils/workspace_globs.rs, so the merge moves Fix workspace-member refusal for vlt and brace/class globs (#1071, #942) #1073's grammar and its brace/class test into the shared module and keeps pnpm's no-dot rule there. pnpm's packages: check still fails closed on brace, class and extglob patterns (counts as listing the project), as before. CLI_CONTRACT.md keeps main's vlt/glob wording for the lockfile-elsewhere row and the .socket symlink row, plus this branch's pnpm settings rows.
  • Third merge with main (f202603, 2026-10-08): main's Decide which lockfile governs installs in one table #1044 moved npm lock-flavor detection behind a ProjectView and one governing-lock table, replacing the step list this branch had added the Hosted scan with pnpm gitBranchLockfile pins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml #556 lone-branch-lock refusal to. The refusal now sits before main's "nothing recognizable" step, and pnpm_lock::git_branch_lock_refusal takes a ProjectView, so the disk, snapshot and in-memory paths all name the gitBranchLockfile setting. formats/pnpm/mod.rs keeps main's entry_bundled/Bundled exports and this branch's version module. The hosted engine's member-lock test helper gains main's new yarn_classic_outer option.
  • Bench: the pnpm bench fixture is now pinned to pnpm 11. It used to record a 9.15.0 install, so with Hosted and vendored modes create a packages: ['.'] pnpm-workspace.yaml that turns a single-package project into a workspace, so pnpm add <pkg> fails with ERR_PNPM_ADDING_TO_ROOT on pnpm 9.0–10.4 #734 the scan correctly skips the scaffold, and the bench's expected rewrittenFiles no longer matched.

Testing

  • Each issue has at least one regression test that fails on main, and each fix went through adversarial review rounds.
  • Real-pnpm legs cover Vendored pnpm 12 with packageManager set: the two-document pnpm-lock.yaml makes vendor refuse, and vendor --revert, rollback and the hosted takeover half-revert the project and break frozen installs #466 on pnpm 11.27.0 and 12.8.1 (fresh frozen install plus a byte-exact revert). Hosted and vendored modes create a packages: ['.'] pnpm-workspace.yaml that turns a single-package project into a workspace, so pnpm add <pkg> fails with ERR_PNPM_ADDING_TO_ROOT on pnpm 9.0–10.4 #734's e2e legs now expect no scaffold on pnpm 9.
  • hosted_memory_parity checks that the disk and in-memory engines produce the same result for member locks, the trust config, branch-lock refusals, stale member locks under a shared lock, and Rush subspaces, both straight and through path selection.
  • Local cargo test --workspace on an arm Mac has 3 failures. All 3 also fail on origin/main on the same machine:
    • two x86 old-toolchain e2e_vendor_cargo_build tests
    • mode_migration_npm::berry_vendored_then_hosted_takeover_leaves_pure_hosted
  • After the second merge (Linux, root): cargo clippy --workspace --all-features -- -D warnings is clean. cargo test -p socket-patch-core --all-features --lib gives 5742 passed. The 4 failures are the read-only-permission tests that root bypasses (copy_tree, vlt_heal, pypi_poetry, pypi_requirements write-failure cases). in_process_redirect_pnpm (28), hosted_memory_engine (34), hosted_memory_parity (42) and scan_vendor_e2e (37) pass. in_process_redirect gives 131 passed. Its 3 failures are chmod write-failure tests that root bypasses.
  • e866e1a, red → green: pnpm_include_tarball_reads_the_settings_file_of_the_pnpm_major with workspace True / TRUE / 'true' (pnpm 11 and unknown major) failed before the change and passes after it. in_process_redirect pnpm cases (22) pass.
  • After the third merge (f202603, Linux, root): cargo clippy --workspace --all-features -- -D warnings is clean, and cargo check --workspace --all-features --tests compiles every test target. cargo test -p socket-patch-core --all-features --lib: 5817 passed, including a_lone_git_branch_lock_names_the_setting; the same 4 root-bypass failures as above. in_process_redirect_pnpm (28), hosted_memory_parity (42), hosted_memory_engine (34), scan_vendor_e2e (37), in_process_vendor_pnpm_takeover (15) and in_process_vendor_pnpm_parent_child (8) pass. in_process_redirect: 133 passed, with the same 3 root chmod failures.

Out of scope

  • pnpm hosted-to-vendored scan/get dry-run previews success for a refused takeover #853: the scan/get dry-run preview still shows would_vendor for legacy pnpm 5.4/6.0 hosted pins, which aren't lock-text gated. CLI_CONTRACT.md documents this and a test pins it. Yarn hosted pins and non-hosted lock-text refusals are not modelled in the preview either.
  • Hosted scan on a pnpm workspace with sharedWorkspaceLockfile: false ignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing #492 / Hosted scan with pnpm gitBranchLockfile pins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml #556: following the existing hosted convention, these refusals don't change the run status. Making them a non-success status would change it for every hosted refusal.
  • Hosted pnpm rollback/remove restores pnpm-lock.yaml from npmjs's version document instead of the project's .npmrc registry, so a mirror project loses its tarball: URL (cold frozen install 404s) or is moved to npmjs #919: the user or global ~/.npmrc is still not read.

Bugbot follow-up (26ce12c)

git_branch_locks skipped members it could not list (Unresolved), so with gitBranchLockfile on and no root branch lock it answered "none" and vendored mode could wire root overrides while a member branch lock was live. It now fails closed and names why the members could not be listed. Regression test git_branch_locks_fail_closed_on_an_unlisted_member_set: red on be89ccc, green on 26ce12c. Local: core lib 5826 pass (4 pre-existing failures that only fail when tests run as root, same on be89ccc), hosted_memory_parity, in_process_redirect_pnpm, in_process_vendor_pnpm_takeover all pass, clippy -D warnings clean.

  • 017dce1, Bugbot on 26ce12c: a member lock's restore (sharedWorkspaceLockfile: false) read pnpm-workspace.yaml, .npmrc and package.json beside the member lock. pnpm reads them from the workspace root, so tarball: lines and the registry could be wrong. It now reads them from the nearest workspace root listing the member (pnpm_settings_prefix). Test rollback_reads_member_lock_settings_from_the_workspace_root: red on 26ce12c (tarball dropped), green on 017dce1.
  • 2b46121, Agentic Security Review on be89ccc: upstream_registry_fallback repeated a registry URL's user:token@. It is now stripped from both the named registry and the quoted error. Test registry_fallback_warning_drops_url_credentials: red on 017dce1, green on 2b46121.
  • Local on 2b46121: in_process_redirect_pnpm 29/29, hosted_memory_parity 42/42, core redirect::upstream 106/106, clippy -D warnings clean. in_process_redirect passes except 3 write-failure tests that also fail on the unchanged tree here (the sandbox runs as root).

🤖 Generated with Claude Code


Note

High Risk
Changes pnpm lockfile rewrite, rollback, and workspace discovery paths that directly control whether patched bytes install and whether restores match upstream—high blast radius across hosted, vendored, and agent flows.

Overview
pnpm hosted, vendored, and agent behavior is tightened so installs, rollbacks, and scans match how real pnpm reads workspace settings, member locks, mirrors, and branch locks—instead of reporting success while leaving unpatched bytes or non–byte-exact restores.

Hosted mode now documents (and the implementation aligns with) per-member locks under sharedWorkspaceLockfile: false (#492), refusal when gitBranchLockfile and branch locks are present (#556), smarter trustLockfile / root-only pnpm-workspace.yaml handling for pnpm 9.0–10.4 vs ≥11 (#734), Rush-specific trust guidance (#713), and subspace repo-state.json pairing (#714). Upstream restore for pnpm is specified to honor mirror registries (#919), infer lockfileIncludeTarballUrl from lock evidence and pnpm major (#902, warning upstream_pnpm_tarball_setting_guessed), and read member-lock settings from the workspace root.

Vendored mode contract updates cover two-document pnpm 12 locks (#466), workspace overrides: mirroring and exact-pin takeover (#854), dry-run would_refuse for hosted pnpm pins the backend would reject (#853), parent/child lock revert semantics (#830), and matching refusals for branch locks and multi-document locks.

Agent mode path-scoped scans are documented to count every installed copy (e.g. pnpm member links into the store) (#778), with deduped apply/rollback visits (#633). Global pnpm 11+ isolated install roots are crawled separately (#435).

The bench npm fixture bumps the recorded packageManager to [email protected] so redirect/trust expectations stay consistent with the new scaffold rules.

CLI_CONTRACT.md is expanded throughout to capture these rules, remedies, and warning codes; this diff is primarily that contract sync plus the fixture pin.

Reviewed by Cursor Bugbot for commit f172f2d. Configure here.


Generated by Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mikolalysenko @claude
Start pnpm open-issue sweep
09d4ed5
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This was referenced Oct 7, 2026
Hosted and vendored pnpm 11/12 refuse a standalone project nested under an unrelated pnpm-workspace.yaml (not in its packages: globs) as a "workspace member", and the suggested fix doesn't work (regression from #888) #1006
Closed
Hosted pnpm rollback/remove restores pnpm-lock.yaml from npmjs's version document instead of the project's .npmrc registry, so a mirror project loses its tarball: URL (cold frozen install 404s) or is moved to npmjs #919
Closed
Hosted pnpm rollback/remove adds registry tarball: URLs the lock never had when lockfileIncludeTarballUrl sits in a settings file the installed pnpm ignores (workspace file on pnpm 9, .npmrc on pnpm 11/12) #902
Closed
Vendored pnpm refuses a user exact-pin override (left-pad: 1.3.0) in pnpm-workspace.yaml with a misleading "does not match package.json" error, though the same pin in package.json is taken over #854
Closed
pnpm hosted-to-vendored scan/get dry-run previews success for a refused takeover #853
Closed
Vendored pnpm: unwinding a vendored package whose dependency is also vendored clobbers the child's lock wiring — remove <parent> breaks frozen installs, the hosted takeover silently unpatches the child, and rollback fails forever #830
Closed
Agent-mode scan packages/<member> finds nothing in a pnpm workspace (exit 0), while rollback packages/<member> selects the same packages #778
Closed
Hosted and vendored modes create a packages: ['.'] pnpm-workspace.yaml that turns a single-package project into a workspace, so pnpm add <pkg> fails with ERR_PNPM_ADDING_TO_ROOT on pnpm 9.0–10.4 #734
Closed
Hosted scan on a Rush repo with subspaces never emits redirect_rush_repo_state_stale, so rush install fails on the shrinkwrap hash check with no warning #714
Closed
Hosted scan on a Rush repo with pnpm 11/12 reports success, but rush install then fails with ERR_PNPM_TARBALL_URL_MISMATCH, or (pnpm 11.0.0) silently installs the upstream package #713
Closed
Agent-mode apply in a pnpm workspace reports each member-linked package twice, inflating the --json skipped count with duplicate already_patched events #633
Closed
Hosted scan with pnpm gitBranchLockfile pins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml #556
Closed
Hosted scan on a pnpm workspace with sharedWorkspaceLockfile: false ignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing #492
Closed
Vendored pnpm 12 with packageManager set: the two-document pnpm-lock.yaml makes vendor refuse, and vendor --revert, rollback and the hosted takeover half-revert the project and break frozen installs #466
Closed
Global agent mode on pnpm 12 (and 11 without the global virtual store) patches only one of the per-install copies of a package, reports success, and VEX attests not_affected #435
Closed
Mikola Lysenko (mikolalysenko) and others added 11 commits October 7, 2026 09:15
@mikolalysenko @claude
Fix Rush pnpm >=11 hosted trust guidance (#713)
3e32a82
A hosted scan on a Rush repo repoints common/config/rush/pnpm-lock.yaml
(and subspace locks) and reports success, but on pnpm >=11 the next
`rush install` either fails (ERR_PNPM_TARBALL_URL_MISMATCH) or, on pnpm
11, silently re-resolves the hosted entries to upstream with exit 0.

Root cause: `pnpm_trust` skips the trustLockfile write for Rush locks on
purpose (rush runs pnpm in common/temp with a pnpm-workspace.yaml it
generates), but it never knew which spliced locks were Rush locks, so
the run fell through to the generic manual guidance:
`pnpm install --trust-lockfile`, a repo-root `trustLockfile` key and a
`--store-dir` reinstall. None of those reach rush's install.

`rewrite()` now passes `rush_lock_keys` into `pnpm_trust`. When every
spliced pnpm lock is a Rush lock (and not a legacy 5.x/6.0 lock), the
`redirect_pnpm_trust_lockfile` warning carries a Rush remedy instead:
`pnpm_config_trust_lockfile=true rush install`, plus
`"usePnpmFrozenLockfileForRushInstall": true` in
common/config/rush/experiments.json on pnpm 11, `rush purge` before the
reinstall, and `socket-patch vex` to verify. It also says the pnpm 11
failure can be silent. A run that also spliced a non-Rush pnpm lock
keeps the generic text and appends a Rush note. The warning code and
file writes are unchanged. docs/ecosystems.md and CLI_CONTRACT.md
document the Rush pnpm >=11 remedy.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix pnpm restore reading the default registry, not the .npmrc mirror (#…
1bb3cbb
…919)

The hosted pnpm unwind (rollback / remove, and the hosted -> vendored
takeover and eject that share it) restored each pinned pnpm-lock.yaml
resolution from the version document of the default registry
(SOCKET_NPM_REGISTRY, npmjs when unset). restore_pnpm_locks still called
the default-registry `fetch_dists`; the project-registry lookup added
for #908 (`fetch_dists_on`) was wired only into yarn berry and vlt. The
lock-sibling `.npmrc` `registry=` was read, but only to decide whether a
`tarball:` is written, never to pick the registry the dist comes from,
and `@scope:registry` was not read at all. So for a project resolving
against a mirror:

- a CDN-style mirror `tarball:` came back as a bare `{integrity}`,
  because npmjs's URL is conventional, and a cold frozen install 404s;
- under lockfile-include-tarball-url, npmjs's dist.tarball replaced the
  mirror URL pnpm had recorded.

Both exited 0.

pnpm resolves a name against its `.npmrc` `@scope:registry` when the
name is scoped and that key is set, otherwise against `registry`. The
new `pnpm_lookup_registry` encodes that rule, and the restore now uses
it for two things: as the per-name registry for `fetch_dists_on`, which
also gives the existing `upstream_registry_fallback` warning and
default-registry fallback when the mirror can't be read, and in the
`registry_derives_tarball` decision, so a scoped package's conventional
scope-registry URL stays derived. A value that still holds an unexpanded
`${VAR}` is read as unset (today's default-registry behaviour) and is
never fetched as a literal URL.

CLI_CONTRACT.md: the npm-family upstream bullet, the SOCKET_NPM_REGISTRY
row and the upstream_registry_fallback row now list pnpm's `.npmrc`
`registry` / `@scope:registry` next to berry and vlt.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix agent-mode scan PATH scope missing workspace member copies (#778)
656bb3b
`scan --mode agent packages/a` in a pnpm workspace scanned 0 packages
and exited 0, while `rollback packages/a` selected the member's
dependencies.

Root cause: the npm crawler keeps one CrawledPackage per name@version
(`merge_scan_events`' `seen` set), recorded at the first copy the walk
meets. In a pnpm workspace that is the root `node_modules/.pnpm` store
entry, never the member's `packages/a/node_modules/<dep>` link; in a
yarn classic / npm workspace with a version conflict it is whichever
member's nested copy the readdir order reaches first. Scan's PATH filter
tested only that one recorded path, so the contract rule "in scope iff
ANY installed copy sits under a matching path" was never honored for
the other copies. Rollback resolves candidates through
`find_all_packages_for_rollback`, which returns every copy, hence the
divergence.

Fix: keep the cheap first pass over the recorded paths, then resolve
the purls that missed to every installed copy with the same
enumeration rollback's path targets use (new
`find_all_packages_for_rollback_reusing`, which reuses the crawl's npm
roots), and admit a purl when any copy matches. A path-scoped run now
keeps the npm crawl snapshot so the roots are not rediscovered. The
crawler's per-purl dedup is unchanged; apply already patches every copy
of a selected purl. Unscoped scans are untouched.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix pnpm projects outside the workspace globs refused as members (#1006)
3866a2c
#888 made hosted and vendored modes refuse a pnpm project with its own
v9 lock and no pnpm-workspace.yaml of its own whenever any ancestor held
a pnpm-workspace.yaml (redirect_pnpm_settings_elsewhere,
vendor_pnpm_settings_elsewhere). governing_workspace_file took the
nearest ancestor file without asking whether its `packages:` globs list
the project. pnpm 11.28+ and 12 install a directory the nearest file
does not list (an examples/ app, a checkout under an unrelated
workspace) standalone: its own lock, and settings read only from its own
pnpm-workspace.yaml. So both refusals pointed at remedies that do
nothing, and neither mode could patch a project 4.0.0 handled.

governing_workspace_file now reads the nearest regular ancestor file
(FIFO-safe reader) and returns it only when it lists the project, as
probed on pnpm 11.28.5 and 12.10.1:
- no `packages:`, a null or an empty list: root-only workspace, so no;
- otherwise some pattern matches and no `!` pattern does (pnpm's globber
  treats every negation as an ignore, wherever it sits).
A file that does not parse, or a pattern with braces, classes or
extglobs the matcher does not model, still counts as listing the
project, so #880/#881 stay refused. With no governing file, hosted
creates the project's own pnpm-workspace.yaml with trustLockfile: true
and vendored wires its override there, as before #888.

The glob matcher used by the package.json workspaces check (#884) moves
to utils/workspace_globs.rs so both checks share it. CLI_CONTRACT.md
scopes both codes to members listed by the root's `packages:` globs.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix vendored pnpm refusing a pnpm-workspace.yaml exact-pin override (#…
ed668b4
…854)

Vendored pnpm takes over a user's exact-version override of the package
it vendors (the pin already forces that version, so redirecting the same
key keeps its meaning), but the pre-flight only classified package.json
`pnpm.overrides`. On pnpm 10.5+ (always on 11/12) the override lives in
pnpm-workspace.yaml `overrides:`. With no package.json override the
effective key fell back to our canonical `name@version`, so a bare-key
pin (`left-pad: 1.3.0`) in the workspace file and its lock mirror were
refused as `vendor_override_conflict`, with a detail claiming the lock
"does not match package.json's `[email protected]`". The versioned-key pin
only worked because it happened to equal our canonical key.

- The per-entry Insert / Ours / Takeover / conflict rules are factored
  into classify_override_entries, shared by classify_pkg_override and a
  new classify_ws_override (modern locks only; legacy pnpm never reads
  the workspace file). The effective key comes from whichever file
  carries the override; package.json and the workspace file pinning
  under different keys refuses naming both files.
- check_lock_override names the file the effective key came from (or
  says it is the key vendoring would add), and conflict details name
  pnpm-workspace.yaml when that is where the override lives.
- workspace_overrides_govern now counts any workspace override key the
  lock records, vendored values included. Before, once a workspace-only
  takeover made the value ours, a re-run (or vendoring another package)
  saw no user key and wrote a package.json copy that shadows the
  workspace overrides on pnpm 10 (#360 twin).

The #853 CLI fixture that used a bare workspace exact pin as its
"refused" trigger now uses a range, and a new CLI test pins the
takeover. CLI_CONTRACT.md documents the takeover exception.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix duplicate apply/rollback events for pnpm workspace member links (#…
47460ea
…633)

In a pnpm (or Bun isolated) workspace, agent-mode `apply` reported every
package a member links twice: once `applied`, then a phantom `skipped` /
`already_patched` for the same purl, and every re-run counted one extra
skip per member-linked package. `rollback` double-counted
`alreadyOriginal` the same way.

Root cause: the multi-copy resolver (`find_all_packages_for_purls` /
`find_all_packages_for_rollback`) runs `find_by_purls` once per
`node_modules` root. The workspace root pass records the store entry
`node_modules/.pnpm/<pkg>@<ver>/node_modules/<pkg>` and the member pass
records the member's `packages/a/node_modules/<pkg>` link to it.
`merge_npm_copies` dedupes by literal path, so both spellings of one
directory survive and the apply/rollback per-copy loops visited the same
physical copy twice.

Fix: collapse each npm purl's copies to distinct real directories at the
two sites that act per copy (apply's copy loop and rollback's restore
targets), keeping the first-found spelling, via a new
`distinct_npm_copies` built on the canonical-path helper
`distinct_install_dirs` (moved from apply.rs to ecosystem_dispatch.rs,
where PyPI apply keeps using it). The resolver map itself still carries
every spelling on purpose: path targets (`scan --mode agent packages/a`,
`rollback packages/a`, #778) match copies textually through the member's
link, and deduping there would make those scopes select nothing.
Genuinely distinct copies (nested duplicates, store peer variants,
bundled copies) have distinct real paths and are unaffected; a path that
can't be canonicalized is kept as-is.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix pnpm restore following a tarball setting pnpm ignored (#902)
afbaaef
The hosted pnpm unwind (rollback / remove) decides whether a restored
pnpm-lock.yaml resolution gets a `tarball:` from PnpmTarballPolicy. That
policy read `lockfileIncludeTarballUrl` from pnpm-workspace.yaml, else
`lockfile-include-tarball-url` from .npmrc, whatever pnpm major wrote
the lock. But pnpm <= 9 ignores pnpm-workspace.yaml settings and pnpm
11/12 ignore pnpm settings in .npmrc, so in those projects the lock has
no `tarball:` fields, yet rollback/remove wrote the registry's
dist.tarball into every restored resolution: not byte-exact, and each
restored package hard-pinned to that registry.

The decision now follows what pnpm actually did, strongest signal first:

1. The lock's own unpinned registry resolutions (registry key per the
   shared pnpm_registry_key rule, integrity, no git/directory fields,
   tarball neither hosted nor `file:`). With the setting on pnpm writes
   `tarball:` on every one, so a single bare one proves it off; failing
   that, a tarball pnpm could have derived proves it on. Unconventional
   URLs are recorded either way and give no evidence.
2. The settings file the installed pnpm major reads: the major comes
   from node_modules/.modules.yaml `packageManager` (JSON on pnpm 10+,
   YAML before), else package.json's corepack `packageManager`, else a
   pre-9 lockfileVersion or a shrinkwrap.yaml means pnpm <= 8. <= 9 reads
   .npmrc only, 10 the workspace file then .npmrc, 11+ the workspace
   file only.
3. With neither (no install record, only pinned entries, e.g. a fresh
   clone or a Rush lock), pnpm 10's reading, as before.

The splice logic and the unconventional-URL branch (#557) are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Keep pnpm workspace globs off dot directories (#1006)
ada052a
pnpm's globber reads `packages:` with dot matching off: on pnpm 12.10.1,
`packages: ['**']` leaves `.github/actions/demo` standalone with its own
lock, as do `packages/**` for `packages/.x/demo` and `packages/*` for
`packages/.hidden`. The shared matcher let `*`, `?` and `**` match those
components, so governing_workspace_file still named the root file for
them and hosted / vendored refused with redirect_pnpm_settings_elsewhere
/ vendor_pnpm_settings_elsewhere, pointing at a file pnpm never reads
for that directory.

lists_as_member now uses glob_matches_no_dot: a wildcard component never
matches a path component starting with `.` unless the pattern component
itself starts with `.` (`.github/**` still lists it). The npm/yarn
`workspaces` caller keeps its current matching.

Tests: the probed dot cases in the core membership test and at the
refusal level; the refusal test's settings-only root now carries no
trust key (`trustLockfile: false` short-circuited the refusal on main
too, so it never exercised the membership rule); and the #880 doc
comment moves back onto its own test.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix Rush subspace repo-state stale warning never firing (#714)
f26a30f
With Rush subspaces enabled, each subspace keeps its pnpm lock and the
repo-state.json that carries its pnpmShrinkwrapHash side by side under
common/config/subspaces/<name>/, and there is no
common/config/rush/repo-state.json. The hosted engine rewrote the
subspace locks but gated redirect_rush_repo_state_stale on the one fixed
common path (RUSH_REPO_STATE_REL), so the warning never fired and
`rush install` with preventManualShrinkwrapChanges failed on the hash
check with no hint.

The gate now pairs each rewritten Rush lock with the repo-state.json in
its own directory (the common lock still maps to RUSH_REPO_STATE_REL), so
a subspace rewrite warns on its subspace's file and a common-only rewrite
is not flagged by an unrelated subspace's file. The in-memory host's
selector fetches common/config/subspaces/*/repo-state.json presence-only
as well, so disk and memory runs agree. Docs and CLI_CONTRACT name the
per-subspace file.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Ignore pnpm 11's env lockfile document in tarball evidence (#902)
b9faf35
pnpm 11+ writes the env lockfile (configDependencies /
packageManagerDependencies) as a first YAML document ahead of the project
lock, and records its resolutions as a bare `{integrity}` even under
lockfileIncludeTarballUrl (verified with pnpm 11.27.0 and
`pnpm add --config [email protected]`). The tier-1 evidence scan walked every
`packages:` section, so that one bare config dependency proved the setting
off and rollback/remove restored a pinned entry without its `tarball:`,
exiting 0 with a lock that was not byte-exact.

The evidence scan now reads only the main document (after the last `---`
marker), through a new shared grammar::main_document helper.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Skip the root-only pnpm-workspace.yaml on pnpm 9.0-10.4 (#734)
75d89c0
Hosted mode creates `packages: ['.']` + `trustLockfile: true` for every
v9 root lock with no pnpm-workspace.yaml, and vendored mode creates the
same scaffold for its `overrides:` mirror. On pnpm 9.0.0-10.4.x that file
turns a single-package project into a root-only workspace, where
`pnpm add <pkg>` fails with ERR_PNPM_ADDING_TO_ROOT unless given `-w`
(10.5.0 is the first release that adds normally). Those releases read
neither setting from the file: `trustLockfile` is pnpm >= 11, and
workspace `overrides:` are read from 10.5 on.

Direction taken: a version-gated scaffold, not `ignoreWorkspaceRootCheck`.
When the project has no pnpm-workspace.yaml and every pnpm pin it
carries (at least one) names 9.0-10.4, neither mode creates the file.
The pins are the installed node_modules/.modules.yaml `packageManager`
(YAML on pnpm 9, JSON on 10+) and package.json `packageManager`,
`devEngines.packageManager` and `engines.pnpm`, all read with the
FIFO-safe regular-file readers. A pin naming a later pnpm, a range
reaching past 10.4, an unparseable pin, or no pin keeps the scaffold, so
pnpm >= 11 never loses the setting it needs.

- Hosted: the new redirect_pnpm_trust_lockfile variant names the pins,
  says why nothing was written, and gives the pnpm >= 11 recovery
  (re-run the scan, or `pnpm install --trust-lockfile`). A created
  scaffold's detail now notes the `pnpm add -w` caveat.
- Vendored: package.json `pnpm.overrides` and the lock are wired as
  before, the workspace mirror is skipped; a later vendor on pnpm >= 10.5
  adds it, and revert undoes all three byte-for-byte. The "Commit ..."
  next step names pnpm-workspace.yaml only when the file exists.
- package.json `packageManager` parsing moves to
  utils/package_manager.rs, shared with the yarn migration check.

Tests cover both modes: core unit tests for the pin reader, vendor and
revert (including the upgrade path), in-memory and in-process hosted
runs including heal-on-rerun after an upgrade and rollback removing the
created file, and the real-pnpm e2e legs now expect no file on pnpm 9.
CLI_CONTRACT.md, docs/ecosystems.md and docs/testing/pnpm-compatibility.md
describe the rule.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 7, 2026
Stop VEX attesting over yarn PnP, pnpm bundled and deno.lock copies #1033
Merged
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

Closing (burn-down agent): this draft has no changes. Its only commit is an empty placeholder ("Start pnpm open-issue sweep"), the diff against main is 0 files, and nothing has been pushed in about 2.5 hours with no agent heartbeat. The linked issues stay open and untouched. The branch is kept: reopen this PR, or open a new one, once fixes are pushed.


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko Mikola Lysenko (mikolalysenko) closed this Oct 7, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 8, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/socket-patch-core/src/utils/pnpm_workspace.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@claude
Merge main into agent/fix-pnpm-open-issues
bc69b70
Resolve conflicts with #1027 ({code, message} JSON errors): keep this
PR's pnpm rows in CLI_CONTRACT.md with main's top-level `error.code`
wording and main's new rollback `error` row, and keep both import
sets in scan/mod.rs.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

[final reviewer] Merged main at bc69b700 to clear the conflict with #1027 ({code, message} JSON errors):

  • CLI_CONTRACT.md: kept this PR's pnpm rows and rewrote their "top-level errorCode" to main's "top-level error.code" (main's only change in those rows); added main's new rollback error row above this PR's warnings row.
  • scan/mod.rs: kept both import sets.

Merge-only, no new behavior. Locally: cargo clippy --locked -p socket-patch-cli -p socket-patch-core --all-features -- -D warnings clean; socket-patch-cli lib (898), scan, json_error_shape, in_process_redirect_pnpm, in_process_vendor_pnpm_*, hosted_memory_* pass. 3 in_process_redirect write-failure tests fail only because this sandbox runs as root (chmod can't block writes); CI runs them unprivileged.

Tanmay Singla (@Tanmay182003) the re-look request above for f50b13c still stands.


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Claude (claude) added 3 commits October 9, 2026 00:17
@claude
Merge remote-tracking branch 'origin/main' into agent/fix-pnpm-open-i…
337d60c
…ssues

# Conflicts:
#	crates/socket-patch-cli/CLI_CONTRACT.md
#	crates/socket-patch-core/src/hosted/engine.rs

Co-Authored-By: Claude <[email protected]>
@claude
Port the pnpm fixes onto main's private DiskSnapshot root
a11b7b3
Main (#1058) made DiskSnapshot::root private behind ProjectView::disk_root
and added three RewriteOptions fields; read the root through disk_root()
and fill the new fields in the test initializer.

Co-Authored-By: Claude <[email protected]>
@claude
Compare the pnpm settings prefix without the verbatim prefix
c54cf04
The governing workspace root is reported without Windows' \\?\ prefix
(governing_workspace_file strips it), but the test built its expected
value from the canonicalized tempdir, which keeps it. The test failed on
windows-latest only. Strip the prefix from the expectation the same way.

Co-Authored-By: Claude <[email protected]>
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

[burn-down agent] Pushed c54cf04: test (windows-latest, 1) failed on a11b7b3 in pnpm_settings_come_from_the_governing_workspace_root. governing_workspace_file reports the root without the \\?\ verbatim prefix, but the test's expected value came from the canonicalized tempdir, which keeps it. The test now strips the prefix from its expectation with without_verbatim_prefix. It's a test-only change.

bugbot run


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 9, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/socket-patch-cli/src/commands/scan/vendor_flow.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 9, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Ready for review (burn-down agent) at c54cf044.

  • CI: 466/466 checks green (450 success, 15 skipped, 1 neutral, the Cursor Bugbot check).
  • Bugbot: reviewed c54cf04. Its one finding (preview skips non-root pnpm locks, vendor_flow.rs:257) was refuted on the thread and resolved. Those layouts fail the wet run on lock-flavor detection (vendor_rush_unsupported / vendor_lockfile_missing), which the preview didn't predict before this PR either. The root-lock gate is only a shortcut. No open review threads.
  • Mergeable, no CHANGELOG change. Reviewers: this is a 15-issue pnpm PR, so the new hosted→vendored takeover refusal prediction (hosted_pnpm_refusals / pnpm_takeover_lock_text_refusals) deserves the closest look.

Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko Mikola Lysenko (mikolalysenko) removed the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 9, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Withdrawn: right after labeling, main moved and this PR now conflicts with it. The burn-down agent is merging origin/main into it now and will re-label once CI is green on the new head.


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@claude
Merge origin/main (#1008) into agent/fix-pnpm-open-issues
f172f2d
#1008 moved the pnpm vendor wiring into an NpmLockBackend impl and the
vendor run's closing lines into print_vendor_closing. Re-apply this
branch's changes on that structure instead of reverting it:

- PnpmBackend::preflight warns vendor_config_dependency_unpatched when the
  lock's env document also lists the package (#466);
- PnpmBackend::wire skips the pnpm-workspace.yaml mirror for a project
  pinned to pnpm 9.0-10.4 with no workspace file (#734), and writes the
  env-document prefix back ahead of the project lock (#466);
- print_vendor_closing passes whether pnpm-workspace.yaml exists to
  commit_hint (#734);
- engine.rs imports and CLI_CONTRACT.md keep both sides' additions.

Co-Authored-By: Claude <[email protected]>
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 9, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit f172f2d. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 9, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

[burn-down] Ready for review at f172f2db5. CI 466/466 green (451 success, 15 skipped, incl. ci-ok and the gradle windows compat legs); mergeable, no conflicts. Bugbot reviewed f172f2d with no new issues; no open threads. Reviewer focus: the last merge from main re-applied this PR's #466/#734 changes on top of the PnpmBackend structure from #1008, so that part of the diff is worth a careful read.


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

[final reviewer] Tanmay Singla (@Tanmay182003) Two more non-merge commits landed after your approval on 894fd333, on top of the three listed above (57dbb8e9, c1cac563, f50b13c). Everything else since then is merges from main.

  • a11b7b3 Port the pnpm fixes onto main's private DiskSnapshot root (2 files, +11/−8). Main's Decide whether a hosted patch is pinned through lockfile discovery alone #1058 made DiskSnapshot::root private, so root_only_workspace_breaks_add in hosted/engine.rs now reads the root through view.disk_root(), and a test initializer fills main's three new RewriteOptions fields. It's a compile fix with no new behavior.
  • c54cf04 Compare the pnpm settings prefix without the verbatim prefix (1 file, +4/−1). It's a test-only Windows fix: the expected root in pnpm_settings_come_from_the_governing_workspace_root now strips \\?\.

Head f172f2d is green (ci-ok, clippy), mergeable, with no open threads. I'm not sending it to the merge queue until you take another look at that head.


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 9, 2026
Merged via the queue into main with commit 60300b8 Oct 9, 2026
467 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-pnpm-open-issues branch October 9, 2026 07:19
Mikola Lysenko (mikolalysenko) added a commit that referenced this pull request Oct 9, 2026
@mikolalysenko @claude
Add #1007, #1036, #1041, #1193, #1217, #1218 and #1230 to the 5.0.0 r…
75d69ae
…elease notes

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This was referenced Oct 9, 2026
CI perf (settings): merge queue builds 5 entries at a time — a 13-PR burst took 100 min to drain on a 21-min CI run (~21 min per PR past the 5th) #1248
Open
Use one package target grammar for get, remove, rollback and the UUID shortcut #1034
Merged
Path-scoped agent scan packages/a and rollback packages/a skip a workspace member's npm alias (lp@npm:left-pad) under install-strategy=linked, while its plain links are in scope (exit 0, success) #1266
Closed
Hosted pnpm rollback/remove in a sharedWorkspaceLockfile: false workspace leaves trustLockfile: true without the documented pnpm_trust_lockfile_left warning #1268
Closed
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 28, 2026
Fix pnpm trust warning for per-member locks (#1268) #1781
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments
@Tanmay182003 Tanmay Singla (Tanmay182003) Tanmay182003 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Agent-mode apply in a pnpm workspace reports each member-linked package twice, inflating the --json skipped count with duplicate already_patched events Hosted scan with pnpm gitBranchLockfile pins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml Hosted scan on a pnpm workspace with sharedWorkspaceLockfile: false ignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing Vendored pnpm 12 with packageManager set: the two-document pnpm-lock.yaml makes vendor refuse, and vendor --revert, rollback and the hosted takeover half-revert the project and break frozen installs Global agent mode on pnpm 12 (and 11 without the global virtual store) patches only one of the per-install copies of a package, reports success, and VEX attests not_affected
Hosted scan on a Rush repo with pnpm 11/12 reports success, but rush install then fails with ERR_PNPM_TARBALL_URL_MISMATCH, or (pnpm 11.0.0) silently installs the upstream package Hosted scan on a Rush repo with subspaces never emits redirect_rush_repo_state_stale, so rush install fails on the shrinkwrap hash check with no warning Hosted and vendored modes create a packages: ['.'] pnpm-workspace.yaml that turns a single-package project into a workspace, so pnpm add <pkg> fails with ERR_PNPM_ADDING_TO_ROOT on pnpm 9.0–10.4 Agent-mode scan packages/<member> finds nothing in a pnpm workspace (exit 0), while rollback packages/<member> selects the same packages Vendored pnpm: unwinding a vendored package whose dependency is also vendored clobbers the child's lock wiring — remove <parent> breaks frozen installs, the hosted takeover silently unpatches the child, and rollback fails forever

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@mikolalysenko @Tanmay182003 @claude
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.