Skip to content

Fix vendored npm tarballs captured by Git LFS (#1541) - #1559

Merged
Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
agent/fix-vendor-gitattributes-lfs
Oct 15, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
agent/fix-vendor-gitattributes-lfs

Conversation

@mikolalysenko

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

Copy link
Copy Markdown
Collaborator

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

Fixes #1541

Summary

A repo whose .gitattributes hands *.tgz to Git LFS committed every vendored npm-family tarball (and each bun.lockb workspace mirror) as an LFS pointer. Any checkout that doesn't smudge LFS (actions/checkout defaults, no git-lfs, GIT_LFS_SKIP_SMUDGE=1, air-gapped builds) then failed the frozen install, while the vendored scan reported success.

Root cause

All npm-family vendored flavors (npm, pnpm, yarn classic/berry, bun text and bun.lockb, vlt) write .socket/vendor/npm/<uuid>/.gitattributes from one constant, npm_dir::UUID_GITATTRIBUTES. It held * -text, which turns off EOL conversion but leaves a parent filter=lfs rule in force.

Fix

  • UUID_GITATTRIBUTES is now * -text -filter -ident -working-tree-encoding: every attribute that lets git store or check out bytes other than the artifact's is unset at the uuid level, which beats any .gitattributes above it.
  • The pre-Vendored Bun tarballs go into Git LFS when .gitattributes tracks *.tgz with LFS, so a checkout without LFS fails bun install --frozen-lockfile #1541 * -text file still counts as ours (is_uuid_gitattributes), so a Bun workspace mirror's metadata is still removed on revert. An in-sync vendored re-run already passes through restore_uuid_metadata (via stage_patch_pack → keep_pack_committable) for all six tarball flavors, so existing trees are upgraded on their next run.
  • mirror_metadata now checks the file name before reading a sibling.
  • CLI_CONTRACT (npm and vlt rows) and docs/ecosystems.md describe the new attributes, plus the git add --renormalize .socket/vendor/npm step for a tarball an older release already committed as a pointer.

Tests (red → green)

Issue / case Test Without fix With fix
#1541 mechanism: a repo *.tgz filter=lfs / *.js ident working-tree-encoding rule no longer applies under the uuid dir npm_dir::tests::the_uuid_gitattributes_overrides_repository_lfs_rules (core, needs only git) FAILED (filter: lfs) ok
#1541 end to end, Bun 1.4.2: LFS rule → vendor → commit → GIT_LFS_SKIP_SMUDGE=1 clone → bun install --frozen-lockfile installs patched bytes e2e_vendor_bun_build::bun_vendor_tarball_is_not_committed_to_git_lfs FAILED ("the vendored tarball went into LFS") ok
Legacy file upgraded in place npm_dir::tests::legacy_uuid_gitattributes_is_upgraded n/a (new API) ok
Legacy file still removed with a reverted Bun workspace mirror bun_binary::rebuild_tests::a_tgz_rule_still_commits_every_workspace_mirror (extended) FAILED (.socket not pruned) ok

Local runs: cargo fmt --all -- --check ok; cargo clippy --workspace --all-features -- -D warnings ok; SOCKET_PATCH_BUN_REQUIRED=1 cargo test -p socket-patch-cli --all-features --test e2e_vendor_bun_build 40/40 ok. cargo test --workspace --all-features --no-fail-fast: 241 binaries ok, 10 failures, none in code this PR touches. Nine are permission-denial tests (unwritable/unremovable files), which can't fail as intended because the sandbox runs as root. The tenth is e2e_bun_lockb::binary_shared_bundled_record_hosted_pin_is_managed, a hosted rollback that needs patches-api.socket.dev, which the sandbox proxy blocks. CI is the arbiter for these.

Review notes (/code-review high)

  • Fixed: mirror_metadata read every sibling before checking its name; the doc comment overstated what can outrank the uuid file.
  • Not changed: the LFS e2e soft-skips when git-lfs is missing even under the required gate. The Depot runner images aren't guaranteed to ship git-lfs, and without it the test can't reproduce the bug at all. The core check-attr test covers the mechanism on every runner.
  • Not changed: an in-sync re-run that upgrades a legacy .gitattributes emits no event. It's a one-time metadata rewrite of a file that isn't part of the artifact, the same as today's restore of an edited file.

Follow-ups (not in this PR)

  • JVM trees (vendor/jvm/mod.rs TREE_GITATTRIBUTES, redownload.rs) and the Gradle redirect still write * -text, so *.jar filter=lfs repos are likely affected the same way (p3, separate ownership checks).
  • A tarball already committed as an LFS pointer isn't detected; a git cat-file pointer probe with a warning could replace the documented --renormalize step.
  • .git/info/attributes, and a .gitattributes shipped inside a vlt directory payload, can still override the uuid file.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WdaShef4vyGWjbTSpLbh9E


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
A repo that LFS-tracks *.tgz committed every vendored npm-family
tarball (and each bun.lockb member mirror) as an LFS pointer, so any
checkout without LFS smudging failed its frozen install while the
vendored scan reported success.

The per-uuid .gitattributes only unset `text`. It now also unsets
`filter`, `ident` and `working-tree-encoding`, so no parent rule can
change the committed bytes. Files written by older releases still
count as ours on revert and are rewritten by the next vendored run.

Fixes #1541

Assisted-by: Claude Code:claude-opus-5-5
End-to-end check for #1541: with `*.tgz filter=lfs` in the project's
.gitattributes, vendor, commit, clone with GIT_LFS_SKIP_SMUDGE=1 and
run `bun install --frozen-lockfile`. The tarball must not be an LFS
object and the clone must install the patched bytes. Skips when
git-lfs is not installed.

Assisted-by: Claude Code:claude-opus-5-5
Review follow-ups: a Bun workspace mirror's uuid dir only reads the
.gitignore and .gitattributes it may remove, not every sibling file.
Docs note how to fix a tarball an older release already committed as
an LFS pointer (git add --renormalize after the next vendored run).

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 15, 2026 03:11
@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 e87daa4. Configure here.

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

Copy link
Copy Markdown
Collaborator Author

Ready for review — head e87daa4.

  • CI: 36/36 run checks green (50 path-skipped); no main-wide failures.
  • Bugbot: reviewed e87daa4, no findings.
  • Already approved by Tanmay Singla (@Tanmay182003) on this head; no CHANGELOG changes.
  • Reviewer focus: the .gitattributes rule for the vendored npm tarballs (crates/socket-patch-core/src/vendor/npm_dir.rs) and the vlt/bun e2e coverage.

Slack announcement not sent this run (Slack send unavailable); next run will retry.


Generated by Claude Code

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

Development

Successfully merging this pull request may close these issues.

Vendored Bun tarballs go into Git LFS when .gitattributes tracks *.tgz with LFS, so a checkout without LFS fails bun install --frozen-lockfile

3 participants