fix(aura-cli): sweep --list-axes joins the gated intake class

Fieldtest finding B1: the one remaining authored-envelope FILE route,
sweep --list-axes, skipped the root-name gate — a hand-edited
"name":"../escape" listed mangled, non-bindable wrapped axis names
at exit 0 while every sibling intake refused. The discovery surface now
gates before any axis line prints (exit 1, shared prose), restoring
both the #331 every-authored-intake claim and #328's discovery-surface
identity. RED-first: the e2e refusal test was written and observed
failing (exit 0, axis lines printed) before the fix.

Re-enumeration of every read_to_string-fed envelope load confirms the
class is now closed; C24 additionally ratifies the fieldtest's SG1 —
the refusal core sentence is byte-uniform across sites while the
leading context prefix varies by site convention.

refs #331, #328
This commit is contained in:
2026-07-25 05:14:50 +02:00
parent 4ff85b94e5
commit 564a767974
4 changed files with 74 additions and 7 deletions
+6
View File
@@ -913,6 +913,12 @@ pub(crate) fn composite_from_any(text: &str, env: &aura_runner::project::Env) ->
/// reason, on the routes that bypass `validate_and_register_axes`
/// entirely (#331 cycle-close — these used to plant an ungated envelope
/// in the store; see each fn's own comment).
/// - `list_blueprint_axes` (`aura sweep <FILE> --list-axes`, main.rs): no
/// registry write and no trace directory here, but a shape-violating root
/// name otherwise mangles through `wrapped_to_raw_axis` into a printed,
/// non-bindable axis name instead of refusing (#331 fieldtest finding
/// c331_2e) — the class rule is every CLI intake reading an authored
/// envelope from a file gates the root name, not only the writing ones.
///
/// All of these share the identical `name_gate` + `name_gate_fault_prose`
/// primitives this wrapper uses, so the refusal wording is byte-identical
+16 -2
View File
@@ -815,15 +815,29 @@ impl IcReport {
/// alongside it, so the discovery surface must list it regardless too. Names
/// are RAW `<node>.<param>` paths (#328: the wrapped `<blueprint>.<node>.<param>`
/// form is retired from the surface) — exactly what `--axis` binds.
///
/// **Gated (#331 fieldtest finding).** This is a FRESH-FILE intake exactly like
/// `register` / `introspect --content-id <FILE>` / `introspect --params <FILE>`
/// (`composite_from_authored_text`'s doc comment lists the class): a hand-edited
/// envelope with a shape-violating root name (`"../x"`) must be refused before
/// any axis line prints, not mangled through `wrapped_to_raw_axis` into a
/// non-bindable name. Gated immediately after load, before any axis derivation
/// — same placement discipline as the other sites — at exit 1, matching the
/// register-route convention (this route never `put_blueprint`s anything,
/// unlike the exit-2 sweep-EXECUTION route `run_blueprint_sweep` gates).
fn list_blueprint_axes(doc: &str, env: &aura_runner::project::Env) {
let signal = blueprint_from_json(doc, &|t| env.resolve(t))
.expect("doc parse-validated at the dispatch boundary");
if let Err(msg) = graph_construct::gate_authored_root_name(signal.name()) {
eprintln!("aura: {msg}");
std::process::exit(1);
}
let space = blueprint_axis_probe(doc, env).param_space();
for p in &space {
// Strip the wrapper's one leading node segment (#328): open names print
// RAW, matching `--axis`'s own accepted namespace.
println!("{}:{:?}", aura_runner::axes::wrapped_to_raw_axis(&p.name), p.kind); // ScalarKind Debug -> I64/F64/Bool/Timestamp
}
let signal = blueprint_from_json(doc, &|t| env.resolve(t))
.expect("doc parse-validated at the dispatch boundary");
for b in signal.bound_param_space() {
// `bound_param_space()`'s `.name` is already RAW (#203) — no blueprint-name
// concatenation (#328: the blueprint name stays out of axis paths, C23).