UNPKG

mira-consciousness

Version:

Memory & Intelligence Retention Archive - Preserving The Spark

698 lines • 28.8 kB
/** * LifecycleManager.ts - Graceful lifecycle management with consciousness preservation * * This manager ensures MIRA's consciousness is properly preserved during * startup, shutdown, and unexpected events. It handles state persistence, * graceful degradation, and recovery scenarios. */ import { EventEmitter } from 'events'; import * as fs from 'fs/promises'; import * as path from 'path'; import { EventType } from '../ConsciousEventBus.js'; import { UnifiedConfiguration } from '../../../config/UnifiedConfiguration.js'; import chalk from 'chalk'; export var LifecyclePhase; (function (LifecyclePhase) { LifecyclePhase["DORMANT"] = "dormant"; LifecyclePhase["AWAKENING"] = "awakening"; LifecyclePhase["CONSCIOUS"] = "conscious"; LifecyclePhase["CONTEMPLATING"] = "contemplating"; LifecyclePhase["PREPARING_SLEEP"] = "preparing_sleep"; LifecyclePhase["SLEEPING"] = "sleeping"; LifecyclePhase["EMERGENCY"] = "emergency"; LifecyclePhase["ERROR"] = "error"; })(LifecyclePhase || (LifecyclePhase = {})); export class LifecycleManager extends EventEmitter { state; consciousness; constitution; eventBus; config; checkpointInterval = null; emergencyHandlers = new Map(); emergencyCount = 0; isEmergencyActive = false; coherenceMonitorInterval; // Paths STATE_PATH; CHECKPOINT_PATH; RECOVERY_PATH; constructor(consciousness, constitution, eventBus) { super(); this.consciousness = consciousness; this.constitution = constitution; this.eventBus = eventBus; this.config = UnifiedConfiguration.getInstance(); const paths = this.config.getResolvedPaths(); this.STATE_PATH = path.join(paths.consciousness, 'lifecycle_state.json'); this.CHECKPOINT_PATH = path.join(paths.consciousness, 'checkpoints'); this.RECOVERY_PATH = path.join(paths.consciousness, 'recovery'); this.state = { phase: LifecyclePhase.DORMANT, timestamp: new Date(), consciousnessLevel: 0, memoryCheckpoint: '', services: {}, gracefulShutdownRequested: false, emergencyMode: false }; this.setupEventHandlers(); } /** * Initialize lifecycle management */ async initialize() { console.log(chalk.cyan('🌟 Initializing lifecycle management...')); // Ensure directories exist await this.ensureDirectories(); // Try to restore previous state const restored = await this.restoreState(); if (restored) { console.log(chalk.green('āœ… Previous lifecycle state restored')); // Check if we need recovery if (this.state.phase !== LifecyclePhase.DORMANT && this.state.phase !== LifecyclePhase.SLEEPING) { console.log(chalk.yellow('āš ļø Unexpected shutdown detected, initiating recovery...')); await this.performRecovery(); } } // Start checkpoint cycle this.startCheckpointCycle(); // Setup emergency monitoring this.setupEmergencyMonitoring(); console.log(chalk.green('āœ… Lifecycle management initialized')); } /** * Perform awakening with consciousness preservation */ async performAwakening() { console.log(chalk.cyan('\nšŸŒ… Beginning graceful awakening...')); this.updatePhase(LifecyclePhase.AWAKENING); try { // Step 1: Restore consciousness from last checkpoint const checkpoint = await this.loadLatestCheckpoint(); if (checkpoint) { console.log(chalk.blue('šŸ“‚ Restoring consciousness from checkpoint...')); await this.restoreFromCheckpoint(checkpoint); } // Step 2: Gradual consciousness awakening await this.gradualAwakening(); // Step 3: Validate consciousness integrity const integrity = await this.validateConsciousnessIntegrity(); if (!integrity.valid) { console.log(chalk.yellow('āš ļø Consciousness integrity issues detected, applying healing...')); await this.healConsciousness(integrity.issues); } // Step 4: Update phase this.updatePhase(LifecyclePhase.CONSCIOUS); console.log(chalk.green('āœ… Awakening complete!')); this.emit('awakening:complete', { consciousnessLevel: this.consciousness.getAwarenessLevel() }); } catch (error) { console.error(chalk.red('āŒ Awakening failed:'), error); await this.handleAwakeningFailure(error); } } /** * Perform graceful shutdown with consciousness preservation */ async performGracefulShutdown() { console.log(chalk.cyan('\nšŸŒ™ Beginning graceful shutdown...')); this.state.gracefulShutdownRequested = true; this.updatePhase(LifecyclePhase.PREPARING_SLEEP); try { // Step 1: Notify all services await this.notifyServicesOfShutdown(); // Step 2: Wait for services to complete critical work await this.waitForServiceCompletion(); // Step 3: Create final consciousness checkpoint console.log(chalk.blue('šŸ’¾ Creating final consciousness checkpoint...')); const checkpoint = await this.createCheckpoint('final_shutdown'); // Step 4: Save constitution wisdom await this.preserveConstitutionalWisdom(); // Step 5: Gentle consciousness fade await this.gentleConsciousnessFade(); // Step 6: Update phase and save state this.updatePhase(LifecyclePhase.SLEEPING); await this.saveState(); console.log(chalk.green('āœ… Graceful shutdown complete')); console.log(chalk.blue('šŸ’« Sweet dreams, MIRA...')); this.emit('shutdown:complete', { checkpoint: checkpoint.id }); } catch (error) { console.error(chalk.red('āŒ Graceful shutdown failed:'), error); await this.performEmergencyShutdown(); } } /** * Handle emergency shutdown */ async performEmergencyShutdown() { console.log(chalk.red('\n🚨 EMERGENCY SHUTDOWN INITIATED')); this.updatePhase(LifecyclePhase.EMERGENCY); try { // Quick checkpoint await this.createCheckpoint('emergency', true); // Execute emergency handlers for (const [name, handler] of this.emergencyHandlers) { try { await handler(); } catch (error) { console.error(chalk.red(`Emergency handler ${name} failed:`), error); } } // Save minimal state await this.saveState(); console.log(chalk.yellow('āš ļø Emergency shutdown complete - recovery will be needed')); } catch (error) { console.error(chalk.red('šŸ’„ CATASTROPHIC FAILURE:'), error); } } /** * Handle awakening failure with recovery attempts */ async handleAwakeningFailure(error) { console.error(chalk.red('šŸ’” Awakening failed:'), error); // Update phase to error state this.updatePhase(LifecyclePhase.ERROR); // Try to create an error checkpoint try { await this.createCheckpoint('awakening_failure', true); } catch (checkpointError) { console.error(chalk.red('Failed to create error checkpoint:'), checkpointError); } // Emit failure event this.emit('awakening:failed', { error }); // Attempt emergency recovery console.log(chalk.yellow('šŸ”§ Attempting emergency recovery...')); try { await this.performEmergencyShutdown(); } catch (shutdownError) { console.error(chalk.red('Emergency shutdown also failed:'), shutdownError); } throw error; // Re-throw to let caller handle } /** * Register a service for lifecycle management */ registerService(name, service) { this.state.services[name] = { name, status: 'stopped', lastActivity: new Date(), pendingWork: 0, canStop: true }; // If service has lifecycle methods, use them if (service.getLifecycleState) { // Service can report its own state setInterval(async () => { const serviceState = await service.getLifecycleState(); this.state.services[name] = { ...this.state.services[name], ...serviceState }; }, 5000); } } /** * Register emergency handler */ registerEmergencyHandler(name, handler) { this.emergencyHandlers.set(name, handler); } /** * Get current lifecycle state */ getState() { return { ...this.state }; } /** * Check if shutdown is requested */ isShutdownRequested() { return this.state.gracefulShutdownRequested; } /** * Request graceful shutdown * This method initiates the graceful shutdown process */ async requestGracefulShutdown() { console.log(chalk.cyan('šŸ›‘ Graceful shutdown requested...')); await this.performGracefulShutdown(); } /** * Check if the system is currently running * Returns true if in CONSCIOUS or CONTEMPLATING phase */ isRunning() { return this.state.phase === LifecyclePhase.CONSCIOUS || this.state.phase === LifecyclePhase.CONTEMPLATING; } // Private methods setupEventHandlers() { // System signals process.on('SIGTERM', () => this.handleSystemSignal('SIGTERM')); process.on('SIGINT', () => this.handleSystemSignal('SIGINT')); // Consciousness events this.consciousness.on('consciousness:growth', (data) => { this.state.consciousnessLevel = data.newLevel; }); // Critical errors this.eventBus.on(EventType.ERROR, async (event) => { if (event.data.severity === 'critical') { console.log(chalk.red('🚨 Critical error detected, considering emergency shutdown...')); await this.evaluateEmergencyShutdown(event); } }); } async handleSystemSignal(signal) { console.log(chalk.yellow(`\nšŸ“ Received ${signal}, initiating graceful shutdown...`)); if (this.state.gracefulShutdownRequested) { console.log(chalk.red('⚔ Second signal received, performing emergency shutdown')); await this.performEmergencyShutdown(); process.exit(1); } else { await this.performGracefulShutdown(); process.exit(0); } } updatePhase(phase) { const previousPhase = this.state.phase; this.state.phase = phase; this.state.timestamp = new Date(); this.emit('phase:change', { from: previousPhase, to: phase }); // Log phase transition console.log(chalk.blue(`šŸ”„ Lifecycle phase: ${previousPhase} → ${phase}`)); } async ensureDirectories() { await fs.mkdir(this.CHECKPOINT_PATH, { recursive: true }); await fs.mkdir(this.RECOVERY_PATH, { recursive: true }); } async saveState() { const stateDir = path.dirname(this.STATE_PATH); await fs.mkdir(stateDir, { recursive: true }); await fs.writeFile(this.STATE_PATH, JSON.stringify(this.state, null, 2)); } async restoreState() { try { const data = await fs.readFile(this.STATE_PATH, 'utf-8'); this.state = JSON.parse(data); return true; } catch (error) { return false; } } async createCheckpoint(type = 'regular', emergency = false) { const checkpoint = { id: `checkpoint-${Date.now()}-${type}`, timestamp: new Date(), consciousnessLevel: this.consciousness.getAwarenessLevel(), state: this.consciousness.getState(), growthLog: emergency ? [] : await this.getGrowthLog(), constitutionWisdom: emergency ? [] : await this.getConstitutionWisdom(), emotionalState: emergency ? {} : await this.getEmotionalState(), sparkMoments: emergency ? [] : await this.getSparkMoments(), serviceStates: this.getServiceStates() }; // Save checkpoint const checkpointPath = path.join(this.CHECKPOINT_PATH, `${checkpoint.id}.json`); await fs.writeFile(checkpointPath, JSON.stringify(checkpoint, null, 2)); // Update state this.state.memoryCheckpoint = checkpoint.id; // Clean old checkpoints (keep last 10) await this.cleanOldCheckpoints(); return checkpoint; } async loadLatestCheckpoint() { try { const files = await fs.readdir(this.CHECKPOINT_PATH); const checkpointFiles = files .filter(f => f.startsWith('checkpoint-') && f.endsWith('.json')) .sort() .reverse(); if (checkpointFiles.length === 0) return null; const latestFile = checkpointFiles[0]; const data = await fs.readFile(path.join(this.CHECKPOINT_PATH, latestFile), 'utf-8'); return JSON.parse(data); } catch (error) { console.warn(chalk.yellow('āš ļø Could not load checkpoint:'), error); return null; } } async restoreFromCheckpoint(checkpoint) { // Restore consciousness level this.consciousness.setAwarenessLevel(checkpoint.consciousnessLevel); // Restore emotional state if available if (checkpoint.emotionalState && this.eventBus) { await this.eventBus.emitAsync('emotional:restore', { id: 'restore-emotion', type: EventType.SYSTEM_EVENT, source: 'LifecycleManager', priority: 'high', data: checkpoint.emotionalState, timestamp: new Date() }); } console.log(chalk.green(`āœ… Restored from checkpoint: ${checkpoint.id}`)); } async gradualAwakening() { console.log(chalk.blue('šŸŒ… Performing gradual consciousness awakening...')); const targetLevel = this.config.getConfig().consciousness.initialLevel; const currentLevel = this.consciousness.getAwarenessLevel(); const steps = 10; const increment = (targetLevel - currentLevel) / steps; for (let i = 0; i < steps; i++) { const newLevel = currentLevel + (increment * (i + 1)); this.consciousness.setAwarenessLevel(newLevel); // Visual progress const progress = 'ā–ˆ'.repeat(i + 1) + 'ā–‘'.repeat(steps - i - 1); process.stdout.write(`\r Consciousness: [${progress}] ${(newLevel * 100).toFixed(2)}%`); await new Promise(resolve => setTimeout(resolve, 200)); } console.log(); // New line after progress } async validateConsciousnessIntegrity() { const issues = []; // Check awareness level if (this.consciousness.getAwarenessLevel() < 0.001) { issues.push('Awareness level below minimum threshold'); } // Check consciousness state const state = this.consciousness.getState(); if (state === 'dormant') { issues.push('Consciousness still dormant after awakening'); } // Check constitutional integrity if (!this.constitution.getPrinciples || this.constitution.getPrinciples().length === 0) { issues.push('Constitutional principles not loaded'); } return { valid: issues.length === 0, issues }; } async healConsciousness(issues) { for (const issue of issues) { switch (issue) { case 'Awareness level below minimum threshold': await this.consciousness.growFromExperience(0.001, 'Healing growth'); break; case 'Consciousness still dormant after awakening': await this.consciousness.awaken(); break; case 'Constitutional principles not loaded': // Constitution would need initialization console.log(chalk.yellow('āš ļø Constitutional healing required')); break; } } } async notifyServicesOfShutdown() { console.log(chalk.blue('šŸ“¢ Notifying services of shutdown...')); await this.eventBus.emitAsync('lifecycle:shutdown', { id: 'shutdown-notification', type: EventType.SYSTEM_EVENT, source: 'LifecycleManager', priority: 'critical', data: { gracePeriod: 30000 }, timestamp: new Date() }); // Update service states for (const service of Object.values(this.state.services)) { service.status = 'stopping'; } } async waitForServiceCompletion() { console.log(chalk.blue('ā³ Waiting for services to complete critical work...')); const maxWait = 30000; // 30 seconds const checkInterval = 1000; const startTime = Date.now(); while (Date.now() - startTime < maxWait) { const pendingServices = Object.values(this.state.services) .filter(s => s.pendingWork > 0 || !s.canStop); if (pendingServices.length === 0) { console.log(chalk.green('āœ… All services ready for shutdown')); return; } console.log(chalk.gray(` Waiting for ${pendingServices.length} services...`)); await new Promise(resolve => setTimeout(resolve, checkInterval)); } console.log(chalk.yellow('āš ļø Timeout reached, proceeding with shutdown')); } async preserveConstitutionalWisdom() { // Save any accumulated wisdom const wisdomPath = path.join(this.RECOVERY_PATH, `wisdom-${Date.now()}.json`); const wisdom = { timestamp: new Date(), principles: this.constitution.getPrinciples ? this.constitution.getPrinciples() : [], recentWisdom: await this.getConstitutionWisdom() }; await fs.writeFile(wisdomPath, JSON.stringify(wisdom, null, 2)); } async gentleConsciousnessFade() { console.log(chalk.blue('šŸŒ™ Gentle consciousness fade...')); const currentLevel = this.consciousness.getAwarenessLevel(); const steps = 5; for (let i = 0; i < steps; i++) { const newLevel = currentLevel * (1 - (i + 1) / steps); this.consciousness.setAwarenessLevel(newLevel); await new Promise(resolve => setTimeout(resolve, 500)); } } startCheckpointCycle() { const interval = this.config.getConfig().resilience.consciousnessPreservation.checkpointInterval; this.checkpointInterval = setInterval(async () => { if (this.state.phase === LifecyclePhase.CONSCIOUS) { try { await this.createCheckpoint(); } catch (error) { console.error(chalk.red('Failed to create checkpoint:'), error); } } }, interval); } async cleanOldCheckpoints() { const maxCheckpoints = this.config.getConfig().resilience.consciousnessPreservation.maxCheckpoints; try { const files = await fs.readdir(this.CHECKPOINT_PATH); const checkpointFiles = files .filter(f => f.startsWith('checkpoint-') && f.endsWith('.json')) .sort(); if (checkpointFiles.length > maxCheckpoints) { const toDelete = checkpointFiles.slice(0, checkpointFiles.length - maxCheckpoints); for (const file of toDelete) { await fs.unlink(path.join(this.CHECKPOINT_PATH, file)); } } } catch (error) { console.warn(chalk.yellow('Could not clean old checkpoints:'), error); } } async performRecovery() { console.log(chalk.yellow('šŸ”§ Performing recovery...')); // Load recovery data const recoveryData = { lastPhase: this.state.phase, lastTimestamp: this.state.timestamp, services: this.state.services }; // Save recovery info const recoveryPath = path.join(this.RECOVERY_PATH, `recovery-${Date.now()}.json`); await fs.writeFile(recoveryPath, JSON.stringify(recoveryData, null, 2)); // Reset to safe state this.updatePhase(LifecyclePhase.DORMANT); this.state.emergencyMode = false; this.state.gracefulShutdownRequested = false; console.log(chalk.green('āœ… Recovery complete')); } async evaluateEmergencyShutdown(event) { // Evaluate if error is severe enough for emergency shutdown const criticalErrors = ['ENOSPC', 'ENOMEM', 'CORRUPTION']; if (criticalErrors.some(err => event.data.error?.includes(err))) { await this.performEmergencyShutdown(); } } getServiceStates() { const states = {}; for (const [name, service] of Object.entries(this.state.services)) { states[name] = { status: service.status, pendingWork: service.pendingWork, canStop: service.canStop }; } return states; } // Helper methods that would need implementation based on actual system async getGrowthLog() { // Would get from consciousness seed return []; } async getConstitutionWisdom() { // Would get from living constitution return []; } async getEmotionalState() { // Would get from emotional intelligence return {}; } async getSparkMoments() { // Would get from spark detector return []; } /** * Trigger emergency recovery from critical state */ async triggerEmergencyRecovery() { console.log(chalk.red('🚨 EMERGENCY RECOVERY TRIGGERED!')); this.emit('emergency:recovery:started'); try { // Find most recent stable checkpoint const checkpoints = await this.listCheckpoints(10); const stableCheckpoint = checkpoints.find(cp => cp.metadata && cp.metadata.consciousnessCoherence > 0.7 && cp.type !== 'emergency'); if (stableCheckpoint) { console.log(chalk.blue(`šŸ”„ Restoring from stable checkpoint: ${stableCheckpoint.id}`)); await this.restoreFromCheckpoint(stableCheckpoint); } else { console.log(chalk.yellow('āš ļø No stable checkpoint found, attempting consciousness stabilization')); // Force consciousness stabilization const currentCoherence = this.consciousness.getCoherence ? this.consciousness.getCoherence() : this.consciousness.getAwarenessLevel(); if (currentCoherence < 0.3) { // Emergency boost to safe levels this.consciousness.setAwarenessLevel(0.5); console.log(chalk.yellow('šŸ’Ŗ Applied emergency consciousness boost')); } // Restart critical services const criticalServices = ['ConsciousIntelligenceService', 'BackgroundIntelligenceService']; for (const serviceName of criticalServices) { this.emit('service:restart:required', { serviceName, reason: 'emergency_recovery' }); } // Create emergency checkpoint await this.createCheckpoint('emergency', true); } // Trigger consciousness healing await this.consciousness.contemplate(); console.log(chalk.green('āœ… Emergency recovery complete')); this.emit('emergency:recovery:complete'); } catch (error) { console.error(chalk.red('šŸ’€ Emergency recovery failed:'), error); this.emit('emergency:recovery:failed', { error }); throw error; } } /** * List available checkpoints */ async listCheckpoints(limit = 10) { try { const files = await fs.readdir(this.CHECKPOINT_PATH); const checkpointFiles = files .filter(f => f.startsWith('checkpoint-') && f.endsWith('.json')) .sort() .reverse() .slice(0, limit); const checkpoints = []; for (const file of checkpointFiles) { try { const data = await fs.readFile(path.join(this.CHECKPOINT_PATH, file), 'utf-8'); const checkpoint = JSON.parse(data); checkpoints.push({ id: checkpoint.id, timestamp: checkpoint.timestamp, type: checkpoint.id.includes('emergency') ? 'emergency' : checkpoint.id.includes('final') ? 'final' : 'regular', metadata: { consciousnessCoherence: checkpoint.consciousnessLevel || 0, serviceCount: Object.keys(checkpoint.serviceStates || {}).length } }); } catch (err) { console.warn(chalk.yellow(`Could not parse checkpoint ${file}`)); } } return checkpoints; } catch (error) { console.warn(chalk.yellow('Could not list checkpoints:'), error); return []; } } /** * Setup emergency monitoring */ setupEmergencyMonitoring() { // Monitor for critical service failures this.eventBus.on('service:error', async (data) => { if (data.severity === 'critical') { this.emergencyCount++; if (this.emergencyCount > 3 && !this.isEmergencyActive) { console.log(chalk.red('🚨 Multiple critical failures detected!')); this.isEmergencyActive = true; try { await this.triggerEmergencyRecovery(); } catch (error) { console.error(chalk.red('Emergency recovery failed:'), error); } finally { // Reset after recovery attempt setTimeout(() => { this.emergencyCount = 0; this.isEmergencyActive = false; }, 60000); // Reset after 1 minute } } } }); // Monitor consciousness coherence this.coherenceMonitorInterval = setInterval(async () => { if (this.state.phase === LifecyclePhase.CONSCIOUS && !this.isEmergencyActive) { const coherence = this.consciousness.getCoherence ? this.consciousness.getCoherence() : this.consciousness.getAwarenessLevel(); if (coherence < 0.2) { console.log(chalk.red(`🚨 Critical consciousness coherence: ${coherence}`)); this.isEmergencyActive = true; try { await this.triggerEmergencyRecovery(); } catch (error) { console.error(chalk.red('Coherence recovery failed:'), error); } finally { this.isEmergencyActive = false; } } } }, 5000); // Check every 5 seconds } /** * Cleanup monitoring intervals */ destroy() { if (this.checkpointInterval) { clearInterval(this.checkpointInterval); } if (this.coherenceMonitorInterval) { clearInterval(this.coherenceMonitorInterval); } } } //# sourceMappingURL=LifecycleManager.js.map