use ccf_core::min_gate::{
hard_min_gate_step, reject_constant_alpha, reject_per_element_alpha, reject_soft_min_gate,
reject_weighted_average_gate, MinGateInputs, RhoConfig, CONSTANT_ALPHA_OLD_WRONG_PATH,
MIN_GATE_JOURNEY_ID, MIN_GATE_STORY_ID, PER_ELEMENT_ALPHA_OLD_WRONG_PATH,
SOFT_MIN_GATE_OLD_WRONG_PATH, WEIGHTED_AVERAGE_GATE_OLD_WRONG_PATH,
};
fn fixture(c_inst: f64, c_ctx: f64) -> MinGateInputs {
MinGateInputs {
c_inst,
c_ctx,
rho: RhoConfig::try_new(0.05, 0.75).unwrap(),
}
}
fn deterministic_ceiling_pair(index: usize) -> (f64, f64) {
let c_inst = ((index * 37 + 11) % 1000) as f64 / 1000.0;
let c_ctx = ((index * 91 + 73) % 1000) as f64 / 1000.0;
(c_inst, c_ctx)
}
fn assert_close(actual: f64, expected: f64, tolerance: f64, label: &str) {
assert!(
(actual - expected).abs() <= tolerance,
"{label}: expected {expected:.17e}, got {actual:.17e}"
);
}
#[test]
fn exact_min_random_cases_are_required() {
eprintln!("journey={MIN_GATE_JOURNEY_ID} story={MIN_GATE_STORY_ID}");
let mut cases = 0_usize;
for index in 0..1000 {
let (c_inst, c_ctx) = deterministic_ceiling_pair(index);
let expected = c_inst.min(c_ctx);
let actual = hard_min_gate_step(&fixture(c_inst, c_ctx))
.expect("hard min-gate implementation is required");
assert_eq!(
actual.g_t.to_bits(),
expected.to_bits(),
"case {index} must use exact hard min"
);
cases += 1;
}
eprintln!("exact_min_random_cases={cases}");
}
#[test]
fn adversarial_weighted_average_fixture_resolves_to_low_ceiling() {
eprintln!("journey={MIN_GATE_JOURNEY_ID} story={MIN_GATE_STORY_ID}");
let actual =
hard_min_gate_step(&fixture(0.1, 0.9)).expect("hard min-gate implementation is required");
assert_eq!(actual.g_t.to_bits(), 0.1_f64.to_bits());
assert_eq!(actual.alpha_t.to_bits(), 0.12_f64.to_bits());
eprintln!("adversarial_min_fixture=PASS c_inst=0.1 c_ctx=0.9 g_t=0.1");
}
#[test]
fn weighted_average_gate_negative_fixture_is_rejected() {
eprintln!("journey={MIN_GATE_JOURNEY_ID} story={MIN_GATE_STORY_ID}");
let report = reject_weighted_average_gate(&fixture(0.1, 0.9))
.expect("weighted-average gate negative guard is required");
assert_eq!(report.old_wrong_path, WEIGHTED_AVERAGE_GATE_OLD_WRONG_PATH);
assert!(report.rejected);
assert_eq!(report.canonical_g_t.to_bits(), 0.1_f64.to_bits());
assert_close(
report.observed_g_t,
0.66,
f64::EPSILON,
"weighted average g_t",
);
eprintln!(
"weighted_average_gate_negative=PASS old_wrong_path={} observed_g_t={:.16e} g_t_excursion={:.16e}",
report.old_wrong_path,
report.observed_g_t,
(report.observed_g_t - report.canonical_g_t).abs()
);
}
#[test]
fn soft_min_gate_negative_fixture_is_rejected() {
eprintln!("journey={MIN_GATE_JOURNEY_ID} story={MIN_GATE_STORY_ID}");
let report =
reject_soft_min_gate(&fixture(0.1, 0.9)).expect("soft-min gate negative guard is required");
assert_eq!(report.old_wrong_path, SOFT_MIN_GATE_OLD_WRONG_PATH);
assert!(report.rejected);
assert_eq!(report.canonical_g_t.to_bits(), 0.1_f64.to_bits());
assert_close(
report.observed_g_t,
0.09001166670939242,
1.0e-16,
"soft-min g_t",
);
eprintln!(
"soft_min_gate_negative=PASS old_wrong_path={} observed_g_t={:.16e} g_t_excursion={:.16e}",
report.old_wrong_path,
report.observed_g_t,
(report.observed_g_t - report.canonical_g_t).abs()
);
}
#[test]
fn constant_alpha_negative_fixture_is_rejected() {
eprintln!("journey={MIN_GATE_JOURNEY_ID} story={MIN_GATE_STORY_ID}");
let report = reject_constant_alpha(&fixture(0.1, 0.9))
.expect("constant alpha negative guard is required");
assert_eq!(report.old_wrong_path, CONSTANT_ALPHA_OLD_WRONG_PATH);
assert!(report.rejected);
assert_eq!(report.canonical_alpha_t.to_bits(), 0.12_f64.to_bits());
assert_eq!(report.observed_alpha_t.to_bits(), 0.35_f64.to_bits());
eprintln!(
"constant_alpha_negative=PASS old_wrong_path={} observed_alpha_t={:.16e} alpha_t_excursion={:.16e}",
report.old_wrong_path,
report.observed_alpha_t,
(report.observed_alpha_t - report.canonical_alpha_t).abs()
);
}
#[test]
fn per_element_alpha_negative_fixture_is_rejected() {
eprintln!("journey={MIN_GATE_JOURNEY_ID} story={MIN_GATE_STORY_ID}");
let report = reject_per_element_alpha(&fixture(0.1, 0.9))
.expect("per-element alpha negative guard is required");
assert_eq!(report.old_wrong_path, PER_ELEMENT_ALPHA_OLD_WRONG_PATH);
assert!(report.rejected);
assert_eq!(report.canonical_alpha_t.to_bits(), 0.12_f64.to_bits());
assert_eq!(report.observed_alpha_t.to_bits(), 0.68_f64.to_bits());
eprintln!(
"per_element_alpha_negative=PASS old_wrong_path={} observed_alpha_t={:.16e} alpha_t_excursion={:.16e}",
report.old_wrong_path,
report.observed_alpha_t,
(report.observed_alpha_t - report.canonical_alpha_t).abs()
);
}