package main import ( "log" "os" "os/signal" "syscall" "swoosh" ) func main() { // Configuration from environment listenAddr := getEnv("SWOOSH_LISTEN_ADDR", ":8080") walDir := getEnv("SWOOSH_WAL_DIR", "./data/wal") snapshotPath := getEnv("SWOOSH_SNAPSHOT_PATH", "./data/snapshots/latest.json") log.Printf("SWOOSH starting...") log.Printf(" Listen: %s", listenAddr) log.Printf(" WAL: %s", walDir) log.Printf(" Snapshot: %s", snapshotPath) // Initialize production WAL store (BadgerDB) wal, err := swoosh.NewBadgerWALStore(walDir) if err != nil { log.Fatalf("failed to open WAL: %v", err) } defer wal.Close() // Initialize production snapshot store (atomic file writes) snapStore := swoosh.NewFileSnapshotStore(snapshotPath) // Recover state from snapshot + WAL replay state := recoverState(wal, snapStore) log.Printf(" Recovered state hash: %s", state.StateHash) log.Printf(" Licensed: %v", state.Boot.Licensed) log.Printf(" Quarantined: %v", state.Policy.Quarantined) log.Printf(" HLC last: %s", state.HLCLast) // Create initial snapshot if this is first boot snapshot := swoosh.Snapshot{ State: state, LastAppliedHLC: state.HLCLast, LastAppliedIndex: wal.LastIndex(), } // Create nil guard provider for now // In production, implement GuardProvider with KACHING, BACKBEAT, HMMM, SHHH, MCP var guard swoosh.GuardProvider = nil // Initialize executor (single source of truth) executor := swoosh.NewExecutor(wal, snapStore, guard, snapshot) // Setup graceful shutdown sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigChan log.Println("Shutdown signal received, saving final snapshot...") // Get final state and save snapshot finalState := executor.GetStateSnapshot() finalSnapshot := swoosh.Snapshot{ State: finalState, LastAppliedHLC: finalState.HLCLast, LastAppliedIndex: wal.LastIndex(), } if err := snapStore.Save(finalSnapshot); err != nil { log.Printf("WARNING: failed to save final snapshot: %v", err) } else { log.Printf("Final snapshot saved: hash=%s hlc=%s", finalState.StateHash, finalState.HLCLast) } if err := wal.Close(); err != nil { log.Printf("WARNING: failed to close WAL: %v", err) } os.Exit(0) }() // Start HTTP server (blocks until error or shutdown) log.Printf("HTTP server listening on %s", listenAddr) if err := swoosh.StartHTTPServer(listenAddr, executor); err != nil { log.Fatalf("HTTP server failed: %v", err) } } // recoverState loads the latest snapshot and replays WAL to reconstruct state. // // Recovery steps: // 1. Attempt to load latest snapshot // 2. If snapshot exists, use it as base state // 3. If no snapshot, start from genesis state // 4. Replay all WAL records since snapshot's LastAppliedIndex // 5. Return fully recovered OrchestratorState // // This ensures crash recovery: even if crashed mid-transition, WAL replay // deterministically reconstructs exact state. func recoverState(wal *swoosh.BadgerWALStore, snapStore *swoosh.FileSnapshotStore) swoosh.OrchestratorState { var state swoosh.OrchestratorState var lastAppliedIndex uint64 // Try to load latest snapshot snapshot, err := snapStore.LoadLatest() if err != nil { log.Printf("No snapshot found, starting from genesis: %v", err) state = genesisState() lastAppliedIndex = 0 } else { log.Printf("Loaded snapshot: index=%d hlc=%s", snapshot.LastAppliedIndex, snapshot.LastAppliedHLC) state = snapshot.State lastAppliedIndex = snapshot.LastAppliedIndex } // Replay WAL records since snapshot records, err := wal.Replay(lastAppliedIndex + 1) if err != nil { log.Fatalf("WAL replay failed: %v", err) } if len(records) > 0 { log.Printf("Replaying %d WAL records from index %d...", len(records), lastAppliedIndex+1) // Replay each record deterministically // Use nil guard since guards were already evaluated during original execution nilGuard := swoosh.GuardOutcome{ LicenseOK: true, BackbeatOK: true, QuorumOK: true, PolicyOK: true, MCPHealthy: true, } for _, record := range records { // Apply transition using reducer (deterministic replay) newState, err := swoosh.Reduce(state, record.Transition, nilGuard) if err != nil { log.Printf("WARNING: replay error at index %d: %v", record.Index, err) // Continue replay - reducer may have evolved since record was written continue } // Verify state hash matches if newState.StateHash != record.StatePostHash { log.Printf("WARNING: state hash mismatch at index %d (expected=%s got=%s)", record.Index, record.StatePostHash, newState.StateHash) } state = newState lastAppliedIndex = record.Index } log.Printf("Replay complete: final index=%d hash=%s", lastAppliedIndex, state.StateHash) } else { log.Printf("No WAL records to replay") } return state } // genesisState returns the initial OrchestratorState for a fresh deployment. func genesisState() swoosh.OrchestratorState { state := swoosh.OrchestratorState{ Meta: struct { Version string SchemaHash string }{ Version: "1.0.0", SchemaHash: "genesis", }, HLCLast: "0-0-0000000000000000", } // Compute initial state hash hash, err := swoosh.ComputeStateHash(state) if err != nil { log.Printf("WARNING: failed to compute genesis state hash: %v", err) hash = "genesis-hash-unavailable" } state.StateHash = hash return state } func getEnv(key, fallback string) string { if value := os.Getenv(key); value != "" { return value } return fallback }