tidy: fieldtest follow-ups — domain prose for the zero bound, gate-emptied exit semantics documented
The two fieldtest findings, resolved:
- friction: --parallel-instruments 0 now refuses in domain terms ("must be
a whole number of at least 1 — it bounds how many distinct instruments
are resident in parallel") via a custom clap value-parser, instead of
leaking Rust's NonZeroUsize wording; the zero-bound test pins the prose.
- spec_gap: the authoring guide's exit-code contract now states that a
gate-emptied cell (a std::gate leaving no survivors) is a successful
cell — exit 0 with an informational aura: note and a truncated
realization — and that exit 3 is reserved for cells that could not be
evaluated. Records observed behaviour; no code change.
Gates re-verified: workspace suite green, clippy -D warnings clean.
refs #277
This commit is contained in:
@@ -60,6 +60,17 @@ impl DocIntrospectCmd {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse `--parallel-instruments` in domain terms: clap's built-in
|
||||
/// `NonZeroUsize` parser would leak the Rust type name ("number would be
|
||||
/// zero for non-zero type") at exactly the moment a user needs guidance.
|
||||
fn parse_parallel_instruments(s: &str) -> Result<std::num::NonZeroUsize, String> {
|
||||
s.parse::<usize>().ok().and_then(std::num::NonZeroUsize::new).ok_or_else(|| {
|
||||
"must be a whole number of at least 1 — it bounds how many distinct \
|
||||
instruments are resident in parallel"
|
||||
.to_string()
|
||||
})
|
||||
}
|
||||
|
||||
/// Exactly one introspect mode (the graph-introspect guard idiom: usage
|
||||
/// error on stderr, exit 2).
|
||||
fn guard_one_mode(cmd: &DocIntrospectCmd, family: &str) {
|
||||
@@ -320,7 +331,11 @@ pub enum CampaignSub {
|
||||
target: String,
|
||||
/// Bound on distinct instruments resident in parallel (the RAM
|
||||
/// lever; 1 reproduces the sequential loop's footprint).
|
||||
#[arg(long, default_value_t = aura_campaign::DEFAULT_PARALLEL_INSTRUMENTS)]
|
||||
#[arg(
|
||||
long,
|
||||
default_value_t = aura_campaign::DEFAULT_PARALLEL_INSTRUMENTS,
|
||||
value_parser = parse_parallel_instruments,
|
||||
)]
|
||||
parallel_instruments: std::num::NonZeroUsize,
|
||||
},
|
||||
/// List stored campaign realizations, or dump one campaign's records
|
||||
|
||||
@@ -4083,4 +4083,7 @@ fn campaign_over_a_gapped_archive_records_the_uncovered_cell_and_continues() {
|
||||
fn campaign_run_rejects_a_zero_parallel_instruments_bound() {
|
||||
let (out, code) = run_code(&["campaign", "run", "unused", "--parallel-instruments", "0"]);
|
||||
assert_eq!(code, Some(2), "clap usage error expected, got: {out}");
|
||||
// Domain prose, not clap's raw NonZeroUsize wording ("number would be
|
||||
// zero for non-zero type") — the fieldtest friction finding.
|
||||
assert!(out.contains("at least 1"), "domain guidance expected, got: {out}");
|
||||
}
|
||||
|
||||
@@ -609,4 +609,9 @@ Exit codes: a clean run exits 0; a usage error exits 2; a refusal before any
|
||||
cell runs (invalid document, missing project, unresolvable strategy) exits 1;
|
||||
a run that **completes with one or more failed cells** exits 3 — the run record
|
||||
and every healthy cell persist, and the failed cells are named on stderr
|
||||
(#272).
|
||||
(#272). A **gate-emptied cell** — a `std::gate` stage that filters out every
|
||||
member — is a *successful* cell, not a failed one: the gate legitimately
|
||||
answered "no survivors", so the run still exits 0, the cell's realization is
|
||||
recorded as truncated at that stage, and an informational `aura:`-prefixed
|
||||
note names the cell on stderr. Exit 3 is reserved for cells that could not be
|
||||
evaluated (faults), never for an empty-but-valid result.
|
||||
|
||||
Reference in New Issue
Block a user