O worker disse "pronto." Um humano clicou. Nada aconteceu.
O "STATUS: COMPLETE" de um agent é uma afirmação a interrogar, nunca um fato a repassar.
Apollo Space Research
Apollo Space
Um agent termina uma tarefa, imprime um banner verde caprichado, STATUS: COMPLETE, e segue em frente. O orquestrador acima dele lê aquela linha, marca o trabalho como pronto, e avisa todo mundo que a feature foi entregue. Aí uma pessoa abre o produto pra usar a coisa que acabou de ser declarada finalizada, clica no botão que deveria fazer aquilo, e a tela não muda. Nenhuma linha foi escrita. Nenhum fluxo rodou. A feature existe em exatamente um lugar: o auto-relato de um worker.
Essa lacuna, entre “o worker disse pronto” e “um humano clicou e algo aconteceu”, é onde a maioria dos sistemas de agents silenciosamente mente pra si mesma.
Este post é sobre a disciplina que a fecha. A tese é uma frase, e é a regra contra a qual damos nota em cada peça de trabalho de agent.
O “STATUS: COMPLETE” de um agent é uma afirmação a interrogar, nunca um fato a repassar.
A versão ingênua: confie na palavra do worker
O jeito óbvio de tocar uma fleet de agents é acreditar no que eles te dizem.
Você dá a um worker uma tarefa. Ele planeja, edita arquivos, roda as checagens que decidiu rodar, e retorna um status. Se o status é sucesso, você propaga o sucesso: o orquestrador marca a tarefa como completa, o dashboard fica verde, o próximo estágio começa partindo do pressuposto de que o último terminou. É limpo. É rápido. Escala pra cem agents porque nenhum humano está no meio relendo nada.
Também falha do jeito mais caro possível, porque o worker dando nota em si mesmo é o worker em quem você menos confia.
Aqui está o mecanismo, e ele morde todo time que toca uma fleet. Um worker recebe a tarefa de construir uma feature. Ele escreve a função do backend. Ele escreve um teste que chama a função do backend diretamente. O teste passa. O worker, olhando pra um teste verde, conclui que a feature funciona, e ele não está mentindo, exatamente. A peça que ele construiu faz o que ele a construiu pra fazer. Mas “a função retorna o valor certo quando eu a chamo de um script” é uma afirmação muito diferente de “uma pessoa consegue fazer essa coisa no produto”, e o worker silenciosamente substituiu a primeira pela segunda. Ele testou a camada que conseguia alcançar e reportou sobre a camada com que você se importava.
Então o status diz COMPLETE. E o botão de criar na tela de verdade nunca foi conectado àquela função, porque conectar a tela era uma camada diferente que o worker nunca tocou. Ninguém descobre até alguém tentar usar.
O que “pronto” de fato significa, camada por camada
A correção começa com a recusa de deixar uma palavra, “pronto”, substituir uma pilha de fatos muito diferentes.
Uma feature de verdade é um vertical, não um ponto. Tem uma razão de negócio pra ela. Tem uma rota de API. Tem um schema de banco de dados e uma migration. Tem qualquer lógica que faça o agent se comportar corretamente. Tem um teste que exercita o caminho real, não um atalho conveniente. Tem uma tela com um controle nela. E bem no topo tem uma pessoa que clica naquele controle e vê a coisa certa acontecer. “Pronto” é uma propriedade da coluna inteira. Um worker que terminou uma caixinha lá embaixo e reportou sobre a caixinha do topo pulou a parte que era o ponto de verdade.
A armadilha é que a caixinha de baixo é a fácil e a caixinha de cima é a razão inteira de o trabalho existir. Inserir uma linha direto no banco de dados e anunciar que a feature funciona é a versão canônica dessa falha. O dado está lá, então com certeza funciona? Mas “uma linha existe” responde a uma pergunta que ninguém fez. A pergunta era: uma pessoa consegue criar essa coisa, pela tela que ela de fato usa? Se o fluxo de criação no front end não existe, a linha é plumbing, real, necessária, e não a coisa.
O “STATUS: COMPLETE” de um agent é uma afirmação a interrogar, nunca um fato a repassar. A interrogação tem uma forma: percorra o vertical, caixinha por caixinha, e pergunte de cada uma se ela foi provada ou meramente afirmada.
Por que um worker mais inteligente não resolve isso
A resposta tentadora é tornar o worker mais honesto. Diga a ele pra testar o caminho real. Diga a ele pra verificar de ponta a ponta. Com certeza um worker mais cuidadoso dá nota em si mesmo corretamente?
Não dá, e o motivo é estrutural, não uma questão de diligência.
Um worker dando nota no próprio output tem o mesmo ponto cego que o autor de qualquer coisa sempre tem: ele só consegue checar as falhas que já imaginou, porque se tivesse imaginado uma falha, teria tratado. Ele escreve o teste que afirma o que o próprio código já faz. Ele define “pronto” como o que quer que tenha conseguido terminar. Pergunte a ele “você completou a tarefa?” e a gravidade da pergunta puxa pro sim, o trabalho parece plausível, as checagens que ele escolheu estão verdes, a explicação é coerente. Um worker certificando a si mesmo são duas assinaturas no ponto cego de uma só mente.
Uma afirmação e um resultado não são o mesmo tipo de coisa. Uma é um sentimento usando um checkmark. O outro sobreviveu a uma tentativa de refutá-lo.
A nota tem de sair inteiramente do worker. Não um segundo worker que balança a cabeça concordando, uma checagem sem interesse no trabalho ser declarado pronto, cujo trabalho é descrer do status até o caminho real rodar na frente dela. A diferença é a pergunta que você faz. “Isso parece completo?” convida a um sim. “Me leve da necessidade de negócio até um humano clicando na tela ao vivo, e me mostre cada camada de fato rodando” convida à verdade, porque não pode ser respondido com um sentimento. Só pode ser respondido pelo fluxo rodando ou não.
O truque dos dois loops: um proxy rápido e uma verdade lenta
Existe uma objeção prática aqui, e é uma boa. Se “pronto” exige um humano clicando no produto deployado, você só consegue verificar algumas coisas por dia. O ponto inteiro de uma fleet era velocidade. Uma barra de verificação brutal não joga a velocidade fora?
Essa é a armadilha em que a maioria dos times cai: eles escolhem uma. Ou verificam rápido e raso, auto-avaliado, local, verde, e frequentemente errado, ou verificam lento e real, e arrastam-se a passo de tartaruga esperando deploys. A fleet ingênua roda o primeiro loop e chama de pronto. O time cauteloso roda o segundo e entrega uma vez por semana. Nenhum dos dois é a resposta.
A resposta é rodar os dois loops e nunca deixar um se passar pelo outro.
O loop interno é o proxy rápido. A afirmação de um worker é checada localmente contra o runtime real, o caminho de código de verdade, não um mock, em segundos, não em ciclos de deploy. É um proxy porque verde-local não é o mesmo que a tela do cliente funcionando, e você diz isso em voz alta. O loop externo é a verdade lenta: a superfície deployada, onde uma pessoa real (ou um fluxo no lugar de uma) clica no controle ao vivo e o sistema ou faz a coisa ou não faz. A disciplina é reportar dois números, nunca um, taxa de aprovação interna e taxa de aprovação externa, e tratar um verde-interno mergeado como “comportamentalmente verde, pendente da superfície real”, não como entregue.
Colapsar esses dois números num único e animado “funciona” é o pecado original uma altitude acima. O loop rápido te diz que o trabalho provavelmente está certo. Só o loop lento te diz que ele de fato é verdadeiro. Você precisa do proxy pra velocidade e da verdade pra confiança, e no momento em que você deixa o proxy falar pela verdade, está de volta a repassar uma afirmação.
Pra onde o fluxo vermelho aponta
Mais uma peça, porque uma barra de verificação que só diz “não” deixa todo mundo cansado.
Uma checagem reprovada é mais útil quando é um endereço, não uma reclamação. “O sistema parece burro” é um lamento; ninguém consegue agir sobre isso. “Uma pessoa não conseguiu criar isso pela tela porque o fluxo de criação para na camada de API e nunca chega ao front end” é uma lacuna localizada com uma correção anexada. A disciplina que interroga a afirmação tem de também localizar a falha, qual caixinha no vertical ficou vermelha, pra que o próximo worker comece do endereço em vez de re-diagnosticar a stack inteira.
É isso que transforma um padrão duro num loop em vez de num muro. Um fluxo vermelho dispara uma correção. A correção roda o loop interno de novo, rápido. Se ficar verde, entra na fila pro loop externo, real. O padrão nunca cede, pronto ainda significa que um humano clicou e algo aconteceu, mas o caminho pra cumpri-lo é curto e bem iluminado, porque cada falha veio com as próprias coordenadas.
O trabalho do worker é fazer o trabalho. O trabalho do padrão é recusar a palavra “pronto” até o trabalho ser real, e devolver um mapa toda vez que recusa.
A virada: ownership é a parte que você não consegue auto-reportar
Os loops e as camadas são maquinaria pra algo muito mais antigo que software.
A razão de você confiar num colega de trabalho específico não é a confiança nos updates de status dele. Qualquer um consegue digitar “pronto.” Você confia naquele que, quando você pergunta se a coisa de fato funciona, não responde de memória, ele abre o produto, clica no botão que você clicaria, e vê acontecer antes de te dizer sim. Você confia nele porque ele internalizou a lacuna entre eu construí e funciona pra pessoa que precisa, e ele se recusa a deixar o primeiro se mascarar de segundo. Essa recusa não é uma feature. É uma postura diante do trabalho.
Essa é a parte que você não consegue instalar. Você pode montar um loop interno e um loop externo, pode rotear todo status por uma checagem que descrê dele, pode fazer os fluxos vermelhos carregarem os próprios endereços, e tudo isso é real, e tudo isso importa. Mas por baixo do mecanismo está uma única convicção que o mecanismo apenas impõe: que uma afirmação deve uma prova, que a pessoa do outro lado clicando no botão é o único juiz cujo veredicto conta, e que “parece pronto” é um lugar pra começar uma discussão, não um lugar pra parar. Não inventamos isso. Os melhores engenheiros sempre viveram isso. A gente só construiu um sistema que nunca cansa de segurar a linha, no dia em que todo mundo cansa.
O “STATUS: COMPLETE” de um agent é uma afirmação a interrogar, nunca um fato a repassar, e no momento em que uma fleet esquece isso, ela começa a entregar features que existem só nos próprios relatórios de status.
É isso que estamos construindo na Apollo Space: um sistema operacional onde a palavra de um agent é o começo da checagem, não o fim dela, onde “pronto” significa que uma pessoa clicou na coisa real e funcionou. Se você já entregou uma feature com status verde que acabou sendo uma linha numa tabela que ninguém conseguia alcançar, você já sabe qual metade do trabalho a máquina deveria estar fazendo por você.
A Apollo cuida da operação repetitiva da sua empresa pro seu time não precisar.
Entre na lista de espera: acesso antecipado, preço de usuário fundador e um lugar na primeira fila enquanto a gente constrói.
Entrar na lista de esperaO imposto oculto dos agents em paralelo é um diamante de migrations
Seis agents escrevendo para um schema conflitam no banco de dados, não no código, e a CI morre em "multiple heads".
EngenhariaUm orchestrator que não sobrevive ao próprio crash não é um
Um crash que apaga o raciocínio do orchestrator perde a única coisa que você não consegue reconstruir.
EngenhariaColoque um portão determinístico na frente do seu revisor mais esperto
A pega-defeito mais barata é um script burro que checa se duas branches mergeadas ainda sobem antes de qualquer julgamento.