diff --git a/cmd/gadfly/consolidate.go b/cmd/gadfly/consolidate.go index 7f8fb6c..47f2e26 100644 --- a/cmd/gadfly/consolidate.go +++ b/cmd/gadfly/consolidate.go @@ -32,16 +32,25 @@ func (v verdict) label() string { // The base prompt tells each lens to lead with one of the three phrases. func parseVerdict(out string) verdict { l := strings.ToLower(out) - switch { - case strings.Contains(l, "blocking issues found"): - return verdictBlocking - case strings.Contains(l, "no material issues"): - return verdictClean - case strings.Contains(l, "minor issues"): - return verdictMinor - default: - return verdictUnknown + // Match the EARLIEST-appearing verdict phrase (the lead verdict), and match + // leniently — models write "Blocking issues found", "**Blocking issues**", + // "blocking issue", etc. (A strict "blocking issues found" check let a + // gpt-oss section that said "**Blocking issues**" fall through to unknown, + // so the overall header wrongly read "No material issues found".) + best, bestIdx := verdictUnknown, -1 + for _, c := range []struct { + phrase string + v verdict + }{ + {"blocking issue", verdictBlocking}, + {"minor issue", verdictMinor}, + {"no material issue", verdictClean}, + } { + if i := strings.Index(l, c.phrase); i >= 0 && (bestIdx == -1 || i < bestIdx) { + best, bestIdx = c.v, i + } } + return best } // specialistResult pairs a specialist with its rendered review and verdict. diff --git a/cmd/gadfly/specialists_test.go b/cmd/gadfly/specialists_test.go index c720747..708336a 100644 --- a/cmd/gadfly/specialists_test.go +++ b/cmd/gadfly/specialists_test.go @@ -111,10 +111,13 @@ define: func TestParseVerdictAndWorst(t *testing.T) { cases := map[string]verdict{ - "VERDICT: No material issues found.": verdictClean, - "Minor issues\n- nit": verdictMinor, - "**Blocking issues found**": verdictBlocking, - "something unparseable": verdictUnknown, + "VERDICT: No material issues found.": verdictClean, + "Minor issues\n- nit": verdictMinor, + "**Blocking issues found**": verdictBlocking, + "**Blocking issues**\n- bug": verdictBlocking, // no "found" suffix + "VERDICT: Blocking issue\n- one": verdictBlocking, // singular + "No material issues found. There are no blocking issues.": verdictClean, // earliest phrase wins + "something unparseable": verdictUnknown, } for in, want := range cases { if got := parseVerdict(in); got != want {