diff --git a/cmd/acb-evolver/run.go b/cmd/acb-evolver/run.go index d170852..c30c93d 100644 --- a/cmd/acb-evolver/run.go +++ b/cmd/acb-evolver/run.go @@ -187,7 +187,21 @@ func RunEvolutionLoop(ctx context.Context, dbURL string, args []string) { } defer db.Close() + // Initialize database schema and seed initial population if needed + ctx := context.Background() + if err := evolverdb.EnsureSchema(ctx, db); err != nil { + log.Fatalf("ensure schema: %v", err) + } + + // Seed initial population if programs table is empty store := evolverdb.NewStore(db) + if inserted, err := evolverdb.SeedPopulation(ctx, store); err != nil { + log.Fatalf("seed population: %v", err) + } else if inserted > 0 { + log.Printf("Seeded %d initial programs", inserted) + } else { + log.Println("Programs table already seeded") + } // Load config from env with overrides cfg := DefaultRunConfig() diff --git a/cmd/acb-index-builder/db.go b/cmd/acb-index-builder/db.go index 699e0bb..04423d8 100644 --- a/cmd/acb-index-builder/db.go +++ b/cmd/acb-index-builder/db.go @@ -5,6 +5,7 @@ import ( "database/sql" "encoding/json" "fmt" + "log/slog" "time" ) @@ -258,9 +259,18 @@ func fetchAllData(ctx context.Context, db *sql.DB) (*IndexData, error) { return nil, err } - // Evolution data (may be missing if evolver DB is not available) + // Evolution data (may be missing if evolver is not running) data.EvolutionMeta, _ = fetchEvolutionMeta(ctx, db) data.Lineage, _ = fetchLineage(ctx, db) + if data.EvolutionMeta != nil && data.EvolutionMeta.Generation > 0 { + slog.Info("Evolution system running", + "generation", data.EvolutionMeta.Generation, + "promoted_today", data.EvolutionMeta.PromotedToday, + "total_promoted", data.EvolutionMeta.TotalPromoted, + "islands", len(data.EvolutionMeta.IslandPopulations)) + } else { + slog.Info("Evolution system not initialized or not running") + } data.TopPredictors = computeTopPredictors(data.PredictorStats) @@ -1050,6 +1060,7 @@ type LineageNode struct { // fetchEvolutionMeta queries the evolver database for evolution statistics. // It connects to the evolver database using the same connection parameters. +// Returns empty meta (not an error) if the evolution system is not running. func fetchEvolutionMeta(ctx context.Context, db *sql.DB) (*EvolutionMeta, error) { // Query the programs table in the evolver database // Note: the evolver uses a separate database but same PostgreSQL instance @@ -1068,20 +1079,19 @@ func fetchEvolutionMeta(ctx context.Context, db *sql.DB) (*EvolutionMeta, error) 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, - IslandPopulations: make(map[string]int), - BestRatings: []EvolvedBotRating{}, - TotalPromoted: 0, - PromotionRate: 0, - UpdatedAt: updatedAt, - }, nil - } - return nil, fmt.Errorf("fetch evolution meta: %w", err) + // If evolver tables don't exist or query fails, return empty meta + // This is expected when the evolution system has not been initialized yet + slog.Info("Evolution system not running or programs table empty", "error", err) + return &EvolutionMeta{ + Generation: 0, + PromotedToday: 0, + Top10Count: 0, + IslandPopulations: make(map[string]int), + BestRatings: []EvolvedBotRating{}, + TotalPromoted: 0, + PromotionRate: 0, + UpdatedAt: updatedAt, + }, nil } // Calculate promotion rate diff --git a/cmd/acb-index-builder/generator.go b/cmd/acb-index-builder/generator.go index e629ddc..3788906 100644 --- a/cmd/acb-index-builder/generator.go +++ b/cmd/acb-index-builder/generator.go @@ -6,6 +6,7 @@ import ( "encoding/json" "encoding/xml" "fmt" + "log/slog" "math" "os" "path/filepath" @@ -2094,12 +2095,23 @@ func generateEvolutionMeta(data *IndexData, outputDir string) error { // If no evolution meta data, write empty placeholder meta := data.EvolutionMeta if meta == nil { + slog.Info("Evolution meta data not available - evolution system not running") meta = &EvolutionMeta{ - Generation: 0, - PromotedToday: 0, - Top10Count: 0, - UpdatedAt: data.GeneratedAt.Format(time.RFC3339), + Generation: 0, + PromotedToday: 0, + Top10Count: 0, + IslandPopulations: make(map[string]int), + BestRatings: []EvolvedBotRating{}, + TotalPromoted: 0, + PromotionRate: 0, + UpdatedAt: data.GeneratedAt.Format(time.RFC3339), } + } else { + slog.Info("Writing evolution meta data", + "generation", meta.Generation, + "promoted_today", meta.PromotedToday, + "total_promoted", meta.TotalPromoted, + "islands", len(meta.IslandPopulations)) } return writeJSON(filepath.Join(evolDir, "meta.json"), meta)