fix(scan): keep hosted --json envelope schema-consistent across discovery - #163
Open
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Open
fix(scan): keep hosted --json envelope schema-consistent across discovery#163Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Conversation
…very
`scan --json --mode hosted` emitted two incompatible top-level shapes: the
classic scan object (scannedPackages/totalPatches/canAccessPaidPatches/
packages) on zero discovery, but a bare `{status, redirect}` envelope once
>=1 package was found — dropping every scan-count key and the per-patch
enumeration, breaking JSON consumers on the redirect path.
Follow the vendored-mode precedent: always emit the classic scan object and
NEST the redirect result under a `redirect` key, for both the zero-discovery
and >=1-discovery paths. `run_redirect` now takes the classic scan object
(`Option<Value>`) built in `run` and folds `redirect` (and error status) into
it; the zero-package early-return gains a no-op `redirect` block. Human
(non-JSON) output is unchanged.
Kills sweep findings: hosted-scan-json-schema-flips-with-discovery,
hosted-scan-json-omits-enumeration.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mikola Lysenko (mikolalysenko)
enabled auto-merge (squash)
August 12, 2026 23:42
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.
Problem
scan --json --mode hostedemits TWO incompatible top-level JSON shapes depending on whether discovery found packages:crates/socket-patch-cli/src/commands/scan/mod.rsprints the CLASSIC scan object ({status, scannedPackages, lockfileOnlyPackages, totalPatches, canAccessPaidPatches, packages, updates, …}) before the hosted branch runs — with noredirectkey.hosted::run_redirectincrates/socket-patch-cli/src/commands/scan/hosted.rs:531emitted a BARE{status, redirect:{mode, redirected, rewrittenFiles, skipped, warnings, dryRun}}envelope — NONE of the scan-count keys, and no per-patch enumeration.A JSON consumer parsing
scannedPackages/totalPatches/canAccessPaidPatches/packagesbreaks the moment >=1 package is discovered. Confirmed against real prod for maven + nuget, reproduces on npm. Vendored mode does not have this flip — it NESTS avendorblock inside the classic scan object.Fix
Follow the vendored-mode precedent: always emit the classic scan object and NEST the redirect result under a
redirectkey (additive), for BOTH paths. Human (non-JSON) output is unchanged.run_redirectnow takes the classic scan object asOption<serde_json::Value>(crates/socket-patch-cli/src/commands/scan/hosted.rs:114), built byrun. A newbuild_redirect_json_envelopehelper (hosted.rs:88) folds theredirectblock into it;emit_json_error(hosted.rs:75) folds error status into it too — so error envelopes keep the same top-level keys instead of flipping schema.run(mod.rs): the HUMAN hosted path returns early (if hosted && !args.common.json, passingNone); the--jsonhosted path now returns from inside the JSON block, after the classicresult(including thepackagesenumeration +notInstalledflags) is built, passingSome(result)(mod.rs:927).redirectblock when hosted (mod.rs:622) so the 0-package envelope is shape-consistent with the >=1-package one.This also fixes the missing enumeration: the hosted
--jsonoutput now includes thepackagesarray (which packages / patch UUIDs were selected), same as every other scan.Kills sweep findings:
hosted-scan-json-schema-flips-with-discovery(P2),hosted-scan-json-omits-enumeration(P2).Test
Hermetic serialization test
hosted_json_envelope_nests_redirect_into_classic_scan_object(crates/socket-patch-cli/src/commands/scan/hosted.rs) asserts the hosted--jsonenvelope for the >=1-package case carries the classic scan keys (scannedPackages/packagesWithPatches/totalPatches/freePatches/paidPatches/canAccessPaidPatches/updates) AND the per-package/patch-uuid enumeration AND a nestedredirectobject preserving every sub-field. It exercises the extractedbuild_redirect_json_envelope— the exact schema that flipped before.cargo test -p socket-patch-cli --lib commands::scan→ 39 passed.cargo build -p socket-patch-cliandcargo clippy -p socket-patch-cliboth clean.Scope
Touches only
crates/socket-patch-cli/src/commands/scan/{hosted.rs,mod.rs}(the hosted-mode JSON envelope).run_redirecthas a single caller (the hosted branch inrun), updated in place. No cross-dependencies on other in-flight fixes.🤖 Generated with Claude Code
Note
Low Risk
CLI JSON output shape only for hosted scan mode; redirect/lockfile behavior unchanged; human output unchanged.
Overview
Fixes inconsistent
scan --json --mode hostedstdout when discovery finds packages: success used to emit only{status, redirect}and dropped classic scan fields (scannedPackages,totalPatches,packages, etc.), while the zero-package path already printed the full scan object.Hosted JSON now follows vendored mode:
runbuilds the classic scanresultfirst (includingpackagesand lockfile-only flags), thenrun_redirectnests redirect details underredirectviabuild_redirect_json_envelope.emit_json_errormerges errors into that same object whenscan_resultis present. Human (non-JSON) hosted runs still callrun_redirectearly withNone.The empty-scan JSON early return adds a no-op
redirectblock when hosted so shape matches the ≥1-package path. A unit test locks the nested envelope schema.Reviewed by Cursor Bugbot for commit 24d479b. Configure here.