test(0092): run-from-blueprint E2E + bit-identical keystone + demo fixtures

Closes the cycle-1 test coverage for #165. The `aura run <blueprint.json>` CLI
arm itself (the .json dispatch + parse_blueprint_run_args + BlueprintRunArgs)
shipped in ff4a1b3; this adds the coverage that proves it and the in-repo demo
blueprint:

- crates/aura-cli/tests/fixtures/stage1_signal.json — the canonical SMA-cross
  signal (blueprint_to_json of stage1_signal(2,4)); emit_demo_signal_fixture
  (#[ignore]) regenerates it.
- crates/aura-cli/tests/fixtures/unknown_node.json — one type set to "Nope" for
  the fail-clean guard.
- loaded_signal_runs_bit_identical_to_rust_built (the keystone, C1): a signal
  serialized -> loaded via blueprint_from_json -> run is bit-identical to its
  Rust-built twin, incl. topology_hash (64-hex).
- topology_hash_is_stable_and_distinguishes (#158 anchor property).
- cli_run.rs E2E: `aura run <demo>` exits 0 with topology_hash in the manifest;
  an unknown-node blueprint fails clean with UnknownNodeType (the #160 closed-set
  guard at the data-plane face, invariant 9).

Verified end-to-end by actually running the binary: `aura run stage1_signal.json`
-> RunReport with a 64-hex topology_hash, sim-optimal+risk-executor broker, R
metrics; `aura run unknown_node.json` -> UnknownNodeType("Nope"), exit 2. Full
workspace suite green; clippy --all-targets -D warnings clean.

refs #165
This commit is contained in:
2026-06-30 20:48:02 +02:00
parent 43a25547ce
commit 2b1c24668d
4 changed files with 65 additions and 0 deletions
+31
View File
@@ -4945,6 +4945,37 @@ mod tests {
assert!(parse_blueprint_run_args(&["--params", "[{\"I64\":1}]", "--params", "[]"]).is_err()); // repeated
}
/// Regenerates the committed demo signal blueprint the `aura run <file.json>`
/// E2E loads. Ignored by default; run with `--ignored` after a signal change.
#[test]
#[ignore = "regenerates the committed demo signal blueprint fixture"]
fn emit_demo_signal_fixture() {
let json = blueprint_to_json(&stage1_signal(Some(2), Some(4))).expect("serializes");
std::fs::write("tests/fixtures/stage1_signal.json", json).expect("write fixture");
}
/// The cycle-1 keystone (C1): a signal serialized → loaded back through the
/// public `blueprint_from_json` path runs bit-identically to its Rust-built
/// twin — same metrics, same traces, same topology_hash.
#[test]
fn loaded_signal_runs_bit_identical_to_rust_built() {
let json = blueprint_to_json(&stage1_signal(Some(2), Some(4))).expect("serializes");
let loaded = blueprint_from_json(&json, &|t| std_vocabulary(t)).expect("loads");
let a = run_signal_stage1r(stage1_signal(Some(2), Some(4)), &[], RunData::Synthetic, 0);
let b = run_signal_stage1r(loaded, &[], RunData::Synthetic, 0);
assert_eq!(a.to_json(), b.to_json(), "loaded run is bit-identical incl. topology_hash");
assert_eq!(a.manifest.topology_hash.as_deref().map(str::len), Some(64), "64-hex sha256 present");
}
/// `topology_hash` is deterministic per signal and distinguishes topologies —
/// the #158 reproducibility-anchor property.
#[test]
fn topology_hash_is_stable_and_distinguishes() {
let h = topology_hash(&stage1_signal(Some(2), Some(4)));
assert_eq!(h, topology_hash(&stage1_signal(Some(2), Some(4))), "same signal -> same hash");
assert_ne!(h, topology_hash(&stage1_signal(Some(3), Some(4))), "different topology -> different hash");
}
#[test]
fn parse_mc_args_bare_and_name_route_to_synthetic() {
assert_eq!(parse_mc_args(&[]), Ok(McArgs::Synthetic { name: "mc".to_string(), persist: false }));