tractatus/scripts/migrate-to-schema-v3.js
TheFlow afcfc27502 feat: Complete Phase 2 Agent Lightning website integration
- Added Agent Lightning research section to researcher.html with Demo 2 results
- Created comprehensive /integrations/agent-lightning.html page
- Added Agent Lightning link in homepage hero section
- Updated Discord invite links (Tractatus + semantipy) across all pages
- Added feedback.js script to all key pages for live demonstration

Phase 2 of Master Plan complete: Discord setup → Website completion

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 14:38:20 +13:00

203 lines
7.7 KiB
JavaScript

/**
* 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);
}