Files
Redflag/docs/4_LOG/December_2025/2025-12-16_Execution_Order_Investigation.md

4.3 KiB

REDFLAG INVESTIGATION - EXECUTION ORDER BUG

CRITICAL DISCOVERY: EXECUTION ORDER IS THE BUG

THE FUCKING DIFFERENCE BETWEEN LEGACY AND NEW VERSIONS:

LEGACY VERSION (WORKS):

main() starts
config.Load()
├─ If fails → startWelcomeModeServer() → RETURN (NO EnsureAdminUser)
├─ If succeeds → continue with init
   └─ EnsureAdminUser(cfg.Admin.Username, cfg.Admin.Password) (AFTER config loaded)

NEW VERSION (BROKEN):

main() starts
config.Load() (always succeeds, even with empty strings)
├─ Database init continues
├─ Line 217: EnsureAdminUser(cfg.Admin.Username, cfg.Admin.Password) ← RUNS EARLY!
├─ Lines 250-263: Security services init
├─ Line 266: isSetupComplete(cfg, signingService, db, userQueries) ← TOO LATE!
└─ If not complete → startWelcomeModeServer()

THE ACTUAL FAILURE SEQUENCE:

  1. Fresh install with no .env file
  2. config.Load() returns empty strings for REDFLAG_ADMIN_PASSWORD = ""
  3. Line 217: EnsureAdminUser runs with EMPTY password
  4. Admin user created in database with empty/default password → "CHANGE_ME_ADMIN_PASSWORD" hash
  5. Line 266: isSetupComplete() checks if setup complete (admin already exists!)
  6. Setup UI might not even show properly because admin user exists
  7. User completes setup, enters "Qu@ntum21!", .env gets updated
  8. User restarts server
  9. EnsureAdminUser runs again but admin user already exists → returns early, DOES NOTHING
  10. Database still has "CHANGE_ME_ADMIN_PASSWORD" hash
  11. Login fails because database password != .env password

THE ROOT CAUSE:

NEW VERSION ADDED isSetupComplete() AFTER EnsureAdminUser()

This "security improvement" broke the fundamental timing that made setup work:

  • Legacy: Admin user created ONLY after successful config load
  • New: Admin user created BEFORE checking if config is actually valid

LEGACY VERSION DOESN'T HAVE isSetupComplete():

$ grep -r "isSetupComplete" /home/casey/Projects/RedFlag\ \(Legacy\)/aggregator-server/
(no results)

NEW VERSION HAS isSetupComplete():

$ grep -r "isSetupComplete" /home/casey/Projects/RedFlag/aggregator-server/
cmd/server/main.go:266:	if !isSetupComplete(cfg, signingService, db, userQueries) {
cmd/server/main.go:50:func isSetupComplete(cfg *Config, signingService *services.SigningService, db *DB, userQueries *UserQueries) bool {

THE FUCKING TIMING:

LEGACY TIMING (CORRECT):

Config loads with bootstrap → Setup runs → .env created → Restart → Config loads with new password → Admin user created with NEW password

NEW TIMING (BROKEN):

Config loads with empty → Admin user created with EMPTY password → Setup runs → .env created → Restart → Admin user already exists → Login fails

WHY LEGACY WORKS FOR ALPHA TESTERS:

  • Fresh database start (no admin user)
  • Setup creates .env with new password
  • Restart triggers EnsureAdminUser with NEW password
  • Admin user created correctly
  • Login works

WHY NEW VERSION FAILS:

  • Fresh database start
  • EnsureAdminUser creates admin with EMPTY/WRONG password BEFORE setup
  • Setup creates .env but admin user already exists
  • No password update happens
  • Login fails

THIS EXPLAINS EVERYTHING:

  • Identical EnsureAdminUser functions in both versions
  • Identical setup code in both versions
  • But execution timing is completely different
  • New version breaks setup by premature admin user creation

THE CRITICAL QUESTION:

WHEN WAS isSetupComplete() ADDED?

This function and its placement AFTER EnsureAdminUser() is what broke fresh installs. This was added during the "security hardening" updates but broke the fundamental setup flow.

ADDITIONAL QUESTION:

WHY IS THERE AN EnsureAdminUser() FUNCTION AT ALL?

The system only ever has ONE user - THE ADMIN. So why do we need:

  1. A function to "ensure" admin user exists
  2. A function that returns early if admin exists (preventing updates)
  3. No function to UPDATE existing admin user passwords

This design assumes admin user is created once and never changed, which contradicts the documented requirement that users should be able to set custom admin passwords during setup.

THE IMPACT:

  • All fresh installs are broken
  • Setup process fundamentally broken
  • Cannot change admin passwords from defaults
  • Database admin user gets wrong password hash

This is a P0 critical bug that breaks the entire onboarding experience.