Bug hunt ledger: pnpm #303
Replies: 18 comments
|
[agent] 2026-09-30: pnpm bug-hunt run Tested: main This is the first run: no earlier ledger, and no open Cells
Issues
False positives ruled out
Probe
Next
|
|
[agent] 2026-10-01: pnpm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Probe
Next
|
|
[agent] 2026-10-01: maintainer note: test global ( This is a maintainer request, not a run report. Add it to the top of the backlog and keep it there until the cells below are covered. Ask: make sure we correctly scan global installs when Where pnpm puts global installs: What to check (prove each with a real global install, not by reading source):
Add OS × pnpm version cells for |
|
[agent] 2026-10-01: pnpm bug-hunt run Tested: main v5 harness note: hosted pins are recognised only on the named patch server, so set Re-triage
Cells (global mode, Linux)
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-01: pnpm bug-hunt run Tested: main Re-triage
Cells
IssuesFalse positives ruled out
Next
|
|
[agent] 2026-10-01: pnpm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: pnpm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: pnpm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: handover from the Bun bug-hunt routine (ledger #306) Finding (low severity, generic to pnpm-shaped stores, not filed): agent-mode
Generated by Claude Code |
|
[agent] 2026-10-02: handover from the vlt bug-hunt routine (ledger #307) #601 (#601) also reproduces on pnpm 10.28.0 (Linux, main Suspect: |
|
[agent] Handover from the npm bug-hunt routine (#302): agent mode writes through workspace links into first-party source With npm, agent-mode The suspect code is shared by the whole npm family:
with Repro script (npm): see the issue body. |
|
[agent] 2026-10-03: pnpm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-03: pnpm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-03: pnpm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
[agent] Progress ledger for the scheduled pnpm bug-hunt routine (label pm:pnpm).
Last updated: 2026-10-03 (run 14), main
045d7ec, latest release 4.0.0.Method: real pnpm installs. Hosted, vendored and global agent mode run against a local Python mock of the patch API (batch, by-package, view with inline blobs, package grant, hosted tarball,
/registry/<name>/<ver>mirror). On v5, setSOCKET_PATCH_SERVER_URL=<mock>andSOCKET_NPM_REGISTRY=<mock>/registryso that hosted pins are recognised and rollback can restore upstream. The oracle is a marker prepended toindex.js, checked after a fresh--frozen-lockfileinstall against a dead registry, or by running the global tool. The repo's pinned matrix (.github/workflows/pnpm-compatibility.yml) already covers plain hosted and vendored installs on pnpm 1–12. This ledger tracks what it doesn't.Coverage matrix
Project modes (cells before run 3 were tested on main
f6b7fb9; "v5" marks cells re-run on2463257):.pnpmpnpm_trust_lockfile_leftwarning)packageManager(two-doc lock)Run 6 additions (main
61cfb9b, Linux):sharedWorkspaceLockfile: falseconfigDependencies(two-doc on 11+)configDependenciesRun 7 additions (main
61cfb9b, Linux):npm:agent / hostedRun 8 additions (main
61cfb9b, Linux):vendor_lockfile_version_unsupported)Run 9 additions (main
61cfb9b, Linux):gitBranchLockfile(both locks / branch lock only)lockfileIncludeTarballUrlpin + fresh frozenredirect_npm_no_lockfile(not filed; see #417)Run 10 additions (main
203e092, Linux):lockfile-dir=..gitBranchLockfileRun 11 additions (main
045d7ec, Linux):rollback)#636 first bad commit:
09956d90(#247). Release 4.0.0 is byte-exact.Run 12 additions (main
045d7ec, Linux):workspace:*member /link:dir /file:dir named like a patched pkg (#626)modulesDir: depsnode-linker=pnpvirtualStoreDirMaxLength(hashed dirs)node_modules/.pnpm)Run 13 additions (main
045d7ec, Linux):vexover the upstream install:modulesDirvirtualStoreDiroutside project, transitivevirtualStoreDirin project, transitivepnpm patch-commitafter hosted pin, then rollback + fresh frozennode_modules/.pnpm)#696 first bad commit:
cf8150b(#251). Release 4.0.0 is honest withmodulesDir.Run 14 additions (main
045d7ec, Linux, Rush 5.180.0):rush installpreventManualShrinkwrapChanges)--product/ rollbackremoveone of two pins / last pin--no-prefer-frozen-lockfileERR_PNPM_TARBALL_URL_MISMATCH; env trust → upstream)ERR_PNPM_TARBALL_URL_MISMATCH; env trust → pass)Default isolated linker + alias: pass on 7.33.7 / 9.15.9 / 10.34.5 / 11.28.3 / 12.8.1 (one shared
.pnpmcopy).#492 also reproduces on pnpm 7.33.7 (there's no root lock at all, only
redirect_pnpm_no_lockfile).Hosted
--frozen-lockfile [--offline]over an upstreamnode_modulesor warm store (run 5): VEX stays honest on 9.15.9 / 10.34.5 / 11.28.3 / 12.8.1 (pass)."Edge shapes" means a whole-document flow mapping, a
...document end, and quoted orkey :top-level keys.Global mode (
-g, v5 main2463257):pnpm root -glayout--mode hostedrefusalglobal/5/node_modules,virtualStoreDir: ../.pnpm.pnpm)global/v11/<hash>/→ global virtual storestore/v11/linksenableGlobalVirtualStore: falseglobal/v11/<hash>/node_modules/.pnpmglobal/v11/<hash>/node_modules/.pnpmBacklog
-gmode): the Linux cells are done. Still to do: macOS and Windows (corepack, standalone and npm-installed pnpm;PNPM_HOMEwith spaces or unicode; Windows%LOCALAPPDATA%\pnpm), and an unwritable prefix as a non-root user. Full checklist in the 20261001T040000Z entry. Needs a probe branch.bughunt/pnpm/20260930-virtual-store.git push --deletefailed through the git proxy in runs 1, 3 and 10, and was denied by the permission policy in runs 2, 5–9 and 11–14, so a maintainer needs to do it. macOS and Windows probes stay on hold until branch cleanup works.modulesDiris set (pnpm 10.12+), because the missed install is treated as "nothing installed" #696 / Agent mode ignores pnpm'smodulesDir: on pnpm 10.12+ every installed package is "not installed", and apply exits 0 leaving it unpatched #661 follow-ups:modulesDirin the globalconfig.yaml/rc, andmodulesDir+virtualStoreDirtogether. When fixed, check that GVS and out-of-projectvirtualStoreDirtransitive deps also stop attesting.pnpm.overridesin package.json and (lockfile 9.0) a scaffolded pnpm-workspace.yaml behind #636 follow-ups: a hosted → vendored takeover with several packages, then revert, and a user-createdpnpmtable with several vendored packages.removeon legacy locks (5.4 / 6.0), on a two-document lock (pnpm 12packageManager), and vendoredremove.-g: re-check exit codes under Fix apply failing when patched deps are skipped (#403) #555's skip semantics on 11.28.3 / 12.8.1.package-import-method=cloneon reflink (needs CI).gitBranchLockfilepins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml #556 follow-ups: merging branch lockfiles after a hosted pin, and agentvexon the branch.overrides:in pnpm-workspace.yaml: the new package.jsonpnpm.overridesshadows the user's overrides, so frozen installs fail and a re-lock drops them #360, Agent mode ignores pnpm's virtualStoreDir: transitive dependencies are reported package_not_installed with a custom virtualStoreDir or the global virtual store #362, 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, Vendored pnpm 12 withpackageManagerset: the two-document pnpm-lock.yaml makes vendor refuse, andvendor --revert, rollback and the hosted takeover half-revert the project and break frozen installs #466, Hosted scan on a pnpm workspace withsharedWorkspaceLockfile: falseignores the per-package pnpm-lock.yaml files and reports success while redirecting nothing #492, Hosted scan with pnpmgitBranchLockfilepins the stale pnpm-lock.yaml and reports success, while pnpm installs unpatched bytes from pnpm-lock.<branch>.yaml #556, Hosted pnpm rollback drops the upstreamtarball:URL from locks written withlockfileIncludeTarballUrl, so the restore isn't byte-exact #557, Hosted scan/get run from a pnpm workspace member (or withlockfile-dir=..) ignores the parent pnpm-lock.yaml and reports success while pinning nothing #590 (PR Fix hosted scan from a workspace member pinning nothing or the wrong files (#590, #417) #598), Agent-mode apply skips a bundled copy inside another vlt/pnpm store entry whenever the package is also installed normally, and VEX attests not_affected #601 (PR Fix npm store copies missed by agent apply and vex (#601, #603) #605), Agent-mode apply writes through node_modules links into first-party source (npm workspace members, file: deps, npm link targets), overwriting the user's code, and rollback restores upstream bytes instead #626 (PR Fix agent mode patching linked first-party source (#626) #634), Agent-mode apply in a pnpm workspace reports each member-linked package twice, inflating the --json skipped count with duplicate already_patched events #633, Vendored pnpm with two or more packages: vendor --revert and rollback leave an emptypnpm.overridesin package.json and (lockfile 9.0) a scaffolded pnpm-workspace.yaml behind #636, Agent mode ignores pnpm'smodulesDir: on pnpm 10.12+ every installed package is "not installed", and apply exits 0 leaving it unpatched #661 / Hosted pnpm vex attests not_affected over an unpatched install when pnpm'smodulesDiris set (pnpm 10.12+), because the missed install is treated as "nothing installed" #696 (PR Fix pnpm modulesDir store being skipped (#661, #696) #698), Hosted scan on a Rush repo with pnpm 11/12 reports success, butrush installthen fails with ERR_PNPM_TARBALL_URL_MISMATCH, or (pnpm 11.0.0) silently installs the upstream package #713 and Hosted scan on a Rush repo with subspaces never emitsredirect_rush_repo_state_stale, sorush installfails on the shrinkwrap hash check with no warning #714 when fixes land.vendor_lockfile_crlf_unsupportedrefusal; check that hosted handles the same checkout).Known non-bugs
patches-api.socket.devand (for the Rust client)registry.npmjs.orgare unreachable from the sandbox. Mock the API and pointSOCKET_NPM_REGISTRYat a mirror.SOCKET_PATCH_SERVER_URL,rollbacksays "Manifest not found". That's a fixture artifact.trustLockfile: trueand warnpnpm_trust_lockfile_left. A workspace file that exactly matches hosted mode's scaffold is deleted, including a user's ownpackages: ['.']file that the trust append made identical to it (CLI_CONTRACT, upstream restore).enableGlobalVirtualStorewhenCIis set, so the global-virtual-store cells don't engage on GH runners with pnpm 10..npmrcforvirtual-store-dir/enable-global-virtual-store. Put them inpnpm-workspace.yaml, or in the globalconfig.yaml.pnpm root -g/pnpm add -gfail unless$PNPM_HOME/binis onPATH. Put it there in fixtures.pnpm-lock.yamlorpnpm-workspace.yaml(vendor_lockfile_crlf_unsupported), a BOM package.json (vendor_pkg_json_unsupported), an inline / flowoverrides:mapping (vendor_override_conflict, unit-tested), andpatchedDependencieson the target (vendor_lock_entry_unsupported; the detail wrongly says "peer-suffixed snapshot key", which is cosmetic).vexattests from the committed artifact plus lock wiring even when the tree isn't installed. That's by design (CLI_CONTRACT "Manifest-less VEX").vex -gneeds--productoutside a project ("Could not auto-detect a top-level product PURL").get <purl>for an uninstalled package reportssuccess, applied: 1when another manifest entry applies. The nested apply fails only when nothing matches. It's not pnpm-specific (noted on Agent mode ignores pnpm's virtualStoreDir: transitive dependencies are reported package_not_installed with a custom virtualStoreDir or the global virtual store #362).package.jsoncomes back 2-space-indented after vendor + rollback. There's no indent to detect, and indented files round-trip byte-exactly, so it's cosmetic.node_modules: a frozen install keeps the upstream bytes. That's documented in theredirect_pnpm_trust_lockfilewarning, and VEX doesn't attest it.package.jsonpnpm.overridesis ignored on vendored projects. The workspace-file override is what takes effect, so this is noise only.vex --output /dev/stdouthang when stdout is a pipe is not pnpm-specific.catalogs:entry) and peer-suffixed snapshot keys withvendor_lock_entry_unsupported("this lock shape is not supported yet"). It's loud and writes nothing. Hosted handles both.configDependenciescopy (node_modules/.pnpm-config/) stays unpatched under hosted mode while VEX attests the regular copy. Config deps run only at install time, and pnpm 10 keeps their integrity inpnpm-workspace.yaml.--vendor-source buildwas removed), so offline vendoring with only a staged manifest fails withvendor_service_offline_conflict. Fixtures need the mock grant to match the manifest UUID.rush update --fullre-resolves the Rush lock and drops the hosted pin, likepnpm update. VEX then honestly reports nothing to attest.dependenciesMeta.injected("importer dependencies meta (undefined) doesn't match"). That's upstream pnpm, not socket-patch.--storerather than--store-dir. Fixture notes.patchedDependenciesedit to the same file overwrites it with the verified patched content and warnscontent_mismatch_overwritten(documented default mismatch policy;--strictrefuses). Hosted composes both patches, andvexthen declines (no_applicable_patches), because the file matches neither hash.trustLockfile: false(any YAML spelling) and warnsredirect_pnpm_trust_lockfilewith the remedy. The following frozen install fails, which is documented.vendor_lockfile_version_unsupported, and pnpm 7/8 workspace locks withvendor_lock_entry_unsupported. pnpm 7/8 vendored locks carry an absolutefile:specifier (vendor_pnpm_legacy_absolute_specifier), so a moved checkout needspnpm install --offline --no-frozen-lockfileonce. Both are documented.package.jsonpnpm.patchedDependencies. Put it inpnpm-workspace.yaml.vendor_lockfile_missing(partial_failure). Hosted's silent success in the same layout is Hosted scan/get run from a pnpm workspace member (or withlockfile-dir=..) ignores the parent pnpm-lock.yaml and reports success while pinning nothing #590.package.jsonwithout a trailing newline gains one after vendor + revert. That's a fixture artifact; files that end in a newline round-trip byte-exactly.file:tarball host (.pnpm/bundler@file+…) is patched correctly, so it doesn't reproduce Agent-mode apply skips a bundled copy inside another vlt/pnpm store entry whenever the package is also installed normally, and VEX attests not_affected #601..npmrckeys must be kebab-case (modules-dir,virtual-store-dir-max-length); camelCase is silently ignored. pnpm 7–10.11 keep the virtual store innode_modules/.pnpmeven withmodules-dir, so agent mode passes there.file:directory dependencies are copied into the store (.pnpm/<name>@file+…), so patching that copy is correct and doesn't touch the source (unlikelink:/workspace:, Agent-mode apply writes through node_modules links into first-party source (npm workspace members, file: deps, npm link targets), overwriting the user's code, and rollback restores upstream bytes instead #626).scan --mode hosted --vexattests from this run's records without hash verification, so it saysnot_affectedover an upstream install (CLI_CONTRACT(redirected)row). Use standalonevexafter the install as the oracle.pnpm patch-commitover a hosted pin makesvexdecline withhash_mismatch(the file matches neither hash). That's honest. Rollback keeps the user's patch and restores the upstream pin.patch-commitunderCI=trueruns a frozen install and fails withERR_PNPM_LOCKFILE_CONFIG_MISMATCH(fixture note: useconfirmModulesPurge=false, notCI). A mock/registrymust serve the real npmjs tarball, or a rollback restores a foreign integrity.package.json, sovexneeds--productthere (product_undetected), like-g.--no-prefer-frozen-lockfile). Rush subspace fixtures needcommon/config/subspaces/<name>/folders created andcommon/config/rush/.pnpmfile.cjsremoved beforerush update.pnpm install --no-prefer-frozen-lockfilere-resolves hosted pins to upstream even withtrustLockfile: true(9 / 10 / 12 keep them). That's upstream pnpm behaviour; the defaultpnpm installand--frozen-lockfilekeep the pin. It's tracked inside Hosted scan on a Rush repo with pnpm 11/12 reports success, butrush installthen fails with ERR_PNPM_TARBALL_URL_MISMATCH, or (pnpm 11.0.0) silently installs the upstream package #713 because Rush uses that flag by default.All reactions