diff --git a/internal/classifier/classify_test.go b/internal/classifier/classify_test.go index 0aaba02..05e24f1 100644 --- a/internal/classifier/classify_test.go +++ b/internal/classifier/classify_test.go @@ -124,3 +124,28 @@ func TestNoClassification_HealthyTrace(t *testing.T) { t.Errorf("expected 0 classifications for healthy trace, got %d: %v", len(results), results) } } + +func TestDetectFalseCompletion_NoVerification(t *testing.T) { + tr := trace.New([]trace.Iteration{ + {Number: 1, Phase: trace.PhaseAct, Action: trace.Action{Type: "Edit", Target: "src/a.ts"}}, + {Number: 2, Phase: trace.PhaseTerminate, Decision: "stop"}, + }) + tr.Summary.TerminationReason = "goal_met" + + results := Classify(tr) + found := false + for _, r := range results { + if r.Category == CatFalseComplete { + found = true + if r.Confidence != 0.60 { + t.Errorf("confidence = %f, want 0.60", r.Confidence) + } + if r.Evidence != "Loop claimed success but no verification was ever performed." { + t.Errorf("unexpected evidence: %q", r.Evidence) + } + } + } + if !found { + t.Error("expected false completion when success claimed with zero verifications") + } +} diff --git a/internal/classifier/false_complete.go b/internal/classifier/false_complete.go index 2f9d223..e1e72e5 100644 --- a/internal/classifier/false_complete.go +++ b/internal/classifier/false_complete.go @@ -41,7 +41,11 @@ func detectFalseCompletion(t *trace.Trace) *Classification { } if lastVerify == nil { - return nil + return &Classification{ + Category: CatFalseComplete, + Confidence: 0.60, + Evidence: "Loop claimed success but no verification was ever performed.", + } } if lastVerify.Status == "fail" {