Skip to content

Require server artifacts and exact redownload for vendoring - #300

Merged
Mikola Lysenko (mikolalysenko) merged 6 commits into
release/v5-prereleasefrom
codex/server-only-vendoring
Sep 30, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 6 commits into
release/v5-prereleasefrom
codex/server-only-vendoring

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Vendoring now downloads complete server artifacts. Missing or damaged committed artifacts are redownloaded only when their bytes or complete directory inventory match the existing ledger; repair preserves lockfiles and ledger identity.

Based on #277, including the latest v5 Maven reactor and Gradle changes. Companion server PR: depscan#27070.

  • Remove local npm/wheel/NuGet/JAR repacking, the vendoring blob/diff staging pipeline, registry source acquisition, and local-build fallbacks. service is the default; auto is an alias and build is rejected.
  • Verify transfer integrity and patched members before committing server artifacts. Record complete inventories for new directory artifacts, including Cargo and Go. Refuse changed archives, changed inventories, or missing identity records without rewriting the existing project state.
  • Obtain upstream Yarn Berry cache checksums from depscan, eliminating the CLI's remaining production cache ZIP builder.
  • Retain socket-patch-node N-API and hosted in-memory patch application for the future GitHub App. Agent patch application remains supported.
  • Migrate vendoring fixtures to served artifacts and cover offline reuse, redownload, failed repair, lockfile preservation, package-manager installs, and crash recovery.

Validation: workspace Clippy with warnings denied; 87 Composer tests and six exact-redownload tests, including fresh Composer inventory persistence and Go service failures; both Yarn 4 suites and 103 in-process vendoring tests; real vlt, Maven, Ruby, uv, Hatch, PDM, pip, pipenv, Poetry, and Bun compatibility tests (1.4.2 and 1.1.45); Docker npm, Composer, Maven, Ruby, and Python lifecycle tests. Linux CI verifies NuGet: Docker Desktop on this case-insensitive macOS volume reports stale stat results for deleted NuGet.config aliases. Earlier N-API validation rebuilt the addon and passed all 14 smoke tests. The full CI matrix is running on the latest commit.

Rollout: deploy the companion depscan migration, converter/backfill, and upstream metadata endpoint before this CLI. Berry rollback requires that metadata to be ready. Old locally built archives that differ from the server artifact, or legacy directory ledgers without an inventory, cannot be repaired by guessing new identity: restore them from version control or revert and explicitly vendor again.


Note

High Risk
This is a breaking vendoring model change (no offline/local rebuild path) that touches lockfile integrity, repair, and all ecosystem vendor flows; mis-deployed server artifacts or legacy locally-built vendor trees can fail closed until re-vendored.

Overview
Vendoring is server-only: --vendor-source defaults to service, auto is a compatibility alias, and build is rejected at parse time. The CLI contract and help text drop pristine-registry fetches, local patch application to vendor trees, blob/diff staging, and auto→local fallback ladders in favor of downloading integrity-verified patched archives from the patch service.

scan/get --mode vendored still fetch patch records in memory but no longer seed a blob map for the vendor step (DetachedDownload loses the blob HashMap; .socket/blobs is not written on detached download). repair language and behavior are framed as exact same-UUID redownload (human “Redownloaded”, stricter ledger fingerprint checks) rather than rebuilding from installed copies or lockfile-verified pristine sources. Docs also note Berry cache checksums and hosted rollback metadata come from the server, not CLI-built cache zips.

Dev dependency adds test-fixtures on socket-patch-core for updated vendoring tests.

Reviewed by Cursor Bugbot for commit 50af61b. Configure here.

Download verified complete packages instead of rebuilding archives from
installed files, patch blobs, or registry sources. Repair damaged vendor
copies from the exact recorded server artifact without changing lockfile
or ledger identity.

Retain the N-API crate and hosted in-memory patch application engine for
the GitHub App. Consume server-provided upstream Yarn Berry checksums and
preserve the latest v5 Maven reactor and Gradle support.

Assisted-by: Codex:GPT-6
Regenerate the vlt matrix after replacing its local-build leg with the
service alias. Remove orphaned builder documentation and retain the
existing backend argument style for Python distribution downloads.

Assisted-by: Codex:gpt-6-astra
Use fixture grants for fresh vendoring and redownload repairs. Match the
installed npm version when building fixture archives so a workspace's
different top-level version cannot replace its nested dependency.

Assisted-by: Codex:gpt-6-astra
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Claude (@claude) review

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review

@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.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

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

  • ✅ Fixed: Composer vendors omit file inventory
    • Added compute_dir_inventory call to persist file_inventory for Composer vendor artifacts, enabling directory repair and same-UUID vendor restore.

Create PR

Or push these changes by commenting:

@cursor push cf4d89f6e2
Preview (cf4d89f6e2)
diff --git a/crates/socket-patch-core/src/vendor/composer_lock.rs b/crates/socket-patch-core/src/vendor/composer_lock.rs
--- a/crates/socket-patch-core/src/vendor/composer_lock.rs
+++ b/crates/socket-patch-core/src/vendor/composer_lock.rs
@@ -435,7 +435,16 @@
     let marker = VendorMarker::new("composer", &base_purl, record, vendored_at);
     write_marker_or_warn(&uuid_dir, &marker, &mut warnings).await;
 
-    let entry = VendorEntry {
+    let file_inventory = match super::verify::compute_dir_inventory(&copy_dir).await {
+        Ok(inventory) => inventory,
+        Err(error) => {
+            let _ = remove_tree(&uuid_dir).await;
+            prune_empty_vendor_dirs(&copy_dir).await;
+            return refused("vendor_inventory_unavailable", error);
+        }
+    };
+
+    let mut entry = VendorEntry {
         ecosystem: "composer".to_string(),
         base_purl,
         uuid: record.uuid.clone(),
@@ -466,6 +475,7 @@
         pdm: None,
         pipenv: None,
     };
+    entry.artifact.file_inventory = Some(file_inventory);
 
     done(result, Some(entry), warnings)
 }

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

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 50af61b. Configure here.

Comment thread crates/socket-patch-core/src/vendor/composer_lock.rs
Comment thread crates/socket-patch-core/src/vendor/redownload.rs Outdated
Exercise served artifacts across the package-manager fixtures while
preserving cold-cache offline install and revert coverage. Repair keeps
Bun lockfiles and artifact identities unchanged.

Record complete Composer inventories after filter normalization, and
use the shared service policy for archive and Go redownload failures.

Assisted-by: Codex:gpt-6-astra
Check that restoring modified filter files preserves the complete

artifact inventory, lockfile, and ledger without in-place healing.

Assisted-by: Codex:gpt-6-astra
Composer vendors now compute and persist file_inventory at vendor time,
matching the behavior of Cargo, Go, gem, and vlt. This enables directory
repair and same-UUID vendor restore for Composer packages, preventing
redownload::restore from failing on missing inventory data.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit 40957fb into release/v5-prerelease Sep 30, 2026
4 of 9 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the codex/server-only-vendoring branch September 30, 2026 14:38
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Sep 30, 2026
The #300 squash kept both Composer file-inventory fixes: one before
the lock rewrite and one after the marker write. The second rebound
an already-moved value, so socket-patch-core failed to compile and
every Rust CI job went red.

Keep the pre-rewrite inventory. It runs after filter normalization,
and a failure there refuses before composer.lock is touched. The
marker lives in the uuid dir, outside the inventoried copy, so the
result is the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3KCWT9B1MUVPrgerxxGpK
Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Sep 30, 2026
#300 made the ledger-less vendored `scan --vex` cell expect a
`vendor_ledger_entry_missing` refusal. yarn < 1.7 installs nothing for
a vendored `file:` entry, so that scan finds no package to vendor and
attests from the lockfile instead, failing the yarn-classic 1.0.2 and
1.6.0 legs. Gate the expectation on installs_file_tarballs and pin the
older releases' shape (zero scanned packages, attested).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEUik3Qo9HQtYGVEAMs1Di
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Sep 30, 2026
#300 added .zip to artifact_is_file_shaped for pypi sdists. A vlt package
dir path ends in the npm package name, so a package such as lodash.zip
stopped being recognized as a vlt dir: its health check took the generic
dir branch, which refuses the dependency links under its node_modules,
and restore took the file branch and refused for want of an archive
SHA-256.

is_vlt_dir_entry now also accepts a path in the vendored vlt dir layout
(<name>-<version>/node_modules/<name>), whatever its suffix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEUik3Qo9HQtYGVEAMs1Di
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Sep 30, 2026
Ledgers written before #300 record no file inventory for cargo, Go and
composer copies, and a copy past the inventory cap records none either.
Exact restore refuses such an entry, and vendor sent every same-uuid
entry that was not healthy to that same restore, so the re-vendor the
error suggested failed with vendor_redownload_failed on every run.

A dir-shaped entry without an inventory now skips the exact restore and
goes to the backend, which rebuilds the copy from a fresh verified
download as vendor did before #300. The file-shaped entry without a
SHA-256 still refuses. Both restore refusals now name the remedy that
records a new fingerprint: vendor --revert and then vendor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEUik3Qo9HQtYGVEAMs1Di
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Sep 30, 2026
#300 sent every same-uuid ledger entry that was not healthy to exact
redownload before the backend ran. That includes a bun.lockb workspace
whose member-relative mirror tarball is missing or stale while the
canonical tarball still matches its ledger SHA-256. Offline, the
redownload failed with vendor_redownload_failed and skipped the backend,
which would have rewritten the mirror from the committed tarball; online
it downloaded an artifact the project already held.

A workspace mirror issue over a canonical tarball with a recorded
SHA-256 now goes straight to the backend, as repair also handles it
locally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEUik3Qo9HQtYGVEAMs1Di
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant