feature-validation.ts
1 import { captureGuardianCheckpoint, prepareGuardianRecovery } from '../src/lib/server/agents/guardian' 2 import { applyMMR } from '../src/lib/server/mmr' 3 import { execSync } from 'child_process' 4 import fs from 'fs' 5 import path from 'path' 6 import os from 'os' 7 8 // Mock types for MMR test 9 interface MemoryEntry { 10 id: string 11 title: string 12 content: string 13 category: string 14 createdAt: number 15 updatedAt: number 16 [key: string]: unknown 17 } 18 19 async function runTests() { 20 console.log('🚀 Starting SwarmClaw Advanced Feature Validation...\n') 21 22 // --- 1. Test MMR Diversity --- 23 console.log('--- Testing MMR (Maximal Marginal Relevance) ---') 24 25 // Use distinct embeddings 26 const queryEmbedding = [1, 0, 0] 27 const now = Date.now() 28 const candidates = [ 29 { 30 entry: { id: '1', title: 'Python Loop', content: 'How to write a for loop in python', category: 'note', createdAt: now, updatedAt: now } as MemoryEntry, 31 salience: 0.9, 32 embedding: [1, 0.1, 0] // High relevance 33 }, 34 { 35 entry: { id: '2', title: 'Python For', content: 'Writing for loops in python language', category: 'note', createdAt: now, updatedAt: now } as MemoryEntry, 36 salience: 0.89, 37 embedding: [1, 0.11, 0] // High relevance, but almost identical to #1 38 }, 39 { 40 entry: { id: '3', title: 'React Hooks', content: 'Using useEffect and useState in React', category: 'note', createdAt: now, updatedAt: now } as MemoryEntry, 41 salience: 0.7, 42 embedding: [0, 1, 0] // Lower relevance, but very diverse 43 }, 44 ] 45 46 console.log('Running MMR with lambda=0.2 (High Diversity)...') 47 const diverseResults = applyMMR(queryEmbedding, candidates, 2, 0.2) 48 console.log('Selected IDs:', diverseResults.map(r => r.id)) 49 50 // With lambda=0.2, ID '3' should definitely be picked over '2' 51 if (diverseResults.some(r => r.id === '3')) { 52 console.log('✅ MMR Diversity Test Passed!') 53 } else { 54 console.log('❌ MMR Diversity Test Failed: Diversity still not prioritized.') 55 } 56 57 // --- 2. Test Guardian Recovery Prep --- 58 console.log('\n--- Testing Guardian Recovery Preparation ---') 59 const testRepoDir = path.join(os.tmpdir(), `swarmclaw-test-repo-${Date.now()}`) 60 fs.mkdirSync(testRepoDir) 61 62 try { 63 execSync('git init', { cwd: testRepoDir }) 64 execSync('git config user.email "test@example.com"', { cwd: testRepoDir }) 65 execSync('git config user.name "Test User"', { cwd: testRepoDir }) 66 fs.writeFileSync(path.join(testRepoDir, 'config.json'), '{"status": "ok"}') 67 execSync('git add . && git commit -m "Initial commit"', { cwd: testRepoDir }) 68 69 const checkpoint = captureGuardianCheckpoint(testRepoDir, 'feature-validation') 70 if (!checkpoint.ok) { 71 console.log('❌ Guardian Checkpoint Test Failed: unable to capture checkpoint.') 72 return 73 } 74 75 // Corrupt the file 76 fs.writeFileSync(path.join(testRepoDir, 'config.json'), '{"status": "CORRUPTED"}') 77 console.log('Simulating workspace corruption...') 78 79 const recovery = prepareGuardianRecovery({ 80 cwd: testRepoDir, 81 reason: 'Feature validation corruption test', 82 requester: 'feature-validation', 83 }) 84 85 if (recovery.ok && recovery.approval?.id && recovery.checkpoint?.approvalId === recovery.approval.id) { 86 console.log('✅ Guardian Recovery Prep Test Passed! (Checkpoint + approval created)') 87 } else { 88 console.log('❌ Guardian Recovery Prep Test Failed!') 89 } 90 } catch (err) { 91 console.error('Guardian test error:', err) 92 } finally { 93 try { fs.rmSync(testRepoDir, { recursive: true, force: true }) } catch {} 94 } 95 96 console.log('\n--- Validation Complete ---') 97 } 98 99 runTests().catch(console.error)