fix(aura-research): process.ref hint states the tagged { content_id } shape
campaign introspect (--block std::process_ref and --unwired) described
the slot as "content id of a process document" — a plausible bare-string
reading the validator rejects; the required {"content_id":"..."} tagging
appeared in no introspection output (binary-only M1 fieldtest finding).
The SlotKind::ContentRef label and the open-slot hint now lead with the
tagged { content_id } shape. Deliberately narrower than the issue's
suggestion of mirroring std::strategy's { content_id } | { identity_id }
form: validate_campaign refuses an identity_id process ref
(DocFault::ProcessRefMustBeContentId) and a pinned test forbids
advertising it, so the hint states the one accepted key only (C29
honesty; correction minuted on the issue). RED-first: the extended
process_ref_describe_advertises_content_id_only assertion failed against
the old label before the fix.
closes #329
This commit is contained in:
@@ -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}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<Vec<OpenSlot>, 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:?}"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user