O que o Plugin vai Fazer
Escopo, inputs e outputs do revisor de PRs
O plugin pr-reviewer é um Claude Code plugin que automatiza revisões de pull requests. O aluno vai construi-lo do zero usando 5 prompts incrementais — o mesmo padrão da Trilha 2, mas aplicado a um projeto diferente e mais complexo que envolve integração com GitHub.
Input: número do PR. Output: relatório estruturado + comentário no GitHub.
O plugin recebe /pr-reviewer 123 como comando. Ele faz checkout isolado via git worktree, roda 3 rodadas de revisão com personas diferentes, e entrega um relatório Markdown em .claudex/reviews/PR-123.md que pode ser postado automaticamente via gh pr comment.
Input
Número do PR + configuração em .claude/review-config.yaml
Processamento
Worktree isolado + 3 rodadas de revisão com personas Author, Reviewer, Security
Output
Relatório Markdown estruturado com severidade CRITICAL/HIGH/MEDIUM/LOW
Antes de começar qualquer prompt de build, escreva manualmente o comando de uso final: /pr-reviewer 123. Isso ancora todas as decisões de design — se uma decisão torna esse comando mais complicado, é a decisão errada.
Por que Git Worktree
O problema do isolamento de branch resolvido sem stash
A abordagem ingênua para revisar um PR seria fazer git checkout pr-branch e rodar a revisão. O problema: você interrompe o trabalho em progresso na branch atual. Stash funciona, mas esquece de fazer unstash. Git worktree é a solução correta.
# Cria segundo checkout em /tmp sem afetar o working tree atual
git worktree add /tmp/pr-review-123 origin/feature/my-pr
# Revisa no diretório isolado
cd /tmp/pr-review-123 && git diff main...HEAD
# Cleanup garantido via EXIT trap
git worktree remove --force /tmp/pr-review-123
Com Worktree
- ✓Working tree principal intacto
- ✓Múltiplos PRs em paralelo
- ✓Cleanup automático via EXIT trap
- ✓Sem risco de commit acidental
Sem Worktree
- ✗Checkout contamina work-in-progress
- ✗Stash esquecido = perda de trabalho
- ✗Apenas um PR por vez
- ✗Estado inconsistente após falha
Arquitetura em 3 Camadas
Isolamento, Análise e Relatório — independentes e testáveis
O revisor de PRs é estruturado em três camadas com responsabilidades distintas. Cada camada pode falhar, ser testada e ser substituída independentemente. Esta separação é o que permite construir em 5 prompts incrementais sem reescritas.
Camada de Isolamento
Responsabilidade: criar e destruir o worktree. Independente de toda lógica de revisão.
scripts/setup-worktree.sh · scripts/cleanup-worktree.sh · EXIT trap
Camada de Análise
Responsabilidade: loop de revisão com máquina de estados, personas e extração de findings.
hooks/stop-hook.sh · state/review.yaml · runners/PR-NNN-round-N.sh
Camada de Relatório
Responsabilidade: consolidar findings em Markdown estruturado e postar via GitHub CLI.
.claudex/reviews/PR-NNN.md · gh pr comment · review-config.yaml
No Prompt 01 você só constrói a Camada 1. No Prompt 02, só a base da Camada 2. Cada prompt adiciona funcionalidade em uma camada sem quebrar as outras. Se o worktree falha no Prompt 03, você debugar apenas a Camada 1 — a Camada 2 e 3 não são suspeitas.
O SPEC.md Completo do Projeto
O blueprint que vai em contexto em todos os 5 prompts de build
Antes de escrever uma linha de código, escreva o SPEC.md. É o documento de uma página que Claude vai consultar em cada prompt de build. Não é um documento de requisitos corporativo — é um blueprint técnico com decisões explícitas.
SPEC.md — pr-reviewer
# SPEC.md — pr-reviewer Plugin
## O que faz
Plugin Claude Code que revisa PRs de forma automatizada:
- Checkout isolado via git worktree (não contamina branch de trabalho)
- Loop de revisão com 3 personas: Author, Reviewer, Security
- Relatório estruturado com severidade CRITICAL/HIGH/MEDIUM/LOW
- Integração com GitHub via `gh pr comment`
## Ciclo de Vida
SETUP → REVIEWING (rounds 1-3) → SUMMARIZING → DONE
| Estado | Quem Age | Hook Faz |
|-------------|-------------------|----------------------------------------|
| SETUP | Plugin cria worktree | CAS para REVIEWING → escreve runner |
| REVIEWING | Claude revisa diff | Incrementa round ou vai SUMMARIZING |
| SUMMARIZING | Claude consolida | Gera relatório → CAS para DONE |
| DONE | Terminal | Cleanup → APPROVE |
## Schema do Estado (state/review.yaml)
pr_number: int # número do PR
worktree_path: string # /tmp/pr-review-$PR_NUMBER
status: enum # SETUP|REVIEWING|SUMMARIZING|DONE
round: int # rodada atual (1-indexed)
max_rounds: int # default 3, configurável
persona: string # Author|Reviewer|Security
findings: list # [{file, line, severity, description, suggestion}]
started_at: int # epoch timestamp
version: int # para CAS (incrementar a cada escrita)
## File Tree
pr-reviewer/
├── claude.json # manifest + hook registration
├── hooks/
│ └── stop-hook.sh # Stop Hook com lifecycle completo
├── scripts/
│ ├── setup-worktree.sh # git worktree add + idempotente
│ └── cleanup-worktree.sh # git worktree remove --force
├── state/
│ └── review.yaml # estado persistente
├── runners/ # runner scripts por rodada
│ └── PR-NNN-round-N.sh # gerado pelo hook
└── .claudex/reviews/ # artefatos finais
└── PR-NNN.md # relatório de revisão
## Invariantes de Segurança
1. FAIL-OPEN: stop-hook.sh retorna exit 0 em qualquer falha não tratada
2. ESCRITA ATÔMICA: toda escrita de estado via tmp + rename
3. CAS: toda modificação de estado verifica version antes de escrever
4. LOCKFILE: flock -n state/review.lock — apenas um revisor por repo
5. EXIT TRAP: cleanup-worktree.sh chamado sempre, mesmo em falha
6. PATH VALIDATION: worktree_path deve começar com /tmp/pr-review-
## Contrato dos Hooks
Stop Hook:
- Input: lê state/review.yaml
- BLOCK: {"decision":"block","reason":"..."} — reason é Markdown
- APPROVE: {"decision":"approve"}
- Nunca lança exceção para o chamador (ERR trap = fail-open)
## Configuração (.claude/review-config.yaml)
max_rounds: 3 # rodadas de revisão
min_severity: MEDIUM # severidade mínima para comment no PR
ignore_paths: [] # paths a ignorar no diff
timeout_seconds: 120 # timeout por rodada de runner
post_to_github: true # se false, só salva localmente
Cada prompt de build começa com: "Read SPEC.md if present — it's the source of truth." Isso ancora o Claude no blueprint mesmo quando a conversa cresce e o contexto fica longo.
A Estrutura de Arquivos Esperada
O destino final após os 5 prompts de build
Saber o destino antes de começar evita decisões de naming inconsistentes. Cada arquivo tem uma responsabilidade única — se você precisa de um sexto arquivo para algo que deveria estar em um dos cinco, o design está errado.
pr-reviewer/
├── claude.json # Prompt 01
├── hooks/
│ └── stop-hook.sh # Prompt 01 (stub) → Prompt 03 (engine)
├── scripts/
│ ├── setup-worktree.sh # Prompt 01
│ └── cleanup-worktree.sh # Prompt 01
├── state/
│ ├── review.yaml # Prompt 02
│ └── state-helpers.sh # Prompt 02
├── runners/ # Gerado em runtime (Prompt 03)
├── .claudex/
│ └── reviews/ # Relatórios salvos (Prompt 04)
└── .claude/
└── review-config.yaml # Prompt 05
Arquivos Estáticos (versionados)
- claude.json — manifest do plugin
- stop-hook.sh — engine do loop
- setup/cleanup-worktree.sh — infraestrutura
- state-helpers.sh — primitivas de I/O
- review-config.yaml — defaults
Arquivos Dinâmicos (runtime)
- state/review.yaml — estado atual
- state/review.lock — exclusão mútua
- runners/PR-NNN-round-N.sh — por rodada
- .claudex/reviews/PR-NNN.md — relatórios
Como Verificar se o SPEC está Completo
Checklist antes de iniciar o Prompt 01
Um SPEC incompleto gera ambiguidades que o Claude resolve de formas diferentes a cada prompt, criando inconsistências que só aparecem na integração. Use este checklist antes de começar o build.
Ciclo de vida coberto?
Todos os estados definidos? Condições de transição explícitas? Estado terminal definido?
Schema com todos os campos?
Cada campo tem tipo, valores possíveis e responsável por escrever/ler?
Invariantes explícitas?
As 6 primitivas de segurança estão listadas? Cada invariante tem sua implementação descrita?
File tree definido?
Cada arquivo tem nome e responsabilidade? Separação entre estático e dinâmico está clara?
Contrato dos hooks documentado?
Input, output, formato do JSON, condições de BLOCK vs APPROVE — tudo explícito?
Configuração por repo definida?
Quais são os defaults? Quais campos são configuráveis? O arquivo de config tem schema?
Se você começar o Prompt 01 sem o SPEC, Claude vai inventar a arquitetura. O que ele inventar será diferente do que ele inventaria no Prompt 03. Inconsistências aparecem na integração — horas depois, com código acumulado que você vai querer reescrever.
✅ Resumo do Módulo 4.1
Próximo Módulo:
4.2 — Prompt 01: Scaffold e Worktree — construindo a primeira camada