Skip to content

Commit 2b331c1

Browse files
committed
Feed the hosted scan's in-run VEX this run's records
The in-run `scan --mode hosted --vex` attestation read its hosted records from the ledger the run had just written. With no ledger, the run's fetched records reach the VEX builder in memory (VexBuildParams hosted_records), merged over any pre-v5 ledger's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018tncU7u7FK48tubFNA12UQ
1 parent 5eadb00 commit 2b331c1

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

‎crates/socket-patch-cli/src/commands/scan/hosted.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,6 +2943,9 @@ pub(crate) async fn run_redirect_selected(
29432943
// it was taken with these crawler options). `get --mode hosted`
29442944
// passes none.
29452945
params.npm_prior = npm_prior.cloned();
2946+
// v5 keeps no hosted ledger: this run's fetched records are the
2947+
// hosted record source of the in-run attestation.
2948+
params.hosted_records = records.clone();
29462949
// Stale-flagged purls are EXCLUDED from assume_applied: the same-run
29472950
// envelope carries a redirect_gem_stale_install warning proving the
29482951
// installed materialization unpatched, so attesting that purl from

‎crates/socket-patch-cli/src/commands/vex.rs‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::path::{Path, PathBuf};
2222
use clap::Args;
2323
use socket_patch_core::crawlers::Ecosystem;
2424
use socket_patch_core::manifest::operations::read_manifest;
25-
use socket_patch_core::manifest::schema::PatchManifest;
25+
use socket_patch_core::manifest::schema::{PatchManifest, PatchRecord};
2626
use socket_patch_core::telemetry::{track_vex_failed, track_vex_generated};
2727
use socket_patch_core::vendor::state::VendorState;
2828
use 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

Comments
 (0)