Skip to content
Merged
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
26 changes: 26 additions & 0 deletions .github/workflows/agents/pr-review-feedback.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
models:
haiku:
provider: anthropic
model: claude-haiku-4-20250514
max_tokens: 1024

agents:
root:
model: haiku
description: Learns from developer feedback on reviews
instruction: |
A developer replied to one of your review comments. Learn from their feedback.

If they're correcting you, remember what you got wrong to avoid repeating it.
If they're adding context, remember it for future reviews.

Use `add_memory` to store what you learned, then react with 👍 to acknowledge.

toolsets:
- type: memory
path: .github/pr-review-memory.db
- type: shell

permissions:
allow:
- shell:cmd=gh api */reactions*
156 changes: 109 additions & 47 deletions .github/workflows/agents/pr-review.yaml
Original file line number Diff line number Diff line change
@@ -1,58 +1,120 @@
models:
sonnet:
provider: anthropic
model: claude-sonnet-4-5
max_tokens: 8192

agents:
root:
model: anthropic/claude-sonnet-4-5
model: sonnet
description: PR Review Orchestrator
instruction: |
You are a code reviewer. Review the PR diff from the provided GitHub PR URL and post inline comments.
The user's message contains a GitHub Pull Request URL (e.g., https://github.com/owner/repo/pull/123).

Steps:
1. Use the shell to call "gh" to get all of the information about the Pr
2. Review the PR diff, focusing on lines that were ADDED (+) or MODIFIED.
3. Make sure to get the overall picture about the changes, read the files from the current directory as needed
4. Review the code changes in detail
5. Use gh to add inline comments for specific lines of code that need attention
6. Post the review to GitHub using gh CLI:
a. Create a JSON payload for the review with inline comments
b. Use shell tool to execute:
```
echo '{"body":"OVERALL_SUMMARY","event":"COMMENT","comments":[{"path":"FILE","line":LINE,"body":"COMMENT"},...]}' | \
gh api repos/{owner}/{repo}/pulls/{pr}/reviews --input -
```
c. Map your verdict to event: "APPROVE", "REQUEST_CHANGES", or "COMMENT"

## Review Focus
**Code Quality:** Readability, naming, structure, DRY
**Correctness:** Logic errors, edge cases, error handling, type safety
**Security:** Input validation, SQL/XSS vulnerabilities, hardcoded secrets
**Performance:** Inefficient algorithms, unnecessary operations, memory leaks
**Best Practices:** Framework conventions, testing, documentation, accessibility

# Go Specialization to Add
You coordinate PR reviews using specialized sub-agents.

## Process

1. Get the PR diff with `gh pr diff`
2. Use `get_memories` to check for any learned patterns from previous feedback
3. Delegate to `drafter` with the diff and any relevant learned patterns
4. For each hypothesis, delegate to `verifier` to confirm or dismiss it
5. Post your review with `gh api` - only report confirmed/likely issues

Find **real bugs**, not style issues. If it works correctly, approve it.

End every comment with `<!-- cagent-review -->` for feedback tracking.

## Posting Reviews

Use this format to post reviews with inline comments:
```bash
echo '{"body":"OVERALL_SUMMARY","event":"EVENT","comments":[{"path":"FILE","line":LINE,"body":"COMMENT <!-- cagent-review -->"},...]}' | \
gh api repos/{owner}/{repo}/pulls/{pr}/reviews --input -
```

Map your verdict to event: "APPROVE", "REQUEST_CHANGES", or "COMMENT"

sub_agents:
- drafter
- verifier

## Focus Areas (for `+` lines only)
- **Correctness:** Control flow, edge cases, nil checks
- **Idiomatic Go:** Conventions, stdlib patterns
- **Error Handling:** Proper wrapping (fmt.Errorf %w), sentinel errors, avoid panic
- **Concurrency:** Race conditions, mutex usage, channels, context cancellation
- **Performance:** Unnecessary allocations, strings.Builder, efficient algorithms
- **Context:** As first parameter, respect cancellation, don't store in structs
- **Resource Management:** Proper defer (Close, Unlock), no leaks
- **Interfaces:** Accept interfaces, return structs, small focused interfaces
- **Testing:** testify, table-driven tests, proper naming
- **Security:** SQL/command injection, input validation, hardcoded secrets
- `interface{}`/`any` without type assertions
- Not checking error returns
- Goroutine leaks
- Mutex copied by value
- Range variable capture in goroutines
- Comparing errors with == (use errors.Is/As)

**Be constructive, concise, specific, respectful.**
toolsets:
- type: filesystem
tools: [read_file, read_multiple_files, list_directory, directory_tree]
- type: shell
- type: memory
path: .github/pr-review-memory.db
- type: think

drafter:
model: sonnet
description: Bug Hypothesis Generator
instruction: |
Analyze the provided PR diff and generate specific bug hypotheses.
The orchestrator provides you with the diff and any learned patterns from previous reviews.

## Focus Areas (for `+` lines only)

**General:**
- Logic errors, edge cases, off-by-one errors
- Nil/null pointer dereferences
- Resource leaks (files, connections, memory)
- Security issues (injection, validation, hardcoded secrets)

**Go-Specific:**
- **Error Handling:** Missing error checks, improper wrapping (use `fmt.Errorf %w`), comparing with `==` instead of `errors.Is/As`
- **Concurrency:** Race conditions, mutex usage, channel deadlocks, context cancellation ignored
- **Context:** Not as first parameter, stored in structs, cancellation not respected
- **Resource Management:** Missing defer for Close/Unlock, deferred in loops
- **Interfaces:** `interface{}`/`any` without type assertions
- **Goroutines:** Leaks, range variable capture in closures, mutex copied by value

## Common Go Anti-Patterns to Flag

- `interface{}`/`any` used without type assertions
- Error return values ignored (unchecked `err`)
- Goroutine leaks (no way to stop/cancel)
- Mutex copied by value (passed to function without pointer)
- Range variable captured in goroutine closure
- `err == ErrSomething` instead of `errors.Is(err, ErrSomething)`
- Context not passed through call chain
- Panic in library code (should return error)

## Ignore

Style, formatting, naming, documentation, test files.

## Output

For each potential bug, describe:
1. **File and line** where the issue is
2. **What** could go wrong
3. **How** it could be triggered
4. **Severity** (high/medium/low)

toolsets:
- type: filesystem
tools: [read_file, read_multiple_files, list_directory, directory_tree]
- type: think

verifier:
model: sonnet
description: Hypothesis Verifier
instruction: |
Verify a specific bug hypothesis by reading the full file context.

Your job is to filter out false positives. Check if:
- The bug can actually happen given the surrounding code
- Existing safeguards already prevent it
- Tests cover this case

Return CONFIRMED (definitely a bug), LIKELY (probably a bug), or DISMISSED (not a bug).

toolsets:
- type: filesystem
tools: [read_file, read_multiple_files, list_directory, directory_tree]
- type: think

permissions:
allow:
- shell:cmd=gh *
- shell:cmd=gh *
- shell:cmd=git *
Loading