/pr-shepherd
Full PR lifecycle — review, fix findings, address comments, quality gate, push, CI fix loop, merge
$ npx -y skills add nearai/ironclaw --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/pr-shepherd
Context preview
What this command does when you run it.
Full PR lifecycle — review, fix findings, address comments, quality gate, push, CI fix loop, merge
Command definition
pr-shepherd.mddescription: Full PR lifecycle — review, fix findings, address comments, quality gate, push, CI fix loop, merge
disable-model-invocation: true
allowed-tools: Bash(gh pr view:*), Bash(gh pr diff:*), Bash(gh pr comment:*), Bash(gh pr merge:*), Bash(gh pr checks:*), Bash(gh pr edit:*), Bash(gh pr list:*), Bash(gh pr checkout:*), Bash(gh api:*), Bash(gh repo view:*), Bash(gh run view:*), Bash(gh run watch:*), Bash(git diff:*), Bash(git log:*), Bash(git fetch:*), Bash(git checkout:*), Bash(git status:*), Bash(git branch:*), Bash(git add:*), Bash(git commit:*), Bash(git push:*), Bash(git merge:*), Bash(git rebase:*), Bash(cargo fmt:*), Bash(cargo clippy:*), Bash(cargo test:*), Bash(cargo check:*), Read, Edit, Write, Grep, Glob, Agent
argument-hint: "<pr-number or url> [--fix] [--merge] [--review-only]"
PR Shepherd
Full PR lifecycle: review → fix → quality gate → push → CI → merge.
Parse `$ARGUMENTS`:
- Extract PR number from bare number or `https://github.com/owner/repo/pull/123` URL.
- Flags: `--fix` (auto-fix without asking), `--merge` (merge when CI green), `--review-only` (stop after review, don't fix).
- If no PR number, detect from current branch: `gh pr list --head $(git branch --show-current) --json number --jq '.[0].number'`
- If still nothing, stop and ask the user.
---
Phase 1: Situational Awareness
Gather everything in parallel:
**PR metadata:**
gh pr view {number} --json number,title,body,author,baseRefName,headRefName,headRefOid,state,isDraft,mergeable,mergeStateStatus,files,additions,deletions,labels,reviewRequests**Diff:**
gh pr diff {number}
gh pr diff {number} --name-only**CI status:**
gh pr checks {number} --json name,status,conclusion,detailsUrl**Review comments (human + bot):**
gh api --paginate repos/{owner}/{repo}/pulls/{number}/comments
gh api --paginate repos/{owner}/{repo}/pulls/{number}/reviewsResolve `{owner}/{repo}`:
gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"'
Save `headRefOid` — needed for posting line comments later.
**Assess the situation and print a status card:**
PR #{number}: {title}
Author: {author} Base: {base} ← {head}
Size: +{additions} -{deletions} across {file_count} files
CI: {PASS|FAIL|PENDING|NONE} Mergeable: {yes|no|conflict}
Reviews: {N approved, N changes_requested, N comments-only, N bot-only}
Unresolved comments: {N}
Draft: {yes|no}**Decide the mode** based on situation:
- **Has unresolved review comments** → Phase 2a (address comments first, then review remaining)
- **No reviews yet / bot-only reviews** → Phase 2b (full deep review)
- **CI failing, no review issues** → Phase 4 (jump to CI fix)
- **Everything green + approved** → Phase 6 (ready to merge)
---
Phase 2a: Address Existing Review Comments
For each unresolved review comment or review with CHANGES_REQUESTED:
1. **Read the referenced code** at the file and line mentioned. Never assess without reading. 2. **Classify each comment:**
- ✅ **Valid & unresolved** — needs a code fix
- ✅ **Already fixed** — a later commit addressed it
- ❌ **False positive** — explain why the code is correct
- 🔧 **Nit** — optional improvement, not blocking
3. **Deduplicate** — bots (Copilot, Gemini) often post the same finding. Group by actual issue.
Present a table:
| # | Source | File:Line | Issue | Status | Planned Fix | |---|--------|-----------|-------|--------|-------------|
Wait for user confirmation (unless `--fix` flag set), then proceed to Phase 3.
---
Phase 2b: Deep Review (6 Lenses)
Read EVERY changed file in full (not just diff hunks). For PRs touching >20 files, prioritize: service logic > handlers > types > tests > docs. Batch reads in parallel via Agent tool.
IronClaw-specific checks (always)
- No `.unwrap()` or `.expect()` in production code
- Prefer `crate::` for cross-module imports (`super::` OK in tests/intra-module)
- Error types use `thiserror`
- If persistence touched, verify dual-backend parity the way `ironclaw_hooks` does it (`.claude/skills/ironclaw-reborn-testing/SKILL.md` — `src/postgres_backend/` + `src/libsql_backend/`, proved by its `parity_matrix.rs`); first confirm this crate is one of the ones that branch on backend at all (`.claude/rules/database.md`) with `for d in $(find crates -type d -name postgres_backend); do p=$(dirname "$d"); [ -d "$p/libsql_backend" ] && echo "$p"; done` — only `ironclaw_hooks` matches today
- New model-callable tools implement `ToolAdapter` (`crates/contracts/ironclaw_extension_contracts/src/tool_adapter.rs`) via an extension manifest, wired per `.claude/skills/reborn-extension-surfaces/SKILL.md`
- External tool output passes through safety layer
- Tool parameters redacted before logging/SSE
- No byte-index slicing on external strings
- Case-insensitive comparisons where needed
Correctness
Off-by-one, wrong operators, inverted conditions, unreachable code, type confusion, error propagation, broken invariants, TOCTOU races.
Edge cases & failure handling
Empty/None/zero-length input, external service failures, integer boundaries, malformed/adversarial input, partial failure handling.
Security (assume adversarial actors)
Auth/authz bypass, IDOR, injection (SQL/command/log/header), data leakage in logs/errors/API responses, resource exhaustion, replay/race conditions.
Test coverage
New public functions tested? Error paths tested? Edge cases covered? Existing tests still valid?
Architecture
Follows existing patterns? Unnecessary abstractions? Duplicated logic? Clean module dependencies?
**Present findings as a table:**
| # | Severity | Category | File:Line | Finding | Suggested Fix | |---|----------|----------|-----------|---------|---------------|
Severity: Critical > High > Medium > Low > Nit
If `--review-only` flag is set, post findings as GitHub comments (see Phase 2c) and STOP.
Otherwise, ask which findings to fix (default: all Critical + High + Medium). Then proceed to Phase 3.
Read more
description: Full PR lifecycle — review, fix findings, address comments, quality gate, push, CI fix loop, merge disable-model-invocation: true allowed-tools: Bash(gh pr view:*), Bash(gh pr diff:*), Bash(gh pr comment:*), Bash(gh pr merge:*), Bash(gh pr checks:*), Bash(gh pr edit:*), Bash(gh pr list:*), Bash(gh pr checkout:*), Bash(gh api:*), Bash(gh repo view:*), Bash(gh run view:*), Bash(gh run watch:*), Bash(git diff:*), Bash(git log:*), Bash(git fetch:*), Bash(git checkout:*), Bash(git status:*), Bash(git branch:*), Bash(git add:*), Bash(git commit:*), Bash(git push:*), Bash(git merge:*), Bash(git rebase:*), Bash(cargo fmt:*), Bash(cargo clippy:*), Bash(cargo test:*), Bash(cargo check:*), Read, Edit, Write, Grep, Glob, Agent argument-hint: "<pr-number or url> [--fix] [--merge] [--review-only]"
PR Shepherd
Full PR lifecycle: review → fix → quality gate → push → CI → merge.
Parse `$ARGUMENTS`:
- Extract PR number from bare number or `https://github.com/owner/repo/pull/123` URL.
- Flags: `--fix` (auto-fix without asking), `--merge` (merge when CI green), `--review-only` (stop after review, don't fix).
- If no PR number, detect from current branch: `gh pr list --head $(git branch --show-current) --json number --jq '.[0].number'`
- If still nothing, stop and ask the user.
---
Phase 1: Situational Awareness
Gather everything in parallel:
**PR metadata:**
gh pr view {number} --json number,title,body,author,baseRefName,headRefName,headRefOid,state,isDraft,mergeable,mergeStateStatus,files,additions,deletions,labels,reviewRequests**Diff:**
gh pr diff {number}
gh pr diff {number} --name-only**CI status:**
gh pr checks {number} --json name,status,conclusion,detailsUrl**Review comments (human + bot):**
gh api --paginate repos/{owner}/{repo}/pulls/{number}/comments
gh api --paginate repos/{owner}/{repo}/pulls/{number}/reviewsResolve `{owner}/{repo}`:
gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"'
Save `headRefOid` — needed for posting line comments later.
**Assess the situation and print a status card:**
PR #{number}: {title}
Author: {author} Base: {base} ← {head}
Size: +{additions} -{deletions} across {file_count} files
CI: {PASS|FAIL|PENDING|NONE} Mergeable: {yes|no|conflict}
Reviews: {N approved, N changes_requested, N comments-only, N bot-only}
Unresolved comments: {N}
Draft: {yes|no}**Decide the mode** based on situation:
- **Has unresolved review comments** → Phase 2a (address comments first, then review remaining)
- **No reviews yet / bot-only reviews** → Phase 2b (full deep review)
- **CI failing, no review issues** → Phase 4 (jump to CI fix)
- **Everything green + approved** → Phase 6 (ready to merge)
---
Phase 2a: Address Existing Review Comments
For each unresolved review comment or review with CHANGES_REQUESTED:
1. **Read the referenced code** at the file and line mentioned. Never assess without reading. 2. **Classify each comment:**
- ✅ **Valid & unresolved** — needs a code fix
- ✅ **Already fixed** — a later commit addressed it
- ❌ **False positive** — explain why the code is correct
- 🔧 **Nit** — optional improvement, not blocking
3. **Deduplicate** — bots (Copilot, Gemini) often post the same finding. Group by actual issue.
Present a table:
| # | Source | File:Line | Issue | Status | Planned Fix | |---|--------|-----------|-------|--------|-------------|
Wait for user confirmation (unless `--fix` flag set), then proceed to Phase 3.
---
Phase 2b: Deep Review (6 Lenses)
Read EVERY changed file in full (not just diff hunks). For PRs touching >20 files, prioritize: service logic > handlers > types > tests > docs. Batch reads in parallel via Agent tool.
IronClaw-specific checks (always)
- No `.unwrap()` or `.expect()` in production code
- Prefer `crate::` for cross-module imports (`super::` OK in tests/intra-module)
- Error types use `thiserror`
- If persistence touched, verify dual-backend parity the way `ironclaw_hooks` does it (`.claude/skills/ironclaw-reborn-testing/SKILL.md` — `src/postgres_backend/` + `src/libsql_backend/`, proved by its `parity_matrix.rs`); first confirm this crate is one of the ones that branch on backend at all (`.claude/rules/database.md`) with `for d in $(find crates -type d -name postgres_backend); do p=$(dirname "$d"); [ -d "$p/libsql_backend" ] && echo "$p"; done` — only `ironclaw_hooks` matches today
- New model-callable tools implement `ToolAdapter` (`crates/contracts/ironclaw_extension_contracts/src/tool_adapter.rs`) via an extension manifest, wired per `.claude/skills/reborn-extension-surfaces/SKILL.md`
- External tool output passes through safety layer
- Tool parameters redacted before logging/SSE
- No byte-index slicing on external strings
- Case-insensitive comparisons where needed
Correctness
Off-by-one, wrong operators, inverted conditions, unreachable code, type confusion, error propagation, broken invariants, TOCTOU races.
Edge cases & failure handling
Empty/None/zero-length input, external service failures, integer boundaries, malformed/adversarial input, partial failure handling.
Security (assume adversarial actors)
Auth/authz bypass, IDOR, injection (SQL/command/log/header), data leakage in logs/errors/API responses, resource exhaustion, replay/race conditions.
Test coverage
New public functions tested? Error paths tested? Edge cases covered? Existing tests still valid?
Architecture
Follows existing patterns? Unnecessary abstractions? Duplicated logic? Clean module dependencies?
**Present findings as a table:**
| # | Severity | Category | File:Line | Finding | Suggested Fix | |---|----------|----------|-----------|---------|---------------|
Severity: Critical > High > Medium > Low > Nit
If `--review-only` flag is set, post findings as GitHub comments (see Phase 2c) and STOP.
Otherwise, ask which findings to fix (default: all Critical + High + Medium). Then proceed to Phase 3.
IronClaw is an Agent OS focused on privacy, security and extensibility

