From caa83eb7065fec37cecfc777ba8c90db72dfe3f7 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 11 Sep 2026 14:47:56 +0000 Subject: [PATCH 1/2] fix(trace): invert ConvergenceRate so higher means faster --- internal/trace/trace.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/trace/trace.go b/internal/trace/trace.go index bf5fb50..971706c 100644 --- a/internal/trace/trace.go +++ b/internal/trace/trace.go @@ -101,7 +101,9 @@ func (t *Trace) computeSummary() *Summary { } } if firstSuccess > 0 { - s.ConvergenceRate = float64(firstSuccess) / float64(s.TotalIterations) + // Higher is better: success on the first iteration => 1.0, + // success only on the last iteration => near 0. + s.ConvergenceRate = 1.0 - float64(firstSuccess-1)/float64(s.TotalIterations) } } From 5ee18caa1ea00d0d3857ad5e29b444f8121ebb99 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 11 Sep 2026 14:47:58 +0000 Subject: [PATCH 2/2] test(trace): ConvergenceRate higher means faster --- internal/trace/trace_test.go | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 internal/trace/trace_test.go diff --git a/internal/trace/trace_test.go b/internal/trace/trace_test.go new file mode 100644 index 0000000..1be572c --- /dev/null +++ b/internal/trace/trace_test.go @@ -0,0 +1,52 @@ +package trace + +import "testing" + +func TestConvergenceRateHigherMeansFaster(t *testing.T) { + fast := New([]Iteration{ + {Number: 1, Verification: &Verification{Status: "success"}}, + {Number: 2, Verification: &Verification{Status: "success"}}, + {Number: 3, Verification: &Verification{Status: "fail"}}, + {Number: 4}, + {Number: 5}, + {Number: 6}, + {Number: 7}, + {Number: 8}, + {Number: 9}, + {Number: 10}, + }) + slow := New([]Iteration{ + {Number: 1, Verification: &Verification{Status: "fail"}}, + {Number: 2, Verification: &Verification{Status: "fail"}}, + {Number: 3, Verification: &Verification{Status: "fail"}}, + {Number: 4, Verification: &Verification{Status: "fail"}}, + {Number: 5, Verification: &Verification{Status: "fail"}}, + {Number: 6, Verification: &Verification{Status: "fail"}}, + {Number: 7, Verification: &Verification{Status: "fail"}}, + {Number: 8, Verification: &Verification{Status: "fail"}}, + {Number: 9, Verification: &Verification{Status: "fail"}}, + {Number: 10, Verification: &Verification{Status: "success"}}, + }) + + if fast.Summary.ConvergenceRate != 1.0 { + t.Fatalf("first-try ConvergenceRate = %v, want 1.0", fast.Summary.ConvergenceRate) + } + wantSlow := 1.0 - float64(9)/float64(10) + if slow.Summary.ConvergenceRate != wantSlow { + t.Fatalf("last-try ConvergenceRate = %v, want %v", slow.Summary.ConvergenceRate, wantSlow) + } + if !(fast.Summary.ConvergenceRate > slow.Summary.ConvergenceRate) { + t.Fatalf("expected faster convergence to score higher: fast=%v slow=%v", + fast.Summary.ConvergenceRate, slow.Summary.ConvergenceRate) + } +} + +func TestConvergenceRateNoSuccessIsZero(t *testing.T) { + tr := New([]Iteration{ + {Number: 1, Verification: &Verification{Status: "fail"}}, + {Number: 2, Verification: &Verification{Status: "fail"}}, + }) + if tr.Summary.ConvergenceRate != 0 { + t.Fatalf("ConvergenceRate = %v, want 0 when never successful", tr.Summary.ConvergenceRate) + } +}