fix(aura-cli, aura-runner): review findings — duplicate --override refusal, live discovery prose, neutral JSON refusal

In-cycle fixes for the independent review of the #319 package, RED-first
for both Importants. A repeated --override path now refuses at the shared
lexer (exit 2, path named) instead of panicking exit 101 through
reopen_all — which also un-misattributes the campaign leg's collision
prose for duplicates. override_paths' refusal points at aura graph
introspect --params (the retired --list-axes reference swept from every
live comment, one explicitly-historical mention remains). exec classifies
file targets through a Result-bearing peek: unparseable JSON refuses
neutrally before any leg is chosen. RunPresentation (single-variant)
removed; run_campaign_returning's contract note names its one deliberate
usage-class exit; C14's routing sentence and C20's family-builder
paragraph amended to current truth (superseded text to the history
sidecars); bench error strings and deletion blank-line runs tidied.

refs #319
This commit is contained in:
2026-07-25 23:21:07 +02:00
parent 9eb6d6b4f6
commit dc5f1742f4
14 changed files with 326 additions and 236 deletions
+63 -133
View File
@@ -203,7 +203,6 @@ fn sweep_campaign_doc(
)
}
/// Property (ported onto a one-cell campaign document, #319 Task 8 — the
/// retired `run --real` verb's own hard exit-1/no-stdout contract does not
/// survive the campaign path's #272 contained-fault model, but the pip-honesty
@@ -391,9 +390,6 @@ fn run_real_nonvetted_symbol_resolves_pip_from_sidecar() {
);
}
// Note (#159 cut 4 collateral): `--trace` on a single `aura run`/`aura sweep`
// is no longer reachable from any CLI surface — the built-in default that
// accepted it retired with the last two PIP strategies, and the blueprint
@@ -736,8 +732,6 @@ fn no_args_prints_usage_and_exits_two() {
assert!(stderr.contains("Usage"), "stderr was: {stderr:?}");
}
/// Property: `aura graph` emits a single self-contained HTML page — the
/// interactive pin-graph viewer with the deterministic model inlined and the
/// vendored Graphviz-WASM + pan-zoom inlined (no remote fetch). Driven through
@@ -878,7 +872,6 @@ fn graph_with_bad_blueprint_arg_is_a_usage_fault_not_a_silent_sample() {
);
}
#[test]
fn runs_families_list_and_per_family_rank_across_invocations() {
// Ported onto a one-cell campaign document run twice (#319 Task 8): two
@@ -1328,7 +1321,6 @@ fn run_real_ohlc_channel_example_end_to_end_hostless() {
);
}
/// The dissolved real-data sweep + reproduce over the OHLC example (#231
/// acceptance), ported onto a one-cell campaign document (#319 Task 8 —
/// `--list-axes` itself is dead flag surface, retired with `sweep`; its
@@ -1755,24 +1747,27 @@ fn reproduce_real_sweep_family_re_derives_bit_identically() {
/// overriding only the `fast.length` axis and leaving `slow.length` bound —
/// unlike the walk-forward reproduce sibling
/// (`aura_walkforward_over_a_blueprint_reproduces_bit_identically`), which
/// overrides both axes over the same closed blueprint. The walk-forward
/// synthetic route's own `--axis` intake is now RAW (this cycle's tidy fix,
/// #328): the CLI preflight refuses a wrapped name before this run ever starts
/// overrides both axes over the same closed blueprint. Originally modelled on
/// that sibling (the retired synthetic in-process walk-forward dispatch verb —
/// no `--real`), NOT on `reproduce_real_sweep_family_re_derives_bit_identically`:
/// a real-data mint routed through the campaign executor
/// (`CliMemberRunner::run_member` + `validate_and_register_axes`), neither of
/// which carried any #246 override threading — a gap outside that task's file
/// scope (`blueprint_sweep_over`, `reproduce_family_in`) and spanning all four
/// (then-live) dispatch verbs, so exercising it there would have silently
/// expanded into unrelated, unreviewed surface. Back when the synthetic
/// walk-forward dispatch verb existed, its `--axis` intake was RAW (#328): the
/// CLI preflight refused a wrapped name before the run ever started
/// (`refuse_wrapped_synthetic_axes`), and `blueprint_sweep_over`'s own
/// `SweepBinder` call translates the RAW name onto its wrapped `param_space()`
/// slot (`wrapped_name_of`) before keying by it.
/// Modelled on that sibling (synthetic in-process walk-forward — no `--real`),
/// NOT on `reproduce_real_sweep_family_re_derives_bit_identically`: a real-data
/// mint routes through the campaign executor (`CliMemberRunner::run_member` +
/// `validate_and_register_axes`), neither of which carries any #246 override
/// threading — a gap outside this task's file scope (`blueprint_sweep_over`,
/// `reproduce_family_in`) and spanning all four dispatch verbs, so exercising
/// it here would silently expand into unrelated, unreviewed surface. The
/// synthetic walk-forward path exercises exactly the threaded functions:
/// `blueprint_sweep_over` (via `blueprint_walkforward_family`) re-opens
/// `fast.length` for the per-window IS re-fit, and
/// `reproduce_family_in` re-opens it again from the recorded manifest params
/// so the re-derivation resolves against the same space the mint used.
/// `SweepBinder` call translated the RAW name onto its wrapped `param_space()`
/// slot (`wrapped_name_of`) before keying by it. That path exercised exactly
/// the threaded functions: `blueprint_sweep_over` (via
/// `blueprint_walkforward_family`) re-opened `fast.length` for the per-window
/// IS re-fit, and `reproduce_family_in` re-opened it again from the recorded
/// manifest params so the re-derivation resolved against the same space the
/// mint used. #319 Task 8 ported this test onto the campaign
/// `std::walk_forward` stage (see the in-body port note below); the property
/// pinned here is unchanged.
#[test]
fn reproduce_family_with_overridden_bound_param_re_derives() {
// Ported onto a `[std::grid, std::walk_forward]` campaign document over
@@ -1939,7 +1934,6 @@ fn reproduce_real_walkforward_family_does_not_panic() {
// fixture at a single axis value instead.)
const HL_SIGNAL_OPEN_BLUEPRINT: &str = r#"{"format_version":1,"blueprint":{"name":"hl_signal","doc":"high/low SMA difference clamped into a directional bias","nodes":[{"primitive":{"type":"SMA","name":"fast"}},{"primitive":{"type":"SMA","name":"slow"}},{"primitive":{"type":"Sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}}],"edges":[{"from":0,"to":2,"slot":0,"from_field":0},{"from":1,"to":2,"slot":1,"from_field":0},{"from":2,"to":3,"slot":0,"from_field":0}],"input_roles":[{"name":"high","targets":[{"node":0,"slot":0}],"source":"F64"},{"name":"low","targets":[{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":3,"field":0,"name":"bias"}]}}"#;
// Note (#319 Task 8, disposition deviation): `walkforward_synthetic_refuses_a_
// multi_column_blueprint_before_data_access` (the synthetic, no-`--real`
// exit-process arm) retired rather than ported — it is a byte-identical twin
@@ -2042,12 +2036,6 @@ fn sweep_real_multi_column_blueprint_opens_high_and_low_columns() {
}
}
/// Property (issue #246, task 5): the dissolved real-data `aura sweep`
/// campaign path accepts an `--axis` naming a BOUND param of a CLOSED
/// blueprint, not only an already-open one. Tasks 3-4 threaded this override
@@ -2168,11 +2156,6 @@ fn sweep_over_a_bound_override_matches_the_historical_open_bind() {
);
}
// Note (#159 cut 4 collateral): this removes the `aura chart <name>`
// CLI-integration tests (single-run and family overlay/tap-filter/meta, the
// cross-kind write-guard collision + same-kind-overwrite pair) — every one of
@@ -2188,12 +2171,6 @@ fn sweep_over_a_bound_override_matches_the_historical_open_bind() {
// --- `aura run --harness <name>` selector (iter-3 Task 3) --------------------
/// Property: `aura generalize` grades a single r-sma candidate across two
/// instruments — its stdout carries the per-instrument breakdown + the worst-case
/// floor + the sign-agreement, then the persisted CrossInstrument family handle.
@@ -2307,17 +2284,20 @@ fn generalize_real_e2e_pins_the_exact_current_grade() {
assert_eq!(per[1][1].as_f64(), Some(0.005795903617609842), "USDJPY expectancy R: {record_line}");
}
/// Property (#220 generalize vertical): `aura generalize` grades ANY sweepable
/// blueprint, not just the historical r-sma candidate — the whole point of
/// dropping `--strategy r-sma`/`--fast`/`--slow` for a positional blueprint +
/// generic `--axis`. Every other generalize E2E test here still exercises
/// `r_sma.json`, so a regression that silently special-cased r-sma paths
/// back in (e.g. resolving axes against a hardcoded `sma_signal.*` namespace)
/// would ship green there while breaking every other blueprint. This runs the
/// unrelated r-breakout candidate (the ganged `channel_length` axis, no
/// `sma_signal` node in sight) end-to-end and asserts a well-formed two-
/// instrument grade. Gated on the shared GER40/USDJPY Sept-2024 archive; skips
/// cleanly on a data refusal.
/// Property (#220 generalize vertical, ported onto the campaign
/// `std::generalize` stage by #319 Task 8): grades ANY sweepable blueprint,
/// not just the historical r-sma candidate — originally the whole point of
/// the retired `aura generalize` verb dropping `--strategy r-sma`/`--fast`/
/// `--slow` for a positional blueprint + generic `--axis`; the property
/// survives the #319 dissolution onto a `std::sweep, std::generalize`
/// process document unchanged. Every other generalize E2E test here still
/// exercises `r_sma.json`, so a regression that silently special-cased
/// r-sma paths back in (e.g. resolving axes against a hardcoded
/// `sma_signal.*` namespace) would ship green there while breaking every
/// other blueprint. This runs the unrelated r-breakout candidate (the
/// ganged `channel_length` axis, no `sma_signal` node in sight) end-to-end
/// and asserts a well-formed two-instrument grade. Gated on the shared
/// GER40/USDJPY Sept-2024 archive; skips cleanly on a data refusal.
#[test]
fn generalize_grades_a_non_r_sma_blueprint() {
// Ported onto a `[std::sweep, std::generalize]` campaign document
@@ -2367,18 +2347,20 @@ fn generalize_grades_a_non_r_sma_blueprint() {
}
/// Characterization pin (byte-identity anchor for the walkforward dissolution,
/// #210). The current `aura walkforward` runs its per-window IS-refit inline
/// (`walkforward_family` -> `select_winner` -> OOS run -> stitch/pool); the
/// dissolution reroutes the same rolling IS-sweep -> OOS-run -> deflation through
/// the campaign `std::walk_forward` stage, and must retain the OOS pip curve the
/// campaign runner currently discards (`oos_equity: vec![]`) to reproduce
/// #210, ported onto the campaign path by #319 Task 8). The original `aura
/// walkforward` verb ran its per-window IS-refit inline (`walkforward_family`
/// -> `select_winner` -> OOS run -> stitch/pool); the dissolution rerouted the
/// same rolling IS-sweep -> OOS-run -> deflation through the campaign
/// `std::walk_forward` stage, retaining the OOS pip curve the campaign runner
/// used to discard (`oos_equity: vec![]`) so it could still reproduce
/// `stitched_total_pips`, plus reconstruct pooled `oos_r`. The multi-point grid
/// (fast 3,5 x slow 12,20) makes the per-window winner selection non-degenerate --
/// `param_stability` varies across windows -- so a winner-pick divergence between
/// the inline and campaign refit cannot ship green. This pins the EXACT current
/// grade of the identical invocation over a fixed 2025 GER40 window; after the
/// dissolution the same command must reproduce these bytes (the acceptance gate).
/// Gated on the shared GER40 archive; skips cleanly on a data refusal.
/// the inline and campaign refit could not have shipped green. This pins the
/// EXACT grade of the identical invocation over a fixed 2025 GER40 window that
/// the dissolved `std::walk_forward` stage reproduces bit-for-bit (the
/// acceptance gate the port had to clear). Gated on the shared GER40 archive;
/// skips cleanly on a data refusal.
#[test]
fn walkforward_real_e2e_pins_the_exact_current_grade() {
// Ported onto a `[std::grid, std::walk_forward]` campaign document
@@ -2453,21 +2435,24 @@ fn walkforward_real_e2e_pins_the_exact_current_grade() {
assert_eq!(ps[1]["mean"].as_f64(), Some(17.333333333333332), "slow-MA refit mean: {wf}");
}
/// Property (#220 walkforward vertical): `aura walkforward --real` IS-refits ANY
/// sweepable blueprint through the campaign path, not just the historical r-sma
/// candidate — the whole point of dropping `--strategy r-sma`/`--fast`/`--slow`
/// for a positional blueprint + generic `--axis`. Every other walkforward E2E
/// test here still exercises `r_sma.json`; a regression that silently
/// special-cased the refit's axis lookup back to a hardcoded `sma_signal.*`
/// namespace (e.g. in `walkforward_summary_json_from_reports`'s per-axis
/// `raw_matches_wrapped` search) would ship green there while breaking every
/// other blueprint. This runs the unrelated r-breakout candidate
/// (the ganged `channel_length` axis, no `sma_signal` node in sight) end-to-end
/// and asserts a well-formed multi-window summary whose `param_stability` has
/// exactly one entry per bound axis (1 ganged blueprint axis + the 2 stop columns).
/// The window count (9) is roller/data-derived, not strategy-derived, so it is
/// pinned exactly against the same GER40 2025 span the r-sma anchor uses.
/// Gated on the shared GER40 archive; skips cleanly on a data refusal.
/// Property (#220 walkforward vertical, ported onto the campaign
/// `std::walk_forward` stage by #319 Task 8): IS-refits ANY sweepable
/// blueprint, not just the historical r-sma candidate — originally the
/// whole point of the retired `aura walkforward --real` verb dropping
/// `--strategy r-sma`/`--fast`/`--slow` for a positional blueprint + generic
/// `--axis`; the property survives the #319 dissolution unchanged. Every
/// other walkforward E2E test here still exercises `r_sma.json`; a
/// regression that silently special-cased the refit's axis lookup back to a
/// hardcoded `sma_signal.*` namespace (e.g. in
/// `walkforward_summary_json_from_reports`'s per-axis `raw_matches_wrapped`
/// search) would ship green there while breaking every other blueprint.
/// This runs the unrelated r-breakout candidate (the ganged `channel_length`
/// axis, no `sma_signal` node in sight) end-to-end and asserts a well-formed
/// multi-window summary whose `param_stability` has exactly one entry per
/// bound axis (1 ganged blueprint axis + the 2 stop columns). The window
/// count (9) is roller/data-derived, not strategy-derived, so it is pinned
/// exactly against the same GER40 2025 span the r-sma anchor uses. Gated on
/// the shared GER40 archive; skips cleanly on a data refusal.
#[test]
fn walkforward_dissolves_a_non_r_sma_blueprint() {
// Ported onto a `[std::grid, std::walk_forward]` campaign document
@@ -2515,8 +2500,6 @@ fn walkforward_dissolves_a_non_r_sma_blueprint() {
assert_eq!(ps.len(), 3, "one entry per bound axis (channel_length, stop_length, stop_k): {wf}");
}
/// Characterization pin (#215): the same identical invocation as
/// `walkforward_real_e2e_pins_the_exact_current_grade` (fixture, real
/// instrument, axes, stop, window), but selecting `plateau:worst` instead of
@@ -2597,17 +2580,6 @@ fn walkforward_real_e2e_pins_the_exact_current_plateau_grade() {
assert_eq!(ps[1]["mean"].as_f64(), Some(16.444444444444443), "slow-MA refit mean: {wf}");
}
// Note (#319 Task 8, disposition finding): `generalize_without_explicit_
// window_resolves_a_shared_window_and_completes` and `generalize_without_
// explicit_window_resolves_the_intersection_of_all_symbols` retired rather
@@ -2626,12 +2598,6 @@ fn walkforward_real_e2e_pins_the_exact_current_plateau_grade() {
// window" property stays fully covered by `generalize_grades_a_candidate_
// across_two_instruments` and its siblings above.
/// Property, ported onto a `[std::sweep, std::generalize]` campaign document
/// (#319 Task 8 — disposition finding): a successful campaign generalize run
/// persists its per-instrument runs as discoverable, but NOT as a merged
@@ -2843,7 +2809,6 @@ fn aura_sweep_loads_a_blueprint_and_persists_a_sweep_family() {
assert!(fo.contains("\"members\":4"), "2×2 grid -> four members: {fo}");
}
/// Property (#158/#164, C18/C11/C12): a blueprint sweep content-addresses its topology
/// — the canonical blueprint is persisted ONCE under `runs/blueprints/<topology_hash>.json`,
/// keyed by the very SHA256 every member's manifest carries, holding exactly the bytes
@@ -3133,8 +3098,6 @@ fn aura_walkforward_over_a_blueprint_persists_a_family() {
assert_eq!(n, 1, "exactly one content-addressed blueprint stored");
}
/// E2E (#278 decision: same fault class, same verb, same surface => same
/// treatment): a member fault on the SYNTHETIC walk-forward path is CONTAINED
/// exactly like the real/campaign path contains it (#272) — it surfaces as an
@@ -3218,14 +3181,6 @@ fn aura_sweep_synthetic_member_panic_is_contained() {
);
}
/// E2E (negative): `aura reproduce <unknown>` is a hard error (exit non-zero + named
/// cause on stderr), distinct from `runs family <id>`'s treat-as-empty exit 0.
#[test]
@@ -3275,13 +3230,6 @@ fn aura_reproduce_rejects_a_missing_stored_blueprint() {
assert!(out.contains("missing from store"), "names the cause: {out}");
}
/// `--version` / `-V` surface the crate version on stdout and exit 0 (GNU MUST):
/// a version query is a successful query, not a usage error. The expected string
/// is the crate version itself (`CARGO_PKG_VERSION`, i.e. the workspace version),
@@ -3335,13 +3283,6 @@ fn version_flag_carries_the_engine_commit_from_manifest_provenance() {
);
}
/// Characterization pin (byte-identity anchor for the mc R-bootstrap dissolution,
/// #210, the last verb; argv since migrated to the generic form by #220).
/// `aura mc <blueprint> --real --axis …` pools the per-window OOS trade-R
@@ -3715,8 +3656,6 @@ fn mc_real_fits_the_injected_roller_to_a_short_window() {
);
}
/// Property: the one load-bearing decision new to the mc dissolution — `translate_mc`
/// maps `campaign.seed` to the mc `--seed` (unlike `translate_walkforward`, which
/// hardcodes `seed: 0`) — actually flows through the executor to the emitted grade,
@@ -3962,15 +3901,6 @@ fn generalize_campaign_runs_an_arbitrary_blueprint() {
assert!(grade["worst_case"].is_number(), "worst-case floor present: {record_line}");
}
/// Property (#273, list reshape): `aura data list` enumerates the archive's
/// symbols as NDJSON, sorted — the discovery step a campaign author (or an
/// agent operating through the CLI alone, the deployment posture) needs