Repository navigation
Fix vlt extglob workspace members (#1542) - #1555
Merged
Mikola Lysenko (mikolalysenko) merged 5 commits intoOct 15, 2026
Merged
Conversation
Assisted-by: Claude Code:claude-opus-5-5
vlt expands extglobs in workspaces and reads ! patterns differently from npm (1.3 drops excluded dirs wherever the ! sits until a later pattern relists them; 1.2 reads a leading ! literally). These tests pin what vlt 1.2.0 and 1.3.8 actually list (#1542). Assisted-by: Claude Code:claude-opus-5-5
A vlt workspace member listed through an extglob such as packages/+(a|b) was not seen as a member, so hosted and vendored runs from it wrote a stray lock vlt never reads, exited 0, and vendored VEX attested not_affected for a pristine install. The vlt dialect now matches what vlt 1.2.0 and 1.3.8 list: extglobs match, wildcards skip dot dirs, each named group globs on its own, and ! patterns follow vlt 1.3 (excluded wherever they sit until a later pattern relists them) or vlt 1.2 (read literally). Both write the same lock, so the root lock's member edges decide which one applies. Fixes #1542 Assisted-by: Claude Code:claude-opus-5-5
Hosted scan/get and the vendored engine both refuse a vlt workspace member listed through packages/+(a|b) or packages/@(a|b) that holds a stray vlt-lock.json, as they already did for packages/* (#1542). Assisted-by: Claude Code:claude-opus-5-5
A nearer vlt.json that excludes the member with a ! pattern and has no lock of its own stopped the root search, so an outer root that lists the member no longer refused the run. Only a root that the current vlt lists the member under now ends the walk. The relist check also splits paths on both separators, like the matcher. Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 15, 2026 01:22
Collaborator
Author
|
BugBot review 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 fcfe72a. Configure here.
Tanmay Singla (Tanmay182003)
approved these changes
Oct 15, 2026
Collaborator
Author
|
Ready for review (burn-down agent)
Generated by Claude Code |
Mikola Lysenko (mikolalysenko)
deleted the
agent/fix-vlt-workspace-extglob
branch
October 15, 2026 02:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1542
Summary
A vlt workspace member listed through an extglob (
packages/+(a|b),packages/@(a|b)) wasn't recognised as a member. Hosted and vendored runs from it wrote a stray lock orpackage.jsonthat vlt never reads, exited 0, and vendored VEX attestednot_affectedfor a pristine install. Hosted and vendored runs now refuse such a member the same way they already refused one listed bypackages/*(#1134 / #1161).Root cause
WorkspacesDialect::VLT(crates/socket-patch-core/src/utils/workspace_globs.rs) turned extglobs off and read!patterns last-match-wins. I probed real vlt to see what it actually lists (vlt installthenvlt query ':workspace') and read its bundledMonorepo#glob:+(..),@(..),?(..),*(..),!(..).dircomponentspackages/*skipspackages/.h)["!packages/a","packages/*"]["packages/*","!packages/a","packages/a"]["!packages/*","packages/a"]["packages/a","!packages/*"]["!!packages/a"]["!(apps)/a"]vlt 1.3's
splitNegatedPatternsmoves a!pattern into an ignore list, and a later positive pattern drops any ignore that its own text matches. vlt 1.2 globs every pattern as given, so a leading!is literal. Neither reading is the old last-match-wins one, and the issue's suggestedNegation::Unorderedwould also be wrong, because relisting works.Fix
workspace_globs.rs:VLTis nowextglob: true,dot: false,Negation::Relisted(1.3's rule). A newVLT_PRE_1_3usesNegation::Literal. A newdotfield on the dialect keeps every other dialect attrue, so their behaviour is unchanged.governing_root.rs:vlt_lists_memberevaluates eachvlt.jsongroup separately. Both vlt versions write the samevlt-lock.json, so when they disagree on a directory, the root lock'sworkspace~<path>edge sources decide which version wrote it. vlt records an edge from every installed member that has a dependency. This is the same approach as the Bun 1.3 split (Bun 1.3.0 and 1.3.1 locks have no configVersion, so a "!"-excluded member is still refused in hosted and vendored mode after the #1492 fix (regression since #1480) #1521). An unreadable lock keeps the wider reading. It's used by thevlt.jsonwalk (vlt_workspace_root) and by thepackage.jsonfallback (lock_lists_member), so the hosted refusal,member_stray_lock(vendoredvendor_lockfile_missing, VEX discovery) andnested_npm_projectall pick it up.vlt.jsonwith no lock that excludes the member no longer stops the root walk. This came from the/code-review highpass.No wrapper (
npm/,pypi/,gem/) changes: membership is decided only in core.Tests (red → green)
governing_root::tests::vlt_extglob_member_is_refused(both patterns × vlt.json / package.json fallback × with/without stray lock)npm_flavor::tests::bun_and_vlt_members_with_stray_lock_are_refused(+2 extglob rows)member_stray_lockpath)scan/getin_process_redirect_pnpm::hosted_scan_from_bun_or_vlt_member_with_stray_lock_refuses(+2 extglob rows)workspace_globs::tests::vlt_dialects_list_what_vlt_lists,negation_is_per_dialectgoverning_root::tests::vlt_negated_member_reads_the_root_lockvlt_negation_stays_in_its_group,vlt_excluded_by_an_uninstalled_inner_root_walks_onThe red run used a placeholder
VLT_PRE_1_3 = VLTon top ofmain: 4 of 5 new tests failed. The 5th (groups) guards against the new negation rule leaking across groups.Local runs:
cargo fmt --all -- --checkandcargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --all-features --lib: 6504 passed, 4 failed. The 4 failures (copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure…,pypi_requirements::wire_failure_rolls_back…) are chmod-based tests that can't fail as root in this sandbox, and they're unrelated to this change.cargo test -p socket-patch-cli --all-features(--lib,in_process_redirect_pnpm,in_process_vendor,mode_migration_vlt,e2e_vlt,in_process_vendor_npm_v1_takeover): all pass.cargo test --workspace: building every test binary ran this container out of disk. CI runs it.Follow-ups
Monorepo#globOptions). That's not modelled here; it only matters for nested member layouts.🤖 Generated with Claude Code
Generated by Claude Code