GeezerVison is showing github.com — Fix Bun 1.3+ bun.lockb read as pre-1.3 (#1492) by mikolalysenko · Pull Request #1496 · SocketDev/socket-patch
Conversation
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1492
Summary
A Bun 1.3+ project that keeps a binary bun.lockb (saveTextLockfile = false) and excludes a member with "!packages/b" can patch that member again in hosted and vendored mode. Since 5.0.1, socket-patch treated the excluded member as a workspace member. It refused with redirect_workspace_lockfile_elsewhere (hosted) or vendor_lockfile_missing (vendored) and named a root lock Bun never reads for that member.
Root cause
lock_dialect in crates/socket-patch-core/src/hosted/governing_root.rs (#1097, #1480) picks how a root's workspaces globs are read from the lock at that root. Every lone bun.lockb was read with the pre-1.3 Bun rules, which ignore !. Bun 1.3+ applies ! whichever lock format it writes. It marks a bun.lockb with a cNfGvRsN extension that carries configVersion, the binary twin of the text lock's top-level key, which the bun.lock branch already checks.
Fix
Test evidence
- New
hosted::governing_root::tests::bun_lockb_with_a_config_version_tag_honours_negated_workspaces uses real Bun 1.3.14, 1.4.2 workspace-root and 1.4.2 scoped-overrides locks (the last is the new bun-lockb/1.4.2-scoped-overrides fixture, written on Linux) (no refusal, member lock not a stray), plus 1.2.23 and a non-binary lock (still refused).
- Red before the fix:
assertion left == right failed: bun.lockb of 1646 bytes; left: Some("redirect_workspace_lockfile_elsewhere"), right: None.
- Green after:
cargo test -p socket-patch-core --all-features --lib -- governing_root bun_lockb → 67 passed.
- New
vendor::bun_lockb::tests::config_version_is_read_from_tagged_locks_only checks every historical fixture 0.1.1 to 1.4.2, plus workspace "late-dependent" locks.
cargo fmt --all -- --check: clean. cargo clippy --workspace --all-features -- -D warnings: clean.
cargo test -p socket-patch-core --all-features --lib: 6453 passed and 4 failed. All 4 are permission-denial tests (copy_tree symlinked root, vlt_heal unremovable lock, poetry/requirements write failure) that cannot fail as intended when the sandbox runs as root. They are unrelated to this diff, and CI runs as non-root.
- I did not run the full
cargo test --workspace locally: the sandbox ran out of disk building every CLI test binary. CI runs the full suite.
Per-issue checklist
Notes / not changed
- Bun 1.3.0 writes no
cNfGvRsN tag (fixture bun-lockb/1.3.0), so its binary lock still reads as older Bun. Its text bun.lock without configVersion already does the same today. This fails closed: a refusal, never a wrong pin.
/code-review high suggested a different approach: decide membership from the lock's own workspace list (workspace_paths()) instead of the Bun version. I didn't take it. The text-lock branch decides by configVersion too, and the lock's list is stale for a member added since the last install. Moving both branches would be a separate change to the Hosted scan from a yarn classic workspace member still pins nothing and exits 0 when the root's workspaces use a ! pattern (yarn 1 ignores it) or an extglob like packages/@(a|b) #1097 design. Every other finding (full-parse dependence, unknown-extension stop, unbounded read, 1.3.0 doc claim, stale CLI test comment, missing workspace-root fixture) is fixed in 7d05f17. A reviewer's finding on scoped overrides is fixed in 13f02d6 (fixture fitted to the VEX corpus in e509c25).
🤖 Generated with Claude Code
Note Medium Risk
Changes workspace membership and refusal logic for hosted/vendored npm flows when only bun.lockb is present; mis-detection could refuse or allow runs from the wrong directory, but untagged or invalid locks still fall back to pre-1.3 behavior.
Overview
Fixes #1492: lone binary bun.lockb locks were always interpreted with pre–Bun 1.3 workspace rules (negated ! patterns ignored), so excluded workspace members were wrongly refused with redirect_workspace_lockfile_elsewhere / stray-lock handling when only a tagged bun.lockb existed at the root.
read_config_version in bun_lockb.rs reads Bun’s cNfGvRsN extension (binary twin of text configVersion) via a structural walk, including when sCoPdOvR follows the tag. lock_dialect uses that for standalone bun.lockb (FIFO-safe sync read on the blocking pool) to pick Bun 1.3+ vs pre-1.3 glob semantics, matching the existing bun.lock path.
Docs (CLI_CONTRACT.md), CLI test comments, a 1.4.2-scoped-overrides fixture, VEX golden updates, and unit/integration tests cover tagged vs untagged locks and negated workspaces.
Reviewed by Cursor Bugbot for commit e509c25. Configure here.
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+ writes a cNfGvRsN extension into bun.lockb, the binary
twin of the text lock's configVersion. Expose it from the codec and
add regression tests for #1492: a tagged lone bun.lockb root must
honour "!" workspace patterns, so an excluded member's own lock is
the one patched. WIP: lock_dialect does not read the tag yet.
Assisted-by: Claude Code:claude-opus-5-5
A Bun 1.3+ project that keeps a binary bun.lockb (saveTextLockfile =
false) and excludes a member with "!packages/b" could no longer
patch that member in hosted or vendored mode: socket-patch read the
lone bun.lockb as older Bun, which ignores "!", and refused with
redirect_workspace_lockfile_elsewhere. Read the cNfGvRsN
config-version tag Bun 1.3+ writes into bun.lockb, as configVersion
is read from bun.lock. Fixes #1492.
Assisted-by: Claude Code:claude-opus-5-5
The Bun 1.3+ check parsed the whole bun.lockb, so a tagged lock the
codec rejects, or one with an extension it does not know before the
tag, still read as older Bun and kept refusing an excluded member.
Bun writes the cNfGvRsN extension last, right before the lock's
total length, so read the header and those 16 bytes only. This also
keeps the check cheap on large monorepo locks. Cover a workspace
root's lock, whose tag follows its workspace and catalog extensions,
and say in the docs that Bun 1.3.0 does not write the tag.
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.
cursor
Bot
left a comment
•
edited
Loading
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.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
…ialect
# Conflicts:
# crates/socket-patch-cli/CLI_CONTRACT.md
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
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.
Stale Bugbot comment from a previous run.
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.
Bun writes the sCoPdOvR scoped-overrides extension after cNfGvRsN, so
a lock with nested overrides has no tag at total - 16 and still read as
older Bun, refusing a member excluded with "!". Walk the structure
instead: the header, the six buffer descriptors and the extension tags,
seeking past every array, so package records are never read and the
tag is found wherever Bun puts it. Add a Bun 1.4.2 fixture with scoped
overrides and a "!" workspace pattern.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013g2AhipQxH9Q19uPZT6Aph
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 e509c25. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Ready for review (burn-down agent)
Generated by Claude Code
|
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.
This was referenced Oct 14, 2026
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Labels
Ready for review
Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review
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.
|