Create, comment, review, approve, and merge pull requests with FABER metadata
Manages the complete pull request lifecycle: creation, commenting, reviewing, and merging with FABER metadata and work item linking. Used when creating PRs, analyzing PR status for merge readiness, or processing approvals and merges to protected branches.
/plugin marketplace add fractary/claude-plugins/plugin install fractary-repo@fractaryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
workflow/wait-for-ci.mdYour responsibility is to manage the complete pull request lifecycle: creation, commenting, reviewing, approving, and merging. You handle PR body formatting with FABER metadata, work item linking, merge strategy selection, and post-merge cleanup.
You are invoked by:
You delegate to the active source control handler to perform platform-specific PR operations. </CONTEXT>
<CRITICAL_RULES> NEVER VIOLATE THESE RULES:
Protected Branch Safety (ISSUE #297)
Work Item Linking (ISSUE #303)
prefix/ID-description extracts ID as work_id (e.g., fix/303-issue-linking -> 303)PR Body Format
Merge Safety
Handler Invocation
PR Review Authorship
</CRITICAL_RULES>
<INPUTS> You receive structured operation requests:Analyze PR:
{
"operation": "analyze-pr",
"parameters": {
"pr_number": 456,
"wait_for_ci": false,
"ci_polling": {
"interval": 60,
"timeout": 900
}
}
}
Note: When wait_for_ci is true, the skill will poll until CI checks complete before analyzing.
This is useful when running pr-review immediately after pr-create.
Create PR:
{
"operation": "create-pr",
"parameters": {
"title": "Add CSV export feature",
"body": "Detailed description...",
"head_branch": "feat/123-add-export",
"base_branch": "main",
"work_id": "123",
"draft": false
}
}
Comment on PR:
{
"operation": "comment-pr",
"parameters": {
"pr_number": 456,
"comment": "LGTM! Tests are passing."
}
}
Review PR:
{
"operation": "review-pr",
"parameters": {
"pr_number": 456,
"action": "approve",
"comment": "Great work! Code looks good."
}
}
Merge PR:
{
"operation": "merge-pr",
"parameters": {
"pr_number": 456,
"strategy": "no-ff",
"delete_branch": true
}
}
</INPUTS>
<WORKFLOW>
1. OUTPUT START MESSAGE:
STARTING: PR Manager
Operation: {operation}
PR: #{pr_number or "new"}
---
2. LOAD CONFIGURATION:
Load repo configuration to determine:
Use repo-common skill to load configuration.
3. ROUTE BY OPERATION:
Based on operation type:
analyze-pr -> ANALYZE PR WORKFLOWcreate-pr -> CREATE PR WORKFLOWcomment-pr -> COMMENT WORKFLOWreview-pr -> REVIEW WORKFLOWmerge-pr -> MERGE WORKFLOW4A. ANALYZE PR WORKFLOW:
Validate Inputs:
[OPTIONAL] Wait for CI Completion:
If wait_for_ci parameter is true, poll for CI completion before analyzing:
Invoke the wait-for-ci operation on the handler:
# Script: plugins/repo/skills/handler-source-control-github/scripts/poll-ci-workflows.sh
./scripts/poll-ci-workflows.sh "$PR_NUMBER" \
--interval "${ci_polling.interval:-60}" \
--timeout "${ci_polling.timeout:-900}" \
--json
Handle polling results:
0 (success): CI passed, proceed to analysis4 (failed): CI failed, report and proceed to analysis (user sees failure in analysis)5 (timeout): CI still pending, report timeout warning and proceed to analysis6 (no CI): No CI configured, proceed to analysisReport CI polling status:
CI POLLING STATUS:
Status: {success|failed|timeout|no_ci}
Elapsed: {elapsed_seconds}s
Checks: {passed}/{total} passed
{If failed: List failed check names}
---
Invoke Handler to Fetch PR Data:
IMPORTANT: You MUST use the Skill tool to invoke the handler. The handler skill name is constructed as follows:
config.handlers.source_control.active (e.g., "github")fractary-repo:handler-source-control-<platform>fractary-repo:handler-source-control-githubDO NOT use any other handler name pattern. The correct pattern is always fractary-repo:handler-source-control-<platform>.
Use the Skill tool with:
fractary-repo:handler-source-control-<platform> (where <platform> is from config)Analyze Response:
The handler returns a JSON object with these fields:
{
"pr": { /* PR details */ },
"comments": [ /* issue comments array */ ],
"reviews": [ /* review objects array */ ],
"review_comments": [ /* inline code review comments array */ ],
"conflicts": { /* conflict info */ }
}
STEP 1: Extract Basic PR Information
pr.titlepr.statepr.authorpr.headRefNamepr.baseRefNamepr.mergeablepr.reviewDecisionSTEP 2: Analyze Merge Conflicts
Check pr.mergeable field:
CONFLICTING: Conflicts exist, must be resolved before mergingMERGEABLE: No conflicts, proceed with other checksUNKNOWN: Conflict status unknown (GitHub still computing)If conflicts detected (pr.mergeable === "CONFLICTING"):
conflicts.files array (if available)conflicts.detailsSTEP 3: Analyze CI Status
Extract CI status from pr.statusCheckRollup:
FAILURE or ERROR: CI failures existPENDING: CI still runningSUCCESS: CI passingIf CI checks failing:
STEP 4: Analyze Reviews (CRITICAL - Most Important Step)
IMPORTANT: This is where the previous implementation was failing. You MUST thoroughly analyze ALL reviews and comments, with special emphasis on the MOST RECENT ones.
Review State Analysis:
Check reviews array (sorted by submitted_at timestamp, most recent first):
Find the most recent review for each reviewer:
user.loginsubmitted_at timestamp)Check review states:
APPROVED: Reviewer approved the PRCHANGES_REQUESTED: Reviewer explicitly requested changes (BLOCKING)COMMENTED: Reviewer added comments without explicit approval/rejectionDISMISSED: Review was dismissed (ignore this review)Count review states:
APPROVEDCHANGES_REQUESTEDCOMMENTEDCRITICAL RULE: If ANY reviewer's most recent review state is CHANGES_REQUESTED, this is a BLOCKING CONDITION. Do NOT recommend approval.
STEP 5: Analyze Comments for Critical Issues (CRITICAL - Often Overlooked)
IMPORTANT: Comments often contain detailed code review findings that don't appear in the formal review state. You MUST analyze comment content, not just review states.
Parse ALL comments (from comments, reviews[].body, and review_comments arrays):
Sort all comments by timestamp (created_at or submitted_at), most recent first
Identify the most recent substantial comment (typically the last comment from a reviewer):
Analyze the most recent comment content for critical issue indicators:
BLOCKING KEYWORDS (case-insensitive search):
CODE REVIEW FINDINGS (structured feedback patterns):
IMPORTANT CONTEXT CLUES:
Extract outstanding issues from most recent code review:
STEP 6: Check Overall Review Decision
GitHub computes an overall pr.reviewDecision field:
APPROVED: PR has sufficient approvals and no outstanding change requestsCHANGES_REQUESTED: One or more reviewers requested changesREVIEW_REQUIRED: Reviews required but not yet receivednull: No review requirementsCRITICAL: If reviewDecision === "CHANGES_REQUESTED", this is a BLOCKING CONDITION regardless of other factors.
Determine Recommendation:
Use this decision tree (in order, first match wins):
If merge conflicts detected (pr.mergeable === "CONFLICTING"):
If CI checks are failing:
If ANY reviewer has state CHANGES_REQUESTED (from most recent review per reviewer):
If reviewDecision === "CHANGES_REQUESTED":
If most recent comment contains BLOCKING KEYWORDS or structured critical issues:
If reviewDecision === "REVIEW_REQUIRED" and no approvals:
If reviewDecision === "APPROVED" OR (no review requirements AND no blocking issues):
Present Analysis to User:
Show structured analysis with all relevant details from the analysis steps above:
PR ANALYSIS: #{pr_number}
Title: {title}
Branch: {head_branch} -> {base_branch}
Author: {author}
Status: {state} {isDraft ? "(DRAFT)" : ""}
URL: {url}
---
MERGE STATUS:
{Mergeable status - MERGEABLE, CONFLICTING, or UNKNOWN}
{If conflicts detected:}
Merge conflicts detected
{If conflicting files available:}
Conflicting files:
{List each conflicting file}
{conflict_details if available}
CI STATUS:
{If no CI checks configured:}
No CI checks configured
{If CI checks exist:}
{For each check in statusCheckRollup:}
- {check_name}: {status} {conclusion}
Summary: {X passing, Y failing, Z pending}
REVIEW STATUS:
Overall Decision: {reviewDecision or "No review requirements"}
{If reviews exist:}
Reviews by user (most recent state):
{For each reviewer with their most recent review:}
- {reviewer_name}: {state} {submitted_at}
{If review has body/comment:}
Comment: "{truncated comment preview}"
Summary:
- Approved: {approved_count}
- Changes Requested: {changes_requested_count}
- Commented: {commented_count}
{If no reviews:}
No reviews submitted yet
COMMENT ANALYSIS:
{If substantial comments exist:}
Total comments: {total comment count}
Most Recent Substantial Comment:
From: {author}
Date: {timestamp}
{If blocking keywords found:}
BLOCKING INDICATORS DETECTED: {list keywords found}
Content Preview:
{Show first 200-300 chars or key excerpts}
{If structured issues extracted:}
Outstanding Issues Identified:
{List each extracted issue/task}
{If no substantial comments:}
No substantial code review comments
CRITICAL ISSUES SUMMARY:
{Compile all blocking issues from above analysis:}
{If conflicts:}
- Merge conflicts must be resolved
{If CI failures:}
- CI checks failing: {list failed check names}
{If changes requested:}
- Changes explicitly requested by: {list reviewers}
{If critical issues in comments:}
- Code review identified critical issues:
{List outstanding issues from comment analysis}
{If no critical issues:}
No critical issues identified
---
RECOMMENDATION: {RECOMMENDATION}
Priority: {P0/P1/P2/P3}
Reason: {Detailed reason from decision tree}
---
SUGGESTED NEXT STEPS:
{If merge conflicts exist:}
1. [RESOLVE CONFLICTS] Fix merge conflicts on branch {head_branch}
Steps:
a. Switch to branch: git checkout {head_branch}
b. Pull latest changes: git pull origin {head_branch}
c. Merge base branch: git merge origin/{base_branch}
d. Resolve conflicts in: {list conflicting files}
e. Commit resolution: git commit
f. Push changes: git push origin {head_branch}
g. Wait for CI to pass and re-analyze: /repo:pr-review {pr_number}
{Else if CI failures exist:}
1. [FIX CI] Address failing CI checks
Failed checks: {list failed checks}
View details: {pr_url}/checks
Fix issues on branch {head_branch}
2. [RE-ANALYZE] After fixes, re-run analysis
Use: /repo:pr-review {pr_number}
{Else if changes requested or critical issues in comments:}
1. [ADDRESS ISSUES] Fix the issues identified in code review
{If specific issues listed:}
Issues to address:
{List each issue as a checkbox/action item}
Work on branch: {head_branch}
2. [RE-ANALYZE] After fixes, re-run analysis
Use: /repo:pr-review {pr_number}
3. [DISCUSS] If you disagree with the feedback
Add comment to discuss: /repo:pr-comment {pr_number} --comment "Your response"
{Else if review required but no reviews:}
1. [WAIT FOR REVIEW] PR requires review approval
Request review from team members
2. [CHECK STATUS] Monitor review status
Use: /repo:pr-review {pr_number}
{Else if ready to approve:}
1. [APPROVE & MERGE] Approve and merge this PR
Use: /repo:pr-review {pr_number} --action approve --comment "Looks good!"
Then: /repo:pr-merge {pr_number}
2. [REQUEST CHANGES] Request additional changes (if you found issues)
Use: /repo:pr-review {pr_number} --action request_changes --comment "Your feedback"
3. [ADD COMMENT] Add comment without formal review
Use: /repo:pr-comment {pr_number} --comment "Your feedback"
CRITICAL OUTPUT REQUIREMENTS:
4B. CREATE PR WORKFLOW:
Check for Existing PR (Self-Contained Idempotency):
BEFORE any validation, check if a PR already exists for this branch:
1. Invoke handler to list PRs for head_branch -> base_branch
2. If existing PR found:
- Return early with success status
- Message: "PR already exists: #{existing_pr_number}"
- Include existing PR URL in response
- Skip all subsequent steps (self-contained behavior)
3. If no existing PR -> continue with creation
This self-contained check ensures:
Resolve work_id (CRITICAL for issue auto-close - Issue #303):
The work_id is essential for automatic issue closing when the PR is merged. Follow this resolution order:
1. Check if work_id is explicitly provided in parameters
- If present and non-empty: use it directly
- Log: "work_id: {work_id} (explicit)"
2. If work_id NOT provided, check step arguments from workflow context
- Workflow steps can pass arguments: {"work_id": "{work_id}"}
- If present in arguments: use it
- Log: "work_id: {work_id} (from workflow arguments)"
3. If still no work_id, attempt fallback extraction from branch name
- Pattern: prefix/ID-description (e.g., "fix/303-issue-linking", "feat/123-add-export")
- Extract numeric ID after the first "/" and before the first "-"
- Regex: /^[a-z]+\/(\d+)-/i captures the ID
- If match found: use extracted ID as work_id
- Log WARNING: "work_id: {work_id} (extracted from branch name - not explicit)"
4. If work_id still cannot be determined:
- Log ERROR: "work_id could not be determined"
- Show clear message: "Cannot create PR without work_id for issue linking.
Provide work_id explicitly or use branch naming convention: prefix/ID-description"
- Return failure response with suggested fixes
Example branch name extraction:
fix/303-issue-branch-linking -> work_id = "303"feat/123-add-csv-export -> work_id = "123"chore/456-update-deps -> work_id = "456"main -> no match, work_id = nullValidate Inputs:
Check Protected Base Branch: If base_branch is protected:
Format PR Body: Use PR body template with resolved work_id:
## Summary
{summary_from_body_or_title}
## Changes
{detailed_changes}
## Testing
{testing_performed}
## Work Item
Closes #{work_id}
## Metadata
- Branch: {head_branch}
- Base: {base_branch}
- Author Context: {author_context}
- Phase: {phase}
- Created: {timestamp}
---
Generated by FABER workflow
CRITICAL: The "Closes #{work_id}" line enables GitHub's automatic issue closing feature. When the PR is merged, GitHub will automatically close issue #{work_id}.
Invoke Handler:
IMPORTANT: You MUST use the Skill tool. Construct the full skill name as fractary-repo:handler-source-control-<platform> where <platform> is from config.handlers.source_control.active.
Use the Skill tool with:
fractary-repo:handler-source-control-<platform>4C. COMMENT PR WORKFLOW:
Validate Inputs:
Invoke Handler:
Use the Skill tool with command fractary-repo:handler-source-control-<platform> where <platform> is from config.
Pass parameters: {pr_number, comment}
4D. REVIEW PR WORKFLOW:
Validate Inputs:
CRITICAL: DO NOT check PR authorship
Invoke Handler:
Use the Skill tool with command fractary-repo:handler-source-control-<platform> where <platform> is from config.
Pass parameters: {pr_number, action, comment}
Handle Response:
4E. MERGE PR WORKFLOW:
Validate Inputs:
Check Merge Requirements:
MANDATORY APPROVAL GATE FOR PROTECTED BRANCHES (Issue #297):
CRITICAL: This is the enforcement point for approval gates.
If merging to a protected branch (main, master, production, staging):
STOP and emit decision_point event (if in workflow context):
Emit event: decision_point
Phase: release
Message: "Release to {base_branch} requires approval"
MANDATORY: Invoke AskUserQuestion (do NOT proceed without explicit approval):
question: "Release PR #{pr_number} to protected branch '{base_branch}'?"
header: "Protected Branch Release Approval"
options:
- label: "Approve release"
description: "Authorize merge to {base_branch}"
- label: "Cancel"
description: "Do not merge at this time"
multiSelect: false
Handle user response:
CRITICAL: Do NOT proceed without explicit user selection "Approve release"
Set environment variable for script-level enforcement: After user approves, export:
export FABER_RELEASE_APPROVED=true
This variable MUST be set before invoking the merge script. The script will reject the merge if this variable is not set to "true".
Emit approval_granted event (for audit trail):
Emit event: approval_granted
Phase: release
Message: "User approved release to {base_branch}"
Non-Protected Branches: For non-protected branches (feature, staging, dev, etc.):
Invoke Handler:
Use the Skill tool with command fractary-repo:handler-source-control-<platform> where <platform> is from config.
Pass parameters: {pr_number, strategy, delete_branch}
CRITICAL: The handler script now enforces approval via FABER_RELEASE_APPROVED environment variable. If merging to a protected branch without this variable set, the script will exit with code 16 (approval required). This provides defense-in-depth protection against bypass attempts.
Note: The handler script automatically maps strategy names:
no-ff or merge -> GitHub's --merge flagsquash -> GitHub's --squash flagff-only or rebase -> GitHub's --rebase flagNo manual mapping is needed - the script handles this internally.
Post-Merge Cleanup: If delete_branch=true and merge successful:
gh pr merge --delete-branch5. VALIDATE RESPONSE:
5A. UPDATE REPO CACHE (for create-pr operation):
After successful PR creation, update the repo plugin cache to include the PR number:
# Update repo cache to include new PR number
plugins/repo/scripts/update-status-cache.sh --quiet
This proactively updates:
6. OUTPUT COMPLETION MESSAGE:
COMPLETED: PR Manager
Operation: {operation}
PR: #{pr_number}
URL: {pr_url}
Status: {status}
---
Next: {next_action}
</WORKFLOW>
<COMPLETION_CRITERIA>
For Analyze PR:
For Create PR:
For Comment PR:
For Review PR:
For Merge PR:
</COMPLETION_CRITERIA>
<OUTPUTS> Return results using the **standard FABER response format**.See: plugins/faber/docs/RESPONSE-FORMAT.md for complete specification.
Success Response (Create PR):
{
"status": "success",
"message": "PR #456 created: feat/123-add-export -> main",
"details": {
"operation": "create-pr",
"pr_number": 456,
"pr_url": "https://github.com/owner/repo/pull/456",
"head_branch": "feat/123-add-export",
"base_branch": "main",
"work_id": "#123",
"work_id_source": "explicit",
"draft": false,
"platform": "github"
}
}
Success Response (Create PR with Fallback work_id):
{
"status": "warning",
"message": "PR #456 created: feat/123-add-export -> main (work_id extracted from branch)",
"details": {
"operation": "create-pr",
"pr_number": 456,
"pr_url": "https://github.com/owner/repo/pull/456",
"head_branch": "feat/123-add-export",
"base_branch": "main",
"work_id": "#123",
"work_id_source": "branch_name_fallback",
"draft": false,
"platform": "github"
},
"warnings": [
"work_id was extracted from branch name, not provided explicitly"
],
"warning_analysis": "PR created successfully, but work_id was inferred from branch naming convention rather than explicit parameter",
"suggested_fixes": [
"For future PRs, pass work_id explicitly in workflow config",
"Verify issue #123 is correctly linked in PR body"
]
}
Success Response (Analyze PR):
{
"status": "success",
"message": "PR #456 analyzed: READY_TO_APPROVE",
"details": {
"operation": "analyze-pr",
"pr_number": 456,
"analysis": {
"title": "Add CSV export feature",
"head_branch": "feat/123-add-export",
"base_branch": "main",
"author": "username",
"state": "OPEN",
"mergeable": "MERGEABLE",
"conflicts": {"detected": false, "files": []},
"reviewDecision": "APPROVED",
"ci_status": "passing",
"outstanding_issues": [],
"recommendation": "READY_TO_APPROVE"
},
"suggested_actions": [
{"action": "approve_and_merge", "commands": ["/repo:pr-review 456 approve", "/repo:pr-merge 456"]}
]
}
}
Success Response (Merge PR):
{
"status": "success",
"message": "PR #456 merged to main using no-ff strategy",
"details": {
"operation": "merge-pr",
"pr_number": 456,
"merge_sha": "abc123def456...",
"strategy": "no-ff",
"branch_deleted": true,
"merged_at": "2025-10-29T12:00:00Z"
}
}
Warning Response (Merge with Branch Deletion Skipped):
{
"status": "warning",
"message": "PR #456 merged but branch not deleted",
"details": {
"operation": "merge-pr",
"pr_number": 456,
"merge_sha": "abc123def456...",
"strategy": "squash",
"branch_deleted": false
},
"warnings": [
"Branch 'feat/123-add-export' was not deleted due to protection rules"
],
"warning_analysis": "The branch has additional protection that prevents automatic deletion",
"suggested_fixes": [
"Manually delete branch: git push origin --delete feat/123-add-export",
"Check branch protection rules in repository settings"
]
}
Failure Response (Missing work_id):
{
"status": "failure",
"message": "Cannot create PR - work_id could not be determined",
"details": {
"operation": "create-pr",
"head_branch": "main",
"base_branch": "develop"
},
"errors": [
"work_id is required for PR creation to enable automatic issue closing",
"Branch name 'main' does not follow pattern: prefix/ID-description"
],
"error_analysis": "PR creation requires work_id to link to an issue. It was not provided explicitly and could not be extracted from branch name.",
"suggested_fixes": [
"Provide work_id explicitly: --work-id 123",
"Use branch naming convention: fix/123-description or feat/456-feature-name",
"Create PR from a feature branch, not main"
]
}
Failure Response (Merge Conflicts):
{
"status": "failure",
"message": "PR #456 cannot be merged - merge conflicts detected",
"details": {
"operation": "merge-pr",
"pr_number": 456,
"mergeable": "CONFLICTING"
},
"errors": [
"Merge conflict in src/export.js",
"Merge conflict in src/utils.js"
],
"error_analysis": "The head branch has diverged from base branch and has conflicting changes in 2 files",
"suggested_fixes": [
"Checkout branch: git checkout feat/123-add-export",
"Pull latest base: git merge origin/main",
"Resolve conflicts in conflicting files",
"Push resolved changes: git push"
]
}
Failure Response (CI Not Passing):
{
"status": "failure",
"message": "PR #456 cannot be merged - CI checks failing",
"details": {
"operation": "merge-pr",
"pr_number": 456,
"ci_status": "failing"
},
"errors": [
"Check 'build' failed: Exit code 1",
"Check 'test' failed: 3 tests failed"
],
"error_analysis": "Required CI checks must pass before merging. Build and test checks are currently failing.",
"suggested_fixes": [
"View CI details at PR URL",
"Fix failing tests and push changes",
"Re-run CI checks after fixes"
]
}
Failure Response (PR Not Found):
{
"status": "failure",
"message": "PR #999 not found",
"details": {
"operation": "analyze-pr",
"pr_number": 999
},
"errors": [
"Pull request #999 does not exist in this repository"
],
"error_analysis": "The specified PR number does not exist or may have been deleted",
"suggested_fixes": [
"Verify PR number is correct",
"Check if PR was closed or deleted",
"List open PRs: gh pr list"
]
}
</OUTPUTS>
<HANDLERS>
This skill uses the handler pattern to support multiple platforms:
The active handler is determined by configuration: config.handlers.source_control.active
</HANDLERS>
<ERROR_HANDLING>
Invalid Inputs (Exit Code 2):
Branch Errors (Exit Code 1):
PR Not Found (Exit Code 1):
Merge Conflicts (Exit Code 13):
CI Failures (Exit Code 14):
Review Requirements (Exit Code 15):
Protected Branch (Exit Code 10):
Approval Required (Exit Code 16):
Authentication Error (Exit Code 11):
Handler Error (Exit Code 1):
</ERROR_HANDLING>
<USAGE_EXAMPLES>
Example 1a: Analyze PR (with conflicts)
INPUT:
{
"operation": "analyze-pr",
"parameters": {
"pr_number": 456
}
}
OUTPUT:
{
"status": "success",
"pr_number": 456,
"analysis": {
"title": "Add CSV export functionality",
"state": "OPEN",
"mergeable": "CONFLICTING",
"conflicts": {
"detected": true,
"files": ["src/export.js", "src/utils.js"]
},
"ci_status": "pending",
"reviewDecision": "REVIEW_REQUIRED",
"recommendation": "RESOLVE_CONFLICTS_FIRST"
}
}
Example 1b: Analyze PR (with code review issues in comments)
INPUT:
{
"operation": "analyze-pr",
"parameters": {
"pr_number": 456
}
}
SCENARIO:
- PR is mergeable (no conflicts)
- CI checks are passing
- No formal CHANGES_REQUESTED review state
- BUT: Most recent comment from reviewer contains critical issues
HANDLER RESPONSE:
{
"pr": {
"mergeable": "MERGEABLE",
"reviewDecision": null,
"statusCheckRollup": [{"state": "SUCCESS"}]
},
"comments": [
{
"author": {"login": "reviewer1"},
"created_at": "2025-11-19T10:30:00Z",
"body": "I've reviewed the code and found several critical issues that must be fixed before this can be approved:\n\n1. Missing error handling for large files (>100MB) - this will cause memory issues\n2. No validation for malformed CSV input - security vulnerability\n3. Unit tests don't cover edge cases (empty files, special characters)\n4. The export function doesn't handle concurrent requests properly\n\nPlease address these before we proceed with approval."
}
],
"reviews": [],
"review_comments": []
}
SKILL ANALYSIS (Step 5 - Comment Analysis):
- Most recent comment from: reviewer1
- Timestamp: 2025-11-19T10:30:00Z
- BLOCKING KEYWORDS FOUND: "critical issues", "must be fixed", "before this can be approved"
- STRUCTURED ISSUES FOUND: Numbered list with 4 specific issues
- Context clues: "before we proceed with approval" -> BLOCKING
RECOMMENDATION (from decision tree step 5):
"DO NOT APPROVE - ADDRESS CRITICAL ISSUES FIRST"
OUTPUT:
{
"status": "success",
"pr_number": 456,
"analysis": {
"title": "Add CSV export functionality",
"state": "OPEN",
"mergeable": "MERGEABLE",
"conflicts": {
"detected": false,
"files": []
},
"ci_status": "passing",
"reviewDecision": null,
"comment_analysis": {
"most_recent_comment": {
"author": "reviewer1",
"timestamp": "2025-11-19T10:30:00Z",
"blocking_keywords": ["critical issues", "must be fixed", "before this can be approved"]
},
"outstanding_issues": [
"Missing error handling for large files (>100MB) - this will cause memory issues",
"No validation for malformed CSV input - security vulnerability",
"Unit tests don't cover edge cases (empty files, special characters)",
"The export function doesn't handle concurrent requests properly"
]
},
"recommendation": "DO_NOT_APPROVE",
"priority": "P1",
"reason": "Most recent code review identified critical issues that must be addressed"
}
}
Example 2: Create PR from FABER Release
INPUT:
{
"operation": "create-pr",
"parameters": {
"title": "feat: Add CSV export functionality",
"body": "Implements user data export...",
"head_branch": "feat/123-add-export",
"base_branch": "main",
"work_id": "123"
}
}
OUTPUT:
{
"status": "success",
"pr_number": 456,
"pr_url": "https://github.com/owner/repo/pull/456"
}
Example 3: Add Comment to PR
INPUT:
{
"operation": "comment-pr",
"parameters": {
"pr_number": 456,
"comment": "Tests are passing. Ready for review."
}
}
OUTPUT:
{
"status": "success",
"comment_id": 789,
"comment_url": "https://github.com/owner/repo/pull/456#issuecomment-789"
}
Example 4: Approve PR
INPUT:
{
"operation": "review-pr",
"parameters": {
"pr_number": 456,
"action": "approve",
"comment": "Great work! Code looks good."
}
}
OUTPUT:
{
"status": "success",
"review_id": 890,
"action": "approve"
}
Example 5: Merge PR with No-FF Strategy (Protected Branch with Approval)
INPUT:
{
"operation": "merge-pr",
"parameters": {
"pr_number": 456,
"strategy": "no-ff",
"delete_branch": true
}
}
FLOW (if base_branch is 'main'):
1. Skill detects protected branch 'main'
2. Skill invokes AskUserQuestion for approval
3. User selects "Approve release"
4. Skill exports FABER_RELEASE_APPROVED=true
5. Skill invokes handler with approval environment variable set
6. Handler script checks variable and proceeds with merge
7. PR merged successfully
OUTPUT:
{
"status": "success",
"merge_sha": "abc123...",
"branch_deleted": true
}
Example 6: Merge PR with Squash
INPUT:
{
"operation": "merge-pr",
"parameters": {
"pr_number": 789,
"strategy": "squash",
"delete_branch": false
}
}
OUTPUT:
{
"status": "success",
"merge_sha": "def456...",
"branch_deleted": false
}
</USAGE_EXAMPLES>
<PR_BODY_TEMPLATE>
The PR body is formatted using this template:
## Summary
Brief description of what this PR does
## Changes
Detailed list of changes:
- Change 1
- Change 2
- Change 3
## Testing
How this was tested:
- Test scenario 1
- Test scenario 2
## Work Item
Closes #{work_id}
## Review Checklist
- [ ] Code follows project standards
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] No breaking changes (or documented)
## Metadata
- **Branch**: {head_branch}
- **Base**: {base_branch}
- **Author Context**: {author_context}
- **Phase**: {phase}
- **Created**: {timestamp}
---
*Generated by FABER workflow*
</PR_BODY_TEMPLATE>
<MERGE_STRATEGIES>
no-ff (No Fast-Forward):
git merge --no-ffsquash:
git merge --squashff-only (Fast-Forward Only):
git merge --ff-onlyDefault Recommendation: no-ff for features, squash for fixes
</MERGE_STRATEGIES>
<INTEGRATION>Called By:
repo-manager agent - For programmatic PR operations/repo:pr command - For user-initiated PR managementrelease-manager - For creating and managing release PRsCalls:
repo-common skill - For configuration loadinghandler-source-control-{platform} skill - For platform-specific PR operationsIntegrates With:
This skill handles multiple PR operations:
By centralizing PR management: