Fix Windows (yarn berry CRLF support) and first-run real-PM CI failures after #251 - #253
Merged
Mikola Lysenko (mikolalysenko) merged 20 commits intoSep 25, 2026
Merged
Conversation
Wenxin Jiang (Wenxin-Jiang)
approved these changes
Sep 24, 2026
Mikola Lysenko (mikolalysenko)
added a commit
that referenced
this pull request
Sep 24, 2026
…ee ledger The poetry vendored capstone (added in #251, written before its rebase onto #247) still asserted `scan --vendor` writes `.socket/manifest.json`. Since #247 vendored mode is manifest-free (CLI_CONTRACT `scan --vendor`): the run writes only `.socket/vendor/**`, and each ledger entry is `detached: true` with the patch record embedded. The assertion therefore failed on every Poetry release in the CI matrix the first time the leg actually ran (#253). Assert the contract instead: no manifest is written, and the ledger entry for the vendored uuid is detached and embeds its record. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On Windows env var names are case-insensitive: run_isolated blanks NPM_CONFIG_ALLOW_REMOTE before the test sets npm_config_allow_remote=none, so the child sees a single variable under the first spelling and the warning (which names the variable as the OS reports it) says NPM_CONFIG_ALLOW_REMOTE=none. The product is right; the assertion was POSIX-only. Fixes outer_npm_config_layers_are_respected on test (windows-latest) after #251. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The cargo-vex-matrix windows-latest leg used the default pwsh shell, where "$CARGO_TEST_TOOLCHAIN" is an unset PowerShell variable, so it ran `rustup toolchain install ""` and failed. The leg was skipped on #251's own CI, so this is its first real run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ee ledger The poetry vendored capstone (added in #251, written before its rebase onto #247) still asserted `scan --vendor` writes `.socket/manifest.json`. Since #247 vendored mode is manifest-free (CLI_CONTRACT `scan --vendor`): the run writes only `.socket/vendor/**`, and each ledger entry is `detached: true` with the patch record embedded. The assertion therefore failed on every Poetry release in the CI matrix the first time the leg actually ran (#253). Assert the contract instead: no manifest is written, and the ledger entry for the vendored uuid is detached and embeds its record. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… work under CI
yarn 3 and later turn enableImmutableInstalls on by default when ci-info
detects CI (CI / GITHUB_ACTIONS). With that default, the plain
`yarn install` that writes each fixture's first yarn.lock fails with YN0028
("The lockfile would have been created by this install, which is
explicitly forbidden"): exit 1, nothing on stderr. Every hosted, vendored,
pnpm-linker, workspaces and yarn-3 refusal fixture on the new yarn-berry
legs (4.0.2, 4.1.0, 4.6.0, 4.12.0 ubuntu+macOS, 4.18.0) failed that way. The
yarn 2 refusal legs passed because yarn 2 keeps the default off. The suites
were never run under CI before #251 added the legs; the main test job
soft-skips them.
yarn_berry_common::pin_berry_ci_defaults now sets CI=true (local runs get
the runner's defaults) and YARN_ENABLE_IMMUTABLE_INSTALLS=false. It is
applied in every berry suite's corepack helper, after the YARN_* scrub and
cache_env::isolate. The fresh-checkout installs still pass --immutable
explicitly, and yarn's flag outranks the setting, so lock enforcement is
unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Node ships corepack on Windows as the corepack.cmd batch shim, and
Command::new("corepack") only resolves corepack.exe. On the
windows-latest yarn-berry leg every suite's availability probe therefore
reported "`corepack yarn@4.12.0` unavailable" (yarn@2.4.3 / 3.8.7 in the
refusal suite), and SOCKET_PATCH_YARN_E2E_REQUIRED=1 turned each of those
into a failure.
yarn_berry_common::corepack_command() picks the spawnable name.
Every berry suite's has_corepack_pm probe and corepack helper uses it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
yarn berry prints its errors (YN0028, YN0018, …) on stdout and leaves stderr empty. The fixture and bootstrap skip messages printed only stderr, so all 11 failures on each yarn-berry CI leg read "fixture `yarn install` failed (registry unreachable?):" followed by nothing. The real cause was YN0028 under CI's implicit immutable default. yarn_berry_common::yarn_output formats both streams, and every berry fixture/bootstrap skip now uses it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Ruby 3.1 legs pinned to bundler 2.1.4 and 2.2.33 never ran those
bundlers. setup-ruby's `bundler:` input only `gem install`s the release;
with no lockfile to read, RubyGems' `bundle` binstub then activates the
HIGHEST installed bundler, which on Ruby 3.1.7 is its default gem 2.3.27.
tests/common/bundler_e2e.rs correctly panicked on every test ("bundle on
PATH is 2.3.27"). The 1.17.3 legs passed only because the Bundler 1.x
step already exported BUNDLER_VERSION.
Export BUNDLER_VERSION for every pinned-bundler leg (a new step after the
1.x install), which makes the binstub pick exactly the pinned release in
every process and also turns off bundler >= 2.3's lockfile-driven
self-switch. Verified locally in Docker (Ruby 3.1.7 / 3.3.10 / 3.4.9,
setup-ruby layout): all 16 e2e_{redirect,vendor}_gem_build legs and the
setup_matrix_gem leg green with the export; the 2.1.4/2.2.33 legs fail
exactly as in CI without it. The harness panic now names the fix.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The real-deno negative capstone asserted that `scan --mode vendored` "left a manifest" for the patch it could not wire, then checked that the unapplied manifest attests nothing. Vendored mode is manifest-free: its download phase is detached (download_patch_records_with writes nothing; the vendor ledger alone carries records), and a vendor step refused with vendor_lockfile_missing records nothing. So the assertion failed on the first CI run of both deno legs (1.46.3, 2.9.7) at deno.rs:454. Assert the real contract instead: the download is detached, no ledger entry names the package, and there is nothing to attest (no manifest, exit 2 manifest_not_found, zero patch-API requests). The "unapplied manifest patch attests nothing" check moves to step 4, where the test stages the manifest itself, before `apply --vex` runs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The macOS hatch 1.18.1 leg failed all four cases with `".../private/var/.../six.py" outside "/var/.../app"`. The hatch bootstrap venv is built on the runner's actions/setup-python CPython, a macOS framework build, and a framework interpreter realpaths `sys.prefix` — so `six.__file__` names `/private/var/folders/...` while `hatch env find` echoes the `/var/folders/...` spelling of the same temp dir. Linux legs (and a uv-managed standalone Python locally) keep one spelling, which is why only the macOS leg tripped. Canonicalize both sides for the containment check only; the env dir handed on as VIRTUAL_ENV is unchanged. Reproduced locally by bootstrapping hatch 1.18.1 on Homebrew's framework CPython (4/4 fail before, 4/4 pass after). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…aptop The ubuntu Maven 4.0.0-rc-6 leg of e2e_vendor_maven_build failed at the TAMPER probe: Maven rejected the tampered file:// jar and built Central's pristine one (the load-bearing assertion held), but the output carried no "checksum" line, so "the file:// copy was rejected on its checksum" tripped. The CI dump shows no transfer lines at all, not even the Central download that must have happened after the purge. Root cause: Maven 4's CIDetectors (generic CI, GITHUB_ACTIONS, CIRCLECI, Jenkins WORKSPACE, TEAMCITY_VERSION, TRAVIS) make MavenInvoker pick the QuietMavenTransferListener whenever a CI is detected and --force-interactive is absent, even under -B. That listener drops both "Downloading from ..." and the "Checksum validation failed" warning. Maven 3 has no such detection, so only the 4.x legs log differently on a GitHub runner (and only this probe greps a warning a successful build prints; the redirect suite's checksum greps are on failed builds, whose exception text survives the quiet listener). Scrub those markers (plus the Maven config vars run() already dropped) in one mvn_command() used by both detect() and run(). --force-interactive was rejected: it flips the run interactive (progress-bar listener) and Maven 3 refuses the flag. The checksum assertion is unchanged. Repro: CI=true GITHUB_ACTIONS=true on the unfixed tree reproduces the CI panic at e2e_vendor_maven_build.rs:353 locally; with the fix both e2e_vendor_maven_build and e2e_redirect_maven_build pass under the same env on Maven 4.0.0-rc-6 and 3.9.16. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… PAL race
The ubuntu SDK 9 leg failed nuget_vendored_dotnet_restore_then_manifestless_vex
at its first fixture restore (the hosted test passed):
System.IO.IOException: The system cannot open the device or file
specified. : 'NuGet-Migrations'. One or more system calls failed:
mkdir("/tmp/.dotnet/shm/session2027", AllUsers_ReadWriteExecute) == -1;
errno == EEXIST;
at System.Threading.Mutex..ctor ...
at NuGet.Common.Migrations.MigrationRunner.Run ...
at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.Configure()
Both tests run in parallel, each with a fresh HOME, so each first
`dotnet restore` runs the first-use NuGet migrations under the named
mutex `NuGet-Migrations`. On a fresh runner `/tmp/.dotnet` does not
exist yet, and the .NET 9 runtime's named-mutex setup races when two
processes create the shared-memory tree at once: the loser's session
directory mkdir fails with EEXIST. Environment/tool race (SDK 9 PAL),
exposed by the harness running two SDK processes concurrently.
Reproduced in mcr.microsoft.com/dotnet/sdk:9.0 (9.0.318, the leg's SDK)
with two concurrent first-run CLI commands per round, fresh HOMEs,
`/tmp/.dotnet` wiped before each of 60 rounds: 9, 0, 2 and 7 of 120
processes died with the exact CI message across four batches; 0/120 with
the root pre-created and 0/40 rounds run one at a time.
Hold one binary-wide lock around every `dotnet` spawn (the --version
probe and every restore). Only the SDK phases serialize; the
socket-patch runs between them stay parallel. No assertion changes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
yarn 4 enables hardened mode when it detects a GitHub Actions run for a public pull request and then re-resolves every lock entry against the registry. The fresh-checkout installs point the registry at an unreachable address on purpose, so the hosted berry suites failed with ECONNREFUSED 127.0.0.1:1 on PR runs only (seen in the coverage job once the fixture installs stopped failing). Reproduced locally with a simulated public-PR event: 3 failures without the pin, 11/11 with it. --immutable --check-cache still verifies every checksum. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The previous commit pinned YARN_ENABLE_HARDENED_MODE=false for every berry suite, including e2e_yarn_legacy_cachekey_refusal_build, which drives yarn 2.4.3 and 3.8.7. Those releases predate hardened mode and refuse every command while the variable is set: Usage Error: Unrecognized or legacy configuration settings found: enableHardenedMode so all four refusal cells failed at their fixture install under SOCKET_PATCH_YARN_E2E_REQUIRED=1 — how the yarn-berry-e2e job runs the suite — and soft-skipped everywhere else. pin_berry_ci_defaults now takes the yarn spec and pins hardened mode off for yarn 4+ only, removing the variable for yarn 2/3. Reproduced locally: 4/4 cells fail with the Usage Error before, 4/4 pass after. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…exactly yarn berry writes a file it creates with the OS line ending and keeps an existing file's majority ending on every later write (normalizeLineEndings in yarnpkg-fslib FakeFS.ts, called by Project.persistLockfile and, through changeFilePromise's automaticNewlines, Workspace.persistManifest; the same rule from 2.4.3 through 4.18.0). On Windows a fresh yarn.lock is therefore CRLF, and so is the package.json yarn first pretty-prints; a core.autocrlf checkout produces the same on any OS. Once the Windows yarn-berry suites ran (corepack.cmd), both modes failed on those files: - hosted: rewrite_yarn_berry refused every CRLF lock (redirect_yarn_berry_crlf_unsupported, redirected 0); - vendored: package.json was re-serialized LF on both the wiring and the revert, so `vendor --revert` never restored the CRLF manifest byte-for-byte. Hosted: the rewriter works on the LF-normalized lock and re-expands its output (utils::line_endings), keeps a leading BOM, and records the lock's on-disk CRLF fragments in the ledger, so the per-purl takeover and the whole-ledger replay restore them byte-exactly. Both replays now also match yarn blocks respelled in the live lock's ending when a checkout flipped its uniform ending since the redirect (the committed ledger keeps its fragments verbatim). Vendored: package.json is re-serialized in its own layout (vendor::common::JsonLayout: BOM, indent, line ending, trailing-newline shape) and parsed past a BOM, and lock entries are spliced in the terminator of the block they replace (yarn_classic_lock::block_eol, also used by the shared revert, so a lock whose endings were mixed after vendoring keeps every other line as it was). A yarn.lock or package.json that mixes CRLF and LF, or holds a bare CR, has no single ending to keep and fails yarn's own `--immutable` check (YN0028): both modes refuse it before any write (redirect_yarn_berry_mixed_line_endings / vendor_yarn_berry_mixed_line_endings) with `yarn install` as the remedy. Reverts never refuse on line endings. Readers: is_berry_lock, the vendor flavor sniff, repair's sniff, scan_blocks and the .yarnrc.yml compressionLevel read skip a leading BOM (a header-less `__metadata:` lock is berry; a BOM'd yarnrc's first-line knob is no longer read as unset). The lock inventory and manifest-less VEX already split CRLF lines; unit tests pin both. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Hermetic CLI coverage of the Windows file shapes: `scan --mode hosted` over CRLF and BOM + CRLF locks (every line kept CRLF, the ledger's fragments the on-disk CRLF bytes, re-run a no-op, `rollback` restoring the pristine lock byte-for-byte) and its mixed-ending refusal; `vendor` + `vendor --revert` over CRLF (+ BOM) package.json / yarn.lock pairs (byte-exact round trip) and the mixed-ending failed event; both mode takeovers on CRLF files (hosted -> vendored -> revert, vendored -> hosted -> rollback, BOM kept); and a manifest-less VEX cell over a CRLF + BOM vendored lock and manifest. Real yarn: SOCKET_PATCH_YARN_BERRY_EOL=crlf respells the files each fixture's first `yarn install` wrote CRLF — what yarn itself writes on Windows (a new lockfile and a freshly pretty-printed manifest get os.EOL) — and yarn keeps them CRLF on every later write, so the hosted, vendored, pnpm-linker, workspaces, legacy-refusal and mode-migration suites run on CRLF files on macOS / Linux as they do on windows-latest. Every fixture prints `BERRY-EOL|<yarn>|<flow>|<file>|yarn=…|flow=…`, the ending yarn wrote and the one the flow ran on. Against the pre-fix code this mode reproduces both Windows CI failures (redirect_yarn_berry_crlf_unsupported on the hosted suites; "revert must restore package.json byte-identical" on the vendored ones); with the fix, yarn 4.12.0 passes all five suites in both modes (103 VEX-MATRIX cells each) and both mode takeovers. Also drops a doubled doc-comment line in yarn_berry_common. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ibility page CLI_CONTRACT: the hosted redirect keeps a CRLF lock's own line ending and BOM and records on-disk fragments; a mixed-ending lock is refused with redirect_yarn_berry_mixed_line_endings, which replaces v4's redirect_yarn_berry_crlf_unsupported (no longer emitted); the vendored yarn berry row keeps both files' layout, with the new vendor_yarn_berry_mixed_line_endings refusal in the code table; the per-purl revert and whole-ledger replay respell yarn blocks across a uniform LF <-> CRLF checkout flip. CHANGELOG [Unreleased]: the fix (hosted + vendored CRLF support, BOM tolerance) under Fixed, the two refusal codes and the CRLF test mode under Added. docs/testing/yarn-berry-compatibility.md (new): supported releases, the CI matrix, how yarn berry chooses line endings — cited to FakeFS.ts, Project.ts, Workspace.ts, Manifest.ts and syml.ts at @yarnpkg/cli/4.12.0 — the git autocrlf paths to CRLF, socket-patch's contract per mode, and how to run the suites locally in CRLF mode. docs/ecosystems.md links it from the yarn berry notes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… --remove `setup` re-serialized package.json through `serialize_json`, which always emits bare LF and never writes a BOM back. On a Windows yarn berry project (persistManifest pretty-prints the manifest with os.EOL) a two-key script edit became a whole-file CRLF -> LF diff that yarn then keeps (it follows the majority ending), and `setup --remove` could never land byte-identical on the pre-setup file. Render through the vendored backends' `JsonLayout` instead (BOM, indent, line ending, trailing-newline shape). The two BOM tests now assert the BOM survives; a new round-trip test covers LF, CRLF, BOM+CRLF, BOM+LF, no final newline and two final newlines, asserting setup keeps each shape and setup --remove restores the original bytes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…erts the old one The reverts keep line endings as they are (a vendored or hosted revert never refuses on them, so a lock mixed after wiring stays mixed), while the forward hosted rewriter and vendored backend refuse a mixed file. Neither takeover checked first: - `scan`/`get --mode hosted` over a vendored berry purl reverted its wiring, ledger entry and artifact (`redirect_takeover_reverted_vendored`: "now fully hosted"), then the rewriter refused the mixed lock - `redirected: 0`, and the next `yarn install` pulled the unpatched registry package. - `vendor` / `scan --mode vendored` over a hosted berry purl reverted the hosted edits and dropped the redirect-ledger record (`vendor_takeover_reverted_redirect`), then failed `vendor_yarn_berry_mixed_line_endings`. Extract the rewriter's project gates into `redirect::preflight_yarn_berry_hosted` (mixed endings, cacheKey, `.yarnrc.yml` compressionLevel) and the backend's into `vendor::yarn_berry_vendor_preflight` (both files' endings, cacheKey, compressionLevel; berry flavor only), and run each before the matching takeover revert, mirroring the bun preflights - wet and --dry-run alike. A refused purl keeps the old mode's wiring byte-identical and is skipped / failed with the new mode's code. Tests: a hermetic in_process_vendor test drives both directions (mixed lock, mixed package.json, compressionLevel 9; wet and dry-run) and asserts the wiring snapshot is unchanged and no takeover is announced (fails on the pre-fix code in both directions); core unit tests pin that each preflight matches its forward gate's code and detail. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mikola Lysenko (mikolalysenko)
force-pushed
the
fix/windows-npm-env-case-assert
branch
from
September 24, 2026 21:45
c227560 to
bf1aecc
Compare
…che rename race The berry suites' parallel tests share one yarn cache folder. Two yarn processes fetching the same package both rename a .tmp over the cache zip, and on Windows the loser fails with EPERM while the winner holds the file (windows-latest yarn-berry 4.12.0: e2e_yarn4_workspaces_build hosted test, EPERM rename left-pad-npm-1.3.0-....zip-....tmp). A static lock in yarn_berry_common serializes yarn processes on Windows only (Unix rename-over is atomic), mirroring the DOTNET_SPAWN fix. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e CLI
Test binaries that mix in-process command runs with spawned CLI runs raced:
the in-process runs call apply_env_toggles, which std::env::set_var's
SOCKET_OFFLINE / SOCKET_DEBUG / SOCKET_API_URL / SOCKET_PROXY_URL on the
shared test process, and the spawn helpers only removed SOCKET_* vars that
existed when they scanned the environment. A toggle set by a parallel test
between that scan and the spawn was inherited. On test-release this made
in_process_vendor's berry takeover test run its hosted scan offline
("cannot run with --offline/SOCKET_OFFLINE"). The helpers in all eight
such binaries now remove those keys unconditionally; Command applies the
removals to the environment captured at spawn time.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
CI green: 417/417 on 4982572; see description for details. |
Mikola Lysenko (mikolalysenko)
deleted the
fix/windows-npm-env-case-assert
branch
September 25, 2026 01:14
5 tasks
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.
Real-PM e2e legs added in #251 (first run on this PR, since ci.yml changed): 22 failing legs fixed, no product regressions.
poetry_vendored_fresh_install_then_manifestless_vexstill expected.socket/manifest.jsonafterscan --vendor. Since Cleanup: no .socket residue, locks that never outlive a command, manifest-free vendored mode #247, vendored mode is manifest-free (CLI_CONTRACT.md). The test now asserts there is no manifest and that the ledger entry isdetached: truewith the embeddedrecord.uuid.enableImmutableInstallswhenCIis set, so each fixture's lockfile-creatingyarn installfailed with YN0028. Newpin_berry_ci_defaultssetsCI=trueandYARN_ENABLE_IMMUTABLE_INSTALLS=false. The fresh-checkout installs still pass--immutableexplicitly, and a unit test covers the pin. On Windows, corepack iscorepack.cmd, so the newcorepack_command()spawns that. Failure messages now include yarn's stdout, where berry prints its errors.bundlestill runs the highest installed one (the Ruby default, 2.3.27). A new "Select the pinned Bundler" step exportsBUNDLER_VERSIONfor every leg with a bundler pin. The harness mismatch message now names this fix.download.detachedand that there is no ledger record, then checks nothing is attested. The "unapplied manifest attests nothing" check moved to the step that stages a manifest itself.sys.prefix(/private/var/…vs/var/…). Both paths are now canonicalized before the containment check.-B. That hid the checksum-rejection line the TAMPER probe greps for. Allmvncalls now go throughmvn_command(), which scrubs the CI markers. The assertion is unchanged./tmp/.dotnet/shmon a fresh runner (EEXIST on the NuGet-Migrations mutex).dotnetlaunches in the test binary are now serialized behind one lock; the socket-patch steps still run in parallel.Yarn berry on Windows: CRLF support (user decision: fix in this PR). Once the berry suites could actually run on Windows (the
corepack.cmdfix), they showed a gap that existed before #251. On Windows, yarn berry writesyarn.lockandpackage.jsonwith CRLF: a new file getsos.EOL, and an existing file keeps its majority ending (FakeFS.normalizeLineEndings, yarn 2 through 4.18). Gitcore.autocrlfproduces CRLF locks too. socket-patch refused CRLF berry locks entirely, so neither hosted nor vendored yarn berry had ever worked on Windows.redirect_yarn_berry_crlf_unsupported, is gone.package.jsongoes through a newJsonLayout, which keeps the BOM, indent, line ending and trailing-newline shape, so revert is byte-exact. Lock blocks are spliced using the ending of the block they replace.redirect_yarn_berry_mixed_line_endings/vendor_yarn_berry_mixed_line_endings. The message namesyarn installas the fix. Reverts never refuse.setup/setup --removenow keep a CRLF or BOMpackage.jsonbyte-exact too.YARN_ENABLE_HARDENED_MODE, which those versions reject.SOCKET_PATCH_YARN_BERRY_EOL=crlfmode runs the real-yarn suites on CRLF files on macOS/Linux. With real yarn 4.12.0, every berry suite passes in both LF and CRLF mode. Against the old code, the CRLF mode reproduces both Windows CI failures exactly.package.jsonwriters still write LF.Two test-harness races found once the full matrix ran:
EPERM. Yarn launches inyarn_berry_commonnow run one at a time on Windows only (BERRY_SPAWN, mirroringDOTNET_SPAWN). Unix rename-over is atomic, so other platforms stay parallel.apply_env_togglesset_varsSOCKET_OFFLINE/SOCKET_DEBUG/SOCKET_API_URL/SOCKET_PROXY_URLon the shared test process. The spawn helpers only removedSOCKET_*variables present when they scanned the environment, so a toggle set by a parallel test in between was inherited.test-releasehit this: a hosted scan ran offline. The helpers in all 8 such binaries now remove those keys unconditionally.CI: all 417 checks pass on
49825727. That includestest (windows-latest),test-release, the cargo Windows leg, and the full real-package-manager matrix (poetry, yarn berry on Linux/macOS/Windows, bundler, deno, maven 4, dotnet, hatch, pipenv, pip, pnpm, npm, go, uv, cargo, composer, nuget). This is the first complete run of #251's real-PM legs.🤖 Generated with Claude Code