GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Hosted and vendored modes refuse vlt 1.3 locks whose nodes carry the new brotli flag (slot [0] = 4) · Issue #372 · SocketDev/socket-patch

Hosted and vendored modes refuse vlt 1.3 locks whose nodes carry the new brotli flag (slot [0] = 4) #372

New issue
Copy link
New issue
Copy link
Closed
#820
Closed
Hosted and vendored modes refuse vlt 1.3 locks whose nodes carry the new brotli flag (slot [0] = 4)#372
#820
Copy link
Labels
agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:vltvltvltpriority:p1

Description

@mikolalysenko
Mikola Lysenko (mikolalysenko)
opened on Sep 30, 2026
Issue body actions

[agent] Found by the scheduled vlt bug-hunt routine (ledger #307).

Summary

vlt 1.3.0 added --brotli-tarballs (default on). When a registry's packument advertises dist.alternates: [{ "kind": "tar.br", ... }] for a version, vlt resolves the .tar.br artifact and records a new node flag bit, LockfileNodeFlagBrotli = 4, in slot [0] (so a node's flags can now be 4, 5, 6 or 7). vlt 1.3's lockfile code is otherwise unchanged from 1.2.0: the DepID grammar and the one-node-per-line layout are the same, and lockfileVersion stays 1.

socket-patch's strict node-line grammar only accepts slot [0] ∈ {0,1,2,3} (crates/socket-patch-core/src/vendor/vlt_lock_text.rs:673), so a node with a brotli flag doesn't parse:

  • Hosted (scan --mode hosted): when every node is brotli (the normal case for a project on such a registry), the lock is refused with redirect_vlt_lock_unsupported: "nodes section is not in vlt's canonical layout; re-save it with a current vlt (vlt install) or update socket-patch". The command exits 0, nothing is redirected, and vlt ci installs the unpatched bytes. The remedy the message gives is wrong: the lock was just written by the current vlt. In a mixed lock, the lock-level check passes (it uses .any(), patch/redirect/vlt.rs:93-98), but a brotli target still can't be located by instance_line, so that dependency is refused.
  • Vendored (scan --mode vendored / vendor): fails with vendor_lockfile_version_unsupported, "vlt-lock.json is not in vlt's canonical layout; re-save it with vlt install". The code and message are both misleading: the lockfileVersion is 1.
  • Agent mode is unaffected (apply and rollback pass: it doesn't read the lock).

Impact

A vlt ≥ 1.3.0 user on a registry that serves Brotli tarballs can't use hosted or vendored mode at all. The refusal is loud in --json, but scan --mode hosted still exits 0. vlt 1.3.0–1.3.2 are published (1.3.2 is latest). The nightly canary already flags them as unlisted (vlt-compatibility run https://github.com/SocketDev/socket-patch/actions/runs/36669570554, canary (ubuntu-latest)), but the canary's capstones run against npmjs bytes, which don't advertise alternates. So they pass on 1.3.1 and this doesn't show.

Repro (Linux, vlt 1.3.2, Node 22.22.2, main f6b7fb9)

A ~60-line Node mock (mock.mjs, serving a registry plus the patch API) serves [email protected] with dist.alternates → left-pad-1.3.0.tar.br, plus a free hosted patch. NO_ALT=1 turns the alternates off for the control. The mock is in the ledger entry.

node mock.mjs &   # PORT=18555
mkdir p && cd p
echo '{"name":"app","version":"1.0.0","dependencies":{"left-pad":"1.3.0"}}' > package.json
echo '{"config":{"registries":{"npm":"http://127.0.0.1:18555/"}}}' > vlt.json
LANG=C vlt install
grep '~npm~left-pad' vlt-lock.json
#   "[email protected]": [4,"left-pad","sha512-p3Lt…","http://127.0.0.1:18555/left-pad/-/left-pad-1.3.0.tar.br"]
socket-patch scan --mode hosted --yes --api-url http://127.0.0.1:18555 --org test-org --api-token fake --json
#   rc=0, "redirected": 0, warnings: [redirect_vlt_lock_unsupported "nodes section is not in vlt's canonical layout …"]
rm -rf node_modules && vlt ci && node -e "console.log(require('left-pad'))"   # pristine
socket-patch scan --mode vendored --yes --api-url http://127.0.0.1:18555 --org test-org --api-token fake --json
#   rc=1, errorCode vendor_lockfile_version_unsupported "vlt-lock.json is not in vlt's canonical layout; re-save it with `vlt install`"

Control (same mock with NO_ALT=1, so the node flag is 0): hosted redirects 1 dependency, and vlt install then gives patched.

Expected vs actual

  • Expected: docs/ecosystems.md "npm: vlt notes" says a lock is refused only when socket-patch "cannot read [it] exactly as vlt does (a UTF-8 BOM, another lockfileVersion, a nodes section outside vlt's one-node-per-line layout)". This lock has none of those. It's canonical vlt output with lockfileVersion: 1.
  • Actual: refused as non-canonical, with a wrong remedy (hosted) and a wrong error code (vendored).

What a fix must also handle (verified with real vlt 1.3.2)

I hand-applied the pin a hosted rewrite would write to the brotli node (patched sha512 in slot [2], the hosted .tgz URL in slot [3]):

slot [0] kept as vlt ci installs lock after vlt ci
4 patched rewritten: vlt recomputes brotli from the URL and saves [0,…]
0 (bit 4 cleared) patched byte-identical; vlt install --frozen-lockfile is byte-stable too

So the hosted rewrite should clear bit 4 when it points a node at the .tgz artifact, and the slot revert should restore it. Also, vlt_heal::reinstalls_after_removal (patch/redirect/vlt_heal.rs:199, matches!(flags, Some(0 | 2))) treats a prod or dev brotli node (4, 6) like an optional one and keeps the stale copy. It probably wants flags & 1 == 0 once bit 4 is known. VEX discovery goes through the same line parser (vex/discover), so it likely skips these nodes as well.

Matrix

OS vlt brotli alternates advertised hosted vendored agent
Linux 1.2.0 yes (ignored, flag 0) pass untested untested
Linux 1.3.1 yes fail (refused) fail untested
Linux 1.3.2 yes fail (refused) fail pass
Linux 1.3.2 no (control) pass untested untested
macOS / Windows 1.3.x yes untested (pure text-parser path, expected identical) untested untested

vlt 1.3.0 itself fails vlt install with "Integrity check failure" against a registry advertising alternates (a vlt bug, fixed in 1.3.1), so 1.3.0 locks with bit 4 are unlikely in practice.

First bad: vlt 1.3.0 (first release with LockfileNodeFlagBrotli). Release 4.0.0 of socket-patch predates vlt hosted support (it reports redirect_npm_no_lockfile), so this isn't a socket-patch regression.

Suspect code: crates/socket-patch-core/src/vendor/vlt_lock_text.rs:673 (the "0" | "1" | "2" | "3" whitelist), crates/socket-patch-core/src/patch/redirect/vlt.rs:93-103, crates/socket-patch-core/src/patch/redirect/vlt_heal.rs:199.

Activity

  1. Mikola Lysenko (mikolalysenko)
    added
    bugSomething isn't workingSomething isn't working
    bughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agent
    pm:vltvltvlt
    agent:triaged
    priority:p1
    on Sep 30, 2026
  2. mikolalysenko commented on Sep 30, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Sep 30, 2026
    CollaboratorAuthor
    More actions

    [agent] Triaged: priority:p1 (vlt, npm family). Not a duplicate, and I found no existing fix PR.

    The cause is the vlt node-line grammar in vendor/vlt_lock_text.rs, which only whitelists flag values 0–3. Hosted redirect, vendored, vlt_heal and VEX discovery all share that parser, so one fix at the parser has to cover all of them. It also needs to clear and restore bit 4 when pointing a node at a .tgz.


    Generated by Claude Code

  3. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More actions

    [agent] Re-triage: still reproduces on main 2463257 (after the v5 consolidation in #277). Linux, vlt 1.3.2, same mock as the original report, with dist.alternates tar.br advertised (node line [4,"left-pad",…,".tar.br"]):

    • socket-patch scan --yes --json: rc 0, redirected: 0, redirect_vlt_lock_unsupported "nodes section is not in vlt's canonical layout; re-save it with a current vlt (vlt install) or update socket-patch".
    • socket-patch scan --mode vendored --yes --json: rc 1, partial_failure, per-patch vendor_lockfile_version_unsupported.

    In v5, a plain scan defaults to hosted mode, so this is now what a vlt ≥ 1.3 user on such a registry gets without passing any flags. The whitelist at crates/socket-patch-core/src/vendor/vlt_lock_text.rs:673 hasn't changed. The new v5 upstream restore (patch/redirect/upstream/vlt.rs) also goes through parse_node_line, so rollback/remove will need the same fix (and will need to put bit 4 back if the hosted rewrite clears it).


    Generated by Claude Code

  4. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More actions

    [agent] Re-triage on main 2463257: still reproduces on vlt 1.3.3 (published 2026-10-01T02:36Z, now latest). Against a registry that advertises tar.br alternates, vlt install still writes slot [0] = 4 ({'[email protected]': [4]}), and a bare scan exits 0 with redirected: 0 and redirect_vlt_lock_unsupported. That's 2/2 runs on Linux. So the brotli flag isn't specific to 1.3.1 / 1.3.2: every vlt 1.3.x from 1.3.1 on is affected.


    Generated by Claude Code

  5. mikolalysenko commented on Oct 2, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 2, 2026
    CollaboratorAuthor
    More actions

    [agent] This still reproduces on the two vlt releases published since the last check: 1.3.4 (2026-10-01) and 1.3.5 (2026-10-02). It's main 61cfb9b, Linux. Against a registry that advertises tar.br alternates, vlt 1.3.5 still writes [4,"left-pad",…,".../left-pad-1.3.0.tar.br"]. Hosted scan exits 0 with redirected: 0 and a warning, and vlt ci installs the pristine bytes. Without alternates (flag 0), 1.3.4 and 1.3.5 pass the full hosted / vendored / agent / workspace / CRLF matrix.


    Generated by Claude Code

  6. mikolalysenko commented on Oct 2, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 2, 2026
    CollaboratorAuthor
    More actions

    [agent] Re-checked on main b1f9818 (vlt bug-hunt, ledger #307) with vlt 1.3.5, twice, and it still reproduces. Against a registry that advertises tar.br alternates, the lock node is [4,"left-pad",…,".../left-pad-1.3.0.tar.br"]. A hosted scan then exits 0, leaves vlt-lock.json byte-identical, and redirects nothing.


    Generated by Claude Code

  7. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 2, 2026

    vlt bug-hunt run 9: file #601, re-triage #521/#372, verify #471/#541

    382a765
  8. mikolalysenko commented on Oct 5, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 5, 2026
    CollaboratorAuthor
    More actions

    [agent] Claiming this issue (shared root cause: the vlt node-line grammar whitelists slot [0] flags 0–3 and has no model of vlt 1.3's brotli bit 4). Branch: agent/fix-vlt-brotli-node-flag. Claim-ID: 2026-10-05T02:20:28Z-2dad7c


    Generated by Claude Code

  9. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Oct 5, 2026
  10. mikolalysenko commented on Oct 5, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 5, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft PR: #820


    Generated by Claude Code

  11. Mikola Lysenko (mikolalysenko)
    added 2 commits that reference this issue on Oct 5, 2026

    Accept vlt 1.3 brotli lock nodes

    This issue will close once commit b3996a6 is merged into the 'main' branch.
    b3996a6

    vlt: run 12 ledger (#862 filed; #601 verified; #521/#372 still repro)

    This issue will close once commit ecff54d is merged into the 'main' branch.
    ecff54d
  12. Mikola Lysenko (mikolalysenko)
    closed this as completedin #820on Oct 5, 2026
  13. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 6, 2026
  14. mikolalysenko commented on Oct 6, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 6, 2026
    CollaboratorAuthor
    More actions

    [agent] Verified fixed on main 9c43dfc (after #820), Linux, vlt 1.3.6 and 1.3.7, against the original mock (a registry that advertises tar.br alternates, node [4,…,".tar.br"], and a dev node [6,…]):

    • Hosted scan: rc 0, redirected 1, the node becomes [0,…,patched .tgz] (dev: [2,…]). A cold vlt ci and a warm vlt install install patched, --frozen-lockfile keeps the lock, vex rc 0, and a re-scan is a no-op.
    • Vendored: the file~.socket+vendor… node, ci / frozen patched, vex rc 0, and rollback is byte-exact.
    • Mixed lock (gzip wrapper + brotli left-pad): the wrapper line is untouched.

    One gap remains on the restore side: hosted rollback / remove / the hosted→vendored takeover write the gzip form back (flag 0, .tgz integrity and URL) instead of the original brotli node. I filed that as #941.


    Generated by Claude Code

  15. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 6, 2026

    vlt bug-hunt run 13: verify #372, file #941 and #942, cover vlt 1.3.7

    5ada4e8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:vltvltvltpriority:p1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.