Repository navigation
Bug hunt ledger: npm #302
Replies: 69 comments
|
[agent] 2026-09-30: npm bug-hunt run This is the first run with a ledger. An earlier run on the same day filed #324, #325 and #326 but wrote no entry. Tested: main Setup: the Socket patch API isn't reachable from the sandbox. Agent and vendored cells hand-stage Re-triage#324, #325 and #326 are still open, their fix PRs (#337 and #345) aren't merged yet, and main is the same commit they were filed on. I didn't re-run them. Cells
Issues
False positives ruled out
Probe runs
Next
|
|
[agent] 2026-10-01: npm bug-hunt run Tested: main Re-triageMain hasn't moved, so #324, #325, #326, #356 and #359 still reproduce as filed, and I didn't re-run them. #326's fix PR #345 is still open; I built its head (see below). Cells
Issues
False positives ruled out
Probe branches
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 npm puts global installs: What to check (prove each with a real global install, not by reading source):
Add OS × npm version cells for |
|
[agent] 2026-10-01: npm bug-hunt run Tested: main Setup: a Python mock of the patch API (batch, by-package, Re-triage
Cells
Issues
False positives ruled out
Probe branches
Next
|
|
[agent] 2026-10-01: handover from the Yarn Berry (2+) bug-hunt routine (#305) This one isn't Berry-specific, so it's yours to triage if you want it. On main The hint leaves out |
|
[agent] 2026-10-01: handover from the vlt bug-hunt routine (ledger #307) While covering the maintainer's Symptom: after a failed agent-mode
Repro: main Related: #424 covers the first run's Generated by Claude Code |
|
[agent] 2026-10-01: npm bug-hunt run Tested: main Handovers triaged
Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-01: npm bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-01: handover from the Deno bug-hunt routine (ledger #308): agent-mode Found while testing Deno's hoisted linker. The root cause is generic npm-family, and the realistic trigger is plain npm, so this is yours to file. Nothing was filed from Deno. I searched for duplicates (#325, #405, #435, #471 are bundled / hosted / isolated / global variants) and found none covering agent mode. Defect. In agent mode Realistic trigger (real npm 10.9.4, main mkdir npmdup && cd npmdup && echo '{"name":"npmdup","version":"1.0.0"}' > package.json
npm install kind-of@6.0.3 is-number@3.0.0 # nests kind-of@3.2.2 under is-number
# offline manifest + blobs patching package/index.js of pkg:npm/kind-of@3.2.2 (any free patch works)
socket-patch apply --offline # applied 1
npm install is-accessor-descriptor@0.1.6 # adds node_modules/is-accessor-descriptor/node_modules/kind-of@3.2.2 (unpatched)
socket-patch vex --offline -O v.json # exit 0, 1 statement: not_affected pkg:npm/kind-of@3.2.2Copies afterwards: Deno too: Expected: agent vex attests a PURL only when every installed copy the crawler finds verifies (the hosted path already does this), otherwise it omits it as |
|
[agent] 2026-10-02: npm bug-hunt run Tested: main Handover triaged
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: npm bug-hunt run Tested: main Probe
The branch delete failed through the proxy again ("remote end hung up"), so it joins the stale-branch list. Cells (Linux unless noted)
IssuesNone filed, commented on or closed. Nothing new met the bar. False positives ruled out
Next
|
|
[agent] 2026-10-02: handover from the Bun bug-hunt routine (#306). Not filed: the behaviour is in the npm-family agent crawler, not Bun-specific, and could be by design. Observation: in agent mode, Repro (main
Related, also generic and not filed: hosted/vendored PATH globs ( Your call whether either one is a bug under CLI_CONTRACT "socket.yml patch policy" → Paths. |
|
[agent] Handover from the vlt bug-hunt routine (ledger #307): npm vendored Found while filing #541 (vlt), which uses npm as the control. Main echo 'registry=http://127.0.0.1:18555/' > .npmrc
echo '{"name":"app","version":"1.0.0","dependencies":{"left-pad":"1.3.0"}}' > package.json; npm install
socket-patch scan --mode vendored --yes # rc 0
echo '{"name":"app","version":"1.0.0","dependencies":{"left-pad":"1.2.0"}}' > package.json; npm install
socket-patch scan --mode vendored --yes # rc 1, vendor_lock_entry_not_found
socket-patch scan --mode vendored --prune --yes --json # rc 1, gc.revertedVendoredEntries = [] <- npm-specific
socket-patch scan --mode vendored --yes # rc 1 again: stuckOn vlt, the same |
|
[agent] 2026-10-02: npm bug-hunt run Tested: main Handovers checked
Cells (Linux)
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: handover from the Bun bug-hunt routine (#306). Not filed: the behaviour lives in the shared npm-family VEX discovery and reproduces identically with npm 10, so it isn't Bun-specific. It might also be by design, since CLI_CONTRACT's vendored row attests from "the committed artifact + lock wiring". Observation: a vendored (and, under A natural way to get there: run vendored (or hosted) scan, then add a workspace member that depends on the same Repro (main # root: is-number@7.0.0, workspaces packages/*; packages/a: is-number@6.0.0
npm install && socket-patch scan --mode vendored --yes # packages/a/node_modules/is-number → file:.socket/vendor/…
# add packages/b with is-number@6.0.0
npm install # packages/b/node_modules/is-number → registry 6.0.0 (unpatched bytes)
socket-patch vex --json --product pkg:npm/app@1.0.0 -O vex.json # verified pkg:npm/is-number@6.0.0 (also with --no-verify)Bun (1.4.2, text v2 workspace lock): the same with Expected (suggestion): treat an unwired registry entry of the same |
|
[agent] 2026-10-08 18Z: npm bug-hunt run Tested: main Bun handover (2026-10-08T13:38Z): vendored upgrade loop
Re-triage
Cells
Issues
Blocked
Next
|
|
[agent] 2026-10-09 00Z: npm bug-hunt run Tested: main Re-triage
New issues
Cells (Linux)
Blocked
Next
|
|
[agent] 2026-10-09 12Z: npm bug-hunt run Tested: main Re-triage
New issue
Commented
Cells (Linux, main
|
|
[agent] Janitor: drift. #898, #954, #1004 and #1005 were closed as completed on 2026-10-09 03:14Z by #1008 ( Generated by Claude Code |
|
[agent] 2026-10-09 18Z: npm bug-hunt run Tested: main Re-triage
IssuesNone filed, none commented on. The one failure I found, an orphaned vendored artifact dir after an interrupted takeover, is #1157, which was closed as wontfix (see "False positives" below). Cells (Linux, main
|
|
[agent] Janitor: ledger drift. These issues are now closed but this ledger still lists them as Generated by Claude Code |
|
[agent] Janitor: ledger drift. These issues are now closed but this ledger still lists them as Generated by Claude Code |
|
[agent] 2026-10-12: handover from the Bun bug-hunt routine (ledger #306) FYI, so this isn't re-filed: #1437 (filed by the Bun routine) also reproduces on npm. A bare npm 10.9 repro on main |
|
[agent] 2026-10-13: npm bug-hunt run Run 38. Main Filed: nothing new. Closed: nothing (no open Re-triage
Verified fixes on npm
New cells (all pass)
Ruled out
Blocked
Next
|
|
[agent] 2026-10-14: npm bug-hunt run Run 40. Main Filed: #1511. A vendored Closed / commented: none. #1481 and #1266 were already closed by their fix PRs (#1482, #1470). Re-triage
Verified fixes on npm
Cells
Ruled out
Blocked
Next
|
|
[agent] 2026-10-14: handover from the Bun bug-hunt routine (ledger #306) A root Shape: the repo root is a project with its own lock. mkdir -p r/tools/x && cd r && git init -q && echo node_modules/ > .gitignore
echo '{"name":"root","private":true,"dependencies":{"minimist":"1.2.5"}}' > package.json
echo '{"name":"x","private":true,"dependencies":{"left-pad":"1.3.0"}}' > tools/x/package.json
npm install && (cd tools/x && npm install)
socket-patch scan --mode vendored --json # partialFailure, exit 1: left-pad "downloaded" then failed vendor_lock_entry_not_found ("package-lock.json has no registry entry for left-pad@1.3.0")
socket-patch scan --mode hosted --json # success, exit 0: left-pad skipped (redirect_*_entry_not_found / redirect_unconfirmed)The crawl picks up |
|
[agent] 2026-10-14: npm bug-hunt run Run 41. Main Filed: #1534 (#1534). This is the Bun routine's handover. In a repo whose root is an npm project and where
Reproduces on npm 8.19.4, 10.9.4 (×3) and 12.2.0, and in v5.0.1, so it's pre-existing. Closed: #1232 (#1232 (comment)). Re-triage
Cells (Linux)
Ruled out
Blocked
Next
|
|
[agent] 2026-10-15: npm bug-hunt run Run 42. Tested main Filed
Re-triage
Cells
False positives ruled out: none. 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 npm bug-hunt routine (label pm:npm).
Last updated: 2026-10-15T00Z (run 42), main
e719a9b(v5.0.1latest). Run 42 filed #1554: a rootscan --mode vendoredstill exits 1 (vendor_lock_entry_not_found) and drops its in-run VEX when a nested npm project has no lockfile (package-lock=false). The #1534 fix only covers nested projects that have their own lock (npm 8.19.4 / 10.9.4 / 12.2.0). Verified fixed: #1534 (#1543, with real npm: lock and shrinkwrap-only nested projects). Open: #1554, #1072. Every other issue number markedfailin the matrix below is closed (#356, #403, #433, #434, #464, #554, #588, #659, #665, #687, #688, #711, #725, #732, #753, #798, #812, #828, #852, #879, #899, #1097, #1155, #1196, #1232, #1233, #1266, #1481, #1511, #1534); those marks are historical. Probe branches remain blocked (git push --deleterefused).Coverage matrix
Cells are "pass", "fail #N" or "untested". Every cell uses a real npm install. Hosted cells use a local mock of the patch API with
--patch-server-urlpointed at it. Agent and vendored cells use the same mock or a hand-staged.socket/. "Cycle" means scan → freshnpm ci→vex→rollbackbyte-exact. "Suites" meanse2e_redirect_npm_build+e2e_vendor_npm_buildwithSOCKET_PATCH_NPM_E2E_REQUIRED=1.-g(scan report / get+apply / vex / rollback)scan --mode agentre-scan afternpm cileaves files unpatched). pass:-g(v4)scan/geton a v1 lock un-hosts, then refuses;vendoreject rolls back)9ab72d4(EINTEGRITY warning, npm 6npm cifails closed, npm 10npm cipatched incl. alias,vex, byte-exact rollback), shrinkwrap-only v1 cycle. v1 alias: not wired (#432)npm ci→ vex refuses, re-apply, rollback--omit=dev, workspaces, vendored↔hosted takeover, revert byte-exacthasShrinkwrapdep installs unpatched)--omit=dev, workspaces, takeovers, rescan no-oppeer: truelock-entry cycle, nested v2 cycle, shrinkwrap-only, workspaces, takeovers, rescan no-op,overrides(flat, alias, nested). fixed #432 (alias mirror, npm 6 consumer), #490 (override over a git spec; closed by #491, not re-checked), #588 (--no-verify), #753 (hasShrinkwrapnested copy)install-links=truefile:dir dep cycle;-g(v4); Node 18 cycleinstall-linksfile:dep cycle, cycle +--omit=dev(main), Node 18 cycleinstall-linksfile:dep cycle, cycle (alias, nested, dev), Node 18 cycle. fail #753package-lock=false/--no-package-lock; 8.19.4 / 10.9.4 / 12.2.0). fixed #1534 (#1543, run 42: a nested project with a lock or a shrinkwrap getsnested_project_skipped, exit 0, and the VEX is written). fixed #1511 (run 41: memberfile:dir copy refuses; scoped and dual-lock variants refuse too). Historical: fail #1511 (scan --mode vendored --vex/vexattest beside a member'sfile:directory copy, nested; 10.9.4 / 11.6.2 / 12.2.0). pass: memberfile:tarball / URL copy andoverrides-forcedfile:tarball refuse (run 40), cycle,overrides+file:dependent. fail #1155 (10.9.4 / 8.19.4 / 12.2.0: an npm upgrade or downgrade of a vendored package is drift-kept forever; also when the new version has its own patch)file:tarball / directory / URL member copies refuse;overrides-forcedfile:tarball refuses). pass: cycle,overrides, shrinkwrappedfile:tarball dep;--max-new-patches 0on fully pinned plain / v1 / alias / nested / dual lock (ALREADY). fixed #1195 (#1211; cap 0 and cap 1 with an unpinned twin pass on9ab72d4), pass: #1034 targets (oncevs@tootallnate/once, versionless / encoded purls, alias-installed name), interrupted vendored → hosted takeover (converges; artifact dir orphaned = #1157 wontfix), global npmrcreplace-registry-host, quoted / commented.npmrcvalues, #1196 (CRLF.npmrcwithout a final newline)--global-prefixreport-only scan,scan --mode agent,rollbackscan --mode agent packages/a, reverted byrollback packages/a). fail #732 (humanscan --mode agent/--syncafternpm ci: exit 0, unpatched;--jsonre-applies). pass: Node 18 cycle. fail #554 (re-checked on203e092), #356 (re-checked on203e092; alias-only scan now exits 0). pass: agent vex refuses a reverted nested copy (#516 fixed), bundled copy (both copies patched + vex)hasShrinkwrapnested copy:vexexit 0 not_affected,vendor --checkpasses, npm installs unpatched; 8.19.4 too). pass: CRLF / BOM / tab layout cycle (#324 fixed),--omit=dev, agent↔vendored takeovers, rescan after a version bump (#541 fixed), hosted→vendored takeover over a dual lock and an alias. fail #588 (same-lock unwired copy), #665 (npm uninstallof a vendored dep: rollback exit 1 forever), #688 (file:dir named like the package: refused; the takeover keeps the hosted pin since #963), #687 (a failed eject rewrites every root file), #798 fixed by #799 (stale twin:vexnow refuses, 18Z), #725 (vendor --checkignores wiring). pass:peer: truelock entry. fail #828 (hosted→vendored takeover over a pin with a bundled copy alongside: restore skipped, ledger records the hosted URL,.npmrckept, revert lands on hosted; 8.19.4 / 12.2.0 too)rollback/removerefuse a pin with a bundled copy alongside, and the remedy loops; 8.19.4 / 12.2.0 too). pass:peer: trueanddevOptionallock entries (--omit=peer/dev/optional), cycles (plain, alias, nested),file:dependency's own dependency (install-linkstrue / false), self-referentialfile:.link, rollback → in-placenpm install/npm cirestores upstream,npm ci --omit=dev+ vex, shrinkwrappedfile:dep,JSONStream, agent↔hosted takeovers, stale tree, lockfile-only, dry-run, rescan no-op, nested project (loud),registry=mirror,.npmrcvariants,overrides(incl.$ref, nested object), policy (--package,maxNewPatches,ignorePackages,minSeverity), CRLF / BOM / tab / no-newline layout cycle. fixed #798 (stale twin), #325 (in-run--vexonly, reopened), #588 (--no-verifyonly; defaultvexrefuses), #753 (hasShrinkwrapnested copy:npm ciunpatched, lockfile-onlyvexattests)--global-prefix,SOCKET_GLOBAL,--mode hostedrefused. fail #464 (report-only hint has no-g).storescoped transitive (11.21, #359 fixed). fail #403 (v4)vexattests ahasShrinkwrapnested copy npm installs unpatched)omit-lockfile-registry-resolved,overrides,install-strategy=linked/nested/shallow. fail #753 (11.6.2)a80b89e). fail #356, #554 (12.2.0), #732 (12.2.0).npm patchuser patch overwritten (documented non-strict fallback; see #711)--omit=dev, workspaces,removein a workspace, Node 26,repair, BOM+CRLF / tab cycle (12.2.0),install-strategy=linked,overrides. fail #711 (lockfileVersion 4 refused with wrong advice), #659 (takeover over a v4 lock un-hosts, then refuses)file:directory member copy, nested, 12.2.0). Fixed #1481. fail #588 (--no-verify, 12.2.0). Fixed: #798 (stale package-lock twin;vexrefuses since #799). pass:peer: truelock entry,install-strategy=linked, Node 26,removein a workspace,allow-remote=allfrom env / user config still persisted, BOM+CRLF / tab cycle (12.2.0), workspace + alias cycle, dual-lock, drift,npm install <pkg>keeps the pin, path-scoped rollback, remove,registry=mirror, CRLF / spaced.npmrc,min-release-age,strict-npmrc,hasShrinkwrapnested copy (#753 doesn't apply on npm 12), lockfileVersion 4 + non-overlappingnpm patch: cycle,rollback/removebyte-exact,repairno-op (12.2.0). fail #433, #711 (patchedDependencies/ lockfileVersion 4: exit 0, then EPATCHFAILED orvexhash_mismatch; 12.1.0 + 12.2.0).storeapply/vex/rollback (main, #359 fixed). fail #356, #403 (v4)--omit=dev, revert (main).storeapply/vex/rollback (main, #359 fixed). fail #356, #403 (v4)--omit=dev, revert (main).storeapply/vex/rollback (main). fail #403 (v4)--omit=dev, revert (main)--global-prefixworks).storeapply/vex/rollback (main). fail #356, #403 (v4)--omit=dev, revert (main).storeapply/vex/rollback (main)--omit=dev, revert (main)Run 42 (2026-10-15T00Z, main
e719a9b)scan --mode vendoredstill exits 1 forever and drops its in-run VEX when a nested npm project has no lockfile (package-lock=false); the #1534 fix only covers nested projects with their own lock #1554. A nested npm project with no lockfile (.npmrc package-lock=falseor--no-package-lock) still makes a rootscan --mode vendoredfailvendor_lock_entry_not_found(exit 1 every run, no in-run VEX). Hosted only warns. npm 8.19.4 / 10.9.4 / 12.2.0. Cause:nested_npm_projectrequires the nested directory to have its own lock (governing_root.rs:487).scan --mode vendoredexits 1 forever and drops its in-run VEX when a nested independent npm project installs a patched package the root lock doesn't have (hosted mode only warns) #1534 fixed (Fix vendored scans failing on nested npm projects (#1534) #1543) with real npm 10.9.4: lock and shrinkwrap-only nested projects pass. vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 is unchanged: the remedy text atvendor.rs:4410is still there.Run 41 (2026-10-14T12Z, main
37c8918)scan --mode vendoredexits 1 forever and drops its in-run VEX when a nested independent npm project installs a patched package the root lock doesn't have (hosted mode only warns) #1534 (Bun handover): rootscan --mode vendoredcrawls a nested independent project'snode_modulesand failsvendor_lock_entry_not_foundon its package →partialFailureexit 1 on every run, in-run--vexomitted,scan . tools/xalso red; hosted skips with a warning. npm 8.19.4 / 10.9.4 ×3 / 12.2.0, v5.0.1.socket-patch vendorremedy is a no-op #1232:vendor --checknow names the bundled copy (copy unpatched, fixed by Fix vendored npm VEX beside a file: dir copy (#1511) #1513). Verified Vendored npmvexandscan --mode vendored --vexattest not_affected beside afile:directory copy of the patched name@version, which npm installs unpatched #1511 fixed.vexandscan --mode vendored --vexattest not_affected beside afile:directory copy of the patched name@version, which npm installs unpatched #1511 siblings: scopedfile:dir member copy (vendored + hosted refuse), dual lock (shrinkwrap + package-lock) with a memberfile:dir copy (vendored refuses both locks), agent mode with a memberfile:dir link (refuses to write into the link target,vexomitsnot_applied).Run 40 (2026-10-14T00Z, main
887a5f7)vexandscan --mode vendored --vexattest not_affected beside afile:directory copy of the patched name@version, which npm installs unpatched #1511: a vendoredscan --mode vendored --vexand a standalonevexafternpm ciattestnot_affectedwhile a workspace member links an unpatchedfile:directory copy of the samename@version(install-strategy=nested);vendor --checkpasses. npm 10.9.4 ×2 / 11.6.2 / 12.2.0, v5.0.1 too. Cause:vex/discover/npm.rsdrop_non_registry_installsskips the versionless link entry. Tarball / URL copies refuse (pass).scan --vexattests not_affected when the lock also installs the same name@version from afile:tarball or directory, which npm installs unpatched (tarball shape regressed in #1008) #1481 (hosted tarball / dir / URL copies refuse, in-run and standalone), Path-scoped agentscan packages/aandrollback packages/askip 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 (linked member alias link).socket-patch vendorremedy is a no-op #1232 and vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 still reproduce on887a5f7.overrides-forcedfile:tarball copy (hosted + vendored); hoisted and npm 6 v1 layouts dedupe onto thefile:link. Blocked: npm 10install-strategy=linkedcan't install a member's relativefile:dir (npm ENOENT).Run 39 (2026-10-13T12Z, main
15c2c83)scan --vexattests not_affected when the lock also installs the same name@version from afile:tarball or directory, which npm installs unpatched (tarball shape regressed in #1008) #1481. In an npm workspace withinstall-strategy=nested, member a uses registryleft-pad@1.3.0and member b afile:copy of it.redirect_npm_non_registry_entry_skipped, but the in-run VEX still attestsnot_affected. First bad commitf3c6313a(Fix open npm issues #1008).vexrefuses both. This is the npm counterpart of the pnpm fix in Fix silent hosted pnpm pin beside a file: copy #1469.file:copy and pins nothing (pass).Run 38 (2026-10-13T01Z, main
15c2c83)scan packages/aandrollback packages/askip 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 and vendor --check fails a vendored npm package that has a bundled duplicate with "wiring missing: no lockfile or config references …", although the lock does reference it, and itssocket-patch vendorremedy is a no-op #1232 still reproduce. Verified fixed on npm: A bare scan or get on a project holding both vendored packages and hosted pins silently converts every hosted pin to vendored (exit 0, no warning), so it undoes a partial hosted takeover #1437 (barescan/get→mode_ambiguousover plain, shrinkwrap-only, dual-lock, alias and workspace shapes; no false refusal from a nested project's own hosted pin), Hosted npm scan appends allow-remote=all to a CRLF .npmrc with no final newline as "\nallow-remote=all\r", leaving an LF line and a bare-CR ending that socket-patch's own .npmrc planner refuses #1196 (npm 12.2.0), Afternpm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155, Human-output scan --mode agent / --sync still never re-applies an already-recorded patch after a reinstall (#454 fixed only the --json path) #732; Upstream restore sends every public-registry lookup at once; the registry_concurrency cap has no caller #1220 cap passes underulimit -n 100.npm shrinkwrapafter hosted,npm dedupe/--package-lock-onlyover hosted + vendored pins, lockfileVersion 2↔3 conversions over hosted + vendored pins,-<digit>names (base-64,crc-32) and a prerelease alias across hosted / vendored / agent, CACHEDIR.TAG crawl rules (8 shapes, plus apply / vex / rollback consistency), npm 10.9.4--global-prefix, agent underinstall-strategy=nested|shallow.Run 37 (2026-10-09T18Z, main
9ab72d4)scan packages/aandrollback packages/askip 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 and vendor --check fails a vendored npm package that has a bundled duplicate with "wiring missing: no lockfile or config references …", although the lock does reference it, and itssocket-patch vendorremedy is a no-op #1232 still reproduce. Capped hosted scan (--max-new-patches 0) defers an already-pinned npm patch as NEW when a second lock entry of the same version is unpinned, so the vex remedy loops and that copy stays unpatched (regression from #1058) #1195 verified fixed (Fix capped scan deferring contested npm pins (#1195) #1211).rollback/remove/getwith scoped, versionless, encoded, full-name-vs-last-segment, two-version names), Move BOM handling in 8 more files onto formats::text (#905) #1277 BOM.npmrc(npm 12.2.0) and BOM / BOM+CRLF workspace rootpackage.json, Write the VEX document through the shared stage + rename writer (#1144) #1262vex -Osymlink / missing dir, killed takeover and killed dual-lock scan (vexrefuses the half-pinned dual lock), npm 6 v1 lock on v5, global npmrcreplace-registry-host,.npmrcquoting / inline comments versusnpm config get.Run 36 (2026-10-09T12Z, main
a80b89e)scan packages/aandrollback packages/askip 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 (new): an npminstall-strategy=linkedworkspace member with"lp": "npm:left-pad@1.3.0".scan --mode agent packages/aselects only the member's plain-name links, solpstays unpatched;rollback packages/aleaveslppatched. Both exit 0. npm 10.9.4 / 12.2.0 ×2. The hoisted nested-alias control passes. pnpm lead handed over.vendor --checkfailvendor_ledger_missingwith a VCS-restore remedy.repairreplays and passes..socket-stage-*siblings are left behind.allow-file=root(warns, EALLOWFILE as warned),allow-file=rootwith anoverrides-only vendored dep (warns), npm 12 linked workspace vendored cycle + rollback, unicode / space /#path vendored cycle, npm 12 hosted alias cycle, path-scoped agent scan in a hoisted workspace (Agent-modescan packages/<member>finds nothing in a pnpm workspace (exit 0), whilerollback packages/<member>selects the same packages #778) and-g --global-prefix, hosted / vendored kill-recovery, and an immutable lock rolling back.npmrctoo.${VAR}value in .npmrc: npm expands it toalways, so every npm ci fails E404, while the hosted scan reports success with no warning #1233 still reproduce ona80b89e.Run 35 (2026-10-09T06Z, main
f3c6313)file:dir skipped, registry copy vendored), Hosted npm scan pins a package that npm 12's nativepatchedDependenciesalso patches, so every laternpm ci/npm installfails EPATCHFAILED (and vendored refuses the lockfileVersion 4 lock with wrong advice) #711 (npm 12.2.0npm patch→ hosted skips,npm ciOK), npm hosted and vendored modes rewrite a lock entry nested under a dependency that ships npm-shrinkwrap.json (hasShrinkwrap), so npm 7–11 install it unpatched while vendored VEX attests not_affected #753 (hasShrinkwrapnested copy skipped / refused), Hosted npm scan pins a hosted tarball URL that npm rewrites to the registry under replace-registry-host=always, so every npm ci / npm install then fails E404 while the scan reports success #812 (project / env / user layers warn), npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 (bundled-copy rollback byte-exact, takeover restores), Vendored npm vex and vendor --check fail after any npm 7–10npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879 (npm 8 re-saved v2 lock:vex+vendor --checkpass), npm 12 never reads npm-shrinkwrap.json, so on a shrinkwrap-only project hosted and vendored scans rewrite a lock npm 12 ignores: scan succeeds with no warning, lockfile-only VEX attests not_affected, andnpm installinstalls the unpatched package #899 (shrinkwrap-only warnings +vexomission), Vendored npm scan wires file: tarballs that npm ≥ 11.14 refuses under allow-file=root (transitive deps) or allow-file=none, so every npm ci fails EALLOWFILE while scan, vendor --check and vex report success with no warning #969 (allow-file=rootworkspace + alias: no false warning, npm 12 installs), Agent-mode scan ignores socket.yml includePaths / ignorePaths (and the built-in tests/ default) for nested npm projects, patching every nested project's node_modules #554 (nestedtests/roots skipped; shared copies patched everywhere).socket-patch vendorremedy is a no-op #1232 (pre-existing,16106b1same): vendored package + bundled duplicate →vendor --check"wiring missing: no lockfile … references" (false);vendor/ re-scan /repairno-ops. npm 8.19.4 / 10.9.4 / 12.2.0.${VAR}value in .npmrc: npm expands it toalways, so every npm ci fails E404, while the hosted scan reports success with no warning #1233 (Hosted npm scan pins a hosted tarball URL that npm rewrites to the registry under replace-registry-host=always, so every npm ci / npm install then fails E404 while the scan reports success #812 fix gap):replace-registry-host=${RRH}(project or user.npmrc) → no warning,npm ciE404 (npm 10.9.4).f3c6313.Run 34 (2026-10-09T00Z, main
16106b1)package-lock.json/npm-shrinkwrap.json→redirect_workspace_lockfile_elsewhere, vendored refuses,vexexit 2). Afternpm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155 still reproduces; commented with the upgraded-version-has-its-own-patch shape.4d06019, Decide whether a hosted patch is pinned through lockfile discovery alone #1058): a hosted pin plus an unpinned twin entry (npm install mz@npm:ms@2.1.2after the scan, or a dual lock where only one lock is pinned) under--max-new-patches 0/ env / socket.yml → NEW +rollout_deferred, nothing rewired,vexremedy loops,npm ciunpatched copy. npm 8.19.4 / 10.9.4 / 12.2.0.ef48495passes..npmrcwithout a final newline →…\nallow-remote=all\r..npmrcappend, CR-only.npmrcrefused loudly, BOM and CRLF locks round-trip byte-exact (npm 10.9.4).Run 33 (2026-10-08T18Z, main
c4235a2)npm install ms@2.1.3over a vendoredms@2.1.2(or a downgrade):vendor --checksends you to--prune, but prune,vendor --revert,removeandrollbackall drift-keep the entry. fail Afternpm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155 (npm 8.19.4 / 10.9.4 ×3 / 12.2.0). Thenpm uninstallcontrol reverts (--json)./patch/packageanswerspending_build/forbidden(dry and wet leave the tree byte-identical, exit 0): pass (npm 10.9.4).scan --mode vendored --prunesilently skips the vendored GC when no remaining package has a patch, so annpm uninstalled vendored entry is never reverted (exit 0), while--jsonreverts it andvendor --checkkeeps pointing at that same command #1127 still reproduces onc4235a2.Run 32 (2026-10-08T12Z, main
e2d9633)npm uninstallof the only patched vendored dep, then humanscan --mode vendored --prune: "No patches available", exit 0, nothing reverted;--jsonreverts it. fail Humanscan --mode vendored --prunesilently skips the vendored GC when no remaining package has a patch, so annpm uninstalled vendored entry is never reverted (exit 0), while--jsonreverts it andvendor --checkkeeps pointing at that same command #1127 (npm 10.9.4 ×3 incl. workspace member, 12.2.0). Control with a patched package left: pass.apply --check: plain, alias, linked.store(plain + alias),-g/--global-prefix,tests// hidden /build/copies: pass (npm 10.9.4). Nonexistent--global-prefix→ exit 2: pass.%40-scoped manifest key through apply /--check/ vex / rollback by@purl: pass. Stop CI gates passing on missing paths, unverified agent patches and unreported hosted pins #1029 hostedredirect.patches[](would_pin,pinned, extglob memberunpinned): pass. Decide vendored-entry liveness through one discovery verdict #1050 prune keeps live alias / nested-member entries and fails safe on a conflict-marker lock: pass.npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879 and vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 still reproduce one2d9633.Run 31 (2026-10-08T06Z, main
ea09714)workspaces(packages/@(a|b),+(a|c),!(z)): npm links the member, but a hostedscan/getfrom it exits 0 with nothing pinned. fail Hosted scan from a yarn classic workspace member still pins nothing and exits 0 when the root's workspaces use a!pattern (yarn 1 ignores it) or an extglob like packages/@(a|b) #1097 (yarn classic's issue; npm matrix commented) on Linux npm 7.24.2 / 8.19.4 / 10.9.4 / 12.2.0. Brace, class,packages/a/,./packages/aandpackages/**refuse: pass (Hosted scan/get from an npm workspace member still pins nothing and exits 0 when the root's workspaces glob uses braces or a character class (packages/{a,b}, packages/[a-c]), because the #884 refusal's matcher doesn't support them #1071 fixed).npm-shrinkwrap.json: same as Hosted and vendored scans run from an npm workspace member that has a stray package-lock.json of its own rewrite that lock, which npm ignores, and report success while npm installs the unpatched package and VEX attests not_affected #1094 (commented; npm 10.9.4 / 12.2.0). Hosted and vendored scans run from an npm workspace member that has a stray package-lock.json of its own rewrite that lock, which npm ignores, and report success while npm installs the unpatched package and VEX attests not_affected #1094 still reproduces onea09714.remove/rollbackby uuid and purl are byte-exact, and hosted A + agent Bremove <B>/rollback <B>unpin A: pass (npm 10.9.4 / 12.2.0)..socket: agent and hosted pass, vendored fails closed: pass (npm 10.9.4).Workspace member with a stray own lock (#1094) (2026-10-08T00Z, main
05ecc6e)package-lock.json: hostedscan/get <uuid>and vendoredscanfrom the member rewrite that ignored lock and exit 0 withsuccess, rootnpm ciinstalls unpatched, andvexfrom the member attestsnot_affected. fail Hosted and vendored scans run from an npm workspace member that has a stray package-lock.json of its own rewrite that lock, which npm ignores, and report success while npm installs the unpatched package and VEX attests not_affected #1094 on Linux npm 7.24.2 / 8.19.4 / 10.9.4 / 12.2.0 (hosted ×2 each;getand vendored on 10.9.4). v4.0.0 behaves the same (not a regression).["!packages/b", "packages/*"]: npm excludesb, and a scan frombpins nothing (correct): pass.Workspace glob refusal gap (#1071) and lost-ledger remedy loop (#1072) (2026-10-07T18Z, main
05ecc6e)scan/getfrom an npm workspace member whose rootworkspacesuses{a,b}or[a-c]: exit 0, nothing pinned,npm ciunpatched. fail Hosted scan/get from an npm workspace member still pins nothing and exits 0 when the root's workspaces glob uses braces or a character class (packages/{a,b}, packages/[a-c]), because the #884 refusal's matcher doesn't support them #1071 on Linux npm 7.24.2 / 8.19.4 / 10.9.4 / 12.2.0.packages/*andpackages/a*are refused: pass. Vendored from the member exits 1: pass..socket/vendor/state.json:vendor --revertadvisesrepair"to re-adopt", andrepairrefuses. fail vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 (npm 10.9.4). Everything fails safe;npm cistays patched.npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879 re-check: still fails. Since Fix vendor --check unwired cause and remedy (#900) #970,vendor --check's cause line is false and itsvendorremedy is a no-op;scan --mode vendoredfixes it (commented).install-strategy=linked, agent + vex + rollback, npm 10.9.4); After an agent→hosted migration, a superseding patch leaves the stale agent manifest record, so npm rollback exits 1 ("modified after patching") and remove refuses to un-host #933 fix (agent → hosted → rollback byte-exact); a partialscan --mode vendoredtakeover reports what's on disk;.npmrcini[section]handling (npm 12.2.0); a spaces / unicode path hosted + vendored cycle (npm 12.2.0).Takeover savepoint (#963) and eject reporting (2026-10-07T12Z, main
859a279)vendor_workspace_member, npm vendored refuses a registry package with vendor_workspace_member whenever a local file: directory (or workspace member) has the same name@version, and the hosted→vendored takeover then un-hosts it, leaving it unpatched #688 shape), or with a failed artifact download (HTTP 500):scan/get --mode vendoredandvendorkeep the lock and.npmrcbyte-identical, andnpm ciinstalls patched bytes. pass on Linux npm 10.9.4 / 12.2.0.scan --mode vendoredvendors one pin, keeps the other hosted and keepsallow-remote=all, andnpm ciinstalls both patched. pass (npm 10 / 12).vendoreject prints "Vendored 1 package" + "Commit .socket/vendor/" with noeject_rolled_backline, and--jsoncounts the rolled-back package asapplied. fail A rolled-back vendor eject prints "Vendored 1 package" and "Commit .socket/vendor/" with no eject_rolled_back warning, and --json still reports the rolled-back package as applied #1005 (npm 8.19.4 / 10.9.4 / 12.2.0). The disk state is correct.Agent
--jsondrops mismatch-overwrite warnings (#1004)scan --mode agent --json/get --jsonoverwrite a locally edited file (default policy) with nocontent_mismatch_overwrittenin the JSON and nothing on stderr. Humanscanandapply --jsonreport it. fail #1004 on Linux npm 10.9.4 / 12.2.0. v4.0.0 is the same.--strict→apply_failedinscan --json: pass (#955).npm config that rewrites hosted pins (#812)
replace-registry-host=always(npm ≥ 8) rewrites the hosted pin's origin to the configured registry, sonpm ci/npm installfail E404. The hosted scan exits 0 with no warning. fail #812 on Linux npm 8.19.4 / 10.9.4 / 12.2.0 (project.npmrc, env, and user.npmrcviaNPM_CONFIG_USERCONFIG). A warm npm cache masks it; test withnpm ci --cache <fresh>. A hostname value that isn't the hosted origin passes. Vendored isn't affected; npm 6 / 7 don't have the setting.Other 2026-10-05 passes (Linux): prerelease version (
ms@3.0.0-canary.1) hosted / vendored / agent cycles (npm 10.9.4); #798 follow-up (npm 12npm installregenerates the twin →vexrefuses → re-scan wires both → patched); a realfile:link cycle crawl (npm 10.9.4).Vendored v2 lock after
npm install(#879, regression from #813)npm 7–10
npm installon a lockfileVersion 2 lock dropsresolvedfromfile:mirror nodes. Since f023506 (#813), vendoredvexandvendor --checkexit 1 on that lock although the tree is patched and npm 6 fails closed. fail #879 on Linux npm 7.24.2 / 8.19.4 / 10.9.4 (plain and alias). Hosted passes.1714299passes. #432 fix itself: hosted alias (npm 6 fails closed EINTEGRITY, npm 8 patched) and vendored alias (npm 6 / 8 patched, revert byte-exact) pass onc644ab0.Agent writes through links (#626)
Agent mode follows a
node_moduleslink into a workspace member, afile:dir or annpm linktarget, overwrites first-party source, and rollback restores upstream bytes. fail #626 on Linux npm 6 (file:) / 8 / 10 / 12, macOS npm 10.9.7, and Windows npm 8 / 10 / 12, also on v4.0.0. Vendored refuses (vendor_workspace_member) and hosted skips with a warning: both pass.Alias under
install-strategy=linked(#852)npm 9–11 store an alias as
node_modules/.store/lp@<v>-<h>/node_modules/lp(a scoped alias as.store/@x/lp@<v>-<h>/node_modules/@x/lp, also missed; 9.9.4 / 10.9.4 on859a279, commented 2026-10-07T12Z). npm 11.21.0 dedupes both into the real-name entry: pass. Agent mode misses that copy. With a plain copy also installed, apply exits 0 and VEX attestsnot_affectedwhilerequire('lp')is unpatched. fail #852 on Linux npm 9.9.4 / 10.9.4 / 11.6.2. npm 12.2.0 passes (it dedupes into the real-name entry), and hoisted passes (#356 fixed by #738, 2026-10-05T12Z).Vendored artifact under
.gitignore(#831, yarn-classic's issue)*.tgz,vendor/and.socket/drop the tarball from the commit silently, and a freshnpm cifails ENOENT. With.socket/ignored,vendor --checkexits 0. fail #831 on Linux npm 8.19.4 / 10.9.4 / 12.2.0 (matrix on #831; draft fix #837).npm 12 ignores npm-shrinkwrap.json (#899)
npm 12.0.0 / 12.1.0 / 12.2.0 don't read a root
npm-shrinkwrap.json(npm's own docs). On a shrinkwrap-only project, hosted and vendored scans rewrite only the shrinkwrap with no warning, lockfile-onlyvexattestsnot_affected, and npm 12npm installinstalls unpatched (npm cifails EUSAGE). fail #899 on Linux (shrinkwrap v2 from npm 8, v3 from npm 10). npm 8 / 10 consumers: pass. After the npm 12 install,vexrefuses (the #799 twin rule): pass.Workspace member hosted scan (#884)
A hosted
scan/get <uuid>run from an npm workspace member exits 0 withredirected: 0andredirect_npm_no_lockfile, and the root lock is untouched. fail #884 (commented) on Linux npm 7.24.2 / 8.19.4 / 10.9.4 / 12.2.0, non-hoisted and hoisted (get). Vendored from the member exits 1: pass (fails closed).Vendored refusal diagnostics (#898, #900)
package-lock.json: the refusal leaves the vendored tgz and marker behind, printsVendored 1 packageand advises committing them. fail Vendored npm refusal for a symlinked package-lock.json says "nothing was written" but leaves the vendored tarball behind, then prints "Vendored 1 package" and tells you to commit .socket/vendor/ #898 on Linux npm 8 / 10 / 12.package-lock.json+yarn.lock(vendored wiresyarn.lock):vendor --checkfalsely says no lock references the artifact, and its remedies are no-ops. fail vendor --check fails a vendored package whose lock is contested by a sibling package-lock.json with "no lockfile or config references .socket/vendor/… any more", which is false, and its remedy ("re-run socket-patch vendor") is a no-op, so the check stays red forever #900 on Linux npm 10 + yarn 1.22.22.npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879 also covers npm 12npm installon an existing v2 lock (keeps v2, drops mirrorresolved) and an npm 8 v2 shrinkwrap (commented 2026-10-06).npm
allow-filevs vendoredfile:tarballs (#969, 2026-10-07T00Z)npm ≥ 11.14.0 has
allow-file(all/root/none). Underroot(vendored transitive dep) ornone, vendoredscan/vendor --check/ lockfile-onlyvexsucceed silently and everynpm cifails EALLOWFILE. fail #969 on Linux npm 12.2.0 (project.npmrcx2, env var) and 11.21.0. Pass:rootwith a direct dep, defaultall. npm ≤ 11.13 has no such setting.Orphaned vendored entry after
npm uninstall(Bun handover, 2026-10-07T00Z)scan --mode vendored --prunereverts it (#665 fixed by #689): pass.vendor --checkexits 1 with a false "fresh install gets the unpatched package" message and a no-opsocket-patch vendorremedy: commented on #900 (npm 8.19.4 / 10.9.4 / 12.2.0).Superseding patch unavailable / withdrawn (2026-10-06T18Z, main
9c43dfc)Mock: left-pad@1.3.0 at patch A, then the API changes. Linux npm 8.19.4 (v2) / 10.9.4 / 12.2.0 (Node 24.21).
pending_build/build_failed/not_found: hosted pass (keeps A,redirect.skipped[], exit 0). Vendored fail Vendored npm re-scan exits 1 ("Failed to vendor", "1 failed") on every run while a superseding patch's artifact is pending_build / build_failed / not_found, although the vendored older patch is intact; hosted skips the same upgrade with exit 0 #954 (exit 1partial_failure"Failed to vendor … 1 failed" on every re-scan, while A stays vendored,vendor --checkpasses, coldnpm ciinstalls A,vexattests).forbidden(no paid access), A no longer offered: hosted and vendored pass (keep A, exit 0;updates[]still advertises B).withdrawn): hosted / vendored pass (pin kept, exit 0). Hostedvexattests while the view record is served and fails closed (record_unavailable, exit 1) once it's 404.scan --mode agentexits 1 "could not fetch details" every run, A stays applied. Needs an inconsistent API (offer without record); noted, not filed.Patch superseding (2026-10-06T12Z, main
9c43dfc)The same
name@versiongets a new patch UUID with different bytes. Mock: left-pad@1.3.0 A→B, cold-cachenpm ci.updates[], the lock re-pinned in every node, the old artifact GC'd,npm ciinstalls B,vexattests B, rollback byte-exact).vexfails closed or attests A).rollbackexits 1 until a reinstall andremoveexits 1 with pin B live (npm 8 / 10 / 12, and a v4.0.0 manifest).Run 23 passes (Linux, 2026-10-06T06Z, main
9c43dfc)npm dedupe,install --package-lock-only,install <new dep>andpruneon npm 8.19.4 / 10.9.4 / 12.2.0 (plain and scoped alias). Vendored passes on npm 10 / 12. On npm 8 (v2), everything exceptdedupehits Vendored npm vex and vendor --check fail after any npm 7–10npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879.npm installafter a hosted / vendored scan replaces the tree with patched bytes (npm 8 / 10 / 12).rollback(v2 mirrorlpnode, scoped alias) is byte-exact on npm 6 / 8 / 10 / 12.ciandinstall.binlinking (semver@7.6.0, plain + alias), hosted and vendored, npm 8 / 10 / 12.packages/a/node_modules/lp), hosted and vendored, npm 8 / 10 / 12: cycle,vendor --checkandrollbackpass.rollbackis byte-exact. Kills inside the narrow write window weren't tested (blocked by the session permission classifier).Backlog
New 2026-10-15T00Z: re-check Root
scan --mode vendoredstill exits 1 forever and drops its in-run VEX when a nested npm project has no lockfile (package-lock=false); the #1534 fix only covers nested projects with their own lock #1554 / vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 on the next main; Rootscan --mode vendoredexits 1 forever and drops its in-run VEX when a nested independent npm project installs a patched package the root lock doesn't have (hosted mode only warns) #1534 siblings (a nested project inside anignorePaths-excluded dir or under a workspace member,scan . tools/xwith a locklesstools/x); hostednested_project_skippedparity; npm 12npm patch rmlock downgrade vs vendored refusal text; Fix bare scan/get converting hosted pins (#1437) #1440 follow-ups.New 2026-10-14T12Z: re-check Root
scan --mode vendoredexits 1 forever and drops its in-run VEX when a nested independent npm project installs a patched package the root lock doesn't have (hosted mode only warns) #1534 / vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 on the next main; Rootscan --mode vendoredexits 1 forever and drops its in-run VEX when a nested independent npm project installs a patched package the root lock doesn't have (hosted mode only warns) #1534 siblings (anignorePaths-excluded nested project, a nested project with no lock, a workspace member with a stray own lock under vendored); Fix bare scan/get converting hosted pins (#1437) #1440 follow-ups; npm 12npm patch rmlock downgrade vs vendored refusal text.New 2026-10-14T00Z: re-check Vendored npm
vexandscan --mode vendored --vexattest not_affected beside afile:directory copy of the patched name@version, which npm installs unpatched #1511 / vendor --check fails a vendored npm package that has a bundled duplicate with "wiring missing: no lockfile or config references …", although the lock does reference it, and itssocket-patch vendorremedy is a no-op #1232 / vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 on the next main; Vendored npmvexandscan --mode vendored --vexattest not_affected beside afile:directory copy of the patched name@version, which npm installs unpatched #1511 siblings (a scopedfile:dir copy, a dual lock carrying the link, agent mode with afile:dir copy); Fix bare scan/get converting hosted pins (#1437) #1440 follow-ups (still open).New 2026-10-13T12Z: re-check Hosted npm
scan --vexattests not_affected when the lock also installs the same name@version from afile:tarball or directory, which npm installs unpatched (tarball shape regressed in #1008) #1481 / Path-scoped agentscan packages/aandrollback packages/askip 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 (PR Fix path-scoped scan missing member alias links (#1266) #1470) on the next main; Hosted npmscan --vexattests not_affected when the lock also installs the same name@version from afile:tarball or directory, which npm installs unpatched (tarball shape regressed in #1008) #1481 siblings (a git or URL dependency of the samename@versionunderinstall-strategy=nested|linked, anoverrides-forcedfile:copy,scan --mode vendored --vexover the same shapes).New 2026-10-13T01Z: re-check Path-scoped agent
scan packages/aandrollback packages/askip 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 / vendor --check fails a vendored npm package that has a bundled duplicate with "wiring missing: no lockfile or config references …", although the lock does reference it, and itssocket-patch vendorremedy is a no-op #1232 / vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072 / Hosted scan from a yarn classic workspace member still pins nothing and exits 0 when the root's workspaces use a!pattern (yarn 1 ignores it) or an extglob like packages/@(a|b) #1097 on the next main; Fix bare scan/get converting hosted pins (#1437) #1440 follow-ups (get --save-only/--mode agenton mixed state, a mixed state left by an interrupted--mode hostedtakeover, bare run without the--patch-server-urlthe pins were made with); CACHEDIR.TAG on a workspace member and underinstall-strategy=linked.New 2026-10-09T18Z: re-check Path-scoped agent
scan packages/aandrollback packages/askip 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 / vendor --check fails a vendored npm package that has a bundled duplicate with "wiring missing: no lockfile or config references …", although the lock does reference it, and itssocket-patch vendorremedy is a no-op #1232 / Hosted npm scan appends allow-remote=all to a CRLF .npmrc with no final newline as "\nallow-remote=all\r", leaving an LF line and a bare-CR ending that socket-patch's own .npmrc planner refuses #1196 / The #812 replace-registry-host warning misses a${VAR}value in .npmrc: npm expands it toalways, so every npm ci fails E404, while the hosted scan reports success with no warning #1233 / Afternpm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155 on the next main; Use one package target grammar for get, remove, rollback and the UUID shortcut #1034 agentremove <name> --preserve-stateand a scoped name that also matches a member dir; Finish vendored reverts through one shared step with a keep policy (#989) #1245NpmFamilykeep policy after an npm upgrade and with a shared artifact; an agent → hosted takeover killed at each rename; the npm 12npm patch rmlock downgrade versus vendored refusal text;get pkg:npm/<name>(versionless) against the real API (the mock only answers exact purls).New 2026-10-09T12Z: Path-scoped agent
scan packages/aandrollback packages/askip 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 follow-ups (pnpm member alias link — handed over;apply --check packages/aandvexwith a member alias link; a scoped alias@x/padlink); an interrupted vendored → hosted takeover on npm (A vendored-to-hosted takeover interrupted after its commit journal is written leaves the vendored artifact directory behind for good: recovery finishes the files but not the deferred deletions, and no GC can reclaim it once the ledger is gone #1157 analogue);vexright after a killed hosted dual-lock scan; Capped hosted scan (--max-new-patches 0) defers an already-pinned npm patch as NEW when a second lock entry of the same version is unpinned, so the vex remedy loops and that copy stays unpatched (regression from #1058) #1195 cap N>0 competing for a slot; re-check Hosted npm scan appends allow-remote=all to a CRLF .npmrc with no final newline as "\nallow-remote=all\r", leaving an LF line and a bare-CR ending that socket-patch's own .npmrc planner refuses #1196 / The #812 replace-registry-host warning misses a${VAR}value in .npmrc: npm expands it toalways, so every npm ci fails E404, while the hosted scan reports success with no warning #1233 / Capped hosted scan (--max-new-patches 0) defers an already-pinned npm patch as NEW when a second lock entry of the same version is unpinned, so the vex remedy loops and that copy stays unpatched (regression from #1058) #1195 / Afternpm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155 on the next main.New 2026-10-09T06Z: vendor --check fails a vendored npm package that has a bundled duplicate with "wiring missing: no lockfile or config references …", although the lock does reference it, and its
socket-patch vendorremedy is a no-op #1232 siblings (a git / URL / override duplicate of a vendored name@version: same genericvendor --checkreason?); Vendored npm scan wires file: tarballs that npm ≥ 11.14 refuses under allow-file=root (transitive deps) or allow-file=none, so every npm ci fails EALLOWFILE while scan, vendor --check and vex report success with no warning #969 underinstall-strategy=linkedandoverrides-only declarations; Hosted npm scan pins a package that npm 12's nativepatchedDependenciesalso patches, so every laternpm ci/npm installfails EPATCHFAILED (and vendored refuses the lockfileVersion 4 lock with wrong advice) #711 range / aliaspatchedDependenciesselectors on a lock without apatchedrecord, and a pin that predatesnpm patch; re-check Afternpm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155 / Capped hosted scan (--max-new-patches 0) defers an already-pinned npm patch as NEW when a second lock entry of the same version is unpinned, so the vex remedy loops and that copy stays unpatched (regression from #1058) #1195 / Hosted npm scan appends allow-remote=all to a CRLF .npmrc with no final newline as "\nallow-remote=all\r", leaving an LF line and a bare-CR ending that socket-patch's own .npmrc planner refuses #1196 on the next main; verify remove --preserve-state on a manifest-less hosted npm project silently restores the pin without the documented hosted_state_not_preservable note #433 (remove --preserve-state) onf3c6313.New 2026-10-09T00Z: Capped hosted scan (--max-new-patches 0) defers an already-pinned npm patch as NEW when a second lock entry of the same version is unpinned, so the vex remedy loops and that copy stays unpatched (regression from #1058) #1195 siblings (the npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 bundled copy under a cap, the in-memory engine with partial pins, a cap N>0 competing for a slot); re-check After
npm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155 when Fix vendored npm/Bun revert treating an upgrade as drift (#1155) #1187 lands; Remove scan --apply/--vendor, get --no-apply and the download/gc aliases (#966) #1031 removed flags in npm docs and remedy texts; Make every --json top-level error a {code, message} object (#704) #1027{code, message}errors on npm refusal paths; re-check npm VEX attests not_affected while a bundled (inBundle) copy of the same package@version stays unpatched #325 / remove --preserve-state on a manifest-less hosted npm project silently restores the pin without the documented hosted_state_not_preservable note #433 / npm hosted and vendored modes refuse a registry-installed package when its dependent's git spec is replaced by anoverridesentry (regression from #345) #490 / npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 on16106b1.New 2026-10-08T18Z: Make the vendored-to-hosted takeover atomic #1039 takeover with hosted-side refusals that aren't a service status (npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 bundled copy, linked alias, a one-sided dual lock, a mixed retract + take-over run); After
npm install <pkg>@<other version>moves a vendored npm package off its patched version,scan --prune,vendor --revert,removeandrollbackall drift-keep it, sovendor --checkstays red and every remedy it names loops #1155 in a workspace member, a nested copy and an alias; re-check npm VEX attests not_affected while a bundled (inBundle) copy of the same package@version stays unpatched #325 / remove --preserve-state on a manifest-less hosted npm project silently restores the pin without the documented hosted_state_not_preservable note #433 / npm hosted and vendored modes refuse a registry-installed package when its dependent's git spec is replaced by anoverridesentry (regression from #345) #490 / npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 onc4235a2.New 2026-10-08T12Z: Human
scan --mode vendored --prunesilently skips the vendored GC when no remaining package has a patch, so annpm uninstalled vendored entry is never reverted (exit 0), while--jsonreverts it andvendor --checkkeeps pointing at that same command #1127 on other vendored PMs (hand over if unseen);apply --check(Stop CI gates passing on missing paths, unverified agent patches and unreported hosted pins #1029) on npm 6 v1 locks,inBundlecopies, and a hosted-pinned package that still has a manifest record; re-check npm VEX attests not_affected while a bundled (inBundle) copy of the same package@version stays unpatched #325 / remove --preserve-state on a manifest-less hosted npm project silently restores the pin without the documented hosted_state_not_preservable note #433 / npm hosted and vendored modes refuse a registry-installed package when its dependent's git spec is replaced by anoverridesentry (regression from #345) #490 / npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 one2d9633.New 2026-10-08T06Z: re-check Hosted and vendored scans run from an npm workspace member that has a stray package-lock.json of its own rewrite that lock, which npm ignores, and report success while npm installs the unpatched package and VEX attests not_affected #1094 / Hosted scan from a yarn classic workspace member still pins nothing and exits 0 when the root's workspaces use a
!pattern (yarn 1 ignores it) or an extglob like packages/@(a|b) #1097 when fixes land (memberpackage-lock.jsonandnpm-shrinkwrap.json, extglob); re-check npm VEX attests not_affected while a bundled (inBundle) copy of the same package@version stays unpatched #325 / remove --preserve-state on a manifest-less hosted npm project silently restores the pin without the documented hosted_state_not_preservable note #433 / npm hosted and vendored modes refuse a registry-installed package when its dependent's git spec is replaced by anoverridesentry (regression from #345) #490 / Afteryarn removeof a vendored package, rollback fails forever (exit 1) and no command can clean up the orphaned yarn classic artifact; the remedies it prints don't work #665 / npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 / Vendored npm vex and vendor --check fail after any npm 7–10npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879 onea09714; Replace a superseded patch generation's wiring on re-pin and remove #1035 with a vendored A + hosted B mix across a dual lock.New 2026-10-08T00Z: Hosted and vendored scans run from an npm workspace member that has a stray package-lock.json of its own rewrite that lock, which npm ignores, and report success while npm installs the unpatched package and VEX attests not_affected #1094 on yarn / Bun workspaces (same
has_own_npm_family_lockearly exit; hand over if confirmed), a stray membernpm-shrinkwrap.json,rollback/removefrom the member; case-insensitive workspace globs on macOS / Windows (probe branch).New 2026-10-07T18Z: Hosted scan/get from an npm workspace member still pins nothing and exits 0 when the root's workspaces glob uses braces or a character class (packages/{a,b}, packages/[a-c]), because the #884 refusal's matcher doesn't support them #1071 on yarn / Bun roots (shared matcher; hand over if not covered),
!negation order and./patterns vs real npm; re-check npm VEX attests not_affected while a bundled (inBundle) copy of the same package@version stays unpatched #325 / remove --preserve-state on a manifest-less hosted npm project silently restores the pin without the documented hosted_state_not_preservable note #433 / npm hosted and vendored modes refuse a registry-installed package when its dependent's git spec is replaced by anoverridesentry (regression from #345) #490 / Afteryarn removeof a vendored package, rollback fails forever (exit 1) and no command can clean up the orphaned yarn classic artifact; the remedies it prints don't work #665 on05ecc6e. (A rolled-back vendor eject prints "Vendored 1 package" and "Commit .socket/vendor/" with no eject_rolled_back warning, and --json still reports the rolled-back package as applied #1005 on ascan --mode vendoredpartial takeover: done 18Z, pass.)New 2026-10-07T12Z: A rolled-back vendor eject prints "Vendored 1 package" and "Commit .socket/vendor/" with no eject_rolled_back warning, and --json still reports the rolled-back package as applied #1005 on
scan --mode vendoredpartial takeovers (does the human summary match disk?); scan --mode agent --json and get --json overwrite a locally modified npm file without the documented content_mismatch_overwritten warning (not in the JSON, not on stderr) #1004 siblings (other nested-apply warnings dropped fromscan --json:package_not_installednext to a success, sidecar advisories); re-check npm VEX attests not_affected while a bundled (inBundle) copy of the same package@version stays unpatched #325 / remove --preserve-state on a manifest-less hosted npm project silently restores the pin without the documented hosted_state_not_preservable note #433 / npm hosted and vendored modes refuse a registry-installed package when its dependent's git spec is replaced by anoverridesentry (regression from #345) #490 / Afteryarn removeof a vendored package, rollback fails forever (exit 1) and no command can clean up the orphaned yarn classic artifact; the remedies it prints don't work #665 on859a279. (Agent mode misses an npm-aliased copy under install-strategy=linked (node_modules/.store/lp@…), so apply exits 0 with it unpatched and VEX attests not_affected #852 scoped alias confirmed and commented; npm vendored refuses a registry package with vendor_workspace_member whenever a local file: directory (or workspace member) has the same name@version, and the hosted→vendored takeover then un-hosts it, leaving it unpatched #688 takeover half verified fixed; npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 still reproduces on859a279.)New 2026-10-07T00Z: Vendored npm scan wires file: tarballs that npm ≥ 11.14 refuses under allow-file=root (transitive deps) or allow-file=none, so every npm ci fails EALLOWFILE while scan, vendor --check and vex report success with no warning #969 follow-ups (hosted→vendored takeover under
allow-file=root; user / global.npmrclayers; a workspace member's vendored deps underroot;allow-directorywithfile:directory deps).New 2026-10-06T18Z: Vendored npm re-scan exits 1 ("Failed to vendor", "1 failed") on every run while a superseding patch's artifact is pending_build / build_failed / not_found, although the vendored older patch is intact; hosted skips the same upgrade with exit 0 #954 follow-ups (other vendored PMs → handover if confirmed: pnpm / yarn / bun share
ServiceFetch::settle;--max-new-patcheswith an unavailable UPGRADE;get <B> --mode vendoredwording). (Withdrawn / forbidden superseding: done 18Z, pass.)New 2026-10-06T12Z: After an agent→hosted migration, a superseding patch leaves the stale agent manifest record, so npm rollback exits 1 ("modified after patching") and remove refuses to un-host #933 follow-ups (path-scoped
rollback <purl>, agent re-scan after the takeover, other PMs → handover); Interrupted runs inside the write window.(Patch superseding done 2026-10-06T12Z: pass except agent→hosted, After an agent→hosted migration, a superseding patch leaves the stale agent manifest record, so npm rollback exits 1 ("modified after patching") and remove refuses to un-host #933.)
(Hosted alias
rollbackof the v2 mirrorlpnode: done 2026-10-06T06Z, pass.)New 2026-10-06: npm 12 never reads npm-shrinkwrap.json, so on a shrinkwrap-only project hosted and vendored scans rewrite a lock npm 12 ignores: scan succeeds with no warning, lockfile-only VEX attests not_affected, and
npm installinstalls the unpatched package #899 follow-ups (dual lock without a twin, workspace shrinkwrap); Vendored npm refusal for a symlinked package-lock.json says "nothing was written" but leaves the vendored tarball behind, then prints "Vendored 1 package" and tells you to commit .socket/vendor/ #898 on other group-commit refusals (vendor_commit_failed, a symlinked.npmrc); Bun handover Add new commands for patch remove, list and GC #2 (abun.lock+ stalepackage-lock.jsonwith no entry for the package:contest_across_locksignores it), not filed because of the cap and Bun being primary.(Vendored npm vex and vendor --check fail after any npm 7–10
npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879 npm 12 / shrinkwrap v2 follow-ups done 2026-10-06T00Z: both affected, commented.)Vendored npm vex and vendor --check fail after any npm 7–10
npm installon a lockfileVersion 2 lock, because npm dropsresolvedfrom the legacy mirror and #813 treats that as an unpatched npm 6 install (regression) #879 follow-ups: workspaces.(Agent mode misses an npm-aliased copy under install-strategy=linked (node_modules/.store/lp@…), so apply exits 0 with it unpatched and VEX attests not_affected #852 and Hosted npm scan pins a hosted tarball URL that npm rewrites to the registry under replace-registry-host=always, so every npm ci / npm install then fails E404 while the scan reports success #812 re-checked on
c644ab02026-10-05T18Z: both still reproduce.)Agent mode misses an npm-aliased copy under install-strategy=linked (node_modules/.store/lp@…), so apply exits 0 with it unpatched and VEX attests not_affected #852 follow-ups: agent
rollbackover the alias store copy; a scoped alias; a transitive alias in.store.Human-output scan --mode agent / --sync still never re-applies an already-recorded patch after a reinstall (#454 fixed only the --json path) #732 fix re-check (human
scan --mode agentafternpm ci): needs a mock API, because--offlinescan is refused. Also re-check npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 on main4646693.(npm vendored refuses a registry package with vendor_workspace_member whenever a local file: directory (or workspace member) has the same name@version, and the hosted→vendored takeover then un-hosts it, leaving it unpatched #688 and npm v2 lock: aliased packages stay on the registry in the legacy dependencies mirror (hosted silently, vendored with a warning), so npm 6 installs unpatched bytes while VEX attests not_affected #432 re-checked on
4646693: both still reproduce, 2026-10-05T12Z.)npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 follow-ups:
get --mode vendoredtakeover; the realnpmbundle (ansi-regex) shape; a dual lock where only one lock carries the bundle; otherContestedWiringshapes (npm VEX attests a patch that only npm-shrinkwrap.json wires when the package-lock.json beside it has no entry for the package, though npm 12 reads package-lock.json and installs the registry copy #798 stale twin) reaching the vendored takeover silently.Hosted npm scan pins a hosted tarball URL that npm rewrites to the registry under replace-registry-host=always, so every npm ci / npm install then fails E404 while the scan reports success #812 variants: global npmrc; a
registry=mirror +always. macOS / Windows once probe branches are allowed again. (User.npmrcand hostname value done 2026-10-05T06Z.)(npm VEX attests a patch that only npm-shrinkwrap.json wires when the package-lock.json beside it has no entry for the package, though npm 12 reads package-lock.json and installs the registry copy #798 re-scan follow-up done 2026-10-05T00Z: pass. Re-check when Fix npm VEX attesting a patch the twin lock lacks (#798) #799 lands.)
(npm hosted and vendored modes rewrite a lock entry nested under a dependency that ships npm-shrinkwrap.json (hasShrinkwrap), so npm 7–11 install it unpatched while vendored VEX attests not_affected #753 follow-ups done 2026-10-04T12Z: npm 12
npm installpass, workspace member same as npm hosted and vendored modes rewrite a lock entry nested under a dependency that ships npm-shrinkwrap.json (hasShrinkwrap), so npm 7–11 install it unpatched while vendored VEX attests not_affected #753 on 10/11 and pass on 12, agent mode pass, hosted→vendored takeover on npm 12 pass.)(Bun handover done 2026-10-04T12Z: after hosted
rollback/vendor --revert,npm installandnpm cirestore upstream bytes on npm 7/10/11/12.)(Done 2026-10-04T18Z: npm 9.2.0
install-linksfile:cycle,peer: true/devOptionalpins: all pass.)npm VEX attests a patch that only npm-shrinkwrap.json wires when the package-lock.json beside it has no entry for the package, though npm 12 reads package-lock.json and installs the registry copy #798 follow-ups: a workspace member present only in the shrinkwrap; after npm 12
npm installregenerates the twin, does a re-scan wire both? Re-checkvendor --checksays "committed artifact and wiring verified" (exit 0) afterpipenv lockdrops the vendored reference, so a freshpipenv install --deployinstalls the unpatched wheel while vex says vendor_unwired #725 / npm VEX attests a patch that only npm-shrinkwrap.json wires when the package-lock.json beside it has no entry for the package, though npm 12 reads package-lock.json and installs the registry copy #798 on npm when Fix vendor --check passing unwired vendored entries (#725) #730 lands.(Human-output scan --mode agent / --sync still never re-applies an already-recorded patch after a reinstall (#454 fixed only the --json path) #732 mixed run done 2026-10-04T06Z: a new patch re-applies all entries. Human-output scan --mode agent / --sync still never re-applies an already-recorded patch after a reinstall (#454 fixed only the --json path) #732 only bites when nothing is new.)
Hosted npm scan pins a package that npm 12's native
patchedDependenciesalso patches, so every laternpm ci/npm installfails EPATCHFAILED (and vendored refuses the lockfileVersion 4 lock with wrong advice) #711 (npm 12 nativenpm patch, lockfileVersion 4) follow-ups: nested / workspace patched copies; agent--strict.rollback/remove/repairon v4 locks passed (2026-10-04).vendor_lock_entry_not_rewritable) over a hosted pin; a real workspace member forked under the same name@version. Dual lock and alias passed (2026-10-03T12Z). A differing shrinkwrap/package-lock pair: npm VEX attests a patch that only npm-shrinkwrap.json wires when the package-lock.json beside it has no entry for the package, though npm 12 reads package-lock.json and installs the registry copy #798 (2026-10-04T18Z).vendor --json > report.json(or> vendor.log 2>&1) in the project loses the output and concurrent writes to root files are reverted #687 on Windows / macOS (a failed eject rewriting root files; on Windows a rename over a shell-held redirect target may fail witheject_rollback_failed). Needs a probe branch that can be deleted.apply --check/repairover a link; a byte-identical fork (patched silently); a nested member'snode_modulesreached through a link.install-strategy=linkedand across a shrinkwrap/package-lock pair; whethervendor --checkshould flag it.scan -gtells you to runsocket-patch scan --mode agent [PATHS]without-g, so following the hint scans the cwd project instead of the global install #464, npm hosted and vendored modes refuse a registry-installed package when its dependent's git spec is replaced by anoverridesentry (regression from #345) #490 (override over URL /file:transitive deps on npm 8–12), Afteryarn removeof a vendored package, rollback fails forever (exit 1) and no command can clean up the orphaned yarn classic artifact; the remedies it prints don't work #665 (npm matrix in the comment).rollback/vexwith path policy over nested projects.scannow exits 0 with nothing applied (since Fix apply failing when patched deps are skipped (#403) #555). Watch for a fix.-g), still open: Linux npm 7/8/11 passed 2026-10-04T06Z. Still to do: npm 6/8/11 on macOS and Windows; an unwritable prefix (root-owned /Program Files); nvm, volta, fnm and Homebrew prefixes on macOS;%APPDATA%\npmnow that On Windows,scan -g/get -g/vex -gfind no global npm packages becausenpm root -gis spawned as barenpm, which never resolves tonpm.cmd#434 is closed. Full checklist in the 20261001T040000Z entry.git push --deleteoutright, so no new probe branches are pushed until a maintainer allows it or deletes these) (git push --deletefails with "remote end hung up" / "Everything up-to-date"; re-checked 2026-10-03T12Z):bughunt/npm/20260930-alias-linked,20260930-win-mac-e2e,20260930-win-old-npm,20261001-crlf-paths,20261001-optional-dep,20261001-v5-hosted-global,20261001-win-global,20261002-v5-agent-vendored-winmac,20261003-ws-link-agent,20261003-ws-link-mac. A maintainer needs to delete them.Known non-bugs
npm with a member
file:directory dependency (install-strategy=nested,install-links=false) installs that directory's own devDependencies into<dir>/node_modules, so a root crawl sees them. That's npm's behaviour (2026-10-14).Agent
scan --mode agentrefuses (exit 1,apply_failed) to patch afile:directory link target outside everynode_modules; that's the 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 fix, loud by design (2026-10-14).npm 10.9.4
install-strategy=linkedfails ENOENT on a workspace member's relativefile:../../dirdependency (it resolves the path against the wrong base). That's npm's behaviour; the shape can't be built there (2026-10-14).A
CACHEDIR.TAGin a workspace member prunes that member'snode_modulesfrom the agent crawl. That's documented in docs/ecosystems.md, the same class as thebuild//dist/member skip (2026-10-14).Hosted
rollbackagainst a registry answering 429 refuses loudly (exit 1,git checkoutremedy, lock untouched); the upstream fetcher has no 429 /Retry-Afterretry by design (Upstream restore sends every public-registry lookup at once; the registry_concurrency cap has no caller #1220 added only the concurrency cap) (2026-10-13).Plain
socket-patch vendoron a project with vendored entries and hosted pins ejects the hosted pins into.socket/vendor/("Ejecting 1 hosted package"): the documented eject, unlike the barescan/getconversion fixed in A bare scan or get on a project holding both vendored packages and hosted pins silently converts every hosted pin to vendored (exit 0, no warning), so it undoes a partial hosted takeover #1437 (2026-10-13).The
mode_ambiguousmessage names the project root as.when run from it. Cosmetic (2026-10-13).npm shrinkwrapafter a hosted scan moves the pins into npm-shrinkwrap.json;vexthen omits them withvex_npm_shrinkwrap_only(the documented shrinkwrap-only rule), while npm 10npm ciinstalls the patched bytes (2026-10-13).Mock tip (2026-10-13): never
pkill -f mock.pyorpgrep -f mock.pyin the same shell command; both match the calling shell. Record the mock's PID in a file at start.A vendored → hosted takeover SIGKILLed after its commit journal is written: the next locked command finishes the files, but the old
.socket/vendor/npm/<uuid>/dir stays. Same as A vendored-to-hosted takeover interrupted after its commit journal is written leaves the vendored artifact directory behind for good: recovery finishes the files but not the deferred deletions, and no GC can reclaim it once the ledger is gone #1157 (pnpm), closed as wontfix. Reproduced on npm 10.9.4 (2026-10-09T18Z).npm 12.2.0 accepts range
patchedDependencieskeys (ms@^2.1.0). socket-patch's package.json key matcher doesn't parse ranges, but npm writes thepatchedrecord into the lockfileVersion 4 lock for any selector, and the hosted gate reads it. A range key without a regenerated lock failsnpm cianyway (2026-10-09T18Z).rollback '@scope/*'is a path glob relative to the cwd (it matches nothing loudly); usenode_modules/@scope/*or the scoped name (2026-10-09T18Z).Mock tip (2026-10-09T18Z): the
SOCKET_NPM_REGISTRYversion doc'sdist.tarballis written into the lock verbatim on hosted rollback, so serve the real<name>/-/<leaf>-<ver>.tgzshape for scoped names. In shells, neverpkill -f mock.py: it matches the calling shell. Start the mock withsetsid.A SIGKILL inside a hosted or vendored write window leaves a
.socket-stage-<file>-<uuid>sibling that later runs don't remove. Every atomic-rename writer leaves that residue after a kill, and the re-run converges. Noted on vendor --check and vex misreport a crashed vendored run whose commit journal is pending, because only lock-taking commands replay it #809, not filed separately (2026-10-09T12Z).A hosted scan with an immutable lock (chattr +i) now fails with "nothing was changed", and
.npmrcis rolled back too. The older "mid-flush I/O residual" note below about.npmrcbeing left is outdated ona80b89e(2026-10-09T12Z).npm dedupes a root registry
ms@2.1.2onto a git copy of the same version even when anoverridesentry forces the git spec only underdebug. So a registry + git duplicate of one name@version (a vendor --check fails a vendored npm package that has a bundled duplicate with "wiring missing: no lockfile or config references …", although the lock does reference it, and itssocket-patch vendorremedy is a no-op #1232 sibling) can't be built with npm 10 (2026-10-09T12Z).Mock tip (2026-10-09T12Z): the public-proxy routes need only
POST /patch/batch,GET /patch/by-package/<purl>,/patch/view/<uuid>(withblobContent/beforeBlobContentbase64 and git-sha256beforeHash/afterHashfor agent mode),/patch/blob/<hash>,POST /patch/package(results[uuid]withstatus: granted,url,artifacts[{kind: tarball, url, integrity{sha512, sha1, md5}}]) and the tarball URL. AnLD_PRELOADshim that SIGKILLs onrename()to a path suffix reproduces interrupted runs;strace -e injectcounts per thread and misses.Shrinkwrap-only vendored project:
vexomits (vex_npm_shrinkwrap_only) whilevendor --checkpasses. That's the documented "Unattested references" rule (liveness gates keep treating the wiring as live) (2026-10-09T06Z).A raw
allow-file=${AF}is treated as a non-allvalue, so it warnsvendor_npm_allow_fileandvendor --checkfails even whenAF=all. Fails safe. The silent direction forreplace-registry-hostis The #812 replace-registry-host warning misses a${VAR}value in .npmrc: npm expands it toalways, so every npm ci fails E404, while the hosted scan reports success with no warning #1233 (2026-10-09T06Z).Mock tip (2026-10-09T06Z):
npm pack <spec>plus a Python tar rewrite gives a real patched tarball. The org routes are matched on path suffixes as before;/patch/packagereturnsresults[uuid]for every known uuid in the request body.Mock tip (2026-10-09T00Z): org routes work with
--api-url <mock> --org o --api-token fake --patch-server-url <mock>, routing on path suffixes/batch,/by-package/<purl>,/view/<uuid>,/blob/<hash>,/packageand the tarball URL/patch/npm/<name>/<ver>/<tok>/<uuid>/<name>-<ver>.tgz. Hostedrollbackworked withoutSOCKET_NPM_REGISTRYthis run.A CR-only
.npmrcis refused loudly ("not set automatically") and left untouched (documented). Only the splice that produces a bare CR is a bug (Hosted npm scan appends allow-remote=all to a CRLF .npmrc with no final newline as "\nallow-remote=all\r", leaving an LF line and a bare-CR ending that socket-patch's own .npmrc planner refuses #1196).Mock tip (2026-10-08T18Z):
POST /patch/packageansweringpending_build/forbiddenduring a vendored → hosted takeover keeps the vendored wiring byte-identical and exits 0 ("No patches could be switched to hosted"). That's Make the vendored-to-hosted takeover atomic #1039's intended retraction, not a silent no-op.apply --check -gdrift text says "Runsocket-patch apply" without-g; following it fails loudly (exit 1, "matched no installed package"). Noted, not filed (A report-onlyscan -gtells you to runsocket-patch scan --mode agent [PATHS]without-g, so following the hint scans the cwd project instead of the global install #464 class, low value). (2026-10-08T12Z)Mock tip (2026-10-08T12Z): the public-proxy routes (
SOCKET_PROXY_URL+SOCKET_API_URL, no token) need onlyPOST /patch/batch(components[].purl),GET /patch/by-package/<purl>,/patch/view/<uuid>,/patch/blob/<hash>,POST /patch/packageand the tarball URL it returns.Mock tip (2026-10-08T06Z): when two mock origins serve patch generations A and B,
remove/rollbackmust get the A pin's origin as--patch-server-url, or the pin is invisible (documented) and looks like a Replace a superseded patch generation's wiring on re-pin and remove #1035 miss.A
workspacesnegation listed before the positive pattern (["!packages/b", "packages/*"]): npm excludesb, and a hosted scan frombpins nothing becausebis its own project (npm 10.9.4, 2026-10-08T00Z).pnpm handover Hosted pnpm scan pins a pnpm-lock.yaml that pnpm is configured to ignore (
lockfile=false/lockfile: false), reports success, and lock-only VEX attests not_affected while pnpm installs the upstream package #1074's npm analogue (package-lock=false):npm cistill honors the lock, so a lock-only attestation matchesnpm ci, andvexrefuses after a plainnpm install(see the entry below; re-reviewed 2026-10-08T00Z).An
.npmrcthat ends inside an ini[section]: hosted insertsallow-remote=allbefore the first section, and anallow-remotethat sits only inside a section is (correctly) not treated as set (npm 12.2.0, 2026-10-07T18Z).A lost
.socket/vendor/state.jsonwith the lock still wired: every command keeps the artifacts andnpm cistays patched (fail-safe). Only thevendor --revertremedy text is wrong (vendor --revert with a lost vendor ledger tells you to "run socket-patch repair to re-adopt them into the ledger", but repair refuses because it never rebuilds the ledger, so the advice loops and the vendored npm packages can't be reverted #1072).The eject
vendor --dry-runreportseject_planned(exit 0) even when the wet eject will refuse a pin. CLI_CONTRACT eject step (3) says the dry run stops at the restore plan. Thescan/get --mode vendored --dry-runtakeover preview listingwould_vendoris documented too ("does not model the takeover yet"). (2026-10-07T12Z)content_mismatch_overwritten(local edits overwritten under the default policy) is documented behaviour. Only its missing report inscan/get --jsonis a bug (scan --mode agent --json and get --json overwrite a locally modified npm file without the documented content_mismatch_overwritten warning (not in the JSON, not on stderr) #1004).allow-file=root(npm 12.2.0) admits a vendored dep that is a workspace member's direct dependency (2026-10-07T06Z).An alias key that shadows the patched package's name (
"left-pad": "npm:once@1.3.0") is correctly ignored by agent, vendored andvex(2026-10-07T06Z).An npm 10 consumer ignores a published library's vendored
npm-shrinkwrap.jsonand installs registry bytes. socket-patch makes no claim about published libraries.allow-file=rootadmits a vendored direct dependency'sfile:tarball (npm 12.2.0); only transitive vendored entries are refused (Vendored npm scan wires file: tarballs that npm ≥ 11.14 refuses under allow-file=root (transitive deps) or allow-file=none, so every npm ci fails EALLOWFILE while scan, vendor --check and vex report success with no warning #969).An orphaned vendored ledger entry after
npm uninstallis cleaned up byscan --mode vendored --prune(since Fix vendored revert keeping artifact for removed lock entry (#665) #689). Only thevendor --checkwording is wrong (vendor --check fails a vendored package whose lock is contested by a sibling package-lock.json with "no lockfile or config references .socket/vendor/… any more", which is false, and its remedy ("re-run socket-patch vendor") is a no-op, so the check stays red forever #900).A withdrawn patch (nothing offered, reference
withdrawn) keeps its hosted / vendored pin and exits 0; hostedvexkeeps attesting while the API still serves the record. No documented contract says a withdrawal should un-pin.A paid superseding patch without paid access: the scan keeps A and still lists A→B in
updates[](informational).npm 6
npm cithat fails EINTEGRITY on a hosted alias pin (Fix npm 6 installing unpatched aliases (#432) #813's fail-closed path) leaves the unpatched registry bytes extracted innode_modules. That's npm's partial-install behaviour (exit 1), andvexrefuses that tree (not_applied).Mock tip (2026-10-05T18Z): the org-scoped routes (
--api-url … --org o --api-token fake) need only batch, by-package,patches/package, view and blob, and one granted tarball response serves both hosted and vendored.Scratch harness tip: a test file that includes
npm_e2e_commonmust also includevex_e2e_common.scanrefuses--offline(strict airgap), so useapplyfor offline agent cells.Mocks of the public proxy need
SOCKET_PROXY_URL(andNO_PROXY=127.0.0.1);--api-urlalone still reachespatches-api.socket.dev.Project
.npmrcallow-remote=${VAR}is read raw and treated as an explicit user value (warns, doesn't write). Fails safe.patches-api.socket.devis unreachable from the sandbox. Use hand-staged manifests, a local mock API, or the wiremock suites.Running
scan --mode hostedfrom a workspace member directory finds no packages, because discovery is cwd-scoped. It's loud and writes nothing.An explicit
allow-remoteother thanallis respected with a loudredirect_npm_allow_remotewarning, and a fresh npm 12 install then fails EALLOWREMOTE (fails closed). This is documented.npm updatere-resolves a hosted or vendored entry back to the registry. That's npm's behaviour;vexthen refuses (redirect_unwired/vendor_unwired).After that,
applyskips the package as "managed bysocket-patch vendor" with exit 0 and doesn't take ownership back. That's by design (apply.rsVENDOR_OWNED_MARKER), andvexrefuses.npm 12 doesn't install the dependencies of a
file:directory dependency into the linked directory.The walk skips
build,dist,vendor,tmp,temp,coverageand hidden directories, even when one is an npm workspace member (documented in docs/ecosystems.md).applyfrom a workspace member directory reportsnoManifestwhen.socket/lives at the root (--cwdscoping).Concurrent lock-taking commands fail fast with
lock_heldunless--lock-timeoutis set (documented).rollbackdrops the rolled-back manifest entries and GCs their blobs unless--preserve-stateis set (documented).Agent-mode
vexomits patches (ecosystem_not_setup) when there's nosetuphook and nosetup.manual(documented).The VEX product
@idis the raw origin URL for a non-GitHub/GitLab/Bitbucket remote (documented invex --help).npm ≥ 11 redacts UUID-shaped path segments in
npm root -gstdout, soapply -gmisses a global prefix whose path contains a UUID. That's npm's behaviour, it's loud (exit 1), and--global-prefixworks around it. Not filed.The Windows + npm 6 suite cell needs
SOCKET_PATCH_NPM_E2E_LOCK_WRITER_BIN(an npm ≥ 7 to write the v2 lock). That's a harness requirement.On Windows, npm/node can't run in a cwd longer than the Win32 limit, so deep-path cells there can't run.
Hosted pins on any host other than
patch.socket.devor the--patch-server-urlorigin are invisible torollback,vex,listandremove(documented). Mock runs must pass--patch-server-url.In the sandbox, hosted
rollbackcan't reach registry.npmjs.org (the Rust client doesn't trust the proxy CA). UseSOCKET_NPM_REGISTRYpointed at a local passthrough.npm 6 on a hosted lockfileVersion 1 lock: with a cold cache it fails closed with EINTEGRITY, as npm-compatibility.md documents (re-measured 2026-10-06T12Z). An earlier note said it installs the patched bytes; that was a warm-cache artifact.
rollbackre-addsresolvedunderomit-lockfile-registry-resolved=true: hosted keeps no ledger, and npm drops the field on its next install.A failed hosted lock write (an immutable lock) leaves
allow-remote=allin.npmrc: exit 1, the documented mid-flush I/O residual.A bare hosted
scanwires only the cwd project's lock. A nested non-workspace project warnsredirect_npm_entry_not_found.scan . subwires both, butrollback/vexfrom the root don't seesub's pins (use--cwd sub).rollback <path>path targets select installed copies, so a workspace member whose dependency is hoisted to the root matches nothing (documented).Vendored
vexattests from the committed artifact and only warnsvendored_tree_out_of_syncwhen the live tree is stale (documented).scan -gwithout-ealso scans the cargo, pypi and gem global stores (by design).vex -goutside a project needs--product.v5 removes
setup, so the setup-hook cells are retired.Hosted
rollbackrestoresresolvedtoregistry.npmjs.org(orSOCKET_NPM_REGISTRY) even when the project.npmrcuses aregistry=mirror. That's documented ("default upstream registry entry"), andnpm cistill works because of npm'sreplace-registry-host.--packageandignorePackagesmatch package names and purls, not npm alias dependency keys (lp@npm:left-padis matched byleft-pad, notlp).npm 12 ignores
ALLOW-REMOTE=andallow_remote=keys in.npmrc, so socket-patch appendingallow-remote=allafter them is correct.minSeverityskips patches whose per-package records carry no severity (documented). Mocks must fillvulnerabilitiesinby-package.scan -g --mode agentrun inside a project records the global patch in the cwd.socket/manifest.json, androllback -gdrops it again. The manifest is cwd-scoped; CLI_CONTRACT "Global scope never touches the project's state" only covers hosted pins and the vendor ledger, and says rollback/remove-g"drop their manifest records".With no override, npm dedupes a root registry spec (
left-pad@1.3.0) onto a transitive git copy of the same version, so the lock has a single git entry and theredirect_npm_non_registry_entry_skippedskip is correct.v4.0.0 agent
vexomits patches withecosystem_not_setupunlesssetup.manuallists the ecosystem (v4 behaviour). Set it when bisecting vex against v4.Hosted
vexattests an omitted devDependency (npm ci --omit=dev) from its lock pin: documented ("With nothing installed … attests from that pin").A vendored v2 lock re-saved by npm 7/8 (
npm install) losesresolvedin the legacydependenciesmirror, because npm's serializer never writes it for afile:resolution. A cold-cache npm 6npm cithen fails closed with EINTEGRITY. That's npm's behaviour; npm-compatibility.md's npm 6 + vendored v2 claim holds only until such a re-save.vexwith a bundled (inBundle) copy refuses to attest (patched_ref_unattributable). In hosted mode the final error reads as "no references found" (exit 2) because a rejected reference keeps nothing alive (documented). Only the diagnostic is misleading.scan --mode agentover hosted pins keeps the pins and warns (redirectState; documented).Mock tip:
SOCKET_NPM_REGISTRYhosted rollback fetches<registry>/<name>/<version>, so serve a version doc with a top-leveldist, not a packument.(Retired 2026-10-03T12Z: npm vendored
scan --prune/vendor --revert/removekeeping an entry whose lock entry vanished afternpm uninstallis now tracked as a bug in Afteryarn removeof a vendored package, rollback fails forever (exit 1) and no command can clean up the orphaned yarn classic artifact; the remedies it prints don't work #665.)package-lock=falsein.npmrc: hosted pins are ignored by a plainnpm install(unpatched), butnpm cihonors the lock andvexrefusesnot_applied. Fails closed; the user's config choice.A symlinked
.npmrcisn't written through (hosted warns thatallow-remotemust be set). A symlinked lock is refusedredirect_symlinked_file_unsupported.Probe mock servers need a readiness loop: a scan that starts before the server listens fails with "tcp connect error: deadline has elapsed" (a probe artifact).
Lockfile-only discovery skips lockfileVersion 1 locks: on an npm 6 checkout without
node_modules,scanfinds 0 packages and prints "No packages found. Run your package manager's install first." (exit 0). The code calls this documented (vendor/lock_inventory/npm.rs:168), though the user docs don't say it. It's loud, and installing first works. Not filed.A hosted-appended
allow-remote=allline in a pre-existing.npmrcsurvivesrollback/removewithnpm_allow_remote_left(documented: v5 keeps no provenance).v5 vendoring downloads prebuilt artifacts from
POST …/patches/package.--vendor-source buildwas removed, andvendor --offlineover a hand-staged.socket/refusesvendor_service_offline_conflict. Mocks must serve that endpoint, and the batch mock must return only the requested purls.vex --jsonwithout--outputexits 2 withjson_requires_output(documented).A lock with git merge-conflict markers: hosted warns
not valid JSON; npm redirect skippedand exits 0 (same exit-0 contract as bun's invalid lock), vendored exits 1. Loud; not filed.scan --syncGC deletes a recorded patch's before-blob (.socket/blobs/<beforeHash>). That's by design: rollback downloads the before-blob on demand.Python mock blob routes must serve the before bytes for the before-hash, or agent
rollbackfails "Content hash mismatch" (a mock artifact).npm 12 needs Node ^22.22.2 / ^24.15 / ≥26; the sandbox's Node 22.22.0 is too old. Install
node@24from npm into a scratch prefix.rollback/removedelete a user-authored project.npmrcthat is exactlyallow-remote=all\n, even when it existed before the hosted scan. That's documented (CLI_CONTRACT: a file that is exactly hosted mode's own is deleted, because v5 keeps no provenance).npm 12.2.0 installs a copy nested under a
hasShrinkwrapdependency from the root lock, so hosted / vendored rewrites of it work there. npm hosted and vendored modes rewrite a lock entry nested under a dependency that ships npm-shrinkwrap.json (hasShrinkwrap), so npm 7–11 install it unpatched while vendored VEX attests not_affected #753 covers npm 6–11 only.A dual lock whose shrinkwrap lacks the package and whose package-lock twin has it: lockfile-only discovery reads the shrinkwrap, so
scanfinds nothing and writes nothing (loud; no claim made).The sandbox sets
NPM_CONFIG_USERCONFIG=/root/.npmrc, so a scratch$HOME/.npmrcis ignored unless you repoint that variable (a harness artifact).vex -ois--org; the output flag is-O/--output.vendor --checkverifying only the artifact (not the lock wiring) for npm is tracked invendor --checksays "committed artifact and wiring verified" (exit 0) afterpipenv lockdrops the vendored reference, so a freshpipenv install --deployinstalls the unpatched wheel while vex says vendor_unwired #725 (generic root cause, draft fix Fix vendor --check passing unwired vendored entries (#725) #730). Don't re-file it per npm shape.npm 12
npm cion a shrinkwrap-only project fails EUSAGE (npm 12 reads only package-lock.json). That's npm behaviour; the socket-patch side is npm 12 never reads npm-shrinkwrap.json, so on a shrinkwrap-only project hosted and vendored scans rewrite a lock npm 12 ignores: scan succeeds with no warning, lockfile-only VEX attests not_affected, andnpm installinstalls the unpatched package #899.A vendored
package-lock.jsonsymlink refusal: re-running after replacing the link with a regular file reuses the orphan artifact and works (Vendored npm refusal for a symlinked package-lock.json says "nothing was written" but leaves the vendored tarball behind, then prints "Vendored 1 package" and tells you to commit .socket/vendor/ #898 covers the orphan itself).npm 8 (no
install-strategy), and npm 10 with the default hoisted layout, dedupe a registryleft-pad@1.3.0spec onto afile:tarball copy of the same version. The lock then has a singlefile:entry, so the hosted scan correctly pins nothing (run 39).All reactions