use std::process::Command;
fn synth() -> &'static str {
env!("CARGO_BIN_EXE_synth")
}
fn fixture(name: &str) -> std::path::PathBuf {
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("scripts/repro")
.join(name)
}
fn census(fix: &str) -> (usize, usize) {
let path = fixture(fix);
let out = Command::new(synth())
.env("SYNTH_CMP_SELECT_FUSE", "1")
.env("SYNTH_FUSE_STATS", "1")
.args([
"compile",
path.to_str().unwrap(),
"-o",
&format!("/tmp/census_{fix}.elf"),
"--target",
"cortex-m4",
"--all-exports",
"--relocatable",
])
.output()
.expect("run synth");
assert!(
out.status.success(),
"synth compile failed for {fix}: {}",
String::from_utf8_lossy(&out.stderr)
);
let combined = format!(
"{}{}",
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
);
let mut total = 0usize;
let mut two_move = 0usize;
for l in combined.lines().filter(|l| l.contains("[cmp-select-fuse]")) {
let n: usize = l
.split("[cmp-select-fuse]")
.nth(1)
.and_then(|r| r.trim_start().split(' ').next())
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| panic!("unparseable fuse line: {l}"));
let k: usize = l
.split("two-move")
.next()
.and_then(|seg| {
seg.trim_end()
.rsplit(|c: char| c.is_whitespace() || c == '(')
.find(|s| !s.is_empty())
})
.and_then(|s| s.parse().ok())
.unwrap_or_else(|| panic!("unparseable two-move count: {l}"));
total += n;
two_move += k;
}
(total, two_move)
}
const BASELINE: &[(&str, usize, usize)] = &[
("control_step.wasm", 3, 0),
("flight_seam.wasm", 12, 0),
("flight_seam_flat.wasm", 12, 0),
("signed_div_const.wasm", 0, 0),
];
#[test]
fn fusion_census_matches_frozen_baseline_428() {
let mut grand_total = 0usize;
let mut grand_two_move = 0usize;
for &(fix, want_total, want_two_move) in BASELINE {
let (total, two_move) = census(fix);
assert_eq!(
(total, two_move),
(want_total, want_two_move),
"{fix}: fusion census drifted — got (total={total}, two_move={two_move}), \
baseline (total={want_total}, two_move={want_two_move}). A selector change \
altered the cmp→select blast radius; re-measure and update BASELINE \
deliberately (and tell gale — the flip blast radius moved)."
);
grand_total += total;
grand_two_move += two_move;
}
assert!(
grand_total >= 1,
"expected cmp→select to fuse on the frozen fixtures (got {grand_total})"
);
assert_eq!(
grand_two_move, 0,
"a real frozen fixture now exercises the two-move arm ({grand_two_move} sites) — \
update BASELINE and notify gale that the flip's runtime path gained real-code \
coverage beyond gust_mix"
);
}