GeezerVison is showing github.com — Fix untagged Bun 1.3.0/1.3.1 lock dialect (#1521) by mikolalysenko · Pull Request #1523 · SocketDev/socket-patch
Conversation
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1521
Summary
Bun 1.3.0 and 1.3.1 honour ! workspace exclusions, but socket-patch read their locks as pre-1.3 Bun. A project excluded from a Bun workspace with ! therefore couldn't be patched from either directory. The hosted scan was refused, the vendored scan failed, and the suggested root run reported success with nothing pinned. This PR makes the untagged lock's own workspace list decide which Bun wrote it.
Root cause
lock_dialect in crates/socket-patch-core/src/hosted/governing_root.rs works out whether a Bun root lock honours ! from a version tag alone: a top-level configVersion in bun.lock, or the cNfGvRsN trailer in bun.lockb (#1496). Bun 1.3.0 and 1.3.1 write neither tag (1.3.2 is the first release that does), so their locks read as pre-1.3, and package_json_workspace_root counted the excluded member as governed by the root lock. Both the hosted refusal (redirect_workspace_lockfile_elsewhere) and the vendored stray-lock check (member_stray_lock → vendor_lockfile_missing) go through that function.
Fix
New lock_lists_member helper. Only a directory that a ! pattern excludes reads differently between the two Bun dialects, and only an untagged lock is ambiguous. For that case:
- If the lock lists the member, or any other
!-excluded directory, it was written by Bun before 1.3, which lists every member it matched. The member is governed.
- If it lists none of them, it is a 1.3.0/1.3.1 lock and the member is a standalone project.
- If the list can't be read (unparseable or missing section), today's wider pre-1.3 reading is kept.
Workspace keys are normalized (./ prefix, \\ separators) before comparing. Real bun.lockb files written by Bun 1.2.23, 1.3.0 and 1.3.1 for the same ["packages/*","!packages/b"] root are added under tests/fixtures/bun-lockb/negated-workspace. They were generated with the official @oven/bun-linux-x64 builds; the text-lock outputs are inlined in the test.
Accepted trade-off: suppose a stale Bun 1.2 lock was last written before every !-excluded directory existed. Then it lists none of them and is read as 1.3.0/1.3.1, so the member is not refused. Nothing in such a lock tells it apart from a 1.3.0 lock. This matches 5.0.0, before #1480. The fix keeps the refusal whenever the lock lists any excluded directory.
Test evidence
untagged_bun_lock_reads_its_workspace_list (new). Covers 1.2.23 / 1.3.0 text locks and 1.2.23 / 1.3.0 / 1.3.1 binary locks: the hosted refusal, member_stray_lock (the vendored path), the unexcluded member packages/a (still refused), and that each verdict comes from a parsed list. Red without the fix: bun.lock of 219 bytes: left: Some("redirect_workspace_lockfile_elsewhere") right: None. Green with it.
untagged_bun_lock_listing_any_excluded_dir_is_pre_1_3 (new): the per-lock decision and ./ key normalization.
bun_lockb_with_a_config_version_tag_honours_negated_workspaces: the untagged 1.2.23 row now uses the real 1.2.23 lock for this workspace (it lists packages/b; still refused). The old fixture was a non-workspace project lock.
bun_config_version_is_read_at_the_top_level_only: its pre-1.3 lock now lists packages/b, as a real one does, so the test still checks only that a nested configVersion isn't read as the tag.
- VEX discovery golden regenerated for the new fixture directory (empty entries).
Commands run locally:
cargo fmt --all -- --check and cargo clippy --workspace --all-features -- -D warnings: clean.
cargo test -p socket-patch-core --all-features --lib: 6473 passed. The 5 failures were the 4 chmod-based tests that don't hold under root in this sandbox (copy_tree, vlt_heal, pypi_poetry, pypi_requirements) plus the golden corpus, now regenerated.
in_process_redirect_pnpm (38), in_process_vendor_bun_takeover (40), mode_migration_bun (35): all pass.
e2e_bun_lockb: 23/24. binary_shared_bundled_record_hosted_pin_is_managed needs patches-api.socket.dev, which the sandbox can't reach; it doesn't touch this code path.
- A full
cargo test --workspace ran out of the sandbox's disk, so CI covers the rest.
No wrapper (npm/, pypi/, gem/) changes: they only dispatch to the binary.
Per-issue checklist
/code-review high
Fixed: per-lock version decision, key normalization, the shared read_regular_to_bytes helper, and the stale WorkspacesDialect docs. Not fixed: (1) the stale-1.2-lock case above, which can't be told apart from the lock bytes; (2) the repeated lock reads. They happen only for a !-excluded member under an untagged Bun lock, so caching isn't worth the extra code.
🤖 Generated with Claude Code
https://claude.ai/code/session_01FEZwdsnHoJB8vCKkMFipaY
Generated by Claude Code
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
Bun 1.3.0 and 1.3.1 already skip workspace members excluded with a `!`
pattern, but their bun.lock / bun.lockb carry no config-version tag, so
socket-patch read them as older Bun and still counted the excluded
member as part of the root workspace. Hosted scans from that member
were refused (redirect_workspace_lockfile_elsewhere), vendored scans
failed with vendor_lockfile_missing, and the suggested root run pinned
nothing.
For an untagged Bun lock, an excluded directory now counts as a member
only when the root lock actually lists it: Bun before 1.3 lists every
member it matched, while 1.3.0/1.3.1 leave an excluded one out. An
unreadable lock keeps the old, wider reading. Adds real 1.2.23, 1.3.0
and 1.3.1 binary locks as fixtures.
Fixes #1521
Assisted-by: Claude Code:claude-opus-5-5
Asserts the verdict comes from the members each real lock lists rather
than from a lock that failed to read, and records the new
negated-workspace fixture in the VEX discovery golden corpus.
Refs #1521
Assisted-by: Claude Code:claude-opus-5-5
An untagged Bun lock that lists any `!`-excluded directory comes from
Bun before 1.3, so every excluded directory under it now counts as a
member, including one added since the last install. Workspace keys
spelled with a `./` prefix or backslashes are normalized before the
comparison, the binary lock is read through the shared file helper,
and the dialect docs describe the 1.3.0/1.3.1 case.
Refs #1521
Assisted-by: Claude Code:claude-opus-5-5
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ 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 ea8578d. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
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.
|