Passo 5 · O Loop · O Loop · Loop Engineering ENPT
Módulo 2 · O Loop · Passo 3 do ciclo

EXECUTE: uma unidade delimitada, feita do jeito certo

LEARN olhou. ANALYZE escolheu. Agora você constrói — mas exatamente uma coisa, a única unidade delimitada mais valiosa, e nada mais. EXECUTE não é "digitar código até parecer pronto." É um contrato: leia por inteiro, encontre a causa raiz, faça a coisa mais simples que atende ao escopo, adicione a verificação que prova isso, rode essa prova e registre-a. A disciplina está na delimitação.

Leia a versão simples, ou abra a camada técnica em qualquer seção.
1

A grande ideia: construa uma coisa, até o fim


Cada volta do loop tem cinco passos — LEARN → ANALYZE → EXECUTE de uma unidade delimitada → VERIFY no boundary real → DECIDE. Esta lição é o terceiro passo, aquele em que o trabalho de fato acontece. Tudo antes dele era preparação; tudo depois dele é julgamento. EXECUTE é onde você faz uma mudança.

A armadilha é óbvia uma vez nomeada: quando você finalmente vai construir, é tentador consertar cinco coisas já que está ali dentro. Você veio reparar uma torneira pingando e acaba refazendo o encanamento do banheiro inteiro. Isso parece produtivo. É a forma mais comum de uma volta do loop dar errado — porque agora nada é pequeno o bastante para provar, e se algo quebrar você não sabe qual das cinco mudanças causou.

Então o EXECUTE tem uma regra acima de todas as outras: faça a única unidade delimitada mais valiosa e pare. "Delimitada" significa que a mudança tem uma borda que você consegue apontar — estas linhas, este arquivo, este único comportamento. "Mais valiosa" significa que o ANALYZE já a classificou; você não rediscute isso aqui. Você lê tudo primeiro, encontra a causa real (não o sintoma), faz a mudança mais simples que satisfaz o escopo, adiciona uma verificação que a prova, roda essa prova e registra o que fez. Essa sequência é o Contrato de Unidade, e o resto desta lição o ensina por seis ângulos.

Pense nisso como… um cirurgião com um único item na lista. Ele não abre você para um apêndice e decide também "dar uma arrumada" num joelho de quebra. Ele delimita o corte exatamente ao que foi combinado, confere a contagem de instrumentos antes de fechar e escreve a nota operatória. Delimitado, provado, registrado. A habilidade não é cortar mais — é cortar apenas o que foi delimitado, e provar que deixou o resto intacto.

O propósito inteiro de delimitar é atribuição. Se uma volta muda uma coisa e a verificação falha, você sabe exatamente o que desfazer. Se ela muda cinco coisas, uma falha não diz quase nada, e o loop perde sua melhor propriedade: a de que todo passo é reversível e explicável.

Por que "uma unidade delimitada" é estrutural para um loop autônomo

Numa execução autônoma, AFK, o loop roda sem um humano aprovando cada diff. A única coisa que mantém isso seguro é que todo EXECUTE produz uma mudança pequena o bastante para o passo VERIFY provar ou rejeitar num boundary real. Um diff que toca um comportamento mapeia limpo para um Proof Gate; um diff que toca cinco comportamentos precisa de cinco provas e de um raio de impacto muito maior se tiver de ser revertido. Delimitar é o que torna o próximo passo — VERIFY — tratável.

O EXECUTE nunca alega; ele monta a prova

O EXECUTE não tem o direito de dizer "pronto". Ele produz a mudança e a verificação que vai julgar a mudança, e então roda essa verificação. O veredito pertence ao VERIFY (a próxima lição), e num time pertence a um Validador independente — nunca a quem construiu. Então o trabalho do passo EXECUTE é deixar para trás algo que seja barato e honesto de verificar: um teste que falhava e agora passa, um comando cujo código de saída vira, uma observação de boundary que muda. "Adicionei a verificação que prova e a rodei" é o entregável; "funciona" não é algo que o EXECUTE tenha permissão de afirmar.

Desvio de escopo é uma violação de escopo, não um bônus

Se, no meio da construção, você descobre uma segunda mudança valiosa, a jogada correta é registrá-la como uma nova unidade e devolvê-la ao ANALYZE para classificação — não embuti-la no diff atual. O escopo foi definido na lição 2; o ANALYZE escolheu uma unidade dele na lição 4. O EXECUTE honra essa escolha. Alargar o escopo silenciosamente no meio da volta quebra o contrato que deixa o loop rodar sem supervisão.

2

O Contrato de Unidade — seis jogadas, em ordem


O EXECUTE não é livre. É uma sequência fixa de seis jogadas, e pular uma é como as voltas dão errado. Leia como um checklist que você roda toda vez, por menor que a mudança pareça.

1 ler por inteiro 2 causa raiz + plano delimitado 3 coisa mais simples no escopo 4 adicionar a verificação que prova 5 rodar a prova 6 registrar
1 · ler tudo 2 · causa raiz + plano delimitado 3 · mais simples no escopo 4 · adicionar a verificação que prova 5 · rodar prova? passa 6 · registrar → entregar ao VERIFY falha → replaneje a MESMA unidade (não alargue o escopo) a borda da unidade nunca se move — uma prova que falha replaneja o mesmo escopo, não o aumenta
Leia da esquerda → direita: as seis jogadas do contrato. Uma prova que falha volta para replanejar a mesma unidade delimitada — ela nunca alarga o escopo.

1 · Ler por inteiro

Leia toda a superfície relevante antes de editar um caractere — a função e quem a chama, o teste que a cobre, a issue/escopo, as fontes confiáveis do LEARN. A maioria das correções ruins é ruim porque quem construiu editou a primeira linha plausível sem ler a segunda, que explicava por que ela foi escrita daquele jeito.

2 · Causa raiz + plano delimitado

Nomeie a causa de fato, não o sintoma. Um erro 500 é um sintoma; "o handler desreferencia user antes da checagem de null" é uma causa. Depois escreva o menor plano que ataca essa causa e desenhe sua borda: quais linhas, qual arquivo, qual único comportamento muda. A borda é o limite.

3 · A coisa mais simples que atende ao escopo

Entre os planos que satisfazem o escopo, pegue o de menos partes móveis. Não o mais esperto, não o mais geral, não aquele que "também nos prepara para" um recurso futuro. Simplicidade aqui é o que mantém o diff dentro da borda e mantém a prova barata.

4 · Adicionar a verificação que prova

Escreva a verificação antes de acreditar na mudança. Um teste de regressão que falha no código antigo e passa no novo; uma asserção; um comando cujo código de saída vira. A verificação é a espinha do contrato — é o que transforma "acho que funciona" em algo que o VERIFY pode confirmar num boundary real.

5 · Rodar a prova

Rode de verdade, no boundary real — não na sua cabeça, não como mock, não como alegação. Se passar, entregue ao VERIFY. Se falhar, você volta à jogada 2 e replaneja a mesma unidade; você não absorve uma correção nova para fazer a falha sumir.

6 · Registrar

Uma linha em LOOP-LOG.md: qual unidade, qual causa raiz, qual prova, passou/falhou. É isso que torna a execução observável a um humano que nunca toca na construção — o registro durável de que o contrato foi honrado.

3

Em uma imagem: onde o EXECUTE se encaixa no turno


O EXECUTE é o meio do ciclo — alimentado pela unidade escolhida pelo ANALYZE, entregando uma mudança provada ao VERIFY. É o único passo que escreve no artefato, e é exatamente por isso que ele precisa ser o mais delimitado.

LEARN olhar ANALYZE escolher UMA EXECUTE uma unidade delimitada VERIFY provar DECIDE próximo? 1 unidade prova loop — a próxima volta começa do zero a partir do LEARN o único passo que escreve no artefato → por isso precisa ser o mais delimitado
O EXECUTE é o centro da volta: consome uma unidade escolhida e produz uma mudança provada. É o único passo que altera o artefato.
4

A unidade, como um checklist que dá para percorrer


Aqui está o Contrato de Unidade para uma mudança real, disposto como um plano em etapas. A faixa é o contrato; cada cartão amplia uma jogada com suas tarefas concretas, a barra de saída que permite avançar e os riscos de pulá-la. Clique numa etapa — ou foque a faixa e use as setas — para abrir seu cartão.

O exemplo recorrente desta lição: um endpoint de login que lança um 500 quando o e-mail é desconhecido. O ANALYZE já o classificou como a unidade mais valiosa. Agora estamos executando-o.

Unidade Corrigir o 500 no login com e-mail desconhecido Borda de escopo src/routes/auth.ts · um handler Escolhida por ANALYZE (rank 1)
Progresso 2 de 5 jogadas concluídas

Clique numa etapa — ou foque a faixa e use — para abrir seu cartão.

Jogada 3 · Em andamento

A coisa mais simples que atende ao escopo

agora

Objetivo: fazer a menor mudança que corrige a causa nomeada — um único guard que retorna um 401 genérico quando o usuário está ausente, antes de qualquer propriedade ser lida. Sem refatoração, sem nova abstração.

Tarefas
  • Adicionar um guard: if (!user) return 401
  • Usar uma mensagem genérica (sem enumeração de contas)
  • Deixar o código ao redor intocado
  • Resistir a toda tentação de "já que estou aqui"
Barra de saída
  • O diff é um punhado de linhas, um arquivo
  • Nenhuma linha não relacionada foi movida ou reformatada
  • A mudança se lê como obviamente correta
Risco de pular
Méd Superengenharia da correção Um "helper de auth-guard reutilizável" para uma checagem de uma linha. Mitigação: a coisa mais simples que atende ao escopo vence; generalize depois, se um segundo caso aparecer.

A barra de saída é um gate mensurável, não um sentimento

Cada jogada só avança quando sua barra de saída é cumprida — e as barras são escritas como coisas que você consegue checar, não vibrações. "O diff é um punhado de linhas, um arquivo" é checável; "o código parece limpo" não é. É a mesma disciplina de gate que o VERIFY usa, aplicada dentro de um único EXECUTE para que a unidade permaneça honesta sob pressão de tempo.

Uma prova que falha replaneja a mesma unidade

A faixa parece linear, mas a Jogada 5 tem uma aresta de volta: uma prova que falha leva você de volta à Jogada 2 com o mesmo escopo. A tentação quando um teste não passa é "só mudar também" algo adjacente. Isso alarga a borda e quebra a atribuição. O contrato diz: replaneje dentro do limite, ou separe uma nova unidade — nunca aumente esta silenciosamente.

A faixa é uma minúscula máquina de estados

Cada segmento carrega done / active / todo; selecionar um troca o role="tabpanel" visível. Numa execução ao vivo, esses estados vêm do tracker, então a faixa reflete a realidade, não o plano como escrito.

5

Explore as variantes — depois escolha a mais simples que atende ao escopo


A Jogada 3 diz "a coisa mais simples que atende ao escopo". Mas costuma haver mais de um jeito de corrigir a mesma causa. Antes de se comprometer, vale colocar os candidatos lado a lado e sentir os trade-offs deles contra o limite. Escolha uma correção abaixo; o diagrama e a nota de trade-off se atualizam juntos.

As três corrigem o 500. Elas diferem em quanto tocam, quanto risco adicionam e quão bem se encaixam no escopo de uma unidade. O contrato escolhe a que corrige a causa com menos partes móveis — observe os medidores.

POST /auth/login handler existente + uma linha de guard !user → 401 (genérico) resto intocado borda = poucas linhas, um arquivo handler chama o helper novo requireUser() módulo utilitário compartilhado 2 outros pontos de chamada tocados borda = 3 arquivos — mais larga que a unidade handler reescrito fluxo reestruturado muitas linhas movidas sessões caminhos de erro logging borda = o handler inteiro — desvio de escopo
Correção A: uma linha de guard dentro do handler existente retorna 401 quando o usuário está ausente; todo o resto fica exatamente como estava.

Uma cláusula guard

Adiciona uma única linha que retorna um 401 genérico quando o usuário está ausente, antes de qualquer propriedade ser lida. Corrige a causa nomeada e nada mais.

+Menor diff possível — poucas linhas, um arquivo.
+Trivialmente provável: um teste vira 500 → 401.
+Permanece exatamente dentro da borda da unidade.
Não pré-constrói um helper para um caso futuro (de propósito).
Escopo tocadomínimo
Risco adicionadobaixo
Aderência ao escopoexata

Simplicidade é uma propriedade do contrato, não de gosto

A Correção B e a Correção C podem ser "melhor engenharia" no vácuo. Mas a jogada 3 do Contrato de Unidade é "a coisa mais simples que atende ao escopo" — e o escopo é um handler, um comportamento. A Correção A é a única candidata cuja borda é igual à borda da unidade, então é a única que um único Proof Gate cobre por inteiro e que um único revert desfaz de forma limpa. O helper e a reescrita são ideias reais — elas só pertencem a unidades próprias, registradas e classificadas pelo ANALYZE.

Explorar não é o mesmo que alargar

Manter três candidatas lado a lado é boa prática — é como você confirma que a mais simples de fato corrige a causa. A disciplina é que a exploração termina numa escolha, e a escolha respeita o limite. Você compara para estreitar, nunca para justificar fazer as três.

6

As restrições que a unidade deve honrar


"A coisa mais simples que atende ao escopo" tem uma segunda metade silenciosa: ela também precisa ficar dentro das restrições do projeto. O escopo diz o que mudar; as restrições dizem como qualquer mudança deve se comportar — as regras de segurança, estilo e safety que valem em toda a base de código. Uma unidade que corrige o bug mas viola uma restrição não está pronta.

Abaixo estão as restrições que o projeto desta lição carrega, mostradas do jeito que um design system mostra seus tokens: um conjunto nomeado que você consegue percorrer, uma tabela que diz exatamente onde cada uma se aplica e pares fazer / não fazer para aquela que estamos prestes a tocar.

As restrições do projeto (nomeadas, como tokens)

SEGURANÇA
no-enumerationmesma resposta para senha-errada e usuário-inexistente
CONTRATO
status-codes401 não autorizado · 429 limitado · nunca 500 para auth
ESTILO
no-consoleapenas logger estruturado, nunca console.log
ESCOPO
one-behavioruma unidade muda um comportamento em um arquivo
SAFETY
proof-requiredtoda mudança vem com uma verificação que a prova
ENTRADA
validate-firstnunca leia um campo antes de ele ser checado

Onde cada restrição se aplica a ESTA unidade

RestriçãoRegraO que ela força nesta correção
no-enumeration Respostas de auth genéricas A mensagem do 401 não pode revelar se o e-mail existe.
status-codes Auth nunca retorna 500 O ponto inteiro: um usuário ausente é um 401, não um crash.
validate-first Cheque antes de ler Faça guard de user antes de tocar user.hash.
one-behavior Um comportamento, um arquivo Só o caminho do usuário desconhecido muda; todo o resto está congelado.
proof-required Entregue uma verificação Um teste que falha no 500 e passa no 401 deve acompanhar o diff.

Fazer & não fazer — honrando no-enumeration

Fazer — honre a restrição

Uma resposta genérica para os dois modos de falha. Um atacante não consegue distinguir "conta inexistente" de "senha errada", então não consegue enumerar e-mails válidos — e o status é o 401 do contrato, nunca um 500.
if (!user || !ok) return res.status(401).json({ error: 'bad_credentials' });

Não fazer — corrigir o crash, quebrar a regra

Retornar um 404 no_such_user distinto faz o 500 parar — mas agora vaza quais e-mails estão registrados, violando no-enumeration. O bug sumiu; a unidade ainda não está pronta.
if (!user) return res.status(404).json({ error: 'no_such_user' });

O escopo delimita a mudança; as restrições delimitam o comportamento

O escopo é a borda desta unidade — quais linhas você pode tocar. As restrições são invariantes globais que toda unidade deve respeitar, não importa o que toque. São cercas independentes: você pode satisfazer o escopo (um diff minúsculo) e ainda falhar uma restrição (um 404 que enumera contas), ou honrar toda restrição enquanto estoura o escopo (uma reescrita completa limpa de restrições). O contrato exige os dois: dentro da borda e dentro das regras.

Onde as restrições vivem

Num loop real, elas vêm do registro durável do projeto — o bloco de constraints do GOAL.md, um doc CONTEXT/ADR, a config do linter. O EXECUTE as lê como parte da jogada 1 ("ler por inteiro"), para que a correção mais simples seja escolhida a partir do conjunto que já as satisfaz, não remendada depois que um revisor pega uma violação.

7

Delimitado vs desvio de escopo, lado a lado


O hábito mais importante no EXECUTE é manter a borda parada. Aqui está o mesmo ponto de partida levado de dois jeitos — um fica dentro do limite, o outro cresce silenciosamente até nada ser provável.

DELIMITADO — mantenha a borda parada DESVIO DE ESCOPO — a borda escorrega 1 unidade · 1 arquivo · 1 comportamento + uma linha de guard uma prova a cobre ✓ revert limpo de um passo a correção do guard + rate limiting + refatorar o logger + renomear campos + ajustar sessões nenhuma prova única · revert emaranhado uma falha não diz quase nada
À esquerda: a borda se mantém, então uma prova e um revert se aplicam. À direita: cinco mudanças de "já que estou aqui" dissolvem a borda — atribuição e reversibilidade se foram.
Um teste útil no meio da construção: "um revisor conseguiria desfazer minha mudança em um passo?" Se sim, a unidade está delimitada. Se desfazer significa desembaraçar cinco edições entrelaçadas, o escopo já desviou — divida-a.
8

Remendo vs correção delimitada limpa — dois sabores de "pequeno"


Nem toda mudança pequena é uma boa unidade delimitada. Há diferença entre um remendo rápido que esconde o sintoma e uma correção delimitada limpa que resolve a causa — as duas podem ser minúsculas. A matriz dispõe a mesma unidade de três jeitos para você ver qual "pequeno" de fato satisfaz o contrato.

Leia como uma grade: cada linha é uma propriedade com que o contrato se importa, cada coluna é uma abordagem. Depois os cartões dizem quando cada uma é a jogada certa.

O mesmo bug 500, três jeitos — julgados pelo Contrato de Unidade
propriedade \ abordagem remendo de sintoma correção delimitada limpa grande reescrita
ataca a causa? não — esconde o 500 sim — faz guard do deref sim (e muito mais)
tamanho do diff minúsculo pequeno grande
fica na borda do escopo? sim sim não
provável por uma verificação? só o sintoma sim — 500 → 401 não — ampla demais
veredito do contrato falha (sem causa raiz) passa falha (desvio de escopo)

remendo de sintoma

- crash em user.hash + try { ... } catch { return 500 } // engole o erro, causa intacta

Esconde o sintoma envolvendo o crash. O 500 pode parar de aparecer, mas o null deref continua ali esperando.

Veredito do contrato: falha — sem causa raiz.

correção delimitada limpa

// guard antes do deref + if (!user) return res.status(401) // mensagem genérica · um arquivo

Resolve a causa com a menor mudança no escopo, honrando toda restrição, com uma verificação que a prova.

Veredito do contrato: passa — esta é a unidade.

grande reescrita

- handler inteiro + novo fluxo, sessões, logging… // correto, mas sem limite

Corrige tudo e mais um pouco — mas a borda se foi e uma prova não a cobre. As partes boas pertencem a unidades próprias.

Veredito do contrato: falha — desvio de escopo.

Um remendo pode ser minúsculo e ainda assim errado

O remendo de sintoma é o menor diff dos três — e é o que mais falha o contrato, porque não ataca a causa nomeada (jogada 2). "Pequeno" não é o objetivo; "a coisa mais simples que corrige a causa dentro do escopo" é. Um try/catch que transforma um 500 em outro 500 é movimento sem progresso: a próxima requisição com e-mail desconhecido ainda bate no mesmo caminho quebrado.

A correção limpa é a que tem uma prova real

Só a coluna do meio tem uma verificação que distingue corrigido de quebrado num boundary real (POST de e-mail desconhecido → esperar 401). O remendo só consegue "provar" que um erro foi engolido; a reescrita é ampla demais para qualquer verificação única cobrir. Provabilidade-por-uma-verificação é um teste afiado para saber se uma mudança é genuinamente uma unidade delimitada.

9

A jogada que pulam: adicione a verificação que prova


Das seis jogadas, a mais frequentemente abandonada é a jogada 4 — adicionar a verificação que prova a mudança. Parece custo extra quando a correção "obviamente funciona". Mas uma correção sem prova é só uma alegação, e o loop roda sobre provas, não alegações. O truque que torna a verificação confiável: ela precisa falhar primeiro no código antigo.

escreva a verificação e-mail desconhecido → 401 rode no código ANTIGO precisa FALHAR (deu 500) aplique a correção a linha de guard rode no código NOVO precisa PASSAR (deu 401) falha primeiro ↑ — prova que testa a coisa certa passa depois ↑ — prova que a correção funciona uma verificação que passa em AMBOS, código antigo e novo, não prova nada — rejeite-a e escreva uma mais afiada
Uma verificação confiável falha no código quebrado e passa no código corrigido. Se passar nos dois, não está testando o bug — reescreva-a.
src/routes/auth.ts — a verificação que prova (um teste de regressão)
// falha no handler antigo (500), passa depois do guard (401)
test('unknown email returns 401, not 500', async () => {
  const res = await request(app)
    .post('/auth/login')
    .send({ email: 'nobody@example.com', password: 'x' });
  expect(res.status).toBe(401);          // não 500
  expect(res.body.error).toBe('bad_credentials'); // genérico — sem enumeração
});

Rode no boundary real

A verificação atinge a rota de verdade através do app, não uma função stubada — é isso que "boundary real" significa. Rode só este teste enquanto itera:

# rode apenas o novo teste de regressão
npm test -- -t "unknown email returns 401"

# esperado: vermelho no commit pré-correção, verde depois do guard

Este é o entregável do EXECUTE, não o veredito do VERIFY

Adicionar e rodar esta verificação faz parte do EXECUTE. O julgamento independente — "sim, isto de fato atende ao done-when do escopo" — é o próximo passo, VERIFY, e num time é feito por um Validador que não escreveu a correção. O trabalho do EXECUTE é entregar uma mudança que seja barata e honesta de verificar: aqui, um único comando cujo código de saída diz a verdade.

10

Auto-revise antes de entregar


A última coisa que o EXECUTE faz antes de o VERIFY assumir é ler o próprio diff com olhos de revisor. Abaixo está a mudança real da nossa unidade — linhas verdes adicionadas, vermelhas removidas — com os selos de risco que um construtor cuidadoso anexaria e notas de revisor fixadas em linhas específicas. Clique em qualquer linha com um ponto cor de barro para ler sua nota.

Esta é uma auto-revisão: pegar os problemas óbvios antes que um Validador independente (ou um humano lendo o log) os veja. Uma das notas é bloqueante — veja se você a encontra antes de ler todas.

ABERTO  unidade · fix-login-500 · uma mudança delimitada → main
Fazer guard de usuário ausente antes de ler user.hash

Transforma um 500 no login com e-mail desconhecido em um 401 genérico em POST /auth/login. 1 arquivo alterado · +3 −2

Crashescaminho do 500 removido Latência~ estável (uma checagem) Enumeração401 genérico, sem vazamento Novo comportamentoprecisa do teste de 401
src/routes/auth.ts+3−2
@@ -11,7 +11,8 @@ router.post('/auth/login', async (req, res) => {
1111 const { email, password } = req.body;
1212 const user = await db.users.findByEmail(email);
1415 if (!ok) return res.status(401).json({ error: 'bad_credentials' });
0 / 4 notas abertas Auto-revisão: pronta para o VERIFY

Cada linha com ponto cor de barro carrega uma nota. Uma é bloqueante e precisa ser resolvida antes de a unidade ser entregue — abra as notas para encontrá-la.

A auto-revisão pega os erros baratos cedo

Ler o próprio diff com selos de risco e notas de linha faz parte da higiene das jogadas 3–4: a mudança ficou no escopo, honrou as restrições e veio com uma prova? É o lugar mais barato para pegar um vazamento de enumeração ou uma linha reformatada à toa. Mas não é o veredito.

Quem construiu nunca assina o próprio trabalho

No loop, o julgamento de que a unidade de fato atende ao done-when é do VERIFY — e num time pertence a um Validador independente que não escreveu o código. A auto-revisão deixa a entrega limpa; ela não substitui o gate independente. Essa separação é exatamente o que mantém uma execução AFK honesta: quem construiu nunca é quem certifica.

11

Exemplo resolvido: uma correção delimitada, do plano ao provado


Juntando o contrato inteiro na nossa unidade recorrente, jogada por jogada — exatamente o que um Executor produz em um passo de EXECUTE.

Jogadas 1–3 · construir

Ler → causa → correção mais simples

Ler por inteiro: o handler lê user.hash na linha depois de findByEmail, sem checagem de null. Causa: null deref quando o e-mail é desconhecido. Correção mais simples no escopo: um guard retornando um 401 genérico antes do deref. Sem helper, sem reescrita.

o diff delimitado
  const user = await db.users.findByEmail(email);
+ if (!user) return res.status(401)
+     .json({ error: 'bad_credentials' });
  const ok = await verify(password, user.hash);
Jogadas 4–6 · provar + registrar

Verificar → rodar → registrar

Adicionar a verificação: POST de e-mail desconhecido, esperar 401 (falha no código antigo, passa no novo). Rodar a prova: a suíte fica verde no boundary real. Registrar — uma linha, depois entregar ao VERIFY.

LOOP-LOG.md — uma entrada
## volta 7 — EXECUTE
unit:   fix-login-500
cause:  null deref em usuário ausente
change: +1 guard, src/routes/auth.ts
proof:  npm test -t "unknown email"PASS
scope:  1 arquivo · 1 comportamento · dentro do limite
next:   → VERIFY (Validador, não quem construiu)
Repare no que a entrada não diz: ela nunca alega "o bug está corrigido". Ela registra a mudança e a prova que foi rodada, e entrega explicitamente o veredito ao VERIFY. Essa contenção é o contrato funcionando como projetado.
12

Verificação rápida — o contrato passaria?


Cinco perguntas sobre o EXECUTE. Escolha uma resposta para ver se está certa e por quê — recuperar vence reler. Sem pista na formatação; leia cada opção pelos próprios méritos.

Q1O que "uma unidade delimitada" significa no EXECUTE?

B. Delimitada significa que a mudança tem uma borda visível — um comportamento, uma intenção do tamanho de um arquivo — para que uma única prova a cubra e um único revert a desfaça. O tamanho do seu dia e "o que está no arquivo" não são o limite.

Q2No meio da construção você nota uma segunda correção valiosa. O que o contrato diz?

C. Uma correção nova é uma unidade nova. Registre-a e deixe o ANALYZE classificá-la; não alargue a borda atual nem abandone a unidade escolhida. Absorvê-la silenciosamente quebra a atribuição e o contrato que deixa o loop rodar sem supervisão.

Q3Por que a verificação que prova precisa falhar primeiro no código antigo?

A. Uma verificação que passa tanto no código antigo quanto no novo não prova nada — ela não está exercitando o bug. Vê-la falhar no código quebrado e depois passar na correção é o que a torna uma prova real, não decoração.

Q4A correção faz o 500 parar retornando um 404 distinto "no_such_user". Veredito?

B. Escopo e restrições são duas cercas. O diff cabe no escopo, mas um 404 distinto diz a um atacante quais e-mails existem — violando no-enumeration. Dentro da borda e dentro das regras, ou não está pronto.

Q5O EXECUTE rodou a prova e ela passou. O que o EXECUTE tem direito de alegar?

C. O EXECUTE produz uma mudança e roda uma prova, depois a registra. O julgamento de que ela de fato atende ao done-when pertence ao VERIFY — e num time, a um Validador independente que não a construiu. O EXECUTE nunca assina o próprio trabalho.

Pontuação: 0 / 5
Seu agente é seu professor. Quer rodar uma passagem real de EXECUTE no seu próprio repositório — escolher uma unidade, delimitá-la, adicionar a verificação que prova — ou está em dúvida se uma mudança sua é genuinamente "uma unidade"? Pergunte. A seguir, uma vez que a mudança esteja construída e a prova escrita, vem o passo que a julga: VERIFY e os gates: prove, não alegue.