Phase 14 - Lesson 38

Portões de Verificação

O agente não define o próprio trabalho como concluído. Um portão de verificação lê o contrato de escopo, o log de feedback, o relatório de regras e o diff, e responde a uma única pergunta: esta tarefa está realmente concluída? Se o portão disser não, a tarefa não está concluída, não importa o que o chat diga.

Tipo: Build Idiomas: Python (stdlib) Pré-requisitos: Phase 14 · 33 (Rules), Phase 14 · 36 (Scope), Phase 14 · 37 (Feedback) Tempo: ~55 minutos

Objetivos de Aprendizagem

  • Definir um portão de verificação como uma função determinística sobre os artefatos do workbench.
  • Combinar relatório de regras, relatório de escopo, registros de feedback e diff em um único veredicto.
  • Emitir um verification_report.json que tanto o agente revisor quanto a CI possam ler.
  • Recusar o avanço de uma tarefa em qualquer falha de severidade de bloqueio (block-severity), sem exceções.

O Problema

Agentes declaram sucesso com facilidade excessiva. Três formatos de falha dominam:

  • "Parece bom." O modelo leu seu próprio diff e decidiu que estava correto.
  • "Testes passaram." Dito com confiança. Nenhum registro do teste realmente sendo executado.
  • "Critérios de aceitação atendidos." Critérios de aceitação interpretados de forma tão flexível a ponto de significar "qualquer coisa parecida com concluído".

A solução do workbench é um único portão de verificação que lê os artefatos que o agente já produziu e toma a decisão. O portão é determinístico. O portão está sob controle de versão. O portão está conectado à CI. O agente não pode suborná-lo.

O Conceito

flowchart TD
  Diff[Diff] --> Gate[verify_agent.py]
  Scope[scope_report.json] --> Gate
  Rules[rule_report.json] --> Gate
  Feedback[feedback_record.jsonl] --> Gate
  Gate --> Verdict[verification_report.json]
  Verdict --> Pass{passou?}
  Pass -- yes --> Review[Agente Revisor]
  Pass -- no --> Refuse[recusar concluído + expor ao humano]

O que o portão verifica

Check Source artifact Severity
Todos os comandos de aceitação foram executados feedback_record.jsonl block
Todos os comandos de aceitação retornaram código zero feedback_record.jsonl block
A verificação de escopo não tem gravações proibidas scope_report.json block
A verificação de escopo não tem gravações fora do escopo scope_report.json block or warn
Todas as regras de severidade de bloqueio passam rule_report.json block
Nenhum código de saída null no feedback feedback_record.jsonl block
Arquivos modificados correspondem a scope.allowed_files both warn

Um achado warn anota o veredicto; um achado block impede passed: true.

Determinístico, não probabilístico

O portão deve produzir o mesmo veredicto para o mesmo conjunto de artefatos todas as vezes. Sem juízes LLM. Juízes LLM pertencem ao lado do revisor (Phase 14 · 39), onde o objetivo é a avaliação qualitativa, não o status.

Um relatório, um caminho

O portão emite um único verification_report.json por encerramento de tarefa, gravado em outputs/verification/<task_id>.json. A CI consome o mesmo caminho. Múltiplos portões com caminhos diferentes dividem a fonte da verdade.

Recusar sem exceções

Achados de severidade de bloqueio (block-severity) não podem ser contornados pelo agente. Eles só podem ser contornados por um humano, com um override_reason registrado e um ID de usuário overridden_by. O contorno (override) é uma alteração assinada, não uma decisão do agente.

Construa

code/main.py implementa:

  • Um carregador para cada artefato de entrada, todos com stubs locais para que a lição seja autônoma.
  • Uma função pura verify(task_id, artifacts) -> VerdictReport.
  • Um formatador de saída (printer) que mostra os resultados por verificação e o resultado final de aprovação/falha.
  • Uma demonstração com três cenários de tarefas: aprovação limpa (clean pass), desvio de escopo (scope creep) e aceitação ausente (missing acceptance).

Execute:

python3 code/main.py

Saída: três relatórios de veredicto, cada um salvo ao lado do script.

Padrões de produção na prática

Quatro padrões elevam o portão de "mais um trabalho de lint" para "o diferencial decisivo."

Defesa em profundidade, não um único portão. Gancho de pre-commit → verificação de status de CI → gancho de autorização pré-ferramenta → portão pré-merge. Cada camada é determinística, de modo que uma falha em uma camada é capturada pela próxima. O manual de março de 2026 de microservices.io é explícito: o gancho de pre-commit é não ignorável porque, ao contrário de uma habilidade do lado do modelo, não depende do agente seguir instruções. O portão de verificação fica na camada de CI / pré-merge.

Defesa por verificação determinística, juiz de modelo apenas para nuances. O emparelhamento Hybrid Norm de 2026 da Anthropic: recompensas verificáveis (testes unitários, verificações de esquema, códigos de saída) respondem a "o código resolveu o problema?" — rubricas de LLM respondem a "o código é legível, seguro, segue o estilo?". O portão executa a primeira classe; o revisor (Phase 14 · 39) executa a segunda. Misturá-los colapsa o sinal.

Log de contorno (override) assinado, não threads no Slack. Cada contorno emite uma linha em outputs/verification/overrides.jsonl com: carimbo de data/hora (timestamp), código do achado, motivo, usuário assinante, commit HEAD atual. O tempo de execução recusa qualquer contorno que careça de assinatura; a trilha de auditoria é rastreada pelo git. Esta é a linha entre uma política de contorno e um teatro de contorno.

Piso de cobertura de testes (coverage floor) como uma verificação de primeira classe. Um coverage_report.json alimenta uma verificação de coverage_floor (padrão 80%). O portão falha se a cobertura medida cair abaixo do piso ou abaixo do piso do merge anterior por mais de 1 ponto percentual. Sem essa verificação, os agentes silenciosamente excluem os testes que falham e os relatórios de verificação permanecem verdes.

Modo --strict promove alertas (warns) para bloqueios (blocks). Para ramificações de lançamento (release branches), PRs que bloqueiam o envio ou triagem pós-incidente, o modo --strict torna cada aviso uma falha grave. A flag é opcional por branch; não é o padrão global, porque strict-on-everything corrói o fluxo do dia a dia.

Use

Padrões de produção:

  • Etapa de CI. Um job verify_agent executa o portão contra os artefatos finais do agente. A proteção de merge recusa sem passed: true.
  • Gancho pré-entrega (pre-handoff hook). O tempo de execução do agente chama o portão antes de gerar o documento de entrega. Sem veredicto verde, sem entrega.
  • Triagem manual. Os operadores leem o relatório quando um agente alega sucesso e um humano suspeita dele.

O portão é o diferencial decisivo no fluxo do workbench. Todas as outras superfícies estão a montante (upstream) dele.

Envie

outputs/skill-verification-gate.md conecta o portão a um projeto específico: quais comandos de aceitação o alimentam, quais regras são de severidade de bloqueio (block-severity), quais gravações fora do escopo são toleradas, como o log de auditoria de contorno (override) é armazenado.

Exercícios

  1. Adicione uma verificação de coverage_floor: o comando de teste deve produzir um relatório de cobertura com pelo menos 80%. Decida qual artefato carrega o piso.
  2. Dê suporte a um modo --strict que promove cada warn para block. Documente os casos em que o modo strict é o padrão correto.
  3. Faça com que o portão produza um resumo em Markdown além do JSON. Defenda quais campos pertencem ao resumo.
  4. Adicione uma verificação de time_since_last_human_touch: qualquer arquivo editado dentro de 60 segundos após um toque de tecla humano é isento de sinalizações de fora do escopo (off-scope).
  5. Execute o portão em um diff real de agente do seu produto. Quantos achados são reais e quantos são ruído? Onde o portão precisa crescer?

Termos-Chave

Term What people say What it actually means
Portão de verificação "A verificação que impede o avanço" Função determinística sobre os artefatos do workbench que produz um veredicto de aprovação/falha
Severidade de bloqueio "Falha crítica/grave" Um achado que impede passed: true e exige um contorno (override) assinado
Log de contorno (override) "Por que deixamos passar" Entradas assinadas com o motivo e ID de usuário, auditadas por revisão
Comando de aceitação "A prova" Um comando de shell cuja saída zero é o significado de concluído
Caminho único de relatório "Fonte da verdade" outputs/verification/<task_id>.json, consumido tanto pela CI quanto por humanos
0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).