Fix agent scan/get skipping apply for recorded patches (#454) - #456
Open
Mikola Lysenko (mikolalysenko) wants to merge 7 commits into
Open
Mikola Lysenko (mikolalysenko) wants to merge 7 commits into
Mikola Lysenko (mikolalysenko) wants to merge 7 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
A re-run of scan --mode agent, scan --sync, get <uuid> or get <purl> after the package was reinstalled left it unpatched while exiting 0. These tests reinstall the pristine file between runs and expect the recorded patch to be applied again (#454). Assisted-by: Claude Code:claude-opus-5-5
scan --mode agent, scan --sync and agent-mode get only ran the nested apply when they downloaded a new or updated record. When the patch was already in .socket/manifest.json, the installed copy was never checked, so after a reinstall (a fresh Hatch env, a CI cache miss, a failed first apply) the run exited 0 with the package unpatched. Run the nested apply for every selected patch that is recorded, already-recorded ones included, unless --save-only. Apply is a no-op on already-patched files, and a failing apply now fails the run. Fixes #454 Assisted-by: Claude Code:claude-opus-5-5
CodeQL traced the --save-only flag from GetArgs, which also carries the API token, into the stderr save summary. Decide the "nothing to update" suffix from whether an apply follows instead, which is the same condition without passing argument data into the log line. Assisted-by: Claude Code:claude-opus-5-5
scan_apply_with_existing_blob_uses_local_cache pinned the #454 bug: a patch already recorded at the same uuid, over a pristine install, was left unapplied. The record is still skipped (no download, manifest untouched), but the cached blob is now applied to the install. Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 1, 2026 10:51
Collaborator
Author
|
BugBot review Generated by Claude Code |
CodeQL's name heuristics treat "uuid" as sensitive, so the new test helper get_uuid_args() showed up as a fresh taint source for existing stderr lines in get and scan. Rename the helpers; behavior unchanged. Assisted-by: Claude Code:claude-opus-5-5
Collaborator
Author
|
BugBot review Generated by Claude Code |
A workspace-wide cargo fmt run reformatted 125 files this fix does not touch (main is not rustfmt-clean and CI does not gate on it). Restore them to main so the PR only carries the fix and its tests. Assisted-by: Claude Code:claude-opus-5-5
Collaborator
Author
|
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 35ee888. Configure here.
Collaborator
Author
|
[burn-down agent] Ready for review on
Generated by Claude Code |
Wenxin Jiang (Wenxin-Jiang)
approved these changes
Oct 1, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
LLM Description written by Claude Code:claude-opus-5-5
Fixes #454
Summary
scan --mode agent,scan --sync, and agent-modegetnow re-apply a patch that is already recorded in.socket/manifest.json. Before this change, a re-run after a reinstall (a fresh Hatch env,pip install --force-reinstall, a CI cache miss, a failed first apply, a--global-prefixreinstall) exited 0 with the package unpatched.Root cause
Both agent-mode engines in
crates/socket-patch-cli/src/commands/get.rsgated the nestedapplyon a manifest change:download_and_apply_patches_with(get <purl|CVE|GHSA>,scan --mode agent,scan --sync,-g/--global-prefix):apply_lockandapply_failedboth requireddownloaded > 0.save_and_apply_patch(get <uuid>): the same gate, onchanged.A patch already recorded at the same uuid comes back
skipped, so the installed tree was never checked.Fix
The diff is 3 files:
get.rs, one updated test, one new test file.FetchBatch.already_recordedcounts the manifest-storeskippedpatches whose same uuid is already recorded.download_and_apply_patches_withruns the nested apply whendownloaded + already_recorded > 0(and not--save-only).apply_failedandapplieduse the same count, soappliednow means "selected recorded patches confirmed applied after this run". The manifest is still written only when a record changed, and apply is a no-op on already-patched files, so an in-sync re-run changes nothing on disk.save_and_apply_patchapplies unless--save-only. The "nothing to update." suffix now prints only when no apply follows, decided byapply_lock.is_none().--save-onlykeeps its record-only intent.No wrapper (
npm/,pypi/,gem/) changes are needed. They dispatch to the binary.Test evidence
New
crates/socket-patch-cli/tests/in_process_agent_reapply.rs(hermetic npm fixture, wiremock API). Each test records and applies once, reinstalls the pristine file, then re-runs. The "without fix" column comes from the same tests run againstget.rswith the fix stashed:agent_scan_reapplies_already_recorded_patch_after_reinstallscan_sync_reapplies_already_recorded_patch_after_reinstallget_uuid_agent_reapplies_already_recorded_patch_after_reinstallget_purl_agent_reapplies_already_recorded_patch_after_reinstallagent_scan_rerun_fails_when_recorded_patch_cannot_be_applied(--strict, expects exit 1)agent_scan_in_sync_rerun_is_a_clean_noop(control: manifest bytes unchanged)get_save_only_of_recorded_patch_still_does_not_apply(control)One existing test pinned the bug and is updated.
scan/scan_sync_e2e.rs::scan_apply_with_existing_blob_uses_local_cachepre-staged a same-uuid record over a pristine install and asserted the file stays unpatched withapplied: 0. It now asserts the record is stillskipped, there's no download, and the manifest is untouched, while the cached blob gets applied (applied: 1, file holds the patched bytes).Local checks:
cargo clippy --workspace --all-features -- -D warnings: clean.rustfmt --checkon the new test file: clean.mainisn't rustfmt-clean and CI doesn't gate on fmt. A workspace-wide reformat that slipped into 175f3a4 was reverted in the head commit, so only the touched code changes.cargo test -p socket-patch-cli --all-features --lib --binsplus 20 get/scan/apply integration binaries passed 1293, failed 0.scan,get,in_process_get,in_process_scan,covgap_commands_get,in_process_agent_reapplypassed 1133, failed 0.cargo test --workspace --all-featurescouldn't finish locally because the sandbox ran out of disk while linking about 200 test binaries. Before that, the only failures were 3covgap_commands_vendorread-only-dir tests that need a non-root user (the sandbox runs as uid 0), in vendor code this PR doesn't touch.get_uuid_argsmade existing stderr lines look like new cleartext-logging findings.CI on head 35ee888: all 391 non-skipped checks pass (6 skipped), including coverage, the full e2e matrix, and CodeQL ("No new alerts in code changed by this pull request"). Bugbot found no issues.
Per-issue checklist
scan --mode agentre-applies after reinstall:agent_scan_reapplies_already_recorded_patch_after_reinstallscan --syncre-applies:scan_sync_reapplies_already_recorded_patch_after_reinstallagent_scan_rerun_fails_when_recorded_patch_cannot_be_applied--global-prefixvariant goes through the samedownload_and_apply_patches_withgateget <uuid>/get <purl>same-uuid re-get:get_uuid_…,get_purl_…Related, not fixed here: #424 (scan JSON drops the apply failure detail on the first run).
🤖 Generated with Claude Code
Generated by Claude Code