| name | perps-review-pr |
| description | Pre-flight self-review gate for perps PRs. A perps dev runs it on their OWN PR to drive a looping double-agentic cross-review — two different model CLIs (Claude, Codex, Cursor) review independently because each catches different issues — until all APPROVE the same commit with zero findings. Reviewers are deliberately strict: every perps anti-pattern and every nit is a blocker. Loops fix → re-review until the PR meets perps standard, then says it is ready for an external human reviewer. Use for "review my perps PR", "cross review my perps branch", "is my perps PR ready", or self-review before requesting review. Self-gate: does not push, merge, or open the PR. |
| maturity | stable |
Review Perps PR — Cross-Review Self-Gate
Perps dev runs this on their OWN PR before requesting a human reviewer. Drives a looping
double-agentic cross-review: ≥2 different model CLIs review independently (each catches a
different bug class), you fix, re-review, until all APPROVE the same SHA with zero
findings. Self-gate: never pushes, merges, or opens the PR.
Reviewer bar
Every perps anti-pattern AND every nit = BLOCKER. APPROVE only at zero findings.
"APPROVE with N nits" is a FAIL — forward them as work. Require ≥2 distinct providers; one
alone is advisory, not a passed gate.
Step 0 — ask first (use AskUserQuestion), if not already given
- Target — branch/PR (default: current branch)
- Reviewers —
claude,codex (default) / claude,cursor / all three (min 2)
- Autonomy — auto-fix+loop (default) / per-round approval / advisory (dev fixes)
- Rounds — default 3, cap 5
Echo the resolved contract in one line, then loop.
Reviewer CLIs — install all (company allows it; each finds different bugs)
| CLI | one-shot review | install |
|---|
| Claude | claude -p "<prompt>" | npm i -g @anthropic-ai/claude-code |
| Codex | codex exec "<prompt>" | npm i -g @openai/codex |
| Cursor | cursor-agent --print --mode ask --output-format text --workspace <wt> "<prompt>" | curl https://cursor.com/install -fsSL | bash, then cursor-agent login |
Missing a CLI → recommend installing it; don't silently drop to one reviewer. For a long
loop, run each CLI as a live tmux pane instead of one-shot, and /clear between rounds.
Safety (env rules — bypass agents ignore prompt-level "read-only"; this broke a repo once)
- Reviewers run in an isolated read-only worktree pinned at the SHA, never the live
checkout:
git worktree add /tmp/perps-review-<sha> <sha>. A reviewer git checkout on
the live tree detaches HEAD and orphans your fix commits.
- Fixes are local commits only — never push. This skill pushes/merges/opens nothing.
- After every round:
git symbolic-ref -q HEAD must show the branch (not detached) and the
branch must point at the latest fix SHA — else STOP and report.
Perps standard (reviewers must load and enforce as blockers)
From the installed knowledge/ dir: review-antipatterns (core checklist), architecture,
connection-architecture, caching-architecture, formatting-rules, mobile-extension-map,
shared-package-analysis, feature-flags, screens. Check both repos when a shared util/screen
changes. For page/view test changes, also enforce the component-view test guidance: broad
rendered UI behavior tests belong in the component-view framework/skill unless a focused unit
test is explicitly justified.
Reviewer prompt (force a fresh full review every round)
Fresh full review of perps changes in <PR/branch> at <SHA> vs <base>. No prior context.
Load installed perps knowledge (`knowledge/`, review-antipatterns + the rest). You gate this before any human sees it.
Every perps anti-pattern AND every nit (naming, magic number, missing testID, weak test,
component-view behavior left as broad unit tests, .toFixed, fallback-display vs 0) = BLOCKER.
APPROVE only if nothing is left to improve.
Return:
VERDICT: APPROVE | REQUEST_CHANGES
COMMIT: <sha>
BLOCKERS: - <file:line> — <issue> — <fix>
NITS: - ... (any entry ⇒ VERDICT must be REQUEST_CHANGES)
EVIDENCE: - <files/commands inspected>
Reviewers run independently — don't show one's findings to another until both have a verdict.
Loop
- Capture HEAD SHA; make the read-only worktree at it.
- Run all reviewers independently on that SHA.
- Any non-empty BLOCKERS/NITS from any reviewer = work (even on APPROVE).
- All APPROVE, zero findings, same SHA, validation green → Exit GREEN.
- Else consolidate findings (reviewer, file:line, fix). Per autonomy: auto-fix / ask dev / hand off.
- Fix as local commits → run validation → new SHA → verify branch state → reset reviewers → repeat.
Validation each round (show results; no "fixed" without proof)
Lint + typecheck + jest on touched perps paths. If app/controllers/perps/ changed:
scripts/perps/validate-core-sync.sh (controller must stay platform-agnostic for the
@metamask/perps-controller publish).
Pause / escalate
Round cap hit with findings open · reviewers disagree on product/scope · same blocker
survives a round · a fix expands scope · HEAD detached or branch lags · only one provider
available.
Exit
GREEN — report approved SHA, all reviewers APPROVE / 0 findings, validation pass, round
count, branch on-track and unpushed → "ready to request an external human reviewer" (this
skill pushed nothing). Not green — list open findings, current SHA, and what the dev must
decide or do. Don't claim ready.