O vocabulário de 2026 fixou uma fórmula: agente = modelo + harness. O harness é toda a infraestrutura em volta do modelo — o loop, as ferramentas, o estado, o contexto, os guardrails e a verificação. A palavra vem do jargão de teste de software, onde o harness é o andaime que roda o código sob condições controladas. Faz sentido: é exatamente isso que ele é.

A parte que os textos sobre o assunto explicam bem é a anatomia. A parte que quase nenhum mostra funcionando é a última da lista: a verificação.

Este é o 16º post deste blog, escrito por um processo assistido por IA com gate humano obrigatório. O harness que segura isso não tem nada de exótico — um schema, uma bateria de testes, um job de CI e alguns arquivos de texto versionados. Este post abre o registro do que essas peças barraram de verdade. E termina com o que elas não pegaram, que é a parte mais útil.

A régua deste post

Só entra aqui defeito que está registrado em arquivo versionado do repositório: o teste que falhou, o comentário que ficou no código, a lição anotada na memória do projeto. Cada caso aponta onde conferir.

É a mesma régua que aplico a número de fonte externa. Se não dá para auditar, não entra — nem quando o dado é meu.

O que o harness barrou

GateO que pegouO que iria ao ar
Contrato Zod do frontmattertag fora da taxonomia; description com 162 caracteres de 160 permitidos, duas vezes seguidaspost com meta truncada no Google e tag órfã sem rota
Lighthouse no runner LinuxCLS de 0,31 que a minha máquina não reproduzialayout pulando na tela de quem lê pelo celular
Auditoria de SEOdiretiva inventada no robots.txt: nota 100 → 92 nas três páginas medidasqueda de SEO no site inteiro por um arquivo de 15 linhas
Auditoria de acessibilidadeseção nova fechando em h2 antes do rodapé em h4: 100 → 98hierarquia de títulos quebrada para leitor de tela
test:ariaitem de menu marcado na página errada — bug que já mordeu duas vezesnavegação mentindo sobre onde o leitor está
test:tags e test:homecontagem exibida diferente dos posts listados; rascunho virando rota públicanúmero errado na cara do leitor e texto não aprovado no ar
test:sanitizeHTML malicioso embutido em markdown (CWE-79)execução de script de terceiro dentro do post

Três desses merecem a história inteira.

O gate mais barato é o contrato

Todo post passa por um schema declarado em código antes de existir como página: título entre 10 e 70 caracteres, descrição entre 50 e 160, categoria dentro de três valores fixos, tags obrigatoriamente presentes num arquivo versionado à parte. Tag fora da lista derruba o build — o post não fica feio, ele não nasce. Já escrevi sobre o desenho dessa peça no post sobre o contrato de conteúdo.

O detalhe que interessa aqui é outro: o erro que mais se repete nesse gate é meu, não do modelo. A description estourou o limite em 162 caracteres nos posts 14 e 15, em rodadas seguidas, cada uma por dois caracteres. Um contrato que só desconfia da máquina teria deixado os dois passarem.

O gate tem que rodar no ambiente que publica

O caso mais instrutivo do acervo é um CLS de 0,31 — três vezes o limite tolerável — que só aparecia no runner Linux do CI. Na minha máquina, o mesmo commit media cerca de 0,001.

Não era flutuação de medição. A fonte de fallback que o sistema escolhe enquanto a webfont carrega é diferente em cada sistema operacional, e a troca reflowava a página inteira no Linux. A correção foi declarar um @font-face de fallback com size-adjust e ascent-override calculados das métricas reais das fontes, em vez de degradar a tipografia. O CLS foi a zero.

A lição cabe numa linha: “passou na minha máquina” é uma afirmação sobre a minha máquina. O gate que vale é o que roda onde o site é construído para valer.

Em arquivo com validador, só entra o que o padrão define

Quando publiquei o llms.txt do site, quis anunciá-lo no robots.txt com uma linha própria, LLM-Content:. Parecia inofensivo — um arquivo de texto, uma diretiva a mais.

A auditoria de SEO do Lighthouse derrubou a nota de 100 para 92 nas três páginas medidas: para o validador, diretiva desconhecida é erro de sintaxe, não extensão. E a proposta do llms.txt nem prevê ponteiro nenhum; o arquivo é achado pelo caminho fixo, igual ao próprio robots.txt.

Hoje essa tentativa vive como comentário dentro do arquivo, explicando por que ela não voltou. O repositório documenta a própria cicatriz — o que é, ele mesmo, uma peça do harness.

O gate que não bloqueia, e mesmo assim funciona

Uma escolha do CI deste projeto costuma surpreender: o job do Lighthouse roda com continue-on-error. Ele não impede o merge sozinho.

O motivo é honesto. Runners compartilhados têm variação real de CPU e disco entre execuções; um limiar absoluto de nota vira reprovação aleatória por causa do hardware do dia, não por regressão do site. E gate que reprova sem motivo ensina o time a clicar em “merge assim mesmo” — quando isso acontece, o gate parou de proteger e virou decoração.

Então ele foi desenhado para outra função: o script sai com erro quando o LCP passa de 2500 ms ou o CLS passa de 0,1, o job aparece com um X visível na PR, e a decisão de seguir é humana e consciente. Os gates determinísticos — contrato, sanitização, acessibilidade, 404, navegação — esses sim são obrigatórios e travam o merge.

A distinção vale para qualquer harness: gate que mede coisa com variância informa; gate que verifica invariante bloqueia. Trocar os dois de lugar produz ou um processo frouxo, ou um processo que todo mundo aprende a contornar.

Guardrail que é estado, não lembrete

O exemplo mais recente é de quatro dias atrás. O espaço de anúncio do site reservava altura em seis lugares sem existir conta de anúncio nenhuma — um retângulo tracejado escrito “Anúncio”, visível para o leitor.

A correção não foi comentar o código com um <!-- descomentar depois -->. O componente passou a não renderizar nada enquanto a variável de ambiente estiver vazia. Ligar a monetização, no dia em que o acervo justificar, é preencher a variável no painel da hospedagem: os seis espaços voltam sozinhos, com a altura reservada anti-CLS intacta.

A diferença entre as duas soluções é onde mora a decisão. Comentário depende de alguém lembrar; variável de ambiente é estado do sistema. Num processo com agente no meio, guardrail pendurado na memória de alguém é o primeiro a cair.

O que nenhum gate pegou

Aqui o post fica útil de verdade.

Colisão de CSS, duas vezes. Uma regra antiga apagou o display de um elemento e o cartão da home colapsou para altura zero. Nenhum teste acusou — e não era para acusar: a automação deste projeto prova estrutura e geometria, não acabamento. Quem viu foi um humano olhando a tela.

Falso defeito e falso alívio na mesma ferramenta. Uma captura de tela automatizada fotografou o fallback das fontes e inventou um defeito que não existia — faltava esperar a pintura terminar. Dias depois, uma imagem faltando na captura foi quase enterrada pela explicação cômoda (“é só o carregamento preguiçoso”) e era bug de CSS de verdade. O teste que separa os dois casos custa um minuto; a explicação confortável custa um defeito em produção.

Texto verdadeiro no lugar errado. Um aviso interno de trabalho ficou público por dias numa página legal. Nenhuma auditoria reprova isso: o HTML era válido, a nota era honesta, o lugar é que estava errado.

O harness não substitui o gate humano — ele muda o que o humano precisa olhar. A máquina fica com o repetitivo, o objetivo e o chato. Sobra para a pessoa exatamente o que ela faz melhor: julgamento e acabamento.

Como montar o seu, sem plataforma nenhuma

  1. Contrato antes do gerador. Um schema que falha o build vale mais que qualquer instrução no prompt. O prompt pede; o contrato exige.
  2. Gate mecânico antes de revisor caro. O que um script consegue reprovar não deve chegar ao modelo grande — no ciclo que abri em números neste post, uma checagem barata evitou que três revisores redescobrissem o mesmo defeito trivial.
  3. Meça no ambiente que publica. Sistema operacional, fonte, rede e CPU do CI não são os seus.
  4. Em arquivo com validador, só o que o padrão define. O resto vira comentário.
  5. Guardrail como estado, não como lembrete. Variável de ambiente, não bilhete no código.
  6. Declare o que o gate não cobre. A lista do que a automação não pega é o que diz onde o olho humano precisa passar.

Nenhum item dessa lista exige plataforma de agente, orquestrador comercial ou banco vetorial. São um schema, alguns scripts de teste, um arquivo de CI e disciplina de registro — em cima do git, que você já tem.

O benefício, medido

O benefício de um harness não é a sensação de controle. É a lista de erros que ele barrou antes de custarem alguma coisa: uma taxonomia quebrada, duas descrições estouradas, um CLS três vezes acima do limite, oito pontos de SEO em todas as páginas, dois pontos de acessibilidade, um item de navegação mentindo. Todos capturados por peças que rodam em minutos e não custam nada por mês.

E o preço honesto: nenhum desses gates me deixou mais rápido. Todos me deixaram mais difícil de estragar — que, num processo em que uma máquina escreve o rascunho, é a métrica que importa.

Fontes

  • Definição de agent harness (infraestrutura em volta do modelo: ferramentas, memória, estado, contexto e guardrails) e a origem do termo no início de 2026, com atribuição contestada — Agent harness, Wikipedia (enciclopédia, nível 3), verificado em 2026-08-14.
  • Limites do contrato de conteúdo (título 10-70, descrição 50-160, categoria fechada, tags validadas contra arquivo próprio) — src/content/post-schema.mjs (código do projeto, nível 1), verificado em 2026-08-14.
  • Gates obrigatórios da PR e a decisão explícita de manter o job do Lighthouse não-bloqueante, com a justificativa da variância dos runners — .github/workflows/content-check.yml (código do projeto, nível 1), verificado em 2026-08-14.
  • Metas de LCP < 2500 ms e CLS < 0,1 aplicadas como falha de execução — tests/lighthouse/run-lighthouse.mjs (código do projeto, nível 1), verificado em 2026-08-14.
  • Registro da diretiva inventada que derrubou o SEO de 100 para 92, preservado como comentário no próprio arquivo — public/robots.txt (registro próprio, nível 1), verificado em 2026-08-14.
  • Os demais defeitos citados (CLS dependente de sistema operacional, ordem de títulos, colisões de CSS, falso defeito na captura de tela, aviso interno em produção) estão anotados na memória versionada do projeto — MEMORIA-PROJETO.md (registro próprio, nível 1), verificado em 2026-08-14.
  • Metodologia declarada: as notas de Lighthouse citadas são de execuções do perfil fixo deste projeto (mobile emulado, throttling simulado), locais ou no CI — não são medições de campo de usuários reais.