diff --git a/crates/aura-cli/tests/cli_run.rs b/crates/aura-cli/tests/cli_run.rs index 33dac96..a3fec65 100644 --- a/crates/aura-cli/tests/cli_run.rs +++ b/crates/aura-cli/tests/cli_run.rs @@ -6707,3 +6707,86 @@ fn show_is_scoped_to_its_own_document_store() { "campaign show stderr: {campaign_stderr}" ); } + +/// Property (#302): `show` mirrors the prefix resolution `reproduce` gained +/// with #298 — a unique prefix of a registered content id, in the 8-hex form +/// every surface prints (family ids, run records), resolves to the registered +/// document, and `show` prints EXACTLY the bytes the full-id invocation +/// prints (the #164 byte-discipline: the stored canonical bytes, no framing). +/// One document per store makes any prefix of its id unique by construction. +/// Deliberately NOT pinned here: the ambiguous-prefix refusal (listing the +/// candidate ids) — content ids are hash-derived, not choosable, so two +/// documents sharing a printed prefix cannot be constructed honestly at this +/// layer; that arm belongs beside the resolution seam, where candidate id +/// lists are plain strings. +#[test] +fn show_resolves_a_unique_prefix_to_the_full_id_bytes() { + let (cwd, _g) = fresh_project(); + + fn aura(cwd: &Path, args: &[&str]) -> std::process::Output { + Command::new(BIN).args(args).current_dir(cwd).output().expect("spawn aura") + } + + const PREFIX_PROBE_PROCESS: &str = r#"{"format_version":1,"kind":"process","name":"prefix-probe","pipeline":[{"block":"std::sweep","metric":"sqn_normalized","select":"argmax"}]}"#; + const PREFIX_PROBE_CAMPAIGN: &str = r#"{ + "format_version": 1, + "kind": "campaign", + "name": "prefix-probe", + "data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1, "to_ms": 2 } ] }, + "strategies": [ { "ref": { "content_id": "9f3a" }, + "axes": { "fast": { "kind": "I64", "values": [8] } } } ], + "process": { "ref": { "content_id": "4e2d" } }, + "seed": 1, + "presentation": { "persist_taps": [], "emit": ["family_table"] } +}"#; + + for (verb, file, doc) in [ + ("process", "probe.process.json", PREFIX_PROBE_PROCESS), + ("campaign", "probe.campaign.json", PREFIX_PROBE_CAMPAIGN), + ] { + std::fs::write(cwd.join(file), doc).expect("write document"); + let register = aura(&cwd, &[verb, "register", file]); + assert_eq!( + register.status.code(), + Some(0), + "{verb} register must succeed: {}", + String::from_utf8_lossy(®ister.stderr) + ); + let register_out = String::from_utf8_lossy(®ister.stdout).into_owned(); + let marker = format!("registered {verb} "); + let id = register_out + .lines() + .find(|l| l.starts_with(&marker)) + .expect("register line") + .trim_start_matches(marker.as_str()) + .split(' ') + .next() + .expect("content id") + .to_string(); + assert!(id.len() > 8, "content id longer than the printed 8-hex prefix form: {id}"); + + let full = aura(&cwd, &[verb, "show", &id]); + assert_eq!( + full.status.code(), + Some(0), + "{verb} show must succeed: {}", + String::from_utf8_lossy(&full.stderr) + ); + assert!(!full.stdout.is_empty(), "{verb} show prints the document bytes"); + + // The headline: the 8-hex prefix — unique in this one-document store — + // resolves, and the output is byte-identical to the full-id output. + let prefix = &id[..8]; + let short = aura(&cwd, &[verb, "show", prefix]); + assert_eq!( + short.status.code(), + Some(0), + "{verb} show {prefix} (unique prefix of {id}) must resolve: {}", + String::from_utf8_lossy(&short.stderr) + ); + assert_eq!( + short.stdout, full.stdout, + "{verb} show via unique prefix must print the identical document bytes" + ); + } +}