GeezerVison is showing github.com — fix(scan): surface cross-mode state — hosted wiring retained, vendored ownership, berry vendored-entry refusal by mikolalysenko · Pull Request #207 · SocketDev/socket-patch
Conversation
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 agent over a live hosted redirect reported status: success / applied with zero warnings while yarn.lock stayed pinned to patch.socket.dev and .socket/vendor/redirect-state.json stayed 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 for updates[] 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 --json recorded vendor-owned skips only deep in apply.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:
- A old binary: exit 0,
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.
- D old: exit 0,
warnings: null, skip only in apply.patches[]. New: same envelope + warnings[0].code = vendored_ownership_retained naming the purl and remove <purl> / scoped vendor --revert migration path; vendored wiring untouched.
- E old:
redirect_yarn_berry_unsupported_protocol claiming (workspace:/patch:/portal:/link:). New: redirect_yarn_berry_vendored_entry naming the retirement path (remove <purl> / scoped vendor --revert, then re-run scan --mode hosted); other protocols now get the generic code with the entry's ACTUAL protocol. Lock byte-identical, exit 0, both binaries.
Fix summary
- New run-level
warnings[] (top-level {code, detail}, additive, mirrored to stderr unless --silent) on the agent apply flow:
hosted_wiring_retained — new hosted_wiring_retained_purls probes the already-loaded redirect ledger, reusing hosted_wiring_live per scanned purl (deliberately NOT via classify_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 by scan_agent_hosted_warning_silent_once_ledger_records_are_gone. Detail: stay --mode hosted or migrate via scan --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> (or vendor --revert, blast radius called out), per-patch records untouched.
- Berry rewriter:
file: + .socket/vendor/ signature ⇒ distinct redirect_yarn_berry_vendored_entry code 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.rs unit 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.
- core
redirect/mod.rs: vendored-entry code+remediation; actual-protocol naming for portal: and non-vendored file:; existing yarn_layering incident guard 4d still green.
- Gates:
cargo test --workspace green, cargo clippy --workspace --all-features -- -D warnings clean, touched files rustfmt-clean.
Sibling-PR conflict notes (parallel lanes)
🤖 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 / --sync can now emit additive top-level warnings[] on the JSON envelope (and mirror to stderr unless --silent) when another patch mode’s wiring stays in place. vendored_ownership_retained fires when vendor-owned packages were skipped before download—the existing per-patch skipped/vendored records are unchanged; the warning names purls and migration (remove <purl>, or scoped vendor --revert). hosted_wiring_retained fires when redirect ledger records are still live and the lock still proves hosted routing for scanned purls (via new hosted_wiring_retained_purls + hosted_wiring_live); detail steers toward staying hosted or scan --mode vendored, not hand-deleting redirect-state.json. Neither warning changes exit code or status.
Hosted yarn berry rewriter: file: ranges into .socket/vendor/ now get redirect_yarn_berry_vendored_entry with retirement guidance instead of the generic unsupported-protocol message; other non-npm: protocols still refuse with redirect_yarn_berry_unsupported_protocol but the detail names the actual protocol(s) (e.g. portal:, file:), not a fixed four-protocol list.
CLI_CONTRACT.md documents 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.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
… 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 <[email protected]>
…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 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Mikola Lysenko (mikolalysenko)
added a commit
that referenced
this pull request
Aug 19, 2026
…nd list (#220)
Live-verified defect (gem live-matrix D3, 2/2 per cell on bundler
1.17/2.7/4.0 vs production): after `scan --mode hosted` + install, the
hosted state was invisible to both read-only surfaces a user would
check —
* report-only `socket-patch scan --json` (exit 0) contained ZERO
hosted/redirect/warning fields (byte-identical to a never-touched
project's envelope): the `hosted_wiring_retained` warning rides only
the agent-mode apply branch, and the `redirect` sub-object only a
hosted-mode run's;
* `socket-patch list --json` exited 1 `manifest_not_found` — hosted
mode records its patches ONLY in the redirect ledger and never writes
`.socket/manifest.json`.
This matches the long-open "hosted-mode JSON gap" residual from the
2026-07-04 scan/mod.rs review; PR #207 surfaced the adjacent cross-mode
warnings but not these two surfaces.
Fix (both additive/MINOR per CLI_CONTRACT.md):
* scan --json: every non-hosted-mode, non-vendored-mode envelope
(report-only, agent, and the zero-discovery path) now carries a
top-level `redirectState` block whenever the redirect ledger holds
records: `{ mode, ledger, records: [{purl, uuid}], wiringLive }`.
It is a descriptive STATE block, not a warning — records are the
ledger's word, `wiringLive` the live lock's proof (the same
`hosted_wiring_live` gate as the #207 warning). Hosted-mode runs keep
their `redirect` sub-object and vendored runs their takeover warnings
(both can mutate the ledger mid-run, so a pre-run snapshot would go
stale).
* list / list --json: hosted redirect-ledger records fold into the
listing, labeled (`details.mode: "hosted"` + `details.ledger`; a
`Mode: hosted` line on the human path), purl-sorted with the manifest
entry first on a tie. A hosted-only project now exits 0 with its
records; `manifest_not_found` still fires when NEITHER store has a
record (an edits-only ledger asserts no patches), and a
present-but-broken manifest still reports manifest_invalid /
manifest_unreadable — corruption is never masked. A malformed ledger
degrades to "nothing to consult" with a stderr warning (read-only
consumer posture per load_redirect_state's contract).
Test-first: tests/scan_invariants.rs (4 new, mirroring the #207
fixtures) and tests/cli_parse_list.rs (6 new subprocess tests) were RED
against the old binary; plus in-module unit tests for the block builder
and the list envelope labeling. CLI_CONTRACT.md updated (scan section,
subcommands table, manifest_not_found row, list action-matrix row).
Co-authored-by: Claude Fable 5 <[email protected]>
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
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.
|