package console import ( "context" "log" "github.com/carlosframework/platform/internal/provision" ) // discrepancyScanCap bounds one app's record listing. ListRecords treats // max=0 as "list nothing", so the cap must be explicit. const discrepancyScanCap = 10000 // LogPlacementDiscrepancies is spec §5.7 step 4, run once at console // start. For each app holding a non-home region, it lists records with an // empty region created after the app — the shape a console rolled back // below the floor would have written. Shapes that never inherit the app // default are skipped (static, addr-backed, replica, pooled, fleet). A // deliberate home override looks the same and the record keeps no // provenance, so each line is a CANDIDATE for review, worded as one (C29). // It only logs: an error is reported and skipped, never returned, so the // check can neither block nor fail console start. func (s *Server) LogPlacementDiscrepancies(ctx context.Context) { s.logPlacementDiscrepancies(ctx, discrepancyScanCap) } func (s *Server) logPlacementDiscrepancies(ctx context.Context, scanCap int) { if s.cfg.Releases == nil { return } apps, err := s.store.NonHomeAppRegions() if err != nil { log.Printf("console: placement discrepancy check: %v", err) return } for _, a := range apps { recs, truncated, err := provision.ListRecords(ctx, s.cfg.Releases, a.Sqid, a.App, scanCap) if err != nil { log.Printf("console: placement discrepancy check %s/%s: %v", a.Sqid, a.App, err) continue } if truncated { log.Printf("console: placement discrepancy check %s/%s: only the first %d records were checked", a.Sqid, a.App, scanCap) } for _, r := range recs { if r.Region != "" || r.Role != "" || r.Pool != "" || !r.DerivesPaths() || r.CreatedAt.Before(a.CreatedAt) { continue } log.Print("console: " + msgPlacementDiscrepancy(r.Host, a.App, a.Region)) } } }