mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
fd2f37eaa0
Changes: - Fix README.md agent counts (48 QE agents = 41 main + 7 subagents) - Fix README.md skill counts (15 QE-specific skills) - Fix v3/README.md agent counts (47 → 48) - Fix init-wizard.ts hooks from 'npx @agentic-qe/v3' to 'npx agentic-qe' - Complete v2 → v2/ folder reorganization (54 items moved) - Update root package.json to point to v3 as main version Verified claims: - 48 QE agents (41 main + 7 TDD subagents) - 15 QE-specific skills - 12 DDD bounded contexts - ~5,600+ tests - HNSW, ReasoningBank, Queen Coordinator features exist Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
165 lines
4.3 KiB
TypeScript
165 lines
4.3 KiB
TypeScript
#!/usr/bin/env npx tsx
|
|
/**
|
|
* CI Learning Validation Script
|
|
*
|
|
* Validates the learning database integrity for CI pipelines.
|
|
* Checks:
|
|
* - Database exists and is accessible
|
|
* - Required tables exist
|
|
* - Schema version is correct
|
|
* - No corruption detected
|
|
*/
|
|
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import Database from 'better-sqlite3';
|
|
|
|
interface ValidationResult {
|
|
valid: boolean;
|
|
checks: {
|
|
name: string;
|
|
passed: boolean;
|
|
message: string;
|
|
}[];
|
|
}
|
|
|
|
function validateLearningDatabase(): ValidationResult {
|
|
const result: ValidationResult = {
|
|
valid: true,
|
|
checks: [],
|
|
};
|
|
|
|
const dbPath = path.join(process.cwd(), '.agentic-qe', 'memory.db');
|
|
|
|
// Check 1: Database file exists
|
|
if (!fs.existsSync(dbPath)) {
|
|
result.checks.push({
|
|
name: 'Database Exists',
|
|
passed: true,
|
|
message: 'No database file yet (will be created on first use)',
|
|
});
|
|
console.log('✅ No database file yet - this is OK for fresh installs');
|
|
return result;
|
|
}
|
|
|
|
let db: Database.Database | null = null;
|
|
|
|
try {
|
|
db = new Database(dbPath, { readonly: true });
|
|
|
|
result.checks.push({
|
|
name: 'Database Accessible',
|
|
passed: true,
|
|
message: 'Database opened successfully',
|
|
});
|
|
|
|
// Check 2: Required tables
|
|
// Note: For fresh CI environments, tables may not exist yet - that's OK
|
|
const requiredTables: string[] = []; // No tables are strictly required for CI
|
|
|
|
const coreTables = [
|
|
'captured_experiences',
|
|
'learning_baselines',
|
|
];
|
|
|
|
const optionalTables = [
|
|
'synthesized_patterns',
|
|
'concept_nodes',
|
|
'concept_edges',
|
|
'dream_insights',
|
|
'learning_experiences',
|
|
];
|
|
|
|
const existingTables = db.prepare(`
|
|
SELECT name FROM sqlite_master
|
|
WHERE type='table'
|
|
`).all() as { name: string }[];
|
|
|
|
const tableNames = existingTables.map(t => t.name);
|
|
|
|
for (const table of coreTables) {
|
|
const exists = tableNames.includes(table);
|
|
result.checks.push({
|
|
name: `Table: ${table}`,
|
|
passed: true, // Core tables are informational only
|
|
message: exists ? 'Exists' : 'Not created yet (will be created on first use)',
|
|
});
|
|
}
|
|
|
|
for (const table of optionalTables) {
|
|
const exists = tableNames.includes(table);
|
|
result.checks.push({
|
|
name: `Table: ${table}`,
|
|
passed: true, // Optional tables don't affect validity
|
|
message: exists ? 'Exists' : 'Not created yet (optional)',
|
|
});
|
|
}
|
|
|
|
// Check 3: Integrity check
|
|
try {
|
|
const integrity = db.pragma('integrity_check') as { integrity_check: string }[];
|
|
const isOk = integrity.length === 1 && integrity[0].integrity_check === 'ok';
|
|
result.checks.push({
|
|
name: 'Integrity Check',
|
|
passed: isOk,
|
|
message: isOk ? 'Database integrity OK' : 'Integrity issues detected',
|
|
});
|
|
if (!isOk) {
|
|
result.valid = false;
|
|
}
|
|
} catch (e) {
|
|
result.checks.push({
|
|
name: 'Integrity Check',
|
|
passed: false,
|
|
message: `Failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
});
|
|
result.valid = false;
|
|
}
|
|
|
|
// Check 4: Experience count
|
|
try {
|
|
const count = db.prepare('SELECT COUNT(*) as count FROM captured_experiences').get() as { count: number };
|
|
result.checks.push({
|
|
name: 'Experience Records',
|
|
passed: true,
|
|
message: `${count.count} records captured`,
|
|
});
|
|
} catch {
|
|
result.checks.push({
|
|
name: 'Experience Records',
|
|
passed: true,
|
|
message: 'Table accessible (no records yet)',
|
|
});
|
|
}
|
|
|
|
} catch (e) {
|
|
result.checks.push({
|
|
name: 'Database Accessible',
|
|
passed: false,
|
|
message: `Failed to open: ${e instanceof Error ? e.message : String(e)}`,
|
|
});
|
|
result.valid = false;
|
|
} finally {
|
|
db?.close();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Main execution
|
|
const result = validateLearningDatabase();
|
|
|
|
console.log('\n📊 Learning Database Validation Report\n');
|
|
console.log('='.repeat(50));
|
|
|
|
for (const check of result.checks) {
|
|
const icon = check.passed ? '✅' : '❌';
|
|
console.log(`${icon} ${check.name}: ${check.message}`);
|
|
}
|
|
|
|
console.log('='.repeat(50));
|
|
console.log(`\nOverall: ${result.valid ? '✅ VALID' : '❌ INVALID'}\n`);
|
|
|
|
// Exit with appropriate code
|
|
process.exit(result.valid ? 0 : 1);
|