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
+96 -1
View File
@@ -234,6 +234,30 @@ fn exec_campaign_target_outside_project_refuses() {
assert!(!dir.join("runs").exists(), "a refused run must not create a store outside a project");
}
/// A malformed FILE target (a trailing comma — not valid JSON at all) must
/// refuse NEUTRALLY at the routing seam, before either leg's own
/// document-shape validation ever runs — not silently fall through to the
/// blueprint leg's "blueprint document is not valid JSON" prose (review
/// Minor-3). The file's shape (blueprint vs. campaign) was never
/// determined, so neither leg's own wording is the right attribution.
#[test]
fn exec_malformed_json_file_refuses_neutrally_not_misrouted() {
let (dir, _fixture) = fresh_project();
let malformed = r#"{
"format_version": 1,
"kind": "campaign",
"name": "broken",
}"#;
write_doc(&dir, "broken.campaign.json", malformed);
let (out, code) = run_code_in(&dir, &["exec", "broken.campaign.json"]);
assert_eq!(code, Some(2), "stdout/stderr: {out}");
assert!(out.contains("target file is not valid JSON"), "stdout/stderr: {out}");
assert!(
!out.contains("blueprint document is not valid JSON"),
"must not misattribute to the blueprint leg's own prose: {out}"
);
}
// ---------------------------------------------------------------------------
// Task 2: the exec blueprint leg (synthetic single run).
// ---------------------------------------------------------------------------
@@ -448,7 +472,9 @@ fn exec_override_malformed_token_refuses_with_usage() {
}
/// An override path naming no param of the blueprint (open or bound) refuses
/// with `override_paths`' own prose (`member.rs:768-771`).
/// with `override_paths`' own prose (`member.rs:768-771`), pointing at the
/// live axis-discovery verb (`aura graph introspect --params`) — the retired
/// `aura sweep --list-axes` no longer exists.
#[test]
fn exec_override_unknown_path_refuses_with_the_override_prose() {
let (out, code) = run_code(&["exec", "examples/r_sma.json", "--override", "nope.knob=1"]);
@@ -457,6 +483,34 @@ fn exec_override_unknown_path_refuses_with_the_override_prose() {
out.contains("names no param of this blueprint (open or bound)"),
"stdout/stderr: {out}"
);
assert!(
out.contains("aura graph introspect --params"),
"must point at the live discovery verb, not the retired --list-axes: {out}"
);
}
/// A repeated `--override` path (the same NODE.PARAM named twice) refuses as
/// a usage error naming the duplicated path — it must NOT fall through to
/// `reopen_all`'s `NoSuchBoundParam` panic (the second reopen of an
/// already-reopened bound param, exit 101): the first occurrence reopens
/// `fast.length`, so a second `override_paths` resolution against the SAME
/// un-reopened bound-name set still succeeds, and only `reopen_all`'s fold
/// discovers the collision, too late to refuse cleanly. Mirrors `--tap`'s own
/// duplicate refusal (`tap_plan_from_args`).
#[test]
fn exec_override_duplicate_path_refuses_with_usage_not_a_panic() {
let (out, code) = run_code(&[
"exec",
"examples/r_sma.json",
"--override",
"fast.length=5",
"--override",
"fast.length=9",
]);
assert_ne!(code, Some(101), "must not panic: {out}");
assert_eq!(code, Some(2), "stdout/stderr: {out}");
assert!(out.contains("fast.length"), "the duplicated path must be named: {out}");
assert!(out.contains("--override"), "stdout/stderr: {out}");
}
// ---------------------------------------------------------------------------
@@ -535,6 +589,47 @@ fn exec_campaign_override_colliding_with_a_document_axis_refuses() {
assert!(out.contains("declared axis"), "stdout/stderr: {out}");
}
/// A repeated `--override` path on the campaign leg refuses at the SAME
/// shared lexer (`parse_override_tokens`) both legs use — before the
/// per-strategy injection loop (`run_campaign_returning`) ever runs. Prior
/// to the fix, the first occurrence's own injection made the SECOND
/// occurrence look like a document-declared axis, misattributing the
/// refusal to "collides with a declared axis" (review Minor-1) even though
/// `bias.scale` is not declared by the document at all.
#[test]
fn exec_campaign_override_duplicate_path_refuses_at_the_shared_lexer() {
let (dir, _fixture) = fresh_project_with_data();
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("ovdup.process.json")),
ScratchPath::File(dir.join("ovdup.campaign.json")),
]);
let bp_id = seed_blueprint(&dir, "exec-override-dup-seed");
let proc_id = register_process_doc(&dir, "ovdup.process.json", SWEEP_ONLY_PROCESS_DOC);
let doc = campaign_doc_json_for("SYMA", &bp_id, &proc_id, (1709251200000, 1719791999999));
write_doc(&dir, "ovdup.campaign.json", &doc);
let (out, code) = run_code_in(
&dir,
&[
"exec",
"ovdup.campaign.json",
"--override",
"bias.scale=0.75",
"--override",
"bias.scale=0.9",
],
);
assert_eq!(code, Some(2), "stdout/stderr: {out}");
assert!(out.contains("bias.scale"), "the duplicated path must be named: {out}");
assert!(
!out.contains("collides with a declared axis"),
"must not misattribute to the axis-collision cause: {out}"
);
}
/// An override path naming no param of any strategy (a typo'd raw name)
/// falls out of `validate_campaign_refs`'s existing `AxisNotInParamSpace`
/// did-you-mean prose — pinned literally in `research_docs.rs` (:797-822);