🏛️ AI Code Review Bot inspired by Evangelion's MAGI System
Three personas (MELCHIOR, BALTHASAR, CASPER) evaluate PRs from different perspectives. Approves when 2/3 or more personas agree.
| Persona | Role | Focus | Personality |
|---|---|---|---|
| 🔬 MELCHIOR | Scientist | Code efficiency, algorithms, bugs, security | Cold and technical |
| 👩👧 BALTHASAR | Mother | Maintainability, readability, conventions, tests | Strict but collaborative |
| 💃 CASPER | Woman/Human | UX/UI consistency, user experience | Intuitive and emotional |
Choose from 3 LLM Providers:
| Provider | Default Model | Environment Variable |
|---|---|---|
| Gemini | gemini-2.5-flash |
GEMINI_API_KEY or GCP_PROJECT_ID |
| OpenAI | gpt-5.2 |
OPENAI_API_KEY |
| Claude | claude-sonnet-4-5-20250929 |
ANTHROPIC_API_KEY |
- uses: WillowRyu/project-judge@main
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}- uses: WillowRyu/project-judge@main
with:
openai_api_key: ${{ secrets.OPENAI_API_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}.github/magi.yml:
provider:
type: openai
model: gpt-5.2 # optional- uses: WillowRyu/project-judge@main
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}.github/magi.yml:
provider:
type: claude
model: claude-sonnet-4-5-20250929 # optional- uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- uses: WillowRyu/project-judge@main
with:
gcp_project_id: ${{ secrets.GCP_PROJECT_ID }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}.github/workflows/magi-review.yml:
name: MAGI Review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
magi-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: WillowRyu/project-judge@main
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Run review only on PR open, and re-run via /magi-review comment:
.github/workflows/magi-review.yml:
name: MAGI Review
on:
pull_request:
types: [opened] # Only on first open
issue_comment:
types: [created] # Re-trigger via comment
permissions:
contents: read
pull-requests: write
jobs:
magi-review:
runs-on: ubuntu-latest
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '/magi-review'))
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/head', github.event.issue.number) || '' }}
- uses: WillowRyu/project-judge@main
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Usage:
| Trigger | When |
|---|---|
| PR Created | Auto-run once |
| Code Push | ❌ No run |
/magi-review comment |
✅ Re-run |
Customize behavior with .github/magi.yml:
version: 1
# Provider settings (gemini | openai | claude)
provider:
type: gemini
model: gemini-2.5-flash # optional
# Voting settings
voting:
required_approvals: 2 # Required approval count
# Optimization & safety guard
optimization:
prompt_compression: true
context_caching: true
hard_cut:
enabled: true
max_changed_files: 300
max_changed_lines: 100000
# Debate feature
debate:
enabled: true
max_rounds: 1
trigger: disagreement # conflict | disagreement | always
# Output settings
output:
pr_comment:
enabled: true
style: detailed # summary | detailed
labels:
enabled: true
approved: magi-approved
rejected: magi-changes-requested
# Notifications
notifications:
slack:
enabled: true
notify_on: all # all | rejection | approval
# Ignore files
ignore:
files:
- "*.lock"
- ".generated."
paths:
- "node_modules/"
- "dist/"Generated files are ignored by default (for example: generated/,
__generated__/, .generated., .pb., .g.dart, .graphql.dart,
.designer.cs).
Note: A
rejectedresult does not fail the workflow check by itself. Gate merges using theresultoutput (approved/rejected/skipped/error) or the applied label (e.g., branch protection on themagi-changes-requestedlabel).Failed reviews abstain. If a persona's model call fails, that vote is excluded from the tally — it never counts as an approval. If fewer valid reviews remain than
required_approvals(quorum not reached),resultiserrorand the action fails; just re-run it (usually a transient provider or rate-limit error).
Send review results to Slack channel.
-
Create Slack Webhook:
- Go to Slack → Apps → "Incoming Webhooks"
- Select channel and create webhook URL
-
Add to GitHub Secrets:
- Add
SLACK_WEBHOOK_URLto repository secrets
- Add
-
Update Workflow:
- uses: WillowRyu/project-judge@main
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}- Enable in magi.yml:
notifications:
slack:
enabled: true
notify_on: all # all | rejection | approval🏛️ MAGI Review Result
#42 feat: add user authentication
✅ Approved (2/3, 2 votes required)
🔬 MELCHIOR ✅ approve
👩👧 BALTHASAR ⚠️ conditional
💃 CASPER ✅ approve
[📋 View PR] [🔍 View Details]
When personas disagree, they debate and may change their votes.
debate:
enabled: true
max_rounds: 1
trigger: disagreement # conflict | disagreement | always
revote_after_debate: true| Trigger | Description |
|---|---|
conflict |
Only when both approve and reject exist |
disagreement |
When votes are not unanimous |
always |
Always debate (for testing) |
After debate, vote changes are shown as:
❌ reject → ⚠️ conditional⚠️ conditional → ✅ approve
Use different LLM providers for each persona:
personas:
- id: melchior
provider: openai
model: gpt-5.2-pro
- id: balthasar
provider: claude
model: claude-opus-4-5-20251101
- id: casper
provider: gemini
model: gemini-2.5-flashNote: Provide all required API keys when using per-persona providers. The action validates every referenced provider up front and fails fast with a clear error if a key is missing.
Create .github/magi/common.md to add guidelines for all personas:
# Team Guidelines
## Project Context
- This is an e-commerce platform
- PCI DSS compliance required
## Team Conventions
- All APIs follow REST conventions
- Error codes use ERR\_ prefixCreate .github/magi/melchior.md to fully customize individual personas.
Priority:
- Custom guideline file (if exists)
- Built-in default (fallback)
- + common.md (always appended)
## 🏛️ MAGI System Review Result
### ✅ Approved (2/3)
| Persona | Vote | Reason |
|:-------:|:----:|--------|
| 🔬 MELCHIOR | ✅ | Algorithm efficient, no security issues |
| 👩👧 BALTHASAR | ❌ reject → ⚠️ conditional | After debate: maintainability concerns addressed |
| 💃 CASPER | ✅ | UX consistency maintained |
<details>
<summary>🔬 MELCHIOR Details</summary>
...
</details>
project-judge/
├── src/
│ ├── index.ts # Main entry point
│ ├── config/ # Config loader & schema
│ ├── providers/ # LLM Providers (Gemini, OpenAI, Claude)
│ ├── personas/ # Personas & guidelines
│ │ └── built-in/ # Built-in defaults
│ ├── review/ # Review engine
│ ├── notifications/ # Slack notifications
│ └── github/ # GitHub API integration
├── action.yml # GitHub Action metadata
└── .github/workflows/ # Example workflows
# Install dependencies
pnpm install
# Type check
pnpm typecheck
# Build
pnpm build
# Test
pnpm testMIT