UNPKG

claude-flow-novice

Version:

Claude Flow Novice - Advanced orchestration platform for multi-agent AI workflows with CFN Loop architecture Includes Local RuVector Accelerator and all CFN skills for complete functionality.

490 lines (379 loc) 14.9 kB
# BUG: Orchestrator Uses Mock Test Data Instead of Real Agent Deliverables **Status:** CRITICAL - Gate checks use random data, enabling "consensus on vapor" **Component:** `.claude/skills/cfn-loop-orchestration/src/orchestrate.ts` **Confidence Score:** 0.90 **Date Identified:** 2025-11-20 --- ## Problem Statement The orchestrator generates **random test results** instead of executing real tests on agent deliverables. This undermines the entire test-driven validation system and allows "consensus on vapor" - the anti-pattern where agents agree on theoretical work without validating actual implementation. ### Current Behavior (WRONG) **Location:** `orchestrate.ts` lines 626-637 ```typescript // Simulate test result collection from agents // In production, this would collect from actual agent runs for (const context of loop3Contexts) { const testResult: TestResult = { pass: Math.floor(Math.random() * 100), // ❌ Random numbers fail: Math.floor(Math.random() * 20), // ❌ Not real tests skip: Math.floor(Math.random() * 5), // ❌ Mock data }; this.recordTestResult(context.agentId, testResult); this.markAgentComplete(context.agentId, 'loop3'); } ``` **Results:** - Reports like "162 pass, 21 fail" with no connection to agent work - Gate pass rates are random (sometimes 0.85, sometimes 0.92) - Product Owner decisions based on fabricated metrics - Test-driven validation (v3.0) completely bypassed ### Impact Analysis **Critical Issues:** 1. **Gate Checks Invalid:** - Loop 3 gate uses `aggregated.passRate` from random data - Threshold comparisons (0.70/0.95/0.98) meaningless - Agents may pass gate with broken code 2. **Consensus on Vapor Enabled:** - Loop 2 validators review nothing (no real deliverables validated) - Product Owner makes decisions without actual test results - System claims 95%+ accuracy but provides 0% validation 3. **Anti-Pattern Facilitation:** - Agents can "complete" work without creating files - Tests never run on actual code - Quality gates are theatrical, not functional **Affected Workflows:** - `/cfn-loop-cli` (production CLI mode) - `/cfn-loop-task` (debugging Task mode) - All CFN Loop iterations in MVP/Standard/Enterprise modes --- ## Root Cause Analysis ### Why This Happened The orchestrator was implemented as a **placeholder** with mock data for initial development. Comments like "In production, this would collect from actual agent runs" indicate the team knew this was temporary. However, the integration with the **Test Execution Skill** was never completed: - Skill exists: `.claude/skills/cfn-test-execution/` - Scripts available: `test-coordinator-pattern.sh` - Orchestrator never calls them ### Missing Integration **Test Execution Skill provides:** ```bash # Coordinator runs real tests ./.claude/skills/cfn-test-execution/test-coordinator-pattern.sh swarm-123 # Output format (JSON): { "tests": { "passed": 45, "failed": 2, "total": 47 }, "coverage": { "lines": 87.5, "branches": 82.3 } } ``` **Orchestrator should:** 1. Call test execution skill after Loop 3 agents complete 2. Wait for test completion (max 5 min timeout) 3. Parse `test-results.json` or Redis metadata 4. Use real pass/fail counts for gate checks --- ## Solution Design ### 1. Add `executeTests()` Method **Purpose:** Execute real tests on agent deliverables after Loop 3 completion **Implementation:** ```typescript /** * Execute tests on agent deliverables using Test Execution Skill * Returns aggregated test results from actual test runs */ private async executeTests( taskId: string, iteration: number ): Promise<AggregatedTestResults> { const swarmId = `${taskId}-iteration-${iteration}`; // Call test execution skill const testScript = './.claude/skills/cfn-test-execution/test-coordinator-pattern.sh'; const { stdout, exitCode } = await this.runCommand(`${testScript} ${swarmId}`); // Parse test-results.json const resultsFile = 'test-results.json'; if (!fs.existsSync(resultsFile)) { throw new Error('Test execution failed: no results file generated'); } const results = JSON.parse(fs.readFileSync(resultsFile, 'utf-8')); return { totalPass: results.tests.passed || 0, totalFail: results.tests.failed || 0, totalSkip: results.tests.skip || 0, passRate: results.tests.total > 0 ? results.tests.passed / results.tests.total : 0, agentCount: this.testResults.size, }; } ``` ### 2. Replace Mock Data Collection **Current (lines 626-637):** ```typescript // Simulate test result collection from agents for (const context of loop3Contexts) { const testResult: TestResult = { pass: Math.floor(Math.random() * 100), fail: Math.floor(Math.random() * 20), skip: Math.floor(Math.random() * 5), }; this.recordTestResult(context.agentId, testResult); this.markAgentComplete(context.agentId, 'loop3'); } ``` **Replacement:** ```typescript // Wait for Loop 3 agents to complete work await this.waitForAgentCompletion(loop3Contexts, timeoutSeconds); // Execute real tests on agent deliverables console.log('Executing tests on agent deliverables...'); const aggregated = await this.executeTests(this.config.taskId, this.state.iteration); console.log( `Loop 3 Results: ${aggregated.totalPass} pass, ${aggregated.totalFail} fail (${(aggregated.passRate * 100).toFixed(2)}%)` ); ``` ### 3. Add Agent Completion Waiting **Purpose:** Ensure agents finish work before running tests ```typescript /** * Wait for agents to complete their work * Polls agent completion status with timeout */ private async waitForAgentCompletion( contexts: AgentExecutionContext[], timeoutSeconds: number ): Promise<void> { const startTime = Date.now(); const timeoutMs = timeoutSeconds * 1000; while (Date.now() - startTime < timeoutMs) { const completed = contexts.every(ctx => this.state.completedAgents.has(ctx.agentId) ); if (completed) { console.log('All agents completed successfully'); return; } // Wait 5 seconds before next check await new Promise(resolve => setTimeout(resolve, 5000)); } // Timeout - mark incomplete agents as failed for (const context of contexts) { if (!this.state.completedAgents.has(context.agentId)) { this.recordTimeout(context.agentId, timeoutSeconds); } } throw new Error(`Agent completion timeout after ${timeoutSeconds}s`); } ``` ### 4. Parse Test Results from Skill Output **Test Execution Skill Output Format:** ```json { "event": "tests_complete", "swarmId": "task-123-iteration-1", "timestamp": "2025-11-20T10:30:00Z", "duration": 12, "exitCode": 0, "tests": { "passed": 45, "failed": 2, "total": 47 }, "coverage": { "lines": 87.5, "branches": 82.3 }, "resultsFile": "test-results.json" } ``` **Parser:** ```typescript /** * Parse test results from JSON file */ private parseTestResults(resultsFile: string): AggregatedTestResults { const raw = JSON.parse(fs.readFileSync(resultsFile, 'utf-8')); const totalPass = raw.tests?.passed || 0; const totalFail = raw.tests?.failed || 0; const totalSkip = raw.tests?.skip || 0; const total = raw.tests?.total || (totalPass + totalFail + totalSkip); return { totalPass, totalFail, totalSkip, passRate: total > 0 ? totalPass / total : 0, agentCount: this.testResults.size, }; } ``` --- ## Implementation Plan ### Phase 1: Add Test Execution Integration **Tasks:** 1. Add `executeTests()` method to orchestrator 2. Add `waitForAgentCompletion()` method 3. Add `parseTestResults()` helper 4. Add `runCommand()` utility for shell execution **Files Modified:** - `.claude/skills/cfn-loop-orchestration/src/orchestrate.ts` **Tests Required:** - Unit test: `executeTests()` calls test skill correctly - Unit test: `parseTestResults()` handles valid JSON - Unit test: `parseTestResults()` handles missing fields - Integration test: Full orchestration with real test execution ### Phase 2: Replace Mock Data **Tasks:** 1. Remove random test generation (lines 626-637) 2. Replace with `waitForAgentCompletion()` + `executeTests()` 3. Verify gate checks use real pass rates 4. Update error handling for test failures **Validation:** - Gate checks reject broken code (pass rate < threshold) - Gate checks pass working code (pass rate ≥ threshold) - Product Owner receives accurate test metrics ### Phase 3: Add Timeout Handling **Tasks:** 1. Handle test execution timeout (default 5 min) 2. Handle agent completion timeout 3. Cleanup test processes on timeout 4. Record timeout events for debugging **Edge Cases:** - Tests hang indefinitely → kill after 5 min - Agents never complete → mark as failed after timeout - Test results file missing → throw descriptive error ### Phase 4: Validation **Test Scenarios:** 1. **Happy Path:** - Loop 3 agents complete work - Tests run successfully (pass rate ≥ 0.95) - Gate passes, Loop 2 starts 2. **Gate Failure:** - Loop 3 agents complete work - Tests run but fail (pass rate < 0.95) - Gate fails, iterate with feedback 3. **Agent Timeout:** - Loop 3 agents take >timeout seconds - Agents marked as failed - Tests don't run (no deliverables) 4. **Test Execution Failure:** - Loop 3 agents complete work - Test execution script crashes - Orchestrator logs error, marks iteration failed --- ## Testing Strategy ### Unit Tests **Test:** `executeTests()` integration ```typescript describe('Orchestrator.executeTests()', () => { it('should call test execution skill with correct swarm ID', async () => { const orchestrator = new Orchestrator(config); const spy = jest.spyOn(orchestrator, 'runCommand'); await orchestrator.executeTests('task-123', 1); expect(spy).toHaveBeenCalledWith( expect.stringContaining('test-coordinator-pattern.sh task-123-iteration-1') ); }); it('should parse test results correctly', async () => { fs.writeFileSync('test-results.json', JSON.stringify({ tests: { passed: 45, failed: 2, total: 47 } })); const result = await orchestrator.executeTests('task-123', 1); expect(result.totalPass).toBe(45); expect(result.totalFail).toBe(2); expect(result.passRate).toBeCloseTo(0.957, 3); }); it('should throw error if results file missing', async () => { await expect(orchestrator.executeTests('task-123', 1)) .rejects.toThrow('Test execution failed: no results file generated'); }); }); ``` ### Integration Tests **Test:** End-to-end orchestration with real tests ```typescript describe('Orchestrator E2E', () => { it('should execute real tests after Loop 3 completion', async () => { const orchestrator = new Orchestrator({ taskId: 'test-e2e-123', mode: 'standard', maxIterations: 1, }); // Spawn agents and execute const decision = await orchestrator.execute(); // Verify real tests were run const aggregated = orchestrator.aggregateTestResults(); expect(aggregated.totalPass).toBeGreaterThan(0); expect(aggregated.passRate).toBeGreaterThanOrEqual(0.95); // Verify gate passed with real metrics expect(decision).toBe('PROCEED'); }); }); ``` ### Manual Validation **Scenario:** Run orchestrator and verify test execution ```bash # 1. Start orchestrator in standard mode node .claude/skills/cfn-loop-orchestration/src/orchestrate.ts \ --task-id manual-test-123 \ --mode standard \ --max-iterations 1 # 2. Verify test execution # - Check test-results.json exists # - Verify pass/fail counts are non-random # - Confirm gate check uses real pass rate # 3. Verify logs show: # [COORDINATOR] Starting test execution for swarm: manual-test-123-iteration-1 # [COORDINATOR] Test execution complete in 12s (exit code: 0) # [COORDINATOR] Results: 45/47 passed, 2 failed ``` --- ## Success Criteria **Definition of Done:** 1. ✅ Orchestrator calls `.claude/skills/cfn-test-execution/test-coordinator-pattern.sh` after Loop 3 2. ✅ Real tests execute on agent deliverables (not random data) 3. ✅ Test results parsed from `test-results.json` or Redis 4. ✅ Gate checks use actual pass rates (verified with logs) 5. ✅ Unit tests cover test execution, parsing, and error handling 6. ✅ Integration test validates end-to-end workflow 7. ✅ Manual validation confirms non-random test results **Quality Metrics:** - Gate accuracy: ≥95% (gates pass good code, fail broken code) - Test execution timeout: <5 min per iteration - Error handling: All failure modes logged with context - Code coverage: ≥80% for new methods **Confidence Score:** 0.90 --- ## Related Documentation - **Test Execution Skill:** `.claude/skills/cfn-test-execution/SKILL.md` - **Orchestrator Quick Start:** `.claude/skills/cfn-loop-orchestration/ORCHESTRATOR_QUICK_START.md` - **Test-Driven Validation Guide:** `docs/guides/TEST_DRIVEN_CFN_LOOP_GUIDE.md` - **Anti-Pattern Prevention:** `docs/CFN_LOOP_ARCHITECTURE.md` (section on "consensus on vapor") --- ## Additional Notes ### Why This Is Critical The test-driven validation system (v3.0) was designed to replace subjective confidence scoring (55% accuracy) with objective test execution (95%+ accuracy). Without real test execution, the entire system regresses to v1.x behavior. **Risk Timeline:** - **Now:** Mock data enables "consensus on vapor" - **Short term:** Agents ship broken code that passes gates - **Long term:** Users lose trust in CFN Loop quality validation ### Migration from v1.x Confidence Scoring The confidence aggregator (`.claude/skills/cfn-loop-orchestration/src/helpers/confidence-aggregator.ts`) should be **deprecated** in favor of test-driven validation. Confidence scores were subjective agent assessments, not objective metrics. **v1.x (Deprecated):** - Agents report confidence: 0.85, 0.92, 0.88 - Average: 0.883 - No validation of actual work **v3.0 (Test-Driven):** - Tests run on deliverables: 45 pass, 2 fail - Pass rate: 0.957 (95.7%) - Objective validation of working code ### Backward Compatibility If confidence scoring must be preserved for legacy workflows: 1. Keep confidence collection separate 2. Log confidence scores for audit trail 3. **Never use confidence for gate decisions** 4. Always use test pass rates as primary metric --- **End of Bug Report**