Skip to content

Remove --download-mode and the diff download path (#792) - #1049

Open
Mikola Lysenko (mikolalysenko) wants to merge 11 commits into
mainfrom
arch-refactor/792-retire-diff-download-mode
Open

Mikola Lysenko (mikolalysenko) wants to merge 11 commits into
mainfrom
arch-refactor/792-retire-diff-download-mode

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Removes the diff download path and the --download-mode flag. Patch content is now always fetched as per-file blobs.

Why

On #792 the maintainer said: "We should try to clean up older and deprecated options we don't need any more." The decision on the issue is option A, done fully in v5. v5 is not stable yet, so we skip the one-major diff alias and remove the diff path and the flag in one PR. With diff gone, file would be the only value, so the flag would do nothing.

What changed

Core

  • Deleted patch/diff.rs, the diff branch of apply, AppliedVia::Diff and PatchSources::diffs_path.
  • Deleted DownloadMode, fetch_missing_sources and get_missing_archives from api/blob_fetcher.rs. The download loop fetches only blobs, and repair calls fetch_missing_blobs directly.
  • Deleted ApiClient::fetch_diff and package::read_archive_filtered. The rest of package.rs stays, because vendor, hosted npm and vlt heal use it.
  • Removed qbsdiff and its profile blocks (qbsdiff, bzip2, libbz2-rs-sys, suffix_array) from every Cargo.toml and from Cargo.lock.
  • .socket/diffs is swept whole, like .socket/packages. cleanup_unused_archives is gone; only its own tests used it.
  • apply_package_patch and apply_go_redirect no longer take a uuid argument. It only fed the diff lookup (about 40 call sites).
  • Removed apply's mismatch-blob top-up. Staging now fetches every afterHash blob before apply runs, and apply stops before writing if any download fails, so that code could never fetch anything.

CLI

  • --download-mode and SOCKET_DOWNLOAD_MODE are removed with no alias.
  • Staging in fetch_stage.rs fetches blobs only, and repair has no second download pass.
  • appliedVia is always "blob".

User-visible changes

  • Passing --download-mode to any command is now clap's unknown-argument error (exit 2). A leftover SOCKET_DOWNLOAD_MODE is ignored.
  • A cold-cache apply/get/scan/repair makes no /diffs/ requests.
  • .socket/diffs/ is no longer read. repair, scan --prune, remove and rollback sweep every archive in it. The cleanup output still says "N unused diff archives" when it removes old ones.
  • --json appliedVia no longer has the "diff" value.
  • Kept for shape stability: repair's Downloaded/Verified event keeps details.mode, and the patch_fetched telemetry event keeps download_mode. Both are now always "file". Dropping them is the alternative if reviewers prefer it.

Docs

  • CLI_CONTRACT.md: removed the flag and env rows, added a "removed in v5.0" note, made appliedVia "blob" only, updated the GC, prune and repair-event text, and changed the defaults example to name --vendor-source.
  • docs/migrating-to-v5.md: added a Retired spellings row and rewrote the closing note about .socket/diffs/.
  • CHANGELOG.md is unchanged.

Tests

  • Deleted diff_e2e.rs, diff_created_file_e2e.rs and every diff and download-mode case.
  • Added parse tests that apply --download-mode file|diff and repair --download-mode file exit 2.
  • Added cold-cache checks to apply_network, the fetch-stage covgap test and the repair lifecycle test: no request path contains /diff and no .socket/diffs is created. The repair test also checks that a stale .socket/diffs/<referenced-uuid>.tar.gz is swept.
  • cargo test -p socket-patch-core --no-fail-fast: 6119 passed, 1 failed. The failure is utils::digest::tests::production_digests_go_through_the_helpers, which also fails on main and names files this PR doesn't touch.
  • cargo test -p socket-patch-cli: the lib, the 35 integration targets this PR touches, rollback, vendor, spawn_env_hygiene, in_process_remove_repair_lifecycle and the coverage_fix_*_silent_mute_exit targets all pass. The lib, rollback, spawn_env_hygiene, in_process_python_envs and the core api::client tests were re-run after rebasing onto main.
  • cargo tree shows no qbsdiff.
  • Not run locally: docker e2e and a full cargo test --workspace. CI covers those.
  • Clippy with -D warnings reports one warning, an unused unix_default in python_crawler.rs. It comes from main, not this PR.

Review findings fixed

  • tests/spawn_env_hygiene.rs still listed the deleted diff_created_file_e2e.rs in PENDING_RAW_SPAWNS, which would have failed no_new_bare_binary_spawns. Removed it.
  • Repair's download-message unit tests used the diff-archive noun for output repair can no longer produce. They now use the blob noun.
  • Removed stale comments that pointed to deleted code in rollback.rs, rollback_multicopy_blob_gate.rs, in_process_remove_repair_lifecycle.rs, golang_local.rs and args.rs.
  • rustfmt also reformatted a few unrelated lines in vendor.rs and telemetry.rs. They are harmless.

Coordination

#966 touches the same files (args.rs, get.rs, scan/mod.rs, repair.rs, both docs, the cli_parse_* tests). Whichever PR lands second rebases, and both add rows to the Retired spellings table. Blob retry (#676) now covers one artifact kind, because diffs are gone.

Closes #792
Closes #791 (there is no --download-mode value left to validate)

🤖 Generated with Claude Code


Note

High Risk
This is a MAJOR behavioral and CLI contract change: diff archives are no longer used, cleanup sweeps .socket/diffs/, and integrations relying on --download-mode or appliedVia: "diff" will break.

Overview
v5.0 (MAJOR) drops the diff-based patch download path and the global --download-mode / SOCKET_DOWNLOAD_MODE option. Patch content is always resolved from per-file blobs under .socket/blobs/; passing the old flag is a usage error (exit 2).

The qbsdiff dependency and diff-application code are removed from core and CLI. apply no longer prefetches blobs for hash mismatches via a separate top-up pass—staging fetches missing afterHash blobs up front. fetch_stage, repair, and related commands only call blob fetch APIs; obsolete .socket/diffs/ (and legacy package archives) are ignored on read and removed during GC/repair/prune.

JSON contract: appliedVia is only "blob" (no "diff"). CLI_CONTRACT.md and workspace Cargo.toml profile comments are updated accordingly.

Reviewed by Cursor Bugbot for commit 01e4cb7. Configure here.


Generated by Claude Code

Patch content is now always fetched as per-file blobs. v5 has not
shipped stable, so the deprecated diff path goes before it does.

Core:
- delete patch/diff.rs (bspatch) and the qbsdiff dependency
- apply: drop the diff strategy, AppliedVia::Diff,
  PatchSources::diffs_path and the now-unused `uuid` parameter of
  apply_package_patch / apply_go_redirect
- blob_fetcher: drop DownloadMode, get_missing_archives and
  fetch_missing_sources; download_entries is blob-only. DIFF_ARCHIVE
  stays as the noun for the obsolete-archive sweep output
- client: drop fetch_diff
- package.rs: drop read_archive_filtered only; the other readers are
  used by the vendored and hosted backends
- cleanup: .socket/diffs is obsolete like .socket/packages and every
  file in it is swept
- telemetry: patch_fetched keeps download_mode, always "file"

CLI:
- remove --download-mode / SOCKET_DOWNLOAD_MODE outright (no alias,
  no warning), matching how #966 removes deprecated spellings
- fetch_stage stages blobs only; with every afterHash blob staged up
  front, apply's mismatch-blob top-up is dead and is removed
- repair downloads blobs only; the Downloaded event keeps
  details.mode, always "file"
- appliedVia is always "blob"

Tests: delete the diff e2e suites and diff/mode parse tests, add
removal parse tests, a cold-cache no-/diff-request assertion and a
stale referenced .socket/diffs archive sweep check.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CLI_CONTRACT.md: drop the flag and env rows, note the removal, make
appliedVia "blob" only, and mark .socket/diffs obsolete in the GC
notes. migrating-to-v5.md: add the Retired spellings row and say
.socket/diffs archives are no longer read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Remove the deleted diff_created_file_e2e.rs from the bare-spawn ratchet
(its stale-entry check failed), point leftover comments at the blob-only
pipeline, and test repair's download messages with the blob noun.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) added the arch-refactor PR opened by the scheduled architecture refactor routine label Oct 7, 2026
Mikola Lysenko (mikolalysenko) added a commit that referenced this pull request Oct 7, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Comment thread crates/socket-patch-cli/tests/remove/remove_duality_invariants.rs Fixed
CodeQL flags the uuid as sensitive (cleartext logging); label the
entries A/B in the assert message instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] CI status: all green on 1357bcf (552 pass, 6 skipped).

  • Fixed: CodeQL rust/cleartext-logging alert in crates/socket-patch-cli/tests/remove/remove_duality_invariants.rs. The new assert message interpolated the archive uuid, so it now labels the entries A/B instead (3be03b0).
  • Infra, not this PR: hosted-e2e failed when corepack couldn't fetch yarn from registry.npmjs.org. The Windows Gradle multi-project e2e failed on a Maven Central 403. The CodeQL Analyze (rust) SARIF upload also failed, and default-setup runs can't be re-run, so an empty commit (1357bcf) retriggered the checks. All of them passed on the new head.

Generated by Claude Code

Keep this PR's removal of the diff download path: drop main's updated
mismatch-blob prefetch (ensure_blobs_for_mismatches / mismatch_blob_gaps)
and its tests, and main's --download-mode parse tests. Keep main's new
CLI_CONTRACT wording about added files and rollback, minus the diff text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 8, 2026 11:32
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] Merged main, CI green; ready for review.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Ready for review (burn-down agent).

  • Head: 9fc3cd30571fa4e08089138f0272e167e966ff3d
  • CI: 520/520 check runs green (success/skipped/neutral) on this head, mergeable, no conflicts.
  • Bugbot: reviewed this head (Cursor Bugbot check: success), no unresolved review threads.
  • Changelog: untouched.

Nothing specific flagged for the reviewer beyond the PR description.


Generated by Claude Code

@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
@mikolalysenko Mikola Lysenko (mikolalysenko) added Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review and removed Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review labels Oct 8, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 8, 2026
Resolve docs/migrating-to-v5.md: keep this PR's --download-mode removal
row and main's new SOCKET_FORCE row (#1021) in the removed-spellings table.

Co-Authored-By: Claude <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) removed the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 8, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Main (#1043) moved the agent download engine (DownloadParams,
DownloadRun, filter_to_installed_releases, nested_apply_args_from_params,
...) out of commands/get.rs into commands/agent_download.rs and moved
is_local_go into args.rs. This branch had edited that code in get.rs to
drop the --download-mode plumbing, so the conflicts were "deleted on
main, modified here".

Resolution:
- get.rs: take main's removal of the moved block, then re-apply this
  PR's change at the new home: agent_download.rs loses the
  DownloadParams::download_mode field, its forwarding into the nested
  apply's GlobalArgs, and the --download-mode mention in the
  nested-apply doc comment (GlobalArgs no longer has the field).
- commands/apply.rs imports: keep main's `is_local_go` from crate::args;
  keep this PR's removal of `StagedSources` (only the deleted diff path
  used it).

Also gate the core apply.rs `make_fixture` test helper on macOS: with
the diff tests gone, its only remaining caller is the macOS-only chflags
test, so `clippy --all-targets -D warnings` failed on Linux/Windows with
dead_code.

No docs still list --download-mode as a live flag. It appears only in the
v5.0 removal note in CLI_CONTRACT.md and in the Retired spellings row of
migrating-to-v5.md, next to main's SOCKET_FORCE row.

Co-Authored-By: Claude <noreply@anthropic.com>
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread crates/socket-patch-cli/src/commands/apply.rs
Comment thread crates/socket-patch-cli/src/commands/fetch_stage.rs
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@cursor

cursor Bot commented Oct 8, 2026

Copy link
Copy Markdown

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Apply stages blobs for vendored patches
    • Moved vendor ownership computation before staging and filtered vendor-owned packages from the manifest passed to stage_patch_sources, preventing staging failures when vendored packages have no blobs.

Create PR

Or push these changes by commenting:

@cursor push cc95b42ae5
Preview (cc95b42ae5)
diff --git a/crates/socket-patch-cli/src/commands/apply.rs b/crates/socket-patch-cli/src/commands/apply.rs
--- a/crates/socket-patch-cli/src/commands/apply.rs
+++ b/crates/socket-patch-cli/src/commands/apply.rs
@@ -1848,22 +1848,56 @@
         .patches
         .retain(|purl, _| target_manifest_purls.contains(purl));
 
-    let staged = match stage_patch_sources(&args.common, &manifest, &socket_dir, client).await? {
-        StageOutcome::Ready(s) => s,
-        StageOutcome::Unavailable => {
-            return Ok(ApplyOutcome {
-                success: false,
-                results: Vec::new(),
-                unmatched: Vec::new(),
-                lockfile_only: HashSet::new(),
-                run_warnings: vec![stage_failure_warning(args.common.offline)],
-                fallback_skips: Vec::new(),
-                targeted: target_manifest_purls.len(),
-                show_summary: false,
-            })
-        }
+    // Vendor ownership wins for EVERY ecosystem: a purl recorded in
+    // `.socket/vendor/state.json` is managed by the explicit `vendor`
+    // action — apply must not re-patch its installed tree (or repoint a
+    // vendor-owned go `replace` back at `.socket/go-patches/`). Matchable
+    // by ledger key, resolved base purl, or qualifier-stripped key so
+    // release-variant manifest keys (pypi `?artifact_id=`…) hit too;
+    // unreadable state degrades to "nothing vendored" (fail-open).
+    // The ledger owns the PROJECT's copies only: a global apply restores
+    // and patches the global copy even when the cwd project vendors the
+    // same purl (see `project_state_in_scope`).
+    // Resolved BEFORE staging so vendored packages (which need no blobs)
+    // don't cause staging to fail.
+    let vendored_purls = if crate::commands::project_state_in_scope(&args.common) {
+        socket_patch_core::vendor::vendored_purl_keys(&args.common.cwd).await
+    } else {
+        Default::default()
     };
+    let is_vendored = |p: &str| purl_keys_cover(&vendored_purls, p);
 
+    // Stage sources from a manifest that excludes vendor-owned packages:
+    // vendored patches are already in-place and need no blobs, so their
+    // absence must not fail staging (especially `--offline` or when a
+    // vendored blob 404s).
+    let staging_manifest = PatchManifest {
+        patches: manifest
+            .patches
+            .iter()
+            .filter(|(purl, _)| !is_vendored(purl))
+            .map(|(k, v)| (k.clone(), v.clone()))
+            .collect(),
+        setup: manifest.setup.clone(),
+    };
+
+    let staged =
+        match stage_patch_sources(&args.common, &staging_manifest, &socket_dir, client).await? {
+            StageOutcome::Ready(s) => s,
+            StageOutcome::Unavailable => {
+                return Ok(ApplyOutcome {
+                    success: false,
+                    results: Vec::new(),
+                    unmatched: Vec::new(),
+                    lockfile_only: HashSet::new(),
+                    run_warnings: vec![stage_failure_warning(args.common.offline)],
+                    fallback_skips: Vec::new(),
+                    targeted: target_manifest_purls.len(),
+                    show_summary: false,
+                })
+            }
+        };
+
     // Local go: prune `replace`-redirects whose patches were dropped from the
     // manifest (orphans). Done here — before the crawl + the "no packages
     // found" early returns — so orphans are reconciled even when the manifest
@@ -1894,22 +1928,8 @@
         });
     }
 
-    // Vendor ownership wins for EVERY ecosystem: a purl recorded in
-    // `.socket/vendor/state.json` is managed by the explicit `vendor`
-    // action — apply must not re-patch its installed tree (or repoint a
-    // vendor-owned go `replace` back at `.socket/go-patches/`). Matchable
-    // by ledger key, resolved base purl, or qualifier-stripped key so
-    // release-variant manifest keys (pypi `?artifact_id=`…) hit too;
-    // unreadable state degrades to "nothing vendored" (fail-open).
-    // The ledger owns the PROJECT's copies only: a global apply restores
-    // and patches the global copy even when the cwd project vendors the
-    // same purl (see `project_state_in_scope`).
-    let vendored_purls = if crate::commands::project_state_in_scope(&args.common) {
-        socket_patch_core::vendor::vendored_purl_keys(&args.common.cwd).await
-    } else {
-        Default::default()
-    };
-    let is_vendored = |p: &str| purl_keys_cover(&vendored_purls, p);
+    // Synthesize results for vendored packages (ownership already
+    // resolved above, before staging).
     let (mut results, mut matched_manifest_purls, vendored_bases) =
         synthesize_vendor_owned_results(&target_manifest_purls, &vendored_purls);
 

diff --git a/crates/socket-patch-cli/src/commands/scan/policy.rs b/crates/socket-patch-cli/src/commands/scan/policy.rs
--- a/crates/socket-patch-cli/src/commands/scan/policy.rs
+++ b/crates/socket-patch-cli/src/commands/scan/policy.rs
@@ -237,7 +237,9 @@
     }
 
     fn recorded_uuid(&self, purl: &str) -> Option<&str> {
-        self.recorded.get(&PurlKey::new(purl).into_string()).map(String::as_str)
+        self.recorded
+            .get(&PurlKey::new(purl).into_string())
+            .map(String::as_str)
     }
 
     /// Step 3: the root, ecosystem and package filters. Returns whether the
@@ -269,7 +271,10 @@
         }
         if self.root_verdict.is_err() {
             // Already reported as the root's one entry.
-        } else if report.filtered_purls.insert(PurlKey::new(purl).into_string()) {
+        } else if report
+            .filtered_purls
+            .insert(PurlKey::new(purl).into_string())
+        {
             report.filtered.push(FilteredEntry {
                 purl: Some(PurlKey::new(purl).into_string()),
                 uuid: None,
@@ -284,7 +289,10 @@
     /// Record the purls with a newer patch (`updates[]`), for
     /// `retained[].upgradeAvailable`.
     pub(crate) fn set_update_purls<'a>(&self, purls: impl IntoIterator<Item = &'a str>) {
-        self.report().update_purls = purls.into_iter().map(|p| PurlKey::new(p).into_string()).collect();
+        self.report().update_purls = purls
+            .into_iter()
+            .map(|p| PurlKey::new(p).into_string())
+            .collect();
     }
 
     /// Steps 5-6: group the tier-accessible offers, keep retained packages
@@ -298,7 +306,10 @@
         {
             let report = self.report();
             for offer in accessible {
-                if report.retained_purls.contains(&PurlKey::new(&offer.purl).into_string()) {
+                if report
+                    .retained_purls
+                    .contains(&PurlKey::new(&offer.purl).into_string())
+                {
                     continue;
                 }
                 grouped.entry(offer.purl.clone()).or_default().push(offer);

diff --git a/crates/socket-patch-cli/tests/e2e_redirect_yarn_classic_build.rs b/crates/socket-patch-cli/tests/e2e_redirect_yarn_classic_build.rs
--- a/crates/socket-patch-cli/tests/e2e_redirect_yarn_classic_build.rs
+++ b/crates/socket-patch-cli/tests/e2e_redirect_yarn_classic_build.rs
@@ -900,7 +900,10 @@
         return;
     };
     assert!(
-        fx.proj.join("mirror").join(format!("{DEP}-{DEP_VERSION}.tgz")).is_file(),
+        fx.proj
+            .join("mirror")
+            .join(format!("{DEP}-{DEP_VERSION}.tgz"))
+            .is_file(),
         "the fixture install must populate the offline mirror"
     );
     let fresh = fx.tmp.path().join("fresh");
@@ -926,7 +929,11 @@
             String::from_utf8_lossy(&ci.stderr)
         );
         assert!(
-            !fresh.join("node_modules").join(DEP).join("index.js").exists(),
+            !fresh
+                .join("node_modules")
+                .join(DEP)
+                .join("index.js")
+                .exists(),
             "yarn < 1.7 is expected to install nothing from the mirror"
         );
         return;
@@ -948,7 +955,10 @@
         );
         let installed =
             std::fs::read(fresh.join("node_modules").join(DEP).join("index.js")).unwrap();
-        assert_eq!(installed, fx.orig, "the untouched lock installs the upstream bytes");
+        assert_eq!(
+            installed, fx.orig,
+            "the untouched lock installs the upstream bytes"
+        );
         std::fs::remove_dir_all(fresh.join("node_modules")).unwrap();
     }
 }

diff --git a/crates/socket-patch-cli/tests/e2e_vendor_yarn_berry_build.rs b/crates/socket-patch-cli/tests/e2e_vendor_yarn_berry_build.rs
--- a/crates/socket-patch-cli/tests/e2e_vendor_yarn_berry_build.rs
+++ b/crates/socket-patch-cli/tests/e2e_vendor_yarn_berry_build.rs
@@ -729,7 +729,14 @@
 
 fn git(cwd: &Path, args: &[&str]) -> Output {
     let out = Command::new("git")
-        .args(["-c", "user.name=t", "-c", "user.email=t@t", "-c", "init.defaultBranch=main"])
+        .args([
+            "-c",
+            "user.name=t",
+            "-c",
+            "user.email=t@t",
+            "-c",
+            "init.defaultBranch=main",
+        ])
         .args(args)
         .current_dir(cwd)
         .output()
@@ -810,16 +817,30 @@
     };
     let (code, stdout, stderr) = run_socket(
         &proj,
-        &["vendor", "--json", "--offline", "--cwd", proj.to_str().unwrap()],
+        &[
+            "vendor",
+            "--json",
+            "--offline",
+            "--cwd",
+            proj.to_str().unwrap(),
+        ],
     );
-    assert_eq!(code, 0, "vendor failed.\nstdout:\n{stdout}\nstderr:\n{stderr}");
+    assert_eq!(
+        code, 0,
+        "vendor failed.\nstdout:\n{stdout}\nstderr:\n{stderr}"
+    );
 
     git(&proj, &["add", "-A"]);
     git(&proj, &["commit", "-qm", "vendored"]);
     let fresh = tmp.path().join("fresh");
     git(
         tmp.path(),
-        &["clone", "-q", proj.to_str().unwrap(), fresh.to_str().unwrap()],
+        &[
+            "clone",
+            "-q",
+            proj.to_str().unwrap(),
+            fresh.to_str().unwrap(),
+        ],
     );
     let fresh_global = tmp.path().join("fresh-yarn-global");
     let ci = corepack(
@@ -854,14 +875,26 @@
     let pkg_before = std::fs::read(proj.join("package.json")).unwrap();
     let (code, stdout, stderr) = run_socket(
         &proj,
-        &["vendor", "--json", "--offline", "--cwd", proj.to_str().unwrap()],
+        &[
+            "vendor",
+            "--json",
+            "--offline",
+            "--cwd",
+            proj.to_str().unwrap(),
+        ],
     );
-    assert_eq!(code, 1, "vendor must fail.\nstdout:\n{stdout}\nstderr:\n{stderr}");
+    assert_eq!(
+        code, 1,
+        "vendor must fail.\nstdout:\n{stdout}\nstderr:\n{stderr}"
+    );
     assert!(
         stdout.contains("vendor_artifact_gitignored"),
         "refusal code expected:\n{stdout}"
     );
     assert_eq!(std::fs::read(proj.join("yarn.lock")).unwrap(), lock_before);
-    assert_eq!(std::fs::read(proj.join("package.json")).unwrap(), pkg_before);
+    assert_eq!(
+        std::fs::read(proj.join("package.json")).unwrap(),
+        pkg_before
+    );
     assert!(!proj.join(format!(".socket/vendor/npm/{UUID}")).exists());
 }

diff --git a/crates/socket-patch-cli/tests/in_process_redirect_pipenv.rs b/crates/socket-patch-cli/tests/in_process_redirect_pipenv.rs
--- a/crates/socket-patch-cli/tests/in_process_redirect_pipenv.rs
+++ b/crates/socket-patch-cli/tests/in_process_redirect_pipenv.rs
@@ -556,8 +556,7 @@
 #[tokio::test]
 #[serial]
 async fn platform_wheel_is_not_pinned_into_the_lock() {
-    assert_wheel_tag_is_not_pinned("cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64")
-        .await;
+    assert_wheel_tag_is_not_pinned("cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64").await;
 }
 
 /// #1048: a pure wheel bound to one interpreter (`cp311-none-any`) fails

diff --git a/crates/socket-patch-cli/tests/in_process_redirect_pnpm.rs b/crates/socket-patch-cli/tests/in_process_redirect_pnpm.rs
--- a/crates/socket-patch-cli/tests/in_process_redirect_pnpm.rs
+++ b/crates/socket-patch-cli/tests/in_process_redirect_pnpm.rs
@@ -434,7 +434,10 @@
     assert_eq!(code, 0, "scan --mode hosted should succeed on a BOM lock");
     let lock = std::fs::read_to_string(&lock_path).unwrap();
     assert!(lock.starts_with("\u{feff}lockfileVersion:"), "{lock}");
-    assert!(lock.contains(HOSTED_URL), "the BOM lock is redirected: {lock}");
+    assert!(
+        lock.contains(HOSTED_URL),
+        "the BOM lock is redirected: {lock}"
+    );
     let ws_path = tmp.path().join("pnpm-workspace.yaml");
     assert_eq!(
         std::fs::read_to_string(&ws_path).ok().as_deref(),
@@ -449,7 +452,10 @@
         pristine,
         "rollback restores the BOM lock byte for byte"
     );
-    assert!(!ws_path.exists(), "the auto-created workspace file goes too");
+    assert!(
+        !ws_path.exists(),
+        "the auto-created workspace file goes too"
+    );
 
     // A BOM workspace file whose first key is the user's opt-out: left
     // byte-identical (no duplicate `trustLockfile`), lock still redirected.
@@ -475,7 +481,11 @@
             "the lock is still redirected for {user_ws:?}"
         );
         let ws = std::fs::read_to_string(tmp.path().join("pnpm-workspace.yaml")).unwrap();
-        assert_eq!(ws, want.unwrap_or(user_ws), "workspace file for {user_ws:?}");
+        assert_eq!(
+            ws,
+            want.unwrap_or(user_ws),
+            "workspace file for {user_ws:?}"
+        );
         assert_eq!(ws.matches("trustLockfile").count(), 1, "{ws:?}");
     }
 }

diff --git a/crates/socket-patch-cli/tests/mode_migration_pypi.rs b/crates/socket-patch-cli/tests/mode_migration_pypi.rs
--- a/crates/socket-patch-cli/tests/mode_migration_pypi.rs
+++ b/crates/socket-patch-cli/tests/mode_migration_pypi.rs
@@ -1195,9 +1195,18 @@
     set_mode(0o755);
     assert_eq!(code, 1, "{env:#}");
     assert_eq!(env["status"], "error", "{env:#}");
-    assert!(!env.to_string().contains("redirect_takeover_unpatched"), "{env:#}");
-    assert_eq!(std::fs::read(root.join("requirements.txt")).unwrap(), vendored);
-    assert_eq!(std::fs::read(root.join(".socket/vendor/state.json")).unwrap(), state);
+    assert!(
+        !env.to_string().contains("redirect_takeover_unpatched"),
+        "{env:#}"
+    );
+    assert_eq!(
+        std::fs::read(root.join("requirements.txt")).unwrap(),
+        vendored
+    );
+    assert_eq!(
+        std::fs::read(root.join(".socket/vendor/state.json")).unwrap(),
+        state
+    );
     assert!(root.join(format!(".socket/vendor/pypi/{UUID}")).exists());
 }
 

diff --git a/crates/socket-patch-core/src/crawlers/cargo_crawler.rs b/crates/socket-patch-core/src/crawlers/cargo_crawler.rs
--- a/crates/socket-patch-core/src/crawlers/cargo_crawler.rs
+++ b/crates/socket-patch-core/src/crawlers/cargo_crawler.rs
@@ -300,8 +300,7 @@
     let content = crate::utils::fs::read_regular_to_string_sync(&cargo_toml_path).ok()?;
 
     // Fallback: parse directory name as <name>-<version>
-    package_name_version(&content)
-        .or_else(|| CargoCrawler::parse_dir_name_version(dir_name))
+    package_name_version(&content).or_else(|| CargoCrawler::parse_dir_name_version(dir_name))
 }
 
 /// SECURITY: `find_by_purls` formats name/version into a `<name>-<version>`

diff --git a/crates/socket-patch-core/src/formats/mod.rs b/crates/socket-patch-core/src/formats/mod.rs
--- a/crates/socket-patch-core/src/formats/mod.rs
+++ b/crates/socket-patch-core/src/formats/mod.rs
@@ -29,8 +29,8 @@
 pub(crate) mod bun;
 pub mod cargo;
 pub mod composer;
+pub mod gem;
 pub mod governing_locks;
-pub mod gem;
 pub(crate) mod maven;
 pub(crate) mod nuget;
 pub mod pnpm;

diff --git a/crates/socket-patch-core/src/hosted/memory/mod.rs b/crates/socket-patch-core/src/hosted/memory/mod.rs
--- a/crates/socket-patch-core/src/hosted/memory/mod.rs
+++ b/crates/socket-patch-core/src/hosted/memory/mod.rs
@@ -66,9 +66,9 @@
     classify, lookup_incomplete, mentioned_uuids, offers_from_results, Offers, RecordedIndex, Row,
     Stage, ROLLOUT_DEFERRED,
 };
+use crate::utils::purl_key::PurlKey;
 use discover::Provider;
 use stages::{Planned, RewriteRefused, Rewritten, StageOptions};
-use crate::utils::purl_key::PurlKey;
 
 /// `"<crate version>+<git sha or 'unknown'>"`; the sha comes from the
 /// `SOCKET_PATCH_GIT_SHA` build-time variable.

diff --git a/crates/socket-patch-core/src/patch/redirect/mod.rs b/crates/socket-patch-core/src/patch/redirect/mod.rs
--- a/crates/socket-patch-core/src/patch/redirect/mod.rs
+++ b/crates/socket-patch-core/src/patch/redirect/mod.rs
@@ -77,9 +77,9 @@
 use crate::formats::yarn::source::{classic_copy_source, CopySource};
 use crate::formats::yarn::stanzas::{stanza_key, BerryStanzas};
 #[cfg(test)]
+mod platform_wheel_tests;
+#[cfg(test)]
 mod pnpm_equivalence_tests;
-#[cfg(test)]
-mod platform_wheel_tests;
 mod poetry;
 mod pypi_takeover;
 pub use pypi_takeover::preflight_pypi_takeover;
@@ -565,7 +565,7 @@
         bun_lockb_present,
         &std::collections::BTreeSet::new(),
         &std::collections::BTreeSet::new(),
-     &yarnrc::OuterYarnMirror::default(),
+        &yarnrc::OuterYarnMirror::default(),
     )
 }
 
@@ -6760,8 +6760,10 @@
     // One pass over the pom's repositories: `(id, url)` of each, which also
     // answers the per-dep URL-refresh check below while the pom is still
     // unchanged (a no-op rescan then never re-scans the pom per dep).
-    let original_repos: Vec<(String, Option<String>)> =
-        pom.as_deref().map(maven_repository_ids_and_urls).unwrap_or_default();
+    let original_repos: Vec<(String, Option<String>)> = pom
+        .as_deref()
+        .map(maven_repository_ids_and_urls)
+        .unwrap_or_default();
     let hosted_repo_generations: std::collections::BTreeSet<String> = original_repos
         .iter()
         .filter_map(|(id, _)| generation::pin_name_uuid(id, false).map(str::to_string))
@@ -10833,7 +10835,10 @@
             &[(YARNRC_REL, "yarn-offline-mirror: false\n")],
             &[(YARNRC_REL, "yarn-offline-mirror:\n")],
             &[(YARNRC_REL, "yarn-offline-mirror \"\"\n")],
-            &[(YARNRC_REL, "yarn-offline-mirror-pruning true\n# yarn-offline-mirror ./m\n")],
+            &[(
+                YARNRC_REL,
+                "yarn-offline-mirror-pruning true\n# yarn-offline-mirror ./m\n",
+            )],
             &[(npmrc::NPMRC_REL, "[scope]\nyarn-offline-mirror=./m\n")],
             &[
                 (YARNRC_REL, "yarn-offline-mirror false\n"),
@@ -10849,7 +10854,10 @@
             let mut r = RewriteResult::default();
             rewrite_yarn_classic(&files, std::slice::from_ref(&ovr), &mut r);
             assert!(r.warnings.is_empty(), "{rcs:?}: {:?}", r.warnings);
-            assert!(r.files["yarn.lock"].contains("http://p.test/lp.tgz"), "{rcs:?}");
+            assert!(
+                r.files["yarn.lock"].contains("http://p.test/lp.tgz"),
+                "{rcs:?}"
+            );
             assert!(r.refused_yarn_classic_uuids.is_empty(), "{rcs:?}");
         }
     }
@@ -10874,7 +10882,10 @@
         rewrite_yarn_classic(&files, std::slice::from_ref(&other), &mut r);
         assert!(r.refused_yarn_classic_uuids.is_empty());
         assert_eq!(
-            r.warnings.iter().map(|w| w.code.as_str()).collect::<Vec<_>>(),
+            r.warnings
+                .iter()
+                .map(|w| w.code.as_str())
+                .collect::<Vec<_>>(),
             ["redirect_yarn_classic_entry_not_found"]
         );
     }

diff --git a/crates/socket-patch-core/src/patch/redirect/poetry.rs b/crates/socket-patch-core/src/patch/redirect/poetry.rs
--- a/crates/socket-patch-core/src/patch/redirect/poetry.rs
+++ b/crates/socket-patch-core/src/patch/redirect/poetry.rs
@@ -89,7 +89,9 @@
                             new: Some(Value::String(new)),
                         });
                     }
-                    result.confirmed_python_lock_uuids.insert(dep.patch_uuid.clone());
+                    result
+                        .confirmed_python_lock_uuids
+                        .insert(dep.patch_uuid.clone());
                     if !stale_warned {
                         if let Some(format) =
                             *writer_format.get_or_insert_with(|| pre_1_4_writer(&content))
@@ -124,14 +126,18 @@
                 }
                 // Already redirected to this artifact (idempotent re-scan).
                 LockStep::Unchanged => {
-                    result.confirmed_python_lock_uuids.insert(dep.patch_uuid.clone());
+                    result
+                        .confirmed_python_lock_uuids
+                        .insert(dep.patch_uuid.clone());
                 }
                 LockStep::NotFound => result.warnings.push(RewriteWarning {
                     code: "redirect_poetry_entry_not_found".into(),
                     detail: format!("no {path} entry for {}@{}", dep.name, dep.version),
                 }),
                 LockStep::Refused(detail) => {
-                    result.refused_python_lock_uuids.insert(dep.patch_uuid.clone());
+                    result
+                        .refused_python_lock_uuids
+                        .insert(dep.patch_uuid.clone());
                     result.warnings.push(RewriteWarning {
                         code: "redirect_poetry_lock_unsupported".into(),
                         detail: format!("{path}: {detail}"),

diff --git a/crates/socket-patch-core/src/patch/redirect/upstream/cargo.rs b/crates/socket-patch-core/src/patch/redirect/upstream/cargo.rs
--- a/crates/socket-patch-core/src/patch/redirect/upstream/cargo.rs
+++ b/crates/socket-patch-core/src/patch/redirect/upstream/cargo.rs
@@ -489,6 +489,9 @@
         let other = format!("log = {{ version = \"0.4.20\", registry = \"socket-patch-{C}\" }}\n");
         let (outcome, after) = restore_b(&manifest(&other), &config).await;
         assert_eq!(outcome.restored().count(), 1, "{:?}", outcome.pins);
-        assert_eq!(after.as_deref().map(str::trim_start), Some(block(C).as_str()));
+        assert_eq!(
+            after.as_deref().map(str::trim_start),
+            Some(block(C).as_str())
+        );
     }
 }

diff --git a/crates/socket-patch-core/src/utils/group_commit.rs b/crates/socket-patch-core/src/utils/group_commit.rs
--- a/crates/socket-patch-core/src/utils/group_commit.rs
+++ b/crates/socket-patch-core/src/utils/group_commit.rs
@@ -1335,7 +1335,10 @@
             (".socket/vendor/.gitattributes", true),
             (".socket/vendor/gradle/g/a/maven-metadata.xml", true),
             (".socket/vendor/gradle/g/a/1/a-1.jar", false),
-            (".socket/vendor/gradle/g/a/1/socket-patch.vendor.json", false),
+            (
+                ".socket/vendor/gradle/g/a/1/socket-patch.vendor.json",
+                false,
+            ),
             (".socket/vendor/npm/u/left-pad-1.3.0.tgz", false),
             (".socket/manifest.json", false),
             ("packages/a/.socket/vendor/npm/u/a.tgz", false),
@@ -1437,10 +1440,16 @@
             if keep {
                 group.rollback_to(savepoint);
                 group.commit().await.unwrap();
-                assert!(unit.join("a.tgz").exists(), "a rolled-back removal is forgotten");
+                assert!(
+                    unit.join("a.tgz").exists(),
+                    "a rolled-back removal is forgotten"
+                );
             } else {
                 drop(group);
-                assert!(unit.join("a.tgz").exists(), "a dropped group deletes nothing");
+                assert!(
+                    unit.join("a.tgz").exists(),
+                    "a dropped group deletes nothing"
+                );
             }
         }
 
@@ -1449,8 +1458,14 @@
         remove_tree_and_prune(&unit, &socket).await.unwrap();
         group.commit().await.unwrap();
         assert!(!unit.exists());
-        assert!(!socket.join("vendor").exists(), "the emptied levels are pruned");
-        assert!(socket.join("apply.lock").exists(), "`.socket/` itself stays");
+        assert!(
+            !socket.join("vendor").exists(),
+            "the emptied levels are pruned"
+        );
+        assert!(
+            socket.join("apply.lock").exists(),
+            "`.socket/` itself stays"
+        );
     }
 
     /// A journal the commit had to create `.socket/vendor/` for (a hosted

diff --git a/crates/socket-patch-core/src/vendor/lock_inventory/tests.rs b/crates/socket-patch-core/src/vendor/lock_inventory/tests.rs
--- a/crates/socket-patch-core/src/vendor/lock_inventory/tests.rs
+++ b/crates/socket-patch-core/src/vendor/lock_inventory/tests.rs
@@ -999,7 +999,10 @@
         .filter(|l| !l.starts_with('#'))
         .collect::<Vec<_>>()
         .join("\n");
-    assert!(!headerless.contains("lockfile v1"), "fixture drops the header");
+    assert!(
+        !headerless.contains("lockfile v1"),
+        "fixture drops the header"
+    );
     write(tmp.path(), "yarn.lock", &headerless).await;
     let (flavor, entries) = inventory_npm_lock(tmp.path()).await.unwrap().unwrap();
     assert_eq!(flavor, NpmLockFlavor::YarnClassic);

diff --git a/crates/socket-patch-core/src/vendor/mod.rs b/crates/socket-patch-core/src/vendor/mod.rs
--- a/crates/socket-patch-core/src/vendor/mod.rs
+++ b/crates/socket-patch-core/src/vendor/mod.rs
@@ -129,8 +129,8 @@
 };
 // The hosted→vendored takeover refuses a berry project the backend would
 // refuse BEFORE it reverts the hosted redirect.
+pub use npm_common::npm_tarball_gitignore_preflight;
 pub use npm_lock::npm_lock_vendor_preflight;
-pub use npm_common::npm_tarball_gitignore_preflight;
 pub use yarn_berry_lock::{yarn_berry_vendor_preflight, yarn_berry_vendor_target_preflight};
 
 use std::collections::{HashMap, HashSet};

diff --git a/crates/socket-patch-core/src/vendor/yarn_berry_lock.rs b/crates/socket-patch-core/src/vendor/yarn_berry_lock.rs
--- a/crates/socket-patch-core/src/vendor/yarn_berry_lock.rs
+++ b/crates/socket-patch-core/src/vendor/yarn_berry_lock.rs
@@ -46,9 +46,7 @@
 use crate::constants::SOCKET_DIR;
 use crate::formats::yarn::berry_entry::{manifest_bin, render_pinned_entry, Pin};
 use crate::formats::yarn::berry_gates::{self, BerryGate, Yarnrc, SUPPORTED_CACHE_KEY};
-use crate::formats::yarn::blocks::{
-    berry_field, block_eol, replace_block, scan_blocks, LockBlock,
-};
+use crate::formats::yarn::blocks::{berry_field, block_eol, replace_block, scan_blocks, LockBlock};
 use crate::formats::yarn::patterns::{pattern_real_name, split_berry_key_patterns, split_pattern};
 use crate::manifest::schema::PatchRecord;
 use crate::patch::apply::{normalize_file_path, PatchSources};

diff --git a/crates/socket-patch-core/src/vendor/yarn_classic_lock.rs b/crates/socket-patch-core/src/vendor/yarn_classic_lock.rs
--- a/crates/socket-patch-core/src/vendor/yarn_classic_lock.rs
+++ b/crates/socket-patch-core/src/vendor/yarn_classic_lock.rs
@@ -1512,11 +1512,7 @@
             .filter(|&c| c != "vendor_prebuilt_downloaded")
             .collect();
         assert_eq!(codes, ["vendor_yarn_classic_non_registry_legacy_wiring"]);
-        let detail = &warnings
-            .iter()
-            .find(|w| w.code == codes[0])
-            .unwrap()
-            .detail;
+        let detail = &warnings.iter().find(|w| w.code == codes[0]).unwrap().detail;
         assert!(
             detail.contains("host.test/fork")
                 && detail.contains("vendor --revert")

diff --git a/crates/socket-patch-core/src/vex/discover/yarn.rs b/crates/socket-patch-core/src/vex/discover/yarn.rs
--- a/crates/socket-patch-core/src/vex/discover/yarn.rs
+++ b/crates/socket-patch-core/src/vex/discover/yarn.rs
@@ -90,12 +90,12 @@
     DIAG_REF_INVALID, DIAG_REF_UNATTRIBUTABLE,
 };
 use crate::formats::yarn::blocks::{berry_field, classic_field};
+use crate::formats::yarn::is_berry_lock;
 use crate::formats::yarn::patterns::{
     classic_key_real_name, pattern_real_name, resolution_selector_target, split_resolved_sha1,
     BerryLocator,
 };
 use crate::formats::yarn::source::{classic_copy_source, CopySource};
-use crate::formats::yarn::is_berry_lock;
 use crate::utils::digest::is_sri_pin;
 use crate::vendor::lock_inventory::yarn::{
     berry_checksum_pin, berry_entries, classic_entries, BerryLock, YarnEntry,

diff --git a/crates/socket-patch-core/src/vex/product.rs b/crates/socket-patch-core/src/vex/product.rs
--- a/crates/socket-patch-core/src/vex/product.rs
+++ b/crates/socket-patch-core/src/vex/product.rs
@@ -1425,7 +1425,9 @@
     async fn detect_git_remote_handles_non_existent_start_path() {
         let dir = tempfile::tempdir().unwrap();
         let nonexistent = dir.path().join("does/not/exist");
-        assert!(detect_git_remote(&nonexistent, &mut Vec::new()).await.is_none());
+        assert!(detect_git_remote(&nonexistent, &mut Vec::new())
+            .await
+            .is_none());
     }
 
     /// B22: inside a submodule (`.git` is a `gitdir:` FILE), the product is

You can send follow-ups to the cloud agent here.

With the diff download path gone, per-item blob failures print only via
format_fetch_summary, which is gated on quiet (--silent or --json). A
fatal staging failure under --silent then printed the generic error
without the hash and reason lines the old deferred-failure path showed
(Bugbot 4223475496). Print format_fetch_failures before the error when
the summary was held back; --json stays silent on stderr.

Co-Authored-By: Claude <noreply@anthropic.com>
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[final reviewer] Tanmay Singla (@Tanmay182003) One non-merge commit landed after your approval on 9fc3cd30: 6773eaa Keep per-blob download failure reasons under --silent apply (a burn-down fix for Bugbot's finding that apply --silent stopped printing which blob failed and why). It isn't enqueued until you take another look at head 6773eaa and CI is green.


Generated by Claude Code

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 8, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[burn-down agent] Ready for review at 6773eaa6ac

  • CI: all 466 check runs on the current head green or skipped (ci-ok success). sbt 1.2.8 / jdk 8 / agent failed once in "Run the agent group" and passed on a single re-run (run 37852597217, attempt 2), so it was a flake.
  • Mergeable against main, no conflicts; no CHANGELOG.md change.
  • Cursor Bugbot reviewed 6773eaa6; every review thread is resolved (the fetch_stage.rs finding is addressed by 6773eaa6).

Generated by Claude Code

Resolve conflicts with #1031 (scan --apply/--vendor, get --no-apply and
download/gc alias removal):
- docs/migrating-to-v5.md: keep both removal tables' rows (#1031's
  spellings plus --download-mode/SOCKET_DOWNLOAD_MODE) and the
  blobs-only archive note.
- CLI_CONTRACT.md: keep the --download-mode removal paragraph, take
  main's --mode agent/vendored wording, drop diff-strategy text; repair
  events row renamed to `repair` with the file-only Downloaded details.
- tests/cli_parse_repair.rs: keep the --download-mode rejection test,
  drop the gc alias tests main removed; header covers both removals.

Fix merge fallout: drop the uuid argument from a new schema.rs test's
apply_package_patch call (the PR removed that parameter), and remove an
unused FileEdit import in vlt_heal.rs tests left by #1141.

Co-Authored-By: Claude <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) removed the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 9, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Merged main (03b9418) to clear conflicts with #1031; head is now 01e4cb7. Removed Ready for review until CI is green on the new head. Conflict notes: migrating-to-v5 table keeps both #1031's removals and this PR's --download-mode row; CLI_CONTRACT events row uses main's repair name with this PR's mode: "file" content; cli_parse_repair keeps repair_download_mode_flag_is_removed. Merge fallout: a main-added test in manifest/schema.rs dropped the uuid arg this PR removed from apply_package_patch; removed main's unused FileEdit import in vlt_heal tests. Local: workspace check clean; cli 4620 pass / core lib 5798 pass, remaining failures are root-only chmod tests and one network test in the sandbox.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for 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 01e4cb7. Configure here.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 9, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[burn-down agent] Re-labeled Ready for review at 01e4cb70fe (main merge 03b9418, which cleared the #1031 conflict).

  • CI: all 466 check runs on the head are success/skipped (ci-ok green).
  • Bugbot: Cursor Bugbot passed on 01e4cb7; no unresolved review threads.
  • Mergeable, no CHANGELOG.md change. It needs a fresh human approval: 6773eaa landed after the earlier one.

Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-refactor PR opened by the scheduled architecture refactor routine Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

4 participants