From gh-workflow
Use after receiving PR review feedback to systematically address comments, verify fixes, and re-request review
npx claudepluginhub synaptiai/synapti-marketplace --plugin gh-workflow<pr-number-or-url><!-- PARALLEL EXECUTION RULE: When performing multiple independent operations (reads, API calls, TaskCreate), invoke ALL relevant tools simultaneously in a single message rather than sequentially. Err on the side of maximizing parallel tool calls. VARIABLE PERSISTENCE NOTE: Bash variables (like REPO, PR_NUM) do NOT persist across separate tool calls. Each Bash invocation is an independent process. Store values mentally from output and substitute them in subsequent commands. When running parallel Bash calls, each must define any variables it needs inline. --> # Address PR #$ARGUMENTS Comme...
Systematically address review feedback on a pull request with task tracking and quality verification.
Tool Usage: This workflow uses the AskUserQuestion tool to clarify ambiguous feedback, and TaskCreate/TaskUpdate tools to track feedback resolution.
GOAL: All review feedback items addressed with verification that fixes don't introduce new issues. Testable: each feedback item has a corresponding commit and response in the summary comment.
CONSTRAINTS:
FORMAT: Summary comment posted on PR with feedback-to-action mapping table, thread status, and verification checklist.
FAILURE CONDITIONS (output is unacceptable if any apply):
$ARGUMENTS can be a PR number (e.g., 42) or a full URL (e.g., https://github.com/owner/repo/pull/42). Extract the PR number:
PR_NUM=$(echo "$ARGUMENTS" | grep -oE '[0-9]+$')
[[ -n "$PR_NUM" ]] || { echo "ERROR: Could not extract PR number from: '$ARGUMENTS'"; exit 1; }
echo "PR number: $PR_NUM"
Use the extracted PR_NUM in all subsequent commands.
Read CLAUDE.md using the Read tool (not cat/Bash) to extract quality commands and conventions:
.claude/CLAUDE.md first, then CLAUDE.mdExecute in parallel (single message, multiple Bash tool calls). Each call defines REPO independently:
Fetch PR details and reviews:
gh pr view $PR_NUM --json title,headRefName,baseRefName,state,reviews
Fetch review comments (inline code comments):
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
gh api repos/$REPO/pulls/$PR_NUM/comments
Fetch PR conversation (general discussion comments):
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
gh api repos/$REPO/issues/$PR_NUM/comments
Check for resolved/unresolved threads:
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
gh api repos/$REPO/pulls/$PR_NUM/comments --jq '[.[] | select(.in_reply_to_id == null)] | length'
If PR not found (gh pr view fails): Report error and stop:
"PR #$PR_NUM not found. Verify the PR number and try again."
This depends on headRefName from Step 1.3, so it must run after:
git fetch origin {headRefName}
git checkout {headRefName}
Invoke the capability-discovery skill using the Skill tool to discover quality commands and available agents.
After skill returns, extract:
LINT_CMD="{detected lint command}"
TEST_CMD="{detected test command}"
TYPECHECK_CMD="{detected typecheck}"
Store these for Phase 5. If a command is not applicable, note as "N/A — skip".
Graceful fallback: If the Skill tool invocation fails and CLAUDE.md didn't provide commands, detect from tech stack:
| Indicator | Commands |
|---|---|
| pyproject.toml | ruff check ., pytest |
| package.json | npm run lint, npm test |
| tsconfig.json | tsc --noEmit |
| go.mod | go vet ./..., go test ./... |
| Cargo.toml | cargo clippy, cargo test |
Before creating a task for each feedback item, verify it still applies:
This prevents wasted work on stale findings from earlier review rounds.
For each review comment/feedback item, create a tracking task:
TaskCreate:
subject: "Address: [Brief summary of feedback]"
description: |
**Reviewer**: @{reviewer}
**Location**: {file}:{line}
**Comment**: {full comment text}
**Action needed**: [fix/discuss/clarify]
activeForm: "Addressing [feedback summary]"
Group related feedback into single tasks where appropriate. Categorize each item:
When addressing each feedback item:
git diff --stat should show only files directly related to the feedbackFAILURE CONDITION: A fix commit that modifies files not mentioned in the feedback without explicit user approval.
For each feedback task:
Mark in progress: TaskUpdate: taskId={id}, status=in_progress
Read and understand the feedback
Read the relevant content context — Do NOT trust line numbers from review comments; they shift after edits. Instead:
If feedback is ambiguous, use the AskUserQuestion tool to clarify:
If you disagree with feedback, use the AskUserQuestion tool:
Make the necessary changes
Commit with a descriptive message:
# Good - specific and clear
git commit -m "fix: correct broken link per review feedback"
git commit -m "fix: update validation logic as suggested"
git commit -m "docs: clarify usage instructions per review"
Mark task complete: TaskUpdate: taskId={id}, status=completed
Use the quality commands discovered in Phase 2 (LINT_CMD, TEST_CMD, TYPECHECK_CMD). Skip any that are N/A.
Execute a bounded fix-verify cycle. Fix immediately — do not create tasks for lint/test failures. These are mechanical fixes.
Read max iterations from settings:
MAX_ITERATIONS=$(jq -r '.timeouts.qualityCheckMaxIterations // empty' .claude/settings.gh-workflow.local.json 2>/dev/null)
[ -z "$MAX_ITERATIONS" ] && MAX_ITERATIONS=$(jq -r '.timeouts.qualityCheckMaxIterations // empty' .claude/settings.gh-workflow.json 2>/dev/null)
[ -z "$MAX_ITERATIONS" ] && MAX_ITERATIONS=$(jq -r '.timeouts.qualityCheckMaxIterations // empty' "$HOME/.claude/settings.gh-workflow.json" 2>/dev/null)
[ -z "$MAX_ITERATIONS" ] && MAX_ITERATIONS="3"
Iteration 1 (and up to MAX_ITERATIONS total):
Run all quality commands in parallel (3 Bash tool calls in a single message):
- Bash call 1: {lint_cmd} # e.g., ruff check . 2>&1
- Bash call 2: {test_cmd} # e.g., pytest 2>&1
- Bash call 3: {typecheck_cmd} # e.g., tsc --noEmit 2>&1
If ALL pass → proceed to Phase 6
If ANY fail:
git commit -m "fix: [what was fixed]"After MAX_ITERATIONS failed iterations → escalate to user via AskUserQuestion tool:
This is the most critical gate. Reviewer feedback is being addressed — introducing new issues here means another review cycle. The goal is to make this the last round of review on this PR.
git diff origin/{baseRefName}..HEAD
Read the code review checklist from references/code-review-checklist.md (relative to the gh-workflow plugin directory) and follow its instructions. The checklist covers:
code-reviewer agent if available from Phase 2 discovery)Focus the review on fix commits specifically — verify each fix:
Task creation policy for review findings — because this is an address cycle where regressions mean another full review round, be thorough:
TaskCreate: subject="Fix: [issue]", implement fixes, re-run quality checks (Phase 5 Step 5.1)After all finding tasks are completed:
TaskList
Verify all review finding tasks are status=completed.
If any fixes were made during review, re-run ALL quality commands in parallel to confirm nothing broke:
- Bash call 1: {lint_cmd}
- Bash call 2: {test_cmd}
- Bash call 3: {typecheck_cmd}
If failures → apply the same bounded loop from Phase 5 Step 5.1 (max iterations from settings, default: 3).
If tests were added or modified as part of addressing feedback:
Read the test review checklist from references/test-review-checklist.md (relative to the gh-workflow plugin directory) and follow its instructions. The checklist covers:
After identifying issues:
Skip if: No tests were added or modified during Phase 4.
Extract the issue number from the PR branch name for journal file operations:
BRANCH=$(git branch --show-current)
ISSUE_NUM=$(echo "$BRANCH" | grep -oE 'issue-[0-9]+' | grep -oE '[0-9]+')
echo "Issue number: $ISSUE_NUM"
If no issue number found from branch name, extract from the PR body:
gh pr view $PR_NUM --json body --jq '.body' | grep -oiE '(closes|fixes|resolves)\s*#[0-9]+' | grep -oE '[0-9]+' | head -1
After all feedback is addressed, invoke the decision-journal skill in log mode using the Skill tool:
Skill: decision-journal —
"Mode: log
Phase: addressed review feedback
Description: Decisions made while addressing PR #{PR_NUM} review feedback"
The skill analyzes the fix commits and captures decisions about trade-offs (when choosing between competing reviewer suggestions), scope changes (when feedback requires scope adjustments), and implementation changes (when feedback alters the approach).
Append returned entries to {journal-dir}/issue-{ISSUE_NUM}.md (where journal-dir is returned by the skill, default .decisions). Present any gate triggers via AskUserQuestion (see references/gate-configuration.md).
Check if the PR body contains a Comprehension Report that is now stale (diff has changed since the report was generated):
# Get current diff stats
DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')
CURRENT_FILES=$(git diff --name-only "$DEFAULT_BRANCH"...HEAD | wc -l | tr -d ' ')
echo "Current files changed: $CURRENT_FILES"
If the fix commits added/modified files not covered in the existing report, regenerate by invoking the comprehension-report skill and update the PR body:
gh pr edit $PR_NUM --body "{updated body with new report}"
Skip if: No comprehension report exists in the PR body (nothing to refresh).
Before proceeding to response preparation, verify ALL of the following. This gate exists because pushing incomplete or broken fixes means another review cycle — the whole point of /gh-address is to resolve feedback definitively.
Completeness Check:
TaskList
Quality Gate:
Fix Quality:
If ANY gate fails:
.timeouts.qualityCheckMaxIterations setting, default: 3) before escalating to user via AskUserQuestionPreview response and get approval using the AskUserQuestion tool:
First, display a complete summary of what was done:
## Changes Summary
### Feedback Addressed
| Comment | Action Taken | Status |
|---------|--------------|--------|
| [Reviewer comment 1] | [What you changed] | Fixed |
| [Reviewer comment 2] | [Explanation] | Discussed |
### Commits Made
- `abc1234` - fix: description
- `def5678` - fix: description
### Quality Verification
- [x] Lint passes
- [x] Tests pass
- [x] Code review on fixes: no new issues
### Response Comment Preview
[Show the exact comment that will be posted]
Then, and only then, invoke the AskUserQuestion tool with:
IMPORTANT: The user MUST see the complete summary and response preview BEFORE being asked to approve. Never ask for approval without first showing what will be pushed and posted.
Do not push without explicit approval.
Push changes:
git push
Post summary comment:
gh pr comment $PR_NUM --body "RESPONSE"
Use this structure for the summary comment:
## Addressed Review Feedback
Thanks for the review! Here's what I've addressed:
### Changes Made
**1. [Feedback summary]**
- [What was changed]
- Commit: `abc1234`
**2. [Feedback summary]**
- [What was changed]
- Commit: `def5678`
### Discussion Points
> [Quote reviewer comment if needs discussion]
[Your response or explanation]
### Not Addressed (if any)
- **[Item]**: [Reason - needs clarification / out of scope / disagree because X]
### Thread Status
| Thread | Status |
|--------|--------|
| [Comment summary] | Resolved / Addressed / Needs discussion |
### Verification
- [x] All quality checks pass
- [x] Self-reviewed fix commits
- [x] No new issues introduced
After addressing all feedback and pushing, optionally request re-review.
Invoke the suggest-users skill using the Skill tool with re-review context. The skill will:
After the skill returns, present suggestions using the AskUserQuestion tool:
Graceful fallback: If the Skill tool invocation fails, discover reviewers inline:
gh pr view $PR_NUM --json reviews --jq '.reviews[].author.login' | sort | uniq
Present previous reviewers as options using the AskUserQuestion tool.
After reviewer selection:
gh pr edit $PR_NUM --add-reviewer {reviewer-username}
$ARGUMENTS: PR number or PR URL (required). Examples: 42, https://github.com/owner/repo/pull/42/gh-pr: Create PR with full review and reviewer suggestions/gh-review: Review a pull request/gh-start: Start work on an issue/gh-commit: Context-aware commits with change classification