fix(aura-cli): --folds renders the registry roster; op-lists refuse unknown keys

Two fold-selector/op-script surface-honesty bugs from the 2026-07-24
fieldtests, both RED-first.

--folds (#332): graph introspect --folds rendered the aura-std FoldKind
table — capitalized ids (Mean) and no record entry — while aura run
--tap resolves labels against the fold-registry roster (lowercase,
record included). The discovery surface the --tap help points at thus
misdescribed the accepted input twice. It now renders
FoldRegistry::core().roster() (label + doc per entry); the pinned
FoldKind-rendering test was rewritten to pin the roster form (8 rows,
no capitalized id leaks, record present).

Unknown op-list keys (#326): a typo'd key in an op-list element
("params" for "bind") was silently dropped and the wrong graph built
with zero signal, contradicting the closed-vocabulary posture (C25).
OpDoc now carries serde deny_unknown_fields; the refusal names the
offending key. Exit class is 1, not the issue's suggested 2: op-lists
arrive on stdin, and the pinned #175 attribution principle classes
stdin-content faults as runtime — the new refusal fires from that same
deserialize. Blast radius verified: all 21 committed *.ops.json under
fieldtests/ still build cleanly.

closes #332
closes #326
This commit is contained in:
2026-07-24 16:12:12 +02:00
parent 73ad87b08a
commit 8dbca82756
3 changed files with 42 additions and 12 deletions
+15
View File
@@ -354,6 +354,21 @@ fn graph_build_bad_stdin_content_is_runtime_exit_1() {
assert!(stderr.contains("Nope"), "still names the cause: {stderr}");
}
/// Property (#326): an op-list element carrying an unknown/typo'd key (e.g.
/// `params` where the schema expects `bind`) is refused at parse — not
/// silently dropped. Previously the unrecognized key vanished, the field it
/// meant to set kept its default, and the wrong graph built with zero
/// signal. Same content-fault family as `graph_build_bad_stdin_content_is_
/// runtime_exit_1` (both fire from the same top-level deserialize), so the
/// exit class matches: exit 1, stderr names the offending key.
#[test]
fn graph_build_rejects_an_unknown_op_field() {
let doc = r#"[{"op":"add","type":"Const","params":{"value":{"F64":1.0}}}]"#;
let (stderr, code) = run_code(&["graph", "build"], doc);
assert_eq!(code, Some(1), "unknown op field is a content fault -> exit 1; stderr: {stderr}");
assert!(stderr.contains("params"), "names the unknown key: {stderr}");
}
/// Property (exit-code partition, #175 iteration 2): within the SAME `graph
/// introspect` subcommand, an invalid `--node <T>` flag VALUE is a USAGE error (a
/// command-line fault the user must fix in argv) — exit 2 — distinct from bad stdin