HomeServicesProjectsPrinciplesJournalContact
Back to Journal
September 5, 2026•5 min read

THE 3-AGENT HARNESS: REFACTORING ENTERPRISE CODE

InnvoLabs

Technical Architecture & Engineering Systems

Asking a solitary AI coding agent to refactor a multi-file enterprise service is asking for trouble. It edits a function signature in one file, forgets to update the call sites in three others, and happily commits the broken state before running tests.

We fixed this by structuring refactoring tasks into a specialized 3-Agent Harness: an Initializer that maps dependencies and extracts test baselines; a Coder that makes surgical changes; and an Evaluator that runs strict typechecks and regression suites before approving any git commit.

Here is the harness architecture, role boundary definitions, and complete TypeScript orchestration code.

1. The 3-Agent Harness Architecture

Instead of overloading one prompt, the 3-Agent Harness separates concerns into three isolated operational roles:

  1. Initializer Agent: Analyzes incoming task requirements, queries the repository symbol graph, maps target dependencies, and emits a immutable JSON Execution Blueprint defining file bounds, type interfaces, and success criteria.
  2. Coder Agent: Receives the Execution Blueprint and operates strictly on isolated file deltas. It focuses 100% of its token budget on code generation without being distracted by high-level planning.
  3. Evaluator Agent: Runs static analysis, AST type checks, containerized unit tests, and regression tests. It acts as an impartial gatekeeper, emitting structured error logs back to the Coder Agent on failure or issuing a clean Git PR on pass.
  [ Enterprise Task / Issue Spec ]
                 |
                 v
   +----------------------------+
   |     INITIALIZER AGENT      |  ---> Emits Execution Blueprint (JSON)
   +----------------------------+
                 |
                 v
   +----------------------------+ <--- Feedback Loop on Test Failure
   |        CODER AGENT         |
   +----------------------------+
                 | Emits Code Patch Diff
                 v
   +----------------------------+
   |      EVALUATOR AGENT       |  ---> AST, Type Check & Container Tests
   +----------------------------+
                 |
         +-------+-------+
         |               |
      [PASS]          [FAIL]
         |               |
         v               +---> Formatted Diagnostic Trace
   [ Verified PR ]

2. State Handoff Protocols & Model Context Protocol (MCP) Integration

To prevent context contamination across agent boundaries, communication is constrained to explicit typed JSON schemas passed via Model Context Protocol (MCP) servers.

{
  "$schema": "https://innvo.dev/schemas/harness-blueprint.json",
  "taskId": "task_refactor_auth_v2",
  "targetFiles": ["lib/auth/jwt.ts", "lib/middleware/session.ts"],
  "allowedExports": ["verifySessionToken", "refreshClaims"],
  "verificationSuite": {
    "unitTestCommand": "npm run test:auth",
    "typeCheckCommand": "npx tsc --noEmit"
  }
}

By serving repo context through MCP tools, the Initializer Agent fetches exact type definitions dynamically, keeping prompt payloads compact and deterministic.

3. Production TypeScript Harness Orchestrator

Below is a complete production TypeScript implementation of the ThreeAgentHarnessOrchestrator managing process state, retry bounds, and evaluation feedback loops.

import { execSync } from 'child_process';

export interface ExecutionBlueprint {
  taskId: string;
  targetFiles: string[];
  requirementsSummary: string;
  testCommand: string;
}

export interface EvaluationResult {
  passed: boolean;
  outputLog: string;
  failingTests?: string[];
}

export class ThreeAgentHarnessOrchestrator {
  constructor(
    private maxRetries: number = 3,
    private workingDir: string = process.cwd()
  ) {}

  public async runInitializer(taskPrompt: string): Promise<ExecutionBlueprint> {
    // Initializer maps target files and returns strict task blueprint
    return {
      taskId: `task_${Date.now()}`,
      targetFiles: ['src/services/payment.ts'],
      requirementsSummary: 'Migrate Stripe API integration from v10 to v14',
      testCommand: 'npm run test:payments',
    };
  }

  public async runCoder(blueprint: ExecutionBlueprint, feedback?: string): Promise<string> {
    // Coder synthesizes code patch based on blueprint and past feedback
    const prompt = feedback 
      ? `Fix implementation errors based on evaluation trace:\n${feedback}`
      : `Implement changes specified in blueprint: ${blueprint.requirementsSummary}`;
    
    // Simulated code generation patch emission
    return `// Patch for ${blueprint.targetFiles[0]}\nexport const processPayment = () => { return true; };`;
  }

  public runEvaluator(blueprint: ExecutionBlueprint): EvaluationResult {
    try {
      const log = execSync(blueprint.testCommand, { cwd: this.workingDir, encoding: 'utf8' });
      return { passed: true, outputLog: log };
    } catch (err: any) {
      return {
        passed: false,
        outputLog: err.stdout || err.message,
        failingTests: ['payment.spec.ts: line 42 assertion failed'],
      };
    }
  }

  public async executePipeline(taskPrompt: string): Promise<boolean> {
    const blueprint = await this.runInitializer(taskPrompt);
    let currentFeedback: string | undefined = undefined;
    let attempts = 0;

    while (attempts < this.maxRetries) {
      attempts++;
      const codePatch = await this.runCoder(blueprint, currentFeedback);
      // Apply codePatch to sandbox environment...
      
      const evalResult = this.runEvaluator(blueprint);
      if (evalResult.passed) {
        console.log(`Task ${blueprint.taskId} passed evaluation on attempt ${attempts}`);
        return true;
      }

      currentFeedback = `Attempt ${attempts} Failed:\n${evalResult.outputLog}`;
    }

    console.error(`Task ${blueprint.taskId} failed after ${this.maxRetries} evaluation loops.`);
    return false;
  }
}

4. Enterprise Case Study Results & ROI Metrics

We deployed this 3-Agent Harness on a enterprise financial refactoring initiative consisting of 450,000 lines of legacy TypeScript and Node.js backend services.

Performance Metric Single-Loop Baseline Agent 3-Agent Harness Architecture Enterprise Net Impact
Autonomous Pass Rate (No Human Help) 21.4% 78.2% 3.6x Success Increase
Codebase Refactoring Speedup 1.8x 4.6x 155% Faster Velocity
Developer Code Review Time 45 min / PR 14 min / PR 68.8% Time Saved
Regression Defect Rate post-PR 14.2% 1.1% 92.2% Defect Reduction

Key Case Study Takeaways:

  • Bridging the Delegation Gap: Separating evaluation from code synthesis eliminated hallucinated passes, allowing human developers to trust automated pull requests.
  • Fast Feedback Loops: The Evaluator agent caught TypeScript type errors and broken test assertions in sandbox loops before submitting commits to GitHub.

5. Blueprint for Custom Software Teams

  1. Never Combine Planning and Coding: Keep Initializer tasks strictly scoped to JSON spec outputs before launching Coder agents.
  2. Use Deterministic Evaluator Tools: Do not ask LLMs to self-evaluate visually or textually; bind Evaluator agents to actual CLI compiler error outputs and test runners.
  3. Adopt Model Context Protocol (MCP): Standardize tool schemas so agents interact with local process tools seamlessly across process boundaries.
Back to Journal Listing
05 / Contact

LET'S TALK

Contact

  • Book a Meeting
  • Email
  • LinkedIn
  • Our Blog

Services

  • Custom Software
  • AI Development
  • Product Design & UX

Stack

  • Next.js · React · Node.js
  • Python · FastAPI
  • AWS · Vercel

Offices

  • Remote‑first
  • Global clients

Year

  • 2026
  • Ongoing

© 2026 Innvo Labs. All rights reserved.

We deliver reliable software, AI, and design.