Files
proffesor-for-testing__agen…/docs/implementation/specs/SPEC-033-C-controller-integration.md
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
Remove the nested v3/ subdirectory by moving all active source code,
tests, configs, and assets directly to the project root. Archive v2/
(dead code, 847MB) to v2-archive.tar.gz.

Key changes:
- Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/
- Move v3/tsconfig.json, v3/vitest.config.ts to root
- Merge v3/package.json into root package.json (ESM, scripts, deps, exports)
- Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/
- Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes
- Fix all init installer path resolution (3-level-up → 2-level-up)
- Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe"
- Update settings.json ADR/DDD directories to docs/implementation/
- Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks)
- Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces
- Update 15 guidance shards: v3/src/ → src/ path references
- Fix sync interfaces: remove v3/ and v2/ path references
- Fix test path calculations (process.cwd() + '..' no longer needed)
- Fix flaky perf test threshold (500ms → 1000ms for CI environments)
- Fix complexity-analyzer test to match ADR-051 keyword-based eligibility

Build passes, 17,901 tests pass, CLI and MCP bundles verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:35:41 +00:00

6.3 KiB

SPEC-033-C: Controller Integration

Field Value
Specification ID SPEC-033-C
Parent ADR ADR-033
Version 1.0
Status Draft
Last Updated 2026-01-20
Author Architecture Team

Overview

This specification defines the EarlyExitController that orchestrates test pyramid execution with early exit support, integrating the algorithm and speculative execution components.


Test Pyramid Result Types

export interface TestPyramidResult {
  layers: LayerResult[];
  exitedEarly: boolean;
  exitLayer: number;
  exitReason: ExitReason;
  confidence: number;
  speculations: SpeculativeResult[];
  skippedLayers: number;
}

EarlyExitController Class

export class EarlyExitController {
  private earlyExit: CoherenceEarlyExit;
  private speculator: SpeculativeExecutor;
  private layerResults: Map<number, LayerResult> = new Map();

  constructor(config: EarlyExitConfig, totalLayers: number) {
    this.earlyExit = new CoherenceEarlyExit(config, totalLayers);
    this.speculator = new SpeculativeExecutor(config);
  }

  /** Run test pyramid with early exit support */
  async runWithEarlyExit(layers: TestLayer[]): Promise<TestPyramidResult> {
    const results: LayerResult[] = [];
    let exitDecision: EarlyExitDecision | null = null;

    for (let i = 0; i < layers.length; i++) {
      // Execute layer
      const layerResult = await this.executeLayer(layers[i], i);
      results.push(layerResult);
      this.layerResults.set(i, layerResult);

      // Calculate quality signal
      const signal = calculateQualitySignal(layerResult);

      // Check for early exit
      exitDecision = this.earlyExit.shouldExit(signal, i);

      if (exitDecision.canExit) {
        console.log(`[EarlyExit] Exiting at layer ${i}: ${exitDecision.explanation}`);

        // Speculative execution for remaining layers
        const skippedLayers = layers.slice(i + 1);

        if (exitDecision.enableSpeculation && skippedLayers.length > 0) {
          const speculations = await this.speculator.speculate(exitDecision, skippedLayers);
          const verified = await this.speculator.verify(speculations, skippedLayers);

          return {
            layers: results,
            exitedEarly: true,
            exitLayer: i,
            exitReason: exitDecision.reason,
            confidence: exitDecision.confidence,
            speculations: verified,
            skippedLayers: skippedLayers.length,
          };
        }

        return {
          layers: results,
          exitedEarly: true,
          exitLayer: i,
          exitReason: exitDecision.reason,
          confidence: exitDecision.confidence,
          speculations: [],
          skippedLayers: skippedLayers.length,
        };
      }
    }

    // Completed all layers
    return {
      layers: results,
      exitedEarly: false,
      exitLayer: layers.length - 1,
      exitReason: 'forced_continue',
      confidence: 1.0,
      speculations: [],
      skippedLayers: 0,
    };
  }

  private async executeLayer(layer: TestLayer, index: number): Promise<LayerResult> {
    console.log(`[EarlyExit] Executing layer ${index}: ${layer.name}`);

    const executor = new TestExecutor(layer);
    const result = await executor.run();

    // Add previous lambda for delta calculation
    const prevResult = this.layerResults.get(index - 1);
    if (prevResult) {
      result.previousLambda = calculateQualitySignal(prevResult).lambda;
    }

    return result;
  }
}

Agent Integration

// In qe-test-executor agent
import { EarlyExitController, DEFAULT_EXIT_CONFIG } from '../early-exit';

export class TestExecutorAgent {
  private earlyExitController: EarlyExitController;

  async initialize(): Promise<void> {
    this.earlyExitController = new EarlyExitController(
      DEFAULT_EXIT_CONFIG,
      4  // unit, integration, e2e, performance
    );
  }

  async executeTestPyramid(layers: TestLayer[]): Promise<TestPyramidResult> {
    const result = await this.earlyExitController.runWithEarlyExit(layers);

    if (result.exitedEarly) {
      console.log(`[Executor] Early exit at layer ${result.exitLayer} with ${(result.confidence * 100).toFixed(1)}% confidence`);
      console.log(`[Executor] Skipped ${result.skippedLayers} layers`);

      if (result.speculations.length > 0) {
        const correct = result.speculations.filter(s => s.correct).length;
        console.log(`[Executor] Speculation accuracy: ${correct}/${result.speculations.length}`);
      }
    }

    return result;
  }
}

Implementation Plan

Phase 1: Core Early Exit (Days 1-2)

v3/src/early-exit/
├── index.ts
├── types.ts
├── quality-signal.ts        # calculateQualitySignal()
├── early-exit-decision.ts   # CoherenceEarlyExit
└── configs.ts               # DEFAULT/AGGRESSIVE/CONSERVATIVE

Phase 2: Speculative Execution (Days 3-4)

├── speculative-executor.ts  # SpeculativeExecutor
├── prediction-model.ts      # Layer outcome prediction
└── verification.ts          # Verify speculations

Phase 3: Integration (Day 5)

  • Integrate with qe-test-executor agent
  • Add MCP tool for early exit configuration
  • Create metrics dashboard

Validation Rules

Rule ID Description Severity
SPEC-033-C-001 layers array must not be empty Error
SPEC-033-C-002 totalLayers must match actual layers Error
SPEC-033-C-003 Layer results must be stored sequentially Warning

Spec ID Title Relationship
SPEC-033-A Early Exit Algorithm Core decision logic
SPEC-033-B Speculative Execution Prediction system

Changelog

Version Date Author Changes
1.0 2026-01-20 Architecture Team Initial specification

References