Fix human scan skipping re-apply of recorded patches (#732) - #733
Mikola Lysenko (mikolalysenko) wants to merge 5 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
After a reinstall put pristine bytes back, `scan --mode agent` or `scan --sync` without `--json` printed "[skip] ... (already recorded)" and exited 0 while leaving the package unpatched. Only the `--json` path re-applied (#454). The human path now hands recorded selections to the same download step, whose nested apply re-applies them; they are listed as `[re-apply]`. `--dry-run` and report-only scans still change nothing and say what a wet run would do. Fixes #732 Assisted-by: Claude Code:claude-opus-5-5
Clippy's nonminimal_bool lint rejected the negated condition. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
|
[agent] CI status on 77ce09e, with two failures that don't come from this diff:
No fix to port: neither failure comes from this diff. Generated by Claude Code |
`scan --prune --dry-run` with every selection already recorded said a run without --dry-run would re-apply them, but a report-only scan never applies, so following that advice changed nothing. It now points at `socket-patch apply` again; only an agent-mode dry run promises the re-apply. Refs #732 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EPsXDSe1x9i96swon5nxdE
|
bugbot run Generated by Claude Code |
The fix commit ran cargo fmt over the whole workspace, reformatting 127 files the change does not touch. That noise hides the real diff from reviewers and conflicts with every other open PR editing those files. Restore them to main; the fix itself (scan/mod.rs, render.rs and its tests) is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
|
bugbot run 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 e0cc8eb. Configure here.
|
[agent] On e0cc8eb, PDM patch compatibility /
This is the third different PDM cell to fail on this PR ( Generated by Claude Code |
|
[agent] Ready for review at
Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #732
Summary
A human-output (no
--json)socket-patch scan --mode agentorscan --syncnow re-applies a patch already recorded in.socket/manifest.jsonafter a reinstall put the pristine bytes back. It no longer prints[skip] … (already recorded), exits 0 and leaves the package vulnerable. The--jsonpath has re-applied since #456; the two output formats now write the same thing.Root cause
#456 fixed #454 in the shared fetch loop (
get.rs:to_apply = downloaded + batch.already_recorded). But the human scan path (scan/mod.rs) partitioned manifest-recorded selections out ofselectedbefore that loop, and returnedfinish_human(0)when nothing new remained. So the recorded selections never reached the nested apply. When a run also had a new patch, only the new one was applied.Change
scan/mod.rs: on a wet agent run, the recorded selections are passed todownload_and_apply_patches_withtogether with the new ones. The fetch loop skips their records (already in manifest) and counts them inalready_recorded, and the nested apply re-applies them. That apply is idempotent, so an in-sync re-run changes nothing on disk. They are listed as[re-apply] <purl> (already recorded: <uuid>). The early "nothing selected" return now only fires when there is nothing to re-apply, and the "Patches to apply:" header is printed only when there are new patches.--dry-runand report-only scans still change nothing and keep the[skip]line. A dry run now says "a run without --dry-run re-applies them" instead of pointing atsocket-patch apply.render.rs:already_recorded_linetakes areapplyflag; adds anALL_ALREADY_RECORDED_DRY_RUNmessage.npm/,pypi/,gem/) only dispatch to the binary, so no parallel change is needed.Tests (red → green)
crates/socket-patch-cli/tests/covgap_commands_scan_mod.rs:scan_human_reapplies_an_already_recorded_patch_after_reinstall: the Human-output scan --mode agent / --sync still never re-applies an already-recorded patch after a reinstall (#454 fixed only the --json path) #732 repro for both--mode agentand--sync. Scan patches the package, the bytes are restored to pristine, and the re-run must re-patch.scan_human_reapplies_recorded_patch_alongside_a_new_one: the mixed case from the issue. A recorded-but-reverted patch plus a newly published one; both must land.scan_human_dry_run_previews_reapply_of_a_recorded_patch: dry-run downloads nothing and leaves the file and manifest bytes unchanged, with the corrected message.scan_human_does_not_offer_an_already_recorded_patch, which pinned the buggy behaviour. Its premise ("would only be downloaded to be skipped") stopped being true once Fix agent scan/get skipping apply for recorded patches (#454) #456 landed.render.rsunit test covers both[skip]and[re-apply]lines.All three new tests failed on
main045d7ec: the file was stillbefore\nafter the re-run, and the dry-run printed the old "runsocket-patch apply" message. They pass with the fix.scan --mode agentafter reinstallscan_human_reapplies_an_already_recorded_patch_after_reinstall(agent arm)scan --syncafter reinstall--syncarm)scan_human_reapplies_recorded_patch_alongside_a_new_oneLocal verification
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test --workspace --all-features --no-fail-fast: 219 suites, 9726 passed. The 12 failures are all chmod/unwritable-path failure-injection tests (vendor state write, redirect write failure, repair lock, core copy_tree/vlt_heal/poetry/requirements wire failures) that can't fail a write when run as root in this sandbox. Re-running each one as an unprivileged user (setpriv --reuid=65534) passes. None of them touch the scan code changed here.e2e_scan -- --ignoredneeds the live patch API, which is blocked from this sandbox; CI runs it.🤖 Generated with Claude Code
Note
Medium Risk
Changes when scan mutates
node_modulesafter reinstall by routing recorded patches through download/apply; behavior is scoped to agent/sync human paths and is covered by new integration tests.Overview
Fixes #732: human
scan --mode agent/scan --syncno longer stops at[skip] … (already recorded)and leaves packages vulnerable after a reinstall restores pristine files. Wet agent runs now pass manifest-recorded selections intodownload_and_apply_patches_withtogether with new picks (matching the--jsonpath since #454), so the nested apply re-applies them idempotently.Human output distinguishes
[re-apply]on wet runs vs[skip]on previews; dry-run messaging says a run without--dry-runre-applies, while report-only--prune --dry-runstill points atsocket-patch apply. Early exit and the "Patches to apply:" header only apply when there is nothing new and nothing to re-apply.Tests replace the old "do not offer already recorded" expectation with reinstall, mixed new+recorded, dry-run, and report-only cases;
render.rscovers both tag variants.Reviewed by Cursor Bugbot for commit e0cc8eb. Configure here.
Generated by Claude Code