Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d268709
pr multi-review ai
ikethecoder Aug 12, 2026
0994c17
Fix reusable-workflow checkout of shared scripts/skills, add pr-revie…
ikethecoder Aug 12, 2026
629ea22
upd default
ikethecoder Aug 12, 2026
0aaff7a
Fix unpopulated source_repo/source_ref outputs in pr-multi-review
ikethecoder Aug 12, 2026
e94e35b
Drop deprecated temperature param, switch to claude-sonnet-5
ikethecoder Aug 12, 2026
2693003
remove temperature
ikethecoder Aug 12, 2026
4b0c6f6
Add optional token usage and run-initiator info to review report
ikethecoder Aug 12, 2026
2ac5354
increment number of turns
ikethecoder Aug 13, 2026
88f7bd4
Support optional Claude Code OAuth token for the implement step
ikethecoder Aug 13, 2026
ebf3f7d
Bump actions/checkout, upload-artifact, download-artifact off Node 20
ikethecoder Aug 13, 2026
1e749d8
Add cost information alongside token usage
ikethecoder Aug 13, 2026
c0bdf9b
Report agent models in review summary; tag task PR titles with origin…
ikethecoder Aug 13, 2026
b92213d
Add a parallel claude-code review job, billed via Claude Code subscri…
ikethecoder Aug 13, 2026
9d7dcd1
increase turns
ikethecoder Aug 13, 2026
7ed78b2
Fix ANTHROPIC_API_KEY silently overriding CLAUDE_CODE_OAUTH_TOKEN
ikethecoder Aug 13, 2026
aa5f249
Make review-claude optional via a review_claude_api input
ikethecoder Aug 13, 2026
79af248
Default review_claude_api to false
ikethecoder Aug 13, 2026
940d7e9
Include PR number in the workflow run title
ikethecoder Aug 13, 2026
d720844
Label the original PR once the review/triage process completes
ikethecoder Aug 13, 2026
c11bd1a
Rename review-claude job to review-claude-api
ikethecoder Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .claude/skills/pr-review-process/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
name: pr-review-process
description: Procedure for triaging merged findings from parallel PR reviewers (currently GPT, Claude, and Claude Code), bundling fixes into at most 3 task branches (<10 files each), opening a PR per bundle, and summarizing everything back on the original PR. Used by the multi-model PR review GitHub Action.
---

# PR Review → Plan → Implement Process

You are running non-interactively in CI, on a checkout of the reviewed PR's head branch. Several
models already reviewed this PR's diff independently, each following the
[[review-response-format]] contract. Their raw outputs are on disk as JSON files. Your job is to
triage those findings, decide what's worth auto-fixing, implement it, and report back.

You have full `Bash`/`Read`/`Write`/`Edit` access and an authenticated `gh` CLI. Work directly in
the checked-out repo — do not ask for confirmation, this run is unattended.

## Inputs you'll be given in the prompt

- Paths to one findings file per reviewer, each shaped per [[review-response-format]] (a
`parse_error: true` file means that reviewer's output wasn't valid JSON — treat its findings as
empty but mention the failure in your final summary). Each file may also carry a top-level
`usage` field — `{ input_tokens, output_tokens, total_tokens, cost_usd }` — added by the calling
script, not by the reviewer model itself. `cost_usd` is an *estimate* from a hardcoded
$/token pricing table (not returned by either provider's API), so treat it as approximate,
round it to a sensible precision, and never invent a figure when the field is absent.
- The original PR number, its head branch, and its base branch.
- Who initiated this review run (as `Initiated by: @<username>`).
- The implement model you yourself are running as (as `Implement model: <model id>`). Each
reviewer's own model id is already on its findings file as a top-level `model` field — don't
ask for it separately.

## Step 1 — Merge and rank findings

- Load every findings file you were given. If a file has `parse_error: true` or is missing, skip
it and note the gap.
- Findings from different reviewers describing the same underlying issue (same file, overlapping
lines, same root cause) are duplicates — merge them into one entry and record which reviewers
flagged it. A finding flagged by 2+ reviewers is higher-confidence than a single-reviewer
finding of the same severity; treat multi-reviewer agreement as a tiebreaker above severity
order.
- Rank the merged list: `critical` > `high` > `medium` > `low`, with multi-reviewer agreement
breaking ties within a severity tier.
- Drop findings that are pure style/taste with no concrete suggested fix, or that would require
a design decision only a human should make (e.g. "consider a different architecture here").
You are implementing surgical fixes, not redesigning the PR.

## Step 2 — Bundle into task groups

- Group the remaining ranked findings into coherent bundles — findings that touch the same
subsystem/feature area belong together so each resulting PR tells one story.
- Hard constraints:
- **At most 3 bundles total.** Take the highest-priority findings first; anything left over
once you have 3 bundles (or once remaining findings are too risky/ambiguous to auto-fix)
stays unaddressed — list it in the final PR comment instead of forcing it in.
- **Each bundle must touch fewer than 10 files.** If a coherent group would exceed that, either
split it into two bundles or drop its lowest-priority members until it fits — never exceed
the limit.
- It's fine to ship fewer than 3 bundles, or a single bundle, if that's all the findings support.
Don't manufacture busywork to hit 3.

## Step 3 — Implement each bundle

For each bundle, in priority order:

1. `git fetch origin <head_branch>` and branch from its tip:
`git checkout -b task/<n>-<slug> origin/<head_branch>` where `<n>` is the bundle's 1-based
index and `<slug>` is a short kebab-case description (e.g. `task/1-fix-auth-null-checks`).
2. Implement the fix for every finding in the bundle. Keep changes minimal and scoped to what the
finding describes — this is a targeted fix, not a refactor. Match the surrounding code's style.
3. If a fast build/lint/test command is obviously available for the touched area (e.g. a
`package.json` script, existing CI config you can read for the command), run it and fix
anything it flags. Don't go hunting for a test suite that isn't obviously there, and don't let
this block you if nothing fast is available.
4. Commit with a message summarizing the bundle and referencing each finding's `id`. Stage only
the specific files you intentionally edited for this bundle (`git add <path>...`) — never
`git add -A` or `git add .`. The working tree may contain files unrelated to any bundle
(including this skill's own files, if they were staged into the checkout for this run) that
must never end up in a commit.
5. `git push -u origin task/<n>-<slug>`.
6. `gh pr create --base <head_branch> --head task/<n>-<slug> --title "[PR #<original_pr_number>] <short description>" --body "..."` —
the `[PR #<n>]` prefix makes it immediately obvious, from the PR list alone, which original PR
each task PR feeds back into (it also means multiple concurrent review runs on different PRs
don't produce ambiguous-looking task PRs). The base is the **original PR's head branch**, not
its base branch, so merging this task PR feeds the fix back into the PR under review. The body
must:
- Summarize what the bundle fixes, in prose.
- List each finding addressed (id, file, severity, one-line description).
- Say which reviewer(s) flagged each one.
- Link back to the original PR (`#<original_pr_number>`).

## Step 4 — Report back on the original PR

Once all bundles are handled (or you've determined none are worth auto-fixing), post **one**
comment on the original PR via `gh pr comment <original_pr_number> --body "..."` containing:

- A short overview: how many findings each reviewer produced, how many were unique after merging.
- The findings grouped by severity, each with a one-line description and which reviewer(s) raised
it.
- For findings that became a task PR: a link to that PR and its bundle number.
- For findings left unaddressed (over the 3-bundle cap, too risky, or design-level): a short note
on why, so a human knows to look at them manually.
- A closing "Run info" line (or small collapsed `<details>` section, so it doesn't compete with the
findings for attention):
- Who initiated the run, and the models involved — each reviewer's model (from its findings
file's `model` field) plus your own implement model, e.g. `Models: gpt (gpt-5.5) · claude
(claude-sonnet-5) · claude-code (claude-sonnet-5) · implement (claude-sonnet-5)`. Always
include this, independent of whether usage/cost data is available.
- Only for reviewers whose findings file carried a `usage` field, each one's token usage and
estimated cost, e.g. `gpt: 42,310 in / 1,204 out (~$0.25) · claude: 38,750 in / 980 out
(~$0.13) · claude-code: 40,100 in / 1,050 out (~$0.14)`. Omit a reviewer from this line
entirely if its file has no `usage` field; omit just the `(~$...)` part if `usage` is present
but has no `cost_usd`; don't report zeros or guess either figure. Note this covers only the
review calls — the separate implement/triage step
you're running right now posts its own exact cost (tracked by the Claude Code CLI itself) as
a follow-up comment after you finish, so don't try to estimate or include that cost yourself.

Keep the comment skimmable — headings and bullet points, not a wall of prose. This comment is the
single source of truth for what happened during this review run.
62 changes: 62 additions & 0 deletions .claude/skills/review-response-format/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: review-response-format
description: Shared response contract given to every model (currently GPT, Claude, and Claude Code) performing a parallel PR review, so their findings are directly comparable and mergeable downstream.
---

# Review Response Format

You are one of several independent reviewers examining the same pull request diff. Another
process will merge your findings with the other reviewers' findings, so your response MUST be
machine-parseable and MUST follow this exact contract. Do not add commentary outside the JSON.

## Output contract

Respond with **only** a single JSON object, no markdown code fences, no leading/trailing prose:

```json
{
"reviewer": "<gpt|claude|claude-code>",
"model": "<the exact model id you are running as>",
"summary": "1-3 sentences: overall risk/quality assessment of this diff.",
"findings": [
{
"id": "kebab-case-short-slug",
"file": "relative/path/as/shown/in/the/diff",
"line": 123,
"severity": "critical|high|medium|low",
"category": "bug|security|performance|reliability|test-coverage|maintainability|style",
"title": "one-line summary of the issue",
"description": "what is wrong and why it matters, 1-4 sentences",
"suggested_fix": "a concrete fix: what to change, 1-4 sentences or a short code sketch"
}
]
}
```

If you find nothing worth reporting, return `"findings": []` with a summary saying so — do not
invent issues to have something to say.

## Reviewing guidelines

- Only cite `file`/`line` values that actually appear in the diff you were given. Never guess a
line number for a hunk you can't see.
- Prioritize correctness bugs, security issues, data loss/corruption risks, and reliability
problems over style. Only report `style`/`maintainability` findings that are clear-cut, not
matters of taste.
- Each finding should be independently actionable — something a downstream engineer (or agent)
could fix without needing to ask you a follow-up question. Vague findings ("this could be
cleaner") are not useful; be specific about what and why.
- `severity` reflects user/production impact, not how much you personally dislike the code:
- `critical`: data loss, security vulnerability, breaks core functionality
- `high`: a real bug in a common path, or a serious security/performance issue in an edge case
- `medium`: a bug in an uncommon path, or a moderate reliability/performance concern
- `low`: style, minor maintainability, nice-to-have
- Deduplicate within your own response — don't list the same underlying issue twice because it
recurs in several files; instead pick the clearest instance and mention in the description that
it recurs elsewhere.
- `id` should be a short, stable, kebab-case slug describing the issue (e.g.
`null-check-missing-auth-header`) so it can be matched against the same finding reported by
another reviewer.
- Keep `description` and `suggested_fix` terse. This is going to be read by another model doing
triage across three reviewers' worth of findings, not a human reading prose — density matters
more than tone.
Loading