# Cross Review Pr

> Cross-model comparative PR / Pull Request review of a PR, branch, commit, or codebase scope. Runs two LLMs through independent reviews, has Reviewer A validate Reviewer B's findings only, then synthesizes overlap, A-only findings, and A-checked B-only findings. Default: Claude <-> Codex. Supports Claude, Codex, and OpenCode via --from/--to. Trigger for comparative PR review, comparative review, P…

- **Type:** Skill
- **Install:** `agentstack add skill-wnz99-claude-skills-cross-review-pr`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [wnz99](https://agentstack.voostack.com/s/wnz99)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [wnz99](https://github.com/wnz99)
- **Source:** https://github.com/wnz99/llm-dev-skills/tree/main/skills/cross-review-pr

## Install

```sh
agentstack add skill-wnz99-claude-skills-cross-review-pr
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Cross-Review PR

Run a comparative code review on a Pull Request using two independent models.
The value is in independent coverage: each model reviews the same change
without seeing the other's findings. After both independent reviews complete,
Reviewer A validates Reviewer B's findings only. Do not send Reviewer A's
findings to Reviewer B unless the user explicitly asks for that extra step.

## Canonical source and updates

This skill is maintained in [wnz99/llm-dev-skills](https://github.com/wnz99/llm-dev-skills/tree/main/skills/cross-review-pr). When asked to update, reinstall, download, or replace this skill with a newer version, inspect that upstream directory first and use the newest compatible version. Preserve intentional installation-specific adaptations and report any divergence instead of silently overwriting it.

## Supported LLMs

| ID | Description |
|----|-------------|
| `claude` | Claude Code |
| `codex` | OpenAI Codex CLI |
| `opencode` | OpenCode CLI |

## Self-awareness rule

**You (the agent executing this skill) must identify which LLM you are.**
This determines which roles you handle inline vs. which require shelling
out to an external CLI.

- If you are **Claude**: `claude` roles run inline (use `code-reviewer` skill
  or direct analysis). `codex` and `opencode` roles shell out via their CLIs.
- If you are **Codex**: `codex` roles run inline (do the review yourself, and
  do the one-way validation yourself when Codex is Reviewer A). `claude` and
  `opencode` roles shell out via their CLIs.
- If you are **OpenCode**: `opencode` roles run inline. `claude` and `codex`
  roles shell out via their CLIs.

**CRITICAL: Never shell out to yourself.** If `--from` or `--to` matches
your own identity, you perform that step directly — no CLI subprocess.
If the role is a *different* LLM, you invoke it via its CLI.

## Prerequisites

- `gh` CLI installed and authenticated (for PR checkout and metadata)
- External LLM CLIs installed for whichever selected reviewer is not the
  invoking LLM
- Project has a CLAUDE.md with coding standards (strongly recommended)

## Arguments

- **Scope** (required for default mode): PR number (e.g., `47`) or URL
  (e.g., `https://github.com/org/repo/pull/47`). In `--deep` mode the
  scope can also be a branch range (`main..HEAD`), a directory path
  (`src/`), or omitted (review the entire `src/` tree).
- **--from REVIEWER_A** (optional): LLM that performs the first independent review.
  Values: `claude` (default), `codex`, `opencode`.
- **--to REVIEWER_B** (optional): LLM that performs the second independent review.
  Values: `codex` (default), `claude`, `opencode`.
- **--focus AREA** (optional): Narrow both reviews to a specific area
  (security, performance, concurrency, error-handling). Default: general review.
- **--deep** (optional): Run the multi-agent multi-area review described
  in the **Deep Mode** section below. The word "deep" requests deep mode, but
  it is not automatically explicit permission to spawn sub-agents in hosts
  with restrictive delegation policy. If the host requires explicit permission
  for sub-agents or parallel agent work, ask for that permission before
  launching strict deep mode. Default areas: 5. Override with `--areas N`.
- **--areas N** (optional, deep mode only): Number of focus areas to
  decompose the scope into. Default: `5`. Range: 2–8. Smaller scopes
  may use fewer; the skill will downscale automatically.
- **--post** (optional): Post the unified report as a PR comment after
  presenting it (only meaningful when scope is a PR).

`--from` and `--to` must not be the same LLM.

**Common combinations:**

| Shorthand | Equivalent |
|-----------|------------|
| (default) | `--from claude --to codex` |
| `--from codex` | `--from codex --to claude` |
| `--from opencode --to codex` | OpenCode and Codex cross-review |

When only one of `--from`/`--to` is provided, the other defaults to the
opposite side of the ClaudeCodex pair. If the provided value is `claude`,
the other defaults to `codex` and vice versa. If the provided value is
`opencode`, the other defaults to `codex`.

## Workflow

### Step 1: Terminal Awareness

Before gathering diffs or generating prompt files, inspect the active terminal
environment and choose commands that are safe for that shell:

```bash
printf 'SHELL=%s\n' "${SHELL:-unknown}"
ps -p $$ -o comm=
command -v bash || true
command -v zsh || true
```

If the current shell is `zsh`, do not rely on zsh word splitting. Prefer one
of these patterns:

- Run prompt-generation scripts under `bash` with `set -euo pipefail`.
- Use newline-safe loops: `while IFS= read -r file; do ...; done |)' "$PROMPT_FILE" | head
test "$(wc -l "
```

Fetch PR metadata and diff:

```bash
gh pr view "$PR_NUM" --json title,body,baseRefName,headRefName,files > "$CROSS_REVIEW_TMPDIR/pr-meta.json"
gh pr diff "$PR_NUM" > "$CROSS_REVIEW_TMPDIR/pr-diff.patch"
```

Read the PR title, description, base branch, and changed file list from the
metadata. Show the user a brief summary before proceeding:

```text
Comparative review: PR #47 — "feat(27): backpressure pipeline"
Base: develop 
- location: 
- title: 
- description: 
- suggested_fix: 

At the end, give an overall verdict: Approved or Request Changes.

[contents of "$CROSS_REVIEW_TMPDIR/pr-diff.patch"]

```

Run via the appropriate CLI for the reviewer LLM:

```bash
PROMPT_FILE=$(mktemp "$CROSS_REVIEW_TMPDIR/reviewer-a-prompt-XXXXXX")
OUTPUT_FILE=$(mktemp "$CROSS_REVIEW_TMPDIR/reviewer-a-result-XXXXXX")

# Write assembled prompt to PROMPT_FILE

# If reviewer is codex:
codex exec -s read-only --ephemeral -o "$OUTPUT_FILE" -  "$OUTPUT_FILE" 2>&1

# If reviewer is claude and you are NOT Claude:
claude -p "Follow the instructions provided on stdin." \
  --verbose \
  --output-format stream-json \
  --include-partial-messages \
   "$OUTPUT_FILE" 2>&1
```

Use a generous wait budget for external reviewer CLIs, but do not treat a
long-running process as hung merely because it is slow or quiet. Monitor
progress before deciding what to do:

```bash
ps -o pid=,etime=,pcpu=,state=,command= -p "$REVIEWER_PID"
wc -c "$OUTPUT_FILE"
tail -n 40 "$OUTPUT_FILE"
```

If output size is increasing, tool-use events are appearing, CPU is non-zero, or
the process is otherwise doing work, keep waiting and tell the user what
progress you see. If progress is ambiguous, ask the user whether to keep waiting
or stop and include elapsed time, output-file size, recent output summary,
process state, and what result would be lost by stopping. Only kill an external
reviewer without asking when it has clearly exited badly, is an obvious orphan,
or the user explicitly instructs you to stop it.

Parse the output into the same structured findings format.
If Reviewer A fails because the CLI is unavailable, auth is broken, or the
process exits badly, stop the comparative workflow and report the failure. Do
not synthesize a comparative report from only one completed review.

### Step 5: Reviewer B Independent Review

Run the second independent review using whichever LLM is selected via `--to`.
Apply the **self-awareness rule** exactly as in Step 4.

Reviewer B must not receive Reviewer A's findings. Give it the same PR
metadata, project conventions, focus, and diff, but no prior findings.
This preserves independence and avoids anchoring.

Use the same output schema as Step 4:

- severity: Critical / Improvement / Nitpick
- file: 
- location: 
- title: 
- description: 
- suggested_fix: 
- overall verdict: Approved or Request Changes

Use a distinct prompt/output path so the two reviews do not overwrite each
other:

```bash
PROMPT_FILE=$(mktemp "$CROSS_REVIEW_TMPDIR/reviewer-b-prompt-XXXXXX")
OUTPUT_FILE=$(mktemp "$CROSS_REVIEW_TMPDIR/reviewer-b-result-XXXXXX")
```

Monitor external CLIs with the same slow-is-not-hung rule from Step 4. If
Reviewer B fails because the CLI is unavailable, auth is broken, or the process
exits badly, present Reviewer A's review with a clear note that the comparative
layer could not be completed. Do not fabricate a second review.

### Step 6: Reviewer A Validates Reviewer B Findings

After both independent reviews are complete, have Reviewer A evaluate Reviewer
B's findings against the PR diff. This is one-way only: do not ask Reviewer B
to evaluate Reviewer A's findings.

- If Reviewer A is YOU, evaluate Reviewer B's findings inline.
- If Reviewer A is external, send Reviewer B's findings plus the PR diff back
  to Reviewer A, along with Reviewer A's independent review for context. Do
  not ask it to redo the full independent review.

Validation prompt:

```markdown
## Task: Validate Reviewer B's Findings

You previously produced the independent review included below. Use it as
context, but do not redo the full review. Now evaluate Reviewer B's findings
against the PR diff. For EACH Reviewer B finding, give your verdict:

- **CONFIRMED**: You agree this is a real issue. Briefly explain why.
- **FALSE_POSITIVE**: You believe this is not actually an issue. Explain why.
- **UNCERTAIN**: You can see arguments both ways. Explain the ambiguity.

[Structured review previously produced by Reviewer A]

[Structured list of Reviewer B findings, each with severity, file, location,
title, description, and suggested_fix]

[contents of "$CROSS_REVIEW_TMPDIR/pr-diff.patch"]

### Validation Output Format

For each Reviewer B finding:
- finding: 
- verdict: CONFIRMED / FALSE_POSITIVE / UNCERTAIN
- reasoning: 
```

Use a distinct prompt/output path:

```bash
PROMPT_FILE=$(mktemp "$CROSS_REVIEW_TMPDIR/validation-a-checks-b-prompt-XXXXXX")
OUTPUT_FILE=$(mktemp "$CROSS_REVIEW_TMPDIR/validation-a-checks-b-result-XXXXXX")
```

Run external validation through the same CLI command pattern and monitoring
rules used for independent reviews in Step 4.

If Reviewer A validation fails, keep both independent reviews and label
Reviewer B-only findings as not checked by Reviewer A.

### Step 7: Synthesize Unified Report

Read both independent reviews and Reviewer A's validation of Reviewer B's
findings. Build the unified report by cross-referencing findings semantically.

Categorize every finding into one of five buckets:

| Category | Meaning |
|----------|---------|
| **Found by both** | Both models found the same logical issue independently |
| **Reviewer A only** | Reviewer A found it; Reviewer B did not mention the same issue |
| **Reviewer B only, confirmed by A** | Reviewer B found it; Reviewer A did not find it independently but agrees it is real |
| **Reviewer B only, challenged by A** | Reviewer B found it; Reviewer A says it is false positive or uncertain |
| **Conflicting or debatable** | The reviews directly disagree, or one finding depends on an ambiguous requirement |

**Matching logic**: Two findings match if they reference the same file AND the
same logical issue, even if described differently. Use semantic matching, not
string equality.

Treat overlap and A-confirmed B-only findings as stronger evidence. Reviewer
A-only findings are not checked by Reviewer B in this simplified flow, so
present them without claiming cross-model confirmation.

### Step 8: Present The Report

Display the unified report to the user:

```markdown
# Comparative Review: PR #47

**Reviewer A**: [claude/codex/opencode]
**Reviewer B**: [claude/codex/opencode]
**Reviewer A verdict**: [Approved / Request Changes]
**Reviewer B verdict**: [Approved / Request Changes]
**Agreement**: [N found by both, A-only count, B-only confirmed by A count, B-only challenged/uncertain count]

## Found By Both Reviewers

[For each overlapping finding:]
### [severity] [title]
**File**: [path]:[line]
**Reviewer A**: [description]
**Reviewer B**: [description]
**Suggested fix**: [best suggestion from either model]

## Reviewer A-Only Findings

[For each A-only finding:]
### [severity] [title]
**File**: [path]:[line]
**Description**: [finding]

## Reviewer B Findings Checked By Reviewer A

[For each B-only finding:]
### [severity] [title]
**File**: [path]:[line]
**Reviewer B**: [finding]
**Reviewer A verdict**: [CONFIRMED / FALSE_POSITIVE / UNCERTAIN / not checked]
**Reviewer A reasoning**: [reasoning when available]

## Conflicting Or Debatable Findings

[For findings where the two reviews directly disagree or depend on ambiguous requirements.]

## Summary

[Narrative combining both perspectives. Highlight overlap, Reviewer A-only
coverage, Reviewer B findings checked by Reviewer A, and findings needing
human judgment before acting.]
```

### Step 9: Regression Tests For Fixes

When the user asks to fix reported issues after the review, every bug fix
must include a regression test that would have caught the original bug.
This is non-negotiable; a fix without a test is incomplete.

For each fix, add a test that:
1. Reproduces the invalid input or bad state that triggered the bug
2. Asserts the corrected behavior
3. Lives alongside the existing tests for that module

Present a summary of added tests in the report so the user can verify coverage.

### Step 10: Optional Post As PR Comment

If `--post` flag was provided, ask the user to confirm before posting:

```text
Post this report as a comment on PR #47? (yes/no)
```

If confirmed:

```bash
gh pr comment "$PR_NUM" --body-file /tmp/cross-review-report.md
```

### Step 11: Clean Up

```bash
rm -rf "$CROSS_REVIEW_TMPDIR"
```

Switch back to the previous branch:

```bash
git checkout - 2>/dev/null || true
```

## Deep Mode

Activated by `--deep` or by a request for a deep, multi-area, or
parallel-agent review. Deep mode means symmetric focused parallel reviewer
fanout: for each decomposed area, run Reviewer A and Reviewer B independently
on the same scope, then have Reviewer A validate Reviewer B's findings for
that area. It is not one longer inline pass, one fanned-out model plus one
whole-PR pass, or Reviewer B validating Reviewer A.

Read `references/deep-mode.md` before running deep mode. If the current
harness cannot launch parallel agents, say that strict deep mode is unavailable
and clearly label any fallback as a normal comparative review.

## Error Handling

| Failure | Recovery |
|---------|----------|
| `gh` not installed | Tell user to install GitHub CLI |
| PR not found | Check PR number/URL and repo |
| `--from` and `--to` are the same | Error: the two reviewers must be different LLMs |
| External LLM not installed | If an independent review cannot run, stop and report that comparative review is unavailable. If Reviewer A validation of Reviewer B fails after both reviews complete, present both reviews and label B-only findings as not checked by A. |
| External LLM appears slow | Monitor process/output. If progressing, keep waiting. If ambiguous, ask the user whether to wait or stop with elapsed time, output size, recent output summary, and process state. Applies to Claude Code, Codex, and OpenCode. |
| External LLM timeout with no progress | Ask the user before killing unless the process clearly failed or they already instructed you to stop. If stopped, present partial output only if clearly marked incomplete. |
| External LLM auth error | Tell user to check auth config for the selected provider |
| Diff too large (>3000 lines) | Warn the user and suggest `--focus`; above 5000 lines, split by file groups and run sequentially |
| Dirty working tree before PR checkout | Stop before checkout if user changes could be disturbed; ask how to proceed |

## Tips

- The comparative approach is most valuable for critical PRs (security changes,
  core infrastructure, public API changes) where false positives are costly
  and missed bugs are dangerous.
- For routine PRs, a single-model review (just `code-reviewer`) is faster
  and usually sufficient.
- Different models excel at different things: Claude tends to catch architectural
  issues and convention violations; Codex often catches edge cases and
  off-by-one errors. Together they cover more ground.
- Running `--from codex --to claude` starts with Codex

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [wnz99](https://github.com/wnz99)
- **Source:** [wnz99/llm-dev-skills](https://github.com/wnz99/llm-dev-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** yes
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-wnz99-claude-skills-cross-review-pr
- Seller: https://agentstack.voostack.com/s/wnz99
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
