Code Review
Cinco passes de revisão dimensionados pelo tamanho e pelo risco da mudança, com verificação dos achados bloqueantes e veredito documentado.
makuco-code-review
Função
Leva uma mudança pronta — uma PBI implementada pelo
makuco-desenvolver, ou uma branch/PR/working tree avulsa — por cinco
passes de revisão e produz um veredito documentado. Primeiro dimensiona a revisão pelo tamanho e
pelo risco da mudança; depois roda os passes 1–2 no contexto principal e despacha os passes 3–5 para
três subagentes em paralelo, deduplica os candidatos, verifica os achados bloqueantes contra o
código real e decide APROVADO ou NECESSITA CORREÇÕES.
É o único ponto de entrada de review do Makuco. Você pode invocá-lo direto, ou deixar que o
makuco-desenvolver o conduza no fechamento de cada PBI — o contrato é o mesmo nos dois casos.
Os dois modos
O modo nunca é presumido — o passo 1 infere e pergunta quando a inferência não é segura.
| PBI (padrão) | DIFF (avulso) | |
|---|---|---|
| Entrada | id/slug da PBI, ou pasta com sessao-dev.md | branch, PR, range de commits, ou a working tree |
| Passes | 1–5 | 2–5 (o pass 1 é N/A — não há spec contra a qual checar conformidade) |
| Contexto extra | spec.md, task.md, DESIGN.md/EXPERIENCE.md, rca.md (PBI de correção) | só os docs de codebase |
| Saída | review.md via makuco-copy-writer + status.yml | .makuco/reviews/{slug}.md, escrito direto |
| Veredito | APROVADO / NECESSITA CORREÇÕES → pbis.{slug}.review | mesmo veredito, sem status.yml |
Fluxo em passos
step-01-escopo → resolve a raiz · detecta o modo PBI vs DIFF · resolve o escopo do diff ·
oferece retomar · DECIDE O PERFIL (leve / padrao / profundo) ·
semeia sessao-review.md · numera a rodada
↓
step-02-contexto → PBI: spec.md + task.md + sessao-dev.md + DESIGN/EXPERIENCE (+ rca.md) ·
ambos: docs de codebase + o conteúdo COMPLETO dos arquivos que algum passe julga inteiros
↓
step-03-passes → rodada de correção: verificação, não review completo ·
passes 3–5 despachados para subagentes EM PARALELO, numa única mensagem ·
passes 1–2 rodam aqui enquanto eles trabalham (pass 1 só em modo PBI) ·
perfil leve: só o pass 3, inline
↓
step-04-consolidar → dedup por local + mecanismo · agrupa por causa raiz ·
verifica todo critical (e o major sem prova à mão) · descarta não-achados ·
numera sequencialmente · decide o veredito
↓
step-05-fechamento → PBI: entrega ao makuco-copy-writer (review.md + status.yml), depois
aciona o makuco-documentation quando APROVADO ·
DIFF: escreve em .makuco/reviews/ direto · registra lições · reportaO perfil da revisão
A mudança dita a profundidade. No passo 1 a skill conta os arquivos de código e as linhas alteradas, e procura sinais de risco:
autenticação ou autorização · validação/parse de entrada externa · segredo, token ou criptografia · dinheiro, preço ou cobrança · mudança de schema ou migração · deleção de dados · concorrência ou paralelismo · contrato de API pública · modelo de permissão
| Perfil | Quando | Passes | Leitura | Forma |
|---|---|---|---|---|
leve | ≤2 arquivos de código e ≤50 linhas alteradas e nenhum sinal de risco | 1 (só PBI) + 3 | o diff e a função que o envolve — não o arquivo inteiro | inline, sem subagentes |
padrao | todo o resto | 1, 2 + 3, 4, 5 | filtro por passe | subagentes em paralelo |
profundo | qualquer sinal de risco, ou mais de 40 arquivos | 1, 2 + 3, 4, 5 | filtro por passe, mais as dependências que um passe decidir seguir | subagentes em paralelo |
- Sinal de risco nunca é compensado pelo tamanho. Três linhas em
auth/sãoprofundo. - O perfil é declarado no relatório, sempre, com o motivo — "Perfil
leve: 1 arquivo, 12 linhas, sem sinal de risco; passes 4 e 5 não rodaram." Review que cobriu menos diz que cobriu menos. - Você pode mudar o perfil. A skill anuncia o plano e começa sem pedir aprovação, mas aceita
--profundo,--leveou--completo(que incluisuggestionno relatório).
Os cinco passes
| # | Passe | Onde roda | Skill |
|---|---|---|---|
| 1 | Conformidade com spec/tasks | contexto principal | — (só em modo PBI) |
| 2 | Análise do diff | contexto principal | — |
| 3 | Correção — bugs e segurança | subagente | makuco-reviewer-correctness |
| 4 | Design — qualidade e padrões do projeto | subagente | makuco-reviewer-design |
| 5 | Testes | subagente | makuco-reviewer-tests |
As skills makuco-reviewer-quality, -security, -bugs e -patterns foram substituídas por
-correctness e -design, e são oferecidas para remoção no próximo makuco update.
Os passes 1 e 2 ficam no contexto principal porque precisam do quadro inteiro de uma vez — todos os critérios de aceite contra todas as mudanças. Os subagentes são despachados primeiro, e os passes 1–2 rodam enquanto eles trabalham.
Cada passe vê o seu próprio conjunto de arquivos
A skill filtra por passe, não pelo diff. Um diff de 19 arquivos markdown mais 3 de código não é "um diff com código" para todos os passes: são 3 arquivos para quem julga código e 22 para quem julga posicionamento.
| Passe | Vê |
|---|---|
| 3 — correção | Só arquivos de código, com o conteúdo inteiro. Prosa, dados e lockfiles não têm race condition nem OWASP. |
| 4 — design | Todos os caminhos alterados — posicionamento, nomenclatura e camadas valem para docs também. Caminho + diff bastam; não precisa do corpo inteiro. |
| 5 — testes | Arquivos de teste, mais o código que eles cobrem. Nada além. |
Um passe cujo conjunto sai vazio é N/A: não se aplicava, então não rodou. N/A não é
SKIP — N/A significa que o passe não se aplica, SKIP significa que ele deveria ter rodado e
não conseguiu. Os dois são declarados no relatório.
Os passes também não são igualmente difíceis: quando o runner permite escolher o modelo por subagente, o de testes roda num modelo rápido, o de design num intermediário, e o de correção no mais capaz.
Por que ler o arquivo inteiro, não só o diff
A maioria dos bugs reais vive na interação entre as linhas novas e as que estão em volta — uma
guarda que antes rodava mais cedo na função, um chamador cujo contrato acabou de mudar. Um revisor que
só vê o diff não consegue enxergar nada disso. Por isso o pass 3 recebe o arquivo inteiro de todo
código que julga, fora do perfil leve.
Severidade
| Severidade | Critério |
|---|---|
critical | Diretamente explorável, ou impede o funcionamento correto: bypass de auth, injeção, dado exposto, crash garantido. |
major | Requisito não implementado, fraqueza de segurança, ou bug com boa chance de chegar em produção. |
minor | Desvio de padrão, cobertura insuficiente, hardening recomendado. |
suggestion | Melhoria de clareza ou qualidade, sem violação atual. |
Só critical e major bloqueiam a aprovação. Nada mais.
O que chega ao relatório
Por padrão:
| Severidade | Padrão |
|---|---|
critical, major | Sempre emitidos, sem teto. |
minor | No máximo 5, já agrupados por causa. O resto vira uma linha contada. |
suggestion | Não é emitida. Só com --completo. |
Cada subagente recebe a severidade mínima que deve emitir. Pedir o relatório completo (--completo)
traz tudo de volta.
Verificação dos achados bloqueantes
Todo critical é verificado antes de entrar no relatório. Um major só é re-verificado quando a
prova não está no que já foi lido: se o diff e o arquivo que o passe tinha na frente bastam para
mostrar a falha, o achado fica de pé com a linha citada. Quando ele depende de um chamador, de uma
guarda em outro arquivo ou de um estado que ninguém olhou, é verificado.
A skill faz a pergunta invertida: que leitura deste código torna este candidato falso? Depois procura essa leitura no código — uma guarda mais cedo na função, um tipo que torna o estado inalcançável, um chamador que já valida, uma constante que exclui o limite.
| Veredito | Significado |
|---|---|
CONFIRMED | Dá para nomear as entradas/estado que disparam e o resultado errado que segue. |
PLAUSIBLE | O mecanismo é real e alcançável, mas o disparo depende de timing, ambiente ou carga. |
REFUTED | É factualmente errado, comprovadamente impossível, ou já tratado. |
CONFIRMED e PLAUSIBLE ficam. REFUTED é descartado, citando a linha que o refuta.
Refutar só a partir do código, nunca da dúvida. "Parece improvável", "provavelmente é intencional" e "depende de estado de runtime" não são refutações — uma race condition, um null em caminho de cache frio, um zero tratado como ausente e um off-by-one num limite que o código não exclui são todos estados realistas, e descartá-los é como bugs reais chegam em produção.
O que não é achado
Descartado na consolidação, e o descarte é contado e reportado:
- Estilo que o formatador/linter já governa (espaçamento, quotes, ordem de import, comprimento de linha).
- Falhas de compilação, tipo e teste — o build e a suíte rodam à parte.
- Renomeação cosmética sem ambiguidade por trás.
- Nome que segue o padrão do próprio projeto — identificador em português num projeto que fala português está correto.
- Bugs pré-existentes em linhas que a mudança não tocou nem afetou.
- Regra que o código silenciou deliberadamente com anotação explícita — isso é uma decisão.
- Mudanças de comportamento intencionais que a spec ou a task pediram.
- "Faltam testes/docs" no abstrato, sem uma convenção documentada do projeto por trás.
Agrupamento por causa raiz
Deduplicação remove repetições do mesmo achado. O agrupamento é diferente, e é o que mantém o relatório legível: vários achados que compartilham uma causa e uma correção viram um achado com tabela de instâncias.
Quatorze lugares onde um doc contradiz outro não são quatorze achados — é um achado ("o roteador e os steps discordam") com quatorze instâncias, e a correção é uma decisão aplicada quatorze vezes.
O relatório tem alvo de no máximo ~15 achados numerados. Chega-se lá agrupando e descartando
não-achados, nunca cortando em silêncio. critical e major nunca são cortados — todos aparecem,
quantos forem.
O veredito
APROVADO — nenhum critical e nenhum major aberto (entre os que bloqueiam nesta rodada)
NECESSITA CORREÇÕES — ao menos um critical ou major abertoNão existe terceiro resultado, e não existe "aprovado com ressalvas". Um passe registrado como
SKIP não muda o veredito, mas é declarado ao lado dele: uma aprovação que rodou menos passes é uma
afirmação mais estreita, e o leitor precisa saber.
Rodadas
Uma segunda revisão da mesma PBI acrescenta a rodada N+1 em vez de sobrescrever a rodada N. O histórico do que foi achado e corrigido é parte do valor do artefato.
Na rodada > 1, cada critical/major que veio da rodada anterior recebe um veredito explícito:
corrigido, parcialmente corrigido ou em aberto. Um achado ainda aberto mantém o número, a
severidade e a marca (rodada de origem: {M}).
Rodada de correção é verificação, não review
Quando a rodada existe por causa de uma correção — o makuco-desenvolver registrou de qual commit ela
partiu —, ela faz três coisas e pára:
- Responde cada achado em jogo — os carregados e os contestados.
- Roda o pass 3 só sobre o diff da correção.
- Traz o pass 4 ou o 5 só quando a correção os justifica — o de design se ela criou, moveu ou renomeou arquivo ou mudou uma assinatura; o de testes se ela mexeu em teste ou acrescentou comportamento sem teste.
O que bloqueia a partir da segunda rodada
Tudo o que os passes acharem continua reportado; o que muda é o que devolve o trabalho:
| Achado | Bloqueia? |
|---|---|
| Carregado — de uma rodada anterior, ainda em aberto ou parcialmente corrigido | Sim, com a severidade e o número originais |
| Regressão da correção — novo, numa linha ou função que o diff da correção tocou, ou num chamador de uma assinatura que ele mudou | Sim |
| Novo fora da correção | critical sim, em qualquer lugar. major não: vira observação registrada |
A observação não some: fica no review.md. O relatório diz em quantos achados a rodada bloqueou e
quantos ficaram como observação.
Uma rodada que você rodar à mão, fora do ciclo — sem commit de correção registrado —, continua sendo um review completo, que reprova por tudo.
Achado contestado
Quando a correção discorda de um achado em vez de corrigi-lo, o argumento vem por escrito. A rodada seguinte tem que responder, citando código:
- mantido — o argumento não se sustenta, e esta é a linha que mostra por quê. O achado continua aberto e bloqueando;
- aceito — o argumento se sustenta; o achado estava errado. Ele sai, e o relatório diz que a rodada anterior errou.
Invocado pelo makuco-desenvolver
No fechamento de uma PBI, o makuco-desenvolver carrega esta skill no próprio contexto — nunca
num subagente — e lê o veredito do sessao-review.md. Com NECESSITA CORREÇÕES, ele corrige
as tasks apontadas e pede a rodada seguinte, até duas rodadas automáticas; no teto, a decisão
volta para você. Detalhes em Desenvolver → O ciclo de review.
PBI de correção
Quando a PBI saiu de uma investigação de bug, a pasta da feature tem um
rca.md. O review roda os passes normais, no perfil que o passo 1 escolheu, e o pass 1 ganha uma
pergunta: a mudança fecha o mecanismo que o laudo descreve, e um teste cobre a classe do bug?
Uma correção que faz o sintoma sumir sem tocar no mecanismo citado é achado, não aprovação. As linhas
citadas são lidas na versão revisada, não no commit que o laudo fixou.
Artefatos gerados
.makuco/docs/modules/module_NNN_nome/feature_NNN_nome/pbis/pbi-NNN-slug/
├── sessao-review.md # estado da sessão (escrito direto)
└── review.md # artefato canônico (escrito SÓ pelo makuco-copy-writer)
.makuco/reviews/
├── {slug}.md # só em modo DIFF, escrito direto, sem status.yml
└── .sessao-review-{slug}.md # estado da sessão do modo DIFF, um por alvoEstrutura do review.md
- Resumo — o que foi revisado, em qual modo, qual rodada, qual perfil (e por quê), e o veredito.
- Passes executados — quais rodaram, quais foram
SKIPe por quê, quais foramN/A. - Achados — tabela numerada:
#, Severidade, Arquivo, Linha, Categoria, Descrição, Recomendação. - Cobertura dos critérios de aceite — só em modo PBI, vinda do pass 1.
- Rodada anterior — só na rodada > 1: cada achado como corrigido / parcialmente / em aberto, as contestações respondidas e as observações que não bloquearam.
- Notas de escopo — arquivos excluídos, contexto que faltou, candidatos descartados e por quê, e se houve subagentes.
Degradação
- Skill de passe não instalada → avisa uma vez nomeando o passe, marca
SKIP, continua. - Subagentes indisponíveis → não dá erro: a skill trabalha as skills de passe ela mesma, sequencialmente, e declara no relatório que a revisão rodou sem fan-out. O isolamento que torna revisores independentes valiosos é exatamente o que faltou, e o leitor precisa saber.
- Docs de codebase ausentes → avisa uma vez; o pass 4 recorre ao
makuco-project-research.
Sem dependência de tracker
Esta skill nunca lê nem escreve no Azure DevOps. O veredito vive no status.yml (modo PBI), e
sincronizar isso para fora é trabalho do makuco-desenvolver.
O que ela delega
review.md+status.yml(modo PBI) →makuco-copy-writer, formatado pormakuco-artifact-review.- Passes 3–5 → subagentes carregados com
makuco-reviewer-correctness,-designe-tests. - Documentação pós-aprovação →
makuco-documentation, acionado no step-05 quando o veredito é APROVADO. Ele lêpbis.{slug}.reviewe se recusa a rodar se ainda não estiverapproved. - Correções → sempre de volta ao
makuco-desenvolver.
Gatilhos
revisar PBI, code review, revisar PR, revisar branch, revisar meu diff, validar implementação, verificar o trabalho, rodar os passes de review, revisão de código, procurar bugs no que foi implementado, aprovar ou reprovar a entrega.
Modelos sugeridos
| Perfil | Modelo | Quando usar |
|---|---|---|
| Recomendado | Opus 5 | Detecção rigorosa de bugs e falhas de segurança. |
| Econômico | Sonnet 5 | PBIs pequenas e de baixo risco. |
| Máxima qualidade | Opus 5 | Código sensível (auth, pagamentos, dados). |