refactor(ai): make metric bucket ordering deterministic
All checks were successful
Security Scan / security (push) Successful in 10s
Test / test (push) Successful in 1m9s

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 09:07:26 +00:00
parent d6c360813a
commit b6571771f3
2 changed files with 23 additions and 2 deletions

View file

@ -170,7 +170,8 @@ func Summary(events []Event) map[string]any {
}
}
// sortedCountPairs returns a slice of key-count pairs sorted by count descending.
// sortedCountPairs returns a slice of key-count pairs sorted by count descending,
// with key ascending as a deterministic tie-breaker.
func sortedCountPairs(counts map[string]int) []map[string]any {
type entry struct {
key string
@ -182,7 +183,10 @@ func sortedCountPairs(counts map[string]int) []map[string]any {
}
slices.SortFunc(entries, func(a, b entry) int {
return cmp.Compare(b.count, a.count)
if result := cmp.Compare(b.count, a.count); result != 0 {
return result
}
return cmp.Compare(a.key, b.key)
})
result := make([]map[string]any, len(entries))

View file

@ -309,3 +309,20 @@ func TestSortedCountPairs_Good_Ordering(t *testing.T) {
t.Errorf("expected third key 'a', got %v", result[2]["key"])
}
}
func TestSortedCountPairs_Good_TieBreakByKey(t *testing.T) {
m := map[string]int{"beta": 2, "alpha": 2, "gamma": 1}
result := sortedCountPairs(m)
if len(result) != 3 {
t.Fatalf("expected 3 entries, got %d", len(result))
}
if result[0]["key"] != "alpha" {
t.Errorf("expected tie-break to prefer alpha, got %v", result[0]["key"])
}
if result[1]["key"] != "beta" {
t.Errorf("expected beta second, got %v", result[1]["key"])
}
if result[2]["key"] != "gamma" {
t.Errorf("expected gamma last, got %v", result[2]["key"])
}
}