# How Agent Sessions Are Managed in the Review Loop to Maintain Role Isolation

> Learn how the no-mistakes engine manages agent sessions for strict role isolation. Discover unique run ID keys preventing cross-contamination between reviewer and fixer agents.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: internals
- Published: 2026-07-16

---

**The no-mistakes engine enforces strict role isolation by creating separate, durable sessions for the reviewer and fixer agents, keyed uniquely by run ID to prevent cross-contamination between phases.**

In the kunchenguid/no-mistakes codebase, the review loop orchestrates a multi-turn pipeline where distinct AI agents critique and remediate code. To ensure that the **reviewer** and **fixer** operate with independent context and memory, the system implements a sophisticated session management layer that isolates state by both role and pipeline run.

## The Review Loop Architecture

The pipeline executes two distinct agents for every run. First, a reviewer evaluates the code and generates feedback. Then, a fixer implements the suggested changes. Without careful isolation, the reviewer's critique could leak into the fixer's reasoning, or the fixer's implementation details could bias subsequent review turns.

To prevent this, the architecture treats each role as a separate entity with its own conversation history. The **reviewer session** is created when a run first enters the review step, while the **fixer session** is instantiated only when transitioning to the fix phase. These sessions remain isolated throughout the entire pipeline execution.

## Per-Run Session Isolation

Sessions are stored in a dedicated map within [`internal/pipeline/sessions.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/sessions.go), keyed solely by the unique run identifier. This design guarantees that:

- **One reviewer session** exists per run, reused across every review turn to maintain continuity.
- **One separate fixer session** exists per run, never shared with the reviewer.
- **No session leakage** occurs between different pipeline runs.

When a run completes, the `sessionMap` entries are cleared, ensuring that no state persists to contaminate future executions.

## Role-Based Session Creation

The `GetOrCreateSession` function in [`internal/pipeline/sessions.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/sessions.go) implements the isolation logic. It accepts a run ID and a role constant—either `RoleReviewer` or `RoleFixer` defined in [`internal/pipeline/types.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/types.go)—and returns the corresponding session.

```go
// Retrieve (or create) the reviewer session for the current run.
reviewSess, err := pipeline.GetOrCreateSession(
    ctx,
    run.ID,               // unique run identifier
    pipeline.RoleReviewer, // role identifier
)
if err != nil {
    return err
}

// Retrieve (or create) the fixer session – distinct from the reviewer.
fixSess, err := pipeline.GetOrCreateSession(
    ctx,
    run.ID,
    pipeline.RoleFixer,
)
if err != nil {
    return err
}

```

Each session exposes methods such as `AddMessage`, `GetHistory`, and `Reset`, allowing agents to safely manage conversation state without accessing each other's data.

## Phase-Specific Agent Initialization

The step implementations in [`internal/pipeline/steps/review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/review.go) and [`internal/pipeline/steps/fix.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/fix.go) demonstrate how role isolation manifests in practice:

```go
// Example: switching roles during a run.
if step.IsReview() {
    // Use the reviewer session.
    agent := reviewer.NewAgent(reviewSess)
    agent.Run(...)
} else if step.IsFix() {
    // Use the fixer session.
    agent := fixer.NewAgent(fixSess)
    agent.Run(...)
}

```

This strict separation ensures that **the reviewer never inherits the fixer's rationale, and vice versa**. Each phase makes decisions based exclusively on its own view of the code and its prior conversation history.

## Durability Across RPC Boundaries

The session management system guarantees **durability** across process restarts and multiple RPC calls. Because sessions are stored in the `sessionMap` rather than ephemeral memory tied to a single request, agents can continue multi-turn review or fix processes without losing context, even if the daemon restarts between turns.

## Configuring Session Reuse

The implementation respects a `session_reuse` pipeline flag. When set to `false`, this configuration forces the creation of fresh sessions for every turn, further strengthening isolation at the cost of losing historical context within a single phase. This is useful when you want to ensure that each review or fix iteration starts with no prior bias from earlier turns in the same run.

## Summary

- **Role isolation** in no-mistakes is enforced by maintaining separate reviewer and fixer sessions per pipeline run.
- **Session durability** persists across RPC calls and daemon restarts via the `sessionMap` in [`internal/pipeline/sessions.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/sessions.go).
- **Per-run keying** by run ID ensures no cross-contamination between different pipeline executions.
- **Phase-specific retrieval** via `GetOrCreateSession` with `RoleReviewer` or `RoleFixer` constants keeps agent contexts strictly separated.
- **Configurable isolation** through the `session_reuse` flag allows fresh sessions per turn when stricter separation is required.

## Frequently Asked Questions

### What prevents the reviewer and fixer from sharing context?

The system creates **separate sessions** for each role, stored in distinct entries in the `sessionMap` keyed by `(runID, role)`. The reviewer session is retrieved using `pipeline.RoleReviewer` while the fixer uses `pipeline.RoleFixer`, and these are never mixed during a single pipeline run.

### Where is the session isolation logic implemented?

The core logic resides in [`internal/pipeline/sessions.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/sessions.go), which manages the `sessionMap` and provides the `GetOrCreateSession` helper. Role constants are defined in [`internal/pipeline/types.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/types.go), while the consumer logic appears in [`internal/pipeline/steps/review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/review.go) and [`internal/pipeline/steps/fix.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/fix.go).

### Can sessions persist across multiple turns of the same review?

Yes, sessions are **durable by default**. Once created via `GetOrCreateSession`, a session is reused for subsequent turns of the same phase (review or fix) within the same run ID. This preserves conversation history and context, though the `session_reuse` flag can be set to `false` to force fresh sessions per turn.

### How does the system handle session cleanup when a run finishes?

When a pipeline run completes, the entries in the `sessionMap` corresponding to that run ID are cleared. This automatic cleanup prevents memory leaks and ensures that session state never carries over to future runs, maintaining strict temporal isolation between pipeline executions.