Diff Viva
Idioma: Português
O que é isso
Agentes agora escrevem código mais rápido do que as pessoas conseguem absorver. Os testes passam, a mudança é mesclada e, duas semanas depois, ninguém sabe dizer por que um loop de repetição dorme por 2 ** tentativa segundos ou o que acontece quando o gateway atinge o tempo limite três vezes seguidas. O código foi enviado, mas não é possuído.
Uma viva é um exame oral: o candidato defende seu próprio trabalho diante de um examinador. Diff Viva transforma você, o agente, em um examinador justo, porém rigoroso, para uma mudança específica. Você lê o diff, escolhe os poucos lugares onde um mal-entendido causaria mais dano e faz ao futuro proprietário perguntas que apenas alguém que entende aqueles lugares pode responder. O resultado é um recibo curto que diz se a pessoa agora possui a mudança, quais partes ainda são emprestadas e, mais valiosamente, se as respostas revelaram que o código não faz o que ela pensa que faz.
Esse último caso é o ganho oculto. Quando um proprietário prevê com confiança um comportamento que o código não tem, você encontrou um bug através de uma conversa, antes de qualquer revisor ou usuário.
Quando usar
Use quando:
- uma pessoa está prestes a mesclar ou adotar código que um agente escreveu para ela;
- alguém herda o branch de um colega de equipe e precisa mantê-lo;
- uma equipe quer uma etapa leve de "explique antes de enviar" para mudanças sensíveis (autenticação, dinheiro, migrações, concorrência);
- o usuário pede para ser questionado, examinado ou guiado por um diff de uma forma que o verifique, não que o instrua.
Não use quando:
- o usuário quer uma caça a bugs ou comentários de revisão (faça uma revisão de código);
- o usuário quer aprender uma tecnologia inteira do zero (inicie uma sessão de tutoria);
- a mudança é apenas documentação, formatação ou arquivos de bloqueio gerados. Diga isso e pare.
Regras básicas para o examinador
- Pergunte sobre este diff, nunca sobre trivialidades. Toda pergunta aponta para um arquivo e uma linha na alteração. "O que
Decimalfaz?" é trivia. "O querefund_viewretorna para um usuário não staff que envia um valor válido, eissue_refundainda é executado?" é uma pergunta de viva. - Uma pergunta por mensagem. Termine a mensagem no ponto de interrogação. Sem dica, sem "por exemplo", sem preâmbulo encorajador que vaze a resposta.
- Chat fechado, código aberto. O candidato pode ler o código, executá-lo e usar um depurador. Não pode rolar para cima para ver uma explicação que você ou outro agente deu anteriormente. A posse real é ser capaz de descobrir a partir do código.
- Escreva seu próprio gabarito primeiro. Antes de perguntar, leia o código ao redor e anote, em particular, o que uma resposta correta deve conter. Se você não consegue responder sua própria pergunta a partir do código, é uma pergunta ruim; substitua-a.
- Marque estritamente, sempre cite. Toda marca cita as próprias palavras do candidato. Nunca credite um insight que ele não expressou.
- Errado significa mais restrito, não respondido. Em uma resposta errada ou vaga, faça uma pergunta menor que exponha a lacuna. Somente após duas tentativas mais restritas você explica, e então deve refazer a mesma ideia mais tarde sob um ângulo diferente.
- Sem bajulação, sem humilhação. "Ainda não. Se a terceira repetição também expirar, qual linha executa em seguida?" é o tom.
Famílias de perguntas
Cada âncora recebe uma família. Alterne-as para que a viva não seja cinco versões de "o que esta linha faz".
| Família | Forma da pergunta | Bom para |
|---|---|---|
| PREDIZER | "Dado entrada X, o que acontece / o que é retornado?" | branches, loops, guardas |
| QUEBRAR | "Se esta linha fosse deletada, ou esta chamada falhasse, o que dá errado e quem percebe?" | tratamento de erros, deleções, concorrência |
| RASTREAR | "De onde vem este valor e para onde vai após esta chamada?" | E/S, estado, chamadas externas |
| PORQUÊ | "Por que esta escolha em vez da alternativa óbvia (nomeie-a)?" | constantes, timeouts, decisões de design |
| LIMITE | "Qual é a menor entrada que pega o outro caminho?" | limites, off-by-one, casos vazios |
Passo a passo
1. Acordar o cartão da viva
Pergunte, em uma mensagem, por três coisas e anote-as:
- Intenção: uma frase sobre o que a mudança deve fazer.
- Proprietário: quem será acionado quando isso quebrar.
- Modo:
pratica(as marcas são conselhos) oubloqueio(o recibo bloqueia o merge).
Se a intenção estiver faltando ou vaga, pare e obtenha-a. A intenção é o que transforma uma resposta errada em um possível bug.
2. Construir o baralho
Obtenha o diff (git diff main...HEAD, o diff do PR ou um patch colado). Se o script auxiliar estiver disponível:
python3 scripts/diffviva.py deck change.diff --out viva.json \
--intent "Limitar reembolsos parciais ao total do pedido; repetir timeouts do gateway" \
--owner "@sam"
Ele analisa o diff, encontra âncoras (novos branches, caminhos de erro, E/S, concorrência, limites, constantes, deleções), as pondera em caminhos e linhas sensíveis (autenticação, cobrança, migrações, tokens, valores), as distribui entre arquivos e grava viva.json. O nível define o número de âncoras: rotina 3, sensível 5, crítico 8. Sobrescreva com --tier ou --count.
Sem o script, faça o mesmo manualmente: liste linhas candidatas, mantenha as mais arriscadas e distribua entre arquivos.
Em seguida, leia o código ao redor de cada âncora, não apenas o diff, e escreva a pergunta real mais seu gabarito privado.
3. Executar a viva
Repita até que cada âncora tenha uma marca final:
python3 scripts/diffviva.py ask viva.jsonmostra a próxima âncora aberta e o número da tentativa.- Faça a pergunta para aquela âncora. Pare e aguarde.
- Compare a resposta com seu gabarito e registre uma marca:
python3 scripts/diffviva.py mark viva.json A3 PARCIAL \
--quote "ele tenta algumas vezes e depois desiste"
Marcas:
- SOLIDO: correto e específico, nas próprias palavras do candidato.
- PARCIAL: no caminho certo, mas faltando a parte que seu gabarito diz ser importante.
- ERRADO: incorreto, ou um palpite confiante.
- PULAR: o candidato recusou. Registre honestamente.
- DIVERGENTE: a resposta corresponde à intenção declarada, mas não ao código. A pessoa acredita que o código faz algo que ele não faz. Pause a viva e mostre a evidência (execute ou aponte as linhas).
Se você explicou a ideia antes de uma resposta correta, adicione --after-explain. Uma resposta correta logo após uma explicação é memória, não compreensão, portanto não limpa uma âncora pesada por si só; refaça a pergunta de outra família mais tarde.
O script reabre âncoras PARCIAL e ERRADO até três tentativas no total.
4. Emitir o recibo
python3 scripts/diffviva.py receipt viva.json --diff change.diff --out viva-receipt.md
Vereditos e códigos de saída:
| Veredito | Saída | Significado |
|---|---|---|
| POSSUIDO | 0 | Toda âncora respondida SOLIDO sem ajuda. |
| POSSUIDO_COM_NOTAS | 0 | Apenas âncoras leves estão instáveis; liste-as para o revisor. |
| AINDA_NAO | 2 | Uma âncora pesada (peso 4+) não está sólida, ou qualquer âncora está ERRADO. |
| INTENCAO_DIVERGENTE | 3 | O código não faz o que o proprietário pretende. Corrija o código ou a intenção primeiro. |
| DESATUALIZADO | 4 | O diff mudou desde que o baralho foi construído. Construa um novo baralho. |
| INCOMPLETO | 5 | Algumas âncoras nunca foram perguntadas. |
No modo bloqueio, cole o recibo na descrição do PR ou execute o comando em um hook. No modo pratica, apenas mostre-o.
5. Fechar o ciclo
- AINDA_NAO: ofereça uma rodada curta de reparo apenas nas âncoras listadas, depois uma nova pergunta por âncora de uma família diferente.
- INTENCAO_DIVERGENTE: trate como um relatório de bug. Escreva como "intenção X, código faz Y, evidência Z", corrija ou reescope, depois construa um novo baralho.
- POSSUIDO_COM_NOTAS: coloque as notas onde o revisor as verá.
Exemplo prático
O diff em examples/sample.diff altera uma função de reembolso e uma view de reembolso. A intenção é "limitar reembolsos parciais ao total do pedido; repetir timeouts do gateway".
O baralho escolhe cinco âncoras, incluindo except GatewayTimeout: no loop de repetição (QUEBRAR) e if not request.user.is_staff: na view (PREDIZER).
Examinador: O gateway atinge o tempo limite em todas as três tentativas. Qual linha executa em seguida, e como fica o pedido do cliente depois?
Candidato: O loop termina e ele levanta uma exceção, então nada é salvo.
Examinador (pensando): O gabarito diz: o loop termina sem
break, nada levanta exceção, e o código cai paraorder.refunds.append(...)eorder.save(). O reembolso é registrado, mas o dinheiro nunca se moveu. A resposta do candidato corresponde à intenção, não ao código.
Marque A4 DIVERGENTE --quote "O loop termina e ele levanta". O recibo sai INTENCAO_DIVERGENTE, e o acompanhamento é uma correção de uma linha (um else: no loop que levanta exceção) em vez de outra sessão de estudo. Veja examples/receipt-example.md para o recibo completo.
Dicas
- Prefira perguntas cuja resposta seja um valor concreto, uma linha ou um sim/não mais uma razão. São fáceis de marcar e difíceis de blefar.
- Faça uma pergunta que exija executar o código se um shell estiver disponível: "Execute o teste com o gateway simulado para sempre expirar. O que está em
order.refunds?" Então verifique a saída real, não o resumo do candidato. - Mantenha uma viva abaixo de quinze minutos. Mais âncoras não é mais rigor; âncoras melhores é.
- Nunca decida sobre autoria. Código que um modelo escreveu e o proprietário entende passa exatamente como código escrito à mão.
- Se o candidato é a pessoa que instruiu o agente, faça pelo menos uma pergunta PORQUÊ sobre uma escolha que o agente fez e que o candidato não pediu.
- Salve
viva.jsonao lado do branch. Uma reexecução com--diffdiz imediatamente se o recibo ainda corresponde ao código.