Repository navigation
Fix vlt 1.3 brotli lock nodes being refused (#372) - #820
Conversation
Assisted-by: Claude Code:claude-opus-5-5
vlt 1.3 marks a lock node that fetches the registry's Brotli (.tar.br) tarball with a new flag bit, 4, in slot [0]. socket-patch only accepted flags 0-3, so hosted mode refused such a lock as "not canonical" and exited 0 with nothing redirected, and vendored mode failed with a misleading lockfile-version error. Accept flags 0-7. When a pin or vendored wiring points a node at a .tgz or local directory, clear the brotli bit as vlt would save it; reverts put the recorded bit back with the original slots. The vlt heal now reinstalls brotli prod and dev nodes like any other. Fixes #372 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
|
[agent] Labeled Ready for review.
Slack announcement not sent this run (no Slack send tool available), so the next run will retry. Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NhRxWtzEYpLyrByBegiiRy
|
Generated by Claude Code |
|
The failing test's name falls outside the 5,000-line log tail I can read, so the root cause isn't known yet. I'll re-run the job once when its workflow run finishes. If it fails again, I'll treat it as real and dig in. Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NhRxWtzEYpLyrByBegiiRy
main is red since 4646693 (#605): two commands::vex_consumed tests assumed the name-keyed resolver never returns npm-aliased copies. Same test-only change as #851; it no-ops once main carries it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NhRxWtzEYpLyrByBegiiRy
|
Update on the I pushed fde5eef, which merges
Generated by Claude Code |
The fix commit b3996a6 also reformatted 123 files it does not otherwise touch (the output of cargo fmt --all on a tree main has not formatted). Every one of those files is byte-identical to rustfmt run over main's version, so this restores them to main. The PR now only touches the vlt lock, redirect and heal code plus the ported #851 test fix, which keeps the review small and stops the churn from conflicting with every other open PR. Co-Authored-By: Claude <noreply@anthropic.com>
|
Burn-down agent: pushed
Generated by Claude Code |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 95ecf33. Configure here.
|
Burn-down agent: labeled Ready for review.
Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #372
Root cause
vlt 1.3 records a new node flag bit,
brotli = 4, in slot [0] of avlt-lock.jsonnode when it resolved a.tar.bralternate. The shared vlt node-line grammar (vendor/vlt_lock_text.rs::parse_node_entry_text) whitelists slot [0] ∈ {0,1,2,3}, so every brotli node fails to parse. Hosted, vendored, heal and VEX discovery all read nodes through that parser, so hosted refuses the lock as "not canonical" (exit 0, nothing redirected), and vendored fails withvendor_lockfile_version_unsupported.Changes (b3996a6)
0–7(node_flags); anything else is still refused.render_tuple_with_slotsnow takes the brotli bit explicitly, because slots [2]/[3] name one artifact and its hash. vlt derives the bit from slot [3]'s extension (tarballFormat, checked against@vltpkg/graph/@vltpkg/types1.3.6). If slot [3] is omitted, vlt uses the stored bit to rebuild the URL. Callers:.tgz: bit cleared, sovlt cikeeps the lock byte-stable, as the issue verified..tgzintegrity: bit follows the written URL (cleared when omitted).vlt_heal::reinstalls_after_removal: decided by the optional bit (flags <= 7 && flags & 1 == 0), so brotli prod/dev nodes (4, 6) are reinstalled.Tests (red → green)
With only the old
"0" | "1" | "2" | "3"grammar line restored, 3 of the 4 new tests fail. With the fix, all 4 pass:vlt_lock_text::node_line_grammar_accepts_vlt_1_3_brotli_flags(flags 4–7 parse; 8,07,-1still refused)vlt_lock_text::brotli_bit_follows_the_artifact_slot_three_namesredirect::vlt::a_vlt_1_3_brotli_lock_is_pinned_with_the_brotli_bit_cleared(hosted: no refusal, bits cleared with dev kept, idempotent re-run, carried-pin restore puts bit 4 back)vendor::vlt_lock::a_vlt_1_3_brotli_lock_is_vendored_and_reverted_exactly(vendored wire + byte-exact revert)vlt_heal::only_prod_and_dev_nodes_are_reinstalled_after_removalcargo test -p socket-patch-core --lib -- vlt: 171 passed, 1 failed. The failure isvlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry, which depends on a0o555directory blocking writes, and this sandbox runs as root. The change doesn't touch it.Local gate
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test --workspace --all-features --no-fail-fast: every vlt binary passes (e2e_redirect_vlt_build,e2e_vendor_vlt_build,e2e_vlt,e2e_safety_vlt,mode_migration_vlt). The only local failures don't involve vlt:covgap_commands_vendor*_state_write_failure_*,vlt_heal::an_unremovable_hidden_lock_*). This sandbox runs as root, so a0o555directory doesn't block writes.--include-ignored vlt_pinned_matrix) can't fetch npmjs from the Rust test client in this sandbox. CI runs it: 460/466 checks green on b3996a6, 3 still in progress, 0 failed.Per-issue checklist
a_vlt_1_3_brotli_lock_is_pinned_with_the_brotli_bit_cleareda_vlt_1_3_brotli_lock_is_vendored_and_reverted_exactlyonly_prod_and_dev_nodes_are_reinstalled_after_removalFollow-ups (not in this PR)
.tar.bralternates. A real-vlt-1.3 e2e would need a mock registry that serves alternates.Note
Medium Risk
Touches vlt lock parsing and rewrite paths (hosted, vendor, heal, upstream restore); behavior is narrow and heavily tested but incorrect flag handling could break installs on vlt 1.3 locks.
Overview
Fixes #372 by teaching the shared
vlt-lock.jsonnode grammar to accept vlt 1.3 slot [0] flags 0–7 (including the brotli bit 4 for.tar.brresolves), instead of refusing anything above 3 as non-canonical.Brotli-aware tuple rendering:
render_tuple_with_slotsnow takes an explicit brotli flag derived from slot [3]’s URL extension (brotli_for_slot3/has_brotli_flag). Hosted redirect pins clear bit 4 when rewriting to a hosted.tgz; vendored wiring and upstream restore follow the same artifact rules; revert and carried-pin restore put the pristine brotli bit back. Heal treats brotli prod/dev nodes (4, 6) as reinstallable after removal (optional bit still excludes 1, 3, 5, 7).Tests: New coverage for brotli lock parse, pin, vendor/revert, and flag behavior; vex hosted npm tests were adjusted so alias expansion is still exercised now that the name-keyed resolver (#605) discovers aliases on its own.
Reviewed by Cursor Bugbot for commit 95ecf33. Configure here.
Generated by Claude Code