feat(aura-research, aura-runner): RiskRegime::Fixed — the fixed stop is campaign-reachable

Harvest sweep, batch 3 of 6 (second half).

The third externally-tagged variant ('{"fixed":{"distance":..}}',
additive — stored Vol/VolTf documents keep their bytes): doc-tier
validation mirrors FixedStop::new's distance>0 assert (NaN refused)
so the assert is unreachable from a document; stop_rule_for_regime
binds the shipped FixedStop composite; run_blueprint_member stamps
stop_distance beside the vol knobs' precedent and
stop_rule_from_params re-derives Fixed from it (stamps are mutually
exclusive; the pre-#233 no-knob fallback is unchanged). BadRegime
prose widened to name the distance rule. C10's risk-axis paragraph
updates from 'additive when needed' to shipped; glossary gains the
fixed variant.

closes #338
This commit is contained in:
2026-07-26 12:10:43 +02:00
parent c39f5e4762
commit 2b692a71e3
7 changed files with 212 additions and 35 deletions
+64 -2
View File
@@ -662,7 +662,7 @@ fn campaign_validate_refuses_bad_risk_regime_prose_exit_1() {
let (out, code) = run_code_in(&dir, &["campaign", "validate", "risk-bad.campaign.json"]);
assert_eq!(code, Some(1), "stdout/stderr: {out}");
assert!(
out.contains("risk[0]: stop length must be >= 1 and k must be > 0"),
out.contains("risk[0]: stop length must be >= 1, k must be > 0, and a fixed-stop distance must be > 0"),
"stdout/stderr: {out}"
);
assert!(!out.contains("BadRegime"), "Debug leak: {out}");
@@ -1192,7 +1192,7 @@ fn campaign_register_refuses_invalid_risk_section_and_writes_nothing() {
assert_eq!(code, Some(1), "stdout/stderr: {out}");
assert!(out.contains("refusing to register:"), "stdout/stderr: {out}");
assert!(
out.contains("risk[0]: stop length must be >= 1 and k must be > 0"),
out.contains("risk[0]: stop length must be >= 1, k must be > 0, and a fixed-stop distance must be > 0"),
"stdout/stderr: {out}"
);
assert!(
@@ -3086,6 +3086,68 @@ fn campaign_run_real_e2e_non_default_regime_stamps_its_own_stop() {
}
}
/// Property (#338, the `campaign_run_real_e2e_non_default_regime_stamps_its_own_stop`
/// precedent above, `Fixed` edition): a campaign document's `RiskRegime::Fixed`
/// reaches the real `CliMemberRunner::run_member` path and IS the stop actually
/// stamped into each emitted member's manifest as `stop_distance` — making the
/// shipped `FixedStop` composite campaign-reachable end to end, not merely
/// intrinsically valid.
#[test]
fn campaign_run_real_e2e_fixed_regime_stamps_its_own_distance() {
let (dir, _fixture) = fresh_project();
let runs_dir = dir.join("runs");
std::fs::remove_dir_all(&runs_dir).ok();
let _cleanup = ScratchGuard(vec![
ScratchPath::Dir(runs_dir.clone()),
ScratchPath::File(dir.join("fixed_regime.process.json")),
ScratchPath::File(dir.join("fixed_regime.campaign.json")),
]);
let bp_id = seed_blueprint(&dir, "campaign-run-fixed-regime-seed");
let proc_id = register_process_doc(&dir, "fixed_regime.process.json", SWEEP_ONLY_PROCESS_DOC);
let base = campaign_doc_json(
&bp_id,
&proc_id,
(1725148800000, 1727740799999),
"",
"\"family_table\"",
);
let with_regime = base.replacen(
"\"seed\": 7,",
"\"seed\": 7,\n \"risk\": [ { \"fixed\": { \"distance\": 12.0 } } ],",
1,
);
assert_ne!(with_regime, base, "replacen must actually match the fixture's seed field");
write_doc(&dir, "fixed_regime.campaign.json", &with_regime);
let (out, code) = run_code_in(&dir, &["exec", "fixed_regime.campaign.json"]);
if code == Some(3)
&& (out.contains("no recorded geometry") || out.contains("no data for instrument"))
{
eprintln!("skip: no local GER40 data for the fixed-regime campaign e2e");
return;
}
assert_eq!(code, Some(0), "stdout/stderr: {out}");
let member_lines: Vec<&str> =
out.lines().filter(|l| l.starts_with("{\"family_id\":")).collect();
assert!(!member_lines.is_empty(), "family_table member lines emitted: {out}");
for line in &member_lines {
let v: serde_json::Value = serde_json::from_str(line).expect("member line parses as JSON");
let params = v["report"]["manifest"]["params"]
.as_array()
.expect("manifest.params is an array");
let get = |name: &str| params.iter().find(|p| p[0].as_str() == Some(name));
assert_eq!(
get("stop_distance").and_then(|p| p[1]["F64"].as_f64()),
Some(12.0),
"the campaign's own fixed distance is stamped, not the R_SMA vol-stop default: {line}"
);
assert!(
get("stop_length").is_none() && get("stop_k").is_none(),
"a Fixed stop stamps no vol knobs: {line}"
);
}
}
/// Property (#210 T3/T4 — per-cell regime resolution, not a shared last-write):
/// a campaign with TWO distinct non-default risk regimes stamps EACH regime's
/// OWN stop into ITS OWN cell's members, never the other regime's values and