From c5b66a442655853f49434e6a516fab7c84fdf0e4 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 20:43:23 +0000 Subject: [PATCH] adv-accept-3: ratios command (the (c'') ratio of every candidate that reached the dynamic rule) Co-Authored-By: Claude Fable 5.1 --- tools/attack/adv-accept-3/src/main.rs | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tools/attack/adv-accept-3/src/main.rs b/tools/attack/adv-accept-3/src/main.rs index efdd5d5d..bc084e21 100644 --- a/tools/attack/adv-accept-3/src/main.rs +++ b/tools/attack/adv-accept-3/src/main.rs @@ -972,6 +972,47 @@ fn naf_weight(v: u32) -> u32 { w } +// ------------------------------------------------------------------------------------------------------------ +// Q4/Q5: the (c'') ratio of every rejected candidate and the accepted one (the floor's headroom both ways) +// ------------------------------------------------------------------------------------------------------------ + +fn ratios(from: u64, count: u64, threads: usize) { + let out = Mutex::new(std::io::stdout()); + println!("# adv3 ratios {} seeds {from}..{} (internal adversarial pass, not an independent review)", utc(), from + count); + println!("seed\tattempt\tverdict\tpart\tmin_ratio2e20_milli\tmin_site\twin\tsecs"); + let era = era_bytes(); + let class = v4_era_class(&era); + let cap = max_attempts_for(&class); + run_seeds(from, count, threads, &out, |i| { + let b = steer_seed(i); + let label = format!("adv3/steer/{i}"); + let mut rows = Vec::new(); + for attempt in 0..cap { + let p = cand(&label, &b, attempt, class, &era); + let t0 = Instant::now(); + let v = check(&p); + let (verdict, part) = match &v { Ok(_) => ("accept", "-"), Err(r) => ("reject", reject_part(r)) }; + // the ratio at 2^20 on every candidate that reached the dynamic rule, floor 0 so the minimum is returned + let (ratio, site, win) = if check_static(&p).is_ok() { + match distinct_ratio_pass(&p, accept::ACCEPT_UNITS_DISTINCT_V4, 0.0) { + Ok((r, site)) => { + let w = p.instrs.iter().filter(|x| x.op == Op::Load).nth(site).map(|x| x.win).unwrap_or(9); + ((r * 1000.0) as i64, site as i64, w as i64) + } + Err(_) => (-1, -1, -1), + } + } else { + (-2, -2, -2) + }; + rows.push(format!("{i}\t{attempt}\t{verdict}\t{part}\t{ratio}\t{site}\t{win}\t{:.1}", t0.elapsed().as_secs_f64())); + if v.is_ok() { + break; + } + } + rows.join("\n") + }); +} + fn main() { let a = Args::parse(); let threads = a.u("threads", 8) as usize; @@ -985,6 +1026,7 @@ fn main() { "steer" => steer(a.u("from", 0), a.u("count", 1000), threads, a.get("plant", "none") == "hot", a.u("check-every", 50)), "static" => static_sweep(a.u("from", 0), a.u("count", 1000), threads), "era-steer" => era_steer(a.u("from", 0), a.u("count", 1000), threads), + "ratios" => ratios(a.u("from", 0), a.u("count", 300), threads), _ => usage(), } }