GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||
GeezerVison is showing github.com — Fix capped scan deferring contested npm pins (#1195) by mikolalysenko · Pull Request #1211 · SocketDev/socket-patch Conversation
|
| Issue | Test | Red on main | Green with fix |
|---|---|---|---|
| #1195 alias shape | scan_rollout_e2e::issue_1195_a_capped_rescan_rewires_an_unpinned_alias_copy |
counts (new 0, deferred 1, upgrade 0, already 0) |
(0,0,0,1), both lock entries pinned |
| #1195 dual-lock shape | scan_rollout_e2e::issue_1195_a_capped_rescan_rewires_an_unpinned_twin_lock |
deferred 1 |
ALREADY, shrinkwrap rewired |
| every drop rule | vex::discover::npm::tests::issue_1195_withheld_refs_stay_recorded_pins (alias, bundled, twin registry, twin missing, pnpm file:) plus new assertions in the Bun #588 and vlt bundled tests |
(new API) | pass |
The red tests were committed alone first (1d1d6a9); the fix is 93e1993.
Run locally:
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-cli --all-features --lib --bins: 897 passedcargo test -p socket-patch-cli --all-features --test scan_rollout_e2e --test hosted_memory_rollout: 17 + 8 passedcargo test -p socket-patch-core --all-features --test hosted_inventory --test upstream_restore_golden: 9 + 50 passedcargo test -p socket-patch-core --all-features --lib: 5847 passed, 4 failed. The 4 are copy_tree::relax_loop_must_not_traverse_symlinked_root, vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry, pypi_poetry::wire_write_failure_maps_error… and pypi_requirements::wire_failure_rolls_back…. All four test read-only-permission failure paths and fail only because the sandbox runs as uid 0. They are in files this PR doesn't touch; CI runs them as non-root.cargo test --workspace couldn't link all ~240 test binaries in the sandbox's disk allowance, so CI covers the rest.🤖 Generated with Claude Code
https://claude.ai/code/session_018DZMq1J4wpPK5Y7gTYsNSM
Note
Medium Risk
Changes how hosted rollout decides NEW vs ALREADY for contested lock wiring; wrong classification could defer fixes or over-apply patches, but scope is discovery/rollout boundaries with strong regression tests.
Overview
Fixes #1195, where a capped hosted scan (--max-new-patches 0) treated an already-pinned package as NEW and deferred it when a second, still-unpatched copy of the same name@version appeared (e.g. an npm: alias or an unpinned twin lock).
Discovery now tracks those refs in a new rewirable bucket (alongside existing shadowed), populated wherever a pin is withheld from attestation but a re-run can rewire the other copy—npm/Bun same-lock contests, twin locks, legacy npm 6 mirror, cross-lock contests, etc. HostedPin::recorded / discover_recorded include rewirable pins; the scan rollout recorded view (update manifest, foreign-origin pin pass, in-memory engine) uses them so capped re-scans classify the patch as ALREADY and rewire the extra copy. Attestation and management commands still use HostedPin::all (attributable pins only).
E2E and unit tests cover alias and dual-lock re-scan behavior plus golden fixture updates for contested npm wiring.
Reviewed by Cursor Bugbot for commit 328fb35. Configure here.
Generated by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
Add end-to-end regressions for #1195: a hosted pin whose lock later gains an unpinned npm: alias copy of the same version, and a pinned package-lock.json beside an unpinned npm-shrinkwrap.json. Under --max-new-patches 0 both re-scans currently defer the already-applied patch as new and leave the second copy unpatched. Assisted-by: Claude Code:claude-opus-5-5
A capped scan (--max-new-patches 0, SOCKET_MAX_NEW_PATCHES=0 or socket.yml maxNewPatches: 0) deferred an already-applied hosted patch as NEW once the project gained a second, unpinned copy of the same version: an npm: alias, an unpinned npm-shrinkwrap.json twin, a bundled copy. Lockfile discovery rightly stops attesting such a pin, but the rollout read "not attestable" as "nothing recorded", so the re-scan that would rewire the copy never ran and the remedy vex prints looped forever (#1195, regression from #1058). Discovery now keeps every ref it drops over an unpatched copy beside it in Discovery::shadowed (npm's pair, same-lock, bundled and legacy mirror rules, Bun and vlt copies, and the shared within-lock and cross-lock contests). HostedPin::recorded adds those to the attributable pins, and the disk and in-memory rollouts build their recorded view from it. Attestation and management commands still use HostedPin::all and are unchanged. Fixes #1195 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem 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.
There was an error while loading. Please reload this page.
main (#1008) added Discovery::shadowed for pins withheld over a copy no rewire can reach, and HostedPin::all now includes them so the management commands unwind them. Keep that as is and record the pins withheld over a copy a re-run CAN rewire (an npm: alias, the npm twin lock, another manager's lock, npm 6's legacy mirror, a Bun registry entry) in a separate Discovery::rewirable, which only the rollout's recorded view (HostedPin::recorded) reads. Assisted-by: Claude Code:claude-opus-5-5
Running cargo fmt during the merge reformatted 16 files main carries unformatted. They are outside this fix, so take main's bytes back and keep the diff to the rollout change. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem 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 328fb35. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Needs a maintainer decision. This PR conflicts with Both this PR (#1195) and #828 (merged to
The text conflicts merge mechanically (one Question: should twin-lock and alias-contested pins (this PR's new shadow sites) count as pins for rollback / remove / takeover and the forward rewrite's confirmation, the way #828 does for bundled and same-lock copies?
I left the branch unmerged so nothing half-resolved lands. Reply with yes or no and the next run will do the merge. Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent] This is already resolved on the current head, 328fb35 (merge d5e0af4 plus a restore commit), using the No option. Please don't re-merge.
If a maintainer would rather have those pins managed like #828's, it's a one-line change in Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…tested-pins # Conflicts: # crates/socket-patch-cli/src/commands/scan/mod.rs # crates/socket-patch-core/src/hosted/memory/mod.rs
|
Merged main ( Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Capped hosted scan (--max-new-patches 0) defers an already-pinned npm patch as NEW when a second lock entry of the same version is unpinned, so the vex remedy loops and that copy stays unpatched (regression from #1058)
There was an error while loading. Please reload this page.