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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user