Panel Review — Skills as Review Lenses
Review one diff through N lenses, where every lens is an installed skill and every lens runs as its own sub-agent with an isolated context. The orchestrator composes the roster, fans the lens nodes out, adversarially verifies every finding against the actual code, and synthesizes one severity-ranked report. No lens is hardcoded: the defaults are conventions, the roster is yours.
The target is any change boundary, at any phase: uncommitted work-in-progress, the current branch's accumulated diff, one stacked layer, or an actual pull request. A PR is one kind of target, not a precondition — reviewing before the PR exists is a first-class use. The PR-readiness evidence gate is a lens you get when the boundary is heading to a PR, not a gate on running the review.
This skill is an instance of graph-engineering — load that skill for the generic node/topology/runtime machinery. This file owns what is review-specific: the invocation grammar, the lens registry, the PR-readiness gate, and the report.
| Reference | Read when... |
|---|---|
references/lenses.md |
Composing the roster — default lenses, auto-detection signals, lens brief template |
../graph-engineering/references/model-policy.md |
Choosing capability tiers, applying provider mappings and budgets, and recording actual runtime usage |
references/pr-readiness.md |
Judging change-path evidence — TDD/refactor/reduction classification, the mutation-evidence freshness model, the verification gate |
references/workflow-template.md |
Executing the graph — the concrete dynamic-workflow script and Agent-tool fallback |
Invocation Grammar
/panel-review [target] [modifiers] [lens...]
| Token | Meaning |
|---|---|
| (nothing) | Review the current branch's work — its diff against the merge-base with the default branch, plus uncommitted changes; default + auto-detected lenses |
wip |
Review only the uncommitted changes (working tree + staged) against HEAD — the mid-development check |
#123 or a PR URL |
Review that GitHub PR (gh pr diff / gh pr view) |
hexagonal-architecture (any installed skill name) |
Add that skill as a lens |
only <names...> |
Use exactly the named lenses — no defaults, no auto-detection |
-<name> |
Remove a lens from the roster (e.g. -functional) |
thorough |
Widen the roster (include all detected conditional lenses) and use multi-vote adversarial verification |
post |
After review, post the report to the GitHub PR (requires a PR target) |
Examples: /panel-review · /panel-review #482 thorough · /panel-review hexagonal-architecture domain-driven-design structure-codebase · /panel-review only xstate react-testing · /panel-review -testing post
Unknown tokens that don't match an installed skill: say so and list near-matches; don't guess.
Workflow
1. Resolve the target diff
- PR target:
gh pr view <n> --json title,body,baseRefName,files,additions,deletionsandgh pr diff <n>. - Branch target: diff against the merge base —
git diff $(git merge-base <default-branch> HEAD)...HEADplus uncommitted changes if present (say whether they're included). wiptarget:git diff HEAD— the uncommitted working-tree and staged changes only.- Stacked boundary: when reliable stack metadata identifies the branch as stacked, review
git diff <immediate-parent>...HEAD, not the cumulative trunk diff.
No target needs to be a PR. The review runs identically at any phase; only the readiness lens cares whether the boundary claims PR readiness (see references/lenses.md).
STOP and report instead of reviewing when the diff is empty or the target can't be resolved.
2. Scout inline
A few cheap tool calls, no sub-agents: categorize changed files (production / test / config / docs), read the project's CLAUDE.md and key configs for traits, and collect the signals references/lenses.md needs for auto-detection. The scout also captures the change's own claim (PR title/body, plan slice, commit messages, or the user's stated intent for in-progress work) — the review judges the diff against its claim.
3. Compose the roster
Per references/lenses.md: built-in lenses (readiness, quality) + core defaults + auto-detected conditional lenses, then apply the user's only/add/remove tokens. Show the final roster and rough scale (N lens nodes + verification) in one line before launching; for large rosters (>8 nodes) confirm with the user first unless they said thorough.
4. Run the graph
Execute per graph-engineering runtimes — the Workflow tool with references/workflow-template.md when available, Agent-tool fan-out otherwise, sequential degraded mode as the labelled last resort. Load the model policy before dispatch: ordinary lenses and verification use balanced, mechanical work may use economical, and higher tiers require their named gates. Apply the mapped model, effort, and remaining budget where possible, and return the execution ledger with the report. Every lens node loads exactly one skill, receives the diff scope and the sibling-lens list (to keep boundaries disjoint), reads surrounding code as needed, and returns schema-shaped findings with file:line evidence. Lens nodes are read-only.
5. Verify and synthesize
Per graph-engineering: dedup by file/line/claim (multi-lens agreement is signal — note it), adversarially verify every surviving finding with an independent node mandated to refute, keep unverifiable distinct from refuted, and surface cross-lens conflicts with both arguments instead of silently picking a winner.
6. Report
## Review: <target> — <one-line claim>
**Roster:** <lenses run> · **Scale:** <N nodes, M findings verified> · **Runtime:** <workflow | agent fan-out | sequential (degraded)>
| Lens | Verdict | Confirmed findings |
|------|---------|--------------------|
| readiness *(PR-bound targets only)* | ✅/❌/⚠️ | n |
| <skill lens> | ✅/❌/⚠️ | n |
**Recommendation:** APPROVE / REQUEST CHANGES / NEEDS DISCUSSION
### Confirmed findings (ranked)
🔴/⚠️/💡 **[lens] title** — `file:line`
Problem · Why it matters · Suggested fix (with copy-pasteable fix_prompt)
### Conflicts between lenses ← only when present, both arguments
### Unverifiable claims ← reported, never silently dropped
### Clean ← what was inspected and found sound
### Not covered ← lenses not run, scopes not assessable, node failures
Recommendation rules: any confirmed critical → REQUEST CHANGES; unresolved lens conflict or failed readiness gate → NEEDS DISCUSSION; otherwise APPROVE with the minors listed.
7. Post (only when asked)
With the post token and a PR target: write the report to a scratch file and post it with gh pr comment <number> --body-file <file> (or a formal gh pr review --comment/--request-changes --body-file <file>), headed ## 🤖 /panel-review with the roster named — never interpolate the report body through shell arguments. Never post without the explicit token; never use --approve on the user's behalf.
Boundaries
- During development, use the focused agents (
tdd-guardian,ts-enforcer,refactor-scan) — this skill is the whole-boundary review at the end. double-checkanswers a different question. This skill is breadth through your own standards: many same-provider sub-agents, each applying one of your installed skills to the diff, findings verified and merged into one report — wide coverage, but every node shares the host model's blind spots.double-checkis independence: one strong reviewer, preferably from a different provider, starting cold with no inherited context, checking scope fidelity against the original requirements and arguing findings across rounds until genuine convergence. Fan out with/panel-reviewfor coverage; bring indouble-checkwhen the risk is that you (and every sub-agent you spawn) are wrong the same way — high stakes, contested calls, or a final independent gate before shipping. They compose:/panel-reviewfirst,double-checklast./code-review(built-in) runs Anthropic's fixed issue-class lenses; this skill exists precisely to compose your skills instead.- The review reads the target repository's own conventions (its CLAUDE.md, glossary, ADRs) as part of the scout; a lens finding that contradicts an explicit local convention is reported as a conflict, not enforced.
Completion Check
- Was the roster composed (defaults + detection + user tokens) and shown before launch?
- Did every lens node load its one skill and stay inside its boundary?
- Did every reported finding survive independent adversarial verification, with
file:lineevidence? - Are conflicts, unverifiable claims, clean areas, and coverage gaps all explicit in the report?
- When the readiness lens ran, does its verdict follow
references/pr-readiness.md, including the mutation-evidence freshness model — and when it was skipped for a mid-development target, is that listed under "Not covered"? - Did every node receive a policy tier, and does the report distinguish the requested model/effort/budget from what the runtime actually applied?
- Was anything posted to GitHub only with the explicit
posttoken?