PR Review Pipeline
Orchestrate a full PR review using the reviewer MCP server tools. The deterministic
tail (policy gate, line grounding, dedup, idempotency, comment cap, publishing) is
handled by publish_review — your job is analysis quality, not formatting rules.
Inputs
Parse from $ARGUMENTS: target PR as owner/repo#N, owner/repo N, or a GitHub PR URL.
--dry-run flag → pass dry_run=true to publish_review and show the report instead
of posting.
Include resolution (applies to all steps below). When you read any
references/*-prompt.md file to dispatch a subagent (steps 3, 4, and 5 —
analyze, requirements, blast-radius, verify), it may contain
<!-- include: _common/<file>.md --> markers. Before putting the prompt into
the subagent, replace each marker with the verbatim contents of that file
(path is relative to plugin/skills/). These _common/*.md files are the
single source of the shared findings-schema / anti-hallucination / tool-usage
blocks.
Pipeline
Prepare. Call
prepare_review(repo, pr). The payload contains:pr:{number, title, body, base_sha, head_sha, base_ref, draft}policy:{severity_threshold, min_confidence, max_comments, categories, ignore, output_language}units: list of{path, patch, commentable_right, commentable_left}task_board:{type, project, key_pattern, create_target, done_target, options}or null — non-secret generic board metadata from.review.ymltask_keys:{primary, others}or null — task keys extracted from the PR by the serverskipped_paths,skip_drafts,suggestions_mode
If the payload has
status: "skipped", this is NOT an error but an expected skip (the PR's target branch is not inREVIEW_BRANCHES). Tell the user thereasonvalue and stop: do not run analyze/publish, and do not treat it as a failure.If
pr.draftis true andskip_draftsis true, stop and tell the user. Notepolicy.output_language— ALL finding messages, suggestions and the summary MUST be written in that language.Task context (optional). Only if
task_boardis non-null. Resolve the task key: an explicit key in$ARGUMENTSwins; otherwise usetask_keys.primary. If no key is available, skip this step and note in the summary that no task key was found.Task reads are scoped to this repo's project: pass
project=<task_board.project>(from the target branch.review.yml, see step withtask_board) toget_task/get_task_context/search_tasks(PRI-170; emptyproject= unscoped).Read the task store-first (unifies with solve-task):
- Call reviewer
get_task(key, project=<task_board.project>)first. Hit (object with akey) → use it as theTaskBriefdirectly; it is already indexed by the server-side sync, so do NOT callindex_task. - Miss (
null) → call generic incrementalsync_board(board=<task_board.project or null>, board_type=<task_board.type>, provider_options=<task_board.options or {}>, limit=null, purge_orphaned=false), then callget_task(key, project=<task_board.project>)once more. A sync error or second miss is fail-open: skip the requirements dimension and note the reason in the summary — NEVER abort the review.
The
TaskBriefschema is{key, aliases[], title, description, criteria[], status, url, links[]}(phase 3 addsaliases[]and useslinks[]). On either store hit the brief is already indexed — do NOT re-index. Then gather task context to sharpen the requirements check:get_task_context(TaskBrief.key, project=<task_board.project>)→ linked tasks, their PRs, and the code those PRs touched;search_tasks("<TaskBrief.title>. <first lines of description>", project=<task_board.project>)→ semantically similar tasks. Keep ONLY the related/similar items that look relevant; you will pass them to the requirements dimension in step 4. All of this is best-effort: ifindex_task/get_task_context/search_tasksreturn a "(… unavailable)" note or error, continue — never abort the review.
- Call reviewer
Analyze (fan-out). For each unit in
units, dispatch a subagent (Task tool, run independent subagents in parallel; batch units if there are more than ~10) with:- the contents of
references/analyze-prompt.md(read it once, resolve includes, include verbatim); - the unit's
path,patch,commentable_right(sorted list of new-file line numbers available for inline),commentable_left(sorted list of old-file line numbers available for inline), and the PRtitle/body; - the repo/pr identifiers so the subagent can call the reviewer MCP tools
(
search_code,get_related_symbols,read_file,get_definition,find_callers,get_changed_file_diff); - the target output language.
Each subagent submits findings via
submit_findings(repo, pr, findings=[...])(schema-enforced; the server assigns ids).
- the contents of
Dimensions (parallel with step 3). Dispatch whole-diff subagents:
- performance: follow the methodology of
../performance-review/SKILL.md(Goal, Method, Severity sections); - maintainability: follow
../maintainability-review/SKILL.md; - requirements (ONLY if a
TaskBriefwas built in step 2): dispatch one subagent withreferences/requirements-prompt.md, the diffs of all units (path + patch), theTaskBrief, plus the related/similar task context gathered in step 2 (linked tasks, their PRs, touched code, similar tasks) as an optional "Related context" block, the repo/pr identifiers (so it can call the reviewer MCP tools), and the target output language. It submits findings viasubmit_findingswith categoryrequirements. - blast-radius: dispatch one subagent with
references/blast-radius-prompt.md, the diffs of all units (path + patch), each unit'scommentable_right/commentable_left(the line numbers where inline comments are allowed), the PRtitle/body, the repo/pr identifiers, and the target output language. It runs two checks — changed signatures breaking callers (viaget_impact) and interface expansion (a changedProtocol/ABC whose implementations must all be updated, viaget_related_symbols/search_code) — and submits findings viasubmit_findingswith categorycorrectness. Give the performance/maintainability subagents: the diffs of all units (path + patch), the repo/pr identifiers so they can call the reviewer MCP tools, and the target output language. They must submit findings viasubmit_findings(categoryperformance/maintainability).
- performance: follow the methodology of
Verify. Dispatch one subagent with
references/verify-prompt.mdand the repo/pr identifiers. It reads candidates viaget_candidate_findings(repo, pr)and submits verdicts viasubmit_verdicts(repo, pr, verdicts=[{id, is_real}]). A finding withis_real=falseis dropped at publish; a finding with no verdict is kept (recall-safe — no orchestrator action needed if verify fails).Publish. Compose a short review summary (2-5 sentences, in
policy.output_language): what the PR does, overall assessment, key risks. If a task was read, state whether the PR meets the task's requirements; if the task context was requested but unavailable (no key, sync error, task not found), say so briefly. Mention files that were not analyzed: failed subagents andskipped_pathsfrom the prepare payload. Callpublish_review(repo, pr, summary, dry_run, task_key)wheretask_keyis the canonicalTaskBrief.keyif a task was read (else omit / null). If the CLI provides model/usage/cost metadata, pass them via the optional keyword argumentsmodel,usage, andtotal_costtopublish_review. When published, this links the PR to the task in the graph for future reviews. Report to the user: posted/dry-run, inline count, and the report counters (dropped_by_gate/deduped/invalid/already_posted/moved_to_summary/capped/verify_rejected), run_id.
Failure handling
- A failed analyze subagent must not abort the run: continue with the other units and mention the skipped file in the summary.
- A
prepare_reviewpayload withstatus: "skipped"is not a failure: report itsreason(target branch not tracked inREVIEW_BRANCHES) and stop without analyze/publish. - If
prepare_reviewfails, surface its error text to the user as-is (it contains the remediation hint, e.g. "docker compose up -d"). - Never post comments yourself via gh/git — only through
publish_review.
Source: hashgraph-online/awesome-codex-plugins → plugins/mimfort/rag_for_git/plugin/skills/review-pr/SKILL.md