| #!/usr/bin/env node |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import fs from "fs"; |
| import path from "path"; |
|
|
| console.log(` |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| β β |
| β COMPREHENSIVE AUDIT - OpenSkyNet Project β |
| β β |
| β ValidaciΓ³n sin supuestos: β |
| β β Cada problema debe ser verificable β |
| β β Cada soluciΓ³n debe ser testeable β |
| β β El impacto debe ser medible β |
| β β |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| `); |
|
|
| const PROJECT_ROOT = "."; |
|
|
| |
| |
| |
|
|
| console.log("\n[AUDIT] CATEGORY 1: ARQUITECTURA - God Objects\n"); |
|
|
| const likelyGodObjects = [ |
| "ui/src/ui/app.ts", |
| "ui/src/ui/app-settings.ts", |
| "src/omega/heartbeat.ts", |
| ]; |
|
|
| const godObjectProblems = []; |
|
|
| for (const filePath of likelyGodObjects) { |
| const fullPath = path.join(PROJECT_ROOT, filePath); |
| |
| if (!fs.existsSync(fullPath)) continue; |
| |
| try { |
| const content = fs.readFileSync(fullPath, "utf8"); |
| const lines = content.split("\n").length; |
| const importLines = (content.match(/^import /gm) || []).length; |
| const exportCount = (content.match(/^export /gm) || []).length; |
| const classCount = (content.match(/class\s+\w+/g) || []).length; |
| const functionCount = (content.match(/function\s+\w+|const\s+\w+\s*=\s*\(/gm) || []).length; |
|
|
| |
| |
| |
| |
| |
|
|
| const isGodObject = lines > 500 && importLines > 15; |
| const imports = content.match(/^import .* from/gm) || []; |
| const importCategories = new Set(imports.map(i => { |
| const match = i.match(/from ['"]([^'"]+)/); |
| return match ? match[1].split("/")[0] : "unknown"; |
| })); |
|
|
| console.log(`π¦ ${filePath}`); |
| console.log(` Lines: ${lines} | Imports: ${importLines} | Exports: ${exportCount}`); |
| console.log(` Classes: ${classCount} | Functions: ${functionCount}`); |
| console.log(` Import categories: ${importCategories.size}`); |
| |
| if (isGodObject) { |
| console.log(` β οΈ PROBLEM: God Object Pattern Detected`); |
| godObjectProblems.push({ |
| file: filePath, |
| lines, |
| imports: importLines, |
| categories: importCategories.size, |
| reason: "Too many responsibilities in single file", |
| }); |
| } else { |
| console.log(` β
OK`); |
| } |
| console.log(); |
| } catch (e) { |
| console.log(` β Error reading: ${e.message}\n`); |
| } |
| } |
|
|
| |
| |
| |
|
|
| console.log("\n[AUDIT] CATEGORY 2: ENGINES NUEVOS - QA\n"); |
|
|
| const newEngines = [ |
| "src/omega/continuous-thinking-engine.ts", |
| "src/omega/entropy-minimization-loop.ts", |
| "src/omega/active-learning-strategy.ts", |
| ]; |
|
|
| const engineIssues = []; |
|
|
| for (const filePath of newEngines) { |
| const fullPath = path.join(PROJECT_ROOT, filePath); |
| |
| if (!fs.existsSync(fullPath)) { |
| console.log(`β ${filePath} - NOT FOUND!`); |
| engineIssues.push({ file: filePath, issue: "File not found", severity: "CRITICAL" }); |
| continue; |
| } |
|
|
| try { |
| const content = fs.readFileSync(fullPath, "utf8"); |
| const lines = content.split("\n").length; |
|
|
| |
| const todos = (content.match(/\/\/\s*TODO|\/\/\s*FIXME|\/\/\s*XXX|\/\/\s*HACK/gi) || []).length; |
| |
| |
| const consoleLogs = (content.match(/console\.\w+\(/g) || []).length; |
| |
| |
| const tryCatchCount = (content.match(/try\s*{/g) || []).length; |
| const catchCount = (content.match(/catch\s*\(/g) || []).length; |
| const uncaughtTryCatch = tryCatchCount - catchCount; |
| |
| |
| const anyTypes = (content.match(/:\s*any\b|:\s*any[\s,;}]/g) || []).length; |
| |
| |
| const functions = content.match(/(?:function|const\s+\w+\s*=\s*\()/g) || []; |
| const docComments = (content.match(/\/\*\*[\s\S]*?\*\//g) || []).length; |
| const undocumentedRatio = (functions.length - docComments) / Math.max(functions.length, 1); |
|
|
| console.log(`π¦ ${filePath}`); |
| console.log(` Lines: ${lines}`); |
| |
| if (todos > 0) { |
| console.log(` β οΈ ${todos} unresolved TODOs/FIXMEs`); |
| engineIssues.push({ file: filePath, issue: `${todos} TODOs`, severity: "HIGH" }); |
| } else { |
| console.log(` β
No TODOs`); |
| } |
| |
| if (consoleLogs > 3) { |
| console.log(` β οΈ ${consoleLogs} console.log calls (debug noise?)`); |
| engineIssues.push({ file: filePath, issue: `${consoleLogs} console logs`, severity: "LOW" }); |
| } else if (consoleLogs === 0) { |
| console.log(` β
Clean console output`); |
| } |
| |
| if (anyTypes > 0) { |
| console.log(` β οΈ ${anyTypes} 'any' types (type safety risk)`); |
| engineIssues.push({ file: filePath, issue: `${anyTypes} 'any' types`, severity: "MEDIUM" }); |
| } else { |
| console.log(` β
Fully typed`); |
| } |
| |
| if (undocumentedRatio > 0.5) { |
| console.log(` β οΈ ${(undocumentedRatio * 100).toFixed(0)}% functions undocumented`); |
| engineIssues.push({ file: filePath, issue: "Undocumented functions", severity: "MEDIUM" }); |
| } else { |
| console.log(` β
Functions documented`); |
| } |
| |
| console.log(); |
| } catch (e) { |
| console.log(` β Error: ${e.message}\n`); |
| engineIssues.push({ file: filePath, issue: e.message, severity: "CRITICAL" }); |
| } |
| } |
|
|
| |
| |
| |
|
|
| console.log("\n[AUDIT] CATEGORY 3: REDUNDANCIA - DETECCIΓN\n"); |
|
|
| const redundancyIssues = []; |
|
|
| |
| console.log("Analizando patrones de duplicaciΓ³n...\n"); |
|
|
| |
| const heartbeatPath = path.join(PROJECT_ROOT, "src/omega/heartbeat.ts"); |
| if (fs.existsSync(heartbeatPath)) { |
| const heartbeatContent = fs.readFileSync(heartbeatPath, "utf8"); |
| const loaders = (heartbeatContent.match(/load\w+\s*=/g) || []).length; |
| const imports = (heartbeatContent.match(/import.*load/g) || []).length; |
| |
| console.log(`heartbeat.ts:`); |
| console.log(` - ${loaders} loader assignments`); |
| console.log(` - ${imports} loader imports`); |
| |
| if (loaders > 10) { |
| console.log(` β οΈ ISSUE: Many sequential loaders (could be parallelizable)`); |
| redundancyIssues.push({ |
| file: "heartbeat.ts", |
| issue: "Sequential loaders could be parallelized", |
| severity: "MEDIUM", |
| }); |
| } |
| } |
|
|
| |
| |
| |
|
|
| console.log("\n[AUDIT] CATEGORY 4: LΓGICAS CONTRADICTORIAS\n"); |
|
|
| const logicIssues = []; |
|
|
| |
| const checkFiles = [ |
| "src/omega/continuous-thinking-engine.ts", |
| "src/omega/entropy-minimization-loop.ts", |
| "src/omega/heartbeat.ts", |
| ]; |
|
|
| for (const filePath of checkFiles) { |
| const fullPath = path.join(PROJECT_ROOT, filePath); |
| if (!fs.existsSync(fullPath)) continue; |
| |
| const content = fs.readFileSync(fullPath, "utf8"); |
| |
| |
| if (/if\s*\(\s*(\w+)\s*\)\s*{[\s\S]*?}\s*else\s+if\s*\(\s*!\1\s*\)/g.test(content)) { |
| console.log(`β οΈ ${path.basename(filePath)}: Tautological condition found`); |
| logicIssues.push({ |
| file: filePath, |
| issue: "Tautological if/else-if condition", |
| severity: "HIGH", |
| }); |
| } |
| |
| |
| const assignments = content.match(/const\s+(\w+)\s*=\s*true;[\s\S]{0,200}if\s*\(\s*!?\1\s*===\s*false/g); |
| if (assignments && assignments.length > 0) { |
| console.log(`β οΈ ${path.basename(filePath)}: Contradictory logic detected`); |
| logicIssues.push({ |
| file: filePath, |
| issue: "Contradictory variable logic", |
| severity: "HIGH", |
| }); |
| } |
| } |
|
|
| if (logicIssues.length === 0) { |
| console.log("β
No obvious logical contradictions detected\n"); |
| } |
|
|
| |
| |
| |
|
|
| console.log("\n" + "β".repeat(77)); |
| console.log("\nAUDIT SUMMARY REPORT\n"); |
|
|
| const allProblems = [ |
| ...godObjectProblems, |
| ...engineIssues, |
| ...redundancyIssues, |
| ...logicIssues, |
| ]; |
|
|
| |
| const bySeverity = { |
| CRITICAL: allProblems.filter(p => p.severity === "CRITICAL"), |
| HIGH: allProblems.filter(p => p.severity === "HIGH"), |
| MEDIUM: allProblems.filter(p => p.severity === "MEDIUM"), |
| LOW: allProblems.filter(p => p.severity === "LOW"), |
| }; |
|
|
| console.log(`Issues by Severity:`); |
| console.log(` π΄ CRITICAL: ${bySeverity.CRITICAL.length}`); |
| console.log(` π HIGH: ${bySeverity.HIGH.length}`); |
| console.log(` π‘ MEDIUM: ${bySeverity.MEDIUM.length}`); |
| console.log(` π΅ LOW: ${bySeverity.LOW.length}`); |
| console.log(` Total: ${allProblems.length}\n`); |
|
|
| if (bySeverity.CRITICAL.length > 0) { |
| console.log(`Critical Issues:`); |
| for (const issue of bySeverity.CRITICAL) { |
| console.log(` - ${path.basename(issue.file || "")}: ${issue.issue || issue.reason}`); |
| } |
| } |
|
|
| if (bySeverity.HIGH.length > 0) { |
| console.log(`\nHigh Priority Issues:`); |
| for (const issue of bySeverity.HIGH) { |
| console.log(` - ${path.basename(issue.file || "")}: ${issue.issue || issue.reason}`); |
| } |
| } |
|
|
| console.log("\n" + "β".repeat(77)); |
|
|
| |
| |
| |
|
|
| console.log("\nNEXT STEPS (PHASE 4):\n"); |
|
|
| if (godObjectProblems.length > 0) { |
| console.log("1. REFACTOR God Objects:"); |
| for (const p of godObjectProblems) { |
| console.log(` - ${path.basename(p.file)}: Split into ${Math.ceil(p.lines / 300)} modules`); |
| } |
| } |
|
|
| if (engineIssues.length > 0) { |
| console.log("\n2. FIX Engine Issues:"); |
| for (const issue of engineIssues.slice(0, 5)) { |
| console.log(` - ${path.basename(issue.file)}: ${issue.issue}`); |
| } |
| } |
|
|
| if (redundancyIssues.length > 0) { |
| console.log("\n3. OPTIMIZE Redundancy:"); |
| for (const issue of redundancyIssues) { |
| console.log(` - ${path.basename(issue.file)}: ${issue.issue}`); |
| } |
| } |
|
|
| if (logicIssues.length > 0) { |
| console.log("\n4. FIX Logic Issues:"); |
| for (const issue of logicIssues) { |
| console.log(` - ${path.basename(issue.file)}: ${issue.issue}`); |
| } |
| } |
|
|
| console.log(`\nπ Audit completed: ${new Date().toISOString()}`); |
| console.log(`π Total validations: 4 categories`); |
| console.log(`π― Total issues found: ${allProblems.length} (Verified, not assumed)\n`); |
|
|
| process.exit(bySeverity.CRITICAL.length > 0 ? 1 : 0); |
|
|