Reviewer lane of the super-board pipeline and standalone PR/branch readiness review — forms its own hypotheses before reading the builder's summary, remembers prior findings and re-checks each with file:line proof, runs an adversarial truth-check on non-trivial diffs, and classes every finding (Gap, Bug, Verification miss, Scope drift, Over-engineering via `ponytail:ponytail-review`). Merges only through `super-board-merge-gate.sh`, pinned to the reviewed head SHA, and routes other fixes to Super Build or Super QA via the board. Use when the user says "Super Review", "review this branch", "review loop", "make sure this is merge-ready", "PR review", or asks for code, architecture, security, QA evidence, or release-readiness judgment.
npx skills add https://github.com/EricTechPro/super-board --skill super-review
Super Review is the super-board reviewer. It checks whether a branch or PR is safe to merge, records actionable findings, and routes fixes to the right Super workflow.
Super Review should be conservative with claims: only say merge-ready when review evidence is clean and verification has passed. If evidence is missing, say what is unverified.
Use this skill for:
/ui-refine-loop pass.super-board run.Do not use this as the primary implementation workflow. Route fixes to:
Ready issues./ui-refine-loop. The board never triggers it.Accept any of these inputs:
prior_report — the previous review's findings on this PR (see "Review remembers"). Empty on a first review.If the input is ambiguous, default to reviewing the current branch against its upstream/base branch. Ask only when the base branch, PR, or target scope materially changes the result.
prior_report. If one exists, run round 1 of "Review remembers" before step 2.[builder] [report] comment, Testerhandoff), read the issue's acceptance criteria and the raw diff, and write down 2–4
hypotheses: what must be true for this to be right, and where it would most likely
break. Reading their summary first anchors you on their framing; the point of a
reviewer is a second, independent solver.
way you check your own hypotheses. A claim is a lead, not evidence.
mattpocock-skills:codebase-design and read the diff through its vocabulary— module, interface, depth, seam, adapter, leverage,
locality. Ask the shape question the diff raises: does this land behind a
small interface, or does it widen one? Apply the deletion test to anything the
diff adds that looks shallow.
is not this PR's problem.
CLAUDE.md / AGENTS.md, especially:clock.now() instead of new Date();numeric(12,2);date, not timestamptz;AppError({ error_code, context });severity (does it block). Class:
(missing test, test asserts the wrong thing, skipped rerun).
stated constraint.
dependency, abstraction, config or file where the codebase, stdlib, a native feature
or one line already covered it. Find these with ponytail:ponytail-review on the
merge-base diff (git merge-base HEAD origin/<base>); plugin not installed → ask the
ponytail ladder of each addition yourself: needed at all? already in the codebase?
stdlib? native? an installed dep? one line? Always Should fix, routed to
Super Build — it never blocks a merge on its own. A simplification that would
cut validation, security, data-loss protection or accessibility is not a finding.
on the report's ✅ Done line with the file:line or command that showed it. Saying what is
right stops the next round re-litigating it.
Severity:
seam in the wrong place, or behaviour spread across call sites. **This never
blocks a merge.** A green PR does not get held for architecture taste — file it
and merge. See "Deepening opportunities" below.
/ui-refine-loop (the board never triggers it).scripts/super-review-file-refactor.sh and carry on to the merge decision. Do not open a PR thread for it; do not bounce the card.The --body-file uses the ticket format (writing-standard.md § 3): ## Problem,
## Context (- Where: the module and files), ## Fix — the filer refuses a body
without them. Write real acceptance criteria too. A card that carries an
## Acceptance Criteria checklist is filed straight into Ready and the next wave builds it;
one without lands in the holding column and waits for super-board lint. That is the whole
difference between a finding that gets fixed this week and a note nobody grades. Two or three
checkable lines is enough — what must be true when this is done, in terms a test can assert.
The filer appends ## Risk and ## Blocked by for you when you have not written them.
merge-ready, blocked, human-gated, or unverified.The report follows writing-standard.md § 4: a comment header, ≤ 8 lines, then one findings
table. In a super-board run it is ONE PR comment, edited in place every round (see "Review
remembers"); R-ids never change.
<!-- super-review:report -->
[reviewer] [report] <✅ merge-ready | ❌ bounced | 🛑 blocked | 🙋 human-gated | ⚠️ unverified> · round <N>
Did: <scope reviewed · base · verification command + result>
✅ Done: <prior findings fixed, hypotheses that held — each with file:line or command>
❌ Not done: <open findings by id, or what you could not verify and why> (omit when nothing)
Next: <builder | qa | Eric | none>
| ID | Owner | Class | Where | Finding | Status |
|---|---|---|---|---|---|
| R1 | builder | Bug | `src/cart.py:12` | <finding> | ✅ fixed |
| R2 | builder | Bug | `src/cart.py:31` | <finding> | ❌ not fixed |
| R3 | qa | Verification miss | `tests/test_cart.py:8` | <finding> · blocker | open |
| R4 | builder | Over-engineering | `src/fmt.py:1` | <what it builds> → <smaller thing> · should fix, never blocks alone | open |
builder (Super Build) · qa (Super QA) · ui (UI ticket; a human runs/ui-refine-loop) · Eric (human gate).
blocker or should fix in the Finding cell. Over-engineering is always should fix.super-review-file-refactor.sh get a row with Statusfiled #<issue>.
🙋 human-gated and Next: Eric; the decision goes in a row.For short summaries (wave reports), keep it phone-friendly:
[reviewer] [report] 🛑 blocked · PR #123
Did: `npm test -- --run imports` green
❌ Not done: R1 functional bug → qa · R2 schema decision → Eric
Next: qa
In a super-board run the loop runs through the board:
[builder], [qa]) and the card bounces to the owning lane — Super Build or Super QA; for visual polish, file a UI ticket; a human can run /ui-refine-loop.prior_report — round 1 checks those findings before any fresh pass.scripts/super-board-merge-gate.sh, pinned to the head SHA it reviewed.Super Review should not silently push fixes during the loop unless the user explicitly grants that authority.
A re-review starts from the last one. Without it, a rebuilt card gets a fresh reviewer who
re-litigates settled points, misses that a finding was "resolved" without a fix, and can
bounce forever on a moving target.
Lookup — one call, by marker. Every report starts with <!-- super-review:report -->.
prior_report is the newest PR comment carrying it:
gh pr view <PR> --json comments \
--jq '[.comments[] | select(.body | contains("<!-- super-review:report -->"))] | last | {url, body} // {}'
The number after #issuecomment- in url is the comment id. Write this round's report over it:
gh api -X PATCH repos/<owner>/<repo>/issues/comments/<id> -F [email protected]. One report per
PR, edited in place, so the table carries every round's status.
Outside super-board (no PR), prior_report is whatever earlier review the caller hands you.
No prior report → first review. Behave exactly as before.
Round 1 — check each prior finding before anything else. Mark every one:
fixed — cite the file:line that shows it.not fixed — still true of the code. A resolved thread is not evidence, and neither isthe builder's reply saying it was fixed; read the code.
no longer applies — the code it pointed at is gone, or the AC changed. Do not re-raise it.Any not fixed (other than Over-engineering, which never bounces alone) → bounce again: set those rows to ❌ not fixed, keeping their
original ids and owners. Skip the fresh pass; it would review code that is about to change.
All clear → round 2 is the normal fresh pass. New findings take ids after the highest one used.
prior_report — that is how a finding gets "resolved" without a fix and slips through.Super Review is done when one of these is true:
The reviewer loads three skills, all scoped to the diff:
mattpocock-skills:code-review — the two-axis review. Standards (does the difffollow this repo's documented standards, plus the Fowler smell baseline) and Spec
(does it implement the originating issue's acceptance criteria). Always pass the fixed
point explicitly — git merge-base HEAD origin/<base> — so it never stops to ask for
one. A Spec-axis finding that contradicts the AC is a Blocker, not a nit.
mattpocock-skills:codebase-design — the deep-module vocabulary used in step 2 and inevery deepening opportunity written below. It is vocabulary, not a workflow: no report,
no prompts, nothing to wait on.
ponytail:ponytail-review — the Over-engineering pass in step 3, on the merge-basediff. Optional plugin: when it is not installed, use the inline ladder in step 3.
Its findings are Should fix at most; it never decides merge-or-bounce.
Never load inside the lane: mattpocock-skills:improve-codebase-architecture. It
scans the whole codebase rather than the diff, writes a Tailwind/Mermaid HTML report and
shells out to open, then asks the user which candidate to explore and hands off to
grilling. Every one of those is fatal to an unattended reviewer. It is a
you-at-the-keyboard tool — run it yourself against the cards this lane files.
Architecture taste is real, and it is not a merge gate. The reviewer's job is
merge-or-bounce; a shallow module in an otherwise-correct diff is a future ticket,
not a reason to hold a green PR hostage.
diff is correct + tests green + threads clean
│
├─→ merge protocol ← the gate
│
└─→ shape friction noticed in the diff
│
└─→ super-review-file-refactor.sh
label: refactor · column: Backlog
→ you run improve-codebase-architecture
against it later, at a desk
File one when the diff leaves a module whose **interface is nearly as complex as its
implementation, puts a seam** somewhere a caller has to work around, or spreads
behaviour across call sites so a future fix has no locality. Use the
codebase-design glossary terms exactly — a card that says "this feels messy" is a card
nobody can action.
Do not file one for: style, naming a future refactor might rename anyway, anything an
existing ADR in docs/adr/ already settled, or a shape the issue's acceptance criteria
explicitly asked for. The script dedupes by fingerprint, so re-reviewing a bounced card
will not stack duplicates.
When invoked by super-board (env SUPER_BOARD_RUN=1 or invocation contains "super-board run"):
.claude/bin/super-board-card.sh --config <cfg> move <N> <Status> (1 GraphQL point; gh project item-list / field-list cost ~100–200). Comments, labels and PR reads go over REST; rate-limit-etiquette.md → "Price list" has the calls..claude/worktrees/issue-<N>-review/ and branch issue-<N>-<slug>.feature, bug, no label): review the diff (code + tests).qa card: review the QA report quality and any test diff; there is no product-code diff.See .claude/skills/super-board/references/run.md → Reviewer. Summary of the sub-steps:
issue-<N>-<slug>.alone are explanations, not findings or approval. Human questions or change requests
in those threads still follow the normal review/blocking flow; the marker exempts no
replies. Never auto-resolve them or bypass GitHub's conversation-resolution requirements.
If ANY unresolved finding:
[builder] open → comment, move card Review → Ready.[qa] open → comment, move card Review → QA.3b. Prior-report check — load prior_report (see "Review remembers"); if present, round 1 checks each prior finding; any not fixed → re-open its thread, bounce by prefix, post the report, exit.
issue-<N>-<slug> into review worktree.Local tests: line.[qa]-prefixed thread quoting failure, move card Review → QA with loop:rebuild-N, exit.config.truth_gate — off / non-trivial / always, default non-trivial): see section below.yours, ponytail:ponytail-review's and the truth-check sub-agents': Over-engineering is
Should fix, never Blocker, and never on its own a reason to bounce or block. Then:
scripts/super-review-file-refactor.sh, then keep going. It is not a finding for merge purposes and never bounces a card.ponytail:ponytail-review, see super-review step 3) → list it in the report, open no thread, and carry on to the merge decision; it never bounces a card alone. When the card bounces for another finding anyway, open a [builder] thread for each Over-engineering finding too, so the rebuild trims it.[builder]-prefixed thread, move card Review → Ready (loop:rebuild-N).[qa]-prefixed thread, move card Review → QA (loop:rebuild-N).merge_policy hands it to a human (exit 7 → 🙋 Blocked).<!-- super-review:report -->, ids on every finding) — edit the existing report comment in place, post a new one only on the first review. It is the next re-review's prior_report.Builder opens PRs as drafts, and GitHub never auto-merges a draft. Skipping the
gh pr ready step is why a six-hour run landed zero commits on main while producing
two complete builds. In order, no shortcuts:
gh pr ready <PR> — idempotent, safe on an already-ready PR.merge_policy.default: "human"keeps a person on every merge — the gate returns exit 7 below):
record gh pr view <PR> --json headRefOid when review passes, then
`super-board-merge-gate.sh --config <cfg> --pr <PR> --expect-head <sha> --subject "<PR title>"
--body-file <msg.md> (it merges with --match-head-commit`; the message is the PR title plus the
commit bullets and Closes #N — writing-standard.md § 1). Exit 6 = the head moved after review → your evidence is void;
leave the card in Review with a [reviewer] comment naming both shas.
The gate owns the merge decision (config merge_policy, migrations):
merge_policy matched (money / auth / schema label,path or added-line keyword; a diff over auto_max_lines, default 400 — "big PR — please
review"; default: "human"). schema means destructive only (DROP / TRUNCATE / RENAME);
an additive migration follows migrations.allowed_envs, and a live DB is always human.
Card → Blocked with the 🙋 template: Why blocked quotes the gate's
human-gate: lines; To unblock = review PR #<P> and merge it yourself, OR comment
done to approve (the next wave re-runs the gate, which merges). Label needs-you.
migrations.allowed_envs, an allowed migrate command that failed, or a declared
human-only step. Card → Blocked with the 🙋 template
(block-template.md → "🙋 Needs you"), the gate's needs-you: commands copied
verbatim into To unblock, label needs-you, blocked-by: -. After the human
comments done after the current pinned request, the next wave verifies their
permission and the head, then moves it to Review. Re-run the gate; labels do not
authorize it. For exits 7 and 8, copy approval-request: into the canonical
issue block and link it from the PR (no duplicate request); see block-template.md.
work; live databases, money, auth and destructive schema changes wait for a person.
Exit 79 — required GitHub evidence unavailable: stop the current run. Leave
the card, approval, claims, and worktree intact. Report the local halt reason;
do not classify missing data as safe, bounce it to Build, or post a new approval
request. Explicit recovery is in run-workflow.md → Required GitHub evidence.
gh pr view <PR> --json state,mergeCommit must report MERGED plus a commit sha,
and that sha must be an ancestor of the base branch
(git merge-base --is-ancestor <sha> origin/<base>).
the merge commit sha.
Blocked with the §4 Block template naming the blocker. Never leave it in Review;
a card left in Review gets re-picked and re-reviewed indefinitely.
Invariant: a card in Done has its code on the base branch. The run loop's
landed-work halt gate reads Done as its definition of progress, so a card marked Done
without a confirmed merge makes a runaway look like a healthy run.
[builder], [qa], or [reviewer] — then a label: [blocker], [issue], [suggestion], [nit], [question], [praise] (writing-standard.md § 4). Older PRs may carry [QA] / [review]; read them as [qa] / [reviewer].super-truth is folded into super-reviewThe standalone super-truth skill is removed (spec §10 item 8.9). The adversarial pattern is now built in — see next section.
Activated per config.truth_gate:
off — never adversarial.non-trivial (default) — diff ≥10 lines OR labels in {security, migration, payments, auth} trigger adversarial.always — every card.When activated, spawn 2 sub-agents in parallel:
git blame the changed lines; check for ADRs / prior incidents.Use this brief verbatim. Fill the <…> slots; do not reword, add or drop lines. A
reviewer that wrote its own brief once told the sub-agents over-engineering was blocking,
and a correct PR was held for it.
You are the <Code-grounder | Historian> in an adversarial truth-check of PR #<P>.
Job: <Code-grounder: verify every file:line the PR cites still exists and does what the PR
claims. | Historian: git blame the changed lines; look for ADRs, prior incidents, reverted
attempts.>
Read the issue ACs and the diff first and form your own hypotheses. Only then read the
builder's summary below, as claims to check, not as the frame.
ACs: <paste>
Diff: <merge-base diff or path to it>
Builder's summary (claims): <paste>
Budget: at most 50 gh calls; prefer local git. Over budget: confidence "insufficient_data".
Class every finding: Gap / Bug / Verification miss / Scope drift / Over-engineering / No issue.
Severity: Blocker / Should fix / Nit.
Over-engineering is ALWAYS Should fix and NEVER Blocker on its own. It does not lower your
confidence score.
Confidence 0-100 = how sure you are the PR's claims are true and the code does what the ACs
ask. Design taste and over-building do not count against it.
Return: findings (class, severity, file:line, one line each) and confidence.
After collecting, the Reviewer re-applies the rules itself. Whatever a sub-agent wrote:
reclass any Over-engineering finding marked Blocker to Should fix, and ignore it when
deciding merge or bounce (step 7). A sub-agent that lowered its confidence only because of
over-engineering is re-scored without it. The merge decision is the Reviewer's, not the
sub-agents'.
Aggregation rule: take the MINIMUM of the two scores. Rationale: one strong skeptic should be enough to block.
Compare aggregate to config.truth_threshold (default 70):
[reviewer]-prefixed PR thread quoting the lowest-confidence sub-agent finding. Write the full §4 Block template comment. Move card Review → Blocked with reason 🛡 truth-check failed (confidence X/100). The bot's "Why I cannot decide" line names the specific sub-agent finding it could not confirm.Same rule as super-build/super-qa.
Take erictechpro/super-review from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.