diff --git a/crates/aura-cli/tests/research_docs.rs b/crates/aura-cli/tests/research_docs.rs index 06e6b73..ab1c2ef 100644 --- a/crates/aura-cli/tests/research_docs.rs +++ b/crates/aura-cli/tests/research_docs.rs @@ -996,7 +996,7 @@ fn campaign_introspect_unwired_reports_the_spec_example_slots() { write_doc(&dir, "draft.campaign.json", draft); let (out, code) = run_code_in(&dir, &["campaign", "introspect", "--unwired", "draft.campaign.json"]); assert_eq!(code, Some(0)); - assert!(out.contains("open slot: process.ref (required, content id of a process document)")); + assert!(out.contains("open slot: process.ref (required, { content_id }: content id of a process document)")); assert!(out.contains("open slot: strategies[0].axes.slow (axis declared empty — a P1 axis is a non-empty finite set)")); } @@ -1022,7 +1022,7 @@ fn campaign_introspect_unwired_reports_placeholder_refs() { "strategy `ref: null` placeholder not enumerated: {out}" ); assert!( - out.contains("open slot: process.ref (required, content id of a process document)"), + out.contains("open slot: process.ref (required, { content_id }: content id of a process document)"), "process `ref: {{}}` placeholder not enumerated: {out}" ); } diff --git a/crates/aura-research/src/lib.rs b/crates/aura-research/src/lib.rs index 58a9723..34f000f 100644 --- a/crates/aura-research/src/lib.rs +++ b/crates/aura-research/src/lib.rs @@ -1102,7 +1102,7 @@ pub fn slot_kind_label(kind: SlotKind) -> &'static str { SlotKind::Strings => "list of strings", SlotKind::Windows => "list of { from_ms, to_ms }", SlotKind::Ref => "one of { content_id } | { identity_id }", - SlotKind::ContentRef => "content id of a process document", + SlotKind::ContentRef => "{ content_id }: content id of a process document", SlotKind::Axes => "map: param name -> { kind, values }", SlotKind::EmitKinds => "list of: family_table | selection_report", SlotKind::TapKinds => "list of: equity | exposure | r_equity | net_r_equity", @@ -1301,8 +1301,10 @@ pub fn open_slots_campaign(text: &str) -> Result, DocError> { } if ref_slot_is_open(v.get("process").and_then(|p| p.get("ref"))) { // deliberately narrower than the strategy-ref hint: validate_campaign - // refuses an identity_id process ref, so the guide must not offer it - slots.push(open("process.ref", "required, content id of a process document")); + // refuses an identity_id process ref, so the guide must not offer it. + // The tagged { content_id } shape is stated explicitly (#329) so the + // hint cannot be misread as accepting a bare id string. + slots.push(open("process.ref", "required, { content_id }: content id of a process document")); } if v.get("seed").and_then(|s| s.as_u64()).is_none() { slots.push(open("seed", "required, non-negative integer")); @@ -2374,6 +2376,14 @@ mod tests { label.contains("content"), "process_ref describe must still name the content-id form: {label}" ); + // #329: the label must state the TAGGED shape ({ content_id: ... }) the + // parser actually requires, not read like a bare id string — mirroring + // the `{ content_id } | { identity_id }` bracket notation std::strategy + // already uses, narrowed to the one key process.ref accepts. + assert!( + label.contains("{ content_id }"), + "process_ref describe must state the tagged {{ content_id }} shape, not a bare id: {label}" + ); let strategy = describe_block("std::strategy").expect("strategy describable"); let strat_ref = @@ -2430,7 +2440,7 @@ mod tests { "presentation": { "persist_taps": [], "emit": [] } }"#; let slots = open_slots_campaign(draft).unwrap(); assert!(slots.iter().any(|s| s.path == "process.ref" - && s.hint == "required, content id of a process document")); + && s.hint == "required, { content_id }: content id of a process document")); assert!(slots.iter().any(|s| s.path == "strategies[0].axes.slow" && s.hint == "axis declared empty — a P1 axis is a non-empty finite set")); @@ -2466,7 +2476,7 @@ mod tests { // ...and the `{}` process ref reports the narrower content-id-only hint. assert!( slots.iter().any(|s| s.path == "process.ref" - && s.hint == "required, content id of a process document"), + && s.hint == "required, { content_id }: content id of a process document"), "process `ref: {{}}` placeholder not reported as an open slot: {slots:?}" ); }