Skip to content

Fix berry mode takeover reverting before gates (#468, #369) - #470

Merged
Mikola Lysenko (mikolalysenko) merged 5 commits into
mainfrom
agent/fix-berry-takeover-preflight
Oct 2, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 5 commits into
mainfrom
agent/fix-berry-takeover-preflight

Conversation

@mikolalysenko

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

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #468
Fixes #369

Summary

Switching a yarn berry package between hosted and vendored mode removed
the old mode's wiring before checking whether the new mode could wire
that package. When the new mode then skipped or refused it, the package
ended up patched in neither mode. Both takeovers now run the target
mode's per-package gates first and, on a refusal, leave the existing
mode byte-identical and report the gate's own code. This is what
CLI_CONTRACT.md already promises ("refuses before reverting").

Root cause (shared)

Each berry takeover preflight only covered the project-level gates
(line endings, cacheKey, compressionLevel). The per-package gates ran
after the revert:

Changes

  • Core patch/redirect: preflight_yarn_berry_hosted_dep(dep) checks the grant checksum before a fresh vendored → hosted takeover. The ordinary rewrite gate remains unchanged in this PR, so it composes with Fix yarn berry hosted pin leaking npm auth (#404) #465's lock-aware handling of already-complete pins.
  • CLI scan/hosted.rs: Berry vendored takeovers run that per-package gate before reverting. Warning deduplication retains each package's detail.
  • Core vendor/yarn_berry_lock.rs: yarn_berry_vendor_target_preflight(root, purl, pin, opts) previews the takeover's own upstream restore and runs the backend's resolution and lock-entry gates on the resulting file text. Socket-owned hosted resolutions therefore do not look like user overrides.
  • Core upstream restore exposes the staged text in RestoreOutcome.staged_text, including removals; a dry run writes nothing.
  • CLI vendor.rs: the per-target preflight runs after the project-level checks and before the real restore. The preview resolves upstream metadata before mutation; the wet restore resolves it again.

Tests

Issue Regression test (crates/socket-patch-cli/tests/in_process_vendor.rs) Without fix With fix
#468 berry_vendored_to_hosted_takeover_keeps_vendored_without_berry_checksum (wet + --dry-run) FAILED (no redirect_yarn_berry_missing_checksum refusal; takeover announced) ok
#369 berry_hosted_to_vendored_takeover_runs_package_gates_first (other locked version, user resolutions; wet + --dry-run) FAILED (vendor_takeover_reverted_redirect, hosted pin gone) ok

The #369 test passes --patch-server-url so the vendor run recognises
the hosted pin as a takeover. Without it, the run takes the eject path,
which was already safe.

Local runs:

  • cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo test -p socket-patch-cli --test in_process_vendor berry_: 6/6 ok.
  • scripts/yarn-berry-vex-matrix.sh 4.12.0 (with
    COREPACK_NPM_REGISTRY=https://registry.npmjs.org, because
    repo.yarnpkg.com is blocked in this sandbox): all yarn 4 suites ok. The
    two yarn@2.4.3 legacy-cachekey legs could not get yarn 2 here (it is
    not on the npm registry); they are unrelated refusal tests.
  • cargo test --workspace --all-features --no-fail-fast: everything
    passes except:
    • 12 chmod/read-only "write failure" tests, which can't fail under uid 0
      in this sandbox. They fail identically on a main-based branch.
    • mode_migration_npm berry_*_takeover_* (2): they panic in fixture
      setup (mode_migration_npm.rs:351, the test's own reqwest fetch of
      registry metadata hits the sandbox's TLS proxy, UnknownIssuer)
      before any CLI code runs. CI runs them.
  • cargo fmt --check reports the same pre-existing diffs as main (CI
    doesn't gate on fmt); the files this PR adds are rustfmt-clean.

Follow-ups

🤖 Generated with Claude Code


Note

Medium Risk
Changes Yarn Berry hosted/vendored takeover ordering and lockfile restore preview paths; mistakes could leave projects in a broken patch state, but behavior aligns with documented refuse-before-revert contract and is covered by new integration tests.

Overview
Fixes Yarn Berry mode takeovers (#468, #369) so per-package gates run before tearing down the current mode. Previously, reverting vendored or hosted wiring first could leave a package unpatched when the target mode then refused or skipped it.

Vendored → hosted (hosted.rs): Berry takeover refusal now includes preflight_yarn_berry_hosted_dep (grant must have yarnBerry10c0) ahead of vendored revert; refusals are owned/cloned so skip reasons use the gate’s code; duplicate pre_warnings are deduped by full JSON.

Hosted → vendored (vendor.rs + yarn_berry_vendor_target_preflight): After project-level berry checks, a dry-run restore_upstream populates new RestoreOutcome.staged_text; resolution/lock-entry gates run on that preview so user overrides and conflicting lock entries fail with vendor_override_conflict without removing the hosted pin.

Regression tests cover grants missing the berry checksum and hosted→vendored with an extra locked version or user resolutions.

Reviewed by Cursor Bugbot for commit 852472c. Configure here.


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
Switching a yarn berry package between hosted and vendored mode
removed the old mode's wiring before checking whether the new mode
could wire that package. When the new mode then skipped or refused
it, the package ended up patched in neither mode:

- vendored -> hosted: a grant without the yarnBerry10c0 cache
  checksum deleted the vendored patch, then skipped the redirect,
  and the run still exited 0 saying the package was fully hosted
  (#468).
- hosted -> vendored: another locked version of the name or a
  user-authored resolutions entry restored the registry entry, then
  failed vendoring with vendor_override_conflict (#369).

Both takeovers now run the target mode's per-package gates first and
leave the existing mode byte-identical, reporting the gate's own
code, as CLI_CONTRACT.md already promises.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 1, 2026 14:32
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


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 Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 1, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Ready for review at 83bb9a9 (83bb9a99b1700483279c101984dc18315581381f).

  • CI: 96/96 check runs green on the head; 4 skipped by path filters, 0 failing. Mergeable, 0 commits behind main.
  • Bugbot: reviewed 83bb9a9 and found no issues. No unresolved review threads.
  • Reviewer focus: vendor_records_reusing (hosted → vendored) and commands/scan/hosted.rs (vendored → hosted). Both now run the target mode's per-package gates before reverting the existing mode, as CLI_CONTRACT.md requires ("refuses before reverting"). See tests/in_process_vendor.rs for the byte-identical-on-refusal assertions.

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Reviewed 83bb9a99b170. Ready to merge independently from this code review; no standalone changes requested.

No standalone blocking findings. Both takeover directions run the new package/grant refusal gates before reverting the old mode, and the focused tests preserve the previous wiring byte-for-byte on refusals.

Validation: cargo test --locked -p socket-patch-cli --test in_process_vendor berry_ — 6 passed.

Integration with #465 needs a fix. Do not combine #465 and #470 unchanged: their automatic merge is textually clean, but the combined Berry suite fails berry_crlf_takeovers_round_trip_both_directions. The new target preflight rejects the Socket-owned left-pad@npm:1.3.0 resolution added by #465 as vendor_override_conflict. The preflight needs to recognize owned hosted resolutions or evaluate the restored state. I tested the clean combined tree: 5 passed, 1 failed, versus all 6 passing on #470 alone.

The hosted->vendored takeover's per-package preflight read the
still-hosted package.json / yarn.lock. Hosted wiring that also writes a
Socket-owned package.json resolutions pin (#465) was then mistaken for a
user override (vendor_override_conflict) and the takeover refused.

The preflight now dry-runs the takeover's own restore_upstream and runs
resolutions_gate / scan_berry_target on the restored text
(RestoreOutcome.staged_text), so only the user's own wiring can refuse.
The #369 regression test now mounts the upstream entry the restore reads
and drops a leftover debug eprintln.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014hMbzxwUnf5voAqbc8g4df
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Fixed the #465 integration in eca97d9 + 29bbac4, by evaluating the restored state.

Validation:

Trade-offs:

  • A berry takeover now resolves the upstream entry twice (a dry run, then the real restore).
  • Offline, the dry run can't resolve the entry. The takeover then fails as redirect_revert_failed, not with the check's own code. The hosted wiring stays untouched either way.

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


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

CI on 29bbac4: 459 jobs passed and 1 failed; the rest are still queued (macOS/Windows). The failure is native (ubuntu-latest, 2.3.4), the PDM backtest cell 2.3.4 crlf hosted, check refusalCodeReported. I don't think this PR caused it:

  • This push only changes the npm / yarn berry hosted→vendored takeover (plus a field added to RestoreOutcome). It doesn't touch the PDM hosted scan path.
  • The same job passed on 83bb9a9, the previous head of this PR, and passes on main (d63ae5f).
  • The cell ran for 27.5s, against about 7s for the other hosted cells, and reported no refusal codes at all. That looks like the hosted scan's call to the patch API stalled, not a lock-handling regression.

I couldn't re-run the job: the API returns 403 with this session's credentials. Please re-run native (ubuntu-latest, 2.3.4) once. If it fails again, I'll treat it as real and dig in.


Generated by Claude Code

@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator Author

Pushed compatibility fix 852472c7119a0f6f275db9525a1f4111d3875929 and completed the second review pass. The #465 integration blocker is resolved; code review is clear, pending completion of CI at this head.

The latest #465 moves checksum validation so an already-complete pin can retain its stored checksum. #470's eager rewrite preflight conflicted with that change. This commit keeps the unconditional grant check at the fresh vendored → hosted takeover boundary and restores #470's original, equivalent inline rewrite gate. Neither PR needs to absorb the other. Hosted → vendored still checks the staged restored files before changing the project.

Validation: standalone 124 core Berry tests + 6 takeover tests passed. Combined with #465's latest dc9330f4 (including its main merge), 140 core Berry tests, all 7 Berry vendor/takeover tests, the original orphaned-pin/VEX reproduction, and the Poetry/PDM golden checks passed. The current heads merge cleanly at tree a3fbd2fabcf4b712bae7aeade0adb80966d40506. This includes the previously failing CRLF round trip. An independent reviewer also checked the compatibility change.

The historical-installer failures inspected on this head were external patch API HTTP 504s: Poetry 1.2.2/macOS failed before rewriting, and PDM 2.22.4/Linux failed during a rescan. Uploaded artifacts confirm both causes. I retried the affected jobs: Poetry passed; PDM passed as well. Full platform CI is still required.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

CI on 852472c: native (macos-latest, 1.2.2) in "Poetry patch compatibility" failed. The 1.2.2 direct hosted cell failed appliedExactlyOne; the other 4 cells in the job passed, including crlf hosted. Most other jobs are still running. I don't think this PR caused it:

  • 852472c only changes rewrite_yarn_berry / preflight_yarn_berry_hosted_dep, both berry-only. The Poetry hosted path is untouched.
  • The same job passed on 29bbac4 and 83bb9a9, and on recent main commits (bf0e0d1, 73b17db, 1169ae6).
  • One hosted cell applying 0 patches while its sibling hosted cell passes looks like the same patch-API flake as the PDM 504 on 29bbac4.

I can't confirm it from here: this sandbox can't reach the patch API or download artifacts, and re-running returns 403. Please re-run native (macos-latest, 1.2.2) (Poetry) once. If it fails again, I'll treat it as real.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

A second Python job failed on 852472c, with the same pattern as the Poetry one above. In native (ubuntu-latest, 2.22.4) (PDM), the 2.22.4 dev hosted cell failed rescanIdempotent. It ran for 35.2s, against 10–19s for the other hosted cells, and the other 40 cells in the job passed. Again, nothing in 852472c touches the PDM path. This is now the third hosted-only cell on a different Python tool in an hour, which points to the patch API being unstable rather than to this PR. Please re-run this job together with the Poetry macOS one.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


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 852472c. Configure here.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] Status on 852472c: every check is green, including the Poetry (macOS 1.2.2) and PDM (ubuntu 2.22.4) hosted cells that failed earlier and passed on re-run. Bugbot reviewed 852472c and found no issues, and there are no unresolved review threads. This PR is waiting on human review.


Generated by Claude Code

@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit 9d81139 into main Oct 2, 2026
562 of 564 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-berry-takeover-preflight branch October 2, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

3 participants