Skip to content

Commit 09e0050

Browse files
committed
Merge main into feat/vlt-support
Brings in #257 (concurrent API requests, parallel crawl, single-pass rewriters) and fits vlt support into its new structure with the same output bytes, warnings and ledger edits. - Hosted rewriters: the vlt rewriter is its own group in the parallel rewriter groups, right after the npm-family group, so edits and warnings keep the serial order. It gets the overrides minus the vlt-withheld uuids; vlt_drives is set once after the merge, and the group merge carries the vlt uuid sets. The group equivalence oracle now includes vlt (and a bun.lockb case). The hosted rewrite runs on the blocking pool with the vlt withholding. The confirmation probe searches a withheld dep's needles in every final text except vlt-lock.json, so the one-pass presence check still skips the stale vlt pin. - Crawler: the `.vlt` store is walked by the new parallel scan (after the pnpm stores) and by the level-by-level resolver. Store entries carry their vlt- or pnpm-decoded name. Inside a store entry only real package dirs match, and a store copy an importer link already resolves to is not added again. The peer-variant finder is find_store_peer_variant_copies again. The sequential oracle gets the same vlt changes, and its random trees now include vlt stores. - Vendored: vendor_vlt and stage_patch_dir take a PackageSource (lazy or deferred pristine sources). The download plan gets a vlt pre-flight (flavor change, lock analysis, wiring plan). The committed vlt dir artifact is staged in the new missing-purl local rung, only at the record's uuid. Links to vlt's own vendored dir are still dropped as pristine sources. strict tar extraction is threaded through walk_tar_gz. get's view prefetch skips vlt-refused purls. - Under the group commit, a failed vlt-lock.json write is now vendor_commit_failed with nothing committed (the test is updated to that contract). Assisted-by: Claude Code:claude-opus-5-5
2 parents ff2ceb8 + 8c381ec commit 09e0050

192 files changed

Lines changed: 54048 additions & 4461 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitattributes‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ crates/socket-patch-core/tests/fixtures/vlt-locks/** -text
1616

1717
# The vendored vlt fixtures pin locks real vlt wrote, byte for byte.
1818
crates/socket-patch-core/tests/fixtures/vendor/** -text
19+
20+
# The legacy vendor ledgers are what the base binary wrote, byte for byte:
21+
# vendor_ledger_schema_e2e replays them through `vendor --revert` and
22+
# compares the result byte for byte, so a CRLF checkout would change both
23+
# the replayed wiring files and the expected revert.
24+
crates/socket-patch-cli/tests/fixtures/legacy-ledgers/** -text

‎CHANGELOG.md‎

Lines changed: 337 additions & 2 deletions
Large diffs are not rendered by default.

‎Cargo.lock‎

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,20 @@ sha1 = "=0.10.6"
2121
hex = "=0.4.3"
2222
reqwest = { version = "=0.12.28", features = ["rustls-tls", "json"], default-features = false }
2323
tokio = { version = "=1.50.0", features = ["full"] }
24+
futures-util = { version = "=0.3.32", default-features = false, features = ["std"] }
2425
thiserror = "=2.0.18"
2526
walkdir = "=2.5.0"
2627
uuid = { version = "=1.21.0", features = ["v4"] }
2728
console = "=0.15.11"
2829
dialoguer = "=0.11.0"
2930
tempfile = "=3.26.0"
3031
regex = "=1.12.3"
32+
aho-corasick = "=1.1.4"
3133
glob = "=0.3.4"
3234
toml_edit = "=0.25.12"
3335
once_cell = "=1.21.3"
3436
qbsdiff = "=1.4.4"
37+
rayon = "=1.12.0"
3538
tar = "=0.4.46"
3639
flate2 = "=1.1.9"
3740
zip = { version = "=8.6.0", default-features = false, features = ["deflate"] }

‎README.md‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,40 @@ warning — it never breaks a command or pollutes `--json` output. `socket-patch
550550
cloned repo must never be able to redirect where patches come from or spend your token.
551551
(Full rationale: [docs/design/configuration.md](docs/design/configuration.md).)
552552
553+
One more env-only knob tunes *pacing* rather than routing. `scan` queries the patch API
554+
with several requests in flight: against the authenticated endpoint, a quarter of the
555+
requests a step has to make, between 8 and 32 (so a step with 128 or more requests runs
556+
32 at once, one with 32 or fewer runs 8); against the public proxy, which shares one
557+
server-side limit across anonymous callers, 4. The patch-record fetches behind `vex` and
558+
`scan --vex` run up to 10 at once (4 on the proxy).
559+
`SOCKET_API_CONCURRENCY=<n>` overrides that, clamped to `1`-`32`; on the public proxy it
560+
can only lower it. Set it when an endpoint in front of the API caps in-flight requests
561+
per client — a self-hosted `--api-url`, a corporate reverse proxy, a WAF or a CDN — and
562+
a scan starts reporting fewer patches than it should because some requests are being
563+
rejected. `SOCKET_API_CONCURRENCY=1` sends one request at a time, the slowest and most
564+
conservative setting. An unset, empty or non-numeric value leaves the defaults in place.
565+
566+
A throttled patch API is retried, within bounds. An HTTP `429` or `503` answer to any
567+
patch-API query (batch search, patch lists, patch views, VEX record fetches, hosted
568+
package references) is retried up to 3 times, waiting as long as the server's
569+
`Retry-After` asks (seconds or an HTTP date; a request asked to wait more than 30 s gives
570+
up at once) or, without one, 0.5 s, 1 s, 2 s with jitter. All retries in one run must
571+
finish within 60 s of the run's first retry (wall-clock: requests waiting in parallel
572+
don't add up), so a heavily throttled run gives up instead of hanging. `SOCKET_API_MAX_RETRIES=<n>` changes
573+
the per-request count (`0`-`10`; `0` turns retries off). Other errors are never retried.
574+
A query still throttled after its retries is reported, never dropped: a failed batch
575+
prints `Warning: API batch <n> of <total> failed: …` (under `--json`, a top-level
576+
`warnings[]` entry with code `api_batch_failed`), a failed patch-list lookup prints
577+
`Warning: could not fetch details for <purl>: …` (`--json`: `patch_details_failed`), and
578+
if every query fails the scan exits 1 with an error, as before.
579+
580+
The crawl has a pacing knob too. Its directory walks (`node_modules`, and the Maven
581+
repository with its POM parse) run on a small pool of threads: 4 by default (fewer on a machine with fewer performance cores), because the walk is bound
582+
by the kernel's directory cache and more threads only add system time.
583+
`SOCKET_WALK_THREADS=<n>` overrides that, clamped to `1`-`16` and to the machine's CPU
584+
count; an unset, empty or non-numeric value leaves the default in place. A soft open-file
585+
limit below 128 still runs the walk on one thread, whatever the knob says.
586+
553587
The sections below list only each command's **command-specific** flags.
554588
555589
### `scan`
@@ -585,7 +619,7 @@ socket-patch scan [options]
585619
| `--mode <hosted\|vendored\|agent>` | — | Selects one of the three [patch modes](#three-patch-modes), summarized above. Combining `--mode` with a legacy boolean flag of a *different* mode is an error (exit 2); the same mode spelled both ways is accepted. |
586620
| `--prune` | — | Garbage-collect after the scan: remove manifest entries for packages no longer present in the crawl (installed trees + lockfiles — a wiped `node_modules` alone doesn't prune lockfile-listed entries) and delete orphan blob/diff/package-archive files. Off by default. [Vendored](#vendor) packages are exempt from the crawl-based prune (an absent installed copy is their normal state), but a vendored entry whose dependency has left the lockfile is reverted (and any manifest entry it still had dropped). Orthogonal to `--mode` — combines with any mode. |
587621
| `--detached` | — | Hidden compatibility no-op. Vendored mode is manifest-free by default: the vendor ledger (`.socket/vendor/state.json`) embeds the patch records and `.socket/manifest.json` is never written, so this former opt-in changes nothing. Still an error without `--mode vendored`. |
588-
| `--batch-size <n>` | `SOCKET_BATCH_SIZE` | Packages per API request (default: `100`). |
622+
| `--batch-size <n>` | `SOCKET_BATCH_SIZE` | Packages per API request (default: `500` on the authenticated API, `100` on the public proxy). A request whose body would exceed 256 KiB is split into smaller ones. |
589623
| `--all-releases` | `SOCKET_ALL_RELEASES` | Store patches for every release/distribution variant, not just the installed one — PyPI wheel/sdist, RubyGems platform, Maven classifier. Makes the manifest portable across environments (e.g. cross-platform CI caches). |
590624
| `--vex <path>` | `SOCKET_VEX` | On a successful scan, also write an OpenVEX 0.2.0 document to this path. See [Inline VEX generation](#inline-vex-on-apply--scan--vendor). |
591625
| `--vex-product`, `--vex-no-verify`, `--vex-doc-id`, `--vex-compact` | `SOCKET_VEX_*` | Passthrough to the embedded VEX builder; mirror the standalone [`vex`](#vex) knobs. Inert unless `--vex` is set. |

0 commit comments

Comments
 (0)