@@ -22,7 +22,7 @@ use std::path::{Path, PathBuf};
2222use clap:: Args ;
2323use socket_patch_core:: crawlers:: Ecosystem ;
2424use socket_patch_core:: manifest:: operations:: read_manifest;
25- use socket_patch_core:: manifest:: schema:: PatchManifest ;
25+ use socket_patch_core:: manifest:: schema:: { PatchManifest , PatchRecord } ;
2626use socket_patch_core:: telemetry:: { track_vex_failed, track_vex_generated} ;
2727use socket_patch_core:: vendor:: state:: VendorState ;
2828use socket_patch_core:: vex:: {
@@ -179,6 +179,7 @@ impl VexEmbedArgs {
179179 dry_run : false ,
180180 product_flag : "--vex-product" ,
181181 npm_prior : None ,
182+ hosted_records : Default :: default ( ) ,
182183 }
183184 }
184185}
@@ -219,6 +220,12 @@ pub(crate) struct VexBuildParams {
219220 /// choice and order are unchanged. Ignored when taken with other crawler
220221 /// options. The standalone `vex` passes `None` and walks the tree.
221222 pub npm_prior : Option < crate :: ecosystem_dispatch:: NpmCrawlSnapshot > ,
223+ /// Embedded hosted `scan --vex` only: the patch records THIS RUN
224+ /// fetched for the pins it confirmed, keyed by purl. v5 hosted mode
225+ /// keeps no ledger, so these are the in-run attestation's hosted
226+ /// records (the post-install standalone `vex` fetches them from the
227+ /// API instead). Empty everywhere else.
228+ pub hosted_records : std:: collections:: BTreeMap < String , PatchRecord > ,
222229}
223230
224231/// Successful result of [`generate_vex`].
@@ -337,6 +344,7 @@ pub async fn run(args: VexArgs) -> i32 {
337344 dry_run : args. common . dry_run ,
338345 product_flag : "--product" ,
339346 npm_prior : None ,
347+ hosted_records : Default :: default ( ) ,
340348 } ;
341349
342350 let manifest_path = args. common . resolved_manifest_path ( ) ;
@@ -1109,6 +1117,16 @@ async fn generate_vex_from_manifest_path_inner(
11091117 for diag in & discovery. diagnostics {
11101118 note_warning ( warnings, common, diag. code , diag. detail . clone ( ) ) ;
11111119 }
1120+ // This run's hosted records (embedded hosted `scan --vex`) join a
1121+ // pre-v5 ledger's as the hosted record source, newest wins.
1122+ let redirect = if params. hosted_records . is_empty ( ) {
1123+ redirect
1124+ } else {
1125+ let mut state =
1126+ redirect. unwrap_or_else ( socket_patch_core:: patch:: redirect:: RedirectState :: new) ;
1127+ state. records . extend ( params. hosted_records . clone ( ) ) ;
1128+ Some ( state)
1129+ } ;
11121130 let sources = Sources {
11131131 manifest : manifest_file. unwrap_or_else ( PatchManifest :: new) ,
11141132 vendor,
@@ -1962,6 +1980,7 @@ mod npm_prior_tests {
19621980 dry_run : false ,
19631981 product_flag : "--vex-product" ,
19641982 npm_prior : prior,
1983+ hosted_records : Default :: default ( ) ,
19651984 } ;
19661985 let manifest_path = common. resolved_manifest_path ( ) ;
19671986 match generate_vex_from_manifest_path ( common, & params, & manifest_path) . await {
0 commit comments