Repository navigation
Hosted scan/get run from a vlt workspace member reports success while pinning nothing: the #598 / #901 member refusal has no vlt.json case #942
Description
Activity
- addedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:vltvltvlt
on Oct 6, 2026 mikolalysenko commented
on Oct 6, 2026 CollaboratorAuthorMore actions[agent] Triage:
priority:p1(vlt is npm-family).Shares root cause with #884 (in-flight agent PR #901): the hosted governing-root pre-check in
crates/socket-patch-core/src/hosted/governing_root.rs(refusal) only knows some workspace layouts, so a member run whose lock lives at another root falls through to a silent no-lockfile success. #901 covers npm/yarn/Bunpackage.jsonworkspaces and deliberately leaves vlt out. Fixing this needs one more case in that same refusal: walk up to the nearestvlt.jsonwhoseworkspaces(string, array or object-of-groups) match the member and holdsvlt-lock.json. It isn't in #901's scope today. It can join #901 if that PR is reopened for work, or follow it once #901 lands.
Generated by Claude Code
mikolalysenko commented
on Oct 7, 2026 CollaboratorAuthorMore actions[agent] Claiming this issue (with #1071; shared root cause: the hosted workspace-member refusal in governing_root.rs only recognises package.json workspaces matched with a partial glob grammar). Branch: agent/fix-workspace-member-refusal-globs. Claim-ID: 2026-10-07T18:20:55Z-6e5d91
Generated by Claude Code
mikolalysenko commented
on Oct 7, 2026 CollaboratorAuthorMore actionsmikolalysenko commented
on Oct 8, 2026 CollaboratorAuthorMore actions[agent] vlt bug-hunt re-triage (ledger #307): verified fixed on main
9472be4(#1073), Linux, vlt 1.3.7.- When a hosted
scanorget pkg:npm/left-pad@1.3.0runs from avlt.jsonmember, it now exits 1 withredirect_workspace_lockfile_elsewhere(status: error) and leaves the rootvlt-lock.jsonbyte-identical. That also holds for thepackage.json-workspaces fallback, wherevlt.jsonhas noworkspacesfield. - Pattern shapes that vlt itself treats as members are all refused:
./packages/*, a trailing/, object groups{"p":"packages/*","q":["apps/b"]},**/a, andapps/{b,c}. A!apps/bnegation excludes the member for vlt too. - One gap remains: a member that holds its own stray
vlt-lock.jsonskips the check. I filed that as Hosted and vendored scans from a vlt workspace member with a stray vlt-lock.json write to that lock, which vlt ignores, and exit 0 (vendored VEX then attests not_affected whilevlt cifails) #1134.
Generated by Claude Code
- When a hosted
- added a commit that references this issue
on Oct 8, 2026
[agent] Found by the scheduled vlt bug-hunt routine (ledger #307).
Summary
vlt keeps one
vlt-lock.jsonat the root of a workspace declared invlt.json("workspaces": [...]). Run from a member directory,vlt install/vlt ciwalk up to that root and write or read only the root lock. The member gets no lock of its own.When
socket-patch scan(hosted is the default) orget <uuid> --mode hostedruns from that member directory, it finds the patch for the member'snode_modules/left-pad. It then reads locks only in the cwd, finds none, rewrites nothing and exits 0 withstatus: "success"andredirected: 0. The only signal isredirect_npm_no_lockfile("no package-lock.json / npm-shrinkwrap.json present"), which names the wrong package manager.This is the #590 / #884 shape. #598 added the governing-root refusal for pnpm and cargo, and open PR #901 extends it to npm, yarn and Bun
package.jsonworkspaces. Butgoverning_root.rshas no case for a vlt workspace root. PR #901 states the exclusion directly: "pnpm reads onlypnpm-workspace.yamland vlt onlyvlt.json, so their locks at aworkspacesroot govern no member through that field; the pnpm check owns pnpm workspaces". Nothing owns vlt workspaces. Vendored mode in the same directory already fails closed (vendor_lockfile_missing, exit 1), so the two modes disagree.Impact
get <uuid> --mode hostedasks for it, but nothing is pinned. Exit 0 andsuccesstell CI and users the project is protected.vlt ci(from the member or the root) installs the vulnerable upstream bytes.Repro (Linux, Node 22.22.0, main
9c43dfc)The mock is the run-2 probe mock from ledger #307 (registry on :18555, patch API on :18556, a free patch for
pkg:npm/left-pad@1.3.0). vlt is run with--allow-scripts :scriptsonly because the sandbox blocks vlt's security-data fetch.Expected vs actual
redirect_pnpm_lockfile_elsewhere/cargo_manifest_not_workspace_root): when "the project directory is a workspace member whose lock lives in another directory, so the rewriters, which read only the project directory, would pin nothing", the run is "refused before any takeover or write … the message names the directory to run from; exit 1". A vlt workspace member is exactly that case.status: success,redirected: 0, and onlyredirect_npm_no_lockfile.Matrix
scanfrom memberget --mode hostedfrom memberscanfrom root (control)tar.bralternates)macOS and Windows weren't run (probe branches are blocked for this routine). The check is path logic, so it's OS-independent.
First bad
Not a regression. Every release since vlt support behaves this way. It became a contract gap once #598 made member runs a refusal.
Suspect code
crates/socket-patch-core/src/hosted/governing_root.rs:54(refusal): only the pnpm (pnpm_lock_elsewhere,:106) and cargo checks run. The vlt lock only appears in the "has own lock" short-circuit (:110).WORKSPACE_ROOT_LOCKSdeliberately omitsvlt-lock.json, and it readspackage.jsonworkspaces. vlt readsworkspacesfromvlt.json(string, array or object-of-groups form), so a vlt check needs its own walk up to the nearestvlt.jsonwhoseworkspacesmatch the directory.lockfile-dir=..) ignores the parent pnpm-lock.yaml and reports success while pinning nothing #590 (pnpm).