GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix hosted cargo contested lock in vex and restore (#679, #863) by mikolalysenko · Pull Request #1313 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 9, 2026 •
edited by cursor Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

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

Fixes #679
Fixes #863

Summary

After scan --mode hosted pins a crate such as cfg-if 1.0.4, a dependency added later (cargo add, a merge or a path member) can lock its own crates.io copy of the same name@version. Cargo never unifies packages from different sources, so Cargo.lock holds two cfg-if 1.0.4 blocks and the build compiles the unpatched one for that dependent.

  • Hosted cargo vex attests not_affected while Cargo.lock also builds an unpatched crates.io copy of the same crate@version #679 (vex): vex/discover/cargo.rs now records each non-Socket block (crates.io, git) of a hosted crate's name@version as a same-lock unpatched_copy. The shared contest_within_locks rule then withholds the hosted ref from attestation, with a patched_ref_unattributable diagnostic naming the crates.io entry. Before, it was attested not_affected. The ref is kept as shadowed, so rollback / remove / list / the takeover still unwind it (npm hosted pin next to a bundled copy can't be unwound: rollback/remove refuse it, and the vendored takeover skips the restore, so vendor --revert lands back on hosted and allow-remote=all stays #828 semantics). It is not rewirable, because a re-scan can't rewire a transitive crates.io dependent (redirect_cargo_transitive_dependents).
  • Hosted cargo remove writes a duplicate cfg-if block into Cargo.lock when crates.io also locks the same crate@version, so cargo can no longer parse the lock while remove reports success #863 (remove / rollback): patch/redirect/upstream/cargo.rs merges the Socket block into an existing crates.io block for the same name@version. Before, it spliced crates.io's source into the Socket block and left two identical blocks, which cargo refuses to parse. Now it drops the Socket block (and a v1 lock's [metadata] line) and respells dependents' references the way cargo writes them: the bare name when the crate is unique, "name version" when only the version is, and the full id in v1. The twin already carries the checksum, so this path needs no index lookup and works offline.

Root cause

Neither the cargo VEX extractor nor the cargo upstream restore handled a lock in which the hosted pin and a crates.io copy share one name@version.

Tests (red → green)

Issue Test Red before fix
#679 socket-patch-core vex::discover::cargo::tests::crates_io_twin_of_the_hosted_crate_withholds_the_ref (crates.io and git twins; another version doesn't count) FAILED with the new call disabled
#863 patch::redirect::upstream::cargo::tests::restore_merges_into_an_existing_crates_io_twin, restore_merge_keeps_versioned_refs_while_the_name_is_ambiguous, restore_merge_in_a_v1_lock all 3 FAILED (restore refused / duplicate)
both, real cargo e2e_redirect_cargo_shapes::cargo_hosted_contested_by_a_later_crates_io_copy: hosted scan → fresh checkout adds crc32fast = "=1.5.0" → contested lock (2 blocks); vex doesn't attest cfg-if; remove exits 0 leaving one crates.io block; cargo build --locked --offline succeeds new

CLI_CONTRACT.md: the cargo discovery row and the cargo bullet in "Hosted unwind coverage" are updated.

Commands run

  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo test -p socket-patch-core --lib: 6113 passed
  • cargo test -p socket-patch-cli --test e2e_redirect_cargo_shapes: 28 passed (cargo 1.93.1)
  • cargo test -p socket-patch-cli --test mode_migration_cargo: 28 passed
  • e2e_vendor_cargo_build: the 2 old-toolchain legs (*_old_toolchains, *_below_1_45) fail locally. They exercise vendored wiring under old rustup toolchains, which this diff doesn't touch, so I'm leaving them to CI.
  • rustfmt on the changed files

🤖 Generated with Claude Code


Note

Medium Risk
Changes hosted Cargo lockfile restore and VEX attestation for duplicate name@version blocks; incorrect merge or reference respelling could break cargo build --locked or mis-attest patches.

Overview
Fixes hosted Cargo when Cargo.lock holds both a Socket sparse-index block and a separate crates.io (or git) block for the same name@version—typically after a dependency is added post-scan (#679, #863).

VEX / discovery adds unpatched_twins: any non-Socket twin of a hosted crate is recorded via unpatched_copy, so attestation is withheld (patched_ref_unattributable, “UNPATCHED”) while the pin stays shadowed so rollback / remove / list still unwind it. Upstream restore no longer rewrites the Socket block to crates.io (which duplicated blocks and broke cargo parsing); it drops the Socket [[package]] (and v1 [metadata] checksum lines), skips index lookup when the twin already has the checksum, and respells dependent references with merged_references to match what Cargo would write.

CLI_CONTRACT.md documents the contested-lock behavior for discovery and hosted unwind. Tests cover unit restore/merge paths, discovery withholding, and a new e2e shape cargo_hosted_contested_by_a_later_crates_io_copy.

Reviewed by Cursor Bugbot for commit 659fcbc. Configure here.


Generated by Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Mikola Lysenko (mikolalysenko) and others added 2 commits October 9, 2026 12:42
@mikolalysenko @claude
WIP: Fix hosted cargo contested lock in vex and restore (#679, #863)
d0d8f6a
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko @claude
Fix cargo locks that also hold a crates.io twin
b532b71
After a hosted cargo scan pins cfg-if 1.0.4, a dependency added later
can lock its own crates.io cfg-if 1.0.4 beside the Socket one. Cargo
cannot unify the two sources, so the build compiles the unpatched copy
too.

- vex: the hosted ref is withheld (patched_ref_unattributable, naming
  the crates.io entry) instead of attested not_affected. It stays a
  shadowed ref, so rollback, remove and list still unwind it (#679).
- remove / rollback: the upstream restore merges the Socket block into
  the existing crates.io block. It drops the block (and a v1 lock's
  [metadata] line) and respells dependents' references the way cargo
  writes them. Before, it left two identical blocks that cargo refused
  to parse while the command reported success (#863). No index lookup
  is needed, so this also works offline.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 9, 2026 17:37
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) enabled auto-merge October 9, 2026 17:37
cursor[bot]
cursor Bot reviewed Oct 9, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

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.

All reactions
Tanmay182003
Tanmay Singla (Tanmay182003) approved these changes Oct 9, 2026
View reviewed changes
@mikolalysenko
Merge branch 'main' into agent/v5-cargo-contested-lock
659fcbc
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 9, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 659fcbc. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mikolalysenko
Mikola Lysenko (mikolalysenko) disabled auto-merge October 9, 2026 19:55
@mikolalysenko
Merge branch 'main' into agent/v5-cargo-contested-lock
d0d2ec2
@mikolalysenko
Mikola Lysenko (mikolalysenko) enabled auto-merge October 9, 2026 21:31
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 9, 2026
cursor[bot]
cursor Bot reviewed Oct 9, 2026
View reviewed changes
Comment thread crates/socket-patch-core/src/patch/redirect/upstream/cargo.rs
// crates.io's source into the Socket block would leave two
// identical blocks, which cargo refuses to parse (#863). The twin
// already carries the checksum, so no registry lookup is needed.
let twin_of = |h: &LockHit| {

@cursor cursor Bot Oct 9, 2026

Copy link
Copy Markdown

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.

🔒 Agentic Security Review

Severity: MEDIUM

Description: Hosted Cargo restore treats a contested crates.io twin as already bound and skips the sparse-index checksum rebind. twin_of matches only name, version, and source registry+https://github.com/rust-lang/crates.io-index, then those hits are filtered out of UpstreamClient::cargo_cksum (the lookup that refuses offline and returns the public index cksum). Restore deletes the Socket [[package]] block and its v1 [metadata] checksum line, respells dependents onto the surviving twin, and marks the uuid handled, so the Cargo.toml registry pin and unused [registries.socket-patch-<uuid>] block are removed. The twin checksum bytes are never read or compared. A later cargo fetch from the canonical index still fails closed when that checksum differs from the index cksum, before crate code runs. A [source.crates-io] replace-with registry or vendor directory does not consult that index: cargo accepts the .crate when its sha256 equals the lock checksum. This merge moves former Socket-sourced dependents, which were outside crates.io replacement, onto that checksum.

Impact: Rollback, remove, and vendored takeover all run this restore. A lockfile author can leave a non-index sha256 on the crates.io twin; restore now succeeds offline and publishes that sha256 as the only pin. Builds that use the real crates.io index error on the mismatch. Builds whose crates.io source is replaced or vendored, including a replacement committed next to the lockfile, run the bytes that hash to the preserved checksum (crate code and build scripts). Re-resolving cargo_cksum would have written the public-index checksum and made those divergent bytes fail closed. An honest twin produced by cargo against the real index is unchanged, because that checksum is already the index cksum.

Remediation: Still call cargo_cksum for a contested twin and refuse that pin when the lookup fails or the twin's inline or v1 metadata checksum is not exactly the sparse-index cksum, including under --offline. Only after that match, delete the Socket block, keep the twin, and mark the uuid handled.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Merged via the queue into main with commit ecd67b4 Oct 9, 2026
53 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/v5-cargo-contested-lock branch October 9, 2026 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments
@Tanmay182003 Tanmay Singla (Tanmay182003) Tanmay182003 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Hosted cargo remove writes a duplicate cfg-if block into Cargo.lock when crates.io also locks the same crate@version, so cargo can no longer parse the lock while remove reports success Hosted cargo vex attests not_affected while Cargo.lock also builds an unpatched crates.io copy of the same crate@version

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@mikolalysenko @Tanmay182003
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.