fix(scan): surface cross-mode state — hosted wiring retained, vendored ownership, berry vendored-entry refusal - #207
Merged
Mikola Lysenko (mikolalysenko) merged 2 commits intoAug 19, 2026
Conversation
… retained, berry vendored-entry refusal)
Failing-first tests for three adversarially-verified silence gaps in the
mode-conversion matrix (additive warnings only; no exit/status changes):
* A — scan --mode agent over a live hosted redirect reports success with
zero hint that yarn.lock still pins the patch server and the redirect
ledger stays live: scan_invariants pins a top-level
hosted_wiring_retained run warning (+ two silence guards: records-gone
= lane-B pre-revert world, and registry-clean lock).
* D — agent-mode apply buries vendor-owned skips deep in apply.patches[]:
scan_invariants pins a top-level vendored_ownership_retained warning
naming the purls and the real migration path.
* E — the berry hosted rewriter refuses our OWN vendored
file:./.socket/vendor/ entry under the generic unsupported_protocol
code whose detail hardcodes '(workspace:/patch:/portal:/link:)'
(file: not even listed) and names no remedy: redirect unit tests pin
a distinct redirect_yarn_berry_vendored_entry code + remediation, and
the generic detail naming the ACTUAL protocol.
Currently failing (RED):
core: yarn_berry_vendored_file_entry_refused_with_distinct_code_and_remediation,
yarn_berry_unsupported_protocol_detail_names_actual_protocol
cli: scan_agent_over_live_hosted_wiring_surfaces_run_level_warning,
scan_agent_over_vendored_purl_surfaces_run_level_warning
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d ownership, berry vendored-entry refusal Three additive-warning fixes for the yarn mode-conversion matrix's silence gaps (lane ADE). No exit-code or status changes anywhere — hosted refusals set the precedent (exit 0 + warning). A — hosted→agent silent no-op (scan/mod.rs agent branch): scan --mode agent over a live hosted redirect reported success/applied while yarn.lock stayed pinned to the patch server and .socket/vendor/redirect-state.json stayed live. The takeover machinery can never see this state: classify_overlap_takeover keys on purls in BOTH ledgers (hosted ∩ vendored), so hosted-ONLY wiring is structurally invisible (pinned by a new unit test). New hosted_wiring_retained_purls probes the already-loaded redirect ledger directly, reusing hosted_wiring_live per scanned purl, and emits a run-level hosted_wiring_retained warning (top-level warnings[] on the scan --json envelope + stderr; interactive path prints the same after apply). The probe keys on ledger RECORDS still live at scan time, so a sibling flow that pre-reverts hosted wiring (lane B) retires the warning with the records even while the append-only edits remain — pinned by tests. The detail offers the two real options (stay hosted / migrate via scan --mode vendored), never a hosted→agent unwind (none exists for npm/yarn) and never hand-deleting the ledger (the only revert data). D — vendored→agent refusal invisible at the envelope (scan/mod.rs:1564ff): agent-mode --json buried the vendor-owned skips deep in apply.patches[] (skipped/vendored) with no top-level signal. One run-level vendored_ownership_retained warning now names the purls + the real migration path (remove <purl>, or vendor --revert which unwinds EVERY vendored package, then re-run), mirrored to stderr when not --silent. Per-patch records, exit code, and status are untouched. E — berry rewriter misdiagnosis (core redirect/mod.rs:2039): the unsupported-protocol branch refused our OWN vendored file:./.socket/vendor/ entries with a detail hardcoding '(workspace:/patch:/portal:/link:)' — file: not even listed — and no remedy. A file: range carrying the .socket/vendor/ signature now gets the distinct redirect_yarn_berry_vendored_entry code whose detail names the retirement path (remove <purl> / scoped vendor --revert, then re-run scan --mode hosted — correct both before and after lane B, which covers the opposite direction); other protocols keep the generic code with the entry's ACTUAL protocol named. Refusal stays fail-closed and byte-identical. CLI_CONTRACT.md documents all three (agent-flow run-level warnings section, hosted rewriter refusal codes, vendored skip row/bullet). Tests: RED-committed integration tests now green (scan_invariants ×4, core rewriter ×2) plus new unit tests beside the takeover suite (structural-blindness pin, per-case silence guards, detail wording). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 779f206. Configure here.
Mikola Lysenko (mikolalysenko)
enabled auto-merge (squash)
August 19, 2026 14:55
Wenxin Jiang (Wenxin-Jiang)
approved these changes
Aug 19, 2026
Mikola Lysenko (mikolalysenko)
merged commit Aug 19, 2026
70f1f2f
into
main
119 of 120 checks passed
Mikola Lysenko (mikolalysenko)
deleted the
fix/mode-conversion-visibility-warnings
branch
August 19, 2026 15:15
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.

Lane ADE of the yarn mode-conversion campaign: three adversarially-verified SILENCE gaps, each pattern-fixed with additive warnings only (precedent: #133/#159/#164/#189/#201). No exit-code or status changes anywhere. CLI_CONTRACT.md updated for all three.
Root causes (file:line, pre-fix)
A — hosted→agent is a silent no-op (
crates/socket-patch-cli/src/commands/scan/mod.rs, agent branch ~L1545 JSON + human path)scan --mode agentover a live hosted redirect reportedstatus: success/appliedwith zero warnings whileyarn.lockstayed pinned topatch.socket.devand.socket/vendor/redirect-state.jsonstayed live. The takeover machinery structurally cannot see it:classify_overlap_takeover(mod.rs:602) keys on purls present in both ledgers (hosted ∩ vendored), so hosted-only wiring never triggers it — and the agent path loaded the redirect ledger (mod.rs:1472) only forupdates[]merging. No npm/yarn hosted revert exists, so the "conversion" can never complete without another mode run.D — vendored→agent refusal invisible at the envelope (mod.rs:1564-1571 via
partition_skipped_selected(..., "vendored"), vendor_flow.rs:503-549)Agent-mode
--jsonrecorded vendor-owned skips only deep inapply.patches[](skipped/vendored); no top-level signal, no stderr line — a JSON consumer had to dig per-patch to learn the mode did not change. (Human path already printed[skip] … (vendored …).)E — berry rewriter misdiagnoses our own vendored entry (
crates/socket-patch-core/src/patch/redirect/mod.rs:2039-2053)The unsupported-protocol branch refused socket-patch's OWN
file:./.socket/vendor/…wiring with a detail hardcoding(workspace:/patch:/portal:/link:)—file:not even listed — and named no remedy.Matrix evidence
Repro'd by the matrix sweep (cells convy1-hosted2agent, convy4-hosted-agent, edgey1-roundtrip; convy1/convy4-vendored2agent; convy4-vendored-hosted) and re-verified here against production on throwaway copies of the verify dirs:
status success,warnings: null,grep -c patch.socket.dev yarn.lock= 1 after "conversion". New: same exit/status,warnings[0].code = hosted_wiring_retained(JSON + stderr), state untouched.warnings: null, skip only inapply.patches[]. New: same envelope +warnings[0].code = vendored_ownership_retainednaming the purl andremove <purl>/ scopedvendor --revertmigration path; vendored wiring untouched.redirect_yarn_berry_unsupported_protocolclaiming(workspace:/patch:/portal:/link:). New:redirect_yarn_berry_vendored_entrynaming the retirement path (remove <purl>/ scopedvendor --revert, then re-runscan --mode hosted); other protocols now get the generic code with the entry's ACTUAL protocol. Lock byte-identical, exit 0, both binaries.Fix summary
warnings[](top-level{code, detail}, additive, mirrored to stderr unless--silent) on the agent apply flow:hosted_wiring_retained— newhosted_wiring_retained_purlsprobes the already-loaded redirect ledger, reusinghosted_wiring_liveper scanned purl (deliberately NOT viaclassify_overlap_takeover, which requires a vendored-ledger intersection). Fires only when ledger records are still live at scan time AND the live lock proves hosted wiring — so lane B's hosted→vendored pre-revert (which retires the records) retires this warning with them, pinned byscan_agent_hosted_warning_silent_once_ledger_records_are_gone. Detail: stay--mode hostedor migrate viascan --mode vendored; never a hosted→agent unwind (none exists), never hand-deleting the ledger.vendored_ownership_retained— fires when the vendored partition is non-empty, naming the purls +remove <purl>(orvendor --revert, blast radius called out), per-patch records untouched.file:+.socket/vendor/signature ⇒ distinctredirect_yarn_berry_vendored_entrycode with the real remediation; otherwise the generic detail names the ACTUAL protocol(s). Refusal stays fail-closed/byte-identical.Tests (TDD, RED commit 0842aca first)
scan_invariants.rs: 4 new e2e cases (wiremock, seeded ledgers — no real yarn needed): D warning trigger; A warning trigger; A silence when records are gone (lane-B coordination guard); A silence on a registry-clean lock.scan/mod.rsunit tests beside the takeover suite:hosted_only_wiring_fires_agent_probe_not_the_overlap_classifier(pins the structural blindness), per-case silence guards, detail-wording assertions, distinct-code assertions.redirect/mod.rs: vendored-entry code+remediation; actual-protocol naming forportal:and non-vendoredfile:; existingyarn_layeringincident guard 4d still green.cargo test --workspacegreen,cargo clippy --workspace --all-features -- -D warningsclean, touched files rustfmt-clean.Sibling-PR conflict notes (parallel lanes)
fix/npm-vendored-over-hosted-prerevert(clivendor.rs,scan/hosted.rs, core redirect takeover): no shared regions expected; this PR's A warning is coordination-safe with B by design (keys on ledger records still live at scan time — tested), and the E remedy wording holds in both worlds. If B touchesscan/mod.rsnear the takeover block, trivial context conflicts possible.fix/vendor-revert-driftskip-keep-artifacts(core vendor lock backends,vendor/mod.rs, clivendor.rsrevert path): disjoint files.scan/mod.rs; semantics independent.🤖 Generated with Claude Code
Note
Low Risk
Changes are additive warnings and clearer refusal diagnostics only—no exit/status semantics, lockfile writes, or apply behavior changes beyond documentation and messaging.
Overview
Agent-mode
scan --apply/--synccan now emit additive top-levelwarnings[]on the JSON envelope (and mirror to stderr unless--silent) when another patch mode’s wiring stays in place.vendored_ownership_retainedfires when vendor-owned packages were skipped before download—the existing per-patchskipped/vendoredrecords are unchanged; the warning names purls and migration (remove <purl>, or scopedvendor --revert).hosted_wiring_retainedfires when redirect ledger records are still live and the lock still proves hosted routing for scanned purls (via newhosted_wiring_retained_purls+hosted_wiring_live); detail steers toward staying hosted orscan --mode vendored, not hand-deletingredirect-state.json. Neither warning changes exit code orstatus.Hosted yarn berry rewriter:
file:ranges into.socket/vendor/now getredirect_yarn_berry_vendored_entrywith retirement guidance instead of the generic unsupported-protocol message; other non-npm:protocols still refuse withredirect_yarn_berry_unsupported_protocolbut the detail names the actual protocol(s) (e.g.portal:,file:), not a fixed four-protocol list.CLI_CONTRACT.mddocuments the agent-flow warning codes and berry refusal codes; unit and e2e tests cover triggers, silence cases (records gone, registry-clean lock, unscanned purl), and wording.Reviewed by Cursor Bugbot for commit 779f206. Configure here.