Skip to content

Commit 543e7b5

Browse files
UbuntuCopilot
andcommitted
fix(ooda): sanitize LLM-emitted gh issue labels to drop ellipsis placeholders
Filters labels via is_plausible_label() before passing to gh issue create, dropping empty / pure-punctuation / placeholder strings (`...`, `.…`, `…`) that the LLM occasionally emits from truncated example lists. Two of Simard's active goals were stuck looping on: gh exited with status 1: could not add label: '.… gh exited with status 1: could not add label: '...' Adds 3 unit tests in label_sanitizer_tests, all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 1825941 commit 543e7b5

1 file changed

Lines changed: 52 additions & 2 deletions

File tree

src/ooda_actions/goal_session.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,14 +649,34 @@ fn dispatch_gh_issue_create(
649649
"issue", "create", "--repo", repo, "--title", title, "--body", body,
650650
];
651651
let label_csv;
652-
if !labels.is_empty() {
653-
label_csv = labels.join(",");
652+
let sanitized_labels: Vec<String> = labels
653+
.iter()
654+
.map(|l| l.trim().to_string())
655+
.filter(|l| is_plausible_label(l))
656+
.collect();
657+
if !sanitized_labels.is_empty() {
658+
label_csv = sanitized_labels.join(",");
654659
args.push("--label");
655660
args.push(&label_csv);
656661
}
657662
run_gh(&args)
658663
}
659664

665+
/// Filter labels that are obviously bogus (placeholders, ellipses, control chars, empty).
666+
/// Real labels here are short kebab-case-or-spaced strings; LLM occasionally emits
667+
/// `"..."` or `".…"` (literal ellipsis) from truncated examples in the prompt.
668+
fn is_plausible_label(label: &str) -> bool {
669+
if label.is_empty() || label.len() > 50 {
670+
return false;
671+
}
672+
// Reject pure-punctuation placeholders the LLM tends to emit (`...`, `.…`, `…`).
673+
if label.chars().all(|c| matches!(c, '.' | '…' | '-' | '_' | ' ')) {
674+
return false;
675+
}
676+
// Require at least one alphanumeric character.
677+
label.chars().any(|c| c.is_alphanumeric())
678+
}
679+
660680
fn dispatch_gh_issue_comment(repo: &str, issue: u64, body: &str) -> Result<String, String> {
661681
let issue_str = issue.to_string();
662682
run_gh(&[
@@ -1110,3 +1130,33 @@ Hope that helps!"#;
11101130
assert_ne!(a, c);
11111131
}
11121132
}
1133+
1134+
#[cfg(test)]
1135+
mod label_sanitizer_tests {
1136+
use super::is_plausible_label;
1137+
1138+
#[test]
1139+
fn rejects_ellipsis_placeholders() {
1140+
assert!(!is_plausible_label("..."));
1141+
assert!(!is_plausible_label(".…"));
1142+
assert!(!is_plausible_label("…"));
1143+
assert!(!is_plausible_label("---"));
1144+
assert!(!is_plausible_label(""));
1145+
assert!(!is_plausible_label(" "));
1146+
}
1147+
1148+
#[test]
1149+
fn accepts_real_labels() {
1150+
assert!(is_plausible_label("bug"));
1151+
assert!(is_plausible_label("enhancement"));
1152+
assert!(is_plausible_label("good first issue"));
1153+
assert!(is_plausible_label("workflow:default"));
1154+
assert!(is_plausible_label("parity"));
1155+
}
1156+
1157+
#[test]
1158+
fn rejects_too_long_labels() {
1159+
let long = "x".repeat(60);
1160+
assert!(!is_plausible_label(&long));
1161+
}
1162+
}

0 commit comments

Comments
 (0)