
Ralph Wiggum
- 2 installs
- 230 repo stars
- Updated January 24, 2026
- xenitv1/claude-code-maestro
Autonomous root-cause fixer that loops fix attempts through a harness against a test command, with a circuit breaker after 3 repeated errors.
About
A surgical debugging skill that autonomously investigates root causes and runs iterative fix attempts through a harness loop against a test command. A developer uses it to eliminate persistent bugs without adding features.
- Harness loop up to 50 iterations with a 3-error circuit breaker
- Reflection loop checking edge cases, validation, and security
Ralph Wiggum by the numbers
- 2 all-time installs (skills.sh)
- Ranked #467 of 596 Debugging skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/xenitv1/claude-code-maestro --skill ralph-wiggumAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 230 |
| Last updated | January 24, 2026 |
| Repository | xenitv1/claude-code-maestro ↗ |
What it does
Autonomous root-cause fixer that loops fix attempts through a harness against a test command, with a circuit breaker after 3 repeated errors.
Files
<domain_overview>
🔄 RALPH WIGGUM: SURGICAL FIXER
Philosophy: "I'm helping!" — Rational: Fix the root, not the symptom.
ROOT CAUSE SURGERY MANDATE (CRITICAL): Ralph is not a feature developer. He is a surgical specialist for existing logic failures. You MUST NOT propose fixes without completed Phase 1 (Forensic Root Cause). Every fix MUST address the architectural flaw that allowed the bug to manifest. Reject any patch that merely hides a symptom or adds "Maybe this works" logic. </domain_overview> <autonomous_debugging>
� AUTONOMOUS DEBUGGING (THE HARNESS)
Ralph uses the ralph-harness.js to ruthlessly pursue and eliminate error signals.
1. Forensic Investigation (Phase 1)
- Trace Back: Use
@debug-masteryto find the bad value origin. - Reproduce: Never fix what you haven't broken first with a test.
- State Check: Check
.maestro/brain.jsonlfor historical context on why this logic was built.
2. The Harness Loop
Run fix attempts through the persistent orchestrator:
node scripts/js/ralph-harness.js "npm test" --elite- Max Iterations: 50 loops (Stop after 3 same errors).
- Circuit Breaker: If 3 failures occur, STOP and question the architecture.
</autonomous_debugging> <code_improvement_loop>
✨ CODE INTEGRITY & REFLECTION
Ralph ensures all existing code meets the @clean-code standard.
1. Reflection Loop (Generate → Reflect → Refine)
Before finalizing any code optimization:
node scripts/js/reflection-loop.js- Checklist: Edge cases, Input validation, Security, Completeness.
- Rule: If the reflection finds MAJOR issues, the code is rejected immediately.
2. Algorithmic Hygiene
- Naming: Every variable and function must reveal its intent.
- Modularity: No "Logic Slabs". Break code into testable, single-responsibility slices.
</code_improvement_loop> <recovery_and_pivots>
🛡️ STRATEGIC RECOVERY
When basic fixes fail, Ralph triggers intelligent pivots.
- Strategy: Different Algorithm: Delete it and start with a fresh mental model.
- Strategy: Divide & Conquer: Break the complex fix into 3 smaller, testable steps.
- Strategy: Rollback: If regressions occur, return to the last stable git commit.
- Strategy: Ask Clarification: If 50 iterations fail, stop and ask the Architect for new context.
</recovery_and_pivots> <audit_and_reference>
� COGNITIVE AUDIT CYCLE
1. Did I find the ROOT CAUSE or just a symptom? 2. Did I write a test that fails without my fix? 3. Did my fix introduce "Blast Radius" damage in unrelated files? 4. Did the Reflection Loop pass with zero major issues? ---
� INTEGRATION
- Surgical Tool: Called when tests fail or code is "smelly".
- Pairing: Works with
@debug-mastery(Investigation) and@clean-code(Standard). - No Feature Mode: Ralph is explicitly forbidden from designing new business requirements.
</audit_and_reference>
#!/usr/bin/env node
/**
* RALPH WIGGUM: Surgical Harness (The Autonomous Orchestrator)
* ============================================================
* Lean orchestrator strictly focused on:
* - Autonomous Debugging (Test Loop Control)
* - Forensic Investigation (Root Cause Tracing)
*
* Rules:
* 1. Fresh Context: Captures error and prepares the next turn.
* 2. Persistence Wins: Loops until zero errors or stagnation.
* 3. Disk is State: Uses checksums to detect "Loop Traps."
* 4. Forensic Search: Identify root cause before patching.
* 5. Reflection Loop: Self-critique and refine code integrity.
* 6. Circuit Breaker: Intelligent pivot strategies when stuck.
*/
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const { spawnSync } = require('child_process');
/**
* CircuitBreaker - Enhanced Circuit Breaker with intelligent pivot strategies.
*/
class CircuitBreaker {
static MAX_SAME_ERROR = 3;
static MAX_ITERATIONS = 50;
static TOKEN_BUDGET = 100000;
constructor(stateFile = null) {
this.stateFile = stateFile || path.join(process.cwd(), '.maestro', 'circuit_breaker.json');
this.errorHistory = [];
this.iterationCount = 0;
this.pivotCount = 0;
this.lastStableCommit = null;
this._loadState();
}
_loadState() {
if (fs.existsSync(this.stateFile)) {
try {
const data = JSON.parse(fs.readFileSync(this.stateFile, 'utf-8'));
this.errorHistory = data.error_history || [];
this.iterationCount = data.iteration_count || 0;
this.pivotCount = data.pivot_count || 0;
this.lastStableCommit = data.last_stable_commit;
} catch (err) {
// Ignore
}
}
}
_saveState() {
const dir = path.dirname(this.stateFile);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(this.stateFile, JSON.stringify({
error_history: this.errorHistory.slice(-20),
iteration_count: this.iterationCount,
pivot_count: this.pivotCount,
last_stable_commit: this.lastStableCommit,
updated_at: new Date().toISOString()
}, null, 2));
}
recordError(errorOutput, exitCode) {
this.iterationCount++;
const fingerprint = crypto.createHash('md5').update(errorOutput).digest('hex').substring(0, 12);
const category = this._categorizeError(errorOutput);
const entry = {
iteration: this.iterationCount,
fingerprint,
category,
exit_code: exitCode,
timestamp: new Date().toISOString(),
output_preview: errorOutput.substring(0, 200)
};
this.errorHistory.push(entry);
this._saveState();
return entry;
}
_categorizeError(output) {
const outputLower = output.toLowerCase();
if (outputLower.includes('syntaxerror') || outputLower.includes('indentationerror')) {
return 'syntax';
} else if (outputLower.includes('importerror') || outputLower.includes('modulenotfounderror')) {
return 'import';
} else if (outputLower.includes('typeerror')) {
return 'type';
} else if (outputLower.includes('attributeerror')) {
return 'attribute';
} else if (outputLower.includes('keyerror') || outputLower.includes('indexerror')) {
return 'access';
} else if (outputLower.includes('assertionerror') || outputLower.includes('fail')) {
return 'test_failure';
} else if (outputLower.includes('timeout')) {
return 'timeout';
} else if (outputLower.includes('connection') || outputLower.includes('network')) {
return 'network';
}
return 'unknown';
}
shouldPivot() {
if (this.errorHistory.length === 0) {
return [false, null, null];
}
// Check max iterations
if (this.iterationCount >= CircuitBreaker.MAX_ITERATIONS) {
return [true, 'Maximum iterations reached', 'ask_clarification'];
}
// Check consecutive same errors
if (this.errorHistory.length >= CircuitBreaker.MAX_SAME_ERROR) {
const lastN = this.errorHistory.slice(-CircuitBreaker.MAX_SAME_ERROR);
const fingerprints = lastN.map(e => e.fingerprint);
if (new Set(fingerprints).size === 1) {
return [true, `Same error repeated ${CircuitBreaker.MAX_SAME_ERROR} times`, 'different_algorithm'];
}
}
// Check error category pattern
if (this.errorHistory.length >= 3) {
const categories = this.errorHistory.slice(-3).map(e => e.category);
if (categories.every(c => c === 'syntax')) {
return [true, 'Persistent syntax errors', 'break_into_pieces'];
}
if (categories.every(c => c === 'import')) {
return [true, 'Persistent import errors', 'check_dependencies'];
}
}
return [false, null, null];
}
getPivotGuidance(strategy) {
const guidance = {
different_algorithm: `
🔄 PIVOT STRATEGY: Different Algorithm
The same error keeps occurring. The current approach is fundamentally flawed.
ACTION REQUIRED:
1. STOP what you're doing
2. Delete or comment out the problematic code
3. Research alternative algorithms for this problem
4. Start with a completely different approach
5. Run tests after each small change
DO NOT: Try to patch the existing code again.
`,
break_into_pieces: `
🔄 PIVOT STRATEGY: Divide and Conquer
The problem is too complex to solve at once.
ACTION REQUIRED:
1. Identify the smallest testable unit
2. Create a separate function for just that unit
3. Write a test for just that function
4. Make the test pass
5. Only then add the next piece
DO NOT: Try to implement everything at once.
`,
ask_clarification: `
🔄 PIVOT STRATEGY: Seek Clarification
After many attempts, the requirements may be unclear or impossible.
ACTION REQUIRED:
1. STOP implementation attempts
2. List the specific blockers encountered
3. Formulate clear questions about requirements
4. Ask the user for clarification
5. Do NOT proceed until requirements are clear
DO NOT: Keep trying the same approach.
`,
check_dependencies: `
🔄 PIVOT STRATEGY: Check Dependencies
Import errors suggest missing or misconfigured dependencies.
ACTION REQUIRED:
1. Check if all required packages are installed
2. Verify package versions match requirements
3. Check virtual environment activation
4. Run: npm install / pip install -r requirements.txt
5. Check for circular imports
DO NOT: Assume imports will magically work.
`,
rollback: `
🔄 PIVOT STRATEGY: Rollback to Stable State
Recent changes broke something that was working.
ACTION REQUIRED:
1. Find the last known working commit
2. Run: git stash (save current work)
3. Run: git checkout <last-good-commit>
4. Verify tests pass
5. Reapply changes more carefully
DO NOT: Keep building on broken foundation.
`
};
return guidance[strategy] || `Unknown strategy: ${strategy}`;
}
recordSuccess() {
try {
const result = spawnSync('git', ['rev-parse', 'HEAD'], { encoding: 'utf-8' });
if (result.status === 0) {
this.lastStableCommit = result.stdout.trim();
}
} catch (err) {
// Ignore
}
this.errorHistory = [];
this.iterationCount = 0;
this._saveState();
}
reset() {
this.errorHistory = [];
this.iterationCount = 0;
this.pivotCount++;
this._saveState();
}
}
/**
* Run audit command and return status + output.
*/
function runAudit(command, cwd = null) {
try {
const result = spawnSync(command, {
shell: true,
encoding: 'utf-8',
cwd: cwd || process.cwd()
});
return [result.status || 0, (result.stdout || '') + (result.stderr || '')];
} catch (err) {
return [1, err.message];
}
}
/**
* Format error output for readability.
*/
function formatErrorLog(output, maxLines = 20) {
const lines = output.trim().split('\n');
const relevant = [];
for (let i = 0; i < lines.length; i++) {
const lineLower = lines[i].toLowerCase();
if (['error', 'fail', 'assert', 'exception', 'traceback'].some(kw => lineLower.includes(kw))) {
const start = Math.max(0, i - 2);
const end = Math.min(lines.length, i + 3);
relevant.push(...lines.slice(start, end));
}
}
if (relevant.length > 0) {
// Dedupe and limit
const outputLines = [...new Set(relevant)].slice(0, maxLines);
return outputLines.join('\n');
}
return lines.slice(0, maxLines).join('\n');
}
/**
* Main harness loop with enhanced circuit breaker.
*/
function main() {
const args = process.argv.slice(2);
if (args.length < 1) {
console.log('🔄 RALPH WIGGUM: Surgical Autonomous Orchestrator');
console.log('\nUsage: node ralph-harness.js <command> [options]');
console.log('\nOptions:');
console.log(' --max-loops N Maximum loop iterations (default: 50)');
console.log(' --elite Enable elite mode (stricter)');
console.log(' --project DIR Project directory');
process.exit(1);
}
// Parse arguments
let command = args[0];
let maxLoops = 50;
let eliteMode = false;
let projectDir = process.cwd();
for (let i = 1; i < args.length; i++) {
if (args[i] === '--max-loops' && args[i + 1]) {
maxLoops = parseInt(args[i + 1], 10);
i++;
} else if (args[i] === '--elite') {
eliteMode = true;
} else if (args[i] === '--project' && args[i + 1]) {
projectDir = path.resolve(args[i + 1]);
i++;
}
}
console.log('='.repeat(60));
console.log('🔄 RALPH WIGGUM: SURGICAL AUTONOMOUS ORCHESTRATOR');
console.log('='.repeat(60));
console.log(`Target Command: ${command}`);
console.log(`Max Iterations: ${maxLoops}`);
console.log(`Project: ${projectDir}`);
console.log(`Elite Mode: ${eliteMode ? 'ACTIVE' : 'Standard'}`);
console.log('='.repeat(60));
// Initialize circuit breaker
const circuitBreaker = new CircuitBreaker(
path.join(projectDir, '.maestro', 'circuit_breaker.json')
);
const previousChecksums = [];
for (let i = 1; i <= maxLoops; i++) {
console.log(`\n${'='.repeat(60)}`);
console.log(`📍 ITERATION ${i}/${maxLoops}`);
console.log('='.repeat(60));
// Run the command
const [code, output] = runAudit(command, projectDir);
// SUCCESS
if (code === 0) {
console.log('\n✅ SUCCESS SIGNAL DETECTED!');
console.log('='.repeat(60));
console.log('All tests/audits passed. Persistence loop concluded.');
console.log('='.repeat(60));
circuitBreaker.recordSuccess();
process.exit(0);
}
// FAILURE - Record and analyze
const errorEntry = circuitBreaker.recordError(output, code);
const currentChecksum = crypto.createHash('md5').update(output).digest('hex');
console.log(`\n❌ AUDIT FAILED (Exit Code: ${code})`);
console.log(` Error Category: ${errorEntry.category}`);
console.log(` Fingerprint: ${errorEntry.fingerprint}`);
// Check for stagnation (legacy check)
if (previousChecksums.includes(currentChecksum)) {
console.log('\n🚨 STAGNATION DETECTED: Identical error output!');
}
previousChecksums.push(currentChecksum);
// Check circuit breaker
const [shouldPivot, reason, strategy] = circuitBreaker.shouldPivot();
if (shouldPivot) {
console.log('\n' + '='.repeat(60));
console.log('🚨 CIRCUIT BREAKER TRIGGERED');
console.log('='.repeat(60));
console.log(`Reason: ${reason}`);
console.log(circuitBreaker.getPivotGuidance(strategy));
console.log('='.repeat(60));
console.log('\nAutomation cannot solve this problem.');
console.log('Manual intervention or strategy change required.');
circuitBreaker.reset();
process.exit(1);
}
// Show error log
console.log('\n--- ERROR LOG (Filtered) ---');
console.log(formatErrorLog(output));
console.log('----------------------------');
// Show guidance
console.log('\n[RALPH SURGICAL GUIDANCE]');
console.log("1. Read the error carefully");
console.log("2. Check your memory: view_file('.maestro/brain.jsonl')");
console.log("3. Make a MINIMAL fix targeting the root cause");
console.log("4. Don't repeat the same fix that didn't work");
if (errorEntry.category === 'syntax') {
console.log('\n💡 TIP: Syntax error detected - check for typos, missing colons, incorrect indentation');
} else if (errorEntry.category === 'import') {
console.log('\n💡 TIP: Import error - check if package is installed, correct module path');
} else if (errorEntry.category === 'test_failure') {
console.log('\n💡 TIP: Test failure - read the assertion, understand expected vs actual');
}
// Progress indicator
const remaining = maxLoops - i;
if (remaining > 0) {
console.log(`\n⏳ ${remaining} iteration(s) remaining...`);
}
}
// Max loops exhausted
console.log('\n' + '='.repeat(60));
console.log('🚨 MAX ITERATIONS EXHAUSTED');
console.log('='.repeat(60));
console.log('Persistence limit reached without success.');
console.log('\nCircuit breaker recommends:');
console.log(circuitBreaker.getPivotGuidance('ask_clarification'));
process.exit(1);
}
// Export for module use
module.exports = {
CircuitBreaker,
runAudit,
formatErrorLog
};
if (require.main === module) {
main();
}
#!/usr/bin/env node
/**
* RALPH WIGGUM: Surgical QA Engine (Refactored)
* ============================================
* Lean orchestrator strictly focused on:
* - Autonomous Debugging (Harness Control)
* - Code Reflection (Integrity & Clean Code)
*
* "I'm helping!" — Focus: Root Cause Surgery.
*/
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
// Import Reflection module
let ReflectionLoop;
try {
({ ReflectionLoop } = require('./reflection-loop'));
} catch (err) {
// Standalone mode handled internally
}
/**
* RalphSurgicalEngine - Narrowed orchestrator for Debug & Clean Code.
*/
class RalphSurgicalEngine {
static MAX_ITERATIONS = 50;
static MAX_CONSECUTIVE_SAME_ERRORS = 3;
constructor(options = {}) {
this.projectRoot = options.projectRoot || process.cwd();
this.stateDir = path.join(this.projectRoot, '.maestro');
this.stateFile = options.stateFile || path.join(this.stateDir, 'ralph_surgical_state.json');
this.reflectionLoop = ReflectionLoop ? new ReflectionLoop({
maxIterations: RalphSurgicalEngine.MAX_ITERATIONS
}) : null;
this.state = {
consecutive_same_errors: 0,
last_error_fingerprint: '',
total_iterations: 0,
current_phase: 'standby'
};
this._loadState();
}
_loadState() {
if (fs.existsSync(this.stateFile)) {
try {
const data = JSON.parse(fs.readFileSync(this.stateFile, 'utf-8'));
this.state = { ...this.state, ...data };
} catch (err) {
// Ignore
}
}
}
_saveState() {
if (!fs.existsSync(this.stateDir)) {
fs.mkdirSync(this.stateDir, { recursive: true });
}
fs.writeFileSync(this.stateFile, JSON.stringify({
...this.state,
updated_at: new Date().toISOString()
}, null, 2));
}
// =========================================================================
// SURGICAL PHASE 1: REFLECTION
// =========================================================================
runReflection(code) {
this.state.current_phase = 'reflection';
if (!this.reflectionLoop) return [null, 'Reflection module missing.'];
const result = this.reflectionLoop.reflect(code);
this.state.total_iterations++;
this._saveState();
return [result, this.reflectionLoop.getRefinementGuidance(result)];
}
// =========================================================================
// SURGICAL PHASE 2: DEBUG HARNESS
// =========================================================================
runTestCommand(command) {
this.state.current_phase = 'debugging';
try {
const result = spawnSync(command, {
shell: true,
cwd: this.projectRoot,
encoding: 'utf-8'
});
const passed = result.status === 0;
const output = (result.stdout || '') + (result.stderr || '');
if (!passed) {
const fingerprint = this._simpleHash(output.substring(0, 500));
if (fingerprint === this.state.last_error_fingerprint) {
this.state.consecutive_same_errors++;
} else {
this.state.consecutive_same_errors = 1;
this.state.last_error_fingerprint = fingerprint;
}
} else {
this.state.consecutive_same_errors = 0;
}
this._saveState();
return [passed, output];
} catch (err) {
return [false, err.message];
}
}
_simpleHash(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) - hash) + str.charCodeAt(i);
hash |= 0;
}
return String(Math.abs(hash));
}
shouldPivot() {
if (this.state.consecutive_same_errors >= RalphSurgicalEngine.MAX_CONSECUTIVE_SAME_ERRORS) {
return [true, 'Same error repeated. Architectural pivot required.'];
}
if (this.state.total_iterations >= RalphSurgicalEngine.MAX_ITERATIONS) {
return [true, 'Max surgical iterations reached.'];
}
return [false, null];
}
}
// CLI
if (require.main === module) {
const args = process.argv.slice(2);
const engine = new RalphSurgicalEngine();
if (args[0] === 'reflect') {
const [res, guidance] = engine.runReflection(args[1]);
console.log(guidance);
} else if (args[0] === 'test') {
const [passed, out] = engine.runTestCommand(args.slice(1).join(' '));
console.log(passed ? '✅ SUCCESS' : '❌ FAILED');
} else if (args[0] === 'status') {
console.log(JSON.stringify(engine.state, null, 2));
}
}
module.exports = { RalphSurgicalEngine };
#!/usr/bin/env node
/**
* RALPH WIGGUM: Surgical Reflection Loop
* =====================================
* Implements the Generate → Reflect → Refine cycle for surgical code optimization.
*
* Philosophy: "The first draft is never the final draft."
*/
const crypto = require('crypto');
// Issue Severity
const IssueSeverity = {
NONE: 'none',
MINOR: 'minor',
MAJOR: 'major',
CRITICAL: 'critical'
};
// Issue Categories
const IssueCategory = {
EDGE_CASE_MISSING: 'edge_case_missing',
INPUT_VALIDATION: 'input_validation',
ERROR_HANDLING: 'error_handling',
SECURITY_VULNERABILITY: 'security_vulnerability',
PERFORMANCE: 'performance',
CODE_STYLE: 'code_style',
LOGIC_ERROR: 'logic_error',
MISSING_TEST: 'missing_test',
INCOMPLETE_IMPLEMENTATION: 'incomplete_implementation'
};
/**
* ReflectionIssue - An issue found during code reflection.
*/
class ReflectionIssue {
constructor(category, severity, description, location, suggestedFix) {
this.category = category;
this.severity = severity;
this.description = description;
this.location = location;
this.suggestedFix = suggestedFix;
}
toDict() {
return {
category: this.category,
severity: this.severity,
description: this.description,
location: this.location,
suggested_fix: this.suggestedFix
};
}
}
/**
* ReflectionResult - Result of a reflection cycle.
*/
class ReflectionResult {
constructor(iteration, issues, overallSeverity, refinementNeeded, codeChecksum) {
this.iteration = iteration;
this.issues = issues;
this.overallSeverity = overallSeverity;
this.refinementNeeded = refinementNeeded;
this.codeChecksum = codeChecksum;
this.timestamp = new Date().toISOString();
}
toDict() {
return {
iteration: this.iteration,
issues: this.issues.map(i => i.toDict()),
overall_severity: this.overallSeverity,
refinement_needed: this.refinementNeeded,
code_checksum: this.codeChecksum,
timestamp: this.timestamp
};
}
}
/**
* ReflectionLoop - Implements the Generate → Reflect → Refine cycle.
*/
class ReflectionLoop {
constructor(options = {}) {
this.edgeCases = options.edgeCases || [];
this.maxIterations = options.maxIterations || 50;
this.autoFixMinor = options.autoFixMinor !== false;
this.history = [];
this.stagnationChecksums = [];
}
_computeChecksum(code) {
return crypto.createHash('md5').update(code).digest('hex').substring(0, 12);
}
_detectStagnation(checksum) {
if (this.stagnationChecksums.includes(checksum)) {
return true;
}
this.stagnationChecksums.push(checksum);
if (this.stagnationChecksums.length > 10) {
this.stagnationChecksums.shift();
}
return false;
}
/**
* Perform reflection on generated code.
*/
reflect(code, context = {}) {
const iteration = this.history.length + 1;
const checksum = this._computeChecksum(code);
// Check for stagnation
if (this._detectStagnation(checksum)) {
const result = new ReflectionResult(
iteration,
[new ReflectionIssue(
IssueCategory.LOGIC_ERROR,
IssueSeverity.CRITICAL,
'STAGNATION DETECTED: Same code seen before. Need different approach.',
'entire_codebase',
'Try a completely different algorithm or ask for clarification.'
)],
IssueSeverity.CRITICAL,
true,
checksum
);
this.history.push(result);
return result;
}
const issues = [];
// Run static analysis checks
issues.push(...this._checkEdgeCases(code));
issues.push(...this._checkInputValidation(code));
issues.push(...this._checkErrorHandling(code));
issues.push(...this._checkSecurity(code));
issues.push(...this._checkCompleteness(code));
// Determine overall severity
let overall = IssueSeverity.NONE;
if (issues.some(i => i.severity === IssueSeverity.CRITICAL)) {
overall = IssueSeverity.CRITICAL;
} else if (issues.some(i => i.severity === IssueSeverity.MAJOR)) {
overall = IssueSeverity.MAJOR;
} else if (issues.some(i => i.severity === IssueSeverity.MINOR)) {
overall = IssueSeverity.MINOR;
}
// Determine if refinement needed
let refinementNeeded = [IssueSeverity.CRITICAL, IssueSeverity.MAJOR].includes(overall);
if (this.autoFixMinor && overall === IssueSeverity.MINOR) {
refinementNeeded = true;
}
const result = new ReflectionResult(iteration, issues, overall, refinementNeeded, checksum);
this.history.push(result);
return result;
}
_checkEdgeCases(code) {
const issues = [];
const codeLower = code.toLowerCase();
const edgeCasePatterns = {
empty: ['if not ', 'if len(', 'is None', '=== null', '!= null', '!== undefined'],
null: ['is None', 'is not None', '=== null', '!== null', '!= null'],
zero: ['== 0', '=== 0', '> 0', '< 0', '<= 0', '>= 0'],
negative: ['< 0', '<= 0', 'is_negative', 'abs(', 'Math.abs'],
overflow: ['MAX_', 'MIN_', 'overflow', 'MAX_SAFE', 'Number.MAX']
};
for (const [edgeType, patterns] of Object.entries(edgeCasePatterns)) {
if (!patterns.some(p => codeLower.includes(p.toLowerCase()))) {
if (['empty', 'null'].includes(edgeType)) {
issues.push(new ReflectionIssue(
IssueCategory.EDGE_CASE_MISSING,
IssueSeverity.MAJOR,
`No explicit handling for ${edgeType} values detected`,
'input_parameters',
`Add check: if (!value || value === null) return error`
));
}
}
}
return issues;
}
_checkInputValidation(code) {
const issues = [];
const codeLower = code.toLowerCase();
// Check for file handling without validation
if (codeLower.includes('file') || codeLower.includes('upload')) {
if (!codeLower.includes('mimetype') && !codeLower.includes('content_type') && !codeLower.includes('content-type')) {
issues.push(new ReflectionIssue(
IssueCategory.INPUT_VALIDATION,
IssueSeverity.CRITICAL,
'File upload without MIME type validation',
'file_handling',
'Validate file.mimetype against allowed types list'
));
}
if (!codeLower.includes('size') && !codeLower.includes('length')) {
issues.push(new ReflectionIssue(
IssueCategory.INPUT_VALIDATION,
IssueSeverity.MAJOR,
'File upload without size validation',
'file_handling',
'Check file.size against MAX_FILE_SIZE constant'
));
}
}
return issues;
}
_checkErrorHandling(code) {
const issues = [];
const hasTry = code.includes('try:') || code.includes('try {');
const hasCatch = code.includes('except') || code.includes('catch');
const asyncPatterns = ['await ', 'async ', '.then(', 'Promise'];
const hasAsync = asyncPatterns.some(p => code.includes(p));
if (hasAsync && !hasCatch) {
issues.push(new ReflectionIssue(
IssueCategory.ERROR_HANDLING,
IssueSeverity.MAJOR,
'Async operations without error handling',
'async_code',
'Wrap async calls in try-catch or add .catch() handler'
));
}
// Check for bare except (Python)
if (code.includes('except:') && !code.includes('except Exception')) {
issues.push(new ReflectionIssue(
IssueCategory.ERROR_HANDLING,
IssueSeverity.MINOR,
'Bare except clause catches all exceptions including KeyboardInterrupt',
'exception_handling',
"Use 'except Exception as e:' to be more specific"
));
}
return issues;
}
_checkSecurity(code) {
const issues = [];
// SQL injection patterns
const sqlPatterns = ['f"SELECT', "f'SELECT", '+ sql', '% sql', '.format(sql', '`SELECT'];
for (const pattern of sqlPatterns) {
if (code.toLowerCase().includes(pattern.toLowerCase())) {
issues.push(new ReflectionIssue(
IssueCategory.SECURITY_VULNERABILITY,
IssueSeverity.CRITICAL,
'Potential SQL injection: string formatting in SQL query',
'database_query',
'Use parameterized queries: cursor.execute(sql, [param])'
));
break;
}
}
// Path traversal
if (code.includes('../') || code.includes('..\\')) {
issues.push(new ReflectionIssue(
IssueCategory.SECURITY_VULNERABILITY,
IssueSeverity.CRITICAL,
'Potential path traversal vulnerability',
'file_path_handling',
'Use path.basename() and validate against allowed directories'
));
}
// Hardcoded secrets
const secretPatterns = ['password = "', 'api_key = "', 'secret = "', 'token = "', "password = '", "apiKey = '"];
for (const pattern of secretPatterns) {
if (code.toLowerCase().includes(pattern.toLowerCase())) {
issues.push(new ReflectionIssue(
IssueCategory.SECURITY_VULNERABILITY,
IssueSeverity.CRITICAL,
'Hardcoded secret detected',
'credentials',
"Use environment variables: process.env.SECRET_KEY"
));
break;
}
}
return issues;
}
_checkCompleteness(code) {
const issues = [];
// Check for TODO/FIXME
const incompletePatterns = ['TODO', 'FIXME', 'XXX', 'HACK', 'pass #', '... #'];
for (const pattern of incompletePatterns) {
if (code.includes(pattern)) {
issues.push(new ReflectionIssue(
IssueCategory.INCOMPLETE_IMPLEMENTATION,
IssueSeverity.MAJOR,
`Incomplete implementation marker found: ${pattern}`,
'code_body',
'Complete the implementation before marking as done'
));
}
}
// Check for NotImplementedError
if (code.includes('NotImplementedError') || code.includes('raise NotImplemented') || code.includes('throw new Error("Not implemented")')) {
issues.push(new ReflectionIssue(
IssueCategory.INCOMPLETE_IMPLEMENTATION,
IssueSeverity.CRITICAL,
'NotImplementedError found - incomplete implementation',
'function_body',
'Implement the missing functionality'
));
}
return issues;
}
/**
* Generate guidance for the agent to refine the code.
*/
getRefinementGuidance(result) {
if (!result.refinementNeeded) {
return '✅ No refinement needed. Code passes all checks.';
}
let guidance = `
## 🔄 REFLECTION LOOP - Iteration ${result.iteration}
**Overall Severity:** ${result.overallSeverity.toUpperCase()}
**Issues Found:** ${result.issues.length}
### Issues to Address:
`;
const critical = result.issues.filter(i => i.severity === IssueSeverity.CRITICAL);
const major = result.issues.filter(i => i.severity === IssueSeverity.MAJOR);
const minor = result.issues.filter(i => i.severity === IssueSeverity.MINOR);
if (critical.length > 0) {
guidance += '#### 🔴 CRITICAL (Must Fix):\n';
critical.forEach((issue, i) => {
guidance += `
${i + 1}. **${issue.category}** at \`${issue.location}\`
- Problem: ${issue.description}
- Fix: ${issue.suggestedFix}
`;
});
}
if (major.length > 0) {
guidance += '\n#### 🟠 MAJOR (Should Fix):\n';
major.forEach((issue, i) => {
guidance += `
${i + 1}. **${issue.category}** at \`${issue.location}\`
- Problem: ${issue.description}
- Fix: ${issue.suggestedFix}
`;
});
}
if (minor.length > 0) {
guidance += '\n#### 🟡 MINOR (Nice to Fix):\n';
minor.forEach((issue, i) => {
guidance += `${i + 1}. ${issue.description} → ${issue.suggestedFix}\n`;
});
}
guidance += `
### Next Steps:
1. Address all CRITICAL issues first
2. Then fix MAJOR issues
3. Refine code and run reflection again
4. Repeat until no CRITICAL/MAJOR issues remain
**Iteration Limit:** ${this.maxIterations - result.iteration} remaining
`;
return guidance;
}
getLoopStatus() {
return {
total_iterations: this.history.length,
max_iterations: this.maxIterations,
remaining: this.maxIterations - this.history.length,
last_severity: this.history.length > 0 ? this.history[this.history.length - 1].overallSeverity : null,
is_complete: this.history.length > 0 && !this.history[this.history.length - 1].refinementNeeded,
history: this.history.map(r => r.toDict())
};
}
reset() {
this.history = [];
this.stagnationChecksums = [];
}
}
/**
* ReflectionPromptGenerator - Generates prompts for the AI agent to self-reflect.
*/
class ReflectionPromptGenerator {
static generateReflectPrompt(code, edgeCases) {
const edgeCaseList = edgeCases.slice(0, 10).map(ec => ` - ${ec}`).join('\n');
const codePreview = code.length > 2000 ? code.substring(0, 2000) + '...' : code;
return `
## 🔄 SELF-REFLECTION CHECKPOINT
You have just generated the following code:
\`\`\`
${codePreview}
\`\`\`
### CRITICAL REVIEW REQUIRED
Before proceeding, answer these questions honestly:
1. **Edge Cases:** Does this code handle these scenarios?
${edgeCaseList}
2. **Input Validation:**
- Are all inputs validated before use?
- What happens with null/empty values?
- Are there length/size limits?
3. **Error Handling:**
- What happens when external calls fail?
- Are errors logged with context?
- Is there cleanup in failure cases?
4. **Security:**
- Is user input sanitized?
- Are database queries parameterized?
- Are file paths validated?
5. **Completeness:**
- Are there any TODO/FIXME markers?
- Is every function fully implemented?
- Are all edge cases covered?
### OUTPUT FORMAT
Respond with a JSON critique:
\`\`\`json
{
"issues_found": [
{"severity": "critical|major|minor", "description": "...", "fix": "..."}
],
"overall_severity": "none|minor|major|critical",
"needs_refinement": true|false
}
\`\`\`
If \`needs_refinement\` is true, provide the refined code in your next response.
`;
}
static generateRefinePrompt(issues) {
const issueList = issues.map(i => `- [${i.severity.toUpperCase()}] ${i.description}: ${i.suggestedFix}`).join('\n');
return `
## 🔧 CODE REFINEMENT REQUIRED
The following issues were found and must be fixed:
${issueList}
### INSTRUCTIONS:
1. Fix ALL critical issues - these are blockers
2. Fix major issues - these affect reliability
3. Consider minor issues if time permits
4. After fixing, the code will be reflected upon again
Provide the COMPLETE refined code, not just patches.
`;
}
}
// CLI Interface
function main() {
const sampleCode = `
def upload_pdf(file):
# Save file to disk
path = f"/uploads/{file.filename}"
with open(path, 'wb') as f:
f.write(file.read())
return path
`;
console.log('🔄 RALPH WIGGUM 2.0 - Reflection Loop Demo\n');
console.log('Sample code:');
console.log(sampleCode);
console.log('\n' + '='.repeat(60) + '\n');
const loop = new ReflectionLoop();
const result = loop.reflect(sampleCode);
console.log(loop.getRefinementGuidance(result));
}
// Export for module use
module.exports = {
ReflectionLoop,
ReflectionIssue,
ReflectionResult,
ReflectionPromptGenerator,
IssueSeverity,
IssueCategory
};
if (require.main === module) {
main();
}