bench: harden architecture scan evidence #1

Merged
trevon merged 4 commits from bench/yams-architecture-reproducibility into main 2026-08-30 22:09:35 +00:00
Showing only changes of commit e03c2a299b - Show all commits

fix(fold): normalize imported finding paths

trvon 2026-08-30 14:07:43 -06:00
Signed by: trevon
GPG key ID: 38686EA797D7A8A7

View file

@ -207,19 +207,45 @@ fn native_backend(value: &Value) -> String {
}
fn find_file(building: &Building, path: &str) -> Option<String> {
let normalized = path.replace('\\', "/");
let normalized = normalize_lexical_path(path);
building
.nodes
.iter()
.filter(|node| node.kind == NodeKind::File)
.find(|node| {
node.path.as_deref().is_some_and(|candidate| {
let candidate = normalize_lexical_path(candidate);
normalized == candidate || normalized.ends_with(&format!("/{candidate}"))
})
})
.map(|node| node.id.clone())
}
fn normalize_lexical_path(path: &str) -> String {
let portable = path.replace('\\', "/");
let absolute = portable.starts_with('/');
let mut components = Vec::new();
for component in portable.split('/') {
match component {
"" | "." => {}
".." => {
if components.last().is_some_and(|previous| *previous != "..") {
components.pop();
} else if !absolute {
components.push(component);
}
}
_ => components.push(component),
}
}
let normalized = components.join("/");
if absolute {
format!("/{normalized}")
} else {
normalized
}
}
fn confidence_value(confidence: &str) -> f64 {
match confidence {
"concrete-witness" => 1.0,
@ -258,4 +284,52 @@ mod tests {
assert_eq!(finding.attributes["confidence"], "proved");
assert_eq!(finding.attributes["backend"], "source");
}
#[test]
fn normalizes_fold_paths_without_matching_a_missing_neighbor() {
let dir = tempfile::tempdir().unwrap();
let header = dir.path().join("include/yams/core/types.h");
fs::create_dir_all(header.parent().unwrap()).unwrap();
fs::write(&header, "struct Type {};\n").unwrap();
let report = dir.path().join("fold.sarif");
fs::write(
&report,
r#"{
"runs": [{
"results": [
{
"ruleId": "fold.valid",
"message": {"text": "valid"},
"locations": [{"physicalLocation": {
"artifactLocation": {"uri": "../../include/yams/daemon/components/../../core/types.h"},
"region": {"startLine": 1}
}}]
},
{
"ruleId": "fold.missing",
"message": {"text": "missing"},
"locations": [{"physicalLocation": {
"artifactLocation": {"uri": "../../include/yams/daemon/components/../../core/missing.h"},
"region": {"startLine": 1}
}}]
}
]
}]
}"#,
)
.unwrap();
let mut building = scan(dir.path()).unwrap();
assert_eq!(import_findings(&mut building, &report).unwrap(), 1);
assert_eq!(
building
.nodes
.iter()
.filter(|node| node.kind == NodeKind::Finding)
.count(),
1
);
assert_eq!(building.diagnostics.len(), 1);
assert!(building.diagnostics[0].message.contains("missing.h"));
}
}