Skip to content

[Phase 4] Verification Gate Wrapper for External Agents #415

Description

@frankbria

Summary

Ensure CodeFrame's verification gates (ruff, pytest, etc.) and self-correction loop work uniformly across all execution engines, not just the built-in ReactAgent.

Parent issue: #408

Motivation

Currently verification gates and self-correction are deeply embedded in react_agent.py::_run_final_verification(). When using external engines (Claude Code, Aider, Codex), CodeFrame still needs to:

  1. Run gates after the agent finishes
  2. If gates fail, re-invoke the agent with error context
  3. Repeat up to N times

This is CodeFrame's core value-add over raw agent usage. A developer using Claude Code directly doesn't get automatic "fix the lint errors" retries. CodeFrame does.

Scope

New module: core/verification_loop.py

  1. VerificationLoop class:
class VerificationLoop:
    def __init__(self, workspace, gates, max_retries=5):
        self.workspace = workspace
        self.gates = gates
        self.max_retries = max_retries
    
    def run_with_verification(
        self, 
        adapter: AgentAdapter,
        context: AgentContext,
        workspace_path: Path,
    ) -> AgentResult:
        """Execute agent, verify, retry on failure.
        
        Loop:
        1. adapter.execute(prompt, workspace)
        2. Run gates (ruff, pytest, etc.)
        3. If gates pass → return success
        4. If gates fail → append errors to context, re-invoke adapter
        5. Repeat up to max_retries
        """
        ...
  1. Gate error → context enrichment:

    • When gates fail, append error output to context.previous_errors
    • Increment context.attempt
    • Re-invoke the adapter with enriched context
    • The prompt to the agent includes: "The following verification checks failed: [errors]. Please fix these issues."
  2. Extract verification logic from react_agent.py:

    • Move _run_final_verification() logic into VerificationLoop
    • ReactAgent's internal verification becomes a call to VerificationLoop
    • External engines use the same VerificationLoop

Changes to core/runtime.py

  1. execute_agent() uses VerificationLoop for all engines:
    adapter = registry.get(engine)
    context = packager.build_agent_context(task_id)
    loop = VerificationLoop(workspace, gates, max_retries=5)
    result = loop.run_with_verification(adapter, context, workspace_path)

Quick fix integration

  1. Before re-invoking the agent, attempt quick fixes (core/quick_fixes.py):
    • If the error is a known pattern (missing import, lint error), apply quick fix first
    • Only re-invoke the agent for errors that quick fixes can't handle
    • This preserves CodeFrame's existing optimization

Acceptance Criteria

  • VerificationLoop runs gates after any engine completes
  • Gate failures trigger re-invocation with error context
  • Quick fixes applied before agent re-invocation
  • Max retry limit respected
  • Blocker created if max retries exceeded
  • Works with all registered engines (built-in, claude-code, aider, codex)
  • ReactAgent refactored to use shared VerificationLoop (no behavior change)
  • Integration tests: engine succeeds → gates fail → retry → gates pass

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestphase-4.1Phase 4.1: Agent Adapter Foundation (protocol, registry, verification wrapper)quality

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions