# How Codex Plugin CC Handles Review Target Resolution: Branch vs Working Tree

> Understand how Codex Plugin CC handles review target resolution between branches and working trees. Learn about automatic selection based on repository state and flags.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: internals
- Published: 2026-07-04

---

**Codex Plugin CC resolves review targets through the `resolveReviewTarget` function in `plugins/codex/scripts/lib/git.mjs`, which automatically selects between branch diffs and working-tree changes based on repository cleanliness, explicit `--base` or `--scope` flags, or falls back to branch mode when the working tree is clean.**

Understanding **review target resolution** is essential when using the openai/codex-plugin-cc repository to generate code reviews. The system must determine whether to analyze changes against a specific branch reference or against the current working directory's staged and unstaged modifications. This decision logic is implemented in the Git utility module and consumed by the main companion script.

## The Core Resolution Function

The entire **review target resolution** process centers on the `resolveReviewTarget` function located in `plugins/codex/scripts/lib/git.mjs` (lines 34-90). This async function accepts a repository path and an optional options object, then returns a deterministic target configuration that tells the review engine exactly what changes to analyze.

The function begins by ensuring the environment is valid through `ensureGitRepository` and capturing the current state via `getWorkingTreeState` before applying a cascading decision tree to select the appropriate mode.

## Decision Flow for Target Resolution

The resolution logic follows a strict priority order, checking explicit overrides before falling back to automatic detection.

### Pre-flight Validation

Before any mode selection occurs, the function validates that the current directory resides within a Git repository and gathers the working tree state. This initial check at lines 34-40 ensures that subsequent operations have a valid Git context to work with.

### Explicit Base Reference (--base)

When the caller provides a `base` option (e.g., `--base v1.2.0`), the function immediately forces **branch mode** (lines 42-48). In this scenario, the review will compare the current state against the specified reference, regardless of working tree cleanliness. The returned object sets `mode: "branch"` and uses the provided ref as the `baseRef`.

### Explicit Scope Selection (--scope)

The `--scope` flag allows users to override automatic detection with specific behaviors:

- **`working-tree`**: Forces the review to analyze staged, unstaged, and untracked files in the working directory (lines 51-57). The function returns `mode: "working-tree"` and sets `explicit: true`.

- **`branch`**: Forces branch comparison mode. When specified without a `--base` flag, the function calls `detectDefaultBranch` (lines 65-73) to identify the appropriate comparison branch (typically `main`, `master`, or whatever `origin/HEAD` points to).

### Automatic Mode Detection

When no explicit flags are provided, the function enters **auto mode** (lines 75-89):

1. **Dirty working tree**: If `state.isDirty` returns true (indicating staged, unstaged, or untracked files exist), the function selects **working-tree** mode (lines 75-81). This ensures that local modifications are reviewed even if they haven't been committed.

2. **Clean repository**: When the working tree is clean, the function defaults to **branch mode** using the detected default branch as the comparison base (lines 83-89).

## Target Object Return Structure

Regardless of which path is taken, `resolveReviewTarget` returns a standardized object containing:

| Property | Description |
|----------|-------------|
| `mode` | Either `"branch"` or `"working-tree"` |
| `label` | Human-readable description (e.g., `"branch diff against main"`) |
| `baseRef` | The branch name for comparison (only present in branch mode) |
| `explicit` | Boolean indicating whether the mode was forced via flags |

This structure allows the calling code in `codex-companion.mjs` to consistently handle both review types without additional conditional logic.

## Helper Functions Supporting Resolution

Several utility functions within `git.mjs` provide the data necessary for these decisions:

### detectDefaultBranch

Located at lines 93-114, this function inspects `origin/HEAD` to determine the remote default branch. If that reference isn't available, it falls back to checking common branch names including `main`, `master`, and `trunk`. This ensures that branch-mode reviews always have a sensible comparison target even when the user hasn't specified one explicitly.

### getWorkingTreeState

This function gathers the repository status to determine if the working tree is **dirty**. It checks for staged changes, unstaged modifications, and untracked files, returning a boolean `isDirty` flag that drives the automatic mode selection at line 75.

### getCurrentBranch

Called at line 117, this utility reports the current branch name for inclusion in review summaries and metadata, though it doesn't affect the target resolution logic directly.

## Practical Usage Examples

Here are three common patterns for invoking the resolution logic:

```javascript
import { resolveReviewTarget } from "./plugins/codex/scripts/lib/git.mjs";

// 1. Automatic mode on a clean repository → branch diff
const target1 = await resolveReviewTarget("/path/to/repo");
console.log(target1.mode);   // "branch"
console.log(target1.label); // "branch diff against main"

// 2. Force working-tree review of local changes
const target2 = await resolveReviewTarget("/path/to/repo", { scope: "working-tree" });
console.log(target2.mode);   // "working-tree"
console.log(target2.explicit); // true

// 3. Compare against a specific tag or commit
const target3 = await resolveReviewTarget("/path/to/repo", { base: "v1.2.0" });
console.log(target3.mode);   // "branch"
console.log(target3.baseRef); // "v1.2.0"

```

These examples demonstrate how the function adapts to different workflows while maintaining consistent return types.

## Integration with the Codex Companion

The resolution logic connects to the main application in `plugins/codex/scripts/codex-companion.mjs` at lines 369-371. Here, the `validateNativeReviewRequest` function calls `resolveReviewTarget` to prepare the review context before invoking the AI code review engine.

This integration point ensures that by the time the review starts, the system has already determined whether to analyze a branch diff (using `baseRef`) or the working tree changes, and has gathered the appropriate file lists accordingly.

## Summary

- **Review target resolution** occurs in `plugins/codex/scripts/lib/git.mjs` via the `resolveReviewTarget` function (lines 34-90).
- The function prioritizes explicit user input: `--base` forces branch mode, while `--scope` forces either branch or working-tree mode.
- In **automatic mode**, a dirty working tree triggers working-tree review, while a clean repository defaults to branch comparison against the detected default branch.
- Helper functions `detectDefaultBranch` (lines 93-114) and `getWorkingTreeState` provide the underlying Git intelligence for these decisions.
- The entry point at `codex-companion.mjs` (lines 369-371) consumes this logic to configure the review context.

## Frequently Asked Questions

### How does automatic mode decide between branch and working-tree review?

When running in automatic mode (no `--scope` or `--base` flags provided), the function checks `state.isDirty` at line 75. If the working tree contains any staged, unstaged, or untracked files, it selects **working-tree** mode to capture local modifications. If the repository is clean, it defaults to **branch** mode and compares against the detected default branch (lines 83-89).

### What happens if I specify both --base and --scope?

The `--base` flag takes precedence in the implementation order. At lines 42-48, the function checks for the `base` option before evaluating the `scope` option. Providing a `base` reference automatically forces branch mode, regardless of any `--scope` value provided, because the explicit base reference inherently defines a branch comparison.

### Which files contain the review target resolution logic?

The primary logic resides in `plugins/codex/scripts/lib/git.mjs`, specifically the `resolveReviewTarget` function (lines 34-90) and its helper functions `detectDefaultBranch` (lines 93-114) and `getWorkingTreeState`. The entry point that invokes this logic is `plugins/codex/scripts/codex-companion.mjs` (lines 369-371), and unit tests verifying this behavior are in `tests/git.test.mjs`.

### How is the default branch detected when using branch mode?

The `detectDefaultBranch` function (lines 93-114) first attempts to resolve `origin/HEAD` to determine the remote default branch. If that reference is unavailable, it iterates through common branch names including `main`, `master`, and `trunk`, returning the first existing match. This ensures branch comparisons always have a valid reference point even without explicit configuration.