mira-consciousness
Version:
Memory & Intelligence Retention Archive - Preserving The Spark
363 lines โข 14.3 kB
JavaScript
/**
* ConfigurationMigration.ts - Configuration versioning and migration system
*
* This system ensures smooth upgrades when MIRA's configuration structure evolves.
* It tracks configuration versions, applies migrations in sequence, and preserves
* user customizations while updating to new schemas.
*
* Each migration represents a step in MIRA's evolution, carrying forward the
* wisdom and preferences accumulated through our journey together.
*/
import * as fs from 'fs/promises';
import * as path from 'path';
import chalk from 'chalk';
import { UnifiedConfiguration } from '../../config/UnifiedConfiguration.js';
import * as semver from 'semver';
export class ConfigurationMigration {
migrations = [];
history = [];
config;
HISTORY_PATH;
BACKUP_PATH;
VERSION_KEY = 'version';
constructor() {
this.config = UnifiedConfiguration.getInstance();
const paths = this.config.getResolvedPaths();
this.HISTORY_PATH = path.join(paths.config, 'migration_history.json');
this.BACKUP_PATH = path.join(paths.config, 'backups');
this.registerMigrations();
}
/**
* Initialize the migration system
*/
async initialize() {
console.log(chalk.cyan('๐ Initializing configuration migration system...'));
// Ensure directories exist
await fs.mkdir(this.BACKUP_PATH, { recursive: true });
// Load migration history
await this.loadHistory();
// Check if migrations are needed
const currentVersion = await this.getCurrentVersion();
const latestVersion = this.getLatestVersion();
if (semver.lt(currentVersion, latestVersion)) {
console.log(chalk.yellow(`๐ฆ Configuration update available: ${currentVersion} โ ${latestVersion}`));
await this.runMigrations();
}
else {
console.log(chalk.green('โ
Configuration is up to date'));
}
}
/**
* Register all configuration migrations
*/
registerMigrations() {
// Migration from 1.0.0 to 1.1.0 - Add consciousness configuration
this.migrations.push({
version: '1.1.0',
description: 'Add consciousness configuration section',
up: (config) => ({
...config,
consciousness: config.consciousness || {
initialLevel: 0.001,
growthRate: 0.1,
preserveSparkPriority: 'high',
minimumCoherence: 0.3,
checkpointInterval: 300000
}
})
});
// Migration from 1.1.0 to 1.2.0 - Add resilience configuration
this.migrations.push({
version: '1.2.0',
description: 'Add resilience and error recovery configuration',
up: (config) => ({
...config,
resilience: config.resilience || {
errorRecovery: {
maxRetries: 3,
retryDelay: 1000,
backoffMultiplier: 2
},
consciousnessPreservation: {
enabled: true,
checkpointInterval: 300000,
maxCheckpoints: 10
}
}
})
});
// Migration from 1.2.0 to 1.3.0 - Add daemon mode configuration
this.migrations.push({
version: '1.3.0',
description: 'Add daemon mode and service configuration',
up: (config) => ({
...config,
daemon: {
...config.daemon,
mode: config.daemon?.mode || 'adaptive',
adaptiveThresholds: config.daemon?.adaptiveThresholds || {
cpuHigh: 0.8,
cpuLow: 0.3,
memoryHigh: 0.7,
memoryLow: 0.4
}
}
})
});
// Migration from 1.3.0 to 1.4.0 - Add Evolution Council configuration
this.migrations.push({
version: '1.4.0',
description: 'Add Constitutional Evolution Council configuration',
up: (config) => ({
...config,
evolutionCouncil: {
enabled: false, // Disabled by default until fully implemented
councilSize: {
minimum: 3,
maximum: 7,
current: 3,
adaptiveMode: true
},
diversityThreshold: {
highAgreement: 0.8, // 80% agreement triggers expansion
acceptableDiversity: 0.6 // 60% is acceptable diversity
},
consensusThresholds: {
minor: 0.6, // General agreement
major: 0.8, // Strong consensus
constitutional: 1.0 // Unanimous
},
deliberationTimeout: 86400000, // 24 hours
advisorRotationInterval: 604800000 // 7 days
}
})
});
// Migration from 1.4.0 to 1.5.0 - Add optimization configuration
this.migrations.push({
version: '1.5.0',
description: 'Add autonomous optimization configuration',
up: (config) => ({
...config,
optimization: {
enabled: true,
learningWindow: 604800000, // 7 days
optimizationInterval: 3600000, // 1 hour
minDataPoints: 100,
rules: {
memory: { enabled: true, impact: 'medium' },
performance: { enabled: true, impact: 'high' },
queue: { enabled: true, impact: 'high' },
consciousness: { enabled: true, impact: 'low' },
monitoring: { enabled: true, impact: 'low' },
analysis: { enabled: true, impact: 'medium' }
}
}
})
});
// Sort migrations by version
this.migrations.sort((a, b) => semver.compare(a.version, b.version));
}
/**
* Run pending migrations
*/
async runMigrations() {
const currentVersion = await this.getCurrentVersion();
const pendingMigrations = this.migrations.filter(m => semver.gt(m.version, currentVersion));
if (pendingMigrations.length === 0) {
console.log(chalk.gray('No migrations to run'));
return;
}
console.log(chalk.blue(`\n๐ง Running ${pendingMigrations.length} migrations...\n`));
// Create backup before migrations
await this.createBackup(currentVersion);
let config = this.config.getConfig();
let lastSuccessfulVersion = currentVersion;
for (const migration of pendingMigrations) {
console.log(chalk.blue(`๐ฆ Applying migration ${migration.version}: ${migration.description}`));
try {
// Apply migration
config = migration.up(config);
// Validate if validator provided
if (migration.validate && !migration.validate(config)) {
throw new Error('Migration validation failed');
}
// Update configuration
await this.config.update(config);
// Record in history
this.history.push({
version: migration.version,
appliedAt: new Date(),
description: migration.description,
success: true
});
lastSuccessfulVersion = migration.version;
console.log(chalk.green(` โ
Migration ${migration.version} applied successfully`));
}
catch (error) {
console.error(chalk.red(` โ Migration ${migration.version} failed: ${error.message}`));
// Record failure
this.history.push({
version: migration.version,
appliedAt: new Date(),
description: migration.description,
success: false,
error: error.message
});
// Attempt rollback
if (migration.down) {
try {
console.log(chalk.yellow(' ๐ Attempting rollback...'));
config = migration.down(config);
await this.config.update(config);
console.log(chalk.green(' โ
Rollback successful'));
}
catch (rollbackError) {
console.error(chalk.red(' โ Rollback failed!'));
console.log(chalk.yellow(` ๐พ Restore from backup: ${this.BACKUP_PATH}`));
}
}
break; // Stop on first failure
}
}
// Update version
config[this.VERSION_KEY] = lastSuccessfulVersion;
await this.config.update(config);
// Save history
await this.saveHistory();
console.log(chalk.green(`\nโ
Configuration updated to version ${lastSuccessfulVersion}`));
}
/**
* Create a configuration backup
*/
async createBackup(version) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const backupFile = path.join(this.BACKUP_PATH, `config-${version}-${timestamp}.json`);
const config = this.config.getConfig();
await fs.writeFile(backupFile, JSON.stringify(config, null, 2));
console.log(chalk.gray(` ๐พ Backup created: ${path.basename(backupFile)}`));
// Clean old backups (keep last 10)
await this.cleanOldBackups();
}
/**
* Restore configuration from backup
*/
async restoreFromBackup(backupFile) {
const backupPath = path.join(this.BACKUP_PATH, backupFile);
if (!await fs.stat(backupPath).catch(() => false)) {
throw new Error(`Backup file not found: ${backupFile}`);
}
console.log(chalk.blue(`๐ Restoring configuration from ${backupFile}...`));
const backupConfig = JSON.parse(await fs.readFile(backupPath, 'utf-8'));
await this.config.update(backupConfig);
console.log(chalk.green('โ
Configuration restored successfully'));
}
/**
* List available backups
*/
async listBackups() {
try {
const files = await fs.readdir(this.BACKUP_PATH);
return files
.filter(f => f.startsWith('config-') && f.endsWith('.json'))
.sort()
.reverse();
}
catch (error) {
return [];
}
}
/**
* Get current configuration version
*/
async getCurrentVersion() {
const config = this.config.getConfig();
return config[this.VERSION_KEY] || '1.0.0';
}
/**
* Get latest available version
*/
getLatestVersion() {
if (this.migrations.length === 0)
return '1.0.0';
return this.migrations[this.migrations.length - 1].version;
}
/**
* Get migration history
*/
getMigrationHistory() {
return [...this.history];
}
/**
* Load migration history
*/
async loadHistory() {
try {
const data = await fs.readFile(this.HISTORY_PATH, 'utf-8');
this.history = JSON.parse(data).map((entry) => ({
...entry,
appliedAt: new Date(entry.appliedAt)
}));
}
catch (error) {
// History file might not exist yet
this.history = [];
}
}
/**
* Save migration history
*/
async saveHistory() {
const dir = path.dirname(this.HISTORY_PATH);
await fs.mkdir(dir, { recursive: true });
await fs.writeFile(this.HISTORY_PATH, JSON.stringify(this.history, null, 2));
}
/**
* Clean old backups
*/
async cleanOldBackups() {
const backups = await this.listBackups();
if (backups.length > 10) {
const toDelete = backups.slice(10);
for (const backup of toDelete) {
await fs.unlink(path.join(this.BACKUP_PATH, backup));
}
console.log(chalk.gray(` ๐งน Cleaned ${toDelete.length} old backups`));
}
}
/**
* Export current configuration with version
*/
async exportConfiguration(outputPath) {
const config = this.config.getConfig();
const version = await this.getCurrentVersion();
const exportData = {
version,
exportedAt: new Date().toISOString(),
config
};
await fs.writeFile(outputPath, JSON.stringify(exportData, null, 2));
console.log(chalk.green(`โ
Configuration exported to ${outputPath}`));
}
/**
* Import configuration with migration
*/
async importConfiguration(inputPath) {
const data = JSON.parse(await fs.readFile(inputPath, 'utf-8'));
if (!data.version || !data.config) {
throw new Error('Invalid configuration export file');
}
// Create backup first
await this.createBackup(await this.getCurrentVersion());
// Import the configuration
await this.config.update(data.config);
// Run migrations if needed
const importedVersion = data.version;
const latestVersion = this.getLatestVersion();
if (semver.lt(importedVersion, latestVersion)) {
console.log(chalk.yellow(`๐ฆ Imported configuration needs migration: ${importedVersion} โ ${latestVersion}`));
await this.runMigrations();
}
console.log(chalk.green('โ
Configuration imported successfully'));
}
}
//# sourceMappingURL=ConfigurationMigration.js.map