Skip to content

Fix cargo apply skipping other registry copies (#339) - #1394

Merged
Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
agent/fix-cargo-every-registry-copy
Oct 11, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
agent/fix-cargo-every-registry-copy

Conversation

@mikolalysenko

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

Copy link
Copy Markdown
Collaborator

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

Fixes #339

Summary

A shared CARGO_HOME keeps one extracted copy of a crate per registry
index dir: index.crates.io-6f17d22bba15001f (cargo 1.70–1.84),
index.crates.io-1949cf8c6b5b557f (cargo ≥ 1.85), and the pre-1.70 git
index github.com-1ecc6299db9ec823. Each cargo builds from its own copy.
Agent mode now patches, checks, attests and restores every crates.io
copy
, not just the one in the first dir in listing order.

Root cause

The crawler lists every index dir, but the cargo arm of dispatch_find
(crates/socket-patch-cli/src/ecosystem_dispatch.rs) merged them with
merge_first_wins. So apply, apply --check, vex and rollback
(and the scan --prune keep check, through find_cargo_copies) only
saw one copy. A project built by the other cargo kept compiling the
unpatched crate while apply reported success and VEX attested
not_affected.

Fix

  • New merge_cargo_copies for the cargo arm. It keeps every copy that
    sits in a crates.io index dir (push_path dedup, discovery order).
    The apply loop, rollback and vex already act on every path in the list.
  • A pkg:cargo PURL names a crates.io crate, so a copy with the same
    name@version in another registry's dir (a private registry, or the
    hosted patch.socket.dev-* registry) is a different crate. It is never
    patched beside crates.io copies, whatever the listing order. When no
    crates.io copy exists, it stays the single first-found copy, as before.
    This came from /code-review high.
  • A cargo vendor tree or --global-prefix is one root, so it still
    gives one copy.
  • docs/ecosystems.md ("Cargo: shared registry cache") documents the
    every-copy behavior. Dispatch doc comments that still described cargo
    as first-wins are updated.

Test evidence

  • e2e_cargo::agent_mode_covers_every_registry_index_copy (new) builds
    a hermetic CARGO_HOME with two crates.io index dirs plus a private
    registry dir, all holding cfg-if-1.0.0. It checks:
    • apply patches both crates.io copies and leaves the private one alone.
    • apply --check passes and vex attests not_affected (baseline).
    • After one copy is restored to pristine bytes, apply --check fails
      and vex doesn't attest.
    • Re-apply patches both copies, and rollback restores both and still
      leaves the private crate alone.
  • Red → green: with the cargo arm switched back to merge_first_wins,
    the test fails with apply left …/index.crates.io-6f17d22bba15001f/cfg-if-1.0.0 unpatched.
    With the fix it passes. All 24 tests in e2e_cargo pass.
  • Unit tests merge_cargo_copies_keeps_every_registry_index_copy and
    merge_cargo_copies_prefers_crates_io_over_another_registry pass.
  • cargo fmt --all -- --check and
    cargo clippy --workspace --all-features -- -D warnings are clean.
  • cargo test --workspace --all-features --no-fail-fast: every suite
    passes except 16 tests, and none of them touch cargo or dispatch.
    • 15 are write-failure tests (read-only dirs) that can't fail when run
      as root in the agent sandbox. 4 of them are in socket-patch-core,
      which this PR doesn't change.
    • 1 (e2e_bun_lockb) needs patches-api.socket.dev, which the sandbox
      egress proxy blocks.
    • CI is the authority for these.
  • Wrappers (npm/, pypi/, gem/) only dispatch to the binary, so
    they need no change.

Per-issue checklist

Review notes (/code-review high findings not changed)

  • CargoCrawler::crawl_all still dedupes by PURL across roots. That
    crawl is the package inventory sent to the patch API (one entry per
    crate), not the copy list. Every command that writes or verifies bytes
    resolves copies through dispatch_find.
  • A leftover pre-1.70 git-index copy that is missing a file the patch
    touches now fails apply instead of being ignored when it sorted
    second. That copy is still one an old cargo builds from, so failing
    loudly is the safe choice. Deleting the stale dir clears it.

🤖 Generated with Claude Code

https://claude.ai/code/session_018K8nQgVxQZtm4DDeDVhfUo


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
A shared CARGO_HOME keeps one extracted copy of a crate per registry
index dir: cargo 1.70-1.84 and cargo 1.85+ each unpack and build their
own. Agent mode only patched, checked and restored the copy in the
first dir, so a project built by the other cargo kept compiling the
unpatched crate while apply reported success and vex attested
not_affected.

Carry every copy the crawler finds, so apply patches them all,
apply --check and vex fail on an unpatched one, and rollback restores
each one.

Fixes #339

Assisted-by: Claude Code:claude-opus-5-5
A pkg:cargo PURL names a crates.io crate, but a private registry or
the hosted Socket registry can unpack a different crate with the same
name and version into its own registry/src dir. Patch every crates.io
copy only, and fall back to the single first-found copy as before when
no crates.io copy exists.

The regression test now also shows apply --check passing and vex
attesting once every copy is patched, so its failure checks can't pass
for an unrelated reason.

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

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

Copy link
Copy Markdown
Collaborator Author

Ready for review at 73f4a18.

  • CI: all checks green on the head (35 success, 1 neutral, rest skipped); no main-wide failures.
  • Bugbot: reviewed 73f4a18, no findings.
  • Mergeable with main (41659c1), no CHANGELOG.md change.

Worth a look: the cargo arm of dispatch_find now keeps every registry copy of a crate@version instead of first-wins, so apply/check/rollback touch each extracted copy.


Generated by Claude Code

Merged via the queue into main with commit ea4cff5 Oct 11, 2026
84 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-cargo-every-registry-copy branch October 11, 2026 19:56
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

3 participants