feat: the document-first surface closes — show read-back, typed stops, bare plateau

The #300 keystone cycle: the residual run-quintet flags were already
document vocabulary on the --real arm (#210/#220); this closes the loop
and ratifies the surface.

- `aura process|campaign show <content-id>` prints a registered
  document's canonical bytes (print!, no framing — #164), so
  generate -> retrieve -> hand-extend -> re-register needs no direct
  store filesystem access. Refusals reuse the store-hint prose, exit 1.
- walkforward/mc --stop-length/--stop-k become clap-typed i64/f64
  (generalize's form); stop_knob_or and its parse_csv_list helper are
  deleted (multi-value/invalid input is now clap's exit-2 rejection —
  the two dissolved-verb refusal tests retarget, the type-dead unit
  test is deleted).
- --select accepts bare `plateau` as the documented default
  plateau:mean (#227 carry); document schema untouched — the two
  spellings generate content-id-identical campaigns (test-pinned).
- family.rs's quadruplicated demo stop literal collapses onto one
  DEFAULT_STOP const (maintainer-lens drift finding).
- Ledger: C25's "which projection next" line resolved (document-first
  delivered, per-verb identity re-ratified — F8; host/MCP stay
  demand-driven); C18 records the read-back.

Design triage, fork decisions F1-F8, and the auto-signed spec live on
the reference issue. Verification: full workspace suite 1482 passed /
0 failed with the real GER40 archive exercised (the byte-identity
round-trips ran, not skipped); clippy -D warnings clean.

closes #300
This commit is contained in:
2026-07-21 12:50:10 +02:00
parent 4ed6455b64
commit 757e3ac1bd
5 changed files with 517 additions and 100 deletions
+423 -2
View File
@@ -3220,7 +3220,7 @@ fn walkforward_dissolved_refuses_a_multi_value_stop() {
.expect("spawn aura");
assert_eq!(out.status.code(), Some(2), "multi-value stop is a usage refusal");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(stderr.contains("single risk regime"), "stop-regime refusal: {stderr}");
assert!(stderr.contains("invalid value"), "stop-regime refusal: {stderr}");
}
/// #215: --select plateau is no longer refused on the dissolved path — it now
@@ -3647,6 +3647,96 @@ fn walkforward_stopless_defaults_the_regime_byte_identically_to_explicit_3_2() {
);
}
/// #227: bare `--select plateau` is the documented default aggregation
/// (`plateau:mean`), not a distinct spelling. Same dedup-pin idiom as
/// `walkforward_stopless_defaults_the_regime_byte_identically_to_explicit_3_2`:
/// running the same grid-sweep blueprint in the same store first with
/// `--select plateau`, then with `--select plateau:mean`, must produce
/// byte-identical campaign documents — content-addressed storage collapses
/// them onto EXACTLY ONE stored campaign — while each invocation still
/// records its own campaign-run line. Gated on the shared GER40 archive;
/// skips cleanly on a data refusal.
#[test]
fn walkforward_bare_plateau_generates_the_same_campaign_as_plateau_mean() {
const FROM_MS: &str = "1735689600000";
const TO_MS: &str = "1747353600000";
let (cwd, _g) = fresh_project();
let fixture = format!("{}/examples/r_sma.json", env!("CARGO_MANIFEST_DIR"));
// Bare `plateau`: today this is an unknown-token usage refusal (exit 2);
// the feature makes it an alias for `plateau:mean`.
let bare = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args([
"walkforward", &fixture, "--real", "GER40",
"--axis", "sma_signal.fast.length=3,5", "--axis", "sma_signal.slow.length=12,20",
"--stop-length", "14", "--stop-k", "2.0",
"--select", "plateau",
"--from", FROM_MS, "--to", TO_MS,
])
.current_dir(&cwd)
.output()
.expect("spawn aura");
if bare.status.code() == Some(1) {
let stderr = String::from_utf8_lossy(&bare.stderr);
assert!(
stderr.contains("no local data") || stderr.contains("no recorded geometry"),
"exit 1 must be a data refusal, got: {stderr}"
);
eprintln!("skip: no local GER40 data");
return;
}
assert_eq!(
bare.status.code(),
Some(0),
"bare --select plateau must no longer be refused (it aliases plateau:mean): {}",
String::from_utf8_lossy(&bare.stderr)
);
// Explicit `plateau:mean`: names the very aggregation the bare spelling
// resolves to. Same blueprint, same axes, same window, same stop.
let explicit = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args([
"walkforward", &fixture, "--real", "GER40",
"--axis", "sma_signal.fast.length=3,5", "--axis", "sma_signal.slow.length=12,20",
"--stop-length", "14", "--stop-k", "2.0",
"--select", "plateau:mean",
"--from", FROM_MS, "--to", TO_MS,
])
.current_dir(&cwd)
.output()
.expect("spawn aura");
assert_eq!(
explicit.status.code(),
Some(0),
"the explicit --select plateau:mean walkforward must succeed: {}",
String::from_utf8_lossy(&explicit.stderr)
);
// Byte-identity: bare `plateau` IS `plateau:mean`, so both invocations
// generate the same campaign document and content-addressed storage
// collapses them onto one content id — exactly one campaign document in
// the store, but two independent campaign-run lines.
let count = |sub: &str| {
std::fs::read_dir(cwd.join("runs").join(sub))
.map(|d| d.count())
.unwrap_or(0)
};
assert_eq!(
count("campaigns"),
1,
"bare plateau binds the SAME aggregation as plateau:mean, so the two campaign \
documents are byte-identical and dedup to one content id"
);
let runs_log = std::fs::read_to_string(cwd.join("runs").join("campaign_runs.jsonl"))
.expect("campaign_runs.jsonl exists after two sugar runs");
assert_eq!(
runs_log.lines().count(),
2,
"each invocation still records its own campaign run (a run is an event, a document \
is content)"
);
}
/// Property: `aura generalize` is now thin sugar over the one campaign path — a
/// successful run durably auto-registers exactly one generated process document,
/// one generated campaign document (carrying the `--name` handle and the stop as
@@ -5665,7 +5755,7 @@ fn mc_dissolved_refuses_a_multi_value_stop() {
.expect("spawn aura");
assert_eq!(out.status.code(), Some(2), "multi-value stop is a usage refusal");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(stderr.contains("single risk regime"), "stop-regime refusal: {stderr}");
assert!(stderr.contains("invalid value"), "stop-regime refusal: {stderr}");
}
/// Property: an `--axis` name that is not among the loaded blueprint's sweepable
@@ -6286,3 +6376,334 @@ fn data_list_enumerates_archive_symbols_one_per_line_sorted() {
// scoping an instrument matrix.
assert_eq!(stdout, "SYMA\nSYMB\n", "sorted symbol enumeration: {stdout:?}");
}
/// Property (#300): `aura campaign show <CID>` prints the registered
/// document's exact canonical bytes to stdout — round-tripping them back
/// through `aura campaign register` re-derives the SAME content id (canonical
/// bytes are content-id-identical), and the store stays deduplicated at one
/// document. Gated on the shared GER40 archive; skips cleanly on a data
/// refusal (same guard shape as
/// `walkforward_stopless_defaults_the_regime_byte_identically_to_explicit_3_2`).
#[test]
fn campaign_show_round_trips_the_registered_document() {
const FROM_MS: &str = "1735689600000";
const TO_MS: &str = "1767225599000";
let (cwd, _g) = fresh_project();
let fixture = format!("{}/examples/r_sma.json", env!("CARGO_MANIFEST_DIR"));
let run = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args([
"walkforward", &fixture, "--real", "GER40",
"--axis", "sma_signal.fast.length=3", "--axis", "sma_signal.slow.length=12",
"--select", "plateau:mean",
"--from", FROM_MS, "--to", TO_MS,
])
.current_dir(&cwd)
.output()
.expect("spawn aura");
if run.status.code() == Some(1) {
let stderr = String::from_utf8_lossy(&run.stderr);
assert!(
stderr.contains("no local data") || stderr.contains("no recorded geometry"),
"exit 1 must be a data refusal, got: {stderr}"
);
eprintln!("skip: no local GER40 data");
return;
}
assert_eq!(
run.status.code(),
Some(0),
"walkforward must succeed: {}",
String::from_utf8_lossy(&run.stderr)
);
let campaigns_dir = cwd.join("runs").join("campaigns");
let cid = std::fs::read_dir(&campaigns_dir)
.expect("campaigns dir exists")
.next()
.expect("exactly one campaign document")
.expect("readable dir entry")
.path()
.file_stem()
.expect("campaign filename has a stem")
.to_string_lossy()
.into_owned();
let show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["campaign", "show", &cid])
.current_dir(&cwd)
.output()
.expect("spawn aura campaign show");
assert_eq!(
show.status.code(),
Some(0),
"campaign show must succeed: {}",
String::from_utf8_lossy(&show.stderr)
);
// Directly pin the #164 no-framing invariant: `show` must print the
// stored canonical bytes byte-for-byte, with no added trailing newline
// (a `println!` regression in `show_campaign` would still pass the
// re-register check below via `campaign_to_json` -> `content_id_of`
// stripping it back out before hashing, so this comparison is the only
// thing that would catch it).
let stored_bytes = std::fs::read(campaigns_dir.join(format!("{cid}.json"))).expect("read stored campaign document");
assert_eq!(
show.stdout, stored_bytes,
"campaign show must print the stored canonical bytes byte-for-byte, no framing"
);
let roundtrip_path = cwd.join("roundtrip.campaign.json");
std::fs::write(&roundtrip_path, &show.stdout).expect("write roundtrip campaign doc");
let register = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["campaign", "register", roundtrip_path.to_str().expect("utf-8 path")])
.current_dir(&cwd)
.output()
.expect("spawn aura campaign register");
assert_eq!(
register.status.code(),
Some(0),
"re-registering the shown document must succeed: {}",
String::from_utf8_lossy(&register.stderr)
);
let register_out = String::from_utf8_lossy(&register.stdout).into_owned();
assert!(
register_out.contains(&format!("registered campaign {cid}")),
"canonical bytes must re-register content-id-identically to {cid}: {register_out}"
);
let count = std::fs::read_dir(&campaigns_dir).expect("campaigns dir exists").count();
assert_eq!(count, 1, "the shown bytes dedup onto the same one stored document");
}
/// Property (#300): identical to `campaign_show_round_trips_the_registered_document`
/// but over the generated process document — `aura process show <PID>` prints
/// canonical bytes that re-register content-id-identically through `aura
/// process register`, with the store staying deduplicated at one document.
#[test]
fn process_show_round_trips_the_registered_document() {
const FROM_MS: &str = "1735689600000";
const TO_MS: &str = "1767225599000";
let (cwd, _g) = fresh_project();
let fixture = format!("{}/examples/r_sma.json", env!("CARGO_MANIFEST_DIR"));
let run = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args([
"walkforward", &fixture, "--real", "GER40",
"--axis", "sma_signal.fast.length=3", "--axis", "sma_signal.slow.length=12",
"--select", "plateau:mean",
"--from", FROM_MS, "--to", TO_MS,
])
.current_dir(&cwd)
.output()
.expect("spawn aura");
if run.status.code() == Some(1) {
let stderr = String::from_utf8_lossy(&run.stderr);
assert!(
stderr.contains("no local data") || stderr.contains("no recorded geometry"),
"exit 1 must be a data refusal, got: {stderr}"
);
eprintln!("skip: no local GER40 data");
return;
}
assert_eq!(
run.status.code(),
Some(0),
"walkforward must succeed: {}",
String::from_utf8_lossy(&run.stderr)
);
let processes_dir = cwd.join("runs").join("processes");
let pid = std::fs::read_dir(&processes_dir)
.expect("processes dir exists")
.next()
.expect("exactly one process document")
.expect("readable dir entry")
.path()
.file_stem()
.expect("process filename has a stem")
.to_string_lossy()
.into_owned();
let show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["process", "show", &pid])
.current_dir(&cwd)
.output()
.expect("spawn aura process show");
assert_eq!(
show.status.code(),
Some(0),
"process show must succeed: {}",
String::from_utf8_lossy(&show.stderr)
);
// Directly pin the #164 no-framing invariant (see the sibling campaign
// test's comment): `show` must print the stored canonical bytes
// byte-for-byte, with no added trailing newline.
let stored_bytes = std::fs::read(processes_dir.join(format!("{pid}.json"))).expect("read stored process document");
assert_eq!(
show.stdout, stored_bytes,
"process show must print the stored canonical bytes byte-for-byte, no framing"
);
let roundtrip_path = cwd.join("roundtrip.process.json");
std::fs::write(&roundtrip_path, &show.stdout).expect("write roundtrip process doc");
let register = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["process", "register", roundtrip_path.to_str().expect("utf-8 path")])
.current_dir(&cwd)
.output()
.expect("spawn aura process register");
assert_eq!(
register.status.code(),
Some(0),
"re-registering the shown document must succeed: {}",
String::from_utf8_lossy(&register.stderr)
);
let register_out = String::from_utf8_lossy(&register.stdout).into_owned();
assert!(
register_out.contains(&format!("registered process {pid}")),
"canonical bytes must re-register content-id-identically to {pid}: {register_out}"
);
let count = std::fs::read_dir(&processes_dir).expect("processes dir exists").count();
assert_eq!(count, 1, "the shown bytes dedup onto the same one stored document");
}
/// Property (#300): `show` over an unknown id refuses with the same
/// project-store-not-found prose the referential tier already uses for a
/// missing `process.ref`/`strategy.ref` (`ref_fault_prose`'s
/// `ProcessNotFound`/campaign-equivalent hint shape) — no project run needed,
/// so this test needs no archive gate.
#[test]
fn show_refuses_an_unknown_id_with_the_store_hint() {
let (cwd, _g) = fresh_project();
let campaign_show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["campaign", "show", "deadbeef"])
.current_dir(&cwd)
.output()
.expect("spawn aura campaign show");
assert_eq!(campaign_show.status.code(), Some(1), "unknown campaign id is a runtime refusal");
let campaign_stderr = String::from_utf8_lossy(&campaign_show.stderr);
assert!(
campaign_stderr.contains("campaign deadbeef not found in the project store"),
"campaign show stderr: {campaign_stderr}"
);
let process_show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["process", "show", "deadbeef"])
.current_dir(&cwd)
.output()
.expect("spawn aura process show");
assert_eq!(process_show.status.code(), Some(1), "unknown process id is a runtime refusal");
let process_stderr = String::from_utf8_lossy(&process_show.stderr);
assert!(
process_stderr.contains("process deadbeef not found in the project store"),
"process show stderr: {process_stderr}"
);
}
/// Property (#300): `show`'s not-found prose reuses the existing `prefix_hint`
/// authoring-trap detector (#194) — an id pasted WITH the display-only
/// `content:` prefix (the form `ref_fault_prose` already prints elsewhere for
/// an unresolved `process.ref`/`strategy.ref`) still gets the "drop the
/// 'content:' prefix" hint through the new `show` code path, not a bare
/// not-found. This is the one authoring mistake the store can name outright,
/// and it must survive `show` reusing `ref_fault_prose`'s helper rather than
/// re-deriving its own prose.
#[test]
fn show_hints_the_content_prefix_authoring_mistake() {
let (cwd, _g) = fresh_project();
let campaign_show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["campaign", "show", "content:deadbeef"])
.current_dir(&cwd)
.output()
.expect("spawn aura campaign show");
assert_eq!(campaign_show.status.code(), Some(1), "unresolvable id is a runtime refusal");
let campaign_stderr = String::from_utf8_lossy(&campaign_show.stderr);
assert!(
campaign_stderr.contains("drop the 'content:' prefix"),
"campaign show must hint the content: authoring mistake: {campaign_stderr}"
);
let process_show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["process", "show", "content:deadbeef"])
.current_dir(&cwd)
.output()
.expect("spawn aura process show");
assert_eq!(process_show.status.code(), Some(1), "unresolvable id is a runtime refusal");
let process_stderr = String::from_utf8_lossy(&process_show.stderr);
assert!(
process_stderr.contains("drop the 'content:' prefix"),
"process show must hint the content: authoring mistake: {process_stderr}"
);
}
/// Property (#300): `show` is scoped to its own document-kind store — a
/// content id that IS a real, registered document in one store (here: a
/// minimal sweep-only process) does not resolve through the OTHER verb
/// (`campaign show`). `show_process`/`show_campaign` are two near-identical
/// functions written in the same change (both `registry.get_*(id) -> Option
/// -> print! the bytes or format! a not-found`); this pins that they read
/// from their own store method and neither accidentally shares the other's
/// namespace or falls back to a generic content-blob lookup.
#[test]
fn show_is_scoped_to_its_own_document_store() {
let (cwd, _g) = fresh_project();
const SWEEP_ONLY_PROCESS: &str = r#"{"format_version":1,"kind":"process","name":"knob-sweep-only","pipeline":[{"block":"std::sweep","metric":"sqn_normalized","select":"argmax"}]}"#;
std::fs::write(cwd.join("knob.process.json"), SWEEP_ONLY_PROCESS).expect("write process doc");
let register = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["process", "register", "knob.process.json"])
.current_dir(&cwd)
.output()
.expect("spawn aura process register");
assert_eq!(
register.status.code(),
Some(0),
"process register must succeed: {}",
String::from_utf8_lossy(&register.stderr)
);
let register_out = String::from_utf8_lossy(&register.stdout).into_owned();
let pid = register_out
.lines()
.find(|l| l.starts_with("registered process "))
.expect("register line")
.trim_start_matches("registered process ")
.split(' ')
.next()
.expect("process id")
.to_string();
let process_show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["process", "show", &pid])
.current_dir(&cwd)
.output()
.expect("spawn aura process show");
assert_eq!(
process_show.status.code(),
Some(0),
"process show must find the just-registered process: {}",
String::from_utf8_lossy(&process_show.stderr)
);
let campaign_show = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
.args(["campaign", "show", &pid])
.current_dir(&cwd)
.output()
.expect("spawn aura campaign show");
assert_eq!(
campaign_show.status.code(),
Some(1),
"a process id must NOT resolve through campaign show: {}",
String::from_utf8_lossy(&campaign_show.stdout)
);
let campaign_stderr = String::from_utf8_lossy(&campaign_show.stderr);
assert!(
campaign_stderr.contains(&format!("campaign {pid} not found in the project store")),
"campaign show stderr: {campaign_stderr}"
);
}