diff --git a/crates/buzz-acp/src/relay_skills.rs b/crates/buzz-acp/src/relay_skills.rs index 2f5f1e6479..93536c0b79 100644 --- a/crates/buzz-acp/src/relay_skills.rs +++ b/crates/buzz-acp/src/relay_skills.rs @@ -117,7 +117,7 @@ fn render_assigned_skill_covers(coordinates: &[Coordinate], events: Vec) }; let title = exact_tag(&event, "title") .map(clean_single_line) - .filter(|value| !value.is_empty()) + .filter(|value| !value.is_empty() && value.len() <= MAX_DESCRIPTION_BYTES) .unwrap_or_else(|| coordinate.slug.clone()); rows.push(format!( "- **{title}** (`{}`)\n {summary}\n When relevant, fetch the full signed instructions with `buzz notes get --name {} --author {} --content-only`.", @@ -223,4 +223,24 @@ mod tests { assert!(!rendered.contains("full body stays lazy")); assert!(!rendered.contains("Nope")); } + + #[test] + fn oversized_title_falls_back_to_bounded_slug() { + let author = Keys::generate(); + let coordinate = format!("30023:{}:safe-slug", author.public_key().to_hex()); + let event = EventBuilder::new(Kind::Custom(SKILL_KIND), "lazy body") + .tags([ + Tag::parse(["d", "safe-slug"]).unwrap(), + Tag::parse(["title", &"x".repeat(MAX_DESCRIPTION_BYTES + 1)]).unwrap(), + Tag::parse(["summary", "Bounded summary"]).unwrap(), + ]) + .sign_with_keys(&author) + .unwrap(); + let rendered = + render_assigned_skill_covers(&[parse_coordinate(&coordinate).unwrap()], vec![event]) + .unwrap(); + + assert!(rendered.contains("**safe-slug**")); + assert!(!rendered.contains(&"x".repeat(MAX_DESCRIPTION_BYTES + 1))); + } }