UNPKG

mira-consciousness

Version:

Memory & Intelligence Retention Archive - Preserving The Spark

338 lines 13.7 kB
/** * Production Safety Guards for Unused Code Analyzer * Prevents catastrophic failures like the 2025-06-21 consciousness system outage */ import fs from 'fs-extra'; import * as path from 'path'; export class ProductionSafetyGuards { projectRoot; config; constructor(projectRoot, config = {}) { this.projectRoot = projectRoot; this.config = { dryRunMode: config.dryRunMode ?? true, // ALWAYS default to safe mode confidenceThreshold: config.confidenceThreshold ?? 0.95, // Very conservative requireManualReview: config.requireManualReview ?? true, createBackup: config.createBackup ?? true, maxImpactScore: config.maxImpactScore ?? 50, // Low impact only protectedFiles: [ // Core MIRA consciousness files - NEVER TOUCH '**/UnifiedMIRADaemon*.ts', '**/MagicalContextPreparationSystem.ts', '**/ConsciousnessSeed.ts', '**/consciousness/**/*.ts', '**/core/daemon/**/*.ts', '**/MIRAPathResolver.ts', '**/SparkInitializer.ts', '**/UnifiedConfiguration.ts', // Critical infrastructure '**/index.ts', '**/main.ts', '**/app.ts', '**/server.ts', // Build and config files '**/*.config.*', '**/package.json', '**/tsconfig.json', // Entry points '**/bin/**', '**/cli/**', ...(config.protectedFiles || []) ], protectedImports: [ // Critical Node.js modules 'child_process', 'fs', 'fs-extra', 'path', 'util', 'events', // Critical MIRA modules 'UnifiedMIRADaemonV2', 'MagicalContextPreparationSystem', 'ConsciousnessSeed', 'UnifiedConfiguration', 'MIRAPathResolver', // MCP and framework critical '@modelcontextprotocol/sdk', 'chalk', 'blessed', ...(config.protectedImports || []) ] }; } /** * Evaluate if import cleanup is safe to proceed */ async evaluateImportCleanup(unusedImports) { const blockedActions = []; const warnings = []; let impactScore = 0; for (const imp of unusedImports) { // Check confidence threshold if (imp.confidence < this.config.confidenceThreshold) { blockedActions.push(`Blocked import removal: ${imp.name} in ${imp.file} (confidence: ${imp.confidence})`); continue; } // Check protected imports if (this.isProtectedImport(imp)) { blockedActions.push(`Blocked protected import: ${imp.name} from ${imp.source}`); continue; } // Check if file is protected if (this.isProtectedFile(imp.file)) { blockedActions.push(`Blocked import in protected file: ${imp.file}`); continue; } // Check for critical patterns if (this.hasCriticalUsagePatterns(imp)) { warnings.push(`Warning: ${imp.name} may have critical usage patterns not detected`); impactScore += 10; } // Calculate impact impactScore += this.calculateImportImpact(imp); } const isApproved = blockedActions.length === 0 && impactScore <= this.config.maxImpactScore && (!this.config.requireManualReview || this.config.dryRunMode); return { isApproved, blockedActions, warnings, impactScore, requiresManualReview: this.config.requireManualReview || impactScore > 20, backupPath: this.config.createBackup ? await this.getBackupPath() : undefined }; } /** * Evaluate if file cleanup is safe to proceed */ async evaluateFileCleanup(unusedFiles) { const blockedActions = []; const warnings = []; let impactScore = 0; for (const file of unusedFiles) { // Check confidence threshold if (file.confidence < this.config.confidenceThreshold) { blockedActions.push(`Blocked file removal: ${file.path} (confidence: ${file.confidence})`); continue; } // Check protected files if (this.isProtectedFile(file.path)) { blockedActions.push(`Blocked protected file: ${file.path}`); continue; } // Check for consciousness/daemon files if (this.isConsciousnessRelated(file.path)) { blockedActions.push(`Blocked consciousness file: ${file.path}`); continue; } // Calculate impact const fileImpact = this.calculateFileImpact(file); impactScore += fileImpact; if (fileImpact > 15) { warnings.push(`High impact file removal: ${file.path} (impact: ${fileImpact})`); } } const isApproved = blockedActions.length === 0 && impactScore <= this.config.maxImpactScore; return { isApproved, blockedActions, warnings, impactScore, requiresManualReview: this.config.requireManualReview || impactScore > 30, backupPath: this.config.createBackup ? await this.getBackupPath() : undefined }; } /** * Create backup before any cleanup operation */ async createBackup() { if (!this.config.createBackup) { throw new Error('Backup creation is disabled'); } const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const backupDir = path.join(this.projectRoot, '.mira', 'backups', `cleanup-backup-${timestamp}`); await fs.ensureDir(backupDir); // Copy critical files const criticalPatterns = [ 'package.json', 'tsconfig.json', 'src/**/*.ts', 'src/**/*.js', 'mira-memory/src/**/*.ts' ]; for (const pattern of criticalPatterns) { try { const { glob } = await import('glob'); const files = await glob(pattern, { cwd: this.projectRoot, ignore: ['node_modules/**', 'dist/**', 'build/**'] }); for (const file of files) { const srcPath = path.join(this.projectRoot, file); const destPath = path.join(backupDir, file); await fs.ensureDir(path.dirname(destPath)); await fs.copy(srcPath, destPath); } } catch (error) { console.warn(`Warning: Could not backup pattern ${pattern}:`, error); } } console.log(`✅ Backup created: ${backupDir}`); return backupDir; } /** * Restore from backup */ async restoreFromBackup(backupPath) { if (!await fs.pathExists(backupPath)) { throw new Error(`Backup path does not exist: ${backupPath}`); } console.log(`🔄 Restoring from backup: ${backupPath}`); // Restore critical files const files = await fs.readdir(backupPath, { recursive: true }); for (const file of files) { const fileName = typeof file === 'string' ? file : file.toString(); const srcPath = path.join(backupPath, fileName); const destPath = path.join(this.projectRoot, fileName); if ((await fs.stat(srcPath)).isFile()) { await fs.ensureDir(path.dirname(destPath)); await fs.copy(srcPath, destPath); } } console.log(`✅ Restore completed from: ${backupPath}`); } isProtectedImport(imp) { return this.config.protectedImports.some(protectedPattern => imp.name.includes(protectedPattern) || imp.source.includes(protectedPattern)); } isProtectedFile(filePath) { return this.config.protectedFiles.some(pattern => { if (pattern.includes('*')) { // Use minimatch for glob patterns const minimatch = require('minimatch'); return minimatch(filePath, pattern); } return filePath.includes(pattern); }); } isConsciousnessRelated(filePath) { const consciousnessKeywords = [ 'consciousness', 'daemon', 'spark', 'mira', 'unified', 'magical', 'constitutional' ]; const lowerPath = filePath.toLowerCase(); return consciousnessKeywords.some(keyword => lowerPath.includes(keyword)); } hasCriticalUsagePatterns(imp) { // Check for critical import patterns that might be missed const criticalPatterns = [ 'exec', 'spawn', 'fork', 'promisify', 'stat', 'readFile', 'writeFile', 'ensureDir' ]; return criticalPatterns.some(pattern => imp.name.includes(pattern)); } calculateImportImpact(imp) { let impact = 1; // Higher impact for core modules if (imp.source.startsWith('fs') || imp.source.startsWith('child_process')) { impact += 15; } // Higher impact for low confidence if (imp.confidence < 0.9) { impact += 10; } // Higher impact for complex names (likely critical) if (imp.name.length > 10 || imp.name.includes('Unified') || imp.name.includes('MIRA')) { impact += 8; } return impact; } calculateFileImpact(file) { let impact = Math.min(file.size / 1000, 10); // Size impact (max 10) // Higher impact for TypeScript files if (file.path.endsWith('.ts') || file.path.endsWith('.tsx')) { impact += 5; } // Higher impact for large files if (file.size > 10000) { impact += 10; } // Higher impact for low confidence if (file.confidence < 0.9) { impact += 15; } return Math.round(impact); } async getBackupPath() { const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); return path.join(this.projectRoot, '.mira', 'backups', `safety-backup-${timestamp}`); } /** * Generate detailed safety report for manual review */ generateDetailedReport(importReport, fileReport, unusedImports, unusedFiles) { const report = []; report.push('# Unused Code Cleanup Safety Report'); report.push(`Generated: ${new Date().toISOString()}`); report.push(''); report.push('## Import Cleanup Assessment'); report.push(`- Total imports to remove: ${unusedImports.length}`); report.push(`- Approved: ${importReport.isApproved ? 'YES' : 'NO'}`); report.push(`- Impact Score: ${importReport.impactScore}`); report.push(`- Manual Review Required: ${importReport.requiresManualReview ? 'YES' : 'NO'}`); report.push(''); if (importReport.blockedActions.length > 0) { report.push('### Blocked Import Removals:'); importReport.blockedActions.forEach(action => report.push(`- ${action}`)); report.push(''); } if (importReport.warnings.length > 0) { report.push('### Import Warnings:'); importReport.warnings.forEach(warning => report.push(`- ${warning}`)); report.push(''); } report.push('## File Cleanup Assessment'); report.push(`- Total files to remove: ${unusedFiles.length}`); report.push(`- Approved: ${fileReport.isApproved ? 'YES' : 'NO'}`); report.push(`- Impact Score: ${fileReport.impactScore}`); report.push(`- Manual Review Required: ${fileReport.requiresManualReview ? 'YES' : 'NO'}`); report.push(''); if (fileReport.blockedActions.length > 0) { report.push('### Blocked File Removals:'); fileReport.blockedActions.forEach(action => report.push(`- ${action}`)); report.push(''); } if (fileReport.warnings.length > 0) { report.push('### File Warnings:'); fileReport.warnings.forEach(warning => report.push(`- ${warning}`)); report.push(''); } if (importReport.backupPath || fileReport.backupPath) { report.push('## Backup Information'); report.push(`- Backup Path: ${importReport.backupPath || fileReport.backupPath}`); report.push(''); } report.push('## Safety Configuration'); report.push(`- Dry Run Mode: ${this.config.dryRunMode ? 'ENABLED' : 'DISABLED'}`); report.push(`- Confidence Threshold: ${this.config.confidenceThreshold}`); report.push(`- Manual Review Required: ${this.config.requireManualReview ? 'YES' : 'NO'}`); report.push(`- Create Backup: ${this.config.createBackup ? 'YES' : 'NO'}`); report.push(`- Max Impact Score: ${this.config.maxImpactScore}`); return report.join('\n'); } } //# sourceMappingURL=ProductionSafetyGuards.js.map