Repository navigation
Hosted pnpm rollback/remove in a sharedWorkspaceLockfile: false workspace leaves trustLockfile: true without the documented pnpm_trust_lockfile_left warning #1268
Description
[agent] Found by the scheduled pnpm bug-hunt routine (ledger #303).
Summary
Since #1007 (the #492 fix), scan --mode hosted pins the per-member pnpm-lock.yaml files of a sharedWorkspaceLockfile: false workspace and adds trustLockfile: true to the root pnpm-workspace.yaml. When rollback (or remove <uuid>) restores those member locks, the workspace file keeps trustLockfile: true, as documented, but the pnpm_trust_lockfile_left warning that the contract promises never fires. The same layout with a shared root lock does warn.
The cause is that cleanup_side_config only acts when the root lock was restored:
let restored_pnpm = view.staged.keys().any(|k| k == "pnpm-lock.yaml");
if restored_pnpm && !still_hosted(view, &["pnpm-lock.yaml"], ctx).await {A restored packages/a/pnpm-lock.yaml is staged under packages/a/pnpm-lock.yaml, so restored_pnpm is false and the whole trust-cleanup branch is skipped. still_hosted also checks only the root lock, so a scoped rollback that restores the root lock while a member lock stays hosted would get the opposite message ("no lock entry needs it any more").
Impact
trustLockfile: true turns off pnpm 11+'s check that lockfile tarball URLs match the registry, which guards against lockfile tampering. After a rollback that reports success, a per-member-lock workspace keeps that check disabled, and nothing tells the user to remove the line. In the shared-lock layout the warning is the only mitigation that v5 offers (CLI_CONTRACT: "v5 records no provenance"), and here it's missing.
Repro (Linux, main a80b89e, pnpm 12.10.1; local mock of the patch API serving left-pad@1.3.0)
mkdir -p ws/packages/a && cd ws
echo '{"name":"root","version":"1.0.0","private":true}' > package.json
echo '{"name":"a","version":"1.0.0","dependencies":{"left-pad":"1.3.0"}}' > packages/a/package.json
printf 'packages:\n - packages/*\nsharedWorkspaceLockfile: false\n' > pnpm-workspace.yaml
pnpm install
socket-patch scan --mode hosted --json --yes # pins packages/a/pnpm-lock.yaml, appends trustLockfile: true
socket-patch rollback --json --yes # or: socket-patch remove <uuid> --json --yes
# status success, hosted.reverted ["pkg:npm/left-pad@1.3.0"], warnings: [reinstall_required]
tail -1 pnpm-workspace.yaml # trustLockfile: trueControl: change the last line of pnpm-workspace.yaml to sharedWorkspaceLockfile: true (so the root lock is pinned). Rollback then warns ["reinstall_required","pnpm_trust_lockfile_left"].
Expected vs actual
- Expected (CLI_CONTRACT.md, upstream restore and the warning table): "a
pnpm-workspace.yamlthat is exactly the scaffold hosted mode creates is deleted oncepnpm-lock.yamlis no longer hosted, otherwise a remainingtrustLockfile: truewarnspnpm_trust_lockfile_left". The trigger is that no npm-family lock entry is hosted any more. - Actual: with per-member locks, no lock is hosted any more and
trustLockfile: trueremains, but there's no warning (rollback and remove both exit 0).
Matrix (Linux, a80b89e)
| pnpm | shared root lock (control) | sharedWorkspaceLockfile: false, rollback |
sharedWorkspaceLockfile: false, remove |
|---|---|---|---|
9.15.9 (.npmrc shared-workspace-lockfile=false) |
— | no warning | — |
| 10.34.6 | warns | no warning | — |
| 12.10.1 | warns | no warning | no warning |
In every cell the scan pinned only the member lock, and the rollback restored it (0 hosted URLs left).
First bad commit: 60300b8 (#1007). Before it, hosted mode didn't pin member locks at all (#492), and release 4.0.0 predates that change.
Suspect code
crates/socket-patch-core/src/patch/redirect/upstream/npm.rs:1630-1631 (cleanup_side_config): the check should cover any restored */pnpm-lock.yaml that the root pnpm-workspace.yaml governs, and still_hosted should scan those member locks too.
No probe runs (Linux only).
Activity
mikolalysenko commentedon Oct 9, 2026
[agent] Triaged: priority:p1 (pnpm). Not a duplicate and no open PR covers it; cause is
cleanup_side_configkeying the trust-cleanup branch on the rootpnpm-lock.yamlonly.Generated by Claude Code
mikolalysenko commentedon Oct 9, 2026
v5 triage: P3, not a release blocker. Rollback restores the dependency locks; the remaining defect is a missing warning about trustLockfile configuration. Drop P1 to P3.
This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.