fix(aura-runner, aura-cli): the reference hash reaches the run before persistence

Harvest sweep, review re-check fix.

The prior fix corrected only the stdout record line: run_signal_r
persists the manifest to runs/traces/<name>/index.json (bound.finish)
BEFORE the post-hoc overwrite ran, so an overridden run's trace store
still carried the reopened hash — diverging from stdout in exactly the
case the revised C24/C18 clause describes. run_signal_r now takes
topo: Option<&str> (None = inline computation as before; Some = the
caller's reference-semantics hash, the run_blueprint_member precedent)
so record line and trace index read the one hash built before any
persistence; exec's override branch passes the base document's id and
the post-run mutation is gone. RED-first: the new trace-store pin
failed against the divergent state.

refs #343
This commit is contained in:
2026-07-26 13:47:58 +02:00
parent ef24f06547
commit 567f98b4e5
3 changed files with 83 additions and 20 deletions
+46
View File
@@ -612,6 +612,52 @@ base {base_out} / overridden {ov_out}"
);
}
/// Follow-up to the #343 revised pin above: `run_signal_r`'s in-graph tap
/// persistence (`bound.finish(&manifest)`, `aura-registry::trace_store`)
/// writes `traces/<name>/index.json` INSIDE `run_signal_r`, before
/// `exec_blueprint_leg` ever sees the returned `RunReport` — so the
/// persisted manifest must ALSO carry the base document's reference-semantics
/// hash, not just the stdout record line. A tap-bearing blueprint (so
/// `index.json` exists to inspect) with a no-op `--override` pins that the
/// override run's persisted `topology_hash` equals both its own stdout hash
/// and the un-overridden base run's hash.
#[test]
fn exec_blueprint_override_persists_the_base_documents_hash_in_the_trace_store() {
let cwd = temp_cwd("override-persisted-hash");
let bp_path = cwd.join("tapped_r_sma.json");
std::fs::write(&bp_path, tap_blueprint_json()).expect("write tapped blueprint");
let (base_out, base_code) =
run_code_in(&cwd, &["exec", bp_path.to_str().expect("utf-8 path")]);
assert_eq!(base_code, Some(0), "stdout/stderr: {base_out}");
let base_line = base_out.lines().find(|l| l.starts_with('{')).expect("record line");
let base_v: serde_json::Value = serde_json::from_str(base_line).expect("record parses");
let base_hash =
base_v["manifest"]["topology_hash"].as_str().expect("base topology_hash").to_string();
let (ov_out, ov_code) = run_code_in(
&cwd,
&["exec", bp_path.to_str().expect("utf-8 path"), "--override", "fast.length=2"],
);
assert_eq!(ov_code, Some(0), "stdout/stderr: {ov_out}");
let ov_line = ov_out.lines().find(|l| l.starts_with('{')).expect("record line");
let ov_v: serde_json::Value = serde_json::from_str(ov_line).expect("record parses");
let ov_stdout_hash =
ov_v["manifest"]["topology_hash"].as_str().expect("overridden topology_hash").to_string();
assert_eq!(ov_stdout_hash, base_hash, "stdout already carries the base document's hash");
let index_text = std::fs::read_to_string(cwd.join("runs/traces/sma_signal/index.json"))
.expect("read index.json");
let index: serde_json::Value = serde_json::from_str(&index_text).expect("parse index.json");
let persisted_hash =
index["manifest"]["topology_hash"].as_str().expect("persisted topology_hash").to_string();
assert_eq!(
persisted_hash, base_hash,
"the trace store's persisted manifest must carry the SAME reference-semantics hash \
as stdout, not the reopened topology's own — index.json: {index_text}"
);
}
/// A malformed override token (no `NODE.PARAM=VALUE` shape) refuses as usage.
#[test]
fn exec_override_malformed_token_refuses_with_usage() {