use tracing::warn;
pub(super) fn verdict_pass(reviewer: &str, output: &str) -> bool {
match parse_verdict(output) {
Some(verdict) => verdict,
None => {
warn!(
reviewer = reviewer,
"No VERDICT: PASS|FAIL line found in reviewer output; treating as FAIL"
);
false
}
}
}
pub(super) fn parse_verdict(output: &str) -> Option<bool> {
let tail = if output.len() > 200 {
let mut idx = output.len() - 200;
while !output.is_char_boundary(idx) {
idx += 1;
}
&output[idx..]
} else {
output
};
let lower = tail.to_lowercase();
let pos = lower.rfind("verdict:")?;
let after = &lower[pos + "verdict:".len()..];
let token = after
.split_whitespace()
.next()?
.trim_end_matches(|c: char| !c.is_alphanumeric());
match token {
"pass" | "passed" | "approve" | "approved" | "ok" => Some(true),
"fail" | "failed" | "reject" | "rejected" | "block" | "blocked" => Some(false),
_ => None,
}
}
#[cfg(test)]
mod verdict_tests {
use super::parse_verdict;
#[test]
fn parses_pass_at_end() {
assert_eq!(parse_verdict("looks fine.\nVERDICT: PASS"), Some(true));
}
#[test]
fn parses_fail_at_end() {
assert_eq!(
parse_verdict("found a sql injection on line 12.\nVERDICT: FAIL"),
Some(false)
);
}
#[test]
fn benign_mention_of_fail_does_not_flip_verdict() {
let body = "Notes: no test failures detected; fail-safe pattern used.\n\
VERDICT: PASS";
assert_eq!(parse_verdict(body), Some(true));
}
#[test]
fn missing_verdict_returns_none() {
assert_eq!(parse_verdict("looks fine, nothing critical"), None);
}
#[test]
fn case_insensitive() {
assert_eq!(parse_verdict("\nverdict: pass\n"), Some(true));
assert_eq!(parse_verdict("\nVerdict: Fail\n"), Some(false));
}
#[test]
fn last_verdict_wins_within_tail() {
let body = "VERDICT: FAIL\n\
on second thought, fixed it.\n\
VERDICT: PASS";
assert_eq!(parse_verdict(body), Some(true));
}
#[test]
fn verdict_at_start_of_long_body_is_ignored() {
let mut body = String::from("VERDICT: PASS\n");
body.push_str(&"prose ".repeat(60)); assert_eq!(parse_verdict(&body), None);
}
#[test]
fn multibyte_tail_boundary_is_safe() {
let pad = "𝓍".repeat(80); let body = format!("{}\nfinal note.\nVERDICT: PASS", pad);
assert_eq!(parse_verdict(&body), Some(true));
}
}