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
Markdown
# 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**