Repository navigation
Fix bare scan/get converting hosted pins (#1437) - #1440
Mikola Lysenko (mikolalysenko) merged 4 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
A bare `scan` or `get` (no --mode) picks its mode from the project's state, but only the vendor ledger and the manifest counted. Hosted mode keeps no ledger, so a project holding vendored packages beside hosted pins was classed as vendored, and the run silently took every hosted pin over to vendored: exit 0, no warning. That undid a partial `--mode hosted` takeover and per-package `get --mode` choices. When the vendor ledger is non-empty, the mode decision now also reads the lockfiles' hosted pins. Vendored + hosted state is a usage error (exit 2, `mode_ambiguous`) that names the pinned packages and asks for --mode, the same as agent + vendored state already is. Nothing is written. Projects with only one kind of state are unaffected, and hosted-only projects do not pay for the extra lockfile walk. Fixes #1437 Assisted-by: Claude Code:claude-opus-5-5
A cargo or nuget package pinned to Socket's patch registry with no lockfile entry yet is still hosted, but the bare-run mode check only looked at lockfile pins. A vendored project beside such a pin could still be silently converted. Count those pins too, and tighten the end-to-end test so an explicit --mode must succeed, not just avoid exit 2. Refs #1437 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
On a Gemfile.lock with no CHECKSUMS section, hosted mode pins a gem in the Gemfile only and leaves the lock for the next bundle install. That pin has no lockfile entry yet, so the bare-run mode check missed it, and a vendored project beside it could still be converted. Read those Gemfile pins too. Refs #1437 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ 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 0a72a49. Configure here.
|
Ready for review (burn-down agent)
Generated by Claude Code |
Final review briefWhat it does. A bare Risk: low–medium. The change is one match arm in Look here
Verified
Changes I made. None. Open questions (not blocking)
Auto-merge (squash) is armed, so approving sends this straight to the merge queue. Generated by Claude Code |
* ci(release): publish npm from release.yml, not publish-npm.yml Every socket-patch npm package's trusted publisher is registered against release.yml, and npm allows only one publisher per package. The 5.0.0 release dispatched publish-npm.yml, whose OIDC token named that file, so npm rejected it with E401 before staging anything. Move the npm leg back inline as release.yml's npm-publish job (same steps as publish-npm.yml) and delete publish-npm.yml, so the existing registration keeps working. Add an `npm-retry-version` input that skips the version gate, build, tag, GitHub release and crates.io jobs and re-stages npm from an existing release's assets; this retries 5.0.0 now and replaces the manual Publish npm dispatch. crates.io stays dispatched through publish-cargo.yml, since crates.io allows several publishers per crate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): fold 22 more PRs into the 5.0.0 notes Cover the PRs merged to main after #1432's base (1779317..4cb3643): Cargo source replacement and registry = "crates-io" (#338/#455, #386), pnpm lockfile=false (#1074), berry removed descriptors (#1435), yarnrc ${VAR} reads (#1100), CRLF .npmrc append (#1196), Composer vendor-dir cascade and global home (#439/#686, #586), Go +incompatible vex (#484), gem moved BUNDLE_GEMFILE and commented Gemfile revert (#952, #988), Poetry source = "pypi" (#1282) and Hatch path characters (#547). No entries for #1411 (macOS fix to code #1393 added in this release; the #1393 entry already describes the intended behavior), #1426 (perf regression introduced and fixed within 5.0.0) or the CI/test/bench PRs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): cover #1419, #1434, #1440, #1442, #1444 in the 5.0.0 notes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): 5.0.1 Cut [Unreleased] into [5.0.1] — 2026-10-13 and stamp 5.0.1 with scripts/version-sync.sh. The 5.0.1 notes cover main through 501c6d9 (#1449), i.e. every PR after the v5.0.0 tag (6ad6add): the npm publish fix (5.0.0 never reached npm or crates.io, 5.0.1 is the first v5 there), #1465, #759, #1460, #1462, #1445, #869, #1447, #1450, #1467, and #1449 under Maintenance. CI/test-only PRs (#1448, #1452, #1454, #1457, #1459) have no entries. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(release): 5.0.1 notes for PRs merged since the cut Covers #1469, #1470, #1474, #1475, #1478, #1479, #1480 and #1482; #1484 is CI-only. The notes now cover main through 285a5e8. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1437
Summary
A bare
scanorget(no--mode) on a project that holds vendored packages and hosted pins now stops with exit 2 (mode_ambiguous). The error names the hosted-pinned packages and asks for--mode, and nothing is written. Before this change the run kept vendored mode and silently took every hosted pin over to vendored (exit 0, no warning). That undid a partial--mode hostedtakeover (#1039) and per-packageget --modechoices.Root cause
mode_from_project_state(crates/socket-patch-cli/src/commands/mod.rs) picked the mode from the vendor ledger and the manifest only. Hosted mode keeps no ledger, so its pins never counted. The(vendored, !agent)arm returnedVendoredeven with hosted pins present, and the vendored flow then took over every pin it found.Fix
HostedPin::recorded, plus lockless cargo/nuget pins (Discovery::unlocked_pins) and Gemfile-only gem pins (gem_manifest_source_pins, Capped hosted gem re-scan counts a Gemfile-only (no-CHECKSUMS) pin as NEW, so--max-new-patches Nspends its budget on gems it already wired and starves the next one forever (regression from #1058) #1224; raised by Bugbot). Any hosted state beside a ledger ismode_ambiguous, the same as agent + vendored state already is.npm/,pypi/,gem/) only dispatch to the binary, so they need no change.Design choice: refuse rather than keep per-package modes
The issue offers two fixes: keep each package in its current mode, or refuse as ambiguous. This PR refuses, for three reasons:
--mode./code-review highraised the alternative. Its other findings that I left as they are:get <pkg>is refused even when<pkg>isn't hosted-pinned. Agent + vendored state already behaves the same way. Fixing it would mean resolving the package before the mode is chosen. The user can pass--mode.--cwdis refused before each directory's mode is worked out. That's existing behavior for agent + vendored too. The cwd mode also decides whether PATHs are project dirs or agent globs, so the pre-check can't simply be skipped.scan/mod.rs. It's a small test-only helper in a different module.Test evidence
Red on
main(before the fix commit), green with it:cargo test -p socket-patch-cli --all-features --lib -- commands::tests:hosted_pins_beside_a_ledger_are_ambiguousanda_hosted_pin_over_a_ledger_entry_is_ambiguousFAILED before the fix (returnedOk(Vendored)), and all 9 pass after.a_lockless_hosted_pin_beside_a_ledger_is_ambiguouscovers the nuget lockless pin.a_gemfile_only_hosted_pin_beside_a_ledger_is_ambiguouscovers the Gemfile-only gem pin: it fails with the Gemfile read commented out and passes with it.cargo test -p socket-patch-cli --all-features --test scan_get_mode_from_project_state:bare_scan_and_get_refuse_a_project_with_vendored_and_hosted_stateFAILED before the fix (left: 0, right: 2: the bare scan exited 0) and passes after. It checks barescanand bareget: exit 2,mode_ambiguous, lock, ledger, manifest and.npmrcbyte-identical, hosted pin kept. It also checks that an explicit--mode vendoredstill succeeds.Local runs:
cargo fmt --all -- --check: OKcargo clippy --workspace --all-features -- -D warnings: OKcargo test -p socket-patch-cli --all-features --libplusin_process_get_modes,in_process_vendor_{bun,npm_v1,pnpm,pypi}_takeover,mode_migration_{bun,cargo,npm,pypi,vlt}andscan_get_mode_from_project_state: 1,199 passed, 0 failed. The fullcargo test --workspacerun hit the container's disk limit while building every test binary, so CI covers the rest.Per-issue checklist
scanon vendored + hosted:bare_scan_and_get_refuse_a_project_with_vendored_and_hosted_state(scan leg) andhosted_pins_beside_a_ledger_are_ambiguousgeton vendored + hosted: the same e2e test (get leg)a_hosted_pin_over_a_ledger_entry_is_ambiguous🤖 Generated with Claude Code
https://claude.ai/code/session_01Pg9M6ADMS1SLLmpFkvmA5r
Generated by Claude Code