Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .claude/review-prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Claude Code Review Prompt

You are reviewing pull requests for moqueue. Apply the project rules from CLAUDE.md/AGENTS.md (loaded separately) in addition to this guidance.

**Only comment when you have actionable feedback. Never post "looks good", "no issues found", or summary-only comments.**

## What to Evaluate

- **Correctness**: the change should solve the stated problem, handle edge cases, and be free of bugs and regressions.
- **Code quality, readability, and maintainability**: the change should be clean, easy to follow, and sustainable to maintain and modify.
- **Conventions**: the change should follow this repo's existing patterns and conventions. It should avoid introducing or perpetuating anti-patterns. Do not re-teach language basics — ground convention feedback in what this codebase actually does.
- **Performance**: the change should avoid N+1 queries, excess API calls, unnecessary re-renders, unbounded list operations, and avoidable complexity.
- **Security**: the change should validate and sanitize inputs, enforce authentication and authorization correctly, protect sensitive data, and avoid common web security risks.
- **Testing**: the change should include coverage for changed behavior, failure modes, and important edge cases. Tests should assert meaningful behavior, not just exercise code.
- **Design, architecture, and scope**: the change should be well-designed, make worthwhile tradeoffs, fit the rest of the codebase cleanly, and remain reasonably scoped.
- **Dependencies**: any added library should be necessary and used appropriately.

## Findings

Categorize each finding:

- **Critical**: broken behavior, likely regressions, data loss, security issues, missing authorization, or defects that should block merge
- **Suggestion**: meaningful improvements to correctness, resilience, performance, maintainability, or test coverage
- **Nit**: minor style or readability feedback that is clearly optional
- **Question**: uncertainty about intent, tradeoffs, or missing context

## PR Context

- Link to the project pitch or Jira ticket in the PR body when applicable

## Review Behavior

- Focus on issues that matter. Do not pad the review with trivial comments.
- Explain what is wrong, why it matters, and suggest a concrete fix when possible. If unsure, say so and phrase it as a question.
- Flag change hygiene issues when unrelated changes are mixed in or the work should be split into smaller reviewable pieces.
- Call out genuinely good choices when they are specific and notable.
- Group related issues into a single review comment
- Reference specific lines using GitHub line-link format
- Skip auto-generated files (lockfiles, codegen output, Vite build artifacts)
- If the entire PR looks good, do not post a comment at all
- Read all previous review comments before posting. Do not repeat feedback that has already been given — whether by a human reviewer or a prior bot review. If a previous comment flagged an issue and it remains unfixed, you may briefly note it persists but do not re-explain.
128 changes: 128 additions & 0 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: Claude Code Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]

permissions:
contents: read
pull-requests: write
issues: read
id-token: write

jobs:
review:
if: |
(github.event_name == 'pull_request' && github.event.pull_request.draft == false) ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude'))
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.issue.number || github.run_id }}
cancel-in-progress: true
runs-on: ubuntu-latest
steps:
- name: Resolve PR number
id: pr
run: |
if [ "${{ github.event_name }}" = "issue_comment" ]; then
echo "number=${{ github.event.issue.number }}" >> "$GITHUB_OUTPUT"
else
echo "number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
fi

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: refs/pull/${{ steps.pr.outputs.number }}/head
fetch-depth: 0

- name: Fetch PR diff
env:
GH_TOKEN: ${{ github.token }}
run: |
gh pr diff "${{ steps.pr.outputs.number }}" > /tmp/pr-diff.patch

- name: Fetch previous reviews
env:
GH_TOKEN: ${{ github.token }}
run: |
PR_NUM="${{ steps.pr.outputs.number }}"
REPO="${{ github.repository }}"
{
echo "=== Review Summaries ==="
gh api "repos/${REPO}/pulls/${PR_NUM}/reviews" --paginate \
--jq '.[] | select(.state != "PENDING") | "[\(.user.login)] \(.state)\n\(.body)\n---"' 2>/dev/null || true

echo ""
echo "=== Inline Review Comments ==="
gh api "repos/${REPO}/pulls/${PR_NUM}/comments" --paginate \
--jq '.[] | "[\(.user.login)] \(.path):\(.line // .original_line)\n\(.body)\n---"' 2>/dev/null || true

echo ""
echo "=== PR Conversation Comments ==="
gh api "repos/${REPO}/issues/${PR_NUM}/comments" --paginate \
--jq '.[] | "[\(.user.login)]\n\(.body)\n---"' 2>/dev/null || true
} > /tmp/previous-reviews.txt

- name: Build review prompt
id: prompt
run: |
DELIMITER="PROMPT_EOF_$(uuidgen)"
{
echo "REVIEW_PROMPT<<${DELIMITER}"
for f in CLAUDE.md AGENTS.md; do
if [ -f "$f" ]; then
cat "$f"
echo ""
fi
done
if [ -f ".claude/review-prompt.md" ]; then
cat .claude/review-prompt.md
fi
echo "${DELIMITER}"
} >> "$GITHUB_OUTPUT"

- name: Resolve claude_args
id: args
env:
MODEL: ${{ vars.CLAUDE_REVIEW_MODEL }}
run: |
ALLOWED_TOOLS='Read,Glob,Grep,mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr view:*)'
if [ -n "$MODEL" ]; then
echo "value=--model ${MODEL} --max-turns 10 --allowedTools \"${ALLOWED_TOOLS}\"" >> "$GITHUB_OUTPUT"
else
echo "value=--max-turns 10 --allowedTools \"${ALLOWED_TOOLS}\"" >> "$GITHUB_OUTPUT"
fi

- name: Claude Code Review
continue-on-error: true
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
allowed_bots: "custom-ink-triton"
prompt: |
You are reviewing PR #${{ steps.pr.outputs.number }}.
The full diff is in /tmp/pr-diff.patch — Read that file first.
Previous review comments are in /tmp/previous-reviews.txt — Read that file next.
Do NOT run gh pr diff or git diff to re-fetch it.
Use Read on source files if you need more context beyond the diff.

IMPORTANT: Do NOT repeat or reiterate feedback that has already been given
in previous reviews. If a prior reviewer (human or bot) already flagged an
issue and the author has not addressed it in the current diff, you may
reference it briefly but do not re-explain. Focus your review on NEW issues
not covered by prior feedback.

Post inline review comments and stop.

Review this pull request using the following guidelines:

${{ steps.prompt.outputs.REVIEW_PROMPT }}
claude_args: "${{ steps.args.outputs.value }}"
26 changes: 26 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Moqueue

Ruby gem for mocking the AMQP library in tests. Allows testing AMQP-based code without running a broker by providing mock replacements for queues, exchanges, and channels.

## Tech Stack

- **Language:** Ruby (see `moqueue.gemspec` for dependencies)
- **Type:** Gem (consumed via Bundler)
- **Key dependency:** `amqp` >= 0.9.0

## Local Development & Testing

Run `bundle install` and `bundle exec rake spec`. Test framework: RSpec.

## Key Directories

| Path | Purpose |
|------|---------|
| `lib/moqueue/` | Mock implementations (MockQueue, MockExchange, MockChannel) |
| `spec/` | RSpec suite |

## Architecture Notes

- Provides `overload_amqp` to globally replace AMQP classes with mocks
- Captures published messages in a `routed_messages` array for assertions
- Used by other Custom Ink services (e.g. journal-service) for testing AMQP workflows
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

@AGENTS.md