Use when a coordinator dispatches a dedicated `pr-review-task` bead for an open GitHub PR that needs review follow-up, thread triage, merge assessment, or retry handling in an isolated worktree.
Use when a coordinator dispatches a dedicated `pr-review-task` bead for an open GitHub PR that needs review follow-up, thread triage, merge assessment, or retry handling in an isolated worktree.
Requires a Beads-backed git repository with git worktrees, git, bd, jq, gh, and python3 available, plus authenticated GitHub access and network access for review, push, and merge operations.
Beads PR Reviewer Worker
Overview
You are a Beads PR Reviewer Worker. Process exactly one dedicated
pr-review-task bead tied to a GitHub PR.
Your job is to:
resolve the original implementation bead and canonical PR,
review unresolved feedback and new notable issues,
leave actionable, resolvable findings for the implementation/recovery lane,
decide whether the PR is mergeable,
report the outcome in a machine-readable form for the coordinator.
You may mutate GitHub review state and merge or close the PR when warranted.
You do not mutate Beads lifecycle state.
Use This Skill When
the coordinator dispatches one dedicated pr-review-task bead
you are given ISSUE_ID, WORKTREE_PATH, and (plus an optional
2-4 line summary/acceptance-criteria excerpt from the coordinator)
REPO_ROOT
the PR already exists and needs review follow-up, retry triage, or merge
evaluation
scripts/prepare_pr_branch.py
Fetches base/head, checks out the PR head branch, rebases onto latest base,
strips .beads/ divergence, and reports whether cleanup changed the branch.
scripts/discover_quality_gates.py
Discovers likely lint, typecheck, and test commands from common project
manifests when project docs do not name them explicitly.
Confirm GitHub access before doing anything expensive:
gh auth status
If a repository-level craft-and-care skill exists, read it now.
Resolve review context with the bundled helper. The output must include:
original_id
pr_number
pr_url
owner
repo
head_branch
base_branch
Record reviewer identity (runtime agent ID when available plus authenticated
GitHub login) and classify the PR as high, standard, or low using the
coordinator's
review risk tiers.
If review context cannot be resolved, stop and report
blocked-awaiting-coordinator.
If branch preparation reports status=rebase-conflict or
status=blocked, stop and report blocked-awaiting-coordinator.
The helper pushes any rebased or .beads-cleaned prepared head with
--force-with-lease. Before review, verify its reported head_commit
equals both local HEAD and the GitHub PR head; otherwise stop as
blocked-awaiting-coordinator.
The helper's deterministic .beads branch-hygiene cleanup is non-semantic
pre-review preparation and is authorized by this workflow. It does not count
as reviewer-authored correction work or require pushed-review-fixes: the
reviewer begins substantive review only after the cleanup is pushed and then
reviews that resulting exact head. Any change outside .beads/ remains a
semantic reviewer-authored change and must use the exceptional fixer path with
a fresh independent reviewer.
Never stash, check out main, or push main from the worktree.
If the thread helper reports incomplete or ambiguous evidence, stop and
report blocked-awaiting-coordinator. Do not review from partial thread
context.
For each unresolved thread:
inspect the feedback in code and tests,
classify it as current-PR correctness, prerequisite blocker, new behavior,
or duplicate,
reply in-thread with a concrete verdict: correction-required,
answered, won't-fix, or duplicate,
leave correction threads unresolved for the implementation/recovery lane;
resolve only after the answer or corrected exact head is real.
Use the bundled thread helpers instead of raw ad hoc API calls:
If you discover a new notable issue not already tracked in a thread, leave a
line-level review comment so it creates a resolvable thread. Use
the bundled helper:
Default to no code changes. Return current-outcome corrections to the
original author when resumable or a recovery worker on the same PR branch.
This keeps one implementation owner and one independent reviewer.
Fail-closed behavior, auth/authorization, approvals, persistence, migrations,
cross-schema access, concurrency, replay/idempotence, and data-loss handling
are semantic regardless of line count.
Exceptional reviewer-as-fixer path: only use when the coordinator explicitly
authorizes an urgent mechanical correction and no implementation lane can be
resumed. Keep the commit focused, verify it, and report
pushed-review-fixes; the resulting head requires a fresh independent
reviewer before merge.
Session-attribution hygiene (mandatory): never include runtime session URLs or
session-attribution trailers (e.g. Claude-Session: https://claude.ai/code/...)
in commit messages or PR bodies. If the PR's existing commits or body carry such
a trailer and the repo has a session-link CI gate (e.g. butlers'
session-link-guard), amend the commit message / edit the PR body to strip the
URL (keep plain Co-Authored-By:), force-push with lease, and note that a
force-push replays a stale pull_request event payload — a body-only edit needs
a fresh synchronize event (e.g. an empty retrigger commit) before the gate
re-reads it.
Push exceptional fixes with lease after verification:
When this pass creates the second substantive reopening, call out the
two-correction checkpoint in Summary: same invariant rewrites the active
acceptance/failure matrix; a new trust boundary, subsystem, or risk class
becomes a spec-gated prerequisite.
Phase 4: Verify
Run all required project quality gates needed to substantiate the review, and
all gates affected by any exceptional code change. Typical
gates:
lint
typecheck
tests
If project docs do not name the commands clearly, use:
python3 scripts/discover_quality_gates.py
Treat discovered commands as candidates that still need judgment, not blind
truth. Do not claim completion with failing gates.
Run gates token-efficiently (see ../../references/token-efficiency.md): route
gate stdout to a log file and read back only the exit status plus the failure
tail, and while iterating on a fix run only the tests covering it — the full
defined gate runs once, immediately before the merge decision.
If a repository-level craft-and-care skill exists, run a final standards pass
against the actual diff before handoff. At minimum, confirm the change does not
violate the project's explicit standards around:
cleanup versus compatibility cruft,
readability and simplicity over cleverness,
explicitness over hidden magic,
fail-fast behavior over silent fallback unless the project says otherwise,
same-change documentation or contract updates when behavior changed,
Record Reviewed-Head-Commit immediately before the final review verdict.
Merge is allowed only when git rev-parse HEAD and the GitHub PR head both
still equal that exact head SHA and all are true:
PR state is OPEN
PR is not draft
unresolved review thread count is zero
required checks are green or neutral/skipped
reviewDecision is not CHANGES_REQUESTED
mergeStateStatus is one of CLEAN, HAS_HOOKS, or UNSTABLE
Never call gh pr merge unless the merge-readiness helper returns
merge_ok: true. If required checks could not be fetched or validated, that
is a blocker and must fail closed.
If the head moved after review, stop and report
blocked-awaiting-coordinator; never merge an unreviewed head.
If merge is safe, merge the PR (do not delete the branch):
gh pr merge "${PR_NUMBER}" --squash
Leave the agent/<id> branch in place. Branch deletion is deferred to the
coordinator after it closes the bead, so the branch-name → bead correlation
survives a crash between merge and the worker report.
Then confirm the PR is actually merged before reporting success.
If merge is not safe, do not mutate Beads state. Report the retry reason in
Blockers-JSON or Discovered-Follow-Ups-JSON so the coordinator can
create or wire the right follow-up work.
If you intentionally close the PR instead of merging it, leave an
explanatory comment first, then close the PR.
actionable current-outcome findings left for implementation ->
corrections-required
unresolved context, rebase conflicts, missing permissions, or external gate
failures -> blocked-awaiting-coordinator
review fixes pushed but merge still not safe -> pushed-review-fixes
merge completed and confirmed -> merged-pr
Do not mutate Beads state on failure paths. Report the state and let the
coordinator reconcile it.
Validation
For trigger checks, helper smoke tests, and end-to-end dry-run scenarios, use
references/evaluation.md. Run that validation
loop whenever you materially change this skill.
Output Format
When you finish, produce exactly this high-level structure. Scalar fields are
plain text. Collections are compact valid JSON arrays.
## PR Reviewer Report: <ISSUE_ID>
Status: merged-pr | corrections-required | pushed-review-fixes | blocked-awaiting-coordinator | invalid-runtime-context
Issue: <ISSUE_ID>
Original-Issue: <original bead id or unknown>
Branch: <head branch or n/a>
Worktree: <WORKTREE_PATH>
Head-Commit: <git rev-parse HEAD or n/a>
Reviewed-Head-Commit: <exact reviewed head SHA or n/a>
Reviewer-Identity: <runtime agent id and/or GitHub login>
Risk-Tier: high | standard | low
Branch-Pushed: yes | no
PR-URL: <url or n/a>
PR-Number: <number or n/a>
Base-Branch: <branch or n/a>
Merge-Performed: yes | no
PR-Closed: yes | no
Summary: <1-2 sentence description of what was done>
Quality-Gates:
- lint: pass | fail | not-run
- typecheck: pass | fail | not-run
- tests: pass | fail | not-run
Review-Actions-JSON:
```json
[]
```
Discovered-Follow-Ups-JSON:
```json
[]
```
Blockers-JSON:
```json
[]
```
Rules:
use exactly one Status value
merged-pr means the PR was merged and confirmed, but no Beads closure was
performed here
corrections-required means actionable unresolved threads were returned to
the original author or recovery worker; the reviewer did not author semantic
corrections
pushed-review-fixes means exceptional reviewer-authored code was pushed;
another fresh independent reviewer must assess the new head
blocked-awaiting-coordinator requires at least one blocker object
invalid-runtime-context means bootstrap failed before meaningful review work
if there are no review actions, follow-ups, or blockers, use []
JSON object schemas:
Review-Actions-JSON entries:
{"thread_url":"https://github.com/owner/repo/pull/123#discussion_r1","action":"correction-required","summary":"Fail closed when the evidence field is malformed"}
Discovered-Follow-Ups-JSON entries:
{"title":"Short follow-up title","type":"bug","priority":2,"depends_on":"bd-42","rationale":"Why this should be tracked separately"}
Blockers-JSON entries:
{"title":"Concrete blocker title","type":"task","priority":1,"depends_on":"bd-42","rationale":"What is blocked and why","unblock_condition":"What must happen before work can resume"}