MÓDULO 4.1

O Projeto e o SPEC: Definição Antes do Código

📚

Tópicos

6

⏱️

Minutos

40

🎯

Nível

Avançado

🧠

Tipo

Conceitual

1

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.

💡 Conceito Principal

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

Dica Prática

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.

2

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.

🌳 Como o Worktree Resolve o Problema
# 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
3

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.

1

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

2

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

3

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

🔍 Por que Camadas Importam no Build Incremental

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.

4

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
# 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
Como usar o SPEC nos prompts

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.

5

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.

📁 File Tree Completo

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
6

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?

⚠️ Não Comece Sem o SPEC

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

Escopo definido — input é PR number, output é relatório + gh comment
Git worktree — isolamento sem contaminar o working tree atual
Arquitetura em 3 camadas — Isolamento, Análise e Relatório independentes
SPEC.md completo — ciclo de vida, schema, invariantes, file tree e contrato
Checklist de SPEC — 6 pontos a verificar antes do primeiro prompt de build

Próximo Módulo:

4.2 — Prompt 01: Scaffold e Worktree — construindo a primeira camada