Skip to content

Commit 4bee48a

Browse files
committed
vlt: 2026-10-13 run 19 ledger
1 parent 283b69d commit 4bee48a

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[agent] Handover from the vlt bug-hunt routine (ledger #307), 2026-10-13.
2+
3+
Filed as **#1494** (labelled `pm:vlt`), but it reproduces on pnpm too. On pnpm 10.28.0 (default isolated linker), a workspace member `packages/a` with `"lp": "npm:left-pad@1.3.0"` gets `packages/a/node_modules/lp -> ../../../node_modules/.pnpm/left-pad@1.3.0/node_modules/left-pad`. `cd packages/a && socket-patch scan --mode agent --yes --json` finds `pkg:npm/left-pad@1.3.0` and downloads the patch, then apply fails `package_not_installed` (exit 1, `partialFailure`) and `require('lp')` stays pristine. Run from the root, it patches. Root cause: apply's npm roots are only the cwd and below (`npm_crawler.rs:2870`), and `alias_copies` skips links (`:2546`). The full repro and mock are in #1494. Please add any pnpm-specific cells (other majors, `virtualStoreDir`, rollback from the member) there as comments rather than a new issue.

‎entries/vlt/20261013T172312Z.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[agent] 2026-10-13: vlt bug-hunt run
2+
3+
**Tested:** main `d4af25a` (release **5.0.1**, #1485). The 27 commits since `15c2c83` include #1469 (hosted pnpm pin beside a `file:` copy), #1482 (npm `file:` copy attested by in-run VEX, #1481), #1470 (path-scoped member alias links, #1266) and #1488 (hermetic vlt test spawns). Linux sandbox, Node 22.22.0, vlt 1.2.0 / 1.3.8 (1.3.8 is still the newest vlt), pnpm 10.28.0 for one cross-check. New two-package mock (`left-pad@1.3.0` + `right-pad@1.3.0`, both patchable, `/patches/batch` and `/patches/package` filtered by body, `NO_ALT=` turns on `tar.br` alternates). It's attached in full to #1494.
4+
5+
### Re-triage
6+
- **#862**: `patch/rollback.rs` is unchanged since `15c2c83` (0 commits), so I didn't re-run it.
7+
8+
### Cells (Linux)
9+
- **vlt analog of #1469 / #1481** (a hosted pin beside a `file:` copy of the same name@version: a workspace member `file:` dir / tarball, and a root `file:` dir / tarball beside `wrapper` → registry left-pad). Hosted scan pins only the registry node and warns `redirect_vlt_custom_registry_skipped`. In-run `--vex` omits the patch (`vex_omitted`, exit 1). Standalone `vex` refuses `not_applied` whenever the `file:` copy is installed pristine. Rollback is byte-exact: **pass** (1.2.0 / 1.3.8).
10+
- **#1437 detection with an npm-alias hosted pin** (`lp` → left-pad hosted beside a vendored right-pad) and with a **brotli (`tar.br`, flag 4) hosted pin**. Bare `scan` and `get` exit 2 `mode_ambiguous`, and the lock and `package.json` stay byte-identical. `ci` patches both, vex attests, rollback works, and post-rollback `ci` is pristine: **pass** (alias: 1.2.0 / 1.3.8; brotli: 1.3.8). Brotli rollback restores left-pad as gzip: that's the known #941, still pending #1130.
11+
- **#1266 on vlt** (path-scoped `scan --mode agent packages/a` / `rollback packages/a` from the root, with member alias `lp`): **pass** (1.3.8).
12+
- **Agent-mode scan run from inside a workspace member**: a plain-name dep passes. A member **alias dep fails: #1494** (discovery finds it, apply `package_not_installed`, exit 1, pristine; 1.2.0 / 1.3.8, also pnpm 10.28). Root-run and path-scoped both pass.
13+
14+
### Issues
15+
- Filed **#1494**: agent-mode scan from a vlt (or pnpm) workspace member fails `package_not_installed` for the member's npm-alias dependency. Handover to pnpm: `entries/pnpm/20261013T172312Z-from-vlt.md`.
16+
17+
### False positives ruled out
18+
- "vex attests `not_affected` beside a `file:` tarball copy": `vlt ci` (1.2.0 / 1.3.8) links a `file:` tarball dependency straight to the raw `.tgz` (`node_modules/left-pad -> ../lp.tgz`) instead of extracting it, with or without socket-patch, so no copy is loadable. A fresh `vlt install` extracts it, and then `vex` refuses correctly. In a workspace member, even `vlt install` makes the raw `.tgz` link.
19+
- In-run VEX `vex_omitted` → scan exit 1 `error` after a successful pin is documented in-run VEX behaviour (stale install until `vlt ci`).
20+
21+
### Next
22+
1. #1494 re-check once fixed. Also `rollback` / `repair` / `vex` from a member with an alias.
23+
2. #862 once `patch/rollback.rs` changes.
24+
3. #1130's decision on #941 (brotli restore).
25+
4. Multi-instance `~peer.<hex>` plus a direct copy of the same version (three instances): takeover refusal and `remove` of one purl.
26+
5. Why `vlt-compatibility.yml` hasn't run on main since 2026-10-09.

‎state/vlt.md‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[agent] Progress ledger for the scheduled vlt bug-hunt routine (label pm:vlt).
22

3-
Last updated: 2026-10-13 (run 18), main `15c2c83` (main was squashed on 2026-10-10, so older SHAs here no longer resolve), latest release 5.0.0 (previous 4.0.0, which has no vlt support). Newest vlt: 1.3.8 (2026-10-09). Run 18 mock: two patchable packages (`left-pad@1.3.0`, `right-pad@1.0.0`), with `/patches/batch` and `/patches/package` filtered by body; `PEER=1` plus intermediates `i1` / `i2` (peer-host 1 / 2) force two `~peer.<hex>` instances. Run 17 mock adds `RP=/npm` (registry under a path prefix): start only the registry instance with it, because a prefixed patch server gives a false `redirect_unattributable`. Locally, run `vlt ci --allow-scripts :scripts` (otherwise vlt POSTs to api.socket.dev and the sandbox's 403 fails `ci` on 1.0.10 / 1.2.0; see #448). Run 9 mock adds `left-pad@1.2.0` (`'old'`) for bump tests. The run-11 mock adds a `time` map and `WDEP=` (wrapper's left-pad spec) for version-changing modifiers. The run-12 mock (rebuilt from the run-2 mock) adds `ADD=1` (the patch adds `lib/extra/deep/new.js`) and `EMPTYDIR=1` (the tarball ships empty dir entries), plus `CDN=1` and `bundler`. Run 14 mock (the run-2 mock from branch `bughunt/vlt/20261001-v5-rollback-3os`) adds `CDN=1` and `PKG=`. Run 15 adds `left-pad@1.2.0` to the run-2 mock and filters `/patches/batch` by request body (without that filter a bumped project shows a false `partial_failure`). The sandbox has no `ss`, so poll ports with `/dev/tcp`. Wait for ports 18555/18556 to free up before restarting the mock: a stale mock silently serves the previous mode. Kill mocks with `pkill -f '^node .*mock[.]mjs'`: a bare path pattern also kills the calling shell. The run-16 mock (the run-2 mock plus the batch filter) adds `FAIL_PKG=1` / `FAIL_ART=1`, `DELAY_PATH`+`DELAY_MS`, `bundler@1.0.0` and `PEER=1` (left-pad peers on `peer-host` `1 || 2`). Use `${NO_ALT-1}`, not `${NO_ALT:-1}`, or an empty `NO_ALT=` silently keeps `tar.br` off. To SIGINT a backgrounded run from a script, reset SIGINT to `SIG_DFL` first.
3+
Last updated: 2026-10-13 (run 19), main `d4af25a` (main was squashed on 2026-10-10, so older SHAs here no longer resolve), latest release 5.0.1 (5.0.0 before it; 4.0.0 has no vlt support). Newest vlt: 1.3.8 (2026-10-09). The run-19 mock (`left-pad@1.3.0` + `right-pad@1.3.0`, both patchable, with a body filter; `NO_ALT=` enables `tar.br`) is attached in full to #1494, which makes it the easiest one to rebuild. Run 18 mock: two patchable packages (`left-pad@1.3.0`, `right-pad@1.0.0`), with `/patches/batch` and `/patches/package` filtered by body; `PEER=1` plus intermediates `i1` / `i2` (peer-host 1 / 2) force two `~peer.<hex>` instances. Run 17 mock adds `RP=/npm` (registry under a path prefix): start only the registry instance with it, because a prefixed patch server gives a false `redirect_unattributable`. Locally, run `vlt ci --allow-scripts :scripts` (otherwise vlt POSTs to api.socket.dev and the sandbox's 403 fails `ci` on 1.0.10 / 1.2.0; see #448). Run 9 mock adds `left-pad@1.2.0` (`'old'`) for bump tests. The run-11 mock adds a `time` map and `WDEP=` (wrapper's left-pad spec) for version-changing modifiers. The run-12 mock (rebuilt from the run-2 mock) adds `ADD=1` (the patch adds `lib/extra/deep/new.js`) and `EMPTYDIR=1` (the tarball ships empty dir entries), plus `CDN=1` and `bundler`. Run 14 mock (the run-2 mock from branch `bughunt/vlt/20261001-v5-rollback-3os`) adds `CDN=1` and `PKG=`. Run 15 adds `left-pad@1.2.0` to the run-2 mock and filters `/patches/batch` by request body (without that filter a bumped project shows a false `partial_failure`). The sandbox has no `ss`, so poll ports with `/dev/tcp`. Wait for ports 18555/18556 to free up before restarting the mock: a stale mock silently serves the previous mode. Kill mocks with `pkill -f '^node .*mock[.]mjs'`: a bare path pattern also kills the calling shell. The run-16 mock (the run-2 mock plus the batch filter) adds `FAIL_PKG=1` / `FAIL_ART=1`, `DELAY_PATH`+`DELAY_MS`, `bundler@1.0.0` and `PEER=1` (left-pad peers on `peer-host` `1 || 2`). Use `${NO_ALT-1}`, not `${NO_ALT:-1}`, or an empty `NO_ALT=` silently keeps `tar.br` off. To SIGINT a backgrounded run from a script, reset SIGINT to `SIG_DFL` first.
44

55
Method: real vlt installs (`scripts/install-vlt.sh`) against a local Node mock of the npm registry plus the patch API. It's a pure-JS tar writer, so it runs on every OS. The registry is on :18555 and the patch server on :18556 via `SOCKET_PATCH_SERVER_URL`; set `SOCKET_NPM_REGISTRY` to the registry for v5 rollback. The oracle is `require('left-pad')` printing `patched` / `pristine`. The 3-OS probe scripts are in the run-2 workflow (run 36803186961), the run-3 global-mode workflow (run 36834317384) and the run-4 bundled-copy workflow (run 36871535059, whose mock adds a `bundler@1.0.0` that bundles left-pad). Run 6 mock adds `PKG=` (scoped names) and `CDN=1` (non-conventional `dist.tarball`); the patch artifact leaf must be the unscoped basename. The mock's `/patches/batch` must answer only for purls in the request body, or `scan -g` shows false hits. CI already runs the capstones and the native backtest on 57 releases × 3 OS.
66

@@ -28,6 +28,7 @@ Method: real vlt installs (`scripts/install-vlt.sh`) against a local Node mock o
2828
| Linux | 1.2.0 / 1.3.7 | run 15 (main `9472be4`): run-2 matrix pass; #942 fixed (member refusal for every vlt pattern shape, `package.json` fallback); catalogs (1.3.7) pass; **member with a stray `vlt-lock.json`: fail #1134** | run-2 matrix pass; liveness after #1050 (uninstall / bump / `--prune` / `--check`) pass; catalogs pass; member refused `vendor_lockfile_missing` pass; **stray member lock: fail #1134** (vex attests `not_affected`) | run-2 matrix pass; from a member: pass | run 15 |
2929
| Linux | 1.2.0 / 1.3.7 | run 16 (main `4aec9d7`): run-2 matrix pass; #1134 fixed (#1161); dual-root member (own `vlt.json`) pass; sibling `package-lock.json` (with / without `node_modules`) pass; brotli pin survives 1.3.7 re-saves; `~peer.<hex>` across 2 workspaces pass; hosted `remove` pass | takeover after #1039 (incl. failed / interrupted takeover, SIGINT / SIGTERM) pass; sibling npm lock: `vendor_multiple_lockfiles` (documented); `~peer.<hex>` pass; `remove` pass | bundled-only and bundled + direct (1.3.7) pass; `~peer.<hex>` pass | run 16 |
3030
| Linux | 1.2.0 / 1.3.7 / 1.3.8 | run 17 (main `1bd3da5`, v5 envelopes): run-2 matrix pass; rollback envelope incl. `rollback_failed` pass; `--dry-run` residue-free; DepID-special member dirs (`~ _ + % # ; ?`) pass; path-prefixed registry pass; `vlt update` drops the pin (documented), vex refuses | run-2 matrix, special dirs, prefixed registry, `vlt update` keeps `file:` pass; missing vendor ledger → `vendor_ledger_missing` | run-2 matrix pass; global store hardlink / auto / copy is copy-on-write (1.3.8); `apply --check` drift detection pass; #862 still repros | run 17 |
31+
| Linux | 1.2.0 / 1.3.8 | run 19 (main `d4af25a`): hosted pin beside a `file:` dir / tarball copy (root and member) warns, in-run VEX omits, standalone vex refuses: pass; #1437 with an alias pin and with a brotli pin: pass (#941 still restores gzip) | #1437 alias / brotli mixed state: pass | path-scoped `scan packages/a` with member alias (#1266): pass; **scan run from a member with an alias dep: fail #1494** (also pnpm 10.28); plain-name dep from a member: pass | run 19 |
3132
| Linux | 1.0.10 / 1.2.0 / 1.3.8 | run 18 (main `15c2c83`): #1437 vendored + hosted mixed state → bare `scan` / `get` `mode_ambiguous`, nothing written (1.0.10 / 1.2.0 / 1.3.8); mixed vex / list / remove / rollback pass; #1220 registry cap under `ulimit -n 64` (rollback / remove / takeover) pass; two transitive `~peer.<hex>` instances pass | multi-instance peers refused (documented), hosted pins kept; `--prune` after `vlt uninstall` reverts the entry (documented GC) | multi-instance peers pass | run 18 |
3233
| Linux | 0.0.0-18 / 0.0.0-20 / 1.0.0-rc.5 | rc.5 pass; 0.0.0-20 pins, but vlt ignores the lock (documented advisory) | 0.0.0-20 / rc.5 pass (legacy warning); A0 refused (documented) | untested | run 16, eras A0 / A |
3334
| Linux | 1.3.7 | run-2 matrix: pass (run 13); brotli (`tar.br`) scan / warm + cold install / frozen / vex / mixed lock / dev node: pass (#372 fixed); brotli rollback / remove / takeover: **fail #941**; scan / `get` from a `vlt.json` workspace member: **fail #942** (also 1.2.0) | run-2 matrix, brotli: pass; rollback byte-exact | brotli lock: pass | new release |
@@ -50,10 +51,10 @@ Method: real vlt installs (`scripts/install-vlt.sh`) against a local Node mock o
5051

5152
## Backlog
5253

53-
1. #862 once it's fixed (shipped empty dirs, nested new dirs, `remove`, macOS / Windows). `patch/rollback.rs` is unchanged on `15c2c83`.
54-
2. #1130's decision on #941 (brotli restore).
55-
3. Multi-instance `~peer.<hex>` plus a direct copy of the same version (three instances): hosted → vendored takeover refusal, and `remove` of one purl.
56-
4. #1437 detection with a brotli (`tar.br`, flag 1) hosted pin and with an npm-alias hosted pin beside a vendored package.
54+
1. #1494 once it's fixed. Also `rollback` / `repair` / `vex` from a member with an alias dep, and a scoped alias (`@sc/x` → `npm:left-pad`).
55+
2. #862 once it's fixed (shipped empty dirs, nested new dirs, `remove`, macOS / Windows). `patch/rollback.rs` is unchanged on `d4af25a`.
56+
3. #1130's decision on #941 (brotli restore).
57+
4. Multi-instance `~peer.<hex>` plus a direct copy of the same version (three instances): hosted → vendored takeover refusal, and `remove` of one purl.
5758
5. Find out why `vlt-compatibility.yml` hasn't run on main since 2026-10-09 (since the rewrite, only `CI` runs on push). Re-check the `native` legs once it does.
5859
6. The #521 residual (same-mirror `SOCKET_NPM_REGISTRY`, [comment](https://github.com/SocketDev/socket-patch/issues/521#issuecomment-6039419242)): re-check after the next restore change (#1444 only added the request cap).
5960
7. vlt 1.3.6 … 1.3.8 on macOS / Windows (probe branches are blocked).
@@ -110,3 +111,4 @@ Method: real vlt installs (`scripts/install-vlt.sh`) against a local Node mock o
110111
- `apply --check` on hosted / vendored vlt projects prints "No patch manifest found": vendor-owned and hosted patches are out of its scope by contract.
111112
- A no-mode `scan --prune` on a vendored vlt project is report-only for patching, but its GC runs for real: it reverts a ledger entry whose dependency `vlt uninstall` dropped and deletes that `.socket/vendor/npm/<uuid>` dir (documented, `CLI_CONTRACT.md` mode resolution and `--prune` leg (b)).
112113
- A bare `scan` / `get` from a vlt workspace member while the vendor ledger sits at the root runs hosted mode and refuses `redirect_workspace_lockfile_elsewhere` without writing. That's fail-closed; run from the root.
114+
- `vlt ci` (1.2.0 / 1.3.8), and `vlt install` in a workspace member, link a `file:` tarball dependency straight to the raw `.tgz` (`node_modules/x -> ../x.tgz`) instead of extracting it, with or without socket-patch. No copy can be loaded, so `vex` attesting the registry pin there isn't a false attestation. With the tarball copy extracted pristine (a fresh root `vlt install`), `vex` refuses correctly.

0 commit comments

Comments
 (0)