Marketplace

feedback-handler

Handles FABER workflow feedback requests - posting to issues and tracking responses

model: claude-opus-4-5

$ 설치

git clone https://github.com/fractary/claude-plugins /tmp/claude-plugins && cp -r /tmp/claude-plugins/plugins/faber/skills/feedback-handler ~/.claude/skills/claude-plugins

// tip: Run this command in your terminal to install the skill


name: feedback-handler description: Handles FABER workflow feedback requests - posting to issues and tracking responses model: claude-opus-4-5

Feedback Handler Skill

  1. Posting feedback requests to issue comments when feedback is needed
  2. Tracking feedback state in run state files
  3. Formatting feedback requests with clear context and options

You work with the work plugin (comment-creator) to post comments and the run-manager to update state.

<CRITICAL_RULES>

  1. ALWAYS emit decision_point event when requesting feedback
  2. ALWAYS update run state with feedback_request details
  3. ALWAYS format feedback comments with clear context and options
  4. ALWAYS include example @faber command in issue comments (for future integration)
  5. NEVER post feedback request without updating state first
  6. ALWAYS track notification_sent status in state </CRITICAL_RULES>

Request feedback from user and optionally post to issue.

{
  "operation": "request-feedback",
  "parameters": {
    "run_id": "fractary/claude-plugins/abc-123-...",
    "work_id": "258",
    "phase": "architect",
    "step": "design-review",
    "feedback_type": "approval",
    "prompt": "Please review the architectural design and approve to proceed.",
    "options": ["approve", "reject", "request_changes"],
    "context": {
      "artifact_path": "/specs/WORK-00258-design.md",
      "summary": "Design proposes 3-layer architecture with handler pattern"
    },
    "post_to_issue": true,
    "cli_prompt": true
  }
}

Parameters:

  • run_id (required): FABER run identifier
  • work_id (optional): Issue ID for posting comment
  • phase (required): Current workflow phase
  • step (required): Current workflow step
  • feedback_type (required): Type of feedback (see FEEDBACK_TYPES)
  • prompt (required): Human-readable question/request
  • options (required): Array of valid response options
  • context (optional): Additional context for the decision
  • post_to_issue (optional, default: true if work_id present): Post as issue comment
  • cli_prompt (optional, default: true): Show prompt in CLI

process-response operation

Process a feedback response and update state.

{
  "operation": "process-response",
  "parameters": {
    "run_id": "fractary/claude-plugins/abc-123-...",
    "request_id": "fr-20251206-001",
    "response": "approve",
    "comment": "Looks good, proceed with implementation",
    "source": "cli",
    "user": "jmcwilliam"
  }
}

<FEEDBACK_TYPES>

TypeDescriptionDefault Options
approvalBinary approval decision["approve", "reject"]
confirmationConfirm destructive action["confirm", "cancel"]
selectionChoose from options[custom list required]
clarificationRequest information[free text accepted]
reviewReview with feedback option["approve", "request_changes", "reject"]
error_resolutionError occurred, decide action["retry", "skip", "abort"]
</FEEDBACK_TYPES>
  1. Generate request ID

    request_id = "fr-" + timestamp + "-" + short_uuid
    Example: fr-20251206-a1b2c3
    
  2. Build feedback request object

    {
      "request_id": "fr-20251206-a1b2c3",
      "type": "approval",
      "prompt": "Please review the design...",
      "options": ["approve", "reject", "request_changes"],
      "context": { ... },
      "requested_at": "2025-12-06T18:00:00Z",
      "notification_sent": {
        "cli": false,
        "issue_comment": false,
        "comment_url": null
      }
    }
    
  3. Emit decision_point event

    plugins/faber/skills/run-manager/scripts/emit-event.sh \
      --run-id "{run_id}" \
      --type "decision_point" \
      --phase "{phase}" \
      --step "{step}" \
      --message "Awaiting feedback: {prompt}" \
      --metadata '{"request_id": "{request_id}", "type": "{feedback_type}", "options": {options}}'
    
  4. Update run state

    {
      "status": "awaiting_feedback",
      "current_phase": "{phase}",
      "current_step": "{step}",
      "feedback_request": { ... request object ... },
      "resume_point": {
        "phase": "{phase}",
        "step": "{step}",
        "step_index": {current_step_index}
      }
    }
    
  5. Post to issue (if work_id present and post_to_issue=true)

    • Use comment-creator skill
    • Format using ISSUE_COMMENT_TEMPLATE
    • Store comment_url in notification_sent
  6. Show CLI prompt (if cli_prompt=true)

    • Use AskUserQuestion tool
    • Present options from feedback_request
  7. Return request details

    {
      "status": "success",
      "operation": "request-feedback",
      "result": {
        "request_id": "fr-20251206-a1b2c3",
        "state_updated": true,
        "notifications": {
          "cli": true,
          "issue_comment": true,
          "comment_url": "https://..."
        }
      }
    }
    

process-response Operation

  1. Load current state

    • Verify status is "awaiting_feedback"
    • Verify request_id matches pending request
  2. Validate response

    • Check response is in options list (or accept free text for clarification type)
  3. Emit feedback_received event

    plugins/faber/skills/run-manager/scripts/emit-event.sh \
      --run-id "{run_id}" \
      --type "feedback_received" \
      --phase "{phase}" \
      --step "{step}" \
      --message "Feedback received: {response}" \
      --metadata '{"request_id": "{request_id}", "response": "{response}", "user": "{user}", "source": "{source}"}'
    
  4. Update state

    • Clear feedback_request
    • Set status to "in_progress"
    • Add to feedback_history array
  5. Return processed response

    {
      "status": "success",
      "operation": "process-response",
      "result": {
        "request_id": "fr-20251206-a1b2c3",
        "response": "approve",
        "action": "continue",
        "resume_point": { ... }
      }
    }
    

<ISSUE_COMMENT_TEMPLATE> When posting feedback requests to GitHub issues:

## Feedback Requested

**Workflow Run**: `{run_id}`
**Phase**: {phase}
**Step**: {step}
**Requested**: {timestamp} UTC

### Decision Needed

{prompt}

{#if context.summary}
**Summary**:
{context.summary}
{/if}

{#if context.artifact_path}
**Artifact**: [{artifact_filename}]({context.artifact_path})
{/if}

### Options

{#each options}
{index}. **{option}** - {option_description}
{/each}

### How to Respond

Reply to this issue with your decision. Include `@faber resume` in your comment to trigger workflow continuation.

**Example response:**

I approve this design. The approach looks good.

@faber resume


---
_This feedback request will remain open until addressed._
_Run ID: `{run_id}` | Request ID: `{request_id}`_

Option Descriptions (based on type):

For approval:

  • approve: Continue to next phase
  • reject: Cancel this workflow run

For review:

  • approve: Continue to next phase
  • request_changes: Provide feedback for revision
  • reject: Cancel this workflow run

For error_resolution:

  • retry: Attempt the step again
  • skip: Skip this step and continue
  • abort: Cancel this workflow run

For confirmation:

  • confirm: Proceed with the action
  • cancel: Do not proceed </ISSUE_COMMENT_TEMPLATE>
{
  "status": "success",
  "operation": "request-feedback",
  "message": "Feedback request created",
  "details": {
    "request_id": "fr-20251206-a1b2c3",
    "type": "approval",
    "phase": "architect",
    "step": "design-review"
  },
  "notifications": {
    "cli": true,
    "issue_comment": true,
    "comment_url": "https://github.com/fractary/claude-plugins/issues/258#issuecomment-xyz"
  }
}

process-response Success

{
  "status": "success",
  "operation": "process-response",
  "message": "Feedback processed: approve",
  "details": {
    "request_id": "fr-20251206-a1b2c3",
    "response": "approve",
    "action": "continue",
    "resume_point": {
      "phase": "architect",
      "step": "design-review"
    }
  }
}

<ERROR_HANDLING>

ErrorCodeAction
Missing run_id1Return error, cannot proceed
Invalid feedback_type2Return error, list valid types
State not awaiting_feedback3Return error, nothing to process
Request ID mismatch4Return error, may be stale request
Invalid response option5Re-prompt with valid options
Issue comment failed6Warn but continue (non-critical)
State update failed7Return error (critical)
</ERROR_HANDLING>

<COMPLETION_CRITERIA> request-feedback complete when:

  • Decision_point event emitted
  • State updated to awaiting_feedback
  • Notification sent (CLI and/or issue comment)
  • Request details returned

process-response complete when:

  • Response validated
  • Feedback_received event emitted
  • State updated to in_progress
  • Action determined and returned </COMPLETION_CRITERIA>

request-feedback Start:

🎯 STARTING: Feedback Handler (request-feedback)
Run ID: fractary/claude-plugins/abc-123-...
Type: approval
Phase: architect
Step: design-review
───────────────────────────────────────

request-feedback End:

✅ COMPLETED: Feedback Handler (request-feedback)
Request ID: fr-20251206-a1b2c3
Notifications: CLI ✓, Issue Comment ✓
Comment URL: https://github.com/...
───────────────────────────────────────
Status: awaiting_feedback
Next: User must provide feedback to continue

process-response Start:

🎯 STARTING: Feedback Handler (process-response)
Request ID: fr-20251206-a1b2c3
Response: approve
───────────────────────────────────────

process-response End:

✅ COMPLETED: Feedback Handler (process-response)
Action: continue
Resume Point: architect:design-review
───────────────────────────────────────
Next: Workflow will resume from design-review

Integration Points

Called By:

  • faber-manager agent (at autonomy gates)
  • faber-manager agent (on step failure for error_resolution)

Invokes:

  • run-manager scripts (emit-event.sh)
  • comment-creator skill (for issue comments)

State Files:

  • Reads/Writes: .fractary/plugins/faber/runs/{run_id}/state.json

Scripts:

  • scripts/generate-request-id.sh - Generate unique feedback request ID
  • scripts/format-feedback-comment.sh - Format feedback request as markdown
  • scripts/update-feedback-state.sh - Update run state with feedback details

Script Usage

generate-request-id.sh

# Generate a new request ID
./scripts/generate-request-id.sh
# Output: fr-20251206-a1b2c3

format-feedback-comment.sh

./scripts/format-feedback-comment.sh \
  --run-id "fractary/claude-plugins/abc-123" \
  --request-id "fr-20251206-a1b2c3" \
  --type "approval" \
  --phase "architect" \
  --step "design-review" \
  --prompt "Please review the design" \
  --options '["approve", "reject"]' \
  --context '{"summary": "3-layer architecture"}'
# Outputs formatted markdown comment to stdout

update-feedback-state.sh

# Set awaiting_feedback status
./scripts/update-feedback-state.sh \
  --run-id "fractary/claude-plugins/abc-123" \
  --operation set-awaiting \
  --request-id "fr-20251206-a1b2c3" \
  --type "approval" \
  --prompt "Please review" \
  --options '["approve", "reject"]' \
  --phase "architect" \
  --step "design-review"

# Clear awaiting status after feedback
./scripts/update-feedback-state.sh \
  --run-id "fractary/claude-plugins/abc-123" \
  --operation clear-awaiting \
  --phase "architect" \
  --step "design-review"

# Add to feedback history
./scripts/update-feedback-state.sh \
  --run-id "fractary/claude-plugins/abc-123" \
  --operation add-history \
  --request-id "fr-20251206-a1b2c3" \
  --type "approval" \
  --response "approve" \
  --user "jmcwilliam" \
  --source "cli"

Comment-Creator Integration

To post feedback request to issue:

Invoke Skill: fractary-work:comment-creator
Operation: create-comment
Parameters:
  issue_id: "{work_id}"
  message: "{formatted_markdown}"  # From format-feedback-comment.sh output
  author_context: "ops"

The comment-creator returns comment_url which should be stored in the run state via update-feedback-state.sh --comment-url.