Agent Skills: Athena PR Reviewer — Workflow Edition

PROACTIVELY USED when reviewing a PR, branch, or Jira story. Runs a multi-reviewer code review in a background workflow (7 parallel Opus specialists → Sonnet batched verifiers → Sonnet synthesis), keeping reviewer agents out of main-thread context and returning a synthesized themed report. Then adapts to PR ownership — a fix/explain walkthrough for your own PR, or a pass/request-changes verdict plus an offer to post the findings as PR comments for someone else's. Triggers on "review PR X", "review this branch", "review CSD-123", "workflow review", "background review", or "/athena-workflow".

UncategorizedID: emiperez95/cc-toolkit/athena-pr-reviewer-workflow

Install this agent skill to your local

pnpm dlx add-skill https://github.com/emiperez95/cc-toolkit/tree/HEAD/skills/athena-pr-reviewer-workflow/skills/athena-pr-reviewer-workflow

Skill Files

Browse the full folder contents for athena-pr-reviewer-workflow.

Download Skill

Loading file tree…

skills/athena-pr-reviewer-workflow/skills/athena-pr-reviewer-workflow/SKILL.md

Skill Metadata

Name
athena-pr-reviewer-workflow
Description
PROACTIVELY USED when reviewing a PR, branch, or Jira story. Runs a multi-reviewer code review in a background workflow (7 parallel Opus specialists → Sonnet batched verifiers → Sonnet synthesis), keeping reviewer agents out of main-thread context and returning a synthesized themed report. Then adapts to PR ownership — a fix/explain walkthrough for your own PR, or a pass/request-changes verdict plus an offer to post the findings as PR comments for someone else's. Triggers on "review PR X", "review this branch", "review CSD-123", "workflow review", "background review", or "/athena-workflow".

Athena PR Reviewer — Workflow Edition

Background-mode PR review — the default athena reviewer. The heavy lifting (7 parallel Opus specialists + 7 batched Sonnet verifiers + 1 Sonnet synthesis pass) runs inside a Workflow, so main-thread context only sees the curated final report. Prompts and scripts are bundled in this skill (~/.claude/skills/athena-pr-reviewer-workflow/{prompts,scripts}) — no other skill is required.

When to invoke

Any time the user asks to review a PR, branch, or Jira story. Examples:

  • "review PR 2923"
  • "review this branch"
  • "review CSD-2591"
  • "workflow review PR 2923" / "background review CSD-2591" / "/athena-workflow"

Progress tracking

Initialize a short todo list:

TodoWrite([
  {content: "Resolve PR target", status: "in_progress", activeForm: "Resolving PR target"},
  {content: "Resolve repo path", status: "pending", activeForm: "Resolving repo path"},
  {content: "Determine PR ownership", status: "pending", activeForm: "Determining PR ownership"},
  {content: "Launch workflow", status: "pending", activeForm: "Launching workflow"},
  {content: "Wait for completion", status: "pending", activeForm: "Waiting for workflow"},
  {content: "Present report", status: "pending", activeForm: "Presenting report"},
  {content: "Add main-thread opinion", status: "pending", activeForm: "Forming opinion on findings"},
  {content: "Post-review flow (fix walkthrough or verdict + comments)", status: "pending", activeForm: "Running post-review flow"},
])

Update as each step completes.

1. Resolve PR target + Jira ticket

Parse the user's message:

  • Explicit PR number (PR 123, #123): use directly.
  • Jira ticket (PROJ-123): gh pr list --search "PROJ-123" --json number --jq '.[0].number'.
  • Current branch: gh pr view --json number --jq '.number'.
  • Otherwise: extract Jira from branch with git branch --show-current | grep -oE '[A-Z]+-[0-9]+' and search.

If still no PR, ask the user via AskUserQuestion.

Detect the Jira ticket from the PR (only needed if the workflow can't infer it itself, but passing it is cheap and explicit):

gh pr view ${PR_NUM} --json title,headRefName --jq '.title + " " + .headRefName' | grep -oE '[A-Z]+-[0-9]+' | head -1

2. Resolve repo path

The workflow's gather agent runs gh pr view, gh pr diff, and git blame without --repo, so it must be invoked from inside the PR's repo checkout.

Detection order:

  1. Current working directory: if git remote get-url origin matches the PR's repo (gh pr view ${PR_NUM} --json url --jq '.url' → the owner/repo portion), use pwd.
  2. Common locations: search under ~/Projects for a .git whose origin matches the PR's repo:
    find ~/Projects -maxdepth 5 -name .git -type d 2>/dev/null | while read g; do
      d=$(dirname "$g")
      r=$(cd "$d" && git remote get-url origin 2>/dev/null)
      if [[ "$r" == *${OWNER}/${REPO}* ]]; then echo "$d"; break; fi
    done | head -1
    
  3. If still nothing, ask via AskUserQuestion for the absolute path.

2b. Determine PR ownership

This decides the post-review flow (section 6). Compare the PR author to the authenticated GitHub user:

PR_AUTHOR=$(gh pr view ${PR_NUM} --repo ${OWNER}/${REPO} --json author --jq '.author.login')
ME=$(gh api user --jq '.login')
# isMine = ( "$PR_AUTHOR" == "$ME" )

Remember isMine (and PR_AUTHOR) for section 6:

  • isMine == true → your own PR: run the fix/explain walkthrough (6a).
  • isMine == false → someone else's PR: give a verdict + offer to comment (6b). Do NOT offer to edit their code.

If the author can't be resolved (deleted account, API hiccup), default to isMine == false (the safer, read-only branch) and note the assumption to the user.

3. Launch the workflow

Workflow({
  scriptPath: "~/.claude/skills/athena-pr-reviewer-workflow/workflows/review.js",
  args: {
    prNumber: <number>,
    jiraTicket: "<ticket>",
    repoPath: "<absolute path>"
  }
})

The tool returns immediately with a runId and task ID. Tell the user the workflow is running in background and they can watch progress in /workflows. Do NOT poll — wait for the task notification.

4. Wait for the task notification

When the notification arrives (a <task-notification> block), parse the result.

If status is failed, surface the error to the user and stop. Common failure: gather agent couldn't run gh (auth / wrong directory).

If status is completed, parse result as JSON. Expected shape:

{
  "ok": true,
  "prNumber": 2923,
  "jiraTicket": "CSD-2591",
  "workDir": "/tmp/athena-review-2923",
  "reviewersRun": ["comment-analyzer", ...],
  "reviewersWithNoFindings": [],
  "totals": {
    "rawFindings": 64,
    "verified": 59,
    "partial": 5,
    "rejected": 0,
    "groupsAfterSynthesis": 24,
    "multiReviewerGroups": 6,
    "finalAfterConfidenceFilter": 19
  },
  "themeCounts": {"<theme>": 1, ...},
  "findings": [
    {
      "theme": "...",
      "title": "...",
      "severity": "Critical|High|Medium|Low",
      "confidence": 95,
      "reviewers": ["test-analyzer", "requirements-checker"],
      "reviewersCount": 2,
      "file": "...",
      "line": 42,
      "issue": "...",
      "impact": "...",
      "fix": "...",
      "memberCount": 5
    }
  ],
  "partialFindings": [{"file","line","severity","confidence","issue","fix","reviewer","verdictReason"}]
}

Pull the workflow usage block from the notification (<usage><agent_count><subagent_tokens><tool_uses><duration_ms>) for the stats section.

5. Present the report

Group findings by theme. Within each theme, sort by severity then confidence (workflow already sorts globally; preserve that order when grouping). Format:

# PR Review (workflow): #{prNumber}{jiraTicket ? ` — ${jiraTicket}` : ''}

**Pipeline:** {reviewersRun.length} reviewers → {totals.rawFindings} raw → {totals.verified} verified ({totals.partial} partial, {totals.rejected} rejected by verifier) → {totals.groupsAfterSynthesis} groups → **{totals.finalAfterConfidenceFilter} final** ({totals.multiReviewerGroups} multi-reviewer)

## Findings

### {theme 1}
- [ ] **{severity}** `{file}:{line}` — {title}
  - Reviewers: {reviewers.join(', ')} ({reviewersCount})
  - Issue: {issue}
  - Fix: {fix}

### {theme 2}
...

## Suggestions (partial findings — verifier flagged inaccuracies but core issue is real)

- `{file}:{line}` **{severity}** ({reviewer}, conf {confidence}) — {issue}
  - Verifier note: {verdictReason}
  - Suggested fix: {fix}

## Workflow stats

- Agents: {agent_count}
- Subagent tokens: {subagent_tokens}
- Tool uses: {tool_uses}
- Wall clock: {duration_ms / 1000}s
- Work dir (debug): {workDir}

Multi-reviewer groups (reviewersCount >= 2) deserve emphasis — they're the strongest quality signal in the pipeline. Surface that fact in the theme heading if applicable: ### {theme} — flagged by N reviewers.

If totals.verified === 0, present a brief "no findings" summary and skip the "My take" section. Then:

  • isMine → nothing to address; stop.
  • not isMine → the verdict is a clean Pass; jump to 6b and offer to post an approving / "LGTM" review.

5b. Your opinion (main-thread synthesis)

Before handing control to the user, add your own take. The workflow agents only saw the PR diff + context.md — you have more: the surrounding repo, prior conversation, the user's intent, what's been touched recently, what's reasonable to fix now vs. later. Use that.

After the findings table, write a section like:

## My take

{2-4 sentences. Pick the most important angle.}

- **Worth fixing now:** {findings or themes you'd prioritize, and why — reference file:line}
- **Worth deferring or skipping:** {findings that look real but aren't worth the churn here, and why — reference file:line}
- **Partial findings I'd surface:** {any from the Suggestions section that look genuinely useful}
- **What the workflow may have missed:** {anything you notice that the reviewers couldn't see — e.g. how this PR interacts with code outside the diff, prior decisions in this repo, an in-flight refactor}

Be specific. "All findings look real" is not opinion — it's a non-answer. If you genuinely have no extra signal beyond the report, say so explicitly ("Nothing to add — the report covers it") and move on.

If isMine == false, angle the take toward the merge decision — what actually blocks vs. what's a nit — since it becomes the rationale for your section-6b verdict.

Read files from the repo when needed to ground your opinion (the workflow's workDir artifacts are also available for inspection: reviews/<key>.json, verdicts/<key>.json, synthesis.json).

6. Post-review flow (branches on PR ownership)

Use isMine from section 2b:

  • isMine == true → 6a. Fix / explain walkthrough (you're the author — help land fixes).
  • isMine == false → 6b. Verdict + offer to comment (you're the reviewer — give a verdict and offer to record it on the PR; never edit their code).

The "My take" from 5b feeds both branches — for 6a it prioritizes what to fix; for 6b it's the basis of the verdict.


6a. Your PR — fix / explain walkthrough

After the report, ask via AskUserQuestion:

How would you like to address the findings?

Options:

  • Walk through one by one (Recommended): present each theme's findings, decide fix/skip per item.
  • I'm done: keep the report, no fixes.

Walk through: Replace todos with one per theme:

TodoWrite([
  {content: "Theme 1 ({N} issues)", status: "in_progress", activeForm: "Addressing Theme 1"},
  {content: "Theme 2 ({N} issues)", status: "pending", activeForm: "Addressing Theme 2"},
  ...
])

For each theme, walk through its findings one at a time:

  1. Present the finding with file:line and current code snippet (Read the file).
  2. Explain the issue and your opinion.
  3. Propose a fix.
  4. Ask: fix or skip?
  5. If fix: implement, then commit immediately. Do NOT batch changes.
  6. Move to the next finding.

Once a theme's findings are all addressed (fixed or skipped), mark its todo completed.

Do not accumulate uncommitted changes across findings. Each fix is its own commit (small, isolated, easy to revert).

Done: stop. The report stands as-is.


6b. Someone else's PR — verdict + offer to comment

You're the reviewer, not the author. Do not edit their code or offer to. Instead give a verdict and offer to record it on the PR.

Step 1 — Decide a verdict (your recommendation, grounded in the "My take" opinion):

  • Request changes — any VERIFIED finding is Critical or High (or a High flagged by ≥2 reviewers). Something in this PR should not merge as-is.
  • Pass — only Medium/Low findings, or none. Note remaining nits but nothing blocking.

Present it on its own line with one sentence of rationale:

## Verdict: Request changes
{one-sentence rationale — name the blocking finding(s) by file:line}

Step 2 — Offer to record it via AskUserQuestion:

I recommend {verdict}. How should I record this on PR #{prNumber} by @{PR_AUTHOR}?

Options:

  • Post a review with inline comments (event = {verdict}) — (Recommended) one PR review: each finding as an inline comment on its file:line, plus a summary body carrying the verdict + any findings that don't map to a diff line.
  • Post one summary comment — a single general PR comment with all findings + verdict, no approval state.
  • Don't post — verdict + opinion stay in this chat.

(The user can pick "Other" to flip the verdict — e.g. "post it but as Approve".)

Step 3a — Post a review with inline comments. Map verdict → event: Request changes → REQUEST_CHANGES, Pass → APPROVE (or COMMENT if the user prefers not to approve). Build the payload — inline comments only for findings whose file + line fall inside the PR diff (a line outside the diff makes GitHub reject the whole review with 422). Put line: null findings, partial findings, and anything off-diff into the body instead.

Write the payload to ${workDir}/pr-review-payload.json:

{
  "event": "REQUEST_CHANGES",              // or APPROVE / COMMENT
  "body": "## Athena review — {verdict}\n\n{summary + any off-diff findings, markdown}",
  "comments": [
    { "path": "src/foo.ts", "line": 42, "side": "RIGHT",
      "body": "**High** — {issue}\n\nSuggested fix: {fix}" }
  ]
}

Post it:

gh api --method POST repos/${OWNER}/${REPO}/pulls/${PR_NUM}/reviews \
  --input ${workDir}/pr-review-payload.json

If it fails with 422 (a comment line isn't in the diff), move the offending comment(s) into body and retry, or fall back to Step 3b. Report the posted review URL from the API response.

Step 3b — Post one summary comment. Build the same findings + verdict as markdown and post a single general comment:

gh pr comment ${PR_NUM} --repo ${OWNER}/${REPO} --body-file ${workDir}/pr-comment.md

Step 3c — Don't post. Stop; the verdict stands in the conversation.

Confirmation: posting a review, an approval, or a comment is an outward-facing action on someone else's PR — only do it through the AskUserQuestion choice above. Never post without that explicit selection.

Examples

User: "workflow review PR 2923" (PR authored by the user)

  1. PR 2923, Jira CSD-2591 extracted from title
  2. Repo path resolved (cwd or search)
  3. Ownership: author == me → isMine = true
  4. Workflow launched, runId returned
  5. Wait for notification (typically 3-8 min from scratch, faster on resume)
  6. Themed report + "My take" presented with multi-reviewer emphasis
  7. 6a — offer the fix/explain walkthrough

User: "review PR 4102" (PR authored by a teammate)

  1. PR 4102 resolved
  2. Repo path resolved
  3. Ownership: author != me → isMine = false
  4. Workflow launched → report + "My take" presented
  5. 6b — verdict (e.g. "Request changes" for a High finding), then offer to post a review with inline comments, a summary comment, or nothing

User: "background review CSD-2591"

  1. gh pr list --search CSD-2591 → PR found
  2. Repo lookup → ownership check → workflow launched
  3. Same flow as above, branching on ownership

User: "review PR 2923"

  • Same flow — this is the default reviewer. No workflow keyword needed.

Notes

  • The workflow's args.prNumber is required; args.repoPath is required. args.jiraTicket is optional but recommended.
  • Resume support: if a workflow needs to be re-run after a script edit, invoke with {scriptPath, resumeFromRunId: "<id>"}. Completed agents return cached results instantly.
  • The workflow does NOT use external LLMs (Gemini/Codex) in v1. Only the 7 Claude specialists.