Skip to content

Fix Bun/vlt bundled copies left unpatched (#469, #471) - #472

Merged
Mikola Lysenko (mikolalysenko) merged 11 commits into
mainfrom
agent/fix-bundled-copy-bun-vlt
Oct 2, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 11 commits into
mainfrom
agent/fix-bundled-copy-bun-vlt

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #469
Fixes #471

Summary

Bun and vlt projects whose dependency bundles the patched package (bundleDependencies) got a successful hosted/vendored scan, and VEX attested not_affected, while the copy the parent actually loads stayed unpatched. These copies are now skipped loudly by the rewriters and never attested by VEX, matching what #337 did for npm.

Root cause

#337 (#325) taught only the npm-lock paths that a bundled copy (unpacked from the parent's tarball) is never reached by a rewire. The Bun and vlt backends had no equivalent:

Changes

  • vendor::bun_lock_text::is_bundled_entry: the shared bundled-meta check. It fails closed: a meta that won't parse but mentions "bundled" counts as bundled.
  • Bun hosted (rewrite_bun_lock, rewrite_bun_binary): a bundled entry or bundled-only record is skipped with redirect_bun_bundled_instance_skipped and is not counted or confirmed. A binary record shared with a regular install is still redirected for that install, with the same warning. Each skipped uuid lands in the new RewriteResult.bundled_skipped_uuids, and hosted scan --vex verifies those purls instead of assuming them applied (Bugbot finding).
  • Bun vendored (vendor::bun_lock, vendor::bun_binary): bundled entries and records are never rewired, with vendor_bundled_instance_skipped. When nothing else matches, vendoring refuses with vendor_lock_entry_not_rewritable, which names the real reason instead of "run bun install".
  • Bun VEX (vex/discover/bun.rs): a bundled entry or record is never a ref, even when Socket-wired. It contests same-name@version refs in the same lock and, via resolved_elsewhere, in other locks.
  • bun.lockb codec: BinaryPackage.bundled / bundled_only come from the dependency edges' behavior bits.
  • vlt (vendor::vlt_bundled, new): a bounded, confined walk of the store for bundled copies. VEX withdraws a ref whose name@version has one. Vendored warns, or refuses when the bundled copy is the only install. The hosted scan warns redirect_vlt_bundled_instance_skipped and withholds the purl from in-run VEX.
  • CLI_CONTRACT.md "Contested locks" now covers Bun and vlt.
  • New diagnostics and test messages don't print patch uuids or URLs (CodeQL).
  • The npm, pypi and gem wrappers only dispatch to the binary, so they need no change.

Test evidence

I watched every new regression test fail without its fix, then pass with it:

Issue Test Red without the fix
#469 bun.lock hosted patch::redirect::tests::bun_lock_bundled_entry_is_skipped_with_loud_warning ✔
#469 bun.lock vendored vendor::bun_lock::tests::bundled_entry_is_never_rewired ✔
#469 bun.lock VEX (hosted + vendored, both shapes, other-version control) vex::discover::bun::tests::bundled_entries_are_never_refs_and_contest_the_same_version ✔
#469 hosted in-run scan --vex in_process_redirect::scan_redirect_bun_bundled_copy_is_not_attested_in_run ✔
#469 bun.lockb codec vendor::bun_lockb::tests::bundled_edges_flag_their_records (real Bun 1.3.14 fixtures bun-lockb-bundled/{only,both}) n/a (new field)
#469 bun.lockb hosted patch::redirect::bun_binary::tests::bundled_records_are_not_redirected_silently ✔
#469 bun.lockb vendored vendor::bun_lock::tests::binary_bundled_records_are_never_silently_rewired ✔
#469 bun.lockb VEX vex::discover::bun::tests::binary_bundled_records_are_never_attested ✔
#471 vlt VEX (hosted + vendored, other-version control) vex::discover::vlt::tests::an_installed_bundled_copy_contests_the_ref ✔
#471 vlt vendored vendor::vlt_lock::tests::a_bundled_store_copy_is_reported_not_silently_left_unpatched ✔
#471 vlt hosted scan (CLI) in_process_redirect vlt::scan_redirect_vlt_bundled_store_copy_warns ✔

Local results:

  • cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo test --workspace --all-features --no-fail-fast: all pass except the tests that use chmod to force write failures. This sandbox runs as root, which bypasses them, and they pass on CI's non-root runners.
  • e2e_redirect_bun_build (16), e2e_vendor_bun_build (14) and e2e_bun_lockb (12) pass with --include-ignored against real Bun 1.3.14.
  • Goldens: the new bun-lockb-bundled discovery golden is added. The pdm and poetry equivalence goldens are re-blessed because they hash Debug output, which now includes the empty new field; their inputs are unchanged.
  • Formatting: main is not rustfmt-clean and CI has no fmt check, so this PR leaves untouched files alone. An earlier cargo fmt --all churn was reverted in 4a787fe.

Follow-ups

  • On a vlt project where the bundled copy is the only install, the hosted scan still also prints the generic redirect_vlt_entry_not_found next to the new redirect_vlt_bundled_instance_skipped, which gives the real reason.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RcHrVGj3ZJ2CJQn6LezdCC


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
Bun records a bundleDependencies copy as its own parent/child entry
flagged { "bundled": true } and unpacks it from the parent's
tarball, never reading the entry. Hosted and vendored scans rewired
those entries and reported success, and vex attested not_affected,
while the copy the parent loads stayed unpatched.

Both rewriters now skip a bundled entry with a loud warning (vendored
refuses when it is the only instance), and vex never takes a bundled
entry as a ref: it contests a ref for the same name@version in the
same lock or any other, like npm's inBundle handling (#325).

Refs #469

Assisted-by: Claude Code:claude-opus-5-5
Comment thread crates/socket-patch-core/src/vex/discover/bun.rs Fixed
Comment thread crates/socket-patch-core/src/vex/discover/bun.rs Fixed
bun.lockb marks a bundleDependencies edge with the bundled behavior
bit. A record only such edges reach is unpacked from the parent's
tarball, so redirecting or vendoring it installed nothing while scan
reported success and vex attested not_affected. Bun also shares one
record between a regular and a bundled install of the same version,
where the bundled copy stays unpatched.

The binary codec now flags those records. Hosted and vendored skip a
bundled-only record (vendored refuses when nothing else matches),
warn when the record is shared, and vex never attests either case.

Refs #469

Assisted-by: Claude Code:claude-opus-5-5
vlt unpacks a bundleDependencies copy into its parent's store entry
and records no vlt-lock.json node for it, so no hosted or vendored
rewire reaches it. vex still attested the patch as not_affected while
that copy stayed unpatched.

vex now looks for real package directories inside each store
package's own node_modules (vlt links real dependencies as symlinks
beside the package), and does not attest a ref whose name@version a
bundled copy also installs. Vendored warns about such a copy, and
when it is the only install it refuses with that reason instead of
"run vlt install".

Refs #471

Assisted-by: Claude Code:claude-opus-5-5
A hosted scan in a vlt project pinned the regular lock node and
reported a clean success while a bundled copy of the same version,
unpacked into its parent's store entry, stayed unpatched. The scan
now warns redirect_vlt_bundled_instance_skipped and keeps that purl
out of the in-run VEX attestation.

Refs #471

Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Claude Code:claude-opus-5-5
CodeQL flagged the new bun and vlt bundled-copy diagnostics for
printing the patch uuid. They now name only the package, matching
the other recent VEX diagnostics.

Assisted-by: Claude Code:claude-opus-5-5
The new bun-lockb-bundled fixtures join the VEX discovery golden
corpus. The new bundled-copy tests no longer print lock specs or
diagnostics that carry patch URLs and uuids (CodeQL), only case
numbers and diagnostic codes.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 1, 2026 15:38
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

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.

Comment thread crates/socket-patch-core/src/patch/redirect/bun_binary.rs
A hosted scan --vex treated every confirmed redirect as applied. When
Bun shares a record between a regular install and a bundled copy,
or bun.lock has both entries, the regular entry is redirected but
the bundled copy stays unpatched, and the in-run attestation still
said not_affected.

The bun rewriters now record the uuids whose bundled instance they
skipped, and hosted scan verifies those purls instead of assuming
them applied, matching a standalone vex run.

Refs #469

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

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.

The redirect equivalence goldens hash each RewriteResult. The new
bundled_skipped_uuids set is left out of the serde digests while
empty, and the two goldens that hash its Debug form (pdm, poetry)
are re-blessed: their inputs are unchanged, only the printed struct
gained the empty field.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

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.

An earlier cargo fmt --all reformatted about 120 files this fix does
not touch (main is not rustfmt-clean and CI has no fmt check). Those
files are back to main's bytes, and the files this PR changes carry
only their real edits on top of main's formatting.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 4a787fe. Configure here.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] CI note on head 4a787fe: the only red check is native (ubuntu-latest, 2.17.3) in PDM patch compatibility. 1 of 44 live-API backtest cells failed. I don't think this PR causes it:

  • This PR changes no pip-family code. The diff covers Bun and vlt lock handling, VEX discovery for those, and one filter in hosted scan --vex.
  • The same workflow passed every cell on 93f8463, which has the same runtime code as 4a787fe. The later commits only re-bless test goldens and revert formatting.
  • On earlier heads of this branch, the Poetry, PDM and vlt backtests each failed a different single cell, with a different check, version or mode each time (appliedExactlyOne, rescanIdempotent, vlt crlf-lock). The next run passed them, which points to the live patch API these scripts call.

I'm re-running the failed job once. If it fails again I'll treat it as real and dig in.


Generated by Claude Code

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 1, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Burn-down agent: ready for review at 4a787fe (4a787fef74321c9e4c6d0f691f17461eb4eea756).

  • CI: all check runs green on this head (484 success, 5 skipped, 0 failed). The PDM patch compatibility / native (ubuntu-latest, 2.17.3) cell that was red earlier passed on its single re-run, consistent with the live-API flake noted above.
  • Bugbot: reviewed 4a787fe, no new issues; all earlier threads resolved.
  • Mergeable with no conflicts (16 commits behind main, no overlap).
  • Reviewer focus: the Bun and vlt lock rewriters now skip/contest bundled copies the same way the npm path does (Fix npm VEX attesting packages with an unpatched bundled copy (#325) #337), plus the matching VEX discovery change.

Slack announcement not sent: no Slack send tool is available to this agent; the next run will retry.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Reviewed 4a787fef74321c9e4c6d0f691f17461eb4eea756. Recommendation: ready to merge from a code-review perspective.

No actionable correctness or security regressions found. Bundled Bun entries are excluded from rewiring and attestation, including binary records shared by regular and bundled installs. The vlt installed-store check contests the same package/version, and in-run hosted VEX does not assume those skipped copies were patched.

Validation: cargo test -p socket-patch-core --lib bundled: 19 passed. cargo test -p socket-patch-core --lib bun_lockb: 27 passed across codec and restore compatibility fixtures. cargo test -p socket-patch-cli --test in_process_redirect bundled: 2 passed, covering Bun in-run VEX and vlt warnings. Full workspace and real Bun/vlt toolchain matrix not rerun.

@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit 1169ae6 into main Oct 2, 2026
533 of 534 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

4 participants