Problem
Every real production gem / pypi / maven patch PURL is qualified —
pkg:gem/[email protected]?platform=ruby,
pkg:pypi/[email protected]?artifact_id=py2-py3-none-any-whl — but the
crawler only ever knows the base PURL.
vendor_records resolved installed packages with
find_packages_for_purls (crates/socket-patch-cli/src/commands/vendor.rs:684),
whose unified purl -> path map is keyed by the base PURL for
release-variant ecosystems (it uses merge_first_wins). The subsequent
all_packages.contains_key(purl) "is it installed?" check
(vendor.rs:706) is done against the qualified manifest PURLs, so it
missed every installed qualified-PURL package and falsely classified it
"not installed". That triggered the auto-fetch fallback:
- a spurious
vendor_fetched_missing warning ("…is not installed;
fetched the pristine artifact from <registry>…") plus a redundant
registry download on every run, and
- for gem, staging the fetched artifact into a tempdir literally named
gem, which can never equal activestorage-7.0.2.2 — a
HashMap-iteration-order-dependent platform_gem_unsupported
coin-flip.
The repo already documents the correct invariant on
find_manifest_package_paths (ecosystem_dispatch.rs:406-417):
qualified-PURL lookups must use find_packages_for_rollback, not
find_packages_for_purls.
Fix
Resolve installed packages in vendor_records with
find_packages_for_rollback (crates/socket-patch-cli/src/commands/vendor.rs:684,
import at :43). Its merge_qualified merge fans each base install path
back out to every qualified manifest PURL, so all_packages is keyed by
the qualified PURLs the contains_key check uses — the installed package
is now found, no false "not installed", no redundant fetch, no gem
coin-flip. The downstream match loop (vendor.rs:860) already strips to
the base PURL and dedups on it, so it is unaffected.
The diff is scoped to the lookup; vendor event-count semantics are
untouched (owned by another change).
Test
ecosystem_dispatch::tests::find_packages_for_rollback_resolves_installed_qualified_gem
(crates/socket-patch-cli/src/ecosystem_dispatch.rs) — hermetic, no
network. Lays down a real installed gem fixture
(activestorage-7.0.2.2/lib) and a qualified manifest PURL
(?platform=ruby), then asserts:
find_packages_for_rollback resolves it under its exact qualified
key (the vendor lookup path now finds the installed gem), and
find_packages_for_purls does not contain the qualified key —
demonstrating the exact base-keyed miss that produced the false "not
installed".
The bug's runtime damage (redundant fetch + vendor_fetched_missing +
gem coin-flip) only manifests online, and --offline masks it
because the downstream loop recovers via the base key — so the resolver's
contains_key semantics is the correct hermetic surface to guard, and is
exactly what vendor's missing computation depends on.
cargo build -p socket-patch-cli clean; the full ecosystem_dispatch::
(34) and commands::vendor:: (9) lib test modules pass.
Scope
Only vendor's installed-package lookup. apply.rs:1027 and
repair_vendor.rs:491 also call find_packages_for_purls with qualified
manifest PURLs and may have a related latent issue, but they are out of
scope for this bug and left untouched.
🤖 Generated with Claude Code
Note
Medium Risk
Changes vendor’s installed-package detection for release-variant ecosystems; behavior fix aligns with existing rollback/manifest resolution but alters fetch warnings and gem vendoring when qualified PURLs are used.
Overview
Vendor now resolves on-disk packages with find_packages_for_rollback instead of find_packages_for_purls, matching find_manifest_package_paths.
Manifest keys for gem, PyPI, and Maven use qualified PURLs (?platform=, ?artifact_id=, etc.), while crawlers return base PURLs. The old map was keyed by base only, so all_packages.contains_key(qualified) failed for installed packages. That wrongly triggered auto-fetch (vendor_fetched_missing), redundant registry downloads, and gem platform nondeterminism.
A hermetic test in ecosystem_dispatch asserts rollback resolves a qualified gem under its exact key and that find_packages_for_purls does not.
Reviewed by Cursor Bugbot for commit 6bfe328. Configure here.