Compare commits

...
Author SHA1 Message Date
Sharang ParnerkarandClaude Opus 4.8 6af84c5216 fix(orchestrator): refresh control_refs on existing findings during re-scan
CI / Check (pull_request) Successful in 5m40s
CI / Detect Changes (pull_request) Skipped
CI / Deploy Agent (pull_request) Skipped
CI / Deploy Dashboard (pull_request) Skipped
CI / Deploy Docs (pull_request) Skipped
CI / Deploy MCP (pull_request) Skipped
CI / Check (push) Skipped
The dedup loop only inserted first-seen findings; re-scans skipped existing
fingerprints entirely, so control_refs (re)computed by the mapping passes were
discarded. A finding first seen before control mapping was enabled/tuned would
therefore never gain its control mappings without being deleted + re-added.

Now: existing findings whose re-scan produced non-empty control_refs get updated
in place ($set control_refs). Guarded on non-empty so a run where mapping didn't
run (breakpilot unreachable) can't wipe existing refs. New findings unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 14:18:04 +02:00
+20 -1
View File
@@ -277,8 +277,10 @@ impl PipelineOrchestrator {
}
}
// Dedup against existing findings and insert new ones
// Dedup against existing findings: insert first-seen ones, and refresh the
// control mappings on ones we've seen before.
let mut new_count = 0u32;
let mut refreshed_count = 0u32;
let mut new_findings: Vec<Finding> = Vec::new();
for mut finding in all_findings {
finding.scan_run_id = Some(scan_run_id.to_string());
@@ -293,8 +295,25 @@ impl PipelineOrchestrator {
finding.id = result.inserted_id.as_object_id();
new_findings.push(finding);
new_count += 1;
} else if !finding.control_refs.is_empty() {
// Re-scan refresh: a mapping pass (newly enabled or tuned) computed
// control_refs for a finding first seen before mapping ran. Persist
// them onto the existing row — the insert path alone never would.
self.db
.findings()
.update_one(
doc! { "fingerprint": &finding.fingerprint },
doc! { "$set": { "control_refs": finding.control_refs.clone() } },
)
.await?;
refreshed_count += 1;
}
}
if refreshed_count > 0 {
tracing::info!(
"[{repo_id}] Refreshed control_refs on {refreshed_count} existing findings"
);
}
// Remove stale SBOM entries for this repo before reinserting
if !sbom_entries.is_empty() {