Skip to content

Commit ca08f29

Browse files
committed
Merge main into fix/cargo-members-liveness-origin
Main's #2002 moved the hosted-origin helpers out of patch::redirect into crate::origin, and DiscoverCtx now holds an OriginPolicy instead of the raw origin list. Carry this PR's normalized_hosted_url split into origin.rs, point its liveness and foreign-origin checks at crate::origin::hosted_patch_uuid, and read the run's origins from ctx.origin.origins(). Co-Authored-By: Claude <noreply@anthropic.com>
2 parents d92dab4 + 568e376 commit ca08f29

226 files changed

Lines changed: 21550 additions & 7370 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.

‎.github/workflows/ci.yml‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ jobs:
208208
- name: Python — test native installer harnesses
209209
run: python3 -B -m unittest discover -s scripts/tests -v
210210

211+
- name: Rust — lock model size budget
212+
# Annotates, never fails: a bug fix elsewhere may add lines to these
213+
# files. The lock-model PRs lower the budget as they delete code
214+
# (docs/design/lock-model-unification.md#size-budget).
215+
run: python3 -B scripts/loc-budget.py --warn
216+
211217
- name: Shell — shellcheck the curl|sh installer
212218
# shellcheck is pre-installed on ubuntu-latest.
213219
run: shellcheck --shell=sh scripts/install.sh
@@ -2919,8 +2925,7 @@ jobs:
29192925
--ignored --nocapture --test-threads=4 2>&1 | tee hosted-e2e.log || status=$?
29202926
echo "::endgroup::"
29212927
if [ "$status" -eq 0 ]; then
2922-
# The vlt leg (probe-driven: the clean refusal while the artifact
2923-
# is content-encoded, the full install proof once it is not).
2928+
# The vlt leg: the hosted pin and the fresh-checkout install proof.
29242929
python3 scripts/check-vlt-legs.py \
29252930
--manifest crates/socket-patch-cli/tests/vlt-leg-manifest.json hosted-e2e.log
29262931
exit $?

‎.github/workflows/release.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,14 @@ jobs:
196196
197197
- name: Upload artifact (tar.gz)
198198
if: matrix.archive == 'tar.gz'
199-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
199+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
200200
with:
201201
name: socket-patch-${{ matrix.target }}
202202
path: socket-patch-${{ matrix.target }}.tar.gz
203203

204204
- name: Upload artifact (zip)
205205
if: matrix.archive == 'zip'
206-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
206+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
207207
with:
208208
name: socket-patch-${{ matrix.target }}
209209
path: socket-patch-${{ matrix.target }}.zip
@@ -251,7 +251,7 @@ jobs:
251251
sums-digest: ${{ steps.sums.outputs.digest }}
252252
steps:
253253
- name: Download all artifacts
254-
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
254+
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
255255
with:
256256
path: artifacts
257257
merge-multiple: true

‎.github/workflows/vlt-compatibility.yml‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ on:
7070
- 'crates/socket-patch-cli/src/commands/vendor.rs'
7171
- 'crates/socket-patch-cli/src/commands/vendored_backend/**'
7272
- 'crates/socket-patch-cli/src/commands/get.rs'
73-
- 'crates/socket-patch-cli/src/commands/vlt_preflight.rs'
7473
- 'crates/socket-patch-cli/src/commands/scan/**'
7574
- 'crates/socket-patch-cli/src/commands/vex*'
7675
- 'crates/socket-patch-cli/tests/common/**'
@@ -466,10 +465,10 @@ jobs:
466465
# minutes (EAI_NONAME) while the service is up; see the action.
467466
uses: ./.github/actions/pin-socket-hosts
468467
- name: Backtest against production
469-
# Every hosted cell probes the artifact first; it records
470-
# blocked-by-server-encoding only when that probe saw a non-identity
471-
# Content-Encoding and the CLI refused cleanly. Any other failure is an
472-
# error.
468+
# Every hosted cell probes the artifact first; a must-patch cell
469+
# records blocked-by-server-encoding (without running the CLI) only
470+
# when that probe saw a non-identity Content-Encoding. Any other
471+
# failure is an error.
473472
shell: bash
474473
env:
475474
VLT_TEST_VERSION: ${{ matrix.vlt }}

‎.github/workflows/vlt-serve-watchdog.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ name: vlt serve watchdog
33
# vlt hashes the wire body of a registry tarball and asks for
44
# `accept-encoding: gzip;q=1.0, identity;q=0.5`, so a patch artifact that
55
# patch.socket.dev (or its CDN) serves content-encoded fails `EINTEGRITY` on
6-
# every vlt release, and hosted mode refuses to pin it
7-
# (`redirect_vlt_artifact_unverifiable`). This job fetches the public free
6+
# every vlt release (hosted mode pins it without downloading it, relying on
7+
# the server's `Cache-Control: no-transform`). This job fetches the public free
88
# minimist artifact exactly that way and fails when the response is
99
# content-encoded or its sha512 differs from the API's integrity, which pages
1010
# through the repository's workflow-failure notification.

‎CHANGELOG.md‎

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,193 @@ a version without a non-empty section in this file.
2323

2424
## [Unreleased]
2525

26+
## [5.1.0] — 2026-11-06
27+
28+
### Added
29+
30+
- **RubyGems.**
31+
- **Agent mode patches gems with native (C) extensions for real.** When
32+
`apply` (or `scan` / `get --mode agent`) patches a gem whose patch changes
33+
native-extension sources (such as `ext/**/*.c` or an `extconf.rb`), it
34+
now rebuilds the gem's extensions with RubyGems' own builder, the step
35+
`gem pristine --extensions` runs, using the Ruby that owns the gem home.
36+
Both the copy under `extensions/<platform>/<abi>/` and the copy under the
37+
gem's `lib/` are rebuilt, so Ruby stops loading the stale install-time
38+
`.so` / `.bundle`. A build that fails puts the original sources and build
39+
back (`native_extension_build_failed`), and a copy that can't be rebuilt
40+
in place (a precompiled platform gem, a Bundler git checkout, no matching
41+
Ruby) is refused with `native_extensions_unsupported` before anything is
42+
written. Sources an earlier release patched without a rebuild are rebuilt
43+
on the next `apply` (`native_extension_rebuilt` warning). `vex` and
44+
`apply --check` attest such a patch only once its rebuild is recorded,
45+
and otherwise report `native_extension_not_rebuilt`. `rollback` and
46+
`remove` restore the original build. Callers that compile the extension
47+
themselves can opt out with `--no-gem-native-rebuild` (env
48+
`SOCKET_NO_GEM_NATIVE_REBUILD`): the sources are written without a
49+
rebuild, with a `native_extension_not_rebuilt` warning, and `vex` does
50+
not attest them. Hosted copies are unaffected, since RubyGems compiles
51+
the patched gem itself (#1996, #1998).
52+
53+
### Fixed
54+
55+
- **RubyGems.**
56+
- With Bundler 4.1 `override "other", with: "gem", in: "parent"`, hosted
57+
`rollback` and `remove` treat the override target as transitive and give
58+
back the original lock and Gemfile byte for byte, instead of writing a
59+
new exact `gem "gem", "x.y.z"` pin that blocked later upgrades (#1989,
60+
#1991).
61+
- Gemspec directives and development dependencies are read as Ruby code:
62+
`=begin`/`=end` blocks, heredoc bodies and `__END__` data are skipped, so
63+
a commented-out dev dependency no longer adds a bogus requirement and a
64+
heredoc no longer refuses the Gemfile (#1932, #1936).
65+
- A gem declared inside nested `source … do` blocks is attributed to the
66+
innermost block, as Bundler reads it, so hosted `rollback` and `remove`
67+
of a pin inside the user's own source block no longer refuse with
68+
`hosted_wiring_contested` on Bundler 2.1 and older (#1997, #1999).
69+
- **npm family.**
70+
- pnpm workspace globs with brace sets and character classes
71+
(`packages/{a,b}`, `packages/[ab]*`) are read the way pnpm reads them in
72+
every mode instead of being refused or read as every directory; shapes
73+
pnpm reads its own way (extglobs, `[!a]`, a `+` after a class, stepped or
74+
punctuation-spanning brace ranges) are still refused, and commented
75+
importer lines in `pnpm-lock.yaml` are ignored (#1846, #1863).
76+
- Quoted values, YAML escapes and duplicate keys in `pnpm-workspace.yaml`,
77+
`.yarnrc.yml` and `.modules.yaml` decode one way, as pnpm reads them, so
78+
settings such as `modulesDir` or `lockfileDir` no longer resolve to
79+
different paths depending on the command (#1918, #1973).
80+
- yarn classic's `.yarnrc` is read as yarn 1.22 reads the whole file:
81+
`--modules-folder 'deps'` no longer sends the crawler to a folder yarn
82+
never installs into, and a file yarn can't parse sets nothing (#1901,
83+
#1915).
84+
- A malformed `package.json` `workspaces` field (a non-string item, `null`,
85+
the wrong type) is judged the same way everywhere; the Bun member walk
86+
falls back to `bun.lock` instead of reading no members (#1900, #1971).
87+
- `apply` and `rollback` no longer touch package copies inside a store
88+
nested in another store's entry, which `scan` never reports, and keep
89+
the peer-variant copies of a project that lives under `~/.bun`,
90+
`~/.deno` or `~/.vlt` (#1899, #1986).
91+
- Hosted npm warns `redirect_npm_omit_lockfile_registry_resolved` when any
92+
npm config layer sets `omit-lockfile-registry-resolved`, which makes the
93+
next `npm install` drop the hosted URL and fail with `EINTEGRITY`, and
94+
names where it is set and the remedies (#1871, #1872).
95+
- Hosted vlt scans no longer download every granted patch archive to
96+
check its encoding, and no longer withhold dependencies with
97+
`redirect_vlt_artifact_unverifiable`; a mirror that re-encodes archives
98+
makes `vlt ci` fail closed with `EINTEGRITY`. The in-memory hosted
99+
engine (the Node addon and `hosted-bundle`) now pins vlt dependencies
100+
instead of withholding them as offline (#2013).
101+
- The lock inventory skips Rush subspace locks with unsafe names, as
102+
lockfile discovery already did (#2003).
103+
- **PyPI.**
104+
- A requirements line pinned through an environment variable
105+
(`six==${SIXV}`) is refused by `vendor` with
106+
`pypi_requirement_env_templated`, and `vendor --check` and `vex` read it
107+
as possibly installing any release, so the patch is no longer attested
108+
while `pip install -r` can install the unpatched one (#1873, #1874).
109+
- A hosted scan of a Python project with no lockfile the rewriters read now
110+
warns `redirect_pypi_no_lockfile`, naming the files looked for and the
111+
project's own lock command, instead of passing silently (#638, #1885).
112+
- After a hosted rollback, a vendored rollback or `vendor --revert` of a
113+
requirements-file pin, the reinstall advisory covers pip and names the
114+
requirements files to reinstall from (#1953, #1954).
115+
- The hosted Pipenv stale-install warning ends with the same runnable
116+
remedy as vendored mode and never prints an option-like package name
117+
into a shell command (#1878, #1883).
118+
- A `poetry.lock` in an old format (0, 1.0, 1.1) keeps its "written by
119+
Poetry < 1.4" warnings and refusals even when a hand-merged header claims
120+
a newer Poetry (#1847, #1865).
121+
- Hosted `rollback`, `remove` and `scan` restore the pins hosted mode
122+
writes into uv 0.2 `[[distribution]]` locks (uv < 0.2.35) instead of
123+
refusing them (#2014).
124+
- **Go.**
125+
- In a go 1.16 (unpruned) module where a dependency imports a fork that
126+
the root `go.mod` replaces with the patched module, `apply`,
127+
`apply --check`, hosted mode and `vex` read the module graph to tell
128+
whether the patch is really built, instead of reporting it applied
129+
while `go build` linked the unpatched code (#1840, #1843).
130+
- `vex` reads the `go.work` that governs the project (`GOWORK`, else the
131+
nearest one at or above it, with members anywhere), as hosted and
132+
vendored modes already did, and no longer attests a Socket replace the
133+
workspace keeps out of the build (`go_workspace_override`) (#2011).
134+
- **JVM.**
135+
- A Maven 4 root that builds its subdirectories implicitly (model 4.1.0,
136+
`pom` packaging, no `<subprojects>`) is treated as a reactor by hosted
137+
mode, `vex` and the Maven cache scope, not only by vendored mode, so a
138+
root-only pin is no longer attested while a module keeps its own
139+
version (#1809, #1886).
140+
- Hosted Maven keeps every line of `.mvn/checksums/checksums.sha256` it
141+
doesn't own (single-space or `*` sha256sum lines, tabs, comments) and
142+
the file's line endings, instead of silently dropping them (#2016).
143+
- Vendored Maven `vex` no longer attests a build that may still use the
144+
unpatched jar: an executable classifier copy of the patched artifact,
145+
or a suffixed version left only in a plugin, profile or unused property,
146+
now withholds attestation (#2006).
147+
- Vendored Gradle withholds attestation when a `gradle.lockfile` locks
148+
the patched artifact at another version
149+
(`gradle_lock_overrides_vendored`) or a custom `lockFile` location is
150+
used (`gradle_custom_lock_file`) (#2004).
151+
- sbt: `vex` no longer attests a hosted pin that a build reassignment of
152+
`dependencyOverrides` or `resolvers`, `sbt.override.build.repos=true`,
153+
or newer resolution evidence shows the build doesn't apply
154+
(`vex_sbt_pin_bypassed`) (#2030), nor a vendored pin without current
155+
sbt resolution evidence or with its vendored tree missing
156+
(`vex_sbt_resolution_unverified`, `vex_sbt_vendored_tree_missing`)
157+
(#2008).
158+
- **NuGet.** When a `packages.lock.json` locks a patched package at a
159+
version the writers refuse to wire (another target framework or
160+
project), `vex` no longer attests that version
161+
(`vex_nuget_lock_other_version`); `1.0` and `1.0.0` count as one version
162+
(#2007).
163+
- **Composer.** A `composer.lock` with a UTF-8 BOM is read everywhere,
164+
and vendor then `--revert` keeps the BOM byte for byte; a revert no
165+
longer deletes a vendored artifact such a lock still installs from
166+
(#2017).
167+
- **Vendoring.**
168+
- Vendored dry runs leave already-vendored patches out of the "Would
169+
download and vendor" headline and list them as skipped, matching the wet
170+
run and the JSON (#1850, #1856).
171+
- Run from a workspace member with no lockfile of its own, a vendored
172+
`scan`, `get` or `vendor` names the lock that installs the member and
173+
where to run from (#1904, #1913).
174+
- npm package-lock packages installed from a URL or git spec, and workspace
175+
members, are refused before their patch is downloaded; dry runs preview
176+
them as refused and they no longer hold a `--max-new-patches` rollout
177+
slot (#1976, #1977).
178+
- In a vlt project, `vendor` no longer requests service downloads for
179+
packages it then refuses (#1909, #1947).
180+
- Every vendored entry point (`scan` previews and rollout plans, the
181+
download phase, `get`, and `vendor`) applies the same refusals before
182+
any download: a v1 `package-lock.json` project, or a hosted pnpm pin
183+
whose takeover would be refused, is refused before its patch is
184+
fetched; `get <uuid> --mode vendored` reports every such refusal and
185+
writes nothing; and `vendor` refuses before restoring a hosted pin
186+
instead of restoring it and rolling back. Codes and details are
187+
unchanged (#2015).
188+
- A vendored revert keeps an artifact the lock still references through
189+
an escaped path spelling (`\/` in an older `composer.lock`, Windows
190+
backslashes) instead of deleting it (#2022).
191+
- **General.**
192+
- The nested-project remedy quotes its path for the shell it prints for,
193+
including Windows and `%` (#1859, #1884).
194+
- Patch and vendor download errors read the same on every path (size
195+
limit, HTTP status with a bounded body excerpt), and artifact downloads
196+
log under `--debug` (#1869, #1870).
197+
198+
### Maintenance
199+
200+
- Code consolidation with no output change: one lock-rewrite driver for
201+
Poetry and PDM (#1898) and module sweeps across the CLI and core
202+
(#1855, #1864, #1875, #1884, #1892, #1897, #1903, #1907, #1914, #1920,
203+
#1923, #1929, #1939, #1948, #1967, #1975, #1985, #1990).
204+
- Test and CI infrastructure: shared test env guard, docker harness, PTY
205+
runner, `copy_tree` and apply fixtures; hermetic children scrub color
206+
variables; failing tests are annotated in CI; offline bun.lockb rollback
207+
mock and a Windows venv layout in the PyPI fixture (#1891, #1890, #1905,
208+
#1944, #1955, #1964, #1972, #1978, #1988, #1994, #2000); release
209+
workflow artifact steps move off Node 20 actions (#2027). A design doc
210+
and line-count budget plan one lock model for every lockfile reader
211+
(#2001).
212+
26213
## [5.0.1] — 2026-10-13
27214

28215
### Fixed

‎Cargo.lock‎

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

‎Cargo.toml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ default-members = [
1414
resolver = "2"
1515

1616
[workspace.package]
17-
version = "5.0.1"
17+
version = "5.1.0"
1818
edition = "2021"
1919
license = "MIT"
2020
repository = "https://github.com/SocketDev/socket-patch"
2121

2222
[workspace.dependencies]
23-
socket-patch-core = { path = "crates/socket-patch-core", version = "=5.0.1" }
23+
socket-patch-core = { path = "crates/socket-patch-core", version = "=5.1.0" }
2424
clap = { version = "=4.5.60", features = ["derive", "env"] }
2525
serde = { version = "=1.0.228", features = ["derive"] }
2626
serde_json = { version = "=1.0.149", features = ["preserve_order", "raw_value"] }

0 commit comments

Comments
 (0)