How Agent Sessions Are Managed for Review Loops vs. Fixer Sessions in No-Mistakes

The no-mistakes pipeline uses a per-run, per-role session manager to maintain durable agent sessions across resumable review-loop turns, ensuring complete isolation between reviewer and fixer contexts.

The kunchenguid/no-mistakes repository implements a sophisticated pipeline for automated code review that persists agent state across multiple turns. Understanding how agent sessions are managed for review loops compared to fixer sessions reveals a strict architectural separation that prevents context contamination between distinct operational roles.

The Dual-Role Session Architecture

SessionRole Constants and Role Separation

In internal/pipeline/sessions.go lines 18-21, the pipeline defines two distinct SessionRole constants: SessionRoleReviewer for initial full reviews and subsequent rereviews, and SessionRoleFixer for every review-fix turn. These constants ensure that the fixer role never mixes with the reviewer role, creating a hard boundary between the two operational contexts.

State Isolation Guarantees

The reviewer and fixer sessions remain completely isolated according to the source code. The reviewer’s session is exclusively used for the reviewer role, while the fixer’s session handles only fix operations. This isolation prevents the fixer from inheriting the reviewer’s working context or vice versa, enforced by the SessionRole type and distinct persistence paths in the database schema.

The RunSessions Manager Implementation

Session Lifecycle and Persistence

When a pipeline step executes, it invokes RunSessions.Run with the desired role. The manager executes a three-phase lifecycle defined in internal/pipeline/sessions.go:

  1. Load: Retrieve any persisted session ID for the given (run, role) pair via GetRunAgentSessions (lines 44-63).
  2. Attach: If the adapter supports session resumption, attach the stored ID to agent.RunOpts.Session.
  3. Persist: After the agent completes execution, save the new session ID via UpsertRunAgentSession (lines 84-86).

The review loop implementation in internal/pipeline/steps/review.go utilizes this manager to orchestrate both roles, while internal/pipeline/steps/review_session_test.go verifies that sessions remain distinct and correctly resumed across turns.

Database Schema for Per-Role Storage

Session persistence relies on the run_agent_sessions table defined in internal/db/agent_session.go lines 5-15. The schema includes a distinct role column that stores each role's session ID separately, ensuring that reviewer and fixer sessions occupy separate database records even within the same pipeline run.

Session Fallback and Recovery

When resume attempts fail due to expired or dead sessions, RunSessions.Run implements a SessionFallback mechanism (lines 90-100 in internal/pipeline/sessions.go). The manager drops the stale identity, logs the failure, and re-executes the turn with a fresh session, ensuring pipeline correctness even when session persistence proves unreliable.

Practical Implementation Example

The following Go code demonstrates how RunSessions manages distinct sessions for each role:

// Creating a RunSessions manager for a specific run
rs := pipeline.NewRunSessions(db, runID, myAgent, true)

// Running the reviewer role (initial review or rereview)
reviewResult, err := rs.Run(ctx, myAgent, pipeline.SessionRoleReviewer,
    agent.RunOpts{Prompt: reviewerPrompt}, nil)

// Running the fixer role (each review-fix turn)
fixResult, err := rs.Run(ctx, myAgent, pipeline.SessionRoleFixer,
    agent.RunOpts{Prompt: fixerPrompt}, nil)

The manager automatically loads any saved session ID, attaches it to RunOpts, and persists the new ID after each call, handling the complexity of session resumption transparently.

Summary

  • Per-role isolation: The pipeline uses SessionRoleReviewer and SessionRoleFixer constants to maintain distinct session contexts that never mix.
  • Automatic persistence: The RunSessions manager handles loading and saving session IDs via GetRunAgentSessions and UpsertRunAgentSession without manual intervention.
  • Database separation: The run_agent_sessions table stores each role's session under a distinct role column, preventing cross-contamination at the persistence layer.
  • Graceful degradation: The SessionFallback mechanism ensures pipelines continue executing with fresh sessions when stored sessions expire or become invalid.

Frequently Asked Questions

What happens when a stored session expires during a review loop?

When a resume attempt fails because the stored session is dead or expired, RunSessions.Run detects the failure and triggers SessionFallback. It drops the stale session identity, logs the failure for observability, and re-executes the current turn with a fresh session, ensuring the pipeline completes successfully even when session persistence is unreliable.

Can reviewer and fixer agents share the same session ID?

No. The architecture explicitly forbids session sharing between roles. The SessionRole type and the database schema in internal/db/agent_session.go enforce complete isolation, with each role persisting to a separate record in the run_agent_sessions table. This prevents the fixer from inheriting the reviewer's context or state.

How does the database schema enforce session isolation?

The run_agent_sessions table includes a role column that stores the specific SessionRole value (either SessionRoleReviewer or SessionRoleFixer) alongside the run_id and session_id. This composite key structure ensures that each (run, role) combination maintains its own session record, preventing any overlap between reviewer and fixer session storage.

Is session resumption supported for all agent adapters?

Session resumption depends on the specific agent adapter's capabilities. The RunSessions manager checks whether the adapter supports session resumption before attaching the stored session ID to agent.RunOpts. If the adapter does not support resumption, the manager operates correctly but creates a fresh session for each turn, falling back to standard execution without the persistent context.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →