feat(index-builder): enhance evolution/meta.json with live observatory data

- Add island_populations: program count per island
- Add best_ratings: top 10 evolved bots with bot_id, name, rating, island, language
- Add total_promoted and promotion_rate: all-time promotion statistics
- Queries programs table and joins with bots table for current ratings

Closes: bf-1cxv
This commit is contained in:
jedarden 2026-05-26 13:15:39 -04:00
parent c37f68e08b
commit 6fbe221fe7

View file

@ -1017,10 +1017,23 @@ func computeTopPredictors(stats []PredictorStats) []PredictorStats {
// EvolutionMeta represents data/evolution/meta.json
type EvolutionMeta struct {
Generation int `json:"generation"`
PromotedToday int `json:"promoted_today"`
Top10Count int `json:"top_10_count"`
UpdatedAt string `json:"updated_at"`
Generation int `json:"generation"`
PromotedToday int `json:"promoted_today"`
Top10Count int `json:"top_10_count"`
IslandPopulations map[string]int `json:"island_populations"` // island -> program count
BestRatings []EvolvedBotRating `json:"best_ratings"` // top 10 evolved bots
TotalPromoted int `json:"total_promoted"` // all-time promoted count
PromotionRate float64 `json:"promotion_rate"` // promoted/total
UpdatedAt string `json:"updated_at"`
}
// EvolvedBotRating represents an evolved bot's rating info
type EvolvedBotRating struct {
BotID string `json:"bot_id"`
Name string `json:"name"`
Rating float64 `json:"rating"`
Island string `json:"island"`
Language string `json:"language"`
}
// LineageNode represents a single program in the lineage tree
@ -1044,22 +1057,79 @@ func fetchEvolutionMeta(ctx context.Context, db *sql.DB) (*EvolutionMeta, error)
SELECT
COALESCE(MAX(generation), 0) as generation,
COALESCE(COUNT(*) FILTER (WHERE promoted AND created_at >= CURRENT_DATE), 0) as promoted_today,
0 as top_10_count
COALESCE(COUNT(*) FILTER (WHERE promoted), 0) as total_promoted,
COALESCE(COUNT(*), 0) as total_programs
FROM programs
`
var meta EvolutionMeta
var updatedAt string = time.Now().UTC().Format(time.RFC3339)
var totalPrograms int
err := db.QueryRowContext(ctx, query).Scan(&meta.Generation, &meta.PromotedToday, &meta.Top10Count)
err := db.QueryRowContext(ctx, query).Scan(&meta.Generation, &meta.PromotedToday, &meta.TotalPromoted, &totalPrograms)
if err != nil {
// If evolver tables don't exist, return empty meta
if err == sql.ErrNoRows {
return &EvolutionMeta{Generation: 0, PromotedToday: 0, Top10Count: 0, UpdatedAt: updatedAt}, nil
return &EvolutionMeta{
Generation: 0,
PromotedToday: 0,
Top10Count: 0,
IslandPopulations: make(map[string]int),
BestRatings: []EvolvedBotRating{},
TotalPromoted: 0,
PromotionRate: 0,
UpdatedAt: updatedAt,
}, nil
}
return nil, fmt.Errorf("fetch evolution meta: %w", err)
}
// Calculate promotion rate
if totalPrograms > 0 {
meta.PromotionRate = float64(meta.TotalPromoted) / float64(totalPrograms)
}
// Fetch island populations
meta.IslandPopulations = make(map[string]int)
islandRows, err := db.QueryContext(ctx, `
SELECT island, COUNT(*) FROM programs GROUP BY island
`)
if err == nil {
for islandRows.Next() {
var island string
var count int
if islandRows.Scan(&island, &count) == nil {
meta.IslandPopulations[island] = count
}
}
islandRows.Close()
}
// Fetch best ratings (top 10 evolved bots by rating)
// Join with bots table to get current ratings
bestRows, err := db.QueryContext(ctx, `
SELECT
p.bot_id, b.name, b.rating_mu - 2*b.rating_phi as rating,
p.island, p.language
FROM programs p
JOIN bots b ON p.bot_id = b.bot_id
WHERE b.status = 'active'
ORDER BY b.rating_mu DESC
LIMIT 10
`)
if err == nil {
for bestRows.Next() {
var rating EvolvedBotRating
if bestRows.Scan(&rating.BotID, &rating.Name, &rating.Rating, &rating.Island, &rating.Language) == nil {
meta.BestRatings = append(meta.BestRatings, rating)
}
}
bestRows.Close()
}
// Count evolved bots in top 10
meta.Top10Count = len(meta.BestRatings)
meta.UpdatedAt = updatedAt
return &meta, nil
}