fix(aura-engine): unify RunReport stdout JSON with the on-disk serde shape
RunReport had two divergent JSON encoders: the registry serialized to disk via serde_json (params as an array-of-pairs, floats as 2.0), while stdout rendered through a hand-rolled to_json (params as an object, whole floats as 2). The same record was a structurally different document on disk than on the wire, and no test pinned their relationship — most visibly, `aura runs list` read a record from disk via serde and reprinted it in a different shape. Retire the hand-rolled writer: RunReport::to_json now delegates to serde_json::to_string(self), so stdout is byte-identical to the runs.jsonl line for the same record. The hand-rolled json_str helper is deleted (the graph_model.rs json_str is a separate symbol, untouched — the graph-model JSON is out of scope, #58/#28). A new pin test, to_json_equals_serde_disk_shape, asserts to_json() == serde_json::to_string(&report) so the two encoders can never silently diverge again. Observable change: stdout `params` is now an array-of-pairs and finite f64 fields carry a fractional part (2 -> 2.0); the nested envelope, field order, window [from,to], and integer-valued seed/exposure_sign_flips are unchanged. The on-disk shape does NOT change — only stdout moves to match disk. serde_json is promoted from a dev-dependency to a normal dependency of aura-engine (to_json is non-test code). Under the amended C16 per-case policy this passes: serde_json is a vetted standard crate already in the workspace (registry, ingest), deterministic (C1-safe, already relied on for the disk path), and is exactly "the vetted standard crate doing what the code would otherwise hand-roll" — it removes the last hand-rolled RunReport JSON writer. Goldens flipped to the serde shape: the engine canonical-form golden, the aura-cli sweep golden (cli_run.rs), and the aura-cli odometer-order sweep golden (main.rs) — the last was not in the plan's inventory; the cargo test --workspace gate surfaced it and it took the identical transformation. Structural CLI asserts and the r1.to_json()==r2.to_json() determinism asserts are shape-agnostic and stay green. Spec docs/specs/0033, plan docs/plans/0033, boss-signed (unanimous 5-lens panel). Two stale prose cross-refs (graph_model.rs:30, docs/design/INDEX.md:729) deferred to cycle-close audit. Gates: cargo build/test --workspace green, clippy --all-targets -D warnings clean. closes #54
This commit is contained in:
@@ -211,7 +211,7 @@ fn sweep_prints_four_json_lines_and_exits_zero() {
|
||||
// pin the first odometer point's manifest params, not the commit value.
|
||||
assert!(first.starts_with("{\"manifest\":{\"commit\":\""), "got: {stdout}");
|
||||
assert!(
|
||||
first.contains("\"params\":{\"sma_cross.fast.length\":2,\"sma_cross.slow.length\":4,\"exposure.scale\":0.5}"),
|
||||
first.contains("\"params\":[[\"sma_cross.fast.length\",2.0],[\"sma_cross.slow.length\",4.0],[\"exposure.scale\",0.5]]"),
|
||||
"got: {stdout}"
|
||||
);
|
||||
let _ = std::fs::remove_dir_all(&cwd);
|
||||
|
||||
Reference in New Issue
Block a user