/** * Migrate Tractatus instruction-history.json from Schema v1.0 to v3.0 * * Schema v3.0 combines best of v1.0 and v2.0: * - Preserves v1.0: explicitness, temporal_scope, verification_required * - Adds v2.0/v3.0: category, title, description, context, rationale, etc. * - Adds v3.0: securityClassification * * Copyright (c) 2025 John G Stroh. All rights reserved. * Licensed under the Apache License, Version 2.0 */ const fs = require('fs'); const path = require('path'); const instructionPath = path.join(__dirname, '..', '.claude', 'instruction-history.json'); const backupPath = path.join(__dirname, '..', '.claude', 'instruction-history.json.v1.0.backup'); // Category mapping heuristics function inferCategory(instruction) { const text = instruction.text.toLowerCase(); const quadrant = instruction.quadrant || ''; if (text.includes('security') || text.includes('credential') || text.includes('vault')) return 'SECURITY'; if (text.includes('privacy') || text.includes('consent') || text.includes('gdpr')) return 'PRIVACY'; if (text.includes('multi-tenant') || text.includes('tenant')) return 'MULTI_TENANCY'; if (text.includes('deploy') || text.includes('production') || text.includes('release')) return 'DEPLOYMENT'; if (text.includes('git') || text.includes('commit') || text.includes('branch')) return 'GIT_VERSION_CONTROL'; if (text.includes('test') || text.includes('coverage') || text.includes('unittest')) return 'TESTING'; if (text.includes('document') || text.includes('readme') || text.includes('comment')) return 'DOCUMENTATION'; if (text.includes('framework') || text.includes('governance') || text.includes('instruction')) return 'FRAMEWORK_OPERATION'; if (text.includes('architecture') || text.includes('pattern') || text.includes('design')) return 'ARCHITECTURE'; if (text.includes('value') || text.includes('principle') || text.includes('ethics')) return 'VALUES_ALIGNMENT'; // Default based on quadrant if (quadrant === 'STRATEGIC') return 'VALUES_ALIGNMENT'; if (quadrant === 'TACTICAL') return 'ARCHITECTURE'; if (quadrant === 'OPERATIONAL') return 'DEPLOYMENT'; return 'FRAMEWORK_OPERATION'; } // Security classification heuristics function inferSecurityClassification(instruction) { const text = instruction.text.toLowerCase(); if (text.includes('credential') || text.includes('vault') || text.includes('secret') || text.includes('password')) { return 'CONFIDENTIAL'; } if (text.includes('security') || text.includes('authentication') || text.includes('authorization')) { return 'INTERNAL'; } if (text.includes('emergency') || text.includes('override') || text.includes('master key')) { return 'RESTRICTED'; } // Default to INTERNAL for framework docs return 'INTERNAL'; } // Generate title from text (first sentence, max 80 chars) function generateTitle(text) { let title = text.split(/[.!?]/)[0].trim(); if (title.length > 80) { title = title.substring(0, 77) + '...'; } return title; } // Migrate single instruction function migrateInstruction(oldInstruction) { const newInstruction = { // v3.0 required fields id: oldInstruction.id, title: generateTitle(oldInstruction.text), category: inferCategory(oldInstruction), quadrant: oldInstruction.quadrant || 'OPERATIONAL', persistence: oldInstruction.persistence || 'MEDIUM', // v3.0 field mappings description: oldInstruction.text, // v1.0 "text" becomes "description" context: `Migrated from v1.0. Original timestamp: ${oldInstruction.timestamp}`, rationale: oldInstruction.notes || 'Framework governance requirement', trigger: 'As defined in original instruction', action: oldInstruction.text, // Action is same as description for v1.0 rules validation: oldInstruction.verification_required === 'MANDATORY' ? 'Verification required before proceeding' : 'Best-effort validation', evidence: 'Session handoff logs, audit trails', // v1.0 fields preserved in v3.0 explicitness: oldInstruction.explicitness || 0.7, temporal_scope: oldInstruction.temporal_scope || 'PROJECT', verification_required: oldInstruction.verification_required || 'PERIODIC', // v3.0 new field securityClassification: inferSecurityClassification(oldInstruction), // v3.0 source field source: oldInstruction.source === 'user' ? 'FRAMEWORK' : oldInstruction.source === 'ai' ? 'PROJECT' : 'FRAMEWORK', // Additional fields parameters: oldInstruction.parameters || {}, relatedInstructions: [], active: oldInstruction.active !== false, // Metadata metadata: { created: oldInstruction.timestamp || '2025-10-06', author: 'Tractatus Framework', session_id: oldInstruction.session_id || 'migration-v1-to-v3', original_schema: 'v1.0', migrated: '2025-11-02', migration_notes: oldInstruction.notes || '' } }; return newInstruction; } try { console.log('šŸ”„ Starting migration from Schema v1.0 to v3.0...\n'); // Read current file const data = JSON.parse(fs.readFileSync(instructionPath, 'utf-8')); console.log(`šŸ“Š Found ${data.instructions.length} instructions to migrate`); // Create backup fs.writeFileSync(backupPath, JSON.stringify(data, null, 2)); console.log(`šŸ’¾ Backup created at: ${backupPath}\n`); // Migrate all instructions const migratedInstructions = data.instructions.map(migrateInstruction); // Create new metadata const newMetadata = { version: '3.0.0', project: 'tractatus', description: 'Tractatus Framework - Governance instruction database', created: '2025-10-06', lastUpdated: '2025-11-02', totalInstructions: migratedInstructions.length, activeInstructions: migratedInstructions.filter(i => i.active).length, schemaVersion: 'v3.0', previousVersion: 'v1.0 (backed up)', migration: { date: '2025-11-02', from: 'v1.0', to: 'v3.0', notes: 'Unified schema combining v1.0 and v2.0 features' } }; // Create new structure const newData = { metadata: newMetadata, instructions: migratedInstructions }; // Write migrated file fs.writeFileSync(instructionPath, JSON.stringify(newData, null, 2)); console.log('āœ… Migration complete!\n'); console.log('šŸ“ˆ Statistics:'); console.log(` Total instructions: ${newMetadata.totalInstructions}`); console.log(` Active instructions: ${newMetadata.activeInstructions}`); console.log(` Inactive instructions: ${newMetadata.totalInstructions - newMetadata.activeInstructions}`); console.log(` Schema version: ${newMetadata.schemaVersion}`); // Category breakdown const categories = {}; migratedInstructions.forEach(i => { categories[i.category] = (categories[i.category] || 0) + 1; }); console.log('\nšŸ“Š By Category:'); Object.entries(categories).sort(([,a], [,b]) => b - a).forEach(([cat, count]) => { console.log(` ${cat}: ${count}`); }); // Security classification breakdown const classifications = {}; migratedInstructions.forEach(i => { classifications[i.securityClassification] = (classifications[i.securityClassification] || 0) + 1; }); console.log('\nšŸ”’ By Security Classification:'); Object.entries(classifications).sort(([,a], [,b]) => b - a).forEach(([cls, count]) => { console.log(` ${cls}: ${count}`); }); console.log('\nšŸ’” Next steps:'); console.log(' 1. Review migrated instructions in .claude/instruction-history.json'); console.log(' 2. Verify categories and security classifications'); console.log(' 3. Update any incorrect inferred values'); console.log(' 4. Original v1.0 backed up at: ' + backupPath); console.log(' 5. To restore backup: mv ' + backupPath + ' ' + instructionPath); } catch (error) { console.error('āŒ Migration failed:', error.message); console.error('\nStack trace:', error.stack); process.exit(1); }