Skip to content
carlosboeingPublic

About

Cross-model pull request review loop: one model reviews, another resolves.

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Repository files navigation

CrossRev

npm CI license: MIT platform: macOS | Linux status: pre-1.0

CrossRev is a cross-model pull request (PR) review and resolution loop. It coordinates independent reviewer and resolver agents around a pull request. The reviewer agent examines the changes and posts findings as inline PR comments. The resolver agent verifies each finding, fixes valid defects, and disputes false positives. The reviewer agent then inspects the resulting revision, and the loop continues until it converges, reaches a configured limit, or needs a person.

Agents can be configured with different harnesses, models, and effort levels. Configured harnesses authenticate through existing AI subscriptions or provider API keys.

CrossRev reviews a selected PR on demand from the CLI or starts review cycles automatically through GitHub Actions.

Features

Capability What CrossRev does
Review and resolution Reviews a change, verifies every finding, applies valid fixes, records disagreements, and reviews the new revision
Agent configuration Configures the reviewer and resolver agents independently by harness, model, and effort level
Model access Supports AI subscriptions, provider API keys, and compatible endpoints for cloud-hosted or self-hosted models
Local and automated operation Reviews a selected PR from the CLI or responds to GitHub events through GitHub Actions
Pull-request state Records every pass in comments and labels, with no database or local state file
Credential separation Keeps GitHub credentials in the orchestrator and out of the model process

Quick start

Requirements

CrossRev currently supports macOS and Linux. It requires git, authenticated gh, and at least one supported agent CLI; the npx and npm routes also require Node.js. The default configuration uses Codex for the reviewer agent and Claude for the resolver agent, but you can choose different harnesses and models.

Run without installing

Run one review pass directly from npm:

npx crossrev-ai review --pr 42

The npm package is the last Bash version, 0.5.0.

The review command posts inline comments and a summary, but never edits or pushes the branch. CrossRev uses your existing gh authentication, so the comments appear under your GitHub account.

Install CrossRev

The installer downloads the release binary and installs the complete command set, including automated-mode setup:

curl -fsSL https://raw.githubusercontent.com/carlosboeing/crossrev/main/install.sh | bash

Install the local CLI globally through npm:

npm install -g crossrev-ai

npm is paused, not dropped. Publishing stops at the last Bash version until the platform packages exist. What is on the registry is 0.5.0, which predates the native binary.

An npm installation supports local commands. For the current binary, use the installer above or install from a checkout: crossrev init runs from the repository you are setting up and writes the workflows there, reading the pin from the binary's build stamp, so no CrossRev checkout is needed beside it.

From an existing checkout, run:

./scripts/install-local.sh

See Installing CrossRev for pinned revisions, custom installation directories, updates, and removal.

Review a pull request

Check the machine, then run one review pass:

crossrev doctor
crossrev review --pr 42

That pass runs on whichever harness the configuration names for the reviewer, Codex by default. Name a different one for a single run, without changing repository policy:

crossrev review --pr 42 --harness claude

Run the complete review and resolution cycle when you are ready for CrossRev to apply fixes:

crossrev cycle --pr 42

Warning

crossrev cycle and crossrev resolve can commit and push to the pull request branch.

Review loop

%%{init: {'flowchart': {'wrappingWidth': 300, 'rankSpacing': 28, 'nodeSpacing': 40}}}%%
flowchart TD
    PR(["Pull request opened or updated"]) --> Q1

    Q1{"Label crossrev/stop<br/>applied?"}
    Q1 -- "yes" --> STOPPED
    Q1 -- "no" --> REV("<b>Reviewer Agent</b><br/><i>(codex by default)</i><br/>&bull; reads the diff<br/>&bull; posts findings<br/>&bull; never commits")

    REV --> Q2{"Findings at or above<br/>min_fix_severity?"}
    Q2 -- "no" --> OK
    Q2 -- "yes" --> RES

    RES("<b>Resolver Agent</b><br/><i>(claude by default)</i><br/>&bull; verifies findings<br/>&bull; fixes or disputes<br/>&bull; replies and pushes")
    RES --> Q3
    RES -- "finding deferred" --> BACKLOG

    Q3{"Commit pushed?"}
    Q3 -- "yes" --> Q4
    Q3 -- "no" --> Q5

    Q5{"Finding escalated?"}
    Q5 -- "yes" --> HALT
    Q5 -- "no" --> OK

    Q4{"Review limit<br/>reached?"}
    Q4 -- "no" --> Q1
    Q4 -- "yes" --> HALT

    BACKLOG(["<b>Backlog</b><br/>a GitHub issue, or a file in the repo"])
    OK(["<b>Converged</b><br/>no findings above the threshold"])
    HALT(["<b>Halted</b><br/>a person is needed"])
    STOPPED(["<b>Stopped</b><br/>a person ended the run"])

    classDef reviewer fill:#1f6feb,stroke:#0969da,stroke-width:2px,color:#fff
    classDef resolver fill:#8250df,stroke:#6639ba,stroke-width:2px,color:#fff
    classDef ask fill:#bf8700,stroke:#9a6700,stroke-width:2px,color:#fff
    classDef good fill:#1a7f37,stroke:#116329,stroke-width:2px,color:#fff
    classDef warn fill:#bc4c00,stroke:#953800,stroke-width:2px,color:#fff
    classDef brake fill:#cf222e,stroke:#a40e26,stroke-width:2px,color:#fff
    classDef start fill:#57606a,stroke:#424a53,stroke-width:2px,color:#fff
    classDef sink fill:#6e7781,stroke:#57606a,stroke-width:2px,color:#fff
    class REV reviewer
    class RES resolver
    class Q1,Q2,Q3,Q4,Q5 ask
    class OK good
    class HALT warn
    class STOPPED brake
    class PR start
    class BACKLOG sink
Loading

A cycle contains one or more passes. In each pass, the reviewer agent reads the current revision. The resolver agent follows when findings meet the configured severity threshold. The loop ends when it converges, reaches a limit, or needs a person.

Each review pass reads every changed file: every added, modified, deleted, renamed and type-changed path between the base branch and the pull request branch. A rename counts as new work and is read again from scratch.

crossrev/converged means review work is complete. No check runs in this release. The coverage record names verification status not_implemented and five nulls. Using CrossRev names which files count, which were read, which still wait, and which were hints or exclusions.

The review limit is policy.max_passes_per_cycle, which defaults to 3. Using CrossRev documents all six termination conditions and their precedence.

Every finding receives one resolution:

Resolution Meaning
fixed The resolver agent changed the code
disputed The finding is incorrect for this codebase, with the reason recorded in the review thread
deferred The finding is valid but belongs in the configured backlog
skipped Policy excludes the finding from changes, usually because it is below min_fix_severity
escalated A person must decide, so CrossRev applies crossrev/stop and leaves the thread open

Configuration

CrossRev needs no configuration for local use. The defaults use Codex as the reviewer agent and Claude as the resolver agent.

To configure a repository:

  1. Create .github/crossrev.yml, or let crossrev init generate it for automated mode.
  2. Configure the reviewer agent, resolver agent, and policy.
  3. Keep machine-specific endpoints in ~/.config/crossrev/config.yml.

The following example uses two Claude models in local mode:

version: 2
mode: local

policy:
  min_fix_severity: medium
  max_passes_per_cycle: 3

reviewer:
  harness: claude
  model: claude-fable-5
  effort: medium

resolver:
  harness: claude
  model: claude-opus-5
  effort: high

harness names the agent CLI. model and effort pass through to that harness. The reviewer and resolver configurations must differ by harness, model, or endpoint.

Compatible endpoints extend CrossRev beyond a harness's default provider. CrossRev supports public providers such as Kimi, self-hosted models through Ollama, and LLM gateways such as LiteLLM. See the operator configuration template for endpoint examples.

Override a harness for one command without changing repository policy:

crossrev review --pr 42 --harness claude

CrossRev reads repository policy from the pull request's base revision. A branch under review cannot change the rules used to review itself. See Configuring CrossRev for every field and merge rule.

Local and automated modes

CrossRev uses the same agents and protocol in both modes. The trigger and trusted GitHub identity change:

Local Automated
Trigger A terminal command Pull request events and CrossRev labels
GitHub identity Your authenticated gh account A repository-scoped GitHub App
Setup Install CrossRev and its dependencies Run crossrev auth login, then crossrev init
State Pull request comments and labels Pull request comments and labels
Runner Your machine GitHub-hosted or self-hosted

Caution

CrossRev supports self-hosted runners, but public repositories require stricter isolation because PRs can carry prompt injections that expose credentials or modify shared state. GitHub warns that self-hosted runners can be persistently compromised and should generally not be used for public repositories in its secure-use guidance. For public repositories, use a GitHub-hosted runner or a fresh, ephemeral self-hosted runner that handles one job and is destroyed afterward. A container alone is not sufficient if it can reach host credentials or shared state.

Automated mode starts with two commands. The second prints every file, secret, and label it would change before asking for confirmation:

crossrev auth login
crossrev init

Automated mode reviews branches in the repository, including Dependabot branches. It refuses fork pull requests because GitHub withholds repository secrets from fork workflows. Local review supports forks, and local resolution supports them when maintainer edits are enabled.

Harness support

CrossRev has adapters for Claude Code, Codex, Antigravity, Grok, and opencode. Any of them may take the resolve leg; the review leg refuses a harness whose command block is unverified at its pin, which today means grok reviews are refused with review_isolation_unverified while its resolve leg runs. Kimi runs through the Claude adapter as a named endpoint.

Running a harness locally needs nothing beyond its own CLI installed and logged in the way you already use it. CrossRev shells out to the CLI and never handles the credential itself, and crossrev doctor reports which harnesses it found.

Whether a harness works in GitHub Actions is a separate question, because a hosted runner starts with no login on disk. It depends on the credential's lifetime and the selected runner:

Harness Subscription credential Lifetime Survives an ephemeral runner
claude claude setup-token, purpose-built 1 year Yes
codex OAuth access token in ~/.codex/auth.json 10 days Yes, with the refresher below
agy the OS keyring on macOS (Antigravity Safe Storage); ~/.gemini/antigravity-cli/antigravity-oauth-token on a host with no D-Bus session bus 56 minutes No, CrossRev cannot seed into a hosted runner yet
grok ~/.grok/auth.json 6 hours Yes, by self-refreshing
opencode opencode auth login, purpose-built — Yes
kimi OAuth access token 15 minutes No

crossrev init refuses a pairing that its runner cannot serve. A self-hosted runner uses its installed logins and supports every pairing. CrossRev credentials explains the hosted-runner requirements and the Codex refresher.

--harness overrides one leg for one run, and takes any of the five adapter names — claude, codex, agy, grok, opencode. Kimi is not one of them: it is reached through an endpoints: entry rather than an adapter, so it is named by endpoint in the configuration. Pass the flag to review and resolve separately, because a pairing is two choices:

crossrev review  --pr 42 --harness codex    # reviewer leg on codex
crossrev resolve --pr 42 --harness claude   # resolver leg on claude

Commands

Command Effect
crossrev --pr 42 Runs the complete cycle, the same as crossrev cycle --pr 42
crossrev review --pr 42 Runs one review pass and posts comments without changing the branch
crossrev resolve --pr 42 Verifies the latest findings, then may commit and push fixes
crossrev status --pr 42 Shows the current state, every pass, and the command that resumes the loop
crossrev restart --pr 42 Restarts a halted leg: clears the halt and re-applies its awaiting label
crossrev watchdog --repo owner/name Finds stalled automated work, retries once, then halts it for inspection
crossrev doctor Checks dependencies, GitHub authentication, installed harnesses, and runner compatibility
crossrev init Plans and installs automated mode after confirmation

Safety and limits

crossrev review writes comments but never changes the branch. crossrev resolve and crossrev cycle may commit and push fixes.

CrossRev checks every push target before anything leaves the machine. The target must be the pull request's head branch, not the default branch, and its repository must match the configured remote.

The loop enforces the configured severity threshold and pass limit. CrossRev checks the crossrev/stop label before starting each agent. The label prevents the next agent from starting but does not cancel one already in progress.

CrossRev supports self-hosted runners, but public repositories require stricter isolation because PRs can carry prompt injections that expose credentials or modify shared state. GitHub warns that self-hosted runners can be persistently compromised and should generally not be used for public repositories in its secure-use guidance. For public repositories, use a GitHub-hosted runner or a fresh, ephemeral self-hosted runner that handles one job and is destroyed afterward. A container alone is not sufficient if it can reach host credentials or shared state.

CrossRev reconstructs every pass from the pull request and the repository's ledger ref. Hidden markers record the revision, findings, resolutions, and execution details. A retry reads those markers and continues without duplicating completed writes. What CrossRev writes lists every write, as a contract.

The model process never receives a GitHub credential. The orchestrator makes every GitHub API call and controls every git commit and push.

Documentation

Page Contents
Installation Install, update, and remove CrossRev
Usage Run the loop, inspect its output, and understand each terminal state
What CrossRev writes See everything CrossRev writes to a repository, as a contract
Configuration Configure repository policy, local endpoints, and environment variables
Credentials Understand the secrets required for automated mode
Troubleshooting Diagnose each reported failure and resume a stopped loop
Architecture Follow the orchestrator, adapters, marker protocol, label contract, and security boundary
Decision records Read the decisions, alternatives, and consequences behind the design
Roadmap See current work and deferred directions
Changelog See what changed in each release
Releases Download releases and read release notes

Contributing

Contributions are welcome. See Contributing to CrossRev for development setup, project constraints, test layers, and the pull-request process. Participation follows the Code of Conduct.

Run the offline checks listed under Tests before opening a pull request. CI runs the same five.

Use the repository's issue templates for bug reports and feature requests.

Security

Report vulnerabilities privately through the process in the security policy. Do not open a public issue for a security report.

License

CrossRev is available under the MIT License.

About

Cross-model pull request review loop: one model reviews, another resolves.

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages